LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFExpression.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 139 164 84.8 %
Date: 2018-10-20 13:21:21 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- DWARFExpression.cpp -----------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
      11             : #include "llvm/BinaryFormat/Dwarf.h"
      12             : #include "llvm/MC/MCRegisterInfo.h"
      13             : #include "llvm/Support/Format.h"
      14             : #include <cassert>
      15             : #include <cstdint>
      16             : #include <vector>
      17             : 
      18             : using namespace llvm;
      19             : using namespace dwarf;
      20             : 
      21             : namespace llvm {
      22             : 
      23             : typedef std::vector<DWARFExpression::Operation::Description> DescVector;
      24             : 
      25         480 : static DescVector getDescriptions() {
      26             :   DescVector Descriptions;
      27             :   typedef DWARFExpression::Operation Op;
      28             :   typedef Op::Description Desc;
      29             : 
      30         480 :   Descriptions.resize(0xff);
      31         480 :   Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr);
      32         480 :   Descriptions[DW_OP_deref] = Desc(Op::Dwarf2);
      33         480 :   Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1);
      34         480 :   Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1);
      35         480 :   Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2);
      36         480 :   Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2);
      37         480 :   Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4);
      38         480 :   Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4);
      39         480 :   Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8);
      40         480 :   Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8);
      41         480 :   Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB);
      42         480 :   Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
      43         480 :   Descriptions[DW_OP_dup] = Desc(Op::Dwarf2);
      44         480 :   Descriptions[DW_OP_drop] = Desc(Op::Dwarf2);
      45         480 :   Descriptions[DW_OP_over] = Desc(Op::Dwarf2);
      46         480 :   Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1);
      47         480 :   Descriptions[DW_OP_swap] = Desc(Op::Dwarf2);
      48         480 :   Descriptions[DW_OP_rot] = Desc(Op::Dwarf2);
      49         480 :   Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2);
      50         480 :   Descriptions[DW_OP_abs] = Desc(Op::Dwarf2);
      51         480 :   Descriptions[DW_OP_and] = Desc(Op::Dwarf2);
      52         480 :   Descriptions[DW_OP_div] = Desc(Op::Dwarf2);
      53         480 :   Descriptions[DW_OP_minus] = Desc(Op::Dwarf2);
      54         480 :   Descriptions[DW_OP_mod] = Desc(Op::Dwarf2);
      55         480 :   Descriptions[DW_OP_mul] = Desc(Op::Dwarf2);
      56         480 :   Descriptions[DW_OP_neg] = Desc(Op::Dwarf2);
      57         480 :   Descriptions[DW_OP_not] = Desc(Op::Dwarf2);
      58         480 :   Descriptions[DW_OP_or] = Desc(Op::Dwarf2);
      59         480 :   Descriptions[DW_OP_plus] = Desc(Op::Dwarf2);
      60         480 :   Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB);
      61         480 :   Descriptions[DW_OP_shl] = Desc(Op::Dwarf2);
      62         480 :   Descriptions[DW_OP_shr] = Desc(Op::Dwarf2);
      63         480 :   Descriptions[DW_OP_shra] = Desc(Op::Dwarf2);
      64         480 :   Descriptions[DW_OP_xor] = Desc(Op::Dwarf2);
      65         480 :   Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
      66         480 :   Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2);
      67         480 :   Descriptions[DW_OP_eq] = Desc(Op::Dwarf2);
      68         480 :   Descriptions[DW_OP_ge] = Desc(Op::Dwarf2);
      69         480 :   Descriptions[DW_OP_gt] = Desc(Op::Dwarf2);
      70         480 :   Descriptions[DW_OP_le] = Desc(Op::Dwarf2);
      71         480 :   Descriptions[DW_OP_lt] = Desc(Op::Dwarf2);
      72         480 :   Descriptions[DW_OP_ne] = Desc(Op::Dwarf2);
      73       15840 :   for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
      74       30720 :     Descriptions[LA] = Desc(Op::Dwarf2);
      75       15840 :   for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
      76       30720 :     Descriptions[LA] = Desc(Op::Dwarf2);
      77       15840 :   for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
      78       30720 :     Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
      79         480 :   Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB);
      80         480 :   Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
      81         480 :   Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB);
      82         480 :   Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB);
      83         480 :   Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1);
      84         480 :   Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1);
      85         480 :   Descriptions[DW_OP_nop] = Desc(Op::Dwarf2);
      86         480 :   Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3);
      87         480 :   Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2);
      88         480 :   Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4);
      89         480 :   Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr);
      90         480 :   Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3);
      91         480 :   Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3);
      92         480 :   Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB);
      93         480 :   Descriptions[DW_OP_implicit_value] =
      94             :       Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
      95         480 :   Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
      96         480 :   Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
      97         480 :   Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
      98         480 :   Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
      99         480 :   return Descriptions;
     100             : }
     101             : 
     102        3216 : static DWARFExpression::Operation::Description getOpDesc(unsigned OpCode) {
     103             :   // FIXME: Make this constexpr once all compilers are smart enough to do it.
     104        3216 :   static DescVector Descriptions = getDescriptions();
     105             :   // Handle possible corrupted or unsupported operation.
     106        6432 :   if (OpCode >= Descriptions.size())
     107           3 :     return {};
     108        3213 :   return Descriptions[OpCode];
     109             : }
     110             : 
     111             : static uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
     112           0 :   return (Version == 2) ? AddrSize : 4;
     113             : }
     114             : 
     115        3216 : bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version,
     116             :                                          uint8_t AddressSize, uint32_t Offset) {
     117        3216 :   Opcode = Data.getU8(&Offset);
     118             : 
     119        3216 :   Desc = getOpDesc(Opcode);
     120        3216 :   if (Desc.Version == Operation::DwarfNA) {
     121           3 :     EndOffset = Offset;
     122           3 :     return false;
     123             :   }
     124             : 
     125        5111 :   for (unsigned Operand = 0; Operand < 2; ++Operand) {
     126        5105 :     unsigned Size = Desc.Op[Operand];
     127        5105 :     unsigned Signed = Size & Operation::SignBit;
     128             : 
     129        5105 :     if (Size == Operation::SizeNA)
     130             :       break;
     131             : 
     132        1898 :     switch (Size & ~Operation::SignBit) {
     133           0 :     case Operation::Size1:
     134           0 :       Operands[Operand] = Data.getU8(&Offset);
     135           0 :       if (Signed)
     136           0 :         Operands[Operand] = (int8_t)Operands[Operand];
     137             :       break;
     138           0 :     case Operation::Size2:
     139           0 :       Operands[Operand] = Data.getU16(&Offset);
     140           0 :       if (Signed)
     141           0 :         Operands[Operand] = (int16_t)Operands[Operand];
     142             :       break;
     143           1 :     case Operation::Size4:
     144           1 :       Operands[Operand] = Data.getU32(&Offset);
     145           1 :       if (Signed)
     146           0 :         Operands[Operand] = (int32_t)Operands[Operand];
     147             :       break;
     148           8 :     case Operation::Size8:
     149           8 :       Operands[Operand] = Data.getU64(&Offset);
     150           8 :       break;
     151         658 :     case Operation::SizeAddr:
     152         658 :       if (AddressSize == 8) {
     153         630 :         Operands[Operand] = Data.getU64(&Offset);
     154             :       } else {
     155             :         assert(AddressSize == 4);
     156          28 :         Operands[Operand] = Data.getU32(&Offset);
     157             :       }
     158             :       break;
     159           0 :     case Operation::SizeRefAddr:
     160           0 :       if (getRefAddrSize(AddressSize, Version) == 8) {
     161           0 :         Operands[Operand] = Data.getU64(&Offset);
     162             :       } else {
     163             :         assert(getRefAddrSize(AddressSize, Version) == 4);
     164           0 :         Operands[Operand] = Data.getU32(&Offset);
     165             :       }
     166             :       break;
     167        1231 :     case Operation::SizeLEB:
     168        1231 :       if (Signed)
     169         876 :         Operands[Operand] = Data.getSLEB128(&Offset);
     170             :       else
     171         355 :         Operands[Operand] = Data.getULEB128(&Offset);
     172             :       break;
     173           0 :     case Operation::SizeBlock:
     174             :       // We need a size, so this cannot be the first operand
     175           0 :       if (Operand == 0)
     176             :         return false;
     177             :       // Store the offset of the block as the value.
     178           0 :       Operands[Operand] = Offset;
     179           0 :       Offset += Operands[Operand - 1];
     180           0 :       break;
     181           0 :     default:
     182           0 :       llvm_unreachable("Unknown DWARFExpression Op size");
     183             :     }
     184             :   }
     185             : 
     186        3213 :   EndOffset = Offset;
     187        3213 :   return true;
     188             : }
     189             : 
     190        1243 : static bool prettyPrintRegisterOp(raw_ostream &OS, uint8_t Opcode,
     191             :                                   uint64_t Operands[2],
     192             :                                   const MCRegisterInfo *MRI, bool isEH) {
     193        1243 :   if (!MRI)
     194             :     return false;
     195             : 
     196             :   uint64_t DwarfRegNum;
     197             :   unsigned OpNum = 0;
     198             : 
     199        1190 :   if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx)
     200          18 :     DwarfRegNum = Operands[OpNum++];
     201        1172 :   else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
     202         184 :     DwarfRegNum = Opcode - DW_OP_breg0;
     203             :   else
     204         988 :     DwarfRegNum = Opcode - DW_OP_reg0;
     205             : 
     206        1190 :   int LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH);
     207        1190 :   if (LLVMRegNum >= 0) {
     208        2380 :     if (const char *RegName = MRI->getName(LLVMRegNum)) {
     209        1190 :       if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
     210             :           Opcode == DW_OP_bregx)
     211         368 :         OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
     212             :       else
     213        1006 :         OS << ' ' << RegName;
     214             :       return true;
     215             :     }
     216             :   }
     217             : 
     218             :   return false;
     219             : }
     220             : 
     221        2766 : bool DWARFExpression::Operation::print(raw_ostream &OS,
     222             :                                        const DWARFExpression *Expr,
     223             :                                        const MCRegisterInfo *RegInfo,
     224             :                                        bool isEH) {
     225        2766 :   if (Error) {
     226           2 :     OS << "<decoding error>";
     227           2 :     return false;
     228             :   }
     229             : 
     230        2764 :   StringRef Name = OperationEncodingString(Opcode);
     231             :   assert(!Name.empty() && "DW_OP has no name!");
     232        2764 :   OS << Name;
     233             : 
     234        5528 :   if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
     235        2764 :       (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
     236        1539 :       Opcode == DW_OP_bregx || Opcode == DW_OP_regx)
     237        1243 :     if (prettyPrintRegisterOp(OS, Opcode, Operands, RegInfo, isEH))
     238             :       return true;
     239             : 
     240        2849 :   for (unsigned Operand = 0; Operand < 2; ++Operand) {
     241        2843 :     unsigned Size = Desc.Op[Operand];
     242             :     unsigned Signed = Size & Operation::SignBit;
     243             : 
     244        2843 :     if (Size == Operation::SizeNA)
     245             :       break;
     246             : 
     247        1275 :     if (Size == Operation::SizeBlock) {
     248           0 :       uint32_t Offset = Operands[Operand];
     249           0 :       for (unsigned i = 0; i < Operands[Operand - 1]; ++i)
     250           0 :         OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
     251             :     } else {
     252        1275 :       if (Signed)
     253        1214 :         OS << format(" %+" PRId64, (int64_t)Operands[Operand]);
     254             :       else
     255        1336 :         OS << format(" 0x%" PRIx64, Operands[Operand]);
     256             :     }
     257             :   }
     258             :   return true;
     259             : }
     260             : 
     261        2331 : void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
     262             :                             bool IsEH) const {
     263        2764 :   for (auto &Op : *this) {
     264        2766 :     if (!Op.print(OS, this, RegInfo, IsEH)) {
     265           2 :       uint32_t FailOffset = Op.getEndOffset();
     266           2 :       while (FailOffset < Data.getData().size())
     267           0 :         OS << format(" %02x", Data.getU8(&FailOffset));
     268             :       return;
     269             :     }
     270        2764 :     if (Op.getEndOffset() < Data.getData().size())
     271         436 :       OS << ", ";
     272             :   }
     273             : }
     274             : 
     275             : } // namespace llvm

Generated by: LCOV version 1.13