Home | History | Annotate | Download | only in DebugInfo
      1 //===-- DWARFDebugInfoEntry.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 "DWARFDebugInfoEntry.h"
     11 #include "DWARFCompileUnit.h"
     12 #include "DWARFContext.h"
     13 #include "DWARFDebugAbbrev.h"
     14 #include "llvm/DebugInfo/DWARFFormValue.h"
     15 #include "llvm/Support/Debug.h"
     16 #include "llvm/Support/Dwarf.h"
     17 #include "llvm/Support/Format.h"
     18 #include "llvm/Support/raw_ostream.h"
     19 using namespace llvm;
     20 using namespace dwarf;
     21 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
     22 
     23 void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
     24                                       unsigned recurseDepth,
     25                                       unsigned indent) const {
     26   DataExtractor debug_info_data = u->getDebugInfoExtractor();
     27   uint32_t offset = Offset;
     28 
     29   if (debug_info_data.isValidOffset(offset)) {
     30     uint32_t abbrCode = debug_info_data.getULEB128(&offset);
     31 
     32     OS << format("\n0x%8.8x: ", Offset);
     33     if (abbrCode) {
     34       if (AbbrevDecl) {
     35         const char *tagString = TagString(getTag());
     36         if (tagString)
     37           OS.indent(indent) << tagString;
     38         else
     39           OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag());
     40         OS << format(" [%u] %c\n", abbrCode,
     41                      AbbrevDecl->hasChildren() ? '*' : ' ');
     42 
     43         // Dump all data in the DIE for the attributes.
     44         for (const auto &AttrSpec : AbbrevDecl->attributes()) {
     45           dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent);
     46         }
     47 
     48         const DWARFDebugInfoEntryMinimal *child = getFirstChild();
     49         if (recurseDepth > 0 && child) {
     50           while (child) {
     51             child->dump(OS, u, recurseDepth-1, indent+2);
     52             child = child->getSibling();
     53           }
     54         }
     55       } else {
     56         OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
     57            << abbrCode << '\n';
     58       }
     59     } else {
     60       OS.indent(indent) << "NULL\n";
     61     }
     62   }
     63 }
     64 
     65 void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
     66                                                const DWARFUnit *u,
     67                                                uint32_t *offset_ptr,
     68                                                uint16_t attr, uint16_t form,
     69                                                unsigned indent) const {
     70   OS << "            ";
     71   OS.indent(indent+2);
     72   const char *attrString = AttributeString(attr);
     73   if (attrString)
     74     OS << attrString;
     75   else
     76     OS << format("DW_AT_Unknown_%x", attr);
     77   const char *formString = FormEncodingString(form);
     78   if (formString)
     79     OS << " [" << formString << ']';
     80   else
     81     OS << format(" [DW_FORM_Unknown_%x]", form);
     82 
     83   DWARFFormValue formValue(form);
     84 
     85   if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u))
     86     return;
     87 
     88   OS << "\t(";
     89   formValue.dump(OS, u);
     90   OS << ")\n";
     91 }
     92 
     93 bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U,
     94                                              uint32_t *OffsetPtr) {
     95   Offset = *OffsetPtr;
     96   DataExtractor DebugInfoData = U->getDebugInfoExtractor();
     97   uint32_t UEndOffset = U->getNextUnitOffset();
     98   if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
     99     return false;
    100   uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
    101   if (0 == AbbrCode) {
    102     // NULL debug tag entry.
    103     AbbrevDecl = nullptr;
    104     return true;
    105   }
    106   AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
    107   if (nullptr == AbbrevDecl) {
    108     // Restore the original offset.
    109     *OffsetPtr = Offset;
    110     return false;
    111   }
    112   ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes(
    113       U->getAddressByteSize(), U->getVersion());
    114   assert(FixedFormSizes.size() > 0);
    115 
    116   // Skip all data in the .debug_info for the attributes
    117   for (const auto &AttrSpec : AbbrevDecl->attributes()) {
    118     uint16_t Form = AttrSpec.Form;
    119 
    120     uint8_t FixedFormSize =
    121         (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0;
    122     if (FixedFormSize)
    123       *OffsetPtr += FixedFormSize;
    124     else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) {
    125       // Restore the original offset.
    126       *OffsetPtr = Offset;
    127       return false;
    128     }
    129   }
    130   return true;
    131 }
    132 
    133 bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const {
    134   return getTag() == DW_TAG_subprogram;
    135 }
    136 
    137 bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const {
    138   uint32_t Tag = getTag();
    139   return Tag == DW_TAG_subprogram ||
    140          Tag == DW_TAG_inlined_subroutine;
    141 }
    142 
    143 bool DWARFDebugInfoEntryMinimal::getAttributeValue(
    144     const DWARFUnit *U, const uint16_t Attr, DWARFFormValue &FormValue) const {
    145   if (!AbbrevDecl)
    146     return false;
    147 
    148   uint32_t AttrIdx = AbbrevDecl->findAttributeIndex(Attr);
    149   if (AttrIdx == -1U)
    150     return false;
    151 
    152   DataExtractor DebugInfoData = U->getDebugInfoExtractor();
    153   uint32_t DebugInfoOffset = getOffset();
    154 
    155   // Skip the abbreviation code so we are at the data for the attributes
    156   DebugInfoData.getULEB128(&DebugInfoOffset);
    157 
    158   // Skip preceding attribute values.
    159   for (uint32_t i = 0; i < AttrIdx; ++i) {
    160     DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(i),
    161                               DebugInfoData, &DebugInfoOffset, U);
    162   }
    163 
    164   FormValue = DWARFFormValue(AbbrevDecl->getFormByIndex(AttrIdx));
    165   return FormValue.extractValue(DebugInfoData, &DebugInfoOffset, U);
    166 }
    167 
    168 const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
    169     const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const {
    170   DWARFFormValue FormValue;
    171   if (!getAttributeValue(U, Attr, FormValue))
    172     return FailValue;
    173   Optional<const char *> Result = FormValue.getAsCString(U);
    174   return Result.hasValue() ? Result.getValue() : FailValue;
    175 }
    176 
    177 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
    178     const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
    179   DWARFFormValue FormValue;
    180   if (!getAttributeValue(U, Attr, FormValue))
    181     return FailValue;
    182   Optional<uint64_t> Result = FormValue.getAsAddress(U);
    183   return Result.hasValue() ? Result.getValue() : FailValue;
    184 }
    185 
    186 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant(
    187     const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
    188   DWARFFormValue FormValue;
    189   if (!getAttributeValue(U, Attr, FormValue))
    190     return FailValue;
    191   Optional<uint64_t> Result = FormValue.getAsUnsignedConstant();
    192   return Result.hasValue() ? Result.getValue() : FailValue;
    193 }
    194 
    195 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
    196     const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
    197   DWARFFormValue FormValue;
    198   if (!getAttributeValue(U, Attr, FormValue))
    199     return FailValue;
    200   Optional<uint64_t> Result = FormValue.getAsReference(U);
    201   return Result.hasValue() ? Result.getValue() : FailValue;
    202 }
    203 
    204 uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset(
    205     const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
    206   DWARFFormValue FormValue;
    207   if (!getAttributeValue(U, Attr, FormValue))
    208     return FailValue;
    209   Optional<uint64_t> Result = FormValue.getAsSectionOffset();
    210   return Result.hasValue() ? Result.getValue() : FailValue;
    211 }
    212 
    213 uint64_t
    214 DWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U,
    215                                                    uint64_t FailValue) const {
    216   uint64_t Result =
    217       getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL);
    218   if (Result != -1ULL)
    219     return Result;
    220   return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue);
    221 }
    222 
    223 bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
    224                                                  uint64_t &LowPC,
    225                                                  uint64_t &HighPC) const {
    226   LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL);
    227   if (LowPC == -1ULL)
    228     return false;
    229   HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL);
    230   if (HighPC == -1ULL) {
    231     // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case
    232     // it represents function size.
    233     HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL);
    234     if (HighPC != -1ULL)
    235       HighPC += LowPC;
    236   }
    237   return (HighPC != -1ULL);
    238 }
    239 
    240 DWARFAddressRangesVector
    241 DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
    242   if (isNULL())
    243     return DWARFAddressRangesVector();
    244   // Single range specified by low/high PC.
    245   uint64_t LowPC, HighPC;
    246   if (getLowAndHighPC(U, LowPC, HighPC)) {
    247     return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
    248   }
    249   // Multiple ranges from .debug_ranges section.
    250   uint32_t RangesOffset =
    251       getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
    252   if (RangesOffset != -1U) {
    253     DWARFDebugRangeList RangeList;
    254     if (U->extractRangeList(RangesOffset, RangeList))
    255       return RangeList.getAbsoluteRanges(U->getBaseAddress());
    256   }
    257   return DWARFAddressRangesVector();
    258 }
    259 
    260 void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
    261     const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
    262   if (isNULL())
    263     return;
    264   if (isSubprogramDIE()) {
    265     const auto &DIERanges = getAddressRanges(U);
    266     Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
    267   }
    268 
    269   const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
    270   while (Child) {
    271     Child->collectChildrenAddressRanges(U, Ranges);
    272     Child = Child->getSibling();
    273   }
    274 }
    275 
    276 bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
    277     const DWARFUnit *U, const uint64_t Address) const {
    278   for (const auto& R : getAddressRanges(U)) {
    279     if (R.first <= Address && Address < R.second)
    280       return true;
    281   }
    282   return false;
    283 }
    284 
    285 const char *
    286 DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
    287                                               FunctionNameKind Kind) const {
    288   if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
    289     return nullptr;
    290   // Try to get mangled name only if it was asked for.
    291   if (Kind == FunctionNameKind::LinkageName) {
    292     if (const char *name =
    293             getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
    294       return name;
    295     if (const char *name =
    296             getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
    297       return name;
    298   }
    299   if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
    300     return name;
    301   // Try to get name from specification DIE.
    302   uint32_t spec_ref =
    303       getAttributeValueAsReference(U, DW_AT_specification, -1U);
    304   if (spec_ref != -1U) {
    305     DWARFDebugInfoEntryMinimal spec_die;
    306     if (spec_die.extractFast(U, &spec_ref)) {
    307       if (const char *name = spec_die.getSubroutineName(U, Kind))
    308         return name;
    309     }
    310   }
    311   // Try to get name from abstract origin DIE.
    312   uint32_t abs_origin_ref =
    313       getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U);
    314   if (abs_origin_ref != -1U) {
    315     DWARFDebugInfoEntryMinimal abs_origin_die;
    316     if (abs_origin_die.extractFast(U, &abs_origin_ref)) {
    317       if (const char *name = abs_origin_die.getSubroutineName(U, Kind))
    318         return name;
    319     }
    320   }
    321   return nullptr;
    322 }
    323 
    324 void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U,
    325                                                 uint32_t &CallFile,
    326                                                 uint32_t &CallLine,
    327                                                 uint32_t &CallColumn) const {
    328   CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0);
    329   CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0);
    330   CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0);
    331 }
    332 
    333 DWARFDebugInfoEntryInlinedChain
    334 DWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
    335     const DWARFUnit *U, const uint64_t Address) const {
    336   DWARFDebugInfoEntryInlinedChain InlinedChain;
    337   InlinedChain.U = U;
    338   if (isNULL())
    339     return InlinedChain;
    340   for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) {
    341     // Append current DIE to inlined chain only if it has correct tag
    342     // (e.g. it is not a lexical block).
    343     if (DIE->isSubroutineDIE()) {
    344       InlinedChain.DIEs.push_back(*DIE);
    345     }
    346     // Try to get child which also contains provided address.
    347     const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild();
    348     while (Child) {
    349       if (Child->addressRangeContainsAddress(U, Address)) {
    350         // Assume there is only one such child.
    351         break;
    352       }
    353       Child = Child->getSibling();
    354     }
    355     DIE = Child;
    356   }
    357   // Reverse the obtained chain to make the root of inlined chain last.
    358   std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end());
    359   return InlinedChain;
    360 }
    361