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