LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFFormValue.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 253 296 85.5 %
Date: 2018-09-23 13:06:45 Functions: 14 14 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 "llvm/ADT/ArrayRef.h"
      12             : #include "llvm/ADT/None.h"
      13             : #include "llvm/ADT/Optional.h"
      14             : #include "llvm/ADT/StringRef.h"
      15             : #include "llvm/BinaryFormat/Dwarf.h"
      16             : #include "llvm/DebugInfo/DWARF/DWARFContext.h"
      17             : #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
      18             : #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
      19             : #include "llvm/Support/ErrorHandling.h"
      20             : #include "llvm/Support/Format.h"
      21             : #include "llvm/Support/WithColor.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             : 
      30             : static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
      31             :     DWARFFormValue::FC_Unknown,  // 0x0
      32             :     DWARFFormValue::FC_Address,  // 0x01 DW_FORM_addr
      33             :     DWARFFormValue::FC_Unknown,  // 0x02 unused
      34             :     DWARFFormValue::FC_Block,    // 0x03 DW_FORM_block2
      35             :     DWARFFormValue::FC_Block,    // 0x04 DW_FORM_block4
      36             :     DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
      37             :     // --- These can be FC_SectionOffset in DWARF3 and below:
      38             :     DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
      39             :     DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
      40             :     // ---
      41             :     DWARFFormValue::FC_String,        // 0x08 DW_FORM_string
      42             :     DWARFFormValue::FC_Block,         // 0x09 DW_FORM_block
      43             :     DWARFFormValue::FC_Block,         // 0x0a DW_FORM_block1
      44             :     DWARFFormValue::FC_Constant,      // 0x0b DW_FORM_data1
      45             :     DWARFFormValue::FC_Flag,          // 0x0c DW_FORM_flag
      46             :     DWARFFormValue::FC_Constant,      // 0x0d DW_FORM_sdata
      47             :     DWARFFormValue::FC_String,        // 0x0e DW_FORM_strp
      48             :     DWARFFormValue::FC_Constant,      // 0x0f DW_FORM_udata
      49             :     DWARFFormValue::FC_Reference,     // 0x10 DW_FORM_ref_addr
      50             :     DWARFFormValue::FC_Reference,     // 0x11 DW_FORM_ref1
      51             :     DWARFFormValue::FC_Reference,     // 0x12 DW_FORM_ref2
      52             :     DWARFFormValue::FC_Reference,     // 0x13 DW_FORM_ref4
      53             :     DWARFFormValue::FC_Reference,     // 0x14 DW_FORM_ref8
      54             :     DWARFFormValue::FC_Reference,     // 0x15 DW_FORM_ref_udata
      55             :     DWARFFormValue::FC_Indirect,      // 0x16 DW_FORM_indirect
      56             :     DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
      57             :     DWARFFormValue::FC_Exprloc,       // 0x18 DW_FORM_exprloc
      58             :     DWARFFormValue::FC_Flag,          // 0x19 DW_FORM_flag_present
      59             :     DWARFFormValue::FC_String,        // 0x1a DW_FORM_strx
      60             :     DWARFFormValue::FC_Address,       // 0x1b DW_FORM_addrx
      61             :     DWARFFormValue::FC_Reference,     // 0x1c DW_FORM_ref_sup4
      62             :     DWARFFormValue::FC_String,        // 0x1d DW_FORM_strp_sup
      63             :     DWARFFormValue::FC_Constant,      // 0x1e DW_FORM_data16
      64             :     DWARFFormValue::FC_String,        // 0x1f DW_FORM_line_strp
      65             :     DWARFFormValue::FC_Reference,     // 0x20 DW_FORM_ref_sig8
      66             :     DWARFFormValue::FC_Constant,      // 0x21 DW_FORM_implicit_const
      67             :     DWARFFormValue::FC_SectionOffset, // 0x22 DW_FORM_loclistx
      68             :     DWARFFormValue::FC_SectionOffset, // 0x23 DW_FORM_rnglistx
      69             :     DWARFFormValue::FC_Reference,     // 0x24 DW_FORM_ref_sup8
      70             :     DWARFFormValue::FC_String,        // 0x25 DW_FORM_strx1
      71             :     DWARFFormValue::FC_String,        // 0x26 DW_FORM_strx2
      72             :     DWARFFormValue::FC_String,        // 0x27 DW_FORM_strx3
      73             :     DWARFFormValue::FC_String,        // 0x28 DW_FORM_strx4
      74             :     DWARFFormValue::FC_Address,       // 0x29 DW_FORM_addrx1
      75             :     DWARFFormValue::FC_Address,       // 0x2a DW_FORM_addrx2
      76             :     DWARFFormValue::FC_Address,       // 0x2b DW_FORM_addrx3
      77             :     DWARFFormValue::FC_Address,       // 0x2c DW_FORM_addrx4
      78             : 
      79             : };
      80             : 
      81       19642 : bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
      82             :                                uint32_t *OffsetPtr,
      83             :                                const dwarf::FormParams Params) {
      84             :   bool Indirect = false;
      85             :   do {
      86       19642 :     switch (Form) {
      87             :     // Blocks of inlined data that have a length field and the data bytes
      88             :     // inlined in the .debug_info.
      89        4442 :     case DW_FORM_exprloc:
      90             :     case DW_FORM_block: {
      91        4442 :       uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
      92        4442 :       *OffsetPtr += size;
      93        4442 :       return true;
      94             :     }
      95        3475 :     case DW_FORM_block1: {
      96        3475 :       uint8_t size = DebugInfoData.getU8(OffsetPtr);
      97        3475 :       *OffsetPtr += size;
      98        3475 :       return true;
      99             :     }
     100         209 :     case DW_FORM_block2: {
     101         209 :       uint16_t size = DebugInfoData.getU16(OffsetPtr);
     102         209 :       *OffsetPtr += size;
     103         209 :       return true;
     104             :     }
     105         200 :     case DW_FORM_block4: {
     106         200 :       uint32_t size = DebugInfoData.getU32(OffsetPtr);
     107         200 :       *OffsetPtr += size;
     108         200 :       return true;
     109             :     }
     110             : 
     111             :     // Inlined NULL terminated C-strings.
     112         566 :     case DW_FORM_string:
     113         566 :       DebugInfoData.getCStr(OffsetPtr);
     114         566 :       return true;
     115             : 
     116        8510 :     case DW_FORM_addr:
     117             :     case DW_FORM_ref_addr:
     118             :     case DW_FORM_flag_present:
     119             :     case DW_FORM_data1:
     120             :     case DW_FORM_data2:
     121             :     case DW_FORM_data4:
     122             :     case DW_FORM_data8:
     123             :     case DW_FORM_data16:
     124             :     case DW_FORM_flag:
     125             :     case DW_FORM_ref1:
     126             :     case DW_FORM_ref2:
     127             :     case DW_FORM_ref4:
     128             :     case DW_FORM_ref8:
     129             :     case DW_FORM_ref_sig8:
     130             :     case DW_FORM_ref_sup4:
     131             :     case DW_FORM_ref_sup8:
     132             :     case DW_FORM_strx1:
     133             :     case DW_FORM_strx2:
     134             :     case DW_FORM_strx4:
     135             :     case DW_FORM_addrx1:
     136             :     case DW_FORM_addrx2:
     137             :     case DW_FORM_addrx4:
     138             :     case DW_FORM_sec_offset:
     139             :     case DW_FORM_strp:
     140             :     case DW_FORM_strp_sup:
     141             :     case DW_FORM_line_strp:
     142             :     case DW_FORM_GNU_ref_alt:
     143             :     case DW_FORM_GNU_strp_alt:
     144        8510 :       if (Optional<uint8_t> FixedSize =
     145        8510 :               dwarf::getFixedFormByteSize(Form, Params)) {
     146        8509 :         *OffsetPtr += *FixedSize;
     147             :         return true;
     148        8509 :       }
     149           1 :       return false;
     150             : 
     151             :     // signed or unsigned LEB 128 values.
     152         411 :     case DW_FORM_sdata:
     153         411 :       DebugInfoData.getSLEB128(OffsetPtr);
     154         411 :       return true;
     155             : 
     156        1829 :     case DW_FORM_udata:
     157             :     case DW_FORM_ref_udata:
     158             :     case DW_FORM_strx:
     159             :     case DW_FORM_addrx:
     160             :     case DW_FORM_loclistx:
     161             :     case DW_FORM_rnglistx:
     162             :     case DW_FORM_GNU_addr_index:
     163             :     case DW_FORM_GNU_str_index:
     164        1829 :       DebugInfoData.getULEB128(OffsetPtr);
     165        1829 :       return true;
     166             : 
     167           0 :     case DW_FORM_indirect:
     168             :       Indirect = true;
     169           0 :       Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
     170             :       break;
     171             : 
     172             :     default:
     173             :       return false;
     174             :     }
     175             :   } while (Indirect);
     176             :   return true;
     177             : }
     178             : 
     179      119834 : bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
     180             :   // First, check DWARF5 form classes.
     181      119834 :   if (Form < makeArrayRef(DWARF5FormClasses).size() &&
     182      118249 :       DWARF5FormClasses[Form] == FC)
     183       72174 :     return true;
     184             :   // Check more forms from extensions and proposals.
     185       47660 :   switch (Form) {
     186           9 :   case DW_FORM_GNU_ref_alt:
     187           9 :     return (FC == FC_Reference);
     188         174 :   case DW_FORM_GNU_addr_index:
     189         174 :     return (FC == FC_Address);
     190        1400 :   case DW_FORM_GNU_str_index:
     191             :   case DW_FORM_GNU_strp_alt:
     192        1400 :     return (FC == FC_String);
     193             :   default:
     194             :     break;
     195             :   }
     196             :   // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
     197             :   // Don't check for DWARF version here, as some producers may still do this
     198             :   // by mistake. Also accept DW_FORM_[line_]strp since these are
     199             :   // .debug_[line_]str section offsets.
     200       46077 :   return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
     201       46077 :           Form == DW_FORM_strp || Form == DW_FORM_line_strp) &&
     202             :          FC == FC_SectionOffset;
     203             : }
     204             : 
     205       72332 : bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
     206             :                                   uint32_t *OffsetPtr, dwarf::FormParams FP,
     207             :                                   const DWARFContext *Ctx,
     208             :                                   const DWARFUnit *CU) {
     209       72332 :   if (!Ctx && CU)
     210       68274 :     Ctx = &CU->getContext();
     211       72332 :   C = Ctx;
     212       72332 :   U = CU;
     213             :   bool Indirect = false;
     214             :   bool IsBlock = false;
     215       72332 :   Value.data = nullptr;
     216             :   // Read the value for the form into value and follow and DW_FORM_indirect
     217             :   // instances we run into
     218             :   do {
     219             :     Indirect = false;
     220       72332 :     switch (Form) {
     221        8885 :     case DW_FORM_addr:
     222             :     case DW_FORM_ref_addr: {
     223             :       uint16_t Size =
     224        9663 :           (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
     225        8885 :       Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
     226             :       break;
     227             :     }
     228        1622 :     case DW_FORM_exprloc:
     229             :     case DW_FORM_block:
     230        1622 :       Value.uval = Data.getULEB128(OffsetPtr);
     231             :       IsBlock = true;
     232             :       break;
     233        1528 :     case DW_FORM_block1:
     234        1528 :       Value.uval = Data.getU8(OffsetPtr);
     235             :       IsBlock = true;
     236             :       break;
     237           9 :     case DW_FORM_block2:
     238           9 :       Value.uval = Data.getU16(OffsetPtr);
     239             :       IsBlock = true;
     240             :       break;
     241           9 :     case DW_FORM_block4:
     242           9 :       Value.uval = Data.getU32(OffsetPtr);
     243             :       IsBlock = true;
     244             :       break;
     245       14492 :     case DW_FORM_data1:
     246             :     case DW_FORM_ref1:
     247             :     case DW_FORM_flag:
     248             :     case DW_FORM_strx1:
     249             :     case DW_FORM_addrx1:
     250       14492 :       Value.uval = Data.getU8(OffsetPtr);
     251             :       break;
     252        2318 :     case DW_FORM_data2:
     253             :     case DW_FORM_ref2:
     254             :     case DW_FORM_strx2:
     255             :     case DW_FORM_addrx2:
     256        2318 :       Value.uval = Data.getU16(OffsetPtr);
     257             :       break;
     258           4 :     case DW_FORM_strx3:
     259           4 :       Value.uval = Data.getU24(OffsetPtr);
     260             :       break;
     261       16534 :     case DW_FORM_data4:
     262             :     case DW_FORM_ref4:
     263             :     case DW_FORM_ref_sup4:
     264             :     case DW_FORM_strx4:
     265             :     case DW_FORM_addrx4:
     266       16534 :       Value.uval = Data.getRelocatedValue(4, OffsetPtr);
     267             :       break;
     268         395 :     case DW_FORM_data8:
     269             :     case DW_FORM_ref8:
     270             :     case DW_FORM_ref_sup8:
     271         395 :       Value.uval = Data.getU64(OffsetPtr);
     272             :       break;
     273          70 :     case DW_FORM_data16:
     274             :       // Treat this like a 16-byte block.
     275          70 :       Value.uval = 16;
     276             :       IsBlock = true;
     277             :       break;
     278         368 :     case DW_FORM_sdata:
     279         368 :       Value.sval = Data.getSLEB128(OffsetPtr);
     280             :       break;
     281         570 :     case DW_FORM_udata:
     282             :     case DW_FORM_ref_udata:
     283             :     case DW_FORM_rnglistx:
     284         570 :       Value.uval = Data.getULEB128(OffsetPtr);
     285             :       break;
     286         233 :     case DW_FORM_string:
     287         233 :       Value.cstr = Data.getCStr(OffsetPtr);
     288             :       break;
     289           0 :     case DW_FORM_indirect:
     290           0 :       Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr));
     291             :       Indirect = true;
     292             :       break;
     293       22467 :     case DW_FORM_strp:
     294             :     case DW_FORM_sec_offset:
     295             :     case DW_FORM_GNU_ref_alt:
     296             :     case DW_FORM_GNU_strp_alt:
     297             :     case DW_FORM_line_strp:
     298             :     case DW_FORM_strp_sup: {
     299       22467 :       Value.uval =
     300       22467 :           Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
     301             :       break;
     302             :     }
     303        2013 :     case DW_FORM_flag_present:
     304        2013 :       Value.uval = 1;
     305             :       break;
     306          69 :     case DW_FORM_ref_sig8:
     307          69 :       Value.uval = Data.getU64(OffsetPtr);
     308             :       break;
     309         746 :     case DW_FORM_GNU_addr_index:
     310             :     case DW_FORM_GNU_str_index:
     311             :     case DW_FORM_strx:
     312         746 :       Value.uval = Data.getULEB128(OffsetPtr);
     313             :       break;
     314           0 :     default:
     315             :       // DWARFFormValue::skipValue() will have caught this and caused all
     316             :       // DWARF DIEs to fail to be parsed, so this code is not be reachable.
     317           0 :       llvm_unreachable("unsupported form");
     318             :     }
     319             :   } while (Indirect);
     320             : 
     321       72332 :   if (IsBlock) {
     322        3238 :     StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
     323        3238 :     Value.data = nullptr;
     324        3238 :     if (!Str.empty()) {
     325        3237 :       Value.data = reinterpret_cast<const uint8_t *>(Str.data());
     326        3237 :       *OffsetPtr += Value.uval;
     327             :     }
     328             :   }
     329             : 
     330       72332 :   return true;
     331             : }
     332             : 
     333       20867 : void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
     334       20867 :   uint64_t UValue = Value.uval;
     335             :   bool CURelativeOffset = false;
     336       20867 :   raw_ostream &AddrOS = DumpOpts.ShowAddresses
     337       20867 :                             ? WithColor(OS, HighlightColor::Address).get()
     338          66 :                             : nulls();
     339       20867 :   switch (Form) {
     340        1824 :   case DW_FORM_addr:
     341        1824 :     AddrOS << format("0x%016" PRIx64, UValue);
     342             :     break;
     343          62 :   case DW_FORM_GNU_addr_index: {
     344         124 :     AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
     345             :     uint64_t Address;
     346          62 :     if (U == nullptr)
     347           0 :       OS << "<invalid dwarf unit>";
     348          62 :     else if (U->getAddrOffsetSectionItem(UValue, Address))
     349          96 :       AddrOS << format("0x%016" PRIx64, Address);
     350             :     else
     351          14 :       OS << "<no .debug_addr section>";
     352             :     break;
     353             :   }
     354        1737 :   case DW_FORM_flag_present:
     355        1737 :     OS << "true";
     356             :     break;
     357        2593 :   case DW_FORM_flag:
     358             :   case DW_FORM_data1:
     359        5186 :     OS << format("0x%02x", (uint8_t)UValue);
     360             :     break;
     361         514 :   case DW_FORM_data2:
     362        1028 :     OS << format("0x%04x", (uint16_t)UValue);
     363             :     break;
     364        1739 :   case DW_FORM_data4:
     365        3478 :     OS << format("0x%08x", (uint32_t)UValue);
     366             :     break;
     367          58 :   case DW_FORM_ref_sig8:
     368          58 :     AddrOS << format("0x%016" PRIx64, UValue);
     369             :     break;
     370         101 :   case DW_FORM_data8:
     371         101 :     OS << format("0x%016" PRIx64, UValue);
     372             :     break;
     373             :   case DW_FORM_data16:
     374           2 :     OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16);
     375             :     break;
     376             :   case DW_FORM_string:
     377             :     OS << '"';
     378        1060 :     OS.write_escaped(Value.cstr);
     379             :     OS << '"';
     380             :     break;
     381           7 :   case DW_FORM_exprloc:
     382             :   case DW_FORM_block:
     383             :   case DW_FORM_block1:
     384             :   case DW_FORM_block2:
     385             :   case DW_FORM_block4:
     386           7 :     if (UValue > 0) {
     387             :       switch (Form) {
     388           4 :       case DW_FORM_exprloc:
     389             :       case DW_FORM_block:
     390           4 :         AddrOS << format("<0x%" PRIx64 "> ", UValue);
     391           4 :         break;
     392           3 :       case DW_FORM_block1:
     393           6 :         AddrOS << format("<0x%2.2x> ", (uint8_t)UValue);
     394           3 :         break;
     395           0 :       case DW_FORM_block2:
     396           0 :         AddrOS << format("<0x%4.4x> ", (uint16_t)UValue);
     397           0 :         break;
     398           0 :       case DW_FORM_block4:
     399           0 :         AddrOS << format("<0x%8.8x> ", (uint32_t)UValue);
     400           0 :         break;
     401             :       default:
     402             :         break;
     403             :       }
     404             : 
     405           7 :       const uint8_t *DataPtr = Value.data;
     406           7 :       if (DataPtr) {
     407             :         // UValue contains size of block
     408           7 :         const uint8_t *EndDataPtr = DataPtr + UValue;
     409          21 :         while (DataPtr < EndDataPtr) {
     410          14 :           AddrOS << format("%2.2x ", *DataPtr);
     411          14 :           ++DataPtr;
     412             :         }
     413             :       } else
     414           0 :         OS << "NULL";
     415             :     }
     416             :     break;
     417             : 
     418         354 :   case DW_FORM_sdata:
     419         354 :     OS << Value.sval;
     420             :     break;
     421         399 :   case DW_FORM_udata:
     422         399 :     OS << Value.uval;
     423             :     break;
     424        5410 :   case DW_FORM_strp:
     425        5410 :     if (DumpOpts.Verbose)
     426        6600 :       OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
     427        5410 :     dumpString(OS);
     428             :     break;
     429         118 :   case DW_FORM_line_strp:
     430         118 :     if (DumpOpts.Verbose)
     431         184 :       OS << format(" .debug_line_str[0x%8.8x] = ", (uint32_t)UValue);
     432         118 :     dumpString(OS);
     433             :     break;
     434         898 :   case DW_FORM_strx:
     435             :   case DW_FORM_strx1:
     436             :   case DW_FORM_strx2:
     437             :   case DW_FORM_strx3:
     438             :   case DW_FORM_strx4:
     439             :   case DW_FORM_GNU_str_index:
     440         898 :     if (DumpOpts.Verbose)
     441        1640 :       OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
     442         898 :     dumpString(OS);
     443             :     break;
     444           0 :   case DW_FORM_GNU_strp_alt:
     445           0 :     if (DumpOpts.Verbose)
     446           0 :       OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
     447           0 :     dumpString(OS);
     448             :     break;
     449         224 :   case DW_FORM_ref_addr:
     450         224 :     AddrOS << format("0x%016" PRIx64, UValue);
     451             :     break;
     452           0 :   case DW_FORM_ref1:
     453             :     CURelativeOffset = true;
     454           0 :     if (DumpOpts.Verbose)
     455           0 :       AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue);
     456             :     break;
     457           0 :   case DW_FORM_ref2:
     458             :     CURelativeOffset = true;
     459           0 :     if (DumpOpts.Verbose)
     460           0 :       AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue);
     461             :     break;
     462        3611 :   case DW_FORM_ref4:
     463             :     CURelativeOffset = true;
     464        3611 :     if (DumpOpts.Verbose)
     465        4380 :       AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue);
     466             :     break;
     467           0 :   case DW_FORM_ref8:
     468             :     CURelativeOffset = true;
     469           0 :     if (DumpOpts.Verbose)
     470           0 :       AddrOS << format("cu + 0x%8.8" PRIx64, UValue);
     471             :     break;
     472           0 :   case DW_FORM_ref_udata:
     473             :     CURelativeOffset = true;
     474           0 :     if (DumpOpts.Verbose)
     475           0 :       AddrOS << format("cu + 0x%" PRIx64, UValue);
     476             :     break;
     477           0 :   case DW_FORM_GNU_ref_alt:
     478           0 :     AddrOS << format("<alt 0x%" PRIx64 ">", UValue);
     479             :     break;
     480             : 
     481             :   // All DW_FORM_indirect attributes should be resolved prior to calling
     482             :   // this function
     483           0 :   case DW_FORM_indirect:
     484           0 :     OS << "DW_FORM_indirect";
     485             :     break;
     486             : 
     487           3 :   case DW_FORM_rnglistx:
     488           6 :     OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue);
     489             :     break;
     490             : 
     491             :   // Should be formatted to 64-bit for DWARF64.
     492         684 :   case DW_FORM_sec_offset:
     493        1368 :     AddrOS << format("0x%08x", (uint32_t)UValue);
     494             :     break;
     495             : 
     496           0 :   default:
     497           0 :     OS << format("DW_FORM(0x%4.4x)", Form);
     498             :     break;
     499             :   }
     500             : 
     501             :   if (CURelativeOffset) {
     502        3611 :     if (DumpOpts.Verbose)
     503        2190 :       OS << " => {";
     504        3611 :     if (DumpOpts.ShowAddresses)
     505        7194 :       WithColor(OS, HighlightColor::Address).get()
     506        3597 :           << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
     507        3611 :     if (DumpOpts.Verbose)
     508        2190 :       OS << "}";
     509             :   }
     510       20867 : }
     511             : 
     512        6426 : void DWARFFormValue::dumpString(raw_ostream &OS) const {
     513        6426 :   Optional<const char *> DbgStr = getAsCString();
     514        6426 :   if (DbgStr.hasValue()) {
     515       12808 :     auto COS = WithColor(OS, HighlightColor::String);
     516        6404 :     COS.get() << '"';
     517       12808 :     COS.get().write_escaped(DbgStr.getValue());
     518        6404 :     COS.get() << '"';
     519             :   }
     520        6426 : }
     521             : 
     522       23225 : Optional<const char *> DWARFFormValue::getAsCString() const {
     523       23225 :   if (!isFormClass(FC_String))
     524         704 :     return None;
     525       22521 :   if (Form == DW_FORM_string)
     526        4126 :     return Value.cstr;
     527             :   // FIXME: Add support for DW_FORM_GNU_strp_alt
     528       18395 :   if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
     529           0 :     return None;
     530       18395 :   uint32_t Offset = Value.uval;
     531       18395 :   if (Form == DW_FORM_line_strp) {
     532             :     // .debug_line_str is tracked in the Context.
     533         214 :     if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
     534         214 :       return Str;
     535           0 :     return None;
     536             :   }
     537       18181 :   if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
     538       16983 :       Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
     539             :       Form == DW_FORM_strx4) {
     540             :     uint64_t StrOffset;
     541        1213 :     if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset))
     542           1 :       return None;
     543        1212 :     Offset = StrOffset;
     544             :   }
     545             :   // Prefer the Unit's string extractor, because for .dwo it will point to
     546             :   // .debug_str.dwo, while the Context's extractor always uses .debug_str.
     547       18180 :   if (U) {
     548       18178 :     if (const char *Str = U->getStringExtractor().getCStr(&Offset))
     549       18154 :       return Str;
     550          24 :     return None;
     551             :   }
     552           2 :   if (const char *Str = C->getStringExtractor().getCStr(&Offset))
     553           2 :     return Str;
     554           0 :   return None;
     555             : }
     556             : 
     557        7481 : Optional<uint64_t> DWARFFormValue::getAsAddress() const {
     558        7481 :   if (!isFormClass(FC_Address))
     559        1398 :     return None;
     560        6083 :   if (Form == DW_FORM_GNU_addr_index) {
     561          49 :     uint32_t Index = Value.uval;
     562             :     uint64_t Result;
     563          49 :     if (!U || !U->getAddrOffsetSectionItem(Index, Result))
     564           2 :       return None;
     565          47 :     return Result;
     566             :   }
     567        6034 :   return Value.uval;
     568             : }
     569             : 
     570        8327 : Optional<uint64_t> DWARFFormValue::getAsReference() const {
     571        8327 :   if (!isFormClass(FC_Reference))
     572           8 :     return None;
     573        8319 :   switch (Form) {
     574        7659 :   case DW_FORM_ref1:
     575             :   case DW_FORM_ref2:
     576             :   case DW_FORM_ref4:
     577             :   case DW_FORM_ref8:
     578             :   case DW_FORM_ref_udata:
     579        7659 :     if (!U)
     580           0 :       return None;
     581       15318 :     return Value.uval + U->getOffset();
     582         660 :   case DW_FORM_ref_addr:
     583             :   case DW_FORM_ref_sig8:
     584             :   case DW_FORM_GNU_ref_alt:
     585         660 :     return Value.uval;
     586             :   default:
     587           0 :     return None;
     588             :   }
     589             : }
     590             : 
     591        6326 : Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
     592        6326 :   if (!isFormClass(FC_SectionOffset))
     593          32 :     return None;
     594        6294 :   return Value.uval;
     595             : }
     596             : 
     597       39356 : Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
     598       39356 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     599       24736 :       Form == DW_FORM_sdata)
     600       14975 :     return None;
     601       24381 :   return Value.uval;
     602             : }
     603             : 
     604          39 : Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
     605          39 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     606          33 :       (Form == DW_FORM_udata &&
     607           6 :        uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
     608           7 :     return None;
     609          32 :   switch (Form) {
     610           2 :   case DW_FORM_data4:
     611           4 :     return int32_t(Value.uval);
     612           2 :   case DW_FORM_data2:
     613           4 :     return int16_t(Value.uval);
     614           2 :   case DW_FORM_data1:
     615           4 :     return int8_t(Value.uval);
     616          26 :   case DW_FORM_sdata:
     617             :   case DW_FORM_data8:
     618             :   default:
     619          26 :     return Value.sval;
     620             :   }
     621             : }
     622             : 
     623        3147 : Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
     624        3147 :   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
     625          85 :       Form != DW_FORM_data16)
     626             :     return None;
     627        3131 :   return makeArrayRef(Value.data, Value.uval);
     628             : }
     629             : 
     630          30 : Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
     631          30 :   if (!isFormClass(FC_String) && Form == DW_FORM_string)
     632           0 :     return None;
     633          30 :   return Value.uval;
     634             : }
     635             : 
     636         731 : Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
     637         731 :   if (!isFormClass(FC_Reference))
     638           0 :     return None;
     639         731 :   return Value.uval;
     640             : }

Generated by: LCOV version 1.13