LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFExpression.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 135 164 82.3 %
Date: 2017-09-14 15:23:50 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/DebugInfo/DWARF/DWARFCompileUnit.h"
      13             : #include "llvm/DebugInfo/DWARF/DWARFContext.h"
      14             : #include "llvm/MC/MCRegisterInfo.h"
      15             : #include "llvm/Support/Format.h"
      16             : #include <cassert>
      17             : #include <cstdint>
      18             : #include <vector>
      19             : 
      20             : using namespace llvm;
      21             : using namespace dwarf;
      22             : 
      23             : namespace llvm {
      24             : 
      25             : typedef std::vector<DWARFExpression::Operation::Description> DescVector;
      26             : 
      27         339 : static DescVector getDescriptions() {
      28         339 :   DescVector Descriptions;
      29             :   typedef DWARFExpression::Operation Op;
      30             :   typedef Op::Description Desc;
      31             : 
      32         339 :   Descriptions.resize(0xff);
      33         339 :   Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr);
      34         339 :   Descriptions[DW_OP_deref] = Desc(Op::Dwarf2);
      35         339 :   Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1);
      36         339 :   Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1);
      37         339 :   Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2);
      38         339 :   Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2);
      39         339 :   Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4);
      40         339 :   Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4);
      41         339 :   Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8);
      42         339 :   Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8);
      43         339 :   Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB);
      44         339 :   Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
      45         339 :   Descriptions[DW_OP_dup] = Desc(Op::Dwarf2);
      46         339 :   Descriptions[DW_OP_drop] = Desc(Op::Dwarf2);
      47         339 :   Descriptions[DW_OP_over] = Desc(Op::Dwarf2);
      48         339 :   Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1);
      49         339 :   Descriptions[DW_OP_swap] = Desc(Op::Dwarf2);
      50         339 :   Descriptions[DW_OP_rot] = Desc(Op::Dwarf2);
      51         339 :   Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2);
      52         339 :   Descriptions[DW_OP_abs] = Desc(Op::Dwarf2);
      53         339 :   Descriptions[DW_OP_and] = Desc(Op::Dwarf2);
      54         339 :   Descriptions[DW_OP_div] = Desc(Op::Dwarf2);
      55         339 :   Descriptions[DW_OP_minus] = Desc(Op::Dwarf2);
      56         339 :   Descriptions[DW_OP_mod] = Desc(Op::Dwarf2);
      57         339 :   Descriptions[DW_OP_mul] = Desc(Op::Dwarf2);
      58         339 :   Descriptions[DW_OP_neg] = Desc(Op::Dwarf2);
      59         339 :   Descriptions[DW_OP_not] = Desc(Op::Dwarf2);
      60         339 :   Descriptions[DW_OP_or] = Desc(Op::Dwarf2);
      61         339 :   Descriptions[DW_OP_plus] = Desc(Op::Dwarf2);
      62         339 :   Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB);
      63         339 :   Descriptions[DW_OP_shl] = Desc(Op::Dwarf2);
      64         339 :   Descriptions[DW_OP_shr] = Desc(Op::Dwarf2);
      65         339 :   Descriptions[DW_OP_shra] = Desc(Op::Dwarf2);
      66         339 :   Descriptions[DW_OP_xor] = Desc(Op::Dwarf2);
      67         339 :   Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
      68         339 :   Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2);
      69         339 :   Descriptions[DW_OP_eq] = Desc(Op::Dwarf2);
      70         339 :   Descriptions[DW_OP_ge] = Desc(Op::Dwarf2);
      71         339 :   Descriptions[DW_OP_gt] = Desc(Op::Dwarf2);
      72         339 :   Descriptions[DW_OP_le] = Desc(Op::Dwarf2);
      73         339 :   Descriptions[DW_OP_lt] = Desc(Op::Dwarf2);
      74         339 :   Descriptions[DW_OP_ne] = Desc(Op::Dwarf2);
      75       11187 :   for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
      76       21696 :     Descriptions[LA] = Desc(Op::Dwarf2);
      77       22035 :   for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
      78       21696 :     Descriptions[LA] = Desc(Op::Dwarf2);
      79       22035 :   for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
      80       21696 :     Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
      81         339 :   Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB);
      82         339 :   Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
      83         339 :   Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB);
      84         339 :   Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB);
      85         339 :   Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1);
      86         339 :   Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1);
      87         339 :   Descriptions[DW_OP_nop] = Desc(Op::Dwarf2);
      88         339 :   Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3);
      89         339 :   Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2);
      90         339 :   Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4);
      91         339 :   Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr);
      92         339 :   Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3);
      93         339 :   Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3);
      94         339 :   Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB);
      95         339 :   Descriptions[DW_OP_implicit_value] =
      96         678 :       Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
      97         339 :   Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
      98         339 :   Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
      99         339 :   Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
     100         339 :   Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
     101         339 :   return Descriptions;
     102             : }
     103             : 
     104        2346 : static DWARFExpression::Operation::Description getOpDesc(unsigned OpCode) {
     105             :   // FIXME: Make this constexpr once all compilers are smart enough to do it.
     106        2346 :   static DescVector Descriptions = getDescriptions();
     107             :   assert(OpCode < Descriptions.size());
     108        4692 :   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        2346 : bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version,
     116             :                                          uint8_t AddressSize, uint32_t Offset) {
     117        2346 :   Opcode = Data.getU8(&Offset);
     118             : 
     119        2346 :   Desc = getOpDesc(Opcode);
     120        2346 :   if (Desc.Version == Operation::DwarfNA)
     121             :     return false;
     122             : 
     123        5030 :   for (unsigned Operand = 0; Operand < 2; ++Operand) {
     124        3683 :     unsigned Size = Desc.Op[Operand];
     125        3683 :     unsigned Signed = Size & Operation::SignBit;
     126             : 
     127        3683 :     if (Size == Operation::SizeNA)
     128             :       break;
     129             : 
     130        1342 :     switch (Size & ~Operation::SignBit) {
     131           0 :     case Operation::Size1:
     132           0 :       Operands[Operand] = Data.getU8(&Offset);
     133           0 :       if (Signed)
     134           0 :         Operands[Operand] = (int8_t)Operands[Operand];
     135             :       break;
     136           0 :     case Operation::Size2:
     137           0 :       Operands[Operand] = Data.getU16(&Offset);
     138           0 :       if (Signed)
     139           0 :         Operands[Operand] = (int16_t)Operands[Operand];
     140             :       break;
     141           1 :     case Operation::Size4:
     142           1 :       Operands[Operand] = Data.getU32(&Offset);
     143           1 :       if (Signed)
     144           0 :         Operands[Operand] = (int32_t)Operands[Operand];
     145             :       break;
     146           1 :     case Operation::Size8:
     147           1 :       Operands[Operand] = Data.getU64(&Offset);
     148           1 :       break;
     149         240 :     case Operation::SizeAddr:
     150         240 :       if (AddressSize == 8) {
     151         225 :         Operands[Operand] = Data.getU64(&Offset);
     152             :       } else {
     153             :         assert(AddressSize == 4);
     154          15 :         Operands[Operand] = Data.getU32(&Offset);
     155             :       }
     156             :       break;
     157           0 :     case Operation::SizeRefAddr:
     158           0 :       if (getRefAddrSize(AddressSize, Version) == 8) {
     159           0 :         Operands[Operand] = Data.getU64(&Offset);
     160             :       } else {
     161             :         assert(getRefAddrSize(AddressSize, Version) == 4);
     162           0 :         Operands[Operand] = Data.getU32(&Offset);
     163             :       }
     164             :       break;
     165        1100 :     case Operation::SizeLEB:
     166        1100 :       if (Signed)
     167         716 :         Operands[Operand] = Data.getSLEB128(&Offset);
     168             :       else
     169         384 :         Operands[Operand] = Data.getULEB128(&Offset);
     170             :       break;
     171           0 :     case Operation::SizeBlock:
     172             :       // We need a size, so this cannot be the first operand
     173           0 :       if (Operand == 0)
     174             :         return false;
     175             :       // Store the offset of the block as the value.
     176           0 :       Operands[Operand] = Offset;
     177           0 :       Offset += Operands[Operand - 1];
     178           0 :       break;
     179           0 :     default:
     180           0 :       llvm_unreachable("Unknown DWARFExpression Op size");
     181             :     }
     182             :   }
     183             : 
     184        2346 :   EndOffset = Offset;
     185        2346 :   return true;
     186             : }
     187             : 
     188        1019 : static bool prettyPrintRegisterOp(raw_ostream &OS, uint8_t Opcode,
     189             :                                   uint64_t Operands[2],
     190             :                                   const MCRegisterInfo *MRI, bool isEH) {
     191        1019 :   if (!MRI)
     192             :     return false;
     193             : 
     194             :   uint64_t DwarfRegNum;
     195         991 :   unsigned OpNum = 0;
     196             : 
     197         991 :   if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx)
     198          18 :     DwarfRegNum = Operands[OpNum++];
     199         973 :   else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
     200         167 :     DwarfRegNum = Opcode - DW_OP_breg0;
     201             :   else
     202         806 :     DwarfRegNum = Opcode - DW_OP_reg0;
     203             : 
     204         991 :   int LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH);
     205         991 :   if (LLVMRegNum >= 0) {
     206        1982 :     if (const char *RegName = MRI->getName(LLVMRegNum)) {
     207         991 :       if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
     208             :           Opcode == DW_OP_bregx)
     209         334 :         OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
     210             :       else
     211         824 :         OS << ' ' << RegName;
     212             :       return true;
     213             :     }
     214             :   }
     215             : 
     216             :   return false;
     217             : }
     218             : 
     219        2346 : bool DWARFExpression::Operation::print(raw_ostream &OS,
     220             :                                        const DWARFExpression *Expr,
     221             :                                        const MCRegisterInfo *RegInfo,
     222             :                                        bool isEH) {
     223        2346 :   if (Error) {
     224           0 :     OS << "decoding error.";
     225           0 :     return false;
     226             :   }
     227             : 
     228        2346 :   StringRef Name = OperationEncodingString(Opcode);
     229             :   assert(!Name.empty() && "DW_OP has no name!");
     230        2346 :   OS << Name;
     231             : 
     232        4692 :   if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
     233        2346 :       (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
     234        1345 :       Opcode == DW_OP_bregx || Opcode == DW_OP_regx)
     235        1019 :     if (prettyPrintRegisterOp(OS, Opcode, Operands, RegInfo, isEH))
     236             :       return true;
     237             : 
     238        3669 :   for (unsigned Operand = 0; Operand < 2; ++Operand) {
     239        2507 :     unsigned Size = Desc.Op[Operand];
     240        2507 :     unsigned Signed = Size & Operation::SignBit;
     241             : 
     242        2507 :     if (Size == Operation::SizeNA)
     243             :       break;
     244             : 
     245        1157 :     if (Size == Operation::SizeBlock) {
     246           0 :       uint32_t Offset = Operands[Operand];
     247           0 :       for (unsigned i = 0; i < Operands[Operand - 1]; ++i)
     248           0 :         OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
     249             :     } else {
     250        1157 :       if (Signed)
     251        1098 :         OS << format(" %+" PRId64, (int64_t)Operands[Operand]);
     252             :       else
     253        1216 :         OS << format(" 0x%" PRIx64, Operands[Operand]);
     254             :     }
     255             :   }
     256             :   return true;
     257             : }
     258             : 
     259        1964 : void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo) {
     260        8238 :   for (auto &Op : *this) {
     261        2346 :     if (!Op.print(OS, this, RegInfo, /* isEH */ false)) {
     262           0 :       uint32_t FailOffset = Op.getEndOffset();
     263           0 :       while (FailOffset < Data.getData().size())
     264           0 :         OS << format(" %02x", Data.getU8(&FailOffset));
     265             :       return;
     266             :     }
     267        2346 :     if (Op.getEndOffset() < Data.getData().size())
     268         382 :       OS << ", ";
     269             :   }
     270             : }
     271             : 
     272             : } // namespace llvm

Generated by: LCOV version 1.13