1bd5bc2161cb4520134d3e7eb6ac5f160b3653e78Eric Christopher//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===//
272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//                     The LLVM Compiler Infrastructure
472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source
672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details.
772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFDebugInfoEntry.h"
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFCompileUnit.h"
1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFContext.h"
1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFDebugAbbrev.h"
14cd61455798777446f35723fdb77f54a17e602009Alexey Samsonov#include "llvm/DebugInfo/DWARFFormValue.h"
15dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher#include "llvm/Support/Debug.h"
1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Dwarf.h"
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h"
1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h"
1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace dwarf;
21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestypedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
23cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikievoid DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                      unsigned recurseDepth,
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                      unsigned indent) const {
26cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  DataExtractor debug_info_data = u->getDebugInfoExtractor();
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = Offset;
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (debug_info_data.isValidOffset(offset)) {
3080cc2598f89d09a6df2b84a5f8cea813b280b17bBenjamin Kramer    uint32_t abbrCode = debug_info_data.getULEB128(&offset);
3172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
320942255f6daf49354dd1e19cc5f07aca65bea0d1Benjamin Kramer    OS << format("\n0x%8.8x: ", Offset);
3372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (abbrCode) {
3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (AbbrevDecl) {
3575c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer        const char *tagString = TagString(getTag());
3675c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer        if (tagString)
3775c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer          OS.indent(indent) << tagString;
3875c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer        else
3975c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer          OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag());
4075c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer        OS << format(" [%u] %c\n", abbrCode,
4175c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer                     AbbrevDecl->hasChildren() ? '*' : ' ');
4272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
43e5ef305be2505741941b8e7c7a391add3632ebc3Eric Christopher        // Dump all data in the DIE for the attributes.
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for (const auto &AttrSpec : AbbrevDecl->attributes()) {
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent);
4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        }
4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        const DWARFDebugInfoEntryMinimal *child = getFirstChild();
4972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        if (recurseDepth > 0 && child) {
5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          while (child) {
51cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie            child->dump(OS, u, recurseDepth-1, indent+2);
5272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            child = child->getSibling();
5372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer          }
5472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        }
5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      } else {
5672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
5772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer           << abbrCode << '\n';
5872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      }
5972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
600942255f6daf49354dd1e19cc5f07aca65bea0d1Benjamin Kramer      OS.indent(indent) << "NULL\n";
6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
66cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                                               const DWARFUnit *u,
67cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                                               uint32_t *offset_ptr,
68cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                                               uint16_t attr, uint16_t form,
6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                               unsigned indent) const {
70a9b697975592b204e86496efc62a8b26fbfa1a03David Blaikie  OS << "            ";
7175c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer  OS.indent(indent+2);
7275c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer  const char *attrString = AttributeString(attr);
7375c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer  if (attrString)
7475c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer    OS << attrString;
7575c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer  else
7675c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer    OS << format("DW_AT_Unknown_%x", attr);
7775c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer  const char *formString = FormEncodingString(form);
7875c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer  if (formString)
7975c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer    OS << " [" << formString << ']';
8075c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer  else
8175c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer    OS << format(" [DW_FORM_Unknown_%x]", form);
8272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
8372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFFormValue formValue(form);
8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
85cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u))
8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return;
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OS << "\t(";
89cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  formValue.dump(OS, u);
9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OS << ")\n";
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
93cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U,
94d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov                                             uint32_t *OffsetPtr) {
95d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  Offset = *OffsetPtr;
96cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  DataExtractor DebugInfoData = U->getDebugInfoExtractor();
9739f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov  uint32_t UEndOffset = U->getNextUnitOffset();
9839f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov  if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
9939f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov    return false;
100d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
101d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  if (0 == AbbrCode) {
102d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov    // NULL debug tag entry.
103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AbbrevDecl = nullptr;
104d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov    return true;
105d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  }
106cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (nullptr == AbbrevDecl) {
10839f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov    // Restore the original offset.
10939f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov    *OffsetPtr = Offset;
11039f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov    return false;
11139f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov  }
1126faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov  ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes(
1136faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov      U->getAddressByteSize(), U->getVersion());
1146faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov  assert(FixedFormSizes.size() > 0);
115d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov
116d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  // Skip all data in the .debug_info for the attributes
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const auto &AttrSpec : AbbrevDecl->attributes()) {
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint16_t Form = AttrSpec.Form;
119d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov
120d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov    uint8_t FixedFormSize =
1216faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov        (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0;
122d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov    if (FixedFormSize)
123d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov      *OffsetPtr += FixedFormSize;
1246faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov    else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) {
125d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov      // Restore the original offset.
126d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov      *OffsetPtr = Offset;
127d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov      return false;
128d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov    }
12972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
130d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  return true;
13172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
13272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1335eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovbool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const {
1345eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return getTag() == DW_TAG_subprogram;
1355eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
1365eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1375eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovbool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const {
1385eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  uint32_t Tag = getTag();
1395eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return Tag == DW_TAG_subprogram ||
1405eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov         Tag == DW_TAG_inlined_subroutine;
1415eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
1425eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1432e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonovbool DWARFDebugInfoEntryMinimal::getAttributeValue(
1442e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov    const DWARFUnit *U, const uint16_t Attr, DWARFFormValue &FormValue) const {
1452e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  if (!AbbrevDecl)
1462e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov    return false;
14772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1482e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  uint32_t AttrIdx = AbbrevDecl->findAttributeIndex(Attr);
1492e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  if (AttrIdx == -1U)
1502e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov    return false;
15172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1522e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  DataExtractor DebugInfoData = U->getDebugInfoExtractor();
1532e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  uint32_t DebugInfoOffset = getOffset();
15472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1552e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  // Skip the abbreviation code so we are at the data for the attributes
1562e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  DebugInfoData.getULEB128(&DebugInfoOffset);
15772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1582e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  // Skip preceding attribute values.
1592e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  for (uint32_t i = 0; i < AttrIdx; ++i) {
1602e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov    DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(i),
1612e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov                              DebugInfoData, &DebugInfoOffset, U);
16272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
16372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1642e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  FormValue = DWARFFormValue(AbbrevDecl->getFormByIndex(AttrIdx));
1652e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  return FormValue.extractValue(DebugInfoData, &DebugInfoOffset, U);
16672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
16772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
16863fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonovconst char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
169cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const {
17063fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov  DWARFFormValue FormValue;
171c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!getAttributeValue(U, Attr, FormValue))
172c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return FailValue;
173c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  Optional<const char *> Result = FormValue.getAsCString(U);
174c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return Result.hasValue() ? Result.getValue() : FailValue;
17572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
17672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
17763fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonovuint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
178cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
17963fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov  DWARFFormValue FormValue;
180c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!getAttributeValue(U, Attr, FormValue))
181c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return FailValue;
182c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  Optional<uint64_t> Result = FormValue.getAsAddress(U);
183c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return Result.hasValue() ? Result.getValue() : FailValue;
18463fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov}
18563fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov
186c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonovuint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant(
187cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
18863fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov  DWARFFormValue FormValue;
189c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!getAttributeValue(U, Attr, FormValue))
190c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return FailValue;
191c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  Optional<uint64_t> Result = FormValue.getAsUnsignedConstant();
192c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return Result.hasValue() ? Result.getValue() : FailValue;
19372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
19472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
195cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieuint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
1962e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov    const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
1972e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  DWARFFormValue FormValue;
198c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!getAttributeValue(U, Attr, FormValue))
199c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return FailValue;
200c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  Optional<uint64_t> Result = FormValue.getAsReference(U);
201c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return Result.hasValue() ? Result.getValue() : FailValue;
202c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov}
203c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov
204c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonovuint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset(
205c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
206c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  DWARFFormValue FormValue;
207c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  if (!getAttributeValue(U, Attr, FormValue))
208c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov    return FailValue;
209c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  Optional<uint64_t> Result = FormValue.getAsSectionOffset();
210c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  return Result.hasValue() ? Result.getValue() : FailValue;
21172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
21210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
213cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesuint64_t
214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesDWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U,
215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                   uint64_t FailValue) const {
216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  uint64_t Result =
217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL);
218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Result != -1ULL)
219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return Result;
220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue);
221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
223cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
224203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher                                                 uint64_t &LowPC,
225203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher                                                 uint64_t &HighPC) const {
226cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL);
227d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov  if (LowPC == -1ULL)
228d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov    return false;
229d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov  HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL);
230d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov  if (HighPC == -1ULL) {
231d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov    // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case
232d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov    // it represents function size.
233d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov    HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL);
234d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov    if (HighPC != -1ULL)
235d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov      HighPC += LowPC;
236d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov  }
2375eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return (HighPC != -1ULL);
2385eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
2395eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFAddressRangesVector
241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
2425eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (isNULL())
243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return DWARFAddressRangesVector();
244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Single range specified by low/high PC.
2455eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  uint64_t LowPC, HighPC;
246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getLowAndHighPC(U, LowPC, HighPC)) {
247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Multiple ranges from .debug_ranges section.
250c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  uint32_t RangesOffset =
251c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
2525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (RangesOffset != -1U) {
2535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    DWARFDebugRangeList RangeList;
254cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    if (U->extractRangeList(RangesOffset, RangeList))
255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return RangeList.getAbsoluteRanges(U->getBaseAddress());
256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DWARFAddressRangesVector();
258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isNULL())
263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (isSubprogramDIE()) {
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const auto &DIERanges = getAddressRanges(U);
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (Child) {
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Child->collectChildrenAddressRanges(U, Ranges);
272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Child = Child->getSibling();
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const DWARFUnit *U, const uint64_t Address) const {
278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto& R : getAddressRanges(U)) {
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (R.first <= Address && Address < R.second)
280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
2813e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
2823e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  return false;
2833e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov}
2843e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov
285cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieconst char *
286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                              FunctionNameKind Kind) const {
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Try to get mangled name only if it was asked for.
291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Kind == FunctionNameKind::LinkageName) {
292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (const char *name =
293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return name;
295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (const char *name =
296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return name;
298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
3009d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov    return name;
3019d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov  // Try to get name from specification DIE.
3029d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov  uint32_t spec_ref =
303cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie      getAttributeValueAsReference(U, DW_AT_specification, -1U);
3049d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov  if (spec_ref != -1U) {
3059d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov    DWARFDebugInfoEntryMinimal spec_die;
30639f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov    if (spec_die.extractFast(U, &spec_ref)) {
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (const char *name = spec_die.getSubroutineName(U, Kind))
3089d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov        return name;
3093e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov    }
3103e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
3119d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov  // Try to get name from abstract origin DIE.
3129d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov  uint32_t abs_origin_ref =
313cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie      getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U);
3149d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov  if (abs_origin_ref != -1U) {
3159d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov    DWARFDebugInfoEntryMinimal abs_origin_die;
31639f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov    if (abs_origin_die.extractFast(U, &abs_origin_ref)) {
317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (const char *name = abs_origin_die.getSubroutineName(U, Kind))
3189d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov        return name;
3199d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov    }
3209d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov  }
321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
3223e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov}
3235eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
324cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikievoid DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U,
325203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher                                                uint32_t &CallFile,
326203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher                                                uint32_t &CallLine,
327203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher                                                uint32_t &CallColumn) const {
328c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0);
329c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0);
330c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0);
3315eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
3325eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
333e664290ad6d988e0ae40f2461084f6adbababa47Alexey SamsonovDWARFDebugInfoEntryInlinedChain
3345eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovDWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
335cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    const DWARFUnit *U, const uint64_t Address) const {
336e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  DWARFDebugInfoEntryInlinedChain InlinedChain;
337cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  InlinedChain.U = U;
3385eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (isNULL())
3395eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    return InlinedChain;
3405eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) {
3415eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    // Append current DIE to inlined chain only if it has correct tag
3425eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    // (e.g. it is not a lexical block).
3435eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    if (DIE->isSubroutineDIE()) {
344e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov      InlinedChain.DIEs.push_back(*DIE);
3455eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
3465eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    // Try to get child which also contains provided address.
3475eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild();
3485eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    while (Child) {
349cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie      if (Child->addressRangeContainsAddress(U, Address)) {
3505eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // Assume there is only one such child.
3515eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        break;
3525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      }
3535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      Child = Child->getSibling();
3545eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
3555eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    DIE = Child;
3565eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  }
3575eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  // Reverse the obtained chain to make the root of inlined chain last.
358e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end());
3595eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return InlinedChain;
3605eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
361