LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFFormValue.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 229 265 86.4 %
Date: 2018-06-17 00:07:59 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       18352 : bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
      82             :                                uint32_t *OffsetPtr,
      83             :                                const dwarf::FormParams Params) {
      84             :   bool Indirect = false;
      85             :   do {
      86       18352 :     switch (Form) {
      87             :     // Blocks of inlined data that have a length field and the data bytes
      88             :     // inlined in the .debug_info.
      89        4167 :     case DW_FORM_exprloc:
      90             :     case DW_FORM_block: {
      91        4167 :       uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
      92        4167 :       *OffsetPtr += size;
      93        4167 :       return true;
      94             :     }
      95        3227 :     case DW_FORM_block1: {
      96        3227 :       uint8_t size = DebugInfoData.getU8(OffsetPtr);
      97        3227 :       *OffsetPtr += size;
      98        3227 :       return true;
      99             :     }
     100         199 :     case DW_FORM_block2: {
     101         199 :       uint16_t size = DebugInfoData.getU16(OffsetPtr);
     102         199 :       *OffsetPtr += size;
     103         199 :       return true;
     104             :     }
     105         190 :     case DW_FORM_block4: {
     106         190 :       uint32_t size = DebugInfoData.getU32(OffsetPtr);
     107         190 :       *OffsetPtr += size;
     108         190 :       return true;
     109             :     }
     110             : 
     111             :     // Inlined NULL terminated C-strings.
     112         562 :     case DW_FORM_string:
     113         562 :       DebugInfoData.getCStr(OffsetPtr);
     114         562 :       return true;
     115             : 
     116        7859 :     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        7859 :       if (Optional<uint8_t> FixedSize =
     145        7859 :               dwarf::getFixedFormByteSize(Form, Params)) {
     146        7858 :         *OffsetPtr += *FixedSize;
     147             :         return true;
     148        7858 :       }
     149           1 :       return false;
     150             : 
     151             :     // signed or unsigned LEB 128 values.
     152         409 :     case DW_FORM_sdata:
     153         409 :       DebugInfoData.getSLEB128(OffsetPtr);
     154         409 :       return true;
     155             : 
     156        1739 :     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        1739 :       DebugInfoData.getULEB128(OffsetPtr);
     165        1739 :       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      113890 : bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
     180             :   // First, check DWARF5 form classes.
     181      226246 :   if (Form < makeArrayRef(DWARF5FormClasses).size() &&
     182      112356 :       DWARF5FormClasses[Form] == FC)
     183             :     return true;
     184             :   // Check more forms from extensions and proposals.
     185       45794 :   switch (Form) {
     186           9 :   case DW_FORM_GNU_ref_alt:
     187           9 :     return (FC == FC_Reference);
     188         164 :   case DW_FORM_GNU_addr_index:
     189         164 :     return (FC == FC_Address);
     190        1359 :   case DW_FORM_GNU_str_index:
     191             :   case DW_FORM_GNU_strp_alt:
     192        1359 :     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       44262 :   return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
     201       44262 :           Form == DW_FORM_strp || Form == DW_FORM_line_strp) &&
     202             :          FC == FC_SectionOffset;
     203             : }
     204             : 
     205       68986 : bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
     206             :                                   uint32_t *OffsetPtr, dwarf::FormParams FP,
     207             :                                   const DWARFContext *Ctx,
     208             :                                   const DWARFUnit *CU) {
     209       68986 :   if (!Ctx && CU)
     210       65308 :     Ctx = &CU->getContext();
     211       68986 :   C = Ctx;
     212       68986 :   U = CU;
     213             :   bool Indirect = false;
     214             :   bool IsBlock = false;
     215       68986 :   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       68986 :     switch (Form) {
     221        8411 :     case DW_FORM_addr:
     222             :     case DW_FORM_ref_addr: {
     223             :       uint16_t Size =
     224        9160 :           (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
     225        8411 :       Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
     226             :       break;
     227             :     }
     228        1553 :     case DW_FORM_exprloc:
     229             :     case DW_FORM_block:
     230        1553 :       Value.uval = Data.getULEB128(OffsetPtr);
     231             :       IsBlock = true;
     232             :       break;
     233        1397 :     case DW_FORM_block1:
     234        1397 :       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       13626 :     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       13626 :       Value.uval = Data.getU8(OffsetPtr);
     251             :       break;
     252        2216 :     case DW_FORM_data2:
     253             :     case DW_FORM_ref2:
     254             :     case DW_FORM_strx2:
     255             :     case DW_FORM_addrx2:
     256        2216 :       Value.uval = Data.getU16(OffsetPtr);
     257             :       break;
     258           2 :     case DW_FORM_strx3:
     259           2 :       Value.uval = Data.getU24(OffsetPtr);
     260             :       break;
     261       15584 :     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       15584 :       Value.uval = Data.getRelocatedValue(4, OffsetPtr);
     267             :       break;
     268         366 :     case DW_FORM_data8:
     269             :     case DW_FORM_ref8:
     270             :     case DW_FORM_ref_sup8:
     271         366 :       Value.uval = Data.getU64(OffsetPtr);
     272             :       break;
     273          50 :     case DW_FORM_data16:
     274             :       // Treat this like a 16-byte block.
     275          50 :       Value.uval = 16;
     276             :       IsBlock = true;
     277             :       break;
     278         367 :     case DW_FORM_sdata:
     279         367 :       Value.sval = Data.getSLEB128(OffsetPtr);
     280             :       break;
     281         525 :     case DW_FORM_udata:
     282             :     case DW_FORM_ref_udata:
     283             :     case DW_FORM_rnglistx:
     284         525 :       Value.uval = Data.getULEB128(OffsetPtr);
     285             :       break;
     286         239 :     case DW_FORM_string:
     287         239 :       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       21908 :     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       21908 :       Value.uval =
     300       21908 :           Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
     301             :       break;
     302             :     }
     303        1933 :     case DW_FORM_flag_present:
     304        1933 :       Value.uval = 1;
     305             :       break;
     306          67 :     case DW_FORM_ref_sig8:
     307          67 :       Value.uval = Data.getU64(OffsetPtr);
     308             :       break;
     309         724 :     case DW_FORM_GNU_addr_index:
     310             :     case DW_FORM_GNU_str_index:
     311             :     case DW_FORM_strx:
     312         724 :       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       68986 :   if (IsBlock) {
     322        6036 :     StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
     323        3018 :     Value.data = nullptr;
     324        3018 :     if (!Str.empty()) {
     325        3018 :       Value.data = reinterpret_cast<const uint8_t *>(Str.data());
     326        3018 :       *OffsetPtr += Value.uval;
     327             :     }
     328             :   }
     329             : 
     330       68986 :   return true;
     331             : }
     332             : 
     333       20114 : void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
     334       20114 :   uint64_t UValue = Value.uval;
     335             :   bool CURelativeOffset = false;
     336       20114 :   raw_ostream &AddrOS = DumpOpts.ShowAddresses
     337       40217 :                             ? WithColor(OS, HighlightColor::Address).get()
     338             :                             : nulls();
     339       20114 :   switch (Form) {
     340        1755 :   case DW_FORM_addr:
     341        1755 :     AddrOS << format("0x%016" PRIx64, UValue);
     342             :     break;
     343          57 :   case DW_FORM_GNU_addr_index: {
     344         114 :     AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
     345             :     uint64_t Address;
     346          57 :     if (U == nullptr)
     347           0 :       OS << "<invalid dwarf unit>";
     348          57 :     else if (U->getAddrOffsetSectionItem(UValue, Address))
     349          88 :       AddrOS << format("0x%016" PRIx64, Address);
     350             :     else
     351          13 :       OS << "<no .debug_addr section>";
     352             :     break;
     353             :   }
     354        1673 :   case DW_FORM_flag_present:
     355        1673 :     OS << "true";
     356             :     break;
     357        2505 :   case DW_FORM_flag:
     358             :   case DW_FORM_data1:
     359        5010 :     OS << format("0x%02x", (uint8_t)UValue);
     360             :     break;
     361         506 :   case DW_FORM_data2:
     362        1012 :     OS << format("0x%04x", (uint16_t)UValue);
     363             :     break;
     364        1678 :   case DW_FORM_data4:
     365        3356 :     OS << format("0x%08x", (uint32_t)UValue);
     366             :     break;
     367          56 :   case DW_FORM_ref_sig8:
     368          56 :     AddrOS << format("0x%016" PRIx64, UValue);
     369             :     break;
     370          97 :   case DW_FORM_data8:
     371          97 :     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        1016 :     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           7 :       switch (Form) {
     388           4 :       case DW_FORM_exprloc:
     389             :       case DW_FORM_block:
     390           4 :         OS << format("<0x%" PRIx64 "> ", UValue);
     391           4 :         break;
     392           3 :       case DW_FORM_block1:
     393           6 :         OS << format("<0x%2.2x> ", (uint8_t)UValue);
     394           3 :         break;
     395           0 :       case DW_FORM_block2:
     396           0 :         OS << format("<0x%4.4x> ", (uint16_t)UValue);
     397           0 :         break;
     398           0 :       case DW_FORM_block4:
     399           0 :         OS << 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          35 :         while (DataPtr < EndDataPtr) {
     410          14 :           OS << format("%2.2x ", *DataPtr);
     411          14 :           ++DataPtr;
     412             :         }
     413             :       } else
     414           0 :         OS << "NULL";
     415             :     }
     416             :     break;
     417             : 
     418         353 :   case DW_FORM_sdata:
     419         353 :     OS << Value.sval;
     420             :     break;
     421         395 :   case DW_FORM_udata:
     422         395 :     OS << Value.uval;
     423             :     break;
     424        5304 :   case DW_FORM_strp:
     425        5304 :     if (DumpOpts.Verbose)
     426        6540 :       OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
     427        5304 :     dumpString(OS);
     428             :     break;
     429          89 :   case DW_FORM_line_strp:
     430          89 :     if (DumpOpts.Verbose)
     431         134 :       OS << format(" .debug_line_str[0x%8.8x] = ", (uint32_t)UValue);
     432          89 :     dumpString(OS);
     433             :     break;
     434         806 :   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         806 :     if (DumpOpts.Verbose)
     441        1486 :       OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
     442         806 :     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         226 :   case DW_FORM_ref_addr:
     450         226 :     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        3469 :   case DW_FORM_ref4:
     463             :     CURelativeOffset = true;
     464        3469 :     if (DumpOpts.Verbose)
     465        4324 :       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         626 :   case DW_FORM_sec_offset:
     493        1252 :     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        3469 :     if (DumpOpts.Verbose)
     503        2162 :       OS << " => {";
     504        6938 :     WithColor(OS, HighlightColor::Address).get()
     505       10100 :         << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
     506        3469 :     if (DumpOpts.Verbose)
     507        2162 :       OS << "}";
     508             :   }
     509       20114 : }
     510             : 
     511        6199 : void DWARFFormValue::dumpString(raw_ostream &OS) const {
     512        6199 :   Optional<const char *> DbgStr = getAsCString();
     513        6199 :   if (DbgStr.hasValue()) {
     514       12366 :     auto COS = WithColor(OS, HighlightColor::String);
     515             :     COS.get() << '"';
     516       12366 :     COS.get().write_escaped(DbgStr.getValue());
     517             :     COS.get() << '"';
     518             :   }
     519        6199 : }
     520             : 
     521       22844 : Optional<const char *> DWARFFormValue::getAsCString() const {
     522       22844 :   if (!isFormClass(FC_String))
     523             :     return None;
     524       22150 :   if (Form == DW_FORM_string)
     525             :     return Value.cstr;
     526             :   // FIXME: Add support for DW_FORM_GNU_strp_alt
     527       18031 :   if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
     528             :     return None;
     529       18031 :   uint32_t Offset = Value.uval;
     530       18031 :   if (Form == DW_FORM_line_strp) {
     531             :     // .debug_line_str is tracked in the Context.
     532         160 :     if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
     533             :       return Str;
     534             :     return None;
     535             :   }
     536       17871 :   if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
     537       16803 :       Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
     538             :       Form == DW_FORM_strx4) {
     539             :     uint64_t StrOffset;
     540        1077 :     if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset))
     541           1 :       return None;
     542        1076 :     Offset = StrOffset;
     543             :   }
     544             :   // Prefer the Unit's string extractor, because for .dwo it will point to
     545             :   // .debug_str.dwo, while the Context's extractor always uses .debug_str.
     546       17870 :   if (U) {
     547       17868 :     if (const char *Str = U->getStringExtractor().getCStr(&Offset))
     548             :       return Str;
     549             :     return None;
     550             :   }
     551           4 :   if (const char *Str = C->getStringExtractor().getCStr(&Offset))
     552             :     return Str;
     553             :   return None;
     554             : }
     555             : 
     556        7114 : Optional<uint64_t> DWARFFormValue::getAsAddress() const {
     557        7114 :   if (!isFormClass(FC_Address))
     558             :     return None;
     559        5780 :   if (Form == DW_FORM_GNU_addr_index) {
     560          49 :     uint32_t Index = Value.uval;
     561             :     uint64_t Result;
     562          49 :     if (!U || !U->getAddrOffsetSectionItem(Index, Result))
     563             :       return None;
     564             :     return Result;
     565             :   }
     566             :   return Value.uval;
     567             : }
     568             : 
     569        7611 : Optional<uint64_t> DWARFFormValue::getAsReference() const {
     570        7611 :   if (!isFormClass(FC_Reference))
     571             :     return None;
     572        7603 :   switch (Form) {
     573        6974 :   case DW_FORM_ref1:
     574             :   case DW_FORM_ref2:
     575             :   case DW_FORM_ref4:
     576             :   case DW_FORM_ref8:
     577             :   case DW_FORM_ref_udata:
     578        6974 :     if (!U)
     579             :       return None;
     580       13948 :     return Value.uval + U->getOffset();
     581         629 :   case DW_FORM_ref_addr:
     582             :   case DW_FORM_ref_sig8:
     583             :   case DW_FORM_GNU_ref_alt:
     584             :     return Value.uval;
     585             :   default:
     586             :     return None;
     587             :   }
     588             : }
     589             : 
     590        6021 : Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
     591        6021 :   if (!isFormClass(FC_SectionOffset))
     592             :     return None;
     593             :   return Value.uval;
     594             : }
     595             : 
     596       36672 : Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
     597       59186 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     598       22514 :       Form == DW_FORM_sdata)
     599             :     return None;
     600             :   return Value.uval;
     601             : }
     602             : 
     603          39 : Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
     604          72 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     605          39 :       (Form == DW_FORM_udata &&
     606           6 :        uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
     607             :     return None;
     608          32 :   switch (Form) {
     609           2 :   case DW_FORM_data4:
     610           2 :     return int32_t(Value.uval);
     611           2 :   case DW_FORM_data2:
     612           2 :     return int16_t(Value.uval);
     613           2 :   case DW_FORM_data1:
     614           2 :     return int8_t(Value.uval);
     615          26 :   case DW_FORM_sdata:
     616             :   case DW_FORM_data8:
     617             :   default:
     618             :     return Value.sval;
     619             :   }
     620             : }
     621             : 
     622        2962 : Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
     623        3027 :   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
     624          65 :       Form != DW_FORM_data16)
     625             :     return None;
     626        2946 :   return makeArrayRef(Value.data, Value.uval);
     627             : }
     628             : 
     629          30 : Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
     630          30 :   if (!isFormClass(FC_String) && Form == DW_FORM_string)
     631             :     return None;
     632             :   return Value.uval;
     633             : }
     634             : 
     635         724 : Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
     636         724 :   if (!isFormClass(FC_Reference))
     637             :     return None;
     638             :   return Value.uval;
     639             : }

Generated by: LCOV version 1.13