LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFFormValue.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 233 268 86.9 %
Date: 2018-02-19 03:08:00 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFFormValue.cpp -------------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
      11             : #include "SyntaxHighlighting.h"
      12             : #include "llvm/ADT/ArrayRef.h"
      13             : #include "llvm/ADT/None.h"
      14             : #include "llvm/ADT/Optional.h"
      15             : #include "llvm/ADT/StringRef.h"
      16             : #include "llvm/BinaryFormat/Dwarf.h"
      17             : #include "llvm/DebugInfo/DWARF/DWARFContext.h"
      18             : #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
      19             : #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
      20             : #include "llvm/Support/ErrorHandling.h"
      21             : #include "llvm/Support/Format.h"
      22             : #include "llvm/Support/raw_ostream.h"
      23             : #include <cinttypes>
      24             : #include <cstdint>
      25             : #include <limits>
      26             : 
      27             : using namespace llvm;
      28             : using namespace dwarf;
      29             : using namespace syntax;
      30             : 
      31             : static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
      32             :     DWARFFormValue::FC_Unknown,  // 0x0
      33             :     DWARFFormValue::FC_Address,  // 0x01 DW_FORM_addr
      34             :     DWARFFormValue::FC_Unknown,  // 0x02 unused
      35             :     DWARFFormValue::FC_Block,    // 0x03 DW_FORM_block2
      36             :     DWARFFormValue::FC_Block,    // 0x04 DW_FORM_block4
      37             :     DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
      38             :     // --- These can be FC_SectionOffset in DWARF3 and below:
      39             :     DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
      40             :     DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
      41             :     // ---
      42             :     DWARFFormValue::FC_String,        // 0x08 DW_FORM_string
      43             :     DWARFFormValue::FC_Block,         // 0x09 DW_FORM_block
      44             :     DWARFFormValue::FC_Block,         // 0x0a DW_FORM_block1
      45             :     DWARFFormValue::FC_Constant,      // 0x0b DW_FORM_data1
      46             :     DWARFFormValue::FC_Flag,          // 0x0c DW_FORM_flag
      47             :     DWARFFormValue::FC_Constant,      // 0x0d DW_FORM_sdata
      48             :     DWARFFormValue::FC_String,        // 0x0e DW_FORM_strp
      49             :     DWARFFormValue::FC_Constant,      // 0x0f DW_FORM_udata
      50             :     DWARFFormValue::FC_Reference,     // 0x10 DW_FORM_ref_addr
      51             :     DWARFFormValue::FC_Reference,     // 0x11 DW_FORM_ref1
      52             :     DWARFFormValue::FC_Reference,     // 0x12 DW_FORM_ref2
      53             :     DWARFFormValue::FC_Reference,     // 0x13 DW_FORM_ref4
      54             :     DWARFFormValue::FC_Reference,     // 0x14 DW_FORM_ref8
      55             :     DWARFFormValue::FC_Reference,     // 0x15 DW_FORM_ref_udata
      56             :     DWARFFormValue::FC_Indirect,      // 0x16 DW_FORM_indirect
      57             :     DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
      58             :     DWARFFormValue::FC_Exprloc,       // 0x18 DW_FORM_exprloc
      59             :     DWARFFormValue::FC_Flag,          // 0x19 DW_FORM_flag_present
      60             :     DWARFFormValue::FC_String,        // 0x1a DW_FORM_strx
      61             :     DWARFFormValue::FC_Address,       // 0x1b DW_FORM_addrx
      62             :     DWARFFormValue::FC_Reference,     // 0x1c DW_FORM_ref_sup4
      63             :     DWARFFormValue::FC_String,        // 0x1d DW_FORM_strp_sup
      64             :     DWARFFormValue::FC_Constant,      // 0x1e DW_FORM_data16
      65             :     DWARFFormValue::FC_String,        // 0x1f DW_FORM_line_strp
      66             :     DWARFFormValue::FC_Reference,     // 0x20 DW_FORM_ref_sig8
      67             :     DWARFFormValue::FC_Constant,      // 0x21 DW_FORM_implicit_const
      68             :     DWARFFormValue::FC_SectionOffset, // 0x22 DW_FORM_loclistx
      69             :     DWARFFormValue::FC_SectionOffset, // 0x23 DW_FORM_rnglistx
      70             :     DWARFFormValue::FC_Reference,     // 0x24 DW_FORM_ref_sup8
      71             :     DWARFFormValue::FC_String,        // 0x25 DW_FORM_strx1
      72             :     DWARFFormValue::FC_String,        // 0x26 DW_FORM_strx2
      73             :     DWARFFormValue::FC_String,        // 0x27 DW_FORM_strx3
      74             :     DWARFFormValue::FC_String,        // 0x28 DW_FORM_strx4
      75             :     DWARFFormValue::FC_Address,       // 0x29 DW_FORM_addrx1
      76             :     DWARFFormValue::FC_Address,       // 0x2a DW_FORM_addrx2
      77             :     DWARFFormValue::FC_Address,       // 0x2b DW_FORM_addrx3
      78             :     DWARFFormValue::FC_Address,       // 0x2c DW_FORM_addrx4
      79             : 
      80             : };
      81             : 
      82             : Optional<uint8_t>
      83      164025 : DWARFFormValue::getFixedByteSize(dwarf::Form Form,
      84             :                                  const DWARFFormParams Params) {
      85      164025 :   switch (Form) {
      86             :   case DW_FORM_addr:
      87             :     if (Params)
      88             :       return Params.AddrSize;
      89             :     return None;
      90             : 
      91             :   case DW_FORM_block:          // ULEB128 length L followed by L bytes.
      92             :   case DW_FORM_block1:         // 1 byte length L followed by L bytes.
      93             :   case DW_FORM_block2:         // 2 byte length L followed by L bytes.
      94             :   case DW_FORM_block4:         // 4 byte length L followed by L bytes.
      95             :   case DW_FORM_string:         // C-string with null terminator.
      96             :   case DW_FORM_sdata:          // SLEB128.
      97             :   case DW_FORM_udata:          // ULEB128.
      98             :   case DW_FORM_ref_udata:      // ULEB128.
      99             :   case DW_FORM_indirect:       // ULEB128.
     100             :   case DW_FORM_exprloc:        // ULEB128 length L followed by L bytes.
     101             :   case DW_FORM_strx:           // ULEB128.
     102             :   case DW_FORM_addrx:          // ULEB128.
     103             :   case DW_FORM_loclistx:       // ULEB128.
     104             :   case DW_FORM_rnglistx:       // ULEB128.
     105             :   case DW_FORM_GNU_addr_index: // ULEB128.
     106             :   case DW_FORM_GNU_str_index:  // ULEB128.
     107             :     return None;
     108             : 
     109             :   case DW_FORM_ref_addr:
     110             :     if (Params)
     111             :       return Params.getRefAddrByteSize();
     112             :     return None;
     113             : 
     114       43796 :   case DW_FORM_flag:
     115             :   case DW_FORM_data1:
     116             :   case DW_FORM_ref1:
     117             :   case DW_FORM_strx1:
     118             :   case DW_FORM_addrx1:
     119             :     return 1;
     120             : 
     121        8624 :   case DW_FORM_data2:
     122             :   case DW_FORM_ref2:
     123             :   case DW_FORM_strx2:
     124             :   case DW_FORM_addrx2:
     125             :     return 2;
     126             : 
     127           2 :   case DW_FORM_strx3:
     128             :     return 3;
     129             : 
     130       30981 :   case DW_FORM_data4:
     131             :   case DW_FORM_ref4:
     132             :   case DW_FORM_ref_sup4:
     133             :   case DW_FORM_strx4:
     134             :   case DW_FORM_addrx4:
     135             :     return 4;
     136             : 
     137             :   case DW_FORM_strp:
     138             :   case DW_FORM_GNU_ref_alt:
     139             :   case DW_FORM_GNU_strp_alt:
     140             :   case DW_FORM_line_strp:
     141             :   case DW_FORM_sec_offset:
     142             :   case DW_FORM_strp_sup:
     143             :     if (Params)
     144             :       return Params.getDwarfOffsetByteSize();
     145             :     return None;
     146             : 
     147         234 :   case DW_FORM_data8:
     148             :   case DW_FORM_ref8:
     149             :   case DW_FORM_ref_sig8:
     150             :   case DW_FORM_ref_sup8:
     151             :     return 8;
     152             : 
     153        6739 :   case DW_FORM_flag_present:
     154             :     return 0;
     155             : 
     156           2 :   case DW_FORM_data16:
     157             :     return 16;
     158             : 
     159           0 :   case DW_FORM_implicit_const:
     160             :     // The implicit value is stored in the abbreviation as a SLEB128, and
     161             :     // there no data in debug info.
     162             :     return 0;
     163             : 
     164           0 :   default:
     165           0 :     llvm_unreachable("Handle this form in this switch statement");
     166             :   }
     167             :   return None;
     168             : }
     169             : 
     170       17554 : bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
     171             :                                uint32_t *OffsetPtr,
     172             :                                const DWARFFormParams Params) {
     173             :   bool Indirect = false;
     174             :   do {
     175       17554 :     switch (Form) {
     176             :     // Blocks of inlined data that have a length field and the data bytes
     177             :     // inlined in the .debug_info.
     178        3751 :     case DW_FORM_exprloc:
     179             :     case DW_FORM_block: {
     180        3751 :       uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
     181        3751 :       *OffsetPtr += size;
     182        3751 :       return true;
     183             :     }
     184        3150 :     case DW_FORM_block1: {
     185        3150 :       uint8_t size = DebugInfoData.getU8(OffsetPtr);
     186        3150 :       *OffsetPtr += size;
     187        3150 :       return true;
     188             :     }
     189         199 :     case DW_FORM_block2: {
     190         199 :       uint16_t size = DebugInfoData.getU16(OffsetPtr);
     191         199 :       *OffsetPtr += size;
     192         199 :       return true;
     193             :     }
     194         190 :     case DW_FORM_block4: {
     195         190 :       uint32_t size = DebugInfoData.getU32(OffsetPtr);
     196         190 :       *OffsetPtr += size;
     197         190 :       return true;
     198             :     }
     199             : 
     200             :     // Inlined NULL terminated C-strings.
     201         459 :     case DW_FORM_string:
     202         459 :       DebugInfoData.getCStr(OffsetPtr);
     203         459 :       return true;
     204             : 
     205        7826 :     case DW_FORM_addr:
     206             :     case DW_FORM_ref_addr:
     207             :     case DW_FORM_flag_present:
     208             :     case DW_FORM_data1:
     209             :     case DW_FORM_data2:
     210             :     case DW_FORM_data4:
     211             :     case DW_FORM_data8:
     212             :     case DW_FORM_data16:
     213             :     case DW_FORM_flag:
     214             :     case DW_FORM_ref1:
     215             :     case DW_FORM_ref2:
     216             :     case DW_FORM_ref4:
     217             :     case DW_FORM_ref8:
     218             :     case DW_FORM_ref_sig8:
     219             :     case DW_FORM_ref_sup4:
     220             :     case DW_FORM_ref_sup8:
     221             :     case DW_FORM_strx1:
     222             :     case DW_FORM_strx2:
     223             :     case DW_FORM_strx4:
     224             :     case DW_FORM_addrx1:
     225             :     case DW_FORM_addrx2:
     226             :     case DW_FORM_addrx4:
     227             :     case DW_FORM_sec_offset:
     228             :     case DW_FORM_strp:
     229             :     case DW_FORM_strp_sup:
     230             :     case DW_FORM_line_strp:
     231             :     case DW_FORM_GNU_ref_alt:
     232             :     case DW_FORM_GNU_strp_alt:
     233        7826 :       if (Optional<uint8_t> FixedSize =
     234        7826 :               DWARFFormValue::getFixedByteSize(Form, Params)) {
     235        7825 :         *OffsetPtr += *FixedSize;
     236             :         return true;
     237        7825 :       }
     238           1 :       return false;
     239             : 
     240             :     // signed or unsigned LEB 128 values.
     241         409 :     case DW_FORM_sdata:
     242         409 :       DebugInfoData.getSLEB128(OffsetPtr);
     243         409 :       return true;
     244             : 
     245        1570 :     case DW_FORM_udata:
     246             :     case DW_FORM_ref_udata:
     247             :     case DW_FORM_strx:
     248             :     case DW_FORM_addrx:
     249             :     case DW_FORM_loclistx:
     250             :     case DW_FORM_rnglistx:
     251             :     case DW_FORM_GNU_addr_index:
     252             :     case DW_FORM_GNU_str_index:
     253        1570 :       DebugInfoData.getULEB128(OffsetPtr);
     254        1570 :       return true;
     255             : 
     256           0 :     case DW_FORM_indirect:
     257             :       Indirect = true;
     258           0 :       Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
     259             :       break;
     260             : 
     261             :     default:
     262             :       return false;
     263             :     }
     264             :   } while (Indirect);
     265             :   return true;
     266             : }
     267             : 
     268      108761 : bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
     269             :   // First, check DWARF5 form classes.
     270      216029 :   if (Form < makeArrayRef(DWARF5FormClasses).size() &&
     271      107268 :       DWARF5FormClasses[Form] == FC)
     272             :     return true;
     273             :   // Check more forms from extensions and proposals.
     274       43936 :   switch (Form) {
     275           9 :   case DW_FORM_GNU_ref_alt:
     276           9 :     return (FC == FC_Reference);
     277         158 :   case DW_FORM_GNU_addr_index:
     278         158 :     return (FC == FC_Address);
     279        1324 :   case DW_FORM_GNU_str_index:
     280             :   case DW_FORM_GNU_strp_alt:
     281        1324 :     return (FC == FC_String);
     282             :   default:
     283             :     break;
     284             :   }
     285             :   // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
     286             :   // Don't check for DWARF version here, as some producers may still do this
     287             :   // by mistake. Also accept DW_FORM_[line_]strp since these are
     288             :   // .debug_[line_]str section offsets.
     289       42445 :   return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
     290       42445 :           Form == DW_FORM_strp || Form == DW_FORM_line_strp) &&
     291             :          FC == FC_SectionOffset;
     292             : }
     293             : 
     294       64914 : bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
     295             :                                   uint32_t *OffsetPtr, DWARFFormParams FP,
     296             :                                   const DWARFContext *Ctx,
     297             :                                   const DWARFUnit *CU) {
     298       64914 :   if (!Ctx && CU)
     299       63219 :     Ctx = &CU->getContext();
     300       64914 :   C = Ctx;
     301       64914 :   U = CU;
     302             :   bool Indirect = false;
     303             :   bool IsBlock = false;
     304       64914 :   Value.data = nullptr;
     305             :   // Read the value for the form into value and follow and DW_FORM_indirect
     306             :   // instances we run into
     307             :   do {
     308             :     Indirect = false;
     309       64914 :     switch (Form) {
     310        9602 :     case DW_FORM_addr:
     311             :     case DW_FORM_ref_addr: {
     312             :       uint16_t Size =
     313       10345 :           (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
     314        9602 :       Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
     315             :       break;
     316             :     }
     317        1249 :     case DW_FORM_exprloc:
     318             :     case DW_FORM_block:
     319        1249 :       Value.uval = Data.getULEB128(OffsetPtr);
     320             :       IsBlock = true;
     321             :       break;
     322        1386 :     case DW_FORM_block1:
     323        1386 :       Value.uval = Data.getU8(OffsetPtr);
     324             :       IsBlock = true;
     325             :       break;
     326           9 :     case DW_FORM_block2:
     327           9 :       Value.uval = Data.getU16(OffsetPtr);
     328             :       IsBlock = true;
     329             :       break;
     330           9 :     case DW_FORM_block4:
     331           9 :       Value.uval = Data.getU32(OffsetPtr);
     332             :       IsBlock = true;
     333             :       break;
     334       13361 :     case DW_FORM_data1:
     335             :     case DW_FORM_ref1:
     336             :     case DW_FORM_flag:
     337             :     case DW_FORM_strx1:
     338             :     case DW_FORM_addrx1:
     339       13361 :       Value.uval = Data.getU8(OffsetPtr);
     340             :       break;
     341        1405 :     case DW_FORM_data2:
     342             :     case DW_FORM_ref2:
     343             :     case DW_FORM_strx2:
     344             :     case DW_FORM_addrx2:
     345        1405 :       Value.uval = Data.getU16(OffsetPtr);
     346             :       break;
     347           2 :     case DW_FORM_strx3:
     348           2 :       Value.uval = Data.getU24(OffsetPtr);
     349             :       break;
     350       14326 :     case DW_FORM_data4:
     351             :     case DW_FORM_ref4:
     352             :     case DW_FORM_ref_sup4:
     353             :     case DW_FORM_strx4:
     354             :     case DW_FORM_addrx4:
     355       14326 :       Value.uval = Data.getRelocatedValue(4, OffsetPtr);
     356             :       break;
     357         232 :     case DW_FORM_data8:
     358             :     case DW_FORM_ref8:
     359             :     case DW_FORM_ref_sup8:
     360         232 :       Value.uval = Data.getU64(OffsetPtr);
     361             :       break;
     362          26 :     case DW_FORM_data16:
     363             :       // Treat this like a 16-byte block.
     364          26 :       Value.uval = 16;
     365             :       IsBlock = true;
     366             :       break;
     367         367 :     case DW_FORM_sdata:
     368         367 :       Value.sval = Data.getSLEB128(OffsetPtr);
     369             :       break;
     370         462 :     case DW_FORM_udata:
     371             :     case DW_FORM_ref_udata:
     372         462 :       Value.uval = Data.getULEB128(OffsetPtr);
     373             :       break;
     374         175 :     case DW_FORM_string:
     375         175 :       Value.cstr = Data.getCStr(OffsetPtr);
     376             :       break;
     377           0 :     case DW_FORM_indirect:
     378           0 :       Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr));
     379             :       Indirect = true;
     380             :       break;
     381       19666 :     case DW_FORM_strp:
     382             :     case DW_FORM_sec_offset:
     383             :     case DW_FORM_GNU_ref_alt:
     384             :     case DW_FORM_GNU_strp_alt:
     385             :     case DW_FORM_line_strp:
     386             :     case DW_FORM_strp_sup: {
     387       19666 :       Value.uval =
     388       19666 :           Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
     389             :       break;
     390             :     }
     391        1866 :     case DW_FORM_flag_present:
     392        1866 :       Value.uval = 1;
     393             :       break;
     394          64 :     case DW_FORM_ref_sig8:
     395          64 :       Value.uval = Data.getU64(OffsetPtr);
     396             :       break;
     397         707 :     case DW_FORM_GNU_addr_index:
     398             :     case DW_FORM_GNU_str_index:
     399             :     case DW_FORM_strx:
     400         707 :       Value.uval = Data.getULEB128(OffsetPtr);
     401             :       break;
     402           0 :     default:
     403             :       // DWARFFormValue::skipValue() will have caught this and caused all
     404             :       // DWARF DIEs to fail to be parsed, so this code is not be reachable.
     405           0 :       llvm_unreachable("unsupported form");
     406             :     }
     407             :   } while (Indirect);
     408             : 
     409       64914 :   if (IsBlock) {
     410        5358 :     StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
     411        2679 :     Value.data = nullptr;
     412        2679 :     if (!Str.empty()) {
     413        2679 :       Value.data = reinterpret_cast<const uint8_t *>(Str.data());
     414        2679 :       *OffsetPtr += Value.uval;
     415             :     }
     416             :   }
     417             : 
     418       64914 :   return true;
     419             : }
     420             : 
     421       19054 : void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
     422       19054 :   uint64_t UValue = Value.uval;
     423             :   bool CURelativeOffset = false;
     424             :   raw_ostream &AddrOS =
     425       38097 :       DumpOpts.ShowAddresses ? WithColor(OS, syntax::Address).get() : nulls();
     426       19054 :   switch (Form) {
     427        1721 :   case DW_FORM_addr:
     428        1721 :     AddrOS << format("0x%016" PRIx64, UValue);
     429             :     break;
     430          55 :   case DW_FORM_GNU_addr_index: {
     431         110 :     AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
     432             :     uint64_t Address;
     433          55 :     if (U == nullptr)
     434           0 :       OS << "<invalid dwarf unit>";
     435          55 :     else if (U->getAddrOffsetSectionItem(UValue, Address))
     436          88 :       AddrOS << format("0x%016" PRIx64, Address);
     437             :     else
     438          11 :       OS << "<no .debug_addr section>";
     439             :     break;
     440             :   }
     441        1622 :   case DW_FORM_flag_present:
     442        1622 :     OS << "true";
     443             :     break;
     444        2463 :   case DW_FORM_flag:
     445             :   case DW_FORM_data1:
     446        4926 :     OS << format("0x%02x", (uint8_t)UValue);
     447             :     break;
     448         246 :   case DW_FORM_data2:
     449         492 :     OS << format("0x%04x", (uint16_t)UValue);
     450             :     break;
     451        1668 :   case DW_FORM_data4:
     452        3336 :     OS << format("0x%08x", (uint32_t)UValue);
     453             :     break;
     454          53 :   case DW_FORM_ref_sig8:
     455          53 :     AddrOS << format("0x%016" PRIx64, UValue);
     456             :     break;
     457          97 :   case DW_FORM_data8:
     458          97 :     OS << format("0x%016" PRIx64, UValue);
     459             :     break;
     460             :   case DW_FORM_data16:
     461           2 :     OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16);
     462             :     break;
     463             :   case DW_FORM_string:
     464             :     OS << '"';
     465         838 :     OS.write_escaped(Value.cstr);
     466             :     OS << '"';
     467             :     break;
     468           7 :   case DW_FORM_exprloc:
     469             :   case DW_FORM_block:
     470             :   case DW_FORM_block1:
     471             :   case DW_FORM_block2:
     472             :   case DW_FORM_block4:
     473           7 :     if (UValue > 0) {
     474           7 :       switch (Form) {
     475           4 :       case DW_FORM_exprloc:
     476             :       case DW_FORM_block:
     477           4 :         OS << format("<0x%" PRIx64 "> ", UValue);
     478           4 :         break;
     479           3 :       case DW_FORM_block1:
     480           6 :         OS << format("<0x%2.2x> ", (uint8_t)UValue);
     481           3 :         break;
     482           0 :       case DW_FORM_block2:
     483           0 :         OS << format("<0x%4.4x> ", (uint16_t)UValue);
     484           0 :         break;
     485           0 :       case DW_FORM_block4:
     486           0 :         OS << format("<0x%8.8x> ", (uint32_t)UValue);
     487           0 :         break;
     488             :       default:
     489             :         break;
     490             :       }
     491             : 
     492           7 :       const uint8_t *DataPtr = Value.data;
     493           7 :       if (DataPtr) {
     494             :         // UValue contains size of block
     495           7 :         const uint8_t *EndDataPtr = DataPtr + UValue;
     496          35 :         while (DataPtr < EndDataPtr) {
     497          14 :           OS << format("%2.2x ", *DataPtr);
     498          14 :           ++DataPtr;
     499             :         }
     500             :       } else
     501           0 :         OS << "NULL";
     502             :     }
     503             :     break;
     504             : 
     505         353 :   case DW_FORM_sdata:
     506         353 :     OS << Value.sval;
     507             :     break;
     508         391 :   case DW_FORM_udata:
     509         391 :     OS << Value.uval;
     510             :     break;
     511        5189 :   case DW_FORM_strp:
     512        5189 :     if (DumpOpts.Verbose)
     513        6506 :       OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
     514        5189 :     dumpString(OS);
     515             :     break;
     516          41 :   case DW_FORM_line_strp:
     517          41 :     if (DumpOpts.Verbose)
     518          70 :       OS << format(" .debug_line_str[0x%8.8x] = ", (uint32_t)UValue);
     519          41 :     dumpString(OS);
     520             :     break;
     521         783 :   case DW_FORM_strx:
     522             :   case DW_FORM_strx1:
     523             :   case DW_FORM_strx2:
     524             :   case DW_FORM_strx3:
     525             :   case DW_FORM_strx4:
     526             :   case DW_FORM_GNU_str_index:
     527         783 :     if (DumpOpts.Verbose)
     528        1462 :       OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
     529         783 :     dumpString(OS);
     530             :     break;
     531           0 :   case DW_FORM_GNU_strp_alt:
     532           0 :     if (DumpOpts.Verbose)
     533           0 :       OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
     534           0 :     dumpString(OS);
     535             :     break;
     536         223 :   case DW_FORM_ref_addr:
     537         223 :     AddrOS << format("0x%016" PRIx64, UValue);
     538             :     break;
     539           0 :   case DW_FORM_ref1:
     540             :     CURelativeOffset = true;
     541           0 :     AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue);
     542             :     break;
     543           0 :   case DW_FORM_ref2:
     544             :     CURelativeOffset = true;
     545           0 :     AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue);
     546             :     break;
     547        3116 :   case DW_FORM_ref4:
     548             :     CURelativeOffset = true;
     549        6232 :     AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue);
     550             :     break;
     551           0 :   case DW_FORM_ref8:
     552             :     CURelativeOffset = true;
     553           0 :     AddrOS << format("cu + 0x%8.8" PRIx64, UValue);
     554             :     break;
     555           0 :   case DW_FORM_ref_udata:
     556             :     CURelativeOffset = true;
     557           0 :     AddrOS << format("cu + 0x%" PRIx64, UValue);
     558             :     break;
     559           0 :   case DW_FORM_GNU_ref_alt:
     560           0 :     AddrOS << format("<alt 0x%" PRIx64 ">", UValue);
     561             :     break;
     562             : 
     563             :   // All DW_FORM_indirect attributes should be resolved prior to calling
     564             :   // this function
     565           0 :   case DW_FORM_indirect:
     566           0 :     OS << "DW_FORM_indirect";
     567             :     break;
     568             : 
     569             :   // Should be formatted to 64-bit for DWARF64.
     570         606 :   case DW_FORM_sec_offset:
     571        1212 :     AddrOS << format("0x%08x", (uint32_t)UValue);
     572             :     break;
     573             : 
     574           0 :   default:
     575           0 :     OS << format("DW_FORM(0x%4.4x)", Form);
     576             :     break;
     577             :   }
     578             : 
     579        3116 :   if (CURelativeOffset && DumpOpts.Verbose) {
     580        2155 :     OS << " => {";
     581        4310 :     WithColor(OS, syntax::Address).get()
     582        4310 :         << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
     583        2155 :     OS << "}";
     584             :   }
     585       19054 : }
     586             : 
     587        6013 : void DWARFFormValue::dumpString(raw_ostream &OS) const {
     588        6013 :   Optional<const char *> DbgStr = getAsCString();
     589        6013 :   if (DbgStr.hasValue()) {
     590       11994 :     auto COS = WithColor(OS, syntax::String);
     591             :     COS.get() << '"';
     592       11994 :     COS.get().write_escaped(DbgStr.getValue());
     593             :     COS.get() << '"';
     594             :   }
     595        6013 : }
     596             : 
     597       19825 : Optional<const char *> DWARFFormValue::getAsCString() const {
     598       19825 :   if (!isFormClass(FC_String))
     599             :     return None;
     600       19815 :   if (Form == DW_FORM_string)
     601             :     return Value.cstr;
     602             :   // FIXME: Add support for DW_FORM_GNU_strp_alt
     603       15900 :   if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
     604             :     return None;
     605       15900 :   uint32_t Offset = Value.uval;
     606       15900 :   if (Form == DW_FORM_line_strp) {
     607             :     // .debug_line_str is tracked in the Context.
     608          64 :     if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
     609             :       return Str;
     610             :     return None;
     611             :   }
     612       15836 :   if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
     613       14820 :       Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
     614             :       Form == DW_FORM_strx4) {
     615             :     uint64_t StrOffset;
     616        1025 :     if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset))
     617           1 :       return None;
     618        1024 :     Offset = StrOffset;
     619             :   }
     620             :   // Prefer the Unit's string extractor, because for .dwo it will point to
     621             :   // .debug_str.dwo, while the Context's extractor always uses .debug_str.
     622       15835 :   if (U) {
     623       15833 :     if (const char *Str = U->getStringExtractor().getCStr(&Offset))
     624             :       return Str;
     625             :     return None;
     626             :   }
     627           4 :   if (const char *Str = C->getStringExtractor().getCStr(&Offset))
     628             :     return Str;
     629             :   return None;
     630             : }
     631             : 
     632        8305 : Optional<uint64_t> DWARFFormValue::getAsAddress() const {
     633        8305 :   if (!isFormClass(FC_Address))
     634             :     return None;
     635        7021 :   if (Form == DW_FORM_GNU_addr_index) {
     636          47 :     uint32_t Index = Value.uval;
     637             :     uint64_t Result;
     638          47 :     if (!U || !U->getAddrOffsetSectionItem(Index, Result))
     639             :       return None;
     640             :     return Result;
     641             :   }
     642             :   return Value.uval;
     643             : }
     644             : 
     645        7513 : Optional<uint64_t> DWARFFormValue::getAsReference() const {
     646        7513 :   if (!isFormClass(FC_Reference))
     647             :     return None;
     648        7505 :   switch (Form) {
     649        6879 :   case DW_FORM_ref1:
     650             :   case DW_FORM_ref2:
     651             :   case DW_FORM_ref4:
     652             :   case DW_FORM_ref8:
     653             :   case DW_FORM_ref_udata:
     654        6879 :     if (!U)
     655             :       return None;
     656        6879 :     return Value.uval + U->getOffset();
     657         626 :   case DW_FORM_ref_addr:
     658             :   case DW_FORM_ref_sig8:
     659             :   case DW_FORM_GNU_ref_alt:
     660             :     return Value.uval;
     661             :   default:
     662             :     return None;
     663             :   }
     664             : }
     665             : 
     666        5861 : Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
     667        5861 :   if (!isFormClass(FC_SectionOffset))
     668             :     return None;
     669             :   return Value.uval;
     670             : }
     671             : 
     672       35503 : Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
     673       57135 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     674       21632 :       Form == DW_FORM_sdata)
     675             :     return None;
     676             :   return Value.uval;
     677             : }
     678             : 
     679          39 : Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
     680          72 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
     681          39 :       (Form == DW_FORM_udata &&
     682           6 :        uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
     683             :     return None;
     684          32 :   switch (Form) {
     685           2 :   case DW_FORM_data4:
     686           2 :     return int32_t(Value.uval);
     687           2 :   case DW_FORM_data2:
     688           2 :     return int16_t(Value.uval);
     689           2 :   case DW_FORM_data1:
     690           2 :     return int8_t(Value.uval);
     691          26 :   case DW_FORM_sdata:
     692             :   case DW_FORM_data8:
     693             :   default:
     694             :     return Value.sval;
     695             :   }
     696             : }
     697             : 
     698        2621 : Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
     699        2660 :   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
     700          39 :       Form != DW_FORM_data16)
     701             :     return None;
     702        2607 :   return makeArrayRef(Value.data, Value.uval);
     703             : }
     704             : 
     705          30 : Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
     706          30 :   if (!isFormClass(FC_String) && Form == DW_FORM_string)
     707             :     return None;
     708             :   return Value.uval;
     709             : }
     710             : 
     711          22 : Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
     712          22 :   if (!isFormClass(FC_Reference))
     713             :     return None;
     714             :   return Value.uval;
     715             : }

Generated by: LCOV version 1.13