LLVM API Documentation

DWARFFormValue.cpp
Go to the documentation of this file.
00001 //===-- DWARFFormValue.cpp ------------------------------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/DebugInfo/DWARFFormValue.h"
00011 #include "DWARFCompileUnit.h"
00012 #include "DWARFContext.h"
00013 #include "llvm/ADT/ArrayRef.h"
00014 #include "llvm/ADT/StringRef.h"
00015 #include "llvm/Support/Debug.h"
00016 #include "llvm/Support/Dwarf.h"
00017 #include "llvm/Support/Format.h"
00018 #include "llvm/Support/raw_ostream.h"
00019 #include <cassert>
00020 using namespace llvm;
00021 using namespace dwarf;
00022 
00023 namespace {
00024 uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
00025   // FIXME: Support DWARF64.
00026   return (Version == 2) ? AddrSize : 4;
00027 }
00028 
00029 template <uint8_t AddrSize, uint8_t RefAddrSize>
00030 ArrayRef<uint8_t> makeFixedFormSizesArrayRef() {
00031   static const uint8_t sizes[] = {
00032     0,           // 0x00 unused
00033     AddrSize,    // 0x01 DW_FORM_addr
00034     0,           // 0x02 unused
00035     0,           // 0x03 DW_FORM_block2
00036     0,           // 0x04 DW_FORM_block4
00037     2,           // 0x05 DW_FORM_data2
00038     4,           // 0x06 DW_FORM_data4
00039     8,           // 0x07 DW_FORM_data8
00040     0,           // 0x08 DW_FORM_string
00041     0,           // 0x09 DW_FORM_block
00042     0,           // 0x0a DW_FORM_block1
00043     1,           // 0x0b DW_FORM_data1
00044     1,           // 0x0c DW_FORM_flag
00045     0,           // 0x0d DW_FORM_sdata
00046     4,           // 0x0e DW_FORM_strp
00047     0,           // 0x0f DW_FORM_udata
00048     RefAddrSize, // 0x10 DW_FORM_ref_addr
00049     1,           // 0x11 DW_FORM_ref1
00050     2,           // 0x12 DW_FORM_ref2
00051     4,           // 0x13 DW_FORM_ref4
00052     8,           // 0x14 DW_FORM_ref8
00053     0,           // 0x15 DW_FORM_ref_udata
00054     0,           // 0x16 DW_FORM_indirect
00055     4,           // 0x17 DW_FORM_sec_offset
00056     0,           // 0x18 DW_FORM_exprloc
00057     0,           // 0x19 DW_FORM_flag_present
00058   };
00059   return makeArrayRef(sizes);
00060 }
00061 }
00062 
00063 ArrayRef<uint8_t> DWARFFormValue::getFixedFormSizes(uint8_t AddrSize,
00064                                                     uint16_t Version) {
00065   uint8_t RefAddrSize = getRefAddrSize(AddrSize, Version);
00066   if (AddrSize == 4 && RefAddrSize == 4)
00067     return makeFixedFormSizesArrayRef<4, 4>();
00068   if (AddrSize == 4 && RefAddrSize == 8)
00069     return makeFixedFormSizesArrayRef<4, 8>();
00070   if (AddrSize == 8 && RefAddrSize == 4)
00071     return makeFixedFormSizesArrayRef<8, 4>();
00072   if (AddrSize == 8 && RefAddrSize == 8)
00073     return makeFixedFormSizesArrayRef<8, 8>();
00074   return None;
00075 }
00076 
00077 static const DWARFFormValue::FormClass DWARF4FormClasses[] = {
00078   DWARFFormValue::FC_Unknown,       // 0x0
00079   DWARFFormValue::FC_Address,       // 0x01 DW_FORM_addr
00080   DWARFFormValue::FC_Unknown,       // 0x02 unused
00081   DWARFFormValue::FC_Block,         // 0x03 DW_FORM_block2
00082   DWARFFormValue::FC_Block,         // 0x04 DW_FORM_block4
00083   DWARFFormValue::FC_Constant,      // 0x05 DW_FORM_data2
00084   // --- These can be FC_SectionOffset in DWARF3 and below:
00085   DWARFFormValue::FC_Constant,      // 0x06 DW_FORM_data4
00086   DWARFFormValue::FC_Constant,      // 0x07 DW_FORM_data8
00087   // ---
00088   DWARFFormValue::FC_String,        // 0x08 DW_FORM_string
00089   DWARFFormValue::FC_Block,         // 0x09 DW_FORM_block
00090   DWARFFormValue::FC_Block,         // 0x0a DW_FORM_block1
00091   DWARFFormValue::FC_Constant,      // 0x0b DW_FORM_data1
00092   DWARFFormValue::FC_Flag,          // 0x0c DW_FORM_flag
00093   DWARFFormValue::FC_Constant,      // 0x0d DW_FORM_sdata
00094   DWARFFormValue::FC_String,        // 0x0e DW_FORM_strp
00095   DWARFFormValue::FC_Constant,      // 0x0f DW_FORM_udata
00096   DWARFFormValue::FC_Reference,     // 0x10 DW_FORM_ref_addr
00097   DWARFFormValue::FC_Reference,     // 0x11 DW_FORM_ref1
00098   DWARFFormValue::FC_Reference,     // 0x12 DW_FORM_ref2
00099   DWARFFormValue::FC_Reference,     // 0x13 DW_FORM_ref4
00100   DWARFFormValue::FC_Reference,     // 0x14 DW_FORM_ref8
00101   DWARFFormValue::FC_Reference,     // 0x15 DW_FORM_ref_udata
00102   DWARFFormValue::FC_Indirect,      // 0x16 DW_FORM_indirect
00103   DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
00104   DWARFFormValue::FC_Exprloc,       // 0x18 DW_FORM_exprloc
00105   DWARFFormValue::FC_Flag,          // 0x19 DW_FORM_flag_present
00106 };
00107 
00108 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
00109   // First, check DWARF4 form classes.
00110   if (Form < ArrayRef<FormClass>(DWARF4FormClasses).size() &&
00111       DWARF4FormClasses[Form] == FC)
00112     return true;
00113   // Check DW_FORM_ref_sig8 from DWARF4.
00114   if (Form == DW_FORM_ref_sig8)
00115     return (FC == FC_Reference);
00116   // Check for some DWARF5 forms.
00117   if (Form == DW_FORM_GNU_addr_index)
00118     return (FC == FC_Address);
00119   if (Form == DW_FORM_GNU_str_index)
00120     return (FC == FC_String);
00121   // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
00122   // Don't check for DWARF version here, as some producers may still do this
00123   // by mistake.
00124   if ((Form == DW_FORM_data4 || Form == DW_FORM_data8) &&
00125       FC == FC_SectionOffset)
00126     return true;
00127   return false;
00128 }
00129 
00130 bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
00131                                   const DWARFUnit *cu) {
00132   bool indirect = false;
00133   bool is_block = false;
00134   Value.data = nullptr;
00135   // Read the value for the form into value and follow and DW_FORM_indirect
00136   // instances we run into
00137   do {
00138     indirect = false;
00139     switch (Form) {
00140     case DW_FORM_addr:
00141     case DW_FORM_ref_addr: {
00142       uint16_t AddrSize =
00143           (Form == DW_FORM_addr)
00144               ? cu->getAddressByteSize()
00145               : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
00146       RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
00147       if (AI != cu->getRelocMap()->end()) {
00148         const std::pair<uint8_t, int64_t> &R = AI->second;
00149         Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second;
00150       } else
00151         Value.uval = data.getUnsigned(offset_ptr, AddrSize);
00152       break;
00153     }
00154     case DW_FORM_exprloc:
00155     case DW_FORM_block:
00156       Value.uval = data.getULEB128(offset_ptr);
00157       is_block = true;
00158       break;
00159     case DW_FORM_block1:
00160       Value.uval = data.getU8(offset_ptr);
00161       is_block = true;
00162       break;
00163     case DW_FORM_block2:
00164       Value.uval = data.getU16(offset_ptr);
00165       is_block = true;
00166       break;
00167     case DW_FORM_block4:
00168       Value.uval = data.getU32(offset_ptr);
00169       is_block = true;
00170       break;
00171     case DW_FORM_data1:
00172     case DW_FORM_ref1:
00173     case DW_FORM_flag:
00174       Value.uval = data.getU8(offset_ptr);
00175       break;
00176     case DW_FORM_data2:
00177     case DW_FORM_ref2:
00178       Value.uval = data.getU16(offset_ptr);
00179       break;
00180     case DW_FORM_data4:
00181     case DW_FORM_ref4: {
00182       RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
00183       Value.uval = data.getU32(offset_ptr);
00184       if (AI != cu->getRelocMap()->end())
00185         Value.uval += AI->second.second;
00186       break;
00187     }
00188     case DW_FORM_data8:
00189     case DW_FORM_ref8:
00190       Value.uval = data.getU64(offset_ptr);
00191       break;
00192     case DW_FORM_sdata:
00193       Value.sval = data.getSLEB128(offset_ptr);
00194       break;
00195     case DW_FORM_strp: {
00196       RelocAddrMap::const_iterator AI
00197         = cu->getRelocMap()->find(*offset_ptr);
00198       if (AI != cu->getRelocMap()->end()) {
00199         const std::pair<uint8_t, int64_t> &R = AI->second;
00200         Value.uval = data.getU32(offset_ptr) + R.second;
00201       } else
00202         Value.uval = data.getU32(offset_ptr);
00203       break;
00204     }
00205     case DW_FORM_udata:
00206     case DW_FORM_ref_udata:
00207       Value.uval = data.getULEB128(offset_ptr);
00208       break;
00209     case DW_FORM_string:
00210       Value.cstr = data.getCStr(offset_ptr);
00211       break;
00212     case DW_FORM_indirect:
00213       Form = data.getULEB128(offset_ptr);
00214       indirect = true;
00215       break;
00216     case DW_FORM_sec_offset: {
00217       // FIXME: This is 64-bit for DWARF64.
00218       RelocAddrMap::const_iterator AI
00219         = cu->getRelocMap()->find(*offset_ptr);
00220       if (AI != cu->getRelocMap()->end()) {
00221         const std::pair<uint8_t, int64_t> &R = AI->second;
00222         Value.uval = data.getU32(offset_ptr) + R.second;
00223       } else
00224         Value.uval = data.getU32(offset_ptr);
00225       break;
00226     }
00227     case DW_FORM_flag_present:
00228       Value.uval = 1;
00229       break;
00230     case DW_FORM_ref_sig8:
00231       Value.uval = data.getU64(offset_ptr);
00232       break;
00233     case DW_FORM_GNU_addr_index:
00234     case DW_FORM_GNU_str_index:
00235       Value.uval = data.getULEB128(offset_ptr);
00236       break;
00237     default:
00238       return false;
00239     }
00240   } while (indirect);
00241 
00242   if (is_block) {
00243     StringRef str = data.getData().substr(*offset_ptr, Value.uval);
00244     Value.data = nullptr;
00245     if (!str.empty()) {
00246       Value.data = reinterpret_cast<const uint8_t *>(str.data());
00247       *offset_ptr += Value.uval;
00248     }
00249   }
00250 
00251   return true;
00252 }
00253 
00254 bool
00255 DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
00256                           const DWARFUnit *cu) const {
00257   return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
00258 }
00259 
00260 bool
00261 DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
00262                           uint32_t *offset_ptr, const DWARFUnit *cu) {
00263   bool indirect = false;
00264   do {
00265     switch (form) {
00266     // Blocks if inlined data that have a length field and the data bytes
00267     // inlined in the .debug_info
00268     case DW_FORM_exprloc:
00269     case DW_FORM_block: {
00270       uint64_t size = debug_info_data.getULEB128(offset_ptr);
00271       *offset_ptr += size;
00272       return true;
00273     }
00274     case DW_FORM_block1: {
00275       uint8_t size = debug_info_data.getU8(offset_ptr);
00276       *offset_ptr += size;
00277       return true;
00278     }
00279     case DW_FORM_block2: {
00280       uint16_t size = debug_info_data.getU16(offset_ptr);
00281       *offset_ptr += size;
00282       return true;
00283     }
00284     case DW_FORM_block4: {
00285       uint32_t size = debug_info_data.getU32(offset_ptr);
00286       *offset_ptr += size;
00287       return true;
00288     }
00289 
00290     // Inlined NULL terminated C-strings
00291     case DW_FORM_string:
00292       debug_info_data.getCStr(offset_ptr);
00293       return true;
00294 
00295     // Compile unit address sized values
00296     case DW_FORM_addr:
00297       *offset_ptr += cu->getAddressByteSize();
00298       return true;
00299     case DW_FORM_ref_addr:
00300       *offset_ptr += getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
00301       return true;
00302 
00303     // 0 byte values - implied from the form.
00304     case DW_FORM_flag_present:
00305       return true;
00306 
00307     // 1 byte values
00308     case DW_FORM_data1:
00309     case DW_FORM_flag:
00310     case DW_FORM_ref1:
00311       *offset_ptr += 1;
00312       return true;
00313 
00314     // 2 byte values
00315     case DW_FORM_data2:
00316     case DW_FORM_ref2:
00317       *offset_ptr += 2;
00318       return true;
00319 
00320     // 4 byte values
00321     case DW_FORM_strp:
00322     case DW_FORM_data4:
00323     case DW_FORM_ref4:
00324       *offset_ptr += 4;
00325       return true;
00326 
00327     // 8 byte values
00328     case DW_FORM_data8:
00329     case DW_FORM_ref8:
00330     case DW_FORM_ref_sig8:
00331       *offset_ptr += 8;
00332       return true;
00333 
00334     // signed or unsigned LEB 128 values
00335     //  case DW_FORM_APPLE_db_str:
00336     case DW_FORM_sdata:
00337     case DW_FORM_udata:
00338     case DW_FORM_ref_udata:
00339     case DW_FORM_GNU_str_index:
00340     case DW_FORM_GNU_addr_index:
00341       debug_info_data.getULEB128(offset_ptr);
00342       return true;
00343 
00344     case DW_FORM_indirect:
00345       indirect = true;
00346       form = debug_info_data.getULEB128(offset_ptr);
00347       break;
00348 
00349     // FIXME: 4 for DWARF32, 8 for DWARF64.
00350     case DW_FORM_sec_offset:
00351       *offset_ptr += 4;
00352       return true;
00353 
00354     default:
00355       return false;
00356     }
00357   } while (indirect);
00358   return true;
00359 }
00360 
00361 void
00362 DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
00363   DataExtractor debug_str_data(cu->getStringSection(), true, 0);
00364   DataExtractor debug_str_offset_data(cu->getStringOffsetSection(), true, 0);
00365   uint64_t uvalue = Value.uval;
00366   bool cu_relative_offset = false;
00367 
00368   switch (Form) {
00369   case DW_FORM_addr:      OS << format("0x%016" PRIx64, uvalue); break;
00370   case DW_FORM_GNU_addr_index: {
00371     OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
00372     uint64_t Address;
00373     if (cu->getAddrOffsetSectionItem(uvalue, Address))
00374       OS << format("0x%016" PRIx64, Address);
00375     else
00376       OS << "<no .debug_addr section>";
00377     break;
00378   }
00379   case DW_FORM_flag_present: OS << "true"; break;
00380   case DW_FORM_flag:
00381   case DW_FORM_data1:     OS << format("0x%02x", (uint8_t)uvalue); break;
00382   case DW_FORM_data2:     OS << format("0x%04x", (uint16_t)uvalue); break;
00383   case DW_FORM_data4:     OS << format("0x%08x", (uint32_t)uvalue); break;
00384   case DW_FORM_ref_sig8:
00385   case DW_FORM_data8:     OS << format("0x%016" PRIx64, uvalue); break;
00386   case DW_FORM_string:
00387     OS << '"';
00388     OS.write_escaped(Value.cstr);
00389     OS << '"';
00390     break;
00391   case DW_FORM_exprloc:
00392   case DW_FORM_block:
00393   case DW_FORM_block1:
00394   case DW_FORM_block2:
00395   case DW_FORM_block4:
00396     if (uvalue > 0) {
00397       switch (Form) {
00398       case DW_FORM_exprloc:
00399       case DW_FORM_block:  OS << format("<0x%" PRIx64 "> ", uvalue);     break;
00400       case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue);  break;
00401       case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
00402       case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
00403       default: break;
00404       }
00405 
00406       const uint8_t* data_ptr = Value.data;
00407       if (data_ptr) {
00408         // uvalue contains size of block
00409         const uint8_t* end_data_ptr = data_ptr + uvalue;
00410         while (data_ptr < end_data_ptr) {
00411           OS << format("%2.2x ", *data_ptr);
00412           ++data_ptr;
00413         }
00414       }
00415       else
00416         OS << "NULL";
00417     }
00418     break;
00419 
00420   case DW_FORM_sdata:     OS << Value.sval; break;
00421   case DW_FORM_udata:     OS << Value.uval; break;
00422   case DW_FORM_strp: {
00423     OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
00424     Optional<const char *> DbgStr = getAsCString(cu);
00425     if (DbgStr.hasValue()) {
00426       OS << '"';
00427       OS.write_escaped(DbgStr.getValue());
00428       OS << '"';
00429     }
00430     break;
00431   }
00432   case DW_FORM_GNU_str_index: {
00433     OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
00434     Optional<const char *> DbgStr = getAsCString(cu);
00435     if (DbgStr.hasValue()) {
00436       OS << '"';
00437       OS.write_escaped(DbgStr.getValue());
00438       OS << '"';
00439     }
00440     break;
00441   }
00442   case DW_FORM_ref_addr:
00443     OS << format("0x%016" PRIx64, uvalue);
00444     break;
00445   case DW_FORM_ref1:
00446     cu_relative_offset = true;
00447     OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
00448     break;
00449   case DW_FORM_ref2:
00450     cu_relative_offset = true;
00451     OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
00452     break;
00453   case DW_FORM_ref4:
00454     cu_relative_offset = true;
00455     OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
00456     break;
00457   case DW_FORM_ref8:
00458     cu_relative_offset = true;
00459     OS << format("cu + 0x%8.8" PRIx64, uvalue);
00460     break;
00461   case DW_FORM_ref_udata:
00462     cu_relative_offset = true;
00463     OS << format("cu + 0x%" PRIx64, uvalue);
00464     break;
00465 
00466     // All DW_FORM_indirect attributes should be resolved prior to calling
00467     // this function
00468   case DW_FORM_indirect:
00469     OS << "DW_FORM_indirect";
00470     break;
00471 
00472     // Should be formatted to 64-bit for DWARF64.
00473   case DW_FORM_sec_offset:
00474     OS << format("0x%08x", (uint32_t)uvalue);
00475     break;
00476 
00477   default:
00478     OS << format("DW_FORM(0x%4.4x)", Form);
00479     break;
00480   }
00481 
00482   if (cu_relative_offset)
00483     OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0));
00484 }
00485 
00486 Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const {
00487   if (!isFormClass(FC_String))
00488     return None;
00489   if (Form == DW_FORM_string)
00490     return Value.cstr;
00491   if (!U)
00492     return None;
00493   uint32_t Offset = Value.uval;
00494   if (Form == DW_FORM_GNU_str_index) {
00495     uint32_t StrOffset;
00496     if (!U->getStringOffsetSectionItem(Offset, StrOffset))
00497       return None;
00498     Offset = StrOffset;
00499   }
00500   if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
00501     return Str;
00502   }
00503   return None;
00504 }
00505 
00506 Optional<uint64_t> DWARFFormValue::getAsAddress(const DWARFUnit *U) const {
00507   if (!isFormClass(FC_Address))
00508     return None;
00509   if (Form == DW_FORM_GNU_addr_index) {
00510     uint32_t Index = Value.uval;
00511     uint64_t Result;
00512     if (!U || !U->getAddrOffsetSectionItem(Index, Result))
00513       return None;
00514     return Result;
00515   }
00516   return Value.uval;
00517 }
00518 
00519 Optional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const {
00520   if (!isFormClass(FC_Reference))
00521     return None;
00522   switch (Form) {
00523   case DW_FORM_ref1:
00524   case DW_FORM_ref2:
00525   case DW_FORM_ref4:
00526   case DW_FORM_ref8:
00527   case DW_FORM_ref_udata:
00528     if (!U)
00529       return None;
00530     return Value.uval + U->getOffset();
00531   case DW_FORM_ref_addr:
00532     return Value.uval;
00533   // FIXME: Add proper support for DW_FORM_ref_sig8
00534   default:
00535     return Value.uval;
00536   }
00537 }
00538 
00539 Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
00540   if (!isFormClass(FC_SectionOffset))
00541     return None;
00542   return Value.uval;
00543 }
00544 
00545 Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
00546   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag))
00547       || Form == DW_FORM_sdata)
00548     return None;
00549   return Value.uval;
00550 }
00551 
00552 Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
00553   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
00554     return None;
00555   return ArrayRef<uint8_t>(Value.data, Value.uval);
00556 }
00557