LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFFormValue.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 233 269 86.6 %
Date: 2018-10-20 13:21:21 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       19775 : bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
      82             :                                uint32_t *OffsetPtr,
      83             :                                const dwarf::FormParams Params) {
      84             :   bool Indirect = false;
      85             :   do {
      86       19775 :     switch (Form) {
      87             :     // Blocks of inlined data that have a length field and the data bytes
      88             :     // inlined in the .debug_info.
      89        4541 :     case DW_FORM_exprloc:
      90             :     case DW_FORM_block: {
      91        4541 :       uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
      92        4541 :       *OffsetPtr += size;
      93        4541 :       return true;
      94             :     }
      95        3481 :     case DW_FORM_block1: {
      96        3481 :       uint8_t size = DebugInfoData.getU8(OffsetPtr);
      97        3481 :       *OffsetPtr += size;
      98        3481 :       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         581 :     case DW_FORM_string:
     113         581 :       DebugInfoData.getCStr(OffsetPtr);
     114         581 :       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         412 :     case DW_FORM_sdata:
     153         412 :       DebugInfoData.getSLEB128(OffsetPtr);
     154         412 :       return true;
     155             : 
     156        1841 :     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        1841 :       DebugInfoData.getULEB128(OffsetPtr);
     165        1841 :       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      120634 : bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
     180             :   // First, check DWARF5 form classes.
     181      120634 :   if (Form < makeArrayRef(DWARF5FormClasses).size() &&
     182      119023 :       DWARF5FormClasses[Form] == FC)
     183       72676 :     return true;
     184             :   // Check more forms from extensions and proposals.
     185       47958 :   switch (Form) {
     186           9 :   case DW_FORM_GNU_ref_alt:
     187           9 :     return (FC == FC_Reference);
     188         178 :   case DW_FORM_GNU_addr_index:
     189         178 :     return (FC == FC_Address);
     190        1422 :   case DW_FORM_GNU_str_index:
     191             :   case DW_FORM_GNU_strp_alt:
     192        1422 :     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       46349 :   return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
     201       46349 :           Form == DW_FORM_strp || Form == DW_FORM_line_strp) &&
     202             :          FC == FC_SectionOffset;
     203             : }
     204             : 
     205       72965 : bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
     206             :                                   uint32_t *OffsetPtr, dwarf::FormParams FP,
     207             :                                   const DWARFContext *Ctx,
     208             :                                   const DWARFUnit *CU) {
     209       72965 :   if (!Ctx && CU)
     210       68870 :     Ctx = &CU->getContext();
     211       72965 :   C = Ctx;
     212       72965 :   U = CU;
     213             :   bool Indirect = false;
     214             :   bool IsBlock = false;
     215       72965 :   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       72965 :     switch (Form) {
     221        8950 :     case DW_FORM_addr:
     222             :     case DW_FORM_ref_addr: {
     223             :       uint16_t Size =
     224        9728 :           (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
     225        8950 :       Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
     226             :       break;
     227             :     }
     228        1641 :     case DW_FORM_exprloc:
     229             :     case DW_FORM_block:
     230        1641 :       Value.uval = Data.getULEB128(OffsetPtr);
     231             :       IsBlock = true;
     232             :       break;
     233        1527 :     case DW_FORM_block1:
     234        1527 :       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       14637 :     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       14637 :       Value.uval = Data.getU8(OffsetPtr);
     251             :       break;
     252        2326 :     case DW_FORM_data2:
     253             :     case DW_FORM_ref2:
     254             :     case DW_FORM_strx2:
     255             :     case DW_FORM_addrx2:
     256        2326 :       Value.uval = Data.getU16(OffsetPtr);
     257             :       break;
     258           4 :     case DW_FORM_strx3:
     259           4 :       Value.uval = Data.getU24(OffsetPtr);
     260             :       break;
     261       16660 :     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       16660 :       Value.uval = Data.getRelocatedValue(4, OffsetPtr);
     267             :       break;
     268         399 :     case DW_FORM_data8:
     269             :     case DW_FORM_ref8:
     270             :     case DW_FORM_ref_sup8:
     271         399 :       Value.uval = Data.getU64(OffsetPtr);
     272             :       break;
     273          74 :     case DW_FORM_data16:
     274             :       // Treat this like a 16-byte block.
     275          74 :       Value.uval = 16;
     276             :       IsBlock = true;
     277             :       break;
     278         368 :     case DW_FORM_sdata:
     279         368 :       Value.sval = Data.getSLEB128(OffsetPtr);
     280             :       break;
     281         572 :     case DW_FORM_udata:
     282             :     case DW_FORM_ref_udata:
     283             :     case DW_FORM_rnglistx:
     284         572 :       Value.uval = Data.getULEB128(OffsetPtr);
     285             :       break;
     286         248 :     case DW_FORM_string:
     287         248 :       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       22658 :     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       22658 :       Value.uval =
     300       22658 :           Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
     301             :       break;
     302             :     }
     303        2058 :     case DW_FORM_flag_present:
     304        2058 :       Value.uval = 1;
     305             :       break;
     306          69 :     case DW_FORM_ref_sig8:
     307          69 :       Value.uval = Data.getU64(OffsetPtr);
     308             :       break;
     309         756 :     case DW_FORM_GNU_addr_index:
     310             :     case DW_FORM_GNU_str_index:
     311             :     case DW_FORM_strx:
     312         756 :       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       72965 :   if (IsBlock) {
     322        3260 :     StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
     323        3260 :     Value.data = nullptr;
     324        3260 :     if (!Str.empty()) {
     325        3259 :       Value.data = reinterpret_cast<const uint8_t *>(Str.data());
     326        3259 :       *OffsetPtr += Value.uval;
     327             :     }
     328             :   }
     329             : 
     330       72965 :   return true;
     331             : }
     332             : 
     333       20993 : void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
     334       20993 :   uint64_t UValue = Value.uval;
     335             :   bool CURelativeOffset = false;
     336       20993 :   raw_ostream &AddrOS = DumpOpts.ShowAddresses
     337       20993 :                             ? WithColor(OS, HighlightColor::Address).get()
     338          66 :                             : nulls();
     339       20993 :   switch (Form) {
     340        1847 :   case DW_FORM_addr:
     341        1847 :     AddrOS << format("0x%016" PRIx64, UValue);
     342             :     break;
     343          64 :   case DW_FORM_GNU_addr_index: {
     344         128 :     AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
     345             :     uint64_t Address;
     346          64 :     if (U == nullptr)
     347           0 :       OS << "<invalid dwarf unit>";
     348          64 :     else if (U->getAddrOffsetSectionItem(UValue, Address))
     349         100 :       AddrOS << format("0x%016" PRIx64, Address);
     350             :     else
     351          14 :       OS << "<no .debug_addr section>";
     352             :     break;
     353             :   }
     354        1758 :   case DW_FORM_flag_present:
     355        1758 :     OS << "true";
     356             :     break;
     357        2602 :   case DW_FORM_flag:
     358             :   case DW_FORM_data1:
     359        5204 :     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        1743 :   case DW_FORM_data4:
     365        3486 :     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         103 :   case DW_FORM_data8:
     371         103 :     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        1088 :     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         397 :   case DW_FORM_udata:
     422         397 :     OS << Value.uval;
     423             :     break;
     424        5418 :   case DW_FORM_strp:
     425        5418 :     if (DumpOpts.Verbose)
     426        6612 :       OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
     427        5418 :     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         921 :   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         921 :     if (DumpOpts.Verbose)
     441        1654 :       OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
     442         921 :     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        3624 :   case DW_FORM_ref4:
     463             :     CURelativeOffset = true;
     464        3624 :     if (DumpOpts.Verbose)
     465        4386 :       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         693 :   case DW_FORM_sec_offset:
     493        1386 :     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        3624 :     if (DumpOpts.Verbose)
     503        2193 :       OS << " => {";
     504        3624 :     if (DumpOpts.ShowAddresses)
     505        7220 :       WithColor(OS, HighlightColor::Address).get()
     506        3610 :           << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
     507        3624 :     if (DumpOpts.Verbose)
     508        2193 :       OS << "}";
     509             :   }
     510       20993 : }
     511             : 
     512        6457 : void DWARFFormValue::dumpString(raw_ostream &OS) const {
     513        6457 :   Optional<const char *> DbgStr = getAsCString();
     514        6457 :   if (DbgStr.hasValue()) {
     515       12870 :     auto COS = WithColor(OS, HighlightColor::String);
     516        6435 :     COS.get() << '"';
     517       12870 :     COS.get().write_escaped(DbgStr.getValue());
     518        6435 :     COS.get() << '"';
     519             :   }
     520        6457 : }
     521             : 
     522       23474 : Optional<const char *> DWARFFormValue::getAsCString() const {
     523       23474 :   if (!isFormClass(FC_String))
     524             :     return None;
     525       22769 :   if (Form == DW_FORM_string)
     526             :     return Value.cstr;
     527             :   // FIXME: Add support for DW_FORM_GNU_strp_alt
     528       18631 :   if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
     529             :     return None;
     530       18631 :   uint32_t Offset = Value.uval;
     531       18631 :   if (Form == DW_FORM_line_strp) {
     532             :     // .debug_line_str is tracked in the Context.
     533         220 :     if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
     534             :       return Str;
     535             :     return None;
     536             :   }
     537       18411 :   if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
     538       17131 :       Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
     539             :       Form == DW_FORM_strx4) {
     540             :     uint64_t StrOffset;
     541        1295 :     if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset))
     542           1 :       return None;
     543        1294 :     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       18410 :   if (U) {
     548       18408 :     if (const char *Str = U->getStringExtractor().getCStr(&Offset))
     549             :       return Str;
     550             :     return None;
     551             :   }
     552           2 :   if (const char *Str = C->getStringExtractor().getCStr(&Offset))
     553             :     return Str;
     554             :   return None;
     555             : }
     556             : 
     557        7529 : Optional<uint64_t> DWARFFormValue::getAsAddress() const {
     558        7529 :   if (!isFormClass(FC_Address))
     559             :     return None;
     560        6107 :   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             :       return None;
     565             :     return Result;
     566             :   }
     567             :   return Value.uval;
     568             : }
     569             : 
     570        8367 : Optional<uint64_t> DWARFFormValue::getAsReference() const {
     571        8367 :   if (!isFormClass(FC_Reference))
     572             :     return None;
     573        8359 :   switch (Form) {
     574        7699 :   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        7699 :     if (!U)
     580             :       return None;
     581       15398 :     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             :     return Value.uval;
     586             :   default:
     587             :     return None;
     588             :   }
     589             : }
     590             : 
     591        6353 : Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
     592        6353 :   if (!isFormClass(FC_SectionOffset))
     593             :     return None;
     594             :   return Value.uval;
     595             : }
     596             : 
     597       39583 : Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
     598       39583 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     599       24860 :       Form == DW_FORM_sdata)
     600             :     return None;
     601             :   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             :     return None;
     609          32 :   switch (Form) {
     610           2 :   case DW_FORM_data4:
     611           2 :     return int32_t(Value.uval);
     612           2 :   case DW_FORM_data2:
     613           2 :     return int16_t(Value.uval);
     614           2 :   case DW_FORM_data1:
     615           2 :     return int8_t(Value.uval);
     616          26 :   case DW_FORM_sdata:
     617             :   case DW_FORM_data8:
     618             :   default:
     619             :     return Value.sval;
     620             :   }
     621             : }
     622             : 
     623        3162 : Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
     624        3162 :   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
     625          89 :       Form != DW_FORM_data16)
     626             :     return None;
     627        3146 :   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             :     return None;
     633             :   return Value.uval;
     634             : }
     635             : 
     636         755 : Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
     637         755 :   if (!isFormClass(FC_Reference))
     638             :     return None;
     639             :   return Value.uval;
     640             : }

Generated by: LCOV version 1.13