LCOV - code coverage report
Current view: top level - lib/DebugInfo - DWARFFormValue.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 195 238 81.9 %
Date: 2015-01-30 11:55:44 Functions: 10 12 83.3 %
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 "SyntaxHighlighting.h"
      11             : #include "llvm/ADT/ArrayRef.h"
      12             : #include "llvm/ADT/StringRef.h"
      13             : #include "llvm/DebugInfo/DWARFCompileUnit.h"
      14             : #include "llvm/DebugInfo/DWARFContext.h"
      15             : #include "llvm/DebugInfo/DWARFFormValue.h"
      16             : #include "llvm/Support/Debug.h"
      17             : #include "llvm/Support/Dwarf.h"
      18             : #include "llvm/Support/Format.h"
      19             : #include "llvm/Support/raw_ostream.h"
      20             : #include <cassert>
      21             : using namespace llvm;
      22             : using namespace dwarf;
      23             : using namespace syntax;
      24             : 
      25             : namespace {
      26             : uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
      27             :   // FIXME: Support DWARF64.
      28     7838024 :   return (Version == 2) ? AddrSize : 4;
      29             : }
      30             : 
      31             : template <uint8_t AddrSize, uint8_t RefAddrSize>
      32             : ArrayRef<uint8_t> makeFixedFormSizesArrayRef() {
      33             :   static const uint8_t sizes[] = {
      34             :     0,           // 0x00 unused
      35             :     AddrSize,    // 0x01 DW_FORM_addr
      36             :     0,           // 0x02 unused
      37             :     0,           // 0x03 DW_FORM_block2
      38             :     0,           // 0x04 DW_FORM_block4
      39             :     2,           // 0x05 DW_FORM_data2
      40             :     4,           // 0x06 DW_FORM_data4
      41             :     8,           // 0x07 DW_FORM_data8
      42             :     0,           // 0x08 DW_FORM_string
      43             :     0,           // 0x09 DW_FORM_block
      44             :     0,           // 0x0a DW_FORM_block1
      45             :     1,           // 0x0b DW_FORM_data1
      46             :     1,           // 0x0c DW_FORM_flag
      47             :     0,           // 0x0d DW_FORM_sdata
      48             :     4,           // 0x0e DW_FORM_strp
      49             :     0,           // 0x0f DW_FORM_udata
      50             :     RefAddrSize, // 0x10 DW_FORM_ref_addr
      51             :     1,           // 0x11 DW_FORM_ref1
      52             :     2,           // 0x12 DW_FORM_ref2
      53             :     4,           // 0x13 DW_FORM_ref4
      54             :     8,           // 0x14 DW_FORM_ref8
      55             :     0,           // 0x15 DW_FORM_ref_udata
      56             :     0,           // 0x16 DW_FORM_indirect
      57             :     4,           // 0x17 DW_FORM_sec_offset
      58             :     0,           // 0x18 DW_FORM_exprloc
      59             :     0,           // 0x19 DW_FORM_flag_present
      60             :   };
      61             :   return makeArrayRef(sizes);
      62             : }
      63             : }
      64             : 
      65     7837986 : ArrayRef<uint8_t> DWARFFormValue::getFixedFormSizes(uint8_t AddrSize,
      66             :                                                     uint16_t Version) {
      67     7837986 :   uint8_t RefAddrSize = getRefAddrSize(AddrSize, Version);
      68     7837986 :   if (AddrSize == 4 && RefAddrSize == 4)
      69             :     return makeFixedFormSizesArrayRef<4, 4>();
      70     7837835 :   if (AddrSize == 4 && RefAddrSize == 8)
      71             :     return makeFixedFormSizesArrayRef<4, 8>();
      72     7837835 :   if (AddrSize == 8 && RefAddrSize == 4)
      73             :     return makeFixedFormSizesArrayRef<8, 4>();
      74        1285 :   if (AddrSize == 8 && RefAddrSize == 8)
      75             :     return makeFixedFormSizesArrayRef<8, 8>();
      76           1 :   return None;
      77             : }
      78             : 
      79             : static const DWARFFormValue::FormClass DWARF4FormClasses[] = {
      80             :   DWARFFormValue::FC_Unknown,       // 0x0
      81             :   DWARFFormValue::FC_Address,       // 0x01 DW_FORM_addr
      82             :   DWARFFormValue::FC_Unknown,       // 0x02 unused
      83             :   DWARFFormValue::FC_Block,         // 0x03 DW_FORM_block2
      84             :   DWARFFormValue::FC_Block,         // 0x04 DW_FORM_block4
      85             :   DWARFFormValue::FC_Constant,      // 0x05 DW_FORM_data2
      86             :   // --- These can be FC_SectionOffset in DWARF3 and below:
      87             :   DWARFFormValue::FC_Constant,      // 0x06 DW_FORM_data4
      88             :   DWARFFormValue::FC_Constant,      // 0x07 DW_FORM_data8
      89             :   // ---
      90             :   DWARFFormValue::FC_String,        // 0x08 DW_FORM_string
      91             :   DWARFFormValue::FC_Block,         // 0x09 DW_FORM_block
      92             :   DWARFFormValue::FC_Block,         // 0x0a DW_FORM_block1
      93             :   DWARFFormValue::FC_Constant,      // 0x0b DW_FORM_data1
      94             :   DWARFFormValue::FC_Flag,          // 0x0c DW_FORM_flag
      95             :   DWARFFormValue::FC_Constant,      // 0x0d DW_FORM_sdata
      96             :   DWARFFormValue::FC_String,        // 0x0e DW_FORM_strp
      97             :   DWARFFormValue::FC_Constant,      // 0x0f DW_FORM_udata
      98             :   DWARFFormValue::FC_Reference,     // 0x10 DW_FORM_ref_addr
      99             :   DWARFFormValue::FC_Reference,     // 0x11 DW_FORM_ref1
     100             :   DWARFFormValue::FC_Reference,     // 0x12 DW_FORM_ref2
     101             :   DWARFFormValue::FC_Reference,     // 0x13 DW_FORM_ref4
     102             :   DWARFFormValue::FC_Reference,     // 0x14 DW_FORM_ref8
     103             :   DWARFFormValue::FC_Reference,     // 0x15 DW_FORM_ref_udata
     104             :   DWARFFormValue::FC_Indirect,      // 0x16 DW_FORM_indirect
     105             :   DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
     106             :   DWARFFormValue::FC_Exprloc,       // 0x18 DW_FORM_exprloc
     107             :   DWARFFormValue::FC_Flag,          // 0x19 DW_FORM_flag_present
     108             : };
     109             : 
     110      111917 : bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
     111             :   // First, check DWARF4 form classes.
     112      335217 :   if (Form < ArrayRef<FormClass>(DWARF4FormClasses).size() &&
     113      111383 :       DWARF4FormClasses[Form] == FC)
     114             :     return true;
     115             :   // Check DW_FORM_ref_sig8 from DWARF4.
     116       30196 :   if (Form == DW_FORM_ref_sig8)
     117          63 :     return (FC == FC_Reference);
     118             :   // Check for some DWARF5 forms.
     119       30133 :   if (Form == DW_FORM_GNU_addr_index)
     120          43 :     return (FC == FC_Address);
     121       30090 :   if (Form == DW_FORM_GNU_str_index)
     122         428 :     return (FC == FC_String);
     123             :   // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
     124             :   // Don't check for DWARF version here, as some producers may still do this
     125             :   // by mistake.
     126       29662 :   if ((Form == DW_FORM_data4 || Form == DW_FORM_data8) &&
     127             :       FC == FC_SectionOffset)
     128             :     return true;
     129       29187 :   return false;
     130             : }
     131             : 
     132      102119 : bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
     133             :                                   const DWARFUnit *cu) {
     134      102119 :   bool indirect = false;
     135      102119 :   bool is_block = false;
     136      102119 :   Value.data = nullptr;
     137             :   // Read the value for the form into value and follow and DW_FORM_indirect
     138             :   // instances we run into
     139      102119 :   do {
     140      102119 :     indirect = false;
     141      102119 :     switch (Form) {
     142             :     case DW_FORM_addr:
     143             :     case DW_FORM_ref_addr: {
     144       41904 :       if (!cu)
     145           0 :         return false;
     146             :       uint16_t AddrSize =
     147             :           (Form == DW_FORM_addr)
     148       41870 :               ? cu->getAddressByteSize()
     149       83808 :               : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
     150       83808 :       RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
     151      167616 :       if (AI != cu->getRelocMap()->end()) {
     152         495 :         const std::pair<uint8_t, int64_t> &R = AI->second;
     153         495 :         Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second;
     154             :       } else
     155       41409 :         Value.uval = data.getUnsigned(offset_ptr, AddrSize);
     156       41904 :       break;
     157             :     }
     158             :     case DW_FORM_exprloc:
     159             :     case DW_FORM_block:
     160         415 :       Value.uval = data.getULEB128(offset_ptr);
     161         415 :       is_block = true;
     162         415 :       break;
     163             :     case DW_FORM_block1:
     164         319 :       Value.uval = data.getU8(offset_ptr);
     165         319 :       is_block = true;
     166         319 :       break;
     167             :     case DW_FORM_block2:
     168           0 :       Value.uval = data.getU16(offset_ptr);
     169           0 :       is_block = true;
     170           0 :       break;
     171             :     case DW_FORM_block4:
     172           0 :       Value.uval = data.getU32(offset_ptr);
     173           0 :       is_block = true;
     174           0 :       break;
     175             :     case DW_FORM_data1:
     176             :     case DW_FORM_ref1:
     177             :     case DW_FORM_flag:
     178        3531 :       Value.uval = data.getU8(offset_ptr);
     179        3531 :       break;
     180             :     case DW_FORM_data2:
     181             :     case DW_FORM_ref2:
     182         331 :       Value.uval = data.getU16(offset_ptr);
     183         331 :       break;
     184             :     case DW_FORM_data4:
     185             :     case DW_FORM_ref4: {
     186        2828 :       Value.uval = data.getU32(offset_ptr);
     187        2828 :       if (!cu)
     188             :         break;
     189        5358 :       RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
     190       10716 :       if (AI != cu->getRelocMap()->end())
     191         256 :         Value.uval += AI->second.second;
     192             :       break;
     193             :     }
     194             :     case DW_FORM_data8:
     195             :     case DW_FORM_ref8:
     196       35071 :       Value.uval = data.getU64(offset_ptr);
     197       35071 :       break;
     198             :     case DW_FORM_sdata:
     199          41 :       Value.sval = data.getSLEB128(offset_ptr);
     200          41 :       break;
     201             :     case DW_FORM_strp: {
     202        3645 :       Value.uval = data.getU32(offset_ptr);
     203        3645 :       if (!cu)
     204             :         break;
     205        7290 :       RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
     206       14580 :       if (AI != cu->getRelocMap()->end())
     207        1671 :         Value.uval += AI->second.second;
     208             :       break;
     209             :     }
     210             :     case DW_FORM_udata:
     211             :     case DW_FORM_ref_udata:
     212          19 :       Value.uval = data.getULEB128(offset_ptr);
     213          19 :       break;
     214             :     case DW_FORM_string:
     215          92 :       Value.cstr = data.getCStr(offset_ptr);
     216          92 :       break;
     217             :     case DW_FORM_indirect:
     218           0 :       Form = data.getULEB128(offset_ptr);
     219           0 :       indirect = true;
     220           0 :       break;
     221             :     case DW_FORM_sec_offset: {
     222             :       // FIXME: This is 64-bit for DWARF64.
     223       12916 :       Value.uval = data.getU32(offset_ptr);
     224       12916 :       if (!cu)
     225             :         break;
     226       25832 :       RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
     227       51664 :       if (AI != cu->getRelocMap()->end())
     228         548 :         Value.uval +=  AI->second.second;
     229             :       break;
     230             :     }
     231             :     case DW_FORM_flag_present:
     232         801 :       Value.uval = 1;
     233         801 :       break;
     234             :     case DW_FORM_ref_sig8:
     235          31 :       Value.uval = data.getU64(offset_ptr);
     236          31 :       break;
     237             :     case DW_FORM_GNU_addr_index:
     238             :     case DW_FORM_GNU_str_index:
     239         175 :       Value.uval = data.getULEB128(offset_ptr);
     240         175 :       break;
     241             :     default:
     242             :       return false;
     243             :     }
     244             :   } while (indirect);
     245             : 
     246      102119 :   if (is_block) {
     247        1468 :     StringRef str = data.getData().substr(*offset_ptr, Value.uval);
     248         734 :     Value.data = nullptr;
     249         734 :     if (!str.empty()) {
     250         734 :       Value.data = reinterpret_cast<const uint8_t *>(str.data());
     251         734 :       *offset_ptr += Value.uval;
     252             :     }
     253             :   }
     254             : 
     255             :   return true;
     256             : }
     257             : 
     258             : bool
     259           0 : DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
     260             :                           const DWARFUnit *cu) const {
     261           0 :   return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
     262             : }
     263             : 
     264             : bool
     265     6198796 : DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
     266             :                           uint32_t *offset_ptr, const DWARFUnit *cu) {
     267     6198796 :   bool indirect = false;
     268             :   do {
     269     6198796 :     switch (form) {
     270             :     // Blocks if inlined data that have a length field and the data bytes
     271             :     // inlined in the .debug_info
     272             :     case DW_FORM_exprloc:
     273             :     case DW_FORM_block: {
     274      204741 :       uint64_t size = debug_info_data.getULEB128(offset_ptr);
     275      204741 :       *offset_ptr += size;
     276      204741 :       return true;
     277             :     }
     278             :     case DW_FORM_block1: {
     279        1185 :       uint8_t size = debug_info_data.getU8(offset_ptr);
     280        1185 :       *offset_ptr += size;
     281        1185 :       return true;
     282             :     }
     283             :     case DW_FORM_block2: {
     284         139 :       uint16_t size = debug_info_data.getU16(offset_ptr);
     285         139 :       *offset_ptr += size;
     286         139 :       return true;
     287             :     }
     288             :     case DW_FORM_block4: {
     289           0 :       uint32_t size = debug_info_data.getU32(offset_ptr);
     290           0 :       *offset_ptr += size;
     291           0 :       return true;
     292             :     }
     293             : 
     294             :     // Inlined NULL terminated C-strings
     295             :     case DW_FORM_string:
     296      317315 :       debug_info_data.getCStr(offset_ptr);
     297      317315 :       return true;
     298             : 
     299             :     // Compile unit address sized values
     300             :     case DW_FORM_addr:
     301       36682 :       *offset_ptr += cu->getAddressByteSize();
     302       36682 :       return true;
     303             :     case DW_FORM_ref_addr:
     304           8 :       *offset_ptr += getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
     305           4 :       return true;
     306             : 
     307             :     // 0 byte values - implied from the form.
     308             :     case DW_FORM_flag_present:
     309             :       return true;
     310             : 
     311             :     // 1 byte values
     312             :     case DW_FORM_data1:
     313             :     case DW_FORM_flag:
     314             :     case DW_FORM_ref1:
     315       36334 :       *offset_ptr += 1;
     316       36334 :       return true;
     317             : 
     318             :     // 2 byte values
     319             :     case DW_FORM_data2:
     320             :     case DW_FORM_ref2:
     321        4345 :       *offset_ptr += 2;
     322        4345 :       return true;
     323             : 
     324             :     // 4 byte values
     325             :     case DW_FORM_strp:
     326             :     case DW_FORM_data4:
     327             :     case DW_FORM_ref4:
     328      171220 :       *offset_ptr += 4;
     329      171220 :       return true;
     330             : 
     331             :     // 8 byte values
     332             :     case DW_FORM_data8:
     333             :     case DW_FORM_ref8:
     334             :     case DW_FORM_ref_sig8:
     335         127 :       *offset_ptr += 8;
     336         127 :       return true;
     337             : 
     338             :     // signed or unsigned LEB 128 values
     339             :     //  case DW_FORM_APPLE_db_str:
     340             :     case DW_FORM_sdata:
     341             :     case DW_FORM_udata:
     342             :     case DW_FORM_ref_udata:
     343             :     case DW_FORM_GNU_str_index:
     344             :     case DW_FORM_GNU_addr_index:
     345      175494 :       debug_info_data.getULEB128(offset_ptr);
     346      175494 :       return true;
     347             : 
     348             :     case DW_FORM_indirect:
     349           0 :       indirect = true;
     350           0 :       form = debug_info_data.getULEB128(offset_ptr);
     351             :       break;
     352             : 
     353             :     // FIXME: 4 for DWARF32, 8 for DWARF64.
     354             :     case DW_FORM_sec_offset:
     355       21878 :       *offset_ptr += 4;
     356       21878 :       return true;
     357             : 
     358             :     default:
     359           0 :       return false;
     360             :     }
     361             :   } while (indirect);
     362             :   return true;
     363             : }
     364             : 
     365             : void
     366        7919 : DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
     367        7919 :   uint64_t uvalue = Value.uval;
     368        7919 :   bool cu_relative_offset = false;
     369             : 
     370        7919 :   switch (Form) {
     371        2100 :   case DW_FORM_addr:      OS << format("0x%016" PRIx64, uvalue); break;
     372             :   case DW_FORM_GNU_addr_index: {
     373          54 :     OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
     374             :     uint64_t Address;
     375          18 :     if (cu->getAddrOffsetSectionItem(uvalue, Address))
     376          54 :       OS << format("0x%016" PRIx64, Address);
     377             :     else
     378           0 :       OS << "<no .debug_addr section>";
     379             :     break;
     380             :   }
     381         801 :   case DW_FORM_flag_present: OS << "true"; break;
     382             :   case DW_FORM_flag:
     383        2934 :   case DW_FORM_data1:     OS << format("0x%02x", (uint8_t)uvalue); break;
     384         138 :   case DW_FORM_data2:     OS << format("0x%04x", (uint16_t)uvalue); break;
     385        1725 :   case DW_FORM_data4:     OS << format("0x%08x", (uint32_t)uvalue); break;
     386             :   case DW_FORM_ref_sig8:
     387         174 :   case DW_FORM_data8:     OS << format("0x%016" PRIx64, uvalue); break;
     388             :   case DW_FORM_string:
     389          67 :     OS << '"';
     390         134 :     OS.write_escaped(Value.cstr);
     391          67 :     OS << '"';
     392          67 :     break;
     393             :   case DW_FORM_exprloc:
     394             :   case DW_FORM_block:
     395             :   case DW_FORM_block1:
     396             :   case DW_FORM_block2:
     397             :   case DW_FORM_block4:
     398         734 :     if (uvalue > 0) {
     399         734 :       switch (Form) {
     400             :       case DW_FORM_exprloc:
     401        1245 :       case DW_FORM_block:  OS << format("<0x%" PRIx64 "> ", uvalue);     break;
     402         957 :       case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue);  break;
     403           0 :       case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
     404           0 :       case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
     405             :       default: break;
     406             :       }
     407             : 
     408         734 :       const uint8_t* data_ptr = Value.data;
     409         734 :       if (data_ptr) {
     410             :         // uvalue contains size of block
     411         734 :         const uint8_t* end_data_ptr = data_ptr + uvalue;
     412        3331 :         while (data_ptr < end_data_ptr) {
     413        3726 :           OS << format("%2.2x ", *data_ptr);
     414        1863 :           ++data_ptr;
     415             :         }
     416             :       }
     417             :       else
     418           0 :         OS << "NULL";
     419             :     }
     420             :     break;
     421             : 
     422          41 :   case DW_FORM_sdata:     OS << Value.sval; break;
     423          19 :   case DW_FORM_udata:     OS << Value.uval; break;
     424             :   case DW_FORM_strp: {
     425        6129 :     OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
     426        2043 :     Optional<const char *> DbgStr = getAsCString(cu);
     427        2043 :     if (DbgStr.hasValue()) {
     428        4086 :       raw_ostream &COS = WithColor(OS, syntax::String);
     429        2043 :       COS << '"';
     430        4086 :       COS.write_escaped(DbgStr.getValue());
     431        2043 :       COS << '"';
     432             :     }
     433             :     break;
     434             :   }
     435             :   case DW_FORM_GNU_str_index: {
     436         414 :     OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
     437         138 :     Optional<const char *> DbgStr = getAsCString(cu);
     438         138 :     if (DbgStr.hasValue()) {
     439         276 :       raw_ostream &COS = WithColor(OS, syntax::String);
     440         138 :       COS << '"';
     441         276 :       COS.write_escaped(DbgStr.getValue());
     442         138 :       COS << '"';
     443             :     }
     444             :     break;
     445             :   }
     446             :   case DW_FORM_ref_addr:
     447          99 :     OS << format("0x%016" PRIx64, uvalue);
     448          33 :     break;
     449             :   case DW_FORM_ref1:
     450           0 :     cu_relative_offset = true;
     451           0 :     OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
     452           0 :     break;
     453             :   case DW_FORM_ref2:
     454           0 :     cu_relative_offset = true;
     455           0 :     OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
     456           0 :     break;
     457             :   case DW_FORM_ref4:
     458        1452 :     cu_relative_offset = true;
     459        4356 :     OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
     460        1452 :     break;
     461             :   case DW_FORM_ref8:
     462           0 :     cu_relative_offset = true;
     463           0 :     OS << format("cu + 0x%8.8" PRIx64, uvalue);
     464           0 :     break;
     465             :   case DW_FORM_ref_udata:
     466           0 :     cu_relative_offset = true;
     467           0 :     OS << format("cu + 0x%" PRIx64, uvalue);
     468           0 :     break;
     469             : 
     470             :     // All DW_FORM_indirect attributes should be resolved prior to calling
     471             :     // this function
     472             :   case DW_FORM_indirect:
     473           0 :     OS << "DW_FORM_indirect";
     474           0 :     break;
     475             : 
     476             :     // Should be formatted to 64-bit for DWARF64.
     477             :   case DW_FORM_sec_offset:
     478         648 :     OS << format("0x%08x", (uint32_t)uvalue);
     479         216 :     break;
     480             : 
     481             :   default:
     482           0 :     OS << format("DW_FORM(0x%4.4x)", Form);
     483           0 :     break;
     484             :   }
     485             : 
     486        7919 :   if (cu_relative_offset) {
     487        1452 :     OS << " => {";
     488        2904 :     WithColor(OS, syntax::Address).get()
     489        4356 :       << format("0x%8.8" PRIx64, uvalue + (cu ? cu->getOffset() : 0));
     490        1452 :     OS << "}";
     491             :   }
     492        7919 : }
     493             : 
     494        3821 : Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const {
     495        3821 :   if (!isFormClass(FC_String))
     496             :     return None;
     497        3821 :   if (Form == DW_FORM_string)
     498          25 :     return Value.cstr;
     499        3796 :   if (!U)
     500             :     return None;
     501        3796 :   uint32_t Offset = Value.uval;
     502        3796 :   if (Form == DW_FORM_GNU_str_index) {
     503             :     uint32_t StrOffset;
     504         151 :     if (!U->getStringOffsetSectionItem(Offset, StrOffset))
     505           0 :       return None;
     506         151 :     Offset = StrOffset;
     507             :   }
     508        3796 :   if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
     509             :     return Str;
     510             :   }
     511             :   return None;
     512             : }
     513             : 
     514       58712 : Optional<uint64_t> DWARFFormValue::getAsAddress(const DWARFUnit *U) const {
     515       58712 :   if (!isFormClass(FC_Address))
     516             :     return None;
     517       41176 :   if (Form == DW_FORM_GNU_addr_index) {
     518           6 :     uint32_t Index = Value.uval;
     519             :     uint64_t Result;
     520           6 :     if (!U || !U->getAddrOffsetSectionItem(Index, Result))
     521             :       return None;
     522             :     return Result;
     523             :   }
     524       41170 :   return Value.uval;
     525             : }
     526             : 
     527         414 : Optional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const {
     528         414 :   if (!isFormClass(FC_Reference))
     529             :     return None;
     530         414 :   switch (Form) {
     531             :   case DW_FORM_ref1:
     532             :   case DW_FORM_ref2:
     533             :   case DW_FORM_ref4:
     534             :   case DW_FORM_ref8:
     535             :   case DW_FORM_ref_udata:
     536         406 :     if (!U)
     537             :       return None;
     538         406 :     return Value.uval + U->getOffset();
     539             :   case DW_FORM_ref_addr:
     540           8 :     return Value.uval;
     541             :   // FIXME: Add proper support for DW_FORM_ref_sig8
     542             :   default:
     543           0 :     return Value.uval;
     544             :   }
     545             : }
     546             : 
     547       13174 : Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
     548       13174 :   if (!isFormClass(FC_SectionOffset))
     549             :     return None;
     550       13174 :   return Value.uval;
     551             : }
     552             : 
     553       29195 : Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
     554       64981 :   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag))
     555       52958 :       || Form == DW_FORM_sdata)
     556             :     return None;
     557       23722 :   return Value.uval;
     558             : }
     559             : 
     560           0 : Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
     561           0 :   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
     562             :     return None;
     563           0 :   return ArrayRef<uint8_t>(Value.data, Value.uval);
     564             : }
     565             : 

Generated by: LCOV version 1.11