LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFFormValue.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 251 296 84.8 %
Date: 2017-09-14 15:23:50 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFFormValue.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/DWARFFormValue.h"
      11             : #include "SyntaxHighlighting.h"
      12             : #include "llvm/ADT/ArrayRef.h"
      13             : #include "llvm/ADT/None.h"
      14             : #include "llvm/ADT/Optional.h"
      15             : #include "llvm/ADT/StringRef.h"
      16             : #include "llvm/BinaryFormat/Dwarf.h"
      17             : #include "llvm/DebugInfo/DWARF/DWARFContext.h"
      18             : #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
      19             : #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
      20             : #include "llvm/Support/ErrorHandling.h"
      21             : #include "llvm/Support/Format.h"
      22             : #include "llvm/Support/raw_ostream.h"
      23             : #include <cinttypes>
      24             : #include <cstdint>
      25             : #include <limits>
      26             : 
      27             : using namespace llvm;
      28             : using namespace dwarf;
      29             : using namespace syntax;
      30             : 
      31             : static const DWARFFormValue::FormClass DWARF4FormClasses[] = {
      32             :     DWARFFormValue::FC_Unknown,  // 0x0
      33             :     DWARFFormValue::FC_Address,  // 0x01 DW_FORM_addr
      34             :     DWARFFormValue::FC_Unknown,  // 0x02 unused
      35             :     DWARFFormValue::FC_Block,    // 0x03 DW_FORM_block2
      36             :     DWARFFormValue::FC_Block,    // 0x04 DW_FORM_block4
      37             :     DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
      38             :     // --- These can be FC_SectionOffset in DWARF3 and below:
      39             :     DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
      40             :     DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
      41             :     // ---
      42             :     DWARFFormValue::FC_String,        // 0x08 DW_FORM_string
      43             :     DWARFFormValue::FC_Block,         // 0x09 DW_FORM_block
      44             :     DWARFFormValue::FC_Block,         // 0x0a DW_FORM_block1
      45             :     DWARFFormValue::FC_Constant,      // 0x0b DW_FORM_data1
      46             :     DWARFFormValue::FC_Flag,          // 0x0c DW_FORM_flag
      47             :     DWARFFormValue::FC_Constant,      // 0x0d DW_FORM_sdata
      48             :     DWARFFormValue::FC_String,        // 0x0e DW_FORM_strp
      49             :     DWARFFormValue::FC_Constant,      // 0x0f DW_FORM_udata
      50             :     DWARFFormValue::FC_Reference,     // 0x10 DW_FORM_ref_addr
      51             :     DWARFFormValue::FC_Reference,     // 0x11 DW_FORM_ref1
      52             :     DWARFFormValue::FC_Reference,     // 0x12 DW_FORM_ref2
      53             :     DWARFFormValue::FC_Reference,     // 0x13 DW_FORM_ref4
      54             :     DWARFFormValue::FC_Reference,     // 0x14 DW_FORM_ref8
      55             :     DWARFFormValue::FC_Reference,     // 0x15 DW_FORM_ref_udata
      56             :     DWARFFormValue::FC_Indirect,      // 0x16 DW_FORM_indirect
      57             :     DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
      58             :     DWARFFormValue::FC_Exprloc,       // 0x18 DW_FORM_exprloc
      59             :     DWARFFormValue::FC_Flag,          // 0x19 DW_FORM_flag_present
      60             : };
      61             : 
      62             : Optional<uint8_t>
      63    39372024 : DWARFFormValue::getFixedByteSize(dwarf::Form Form,
      64             :                                  const DWARFFormParams Params) {
      65    39372024 :   switch (Form) {
      66      291049 :   case DW_FORM_addr:
      67             :     assert(Params.Version && Params.AddrSize && "Invalid Params for form");
      68             :     return Params.AddrSize;
      69             : 
      70     2993230 :   case DW_FORM_block:          // ULEB128 length L followed by L bytes.
      71             :   case DW_FORM_block1:         // 1 byte length L followed by L bytes.
      72             :   case DW_FORM_block2:         // 2 byte length L followed by L bytes.
      73             :   case DW_FORM_block4:         // 4 byte length L followed by L bytes.
      74             :   case DW_FORM_string:         // C-string with null terminator.
      75             :   case DW_FORM_sdata:          // SLEB128.
      76             :   case DW_FORM_udata:          // ULEB128.
      77             :   case DW_FORM_ref_udata:      // ULEB128.
      78             :   case DW_FORM_indirect:       // ULEB128.
      79             :   case DW_FORM_exprloc:        // ULEB128 length L followed by L bytes.
      80             :   case DW_FORM_strx:           // ULEB128.
      81             :   case DW_FORM_addrx:          // ULEB128.
      82             :   case DW_FORM_loclistx:       // ULEB128.
      83             :   case DW_FORM_rnglistx:       // ULEB128.
      84             :   case DW_FORM_GNU_addr_index: // ULEB128.
      85             :   case DW_FORM_GNU_str_index:  // ULEB128.
      86             :     return None;
      87             : 
      88         360 :   case DW_FORM_ref_addr:
      89             :     assert(Params.Version && Params.AddrSize && "Invalid Params for form");
      90         720 :     return Params.getRefAddrByteSize();
      91             : 
      92    14176052 :   case DW_FORM_flag:
      93             :   case DW_FORM_data1:
      94             :   case DW_FORM_ref1:
      95             :   case DW_FORM_strx1:
      96             :   case DW_FORM_addrx1:
      97    28352104 :     return 1;
      98             : 
      99     2994976 :   case DW_FORM_data2:
     100             :   case DW_FORM_ref2:
     101             :   case DW_FORM_strx2:
     102             :   case DW_FORM_addrx2:
     103     5989952 :     return 2;
     104             : 
     105           2 :   case DW_FORM_strx3:
     106           4 :     return 3;
     107             : 
     108    10860494 :   case DW_FORM_data4:
     109             :   case DW_FORM_ref4:
     110             :   case DW_FORM_ref_sup4:
     111             :   case DW_FORM_strx4:
     112             :   case DW_FORM_addrx4:
     113    21720988 :     return 4;
     114             : 
     115      492313 :   case DW_FORM_strp:
     116             :   case DW_FORM_GNU_ref_alt:
     117             :   case DW_FORM_GNU_strp_alt:
     118             :   case DW_FORM_line_strp:
     119             :   case DW_FORM_sec_offset:
     120             :   case DW_FORM_strp_sup:
     121             :     assert(Params.Version && Params.AddrSize && "Invalid Params for form");
     122     1476939 :     return Params.getDwarfOffsetByteSize();
     123             : 
     124      375912 :   case DW_FORM_data8:
     125             :   case DW_FORM_ref8:
     126             :   case DW_FORM_ref_sig8:
     127             :   case DW_FORM_ref_sup8:
     128      751824 :     return 8;
     129             : 
     130     7187636 :   case DW_FORM_flag_present:
     131    14375272 :     return 0;
     132             : 
     133           0 :   case DW_FORM_data16:
     134           0 :     return 16;
     135             : 
     136           0 :   case DW_FORM_implicit_const:
     137             :     // The implicit value is stored in the abbreviation as a SLEB128, and
     138             :     // there no data in debug info.
     139           0 :     return 0;
     140             : 
     141           0 :   default:
     142           0 :     llvm_unreachable("Handle this form in this switch statement");
     143             :   }
     144             :   return None;
     145             : }
     146             : 
     147      888386 : bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
     148             :                                uint32_t *OffsetPtr,
     149             :                                const DWARFFormParams Params) {
     150      888386 :   bool Indirect = false;
     151             :   do {
     152      888386 :     switch (Form) {
     153             :     // Blocks of inlined data that have a length field and the data bytes
     154             :     // inlined in the .debug_info.
     155      230465 :     case DW_FORM_exprloc:
     156             :     case DW_FORM_block: {
     157      230465 :       uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
     158      230465 :       *OffsetPtr += size;
     159      230465 :       return true;
     160             :     }
     161       99823 :     case DW_FORM_block1: {
     162       99823 :       uint8_t size = DebugInfoData.getU8(OffsetPtr);
     163       99823 :       *OffsetPtr += size;
     164       99823 :       return true;
     165             :     }
     166         352 :     case DW_FORM_block2: {
     167         352 :       uint16_t size = DebugInfoData.getU16(OffsetPtr);
     168         352 :       *OffsetPtr += size;
     169         352 :       return true;
     170             :     }
     171         188 :     case DW_FORM_block4: {
     172         188 :       uint32_t size = DebugInfoData.getU32(OffsetPtr);
     173         188 :       *OffsetPtr += size;
     174         188 :       return true;
     175             :     }
     176             : 
     177             :     // Inlined NULL terminated C-strings.
     178      549949 :     case DW_FORM_string:
     179      549949 :       DebugInfoData.getCStr(OffsetPtr);
     180      549949 :       return true;
     181             : 
     182        5478 :     case DW_FORM_addr:
     183             :     case DW_FORM_ref_addr:
     184             :     case DW_FORM_flag_present:
     185             :     case DW_FORM_data1:
     186             :     case DW_FORM_data2:
     187             :     case DW_FORM_data4:
     188             :     case DW_FORM_data8:
     189             :     case DW_FORM_flag:
     190             :     case DW_FORM_ref1:
     191             :     case DW_FORM_ref2:
     192             :     case DW_FORM_ref4:
     193             :     case DW_FORM_ref8:
     194             :     case DW_FORM_ref_sig8:
     195             :     case DW_FORM_ref_sup4:
     196             :     case DW_FORM_ref_sup8:
     197             :     case DW_FORM_strx1:
     198             :     case DW_FORM_strx2:
     199             :     case DW_FORM_strx4:
     200             :     case DW_FORM_addrx1:
     201             :     case DW_FORM_addrx2:
     202             :     case DW_FORM_addrx4:
     203             :     case DW_FORM_sec_offset:
     204             :     case DW_FORM_strp:
     205             :     case DW_FORM_strp_sup:
     206             :     case DW_FORM_line_strp:
     207             :     case DW_FORM_GNU_ref_alt:
     208             :     case DW_FORM_GNU_strp_alt:
     209        5478 :       if (Optional<uint8_t> FixedSize =
     210        5478 :               DWARFFormValue::getFixedByteSize(Form, Params)) {
     211        5478 :         *OffsetPtr += *FixedSize;
     212       10956 :         return true;
     213        5478 :       }
     214           0 :       return false;
     215             : 
     216             :     // signed or unsigned LEB 128 values.
     217         850 :     case DW_FORM_sdata:
     218         850 :       DebugInfoData.getSLEB128(OffsetPtr);
     219         850 :       return true;
     220             : 
     221        1281 :     case DW_FORM_udata:
     222             :     case DW_FORM_ref_udata:
     223             :     case DW_FORM_strx:
     224             :     case DW_FORM_addrx:
     225             :     case DW_FORM_loclistx:
     226             :     case DW_FORM_rnglistx:
     227             :     case DW_FORM_GNU_addr_index:
     228             :     case DW_FORM_GNU_str_index:
     229        1281 :       DebugInfoData.getULEB128(OffsetPtr);
     230        1281 :       return true;
     231             : 
     232           0 :     case DW_FORM_indirect:
     233           0 :       Indirect = true;
     234           0 :       Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
     235             :       break;
     236             : 
     237             :     default:
     238             :       return false;
     239             :     }
     240             :   } while (Indirect);
     241             :   return true;
     242             : }
     243             : 
     244      795270 : bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
     245             :   // First, check DWARF4 form classes.
     246     2384490 :   if (Form < makeArrayRef(DWARF4FormClasses).size() &&
     247      793950 :       DWARF4FormClasses[Form] == FC)
     248             :     return true;
     249             :   // Check more forms from DWARF4 and DWARF5 proposals.
     250      219730 :   switch (Form) {
     251         117 :   case DW_FORM_ref_sig8:
     252             :   case DW_FORM_GNU_ref_alt:
     253         117 :     return (FC == FC_Reference);
     254         108 :   case DW_FORM_GNU_addr_index:
     255         108 :     return (FC == FC_Address);
     256        1086 :   case DW_FORM_GNU_str_index:
     257             :   case DW_FORM_GNU_strp_alt:
     258             :   case DW_FORM_strx:
     259             :   case DW_FORM_strx1:
     260             :   case DW_FORM_strx2:
     261             :   case DW_FORM_strx3:
     262             :   case DW_FORM_strx4:
     263        1086 :     return (FC == FC_String);
     264           7 :   case DW_FORM_implicit_const:
     265           7 :     return (FC == FC_Constant);
     266             :   default:
     267             :     break;
     268             :   }
     269             :   // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
     270             :   // Don't check for DWARF version here, as some producers may still do this
     271             :   // by mistake. Also accept DW_FORM_strp since this is .debug_str section
     272             :   // offset.
     273      218412 :   return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
     274      218412 :           Form == DW_FORM_strp) &&
     275             :          FC == FC_SectionOffset;
     276             : }
     277             : 
     278      578389 : bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
     279             :                                   uint32_t *OffsetPtr, const DWARFUnit *CU) {
     280      578389 :   U = CU;
     281      578389 :   bool Indirect = false;
     282      578389 :   bool IsBlock = false;
     283      578389 :   Value.data = nullptr;
     284             :   // Read the value for the form into value and follow and DW_FORM_indirect
     285             :   // instances we run into
     286             :   do {
     287      578389 :     Indirect = false;
     288      578389 :     switch (Form) {
     289      239291 :     case DW_FORM_addr:
     290             :     case DW_FORM_ref_addr: {
     291      239291 :       if (!U)
     292             :         return false;
     293      239699 :       uint16_t Size = (Form == DW_FORM_addr) ? U->getAddressByteSize()
     294      240107 :                                              : U->getRefAddrByteSize();
     295      239291 :       Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
     296             :       break;
     297             :     }
     298         850 :     case DW_FORM_exprloc:
     299             :     case DW_FORM_block:
     300         850 :       Value.uval = Data.getULEB128(OffsetPtr);
     301         850 :       IsBlock = true;
     302             :       break;
     303        1212 :     case DW_FORM_block1:
     304        1212 :       Value.uval = Data.getU8(OffsetPtr);
     305        1212 :       IsBlock = true;
     306             :       break;
     307           9 :     case DW_FORM_block2:
     308           9 :       Value.uval = Data.getU16(OffsetPtr);
     309           9 :       IsBlock = true;
     310             :       break;
     311           9 :     case DW_FORM_block4:
     312           9 :       Value.uval = Data.getU32(OffsetPtr);
     313           9 :       IsBlock = true;
     314             :       break;
     315       10742 :     case DW_FORM_data1:
     316             :     case DW_FORM_ref1:
     317             :     case DW_FORM_flag:
     318             :     case DW_FORM_strx1:
     319             :     case DW_FORM_addrx1:
     320       10742 :       Value.uval = Data.getU8(OffsetPtr);
     321             :       break;
     322        1292 :     case DW_FORM_data2:
     323             :     case DW_FORM_ref2:
     324             :     case DW_FORM_strx2:
     325             :     case DW_FORM_addrx2:
     326        1292 :       Value.uval = Data.getU16(OffsetPtr);
     327             :       break;
     328           2 :     case DW_FORM_strx3:
     329           2 :       Value.uval = Data.getU24(OffsetPtr);
     330             :       break;
     331        9038 :     case DW_FORM_data4:
     332             :     case DW_FORM_ref4:
     333             :     case DW_FORM_ref_sup4:
     334             :     case DW_FORM_strx4:
     335             :     case DW_FORM_addrx4:
     336        9038 :       Value.uval = Data.getRelocatedValue(4, OffsetPtr);
     337             :       break;
     338      184529 :     case DW_FORM_data8:
     339             :     case DW_FORM_ref8:
     340             :     case DW_FORM_ref_sup8:
     341      184529 :       Value.uval = Data.getU64(OffsetPtr);
     342             :       break;
     343          67 :     case DW_FORM_sdata:
     344          67 :       Value.sval = Data.getSLEB128(OffsetPtr);
     345             :       break;
     346         383 :     case DW_FORM_udata:
     347             :     case DW_FORM_ref_udata:
     348         383 :       Value.uval = Data.getULEB128(OffsetPtr);
     349             :       break;
     350         144 :     case DW_FORM_string:
     351         144 :       Value.cstr = Data.getCStr(OffsetPtr);
     352             :       break;
     353           0 :     case DW_FORM_indirect:
     354           0 :       Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr));
     355           0 :       Indirect = true;
     356             :       break;
     357      128939 :     case DW_FORM_strp:
     358             :     case DW_FORM_sec_offset:
     359             :     case DW_FORM_GNU_ref_alt:
     360             :     case DW_FORM_GNU_strp_alt:
     361             :     case DW_FORM_line_strp:
     362             :     case DW_FORM_strp_sup: {
     363      128939 :       if (!U)
     364             :         return false;
     365      128939 :       Value.uval =
     366      257878 :           Data.getRelocatedValue(U->getDwarfOffsetByteSize(), OffsetPtr);
     367             :       break;
     368             :     }
     369        1361 :     case DW_FORM_flag_present:
     370        1361 :       Value.uval = 1;
     371             :       break;
     372          56 :     case DW_FORM_ref_sig8:
     373          56 :       Value.uval = Data.getU64(OffsetPtr);
     374             :       break;
     375         465 :     case DW_FORM_GNU_addr_index:
     376             :     case DW_FORM_GNU_str_index:
     377             :     case DW_FORM_strx:
     378         465 :       Value.uval = Data.getULEB128(OffsetPtr);
     379             :       break;
     380           0 :     default:
     381             :       // DWARFFormValue::skipValue() will have caught this and caused all
     382             :       // DWARF DIEs to fail to be parsed, so this code is not be reachable.
     383           0 :       llvm_unreachable("unsupported form");
     384             :     }
     385             :   } while (Indirect);
     386             : 
     387      578389 :   if (IsBlock) {
     388        4160 :     StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
     389        2080 :     Value.data = nullptr;
     390        2080 :     if (!Str.empty()) {
     391        2080 :       Value.data = reinterpret_cast<const uint8_t *>(Str.data());
     392        2080 :       *OffsetPtr += Value.uval;
     393             :     }
     394             :   }
     395             : 
     396             :   return true;
     397             : }
     398             : 
     399       15382 : void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
     400       15382 :   uint64_t UValue = Value.uval;
     401       15382 :   bool CURelativeOffset = false;
     402             : 
     403       15382 :   switch (Form) {
     404        1528 :   case DW_FORM_addr:
     405        3056 :     OS << format("0x%016" PRIx64, UValue);
     406             :     break;
     407          37 :   case DW_FORM_GNU_addr_index: {
     408          74 :     OS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
     409             :     uint64_t Address;
     410          37 :     if (U == nullptr)
     411           0 :       OS << "<invalid dwarf unit>";
     412          37 :     else if (U->getAddrOffsetSectionItem(UValue, Address))
     413          52 :       OS << format("0x%016" PRIx64, Address);
     414             :     else
     415          11 :       OS << "<no .debug_addr section>";
     416             :     break;
     417             :   }
     418        1265 :   case DW_FORM_flag_present:
     419        1265 :     OS << "true";
     420             :     break;
     421        2211 :   case DW_FORM_flag:
     422             :   case DW_FORM_data1:
     423        4422 :     OS << format("0x%02x", (uint8_t)UValue);
     424             :     break;
     425         137 :   case DW_FORM_data2:
     426         274 :     OS << format("0x%04x", (uint16_t)UValue);
     427             :     break;
     428        1261 :   case DW_FORM_data4:
     429        2522 :     OS << format("0x%08x", (uint32_t)UValue);
     430             :     break;
     431         133 :   case DW_FORM_ref_sig8:
     432             :   case DW_FORM_data8:
     433         266 :     OS << format("0x%016" PRIx64, UValue);
     434             :     break;
     435          87 :   case DW_FORM_string:
     436          87 :     OS << '"';
     437         174 :     OS.write_escaped(Value.cstr);
     438             :     OS << '"';
     439             :     break;
     440           7 :   case DW_FORM_exprloc:
     441             :   case DW_FORM_block:
     442             :   case DW_FORM_block1:
     443             :   case DW_FORM_block2:
     444             :   case DW_FORM_block4:
     445           7 :     if (UValue > 0) {
     446           7 :       switch (Form) {
     447           4 :       case DW_FORM_exprloc:
     448             :       case DW_FORM_block:
     449           8 :         OS << format("<0x%" PRIx64 "> ", UValue);
     450           4 :         break;
     451           3 :       case DW_FORM_block1:
     452           6 :         OS << format("<0x%2.2x> ", (uint8_t)UValue);
     453           3 :         break;
     454           0 :       case DW_FORM_block2:
     455           0 :         OS << format("<0x%4.4x> ", (uint16_t)UValue);
     456           0 :         break;
     457           0 :       case DW_FORM_block4:
     458           0 :         OS << format("<0x%8.8x> ", (uint32_t)UValue);
     459           0 :         break;
     460             :       default:
     461             :         break;
     462             :       }
     463             : 
     464           7 :       const uint8_t *DataPtr = Value.data;
     465           7 :       if (DataPtr) {
     466             :         // UValue contains size of block
     467           7 :         const uint8_t *EndDataPtr = DataPtr + UValue;
     468          35 :         while (DataPtr < EndDataPtr) {
     469          14 :           OS << format("%2.2x ", *DataPtr);
     470          14 :           ++DataPtr;
     471             :         }
     472             :       } else
     473           0 :         OS << "NULL";
     474             :     }
     475             :     break;
     476             : 
     477          54 :   case DW_FORM_sdata:
     478          54 :     OS << Value.sval;
     479             :     break;
     480         359 :   case DW_FORM_udata:
     481         359 :     OS << Value.uval;
     482             :     break;
     483        4487 :   case DW_FORM_strp:
     484        4487 :     if (DumpOpts.Verbose)
     485        7166 :       OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
     486        4487 :     dumpString(OS);
     487             :     break;
     488         339 :   case DW_FORM_strx:
     489             :   case DW_FORM_strx1:
     490             :   case DW_FORM_strx2:
     491             :   case DW_FORM_strx3:
     492             :   case DW_FORM_strx4:
     493             :   case DW_FORM_GNU_str_index:
     494         678 :     OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
     495         339 :     dumpString(OS);
     496             :     break;
     497           0 :   case DW_FORM_GNU_strp_alt:
     498           0 :     OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
     499           0 :     dumpString(OS);
     500             :     break;
     501         209 :   case DW_FORM_ref_addr:
     502         418 :     OS << format("0x%016" PRIx64, UValue);
     503             :     break;
     504           0 :   case DW_FORM_ref1:
     505           0 :     CURelativeOffset = true;
     506           0 :     OS << format("cu + 0x%2.2x", (uint8_t)UValue);
     507             :     break;
     508           0 :   case DW_FORM_ref2:
     509           0 :     CURelativeOffset = true;
     510           0 :     OS << format("cu + 0x%4.4x", (uint16_t)UValue);
     511             :     break;
     512        2776 :   case DW_FORM_ref4:
     513        2776 :     CURelativeOffset = true;
     514        5552 :     OS << format("cu + 0x%4.4x", (uint32_t)UValue);
     515             :     break;
     516           0 :   case DW_FORM_ref8:
     517           0 :     CURelativeOffset = true;
     518           0 :     OS << format("cu + 0x%8.8" PRIx64, UValue);
     519             :     break;
     520           0 :   case DW_FORM_ref_udata:
     521           0 :     CURelativeOffset = true;
     522           0 :     OS << format("cu + 0x%" PRIx64, UValue);
     523             :     break;
     524           0 :   case DW_FORM_GNU_ref_alt:
     525           0 :     OS << format("<alt 0x%" PRIx64 ">", UValue);
     526             :     break;
     527             : 
     528             :   // All DW_FORM_indirect attributes should be resolved prior to calling
     529             :   // this function
     530           0 :   case DW_FORM_indirect:
     531           0 :     OS << "DW_FORM_indirect";
     532             :     break;
     533             : 
     534             :   // Should be formatted to 64-bit for DWARF64.
     535         492 :   case DW_FORM_sec_offset:
     536         984 :     OS << format("0x%08x", (uint32_t)UValue);
     537             :     break;
     538             : 
     539           0 :   default:
     540           0 :     OS << format("DW_FORM(0x%4.4x)", Form);
     541             :     break;
     542             :   }
     543             : 
     544        2776 :   if (CURelativeOffset && DumpOpts.Verbose) {
     545        2335 :     OS << " => {";
     546        7005 :     WithColor(OS, syntax::Address).get()
     547        4670 :         << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
     548        2335 :     OS << "}";
     549             :   }
     550       15382 : }
     551             : 
     552        4826 : void DWARFFormValue::dumpString(raw_ostream &OS) const {
     553        9652 :   Optional<const char *> DbgStr = getAsCString();
     554        4826 :   if (DbgStr.hasValue()) {
     555        9624 :     raw_ostream &COS = WithColor(OS, syntax::String);
     556        4812 :     COS << '"';
     557        9624 :     COS.write_escaped(DbgStr.getValue());
     558             :     COS << '"';
     559             :   }
     560        4826 : }
     561             : 
     562       11487 : Optional<const char *> DWARFFormValue::getAsCString() const {
     563       11487 :   if (!isFormClass(FC_String))
     564             :     return None;
     565       11477 :   if (Form == DW_FORM_string)
     566          57 :     return Value.cstr;
     567             :   // FIXME: Add support for DW_FORM_GNU_strp_alt
     568       11420 :   if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
     569             :     return None;
     570       11420 :   uint32_t Offset = Value.uval;
     571       11420 :   if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
     572       11023 :       Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
     573             :       Form == DW_FORM_strx4) {
     574             :     uint64_t StrOffset;
     575         404 :     if (!U->getStringOffsetSectionItem(Offset, StrOffset))
     576           1 :       return None;
     577         403 :     Offset = StrOffset;
     578             :   }
     579       22838 :   if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
     580       11405 :     return Str;
     581             :   }
     582             :   return None;
     583             : }
     584             : 
     585      422585 : Optional<uint64_t> DWARFFormValue::getAsAddress() const {
     586      422585 :   if (!isFormClass(FC_Address))
     587             :     return None;
     588      237338 :   if (Form == DW_FORM_GNU_addr_index) {
     589          33 :     uint32_t Index = Value.uval;
     590             :     uint64_t Result;
     591          33 :     if (!U || !U->getAddrOffsetSectionItem(Index, Result))
     592             :       return None;
     593             :     return Result;
     594             :   }
     595      237305 :   return Value.uval;
     596             : }
     597             : 
     598        3263 : Optional<uint64_t> DWARFFormValue::getAsReference() const {
     599        3263 :   if (!isFormClass(FC_Reference))
     600             :     return None;
     601        3255 :   switch (Form) {
     602        2986 :   case DW_FORM_ref1:
     603             :   case DW_FORM_ref2:
     604             :   case DW_FORM_ref4:
     605             :   case DW_FORM_ref8:
     606             :   case DW_FORM_ref_udata:
     607        2986 :     if (!U)
     608             :       return None;
     609        5972 :     return Value.uval + U->getOffset();
     610         269 :   case DW_FORM_ref_addr:
     611             :   case DW_FORM_ref_sig8:
     612             :   case DW_FORM_GNU_ref_alt:
     613         269 :     return Value.uval;
     614           0 :   default:
     615             :     return None;
     616             :   }
     617             : }
     618             : 
     619      118921 : Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
     620      118921 :   if (!isFormClass(FC_SectionOffset))
     621             :     return None;
     622      118908 :   return Value.uval;
     623             : }
     624             : 
     625      213765 : Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
     626      415916 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     627      202151 :       Form == DW_FORM_sdata)
     628             :     return None;
     629      202096 :   return Value.uval;
     630             : }
     631             : 
     632          39 : Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
     633          72 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     634          39 :       (Form == DW_FORM_udata &&
     635           6 :        uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
     636             :     return None;
     637          32 :   switch (Form) {
     638           2 :   case DW_FORM_data4:
     639           4 :     return int32_t(Value.uval);
     640           2 :   case DW_FORM_data2:
     641           4 :     return int16_t(Value.uval);
     642           2 :   case DW_FORM_data1:
     643           4 :     return int8_t(Value.uval);
     644          26 :   case DW_FORM_sdata:
     645             :   case DW_FORM_data8:
     646             :   default:
     647          26 :     return Value.sval;
     648             :   }
     649             : }
     650             : 
     651        1990 : Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
     652        1990 :   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
     653             :     return None;
     654        5958 :   return makeArrayRef(Value.data, Value.uval);
     655             : }
     656             : 
     657          30 : Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
     658          30 :   if (!isFormClass(FC_String) && Form == DW_FORM_string)
     659             :     return None;
     660          30 :   return Value.uval;
     661             : }
     662             : 
     663          22 : Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
     664          22 :   if (!isFormClass(FC_Reference))
     665             :     return None;
     666          22 :   return Value.uval;
     667             : }

Generated by: LCOV version 1.13