aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/DebugInfo')
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp18
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.h15
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFCompileUnit.h8
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFContext.cpp530
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFContext.h182
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp127
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.h50
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp12
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.h12
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp131
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugAranges.h47
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp90
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugFrame.h9
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp116
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h62
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp380
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugLine.h114
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp74
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugLoc.h21
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp24
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.h15
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp10
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFTypeUnit.h12
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFUnit.cpp165
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARFUnit.h31
-rw-r--r--contrib/llvm/lib/DebugInfo/module.modulemap1
26 files changed, 1202 insertions, 1054 deletions
diff --git a/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp b/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp
index f46fd58a63b0..c3e570e14ccd 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp
@@ -18,7 +18,7 @@ void DWARFAbbreviationDeclaration::clear() {
Code = 0;
Tag = 0;
HasChildren = false;
- Attributes.clear();
+ AttributeSpecs.clear();
}
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
@@ -51,7 +51,7 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, uint32_t* OffsetPtr) {
}
if (Attr == 0 && Form == 0)
break;
- Attributes.push_back(AttributeSpec(Attr, Form));
+ AttributeSpecs.push_back(AttributeSpec(Attr, Form));
}
if (Tag == 0) {
@@ -69,19 +69,19 @@ void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
else
OS << format("DW_TAG_Unknown_%x", getTag());
OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
- for (unsigned i = 0, e = Attributes.size(); i != e; ++i) {
+ for (const AttributeSpec &Spec : AttributeSpecs) {
OS << '\t';
- const char *attrString = AttributeString(Attributes[i].Attr);
+ const char *attrString = AttributeString(Spec.Attr);
if (attrString)
OS << attrString;
else
- OS << format("DW_AT_Unknown_%x", Attributes[i].Attr);
+ OS << format("DW_AT_Unknown_%x", Spec.Attr);
OS << '\t';
- const char *formString = FormEncodingString(Attributes[i].Form);
+ const char *formString = FormEncodingString(Spec.Form);
if (formString)
OS << formString;
else
- OS << format("DW_FORM_Unknown_%x", Attributes[i].Form);
+ OS << format("DW_FORM_Unknown_%x", Spec.Form);
OS << '\n';
}
OS << '\n';
@@ -89,8 +89,8 @@ void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
uint32_t
DWARFAbbreviationDeclaration::findAttributeIndex(uint16_t attr) const {
- for (uint32_t i = 0, e = Attributes.size(); i != e; ++i) {
- if (Attributes[i].Attr == attr)
+ for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
+ if (AttributeSpecs[i].Attr == attr)
return i;
}
return -1U;
diff --git a/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.h b/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.h
index e9b072eb86d8..b86b9ecbe4b3 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.h
@@ -27,19 +27,24 @@ class DWARFAbbreviationDeclaration {
uint16_t Attr;
uint16_t Form;
};
- SmallVector<AttributeSpec, 8> Attributes;
+ typedef SmallVector<AttributeSpec, 8> AttributeSpecVector;
+ AttributeSpecVector AttributeSpecs;
public:
DWARFAbbreviationDeclaration();
uint32_t getCode() const { return Code; }
uint32_t getTag() const { return Tag; }
bool hasChildren() const { return HasChildren; }
- uint32_t getNumAttributes() const { return Attributes.size(); }
- uint16_t getAttrByIndex(uint32_t idx) const {
- return idx < Attributes.size() ? Attributes[idx].Attr : 0;
+
+ typedef iterator_range<AttributeSpecVector::const_iterator>
+ attr_iterator_range;
+
+ attr_iterator_range attributes() const {
+ return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end());
}
+
uint16_t getFormByIndex(uint32_t idx) const {
- return idx < Attributes.size() ? Attributes[idx].Form : 0;
+ return idx < AttributeSpecs.size() ? AttributeSpecs[idx].Form : 0;
}
uint32_t findAttributeIndex(uint16_t attr) const;
diff --git a/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.h b/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.h
index 1c9573b0b4b7..2ed188e70c1f 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.h
@@ -16,13 +16,13 @@ namespace llvm {
class DWARFCompileUnit : public DWARFUnit {
public:
- DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
- StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
+ DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
+ StringRef SS, StringRef SOS, StringRef AOS,
const RelocAddrMap *M, bool LE)
- : DWARFUnit(DA, IS, AS, RS, SS, SOS, AOS, M, LE) {}
+ : DWARFUnit(DA, IS, RS, SS, SOS, AOS, M, LE) {}
void dump(raw_ostream &OS);
// VTable anchor.
- ~DWARFCompileUnit() LLVM_OVERRIDE;
+ ~DWARFCompileUnit() override;
};
}
diff --git a/contrib/llvm/lib/DebugInfo/DWARFContext.cpp b/contrib/llvm/lib/DebugInfo/DWARFContext.cpp
index e47719025c80..3961905f6582 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFContext.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFContext.cpp
@@ -8,9 +8,10 @@
//===----------------------------------------------------------------------===//
#include "DWARFContext.h"
+#include "DWARFDebugArangeSet.h"
+
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
@@ -21,40 +22,40 @@ using namespace llvm;
using namespace dwarf;
using namespace object;
-typedef DWARFDebugLine::LineTable DWARFLineTable;
+#define DEBUG_TYPE "dwarf"
-DWARFContext::~DWARFContext() {
- DeleteContainerPointers(CUs);
- DeleteContainerPointers(TUs);
- DeleteContainerPointers(DWOCUs);
-}
+typedef DWARFDebugLine::LineTable DWARFLineTable;
+typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
+typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
bool LittleEndian, bool GnuStyle) {
OS << "\n." << Name << " contents:\n";
DataExtractor pubNames(Data, LittleEndian, 0);
uint32_t offset = 0;
- OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
- OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
- OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
- OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
- if (GnuStyle)
- OS << "Offset Linkage Kind Name\n";
- else
- OS << "Offset Name\n";
-
- while (offset < Data.size()) {
- uint32_t dieRef = pubNames.getU32(&offset);
- if (dieRef == 0)
- break;
- OS << format("0x%8.8x ", dieRef);
- if (GnuStyle) {
- PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
- OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
- << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
- << ' ';
+ while (pubNames.isValidOffset(offset)) {
+ OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
+ OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
+ OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
+ OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
+ if (GnuStyle)
+ OS << "Offset Linkage Kind Name\n";
+ else
+ OS << "Offset Name\n";
+
+ while (offset < Data.size()) {
+ uint32_t dieRef = pubNames.getU32(&offset);
+ if (dieRef == 0)
+ break;
+ OS << format("0x%8.8x ", dieRef);
+ if (GnuStyle) {
+ PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
+ OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
+ << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
+ << ' ';
+ }
+ OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
}
- OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
}
}
@@ -64,16 +65,36 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
getDebugAbbrev()->dump(OS);
}
+ if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
+ if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
+ OS << "\n.debug_abbrev.dwo contents:\n";
+ D->dump(OS);
+ }
+
if (DumpType == DIDT_All || DumpType == DIDT_Info) {
OS << "\n.debug_info contents:\n";
- for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
- getCompileUnitAtIndex(i)->dump(OS);
+ for (const auto &CU : compile_units())
+ CU->dump(OS);
}
- if (DumpType == DIDT_All || DumpType == DIDT_Types) {
+ if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
+ getNumDWOCompileUnits()) {
+ OS << "\n.debug_info.dwo contents:\n";
+ for (const auto &DWOCU : dwo_compile_units())
+ DWOCU->dump(OS);
+ }
+
+ if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
OS << "\n.debug_types contents:\n";
- for (unsigned i = 0, e = getNumTypeUnits(); i != e; ++i)
- getTypeUnitAtIndex(i)->dump(OS);
+ for (const auto &TU : type_units())
+ TU->dump(OS);
+ }
+
+ if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
+ getNumDWOTypeUnits()) {
+ OS << "\n.debug_types.dwo contents:\n";
+ for (const auto &DWOTU : dwo_type_units())
+ DWOTU->dump(OS);
}
if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
@@ -81,6 +102,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
getDebugLoc()->dump(OS);
}
+ if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
+ OS << "\n.debug_loc.dwo contents:\n";
+ getDebugLocDWO()->dump(OS);
+ }
+
if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
OS << "\n.debug_frame contents:\n";
getDebugFrame()->dump(OS);
@@ -98,21 +124,33 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
uint8_t savedAddressByteSize = 0;
if (DumpType == DIDT_All || DumpType == DIDT_Line) {
OS << "\n.debug_line contents:\n";
- for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
- DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
- savedAddressByteSize = cu->getAddressByteSize();
+ for (const auto &CU : compile_units()) {
+ savedAddressByteSize = CU->getAddressByteSize();
unsigned stmtOffset =
- cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
- cu, DW_AT_stmt_list, -1U);
+ CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
+ CU.get(), DW_AT_stmt_list, -1U);
if (stmtOffset != -1U) {
DataExtractor lineData(getLineSection().Data, isLittleEndian(),
savedAddressByteSize);
- DWARFDebugLine::DumpingState state(OS);
- DWARFDebugLine::parseStatementTable(lineData, &getLineSection().Relocs, &stmtOffset, state);
+ DWARFDebugLine::LineTable LineTable;
+ LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
+ LineTable.dump(OS);
}
}
}
+ if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
+ OS << "\n.debug_line.dwo contents:\n";
+ unsigned stmtOffset = 0;
+ DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
+ savedAddressByteSize);
+ DWARFDebugLine::LineTable LineTable;
+ while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
+ LineTable.dump(OS);
+ LineTable.clear();
+ }
+ }
+
if (DumpType == DIDT_All || DumpType == DIDT_Str) {
OS << "\n.debug_str contents:\n";
DataExtractor strData(getStringSection(), isLittleEndian(), 0);
@@ -124,6 +162,18 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
}
}
+ if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
+ !getStringDWOSection().empty()) {
+ OS << "\n.debug_str.dwo contents:\n";
+ DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
+ offset = 0;
+ uint32_t strDWOOffset = 0;
+ while (const char *s = strDWOData.getCStr(&offset)) {
+ OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
+ strDWOOffset = offset;
+ }
+ }
+
if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
OS << "\n.debug_ranges contents:\n";
// In fact, different compile units may have different address byte
@@ -154,44 +204,18 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
isLittleEndian(), true /* GnuStyle */);
- if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) {
- const DWARFDebugAbbrev *D = getDebugAbbrevDWO();
- if (D) {
- OS << "\n.debug_abbrev.dwo contents:\n";
- getDebugAbbrevDWO()->dump(OS);
+ if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
+ !getStringOffsetDWOSection().empty()) {
+ OS << "\n.debug_str_offsets.dwo contents:\n";
+ DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
+ 0);
+ offset = 0;
+ uint64_t size = getStringOffsetDWOSection().size();
+ while (offset < size) {
+ OS << format("0x%8.8x: ", offset);
+ OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
}
}
-
- if (DumpType == DIDT_All || DumpType == DIDT_InfoDwo)
- if (getNumDWOCompileUnits()) {
- OS << "\n.debug_info.dwo contents:\n";
- for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
- getDWOCompileUnitAtIndex(i)->dump(OS);
- }
-
- if (DumpType == DIDT_All || DumpType == DIDT_StrDwo)
- if (!getStringDWOSection().empty()) {
- OS << "\n.debug_str.dwo contents:\n";
- DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
- offset = 0;
- uint32_t strDWOOffset = 0;
- while (const char *s = strDWOData.getCStr(&offset)) {
- OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
- strDWOOffset = offset;
- }
- }
-
- if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo)
- if (!getStringOffsetDWOSection().empty()) {
- OS << "\n.debug_str_offsets.dwo contents:\n";
- DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
- offset = 0;
- uint64_t size = getStringOffsetDWOSection().size();
- while (offset < size) {
- OS << format("0x%8.8x: ", offset);
- OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
- }
- }
}
const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
@@ -201,7 +225,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
Abbrev.reset(new DWARFDebugAbbrev());
- Abbrev->parse(abbrData);
+ Abbrev->extract(abbrData);
return Abbrev.get();
}
@@ -211,7 +235,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
AbbrevDWO.reset(new DWARFDebugAbbrev());
- AbbrevDWO->parse(abbrData);
+ AbbrevDWO->extract(abbrData);
return AbbrevDWO.get();
}
@@ -227,6 +251,16 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
return Loc.get();
}
+const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
+ if (LocDWO)
+ return LocDWO.get();
+
+ DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
+ LocDWO.reset(new DWARFDebugLocDWO());
+ LocDWO->parse(LocData);
+ return LocDWO.get();
+}
+
const DWARFDebugAranges *DWARFContext::getDebugAranges() {
if (Aranges)
return Aranges.get();
@@ -265,7 +299,7 @@ DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
cu, DW_AT_stmt_list, -1U);
if (stmtOffset == -1U)
- return 0; // No line table for this compile unit.
+ return nullptr; // No line table for this compile unit.
// See if the line table is cached.
if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
@@ -278,87 +312,110 @@ DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
}
void DWARFContext::parseCompileUnits() {
+ if (!CUs.empty())
+ return;
uint32_t offset = 0;
const DataExtractor &DIData = DataExtractor(getInfoSection().Data,
isLittleEndian(), 0);
while (DIData.isValidOffset(offset)) {
- OwningPtr<DWARFCompileUnit> CU(new DWARFCompileUnit(
- getDebugAbbrev(), getInfoSection().Data, getAbbrevSection(),
- getRangeSection(), getStringSection(), StringRef(), getAddrSection(),
+ std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(
+ getDebugAbbrev(), getInfoSection().Data, getRangeSection(),
+ getStringSection(), StringRef(), getAddrSection(),
&getInfoSection().Relocs, isLittleEndian()));
if (!CU->extract(DIData, &offset)) {
break;
}
- CUs.push_back(CU.take());
+ CUs.push_back(std::move(CU));
offset = CUs.back()->getNextUnitOffset();
}
}
void DWARFContext::parseTypeUnits() {
- const std::map<object::SectionRef, Section> &Sections = getTypesSections();
- for (std::map<object::SectionRef, Section>::const_iterator
- I = Sections.begin(),
- E = Sections.end();
- I != E; ++I) {
+ if (!TUs.empty())
+ return;
+ for (const auto &I : getTypesSections()) {
uint32_t offset = 0;
const DataExtractor &DIData =
- DataExtractor(I->second.Data, isLittleEndian(), 0);
+ DataExtractor(I.second.Data, isLittleEndian(), 0);
while (DIData.isValidOffset(offset)) {
- OwningPtr<DWARFTypeUnit> TU(new DWARFTypeUnit(
- getDebugAbbrev(), I->second.Data, getAbbrevSection(),
- getRangeSection(), getStringSection(), StringRef(), getAddrSection(),
- &I->second.Relocs, isLittleEndian()));
+ std::unique_ptr<DWARFTypeUnit> TU(
+ new DWARFTypeUnit(getDebugAbbrev(), I.second.Data, getRangeSection(),
+ getStringSection(), StringRef(), getAddrSection(),
+ &I.second.Relocs, isLittleEndian()));
if (!TU->extract(DIData, &offset))
break;
- TUs.push_back(TU.take());
+ TUs.push_back(std::move(TU));
offset = TUs.back()->getNextUnitOffset();
}
}
}
void DWARFContext::parseDWOCompileUnits() {
+ if (!DWOCUs.empty())
+ return;
uint32_t offset = 0;
const DataExtractor &DIData =
DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
while (DIData.isValidOffset(offset)) {
- OwningPtr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(
- getDebugAbbrevDWO(), getInfoDWOSection().Data, getAbbrevDWOSection(),
- getRangeDWOSection(), getStringDWOSection(),
- getStringOffsetDWOSection(), getAddrSection(),
+ std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(
+ getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(),
+ getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
&getInfoDWOSection().Relocs, isLittleEndian()));
if (!DWOCU->extract(DIData, &offset)) {
break;
}
- DWOCUs.push_back(DWOCU.take());
+ DWOCUs.push_back(std::move(DWOCU));
offset = DWOCUs.back()->getNextUnitOffset();
}
}
+void DWARFContext::parseDWOTypeUnits() {
+ if (!DWOTUs.empty())
+ return;
+ for (const auto &I : getTypesDWOSections()) {
+ uint32_t offset = 0;
+ const DataExtractor &DIData =
+ DataExtractor(I.second.Data, isLittleEndian(), 0);
+ while (DIData.isValidOffset(offset)) {
+ std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(
+ getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(),
+ getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
+ &I.second.Relocs, isLittleEndian()));
+ if (!TU->extract(DIData, &offset))
+ break;
+ DWOTUs.push_back(std::move(TU));
+ offset = DWOTUs.back()->getNextUnitOffset();
+ }
+ }
+}
+
namespace {
struct OffsetComparator {
- bool operator()(const DWARFCompileUnit *LHS,
- const DWARFCompileUnit *RHS) const {
+
+ bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
+ const std::unique_ptr<DWARFCompileUnit> &RHS) const {
return LHS->getOffset() < RHS->getOffset();
}
- bool operator()(const DWARFCompileUnit *LHS, uint32_t RHS) const {
+ bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
+ uint32_t RHS) const {
return LHS->getOffset() < RHS;
}
- bool operator()(uint32_t LHS, const DWARFCompileUnit *RHS) const {
+ bool operator()(uint32_t LHS,
+ const std::unique_ptr<DWARFCompileUnit> &RHS) const {
return LHS < RHS->getOffset();
}
};
}
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
- if (CUs.empty())
- parseCompileUnits();
+ parseCompileUnits();
- DWARFCompileUnit **CU =
+ std::unique_ptr<DWARFCompileUnit> *CU =
std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator());
if (CU != CUs.end()) {
- return *CU;
+ return CU->get();
}
- return 0;
+ return nullptr;
}
DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
@@ -370,15 +427,13 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
const DWARFLineTable *LineTable,
- uint64_t FileIndex,
- bool NeedsAbsoluteFilePath,
+ uint64_t FileIndex, FileLineInfoKind Kind,
std::string &FileName) {
- if (CU == 0 ||
- LineTable == 0 ||
- !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
- FileName))
+ if (!CU || !LineTable || Kind == FileLineInfoKind::None ||
+ !LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
return false;
- if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
+ if (Kind == FileLineInfoKind::AbsoluteFilePath &&
+ sys::path::is_relative(FileName)) {
// We may still need to append compilation directory of compile unit.
SmallString<16> AbsolutePath;
if (const char *CompilationDir = CU->getCompilationDir()) {
@@ -393,10 +448,9 @@ static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
const DWARFLineTable *LineTable,
uint64_t Address,
- bool NeedsAbsoluteFilePath,
- std::string &FileName,
- uint32_t &Line, uint32_t &Column) {
- if (CU == 0 || LineTable == 0)
+ FileLineInfoKind Kind,
+ DILineInfo &Result) {
+ if (!CU || !LineTable)
return false;
// Get the index of row we're looking for in the line table.
uint32_t RowIndex = LineTable->lookupAddress(Address);
@@ -404,144 +458,141 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
return false;
// Take file number and line/column from the row.
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
- if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
- NeedsAbsoluteFilePath, FileName))
+ if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind,
+ Result.FileName))
return false;
- Line = Row.Line;
- Column = Row.Column;
+ Result.Line = Row.Line;
+ Result.Column = Row.Column;
return true;
}
+static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
+ FunctionNameKind Kind,
+ std::string &FunctionName) {
+ if (Kind == FunctionNameKind::None)
+ return false;
+ // The address may correspond to instruction in some inlined function,
+ // so we have to build the chain of inlined functions and take the
+ // name of the topmost function in it.
+ const DWARFDebugInfoEntryInlinedChain &InlinedChain =
+ CU->getInlinedChainForAddress(Address);
+ if (InlinedChain.DIEs.size() == 0)
+ return false;
+ const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
+ if (const char *Name =
+ TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
+ FunctionName = Name;
+ return true;
+ }
+ return false;
+}
+
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
- DILineInfoSpecifier Specifier) {
+ DILineInfoSpecifier Spec) {
+ DILineInfo Result;
+
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
if (!CU)
- return DILineInfo();
- std::string FileName = "<invalid>";
- std::string FunctionName = "<invalid>";
- uint32_t Line = 0;
- uint32_t Column = 0;
- if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
- // The address may correspond to instruction in some inlined function,
- // so we have to build the chain of inlined functions and take the
- // name of the topmost function in it.
- const DWARFDebugInfoEntryInlinedChain &InlinedChain =
- CU->getInlinedChainForAddress(Address);
- if (InlinedChain.DIEs.size() > 0) {
- const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
- if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
- FunctionName = Name;
- }
- }
- if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
+ return Result;
+ getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
+ if (Spec.FLIKind != FileLineInfoKind::None) {
const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
- const bool NeedsAbsoluteFilePath =
- Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
- getFileLineInfoForCompileUnit(CU, LineTable, Address,
- NeedsAbsoluteFilePath,
- FileName, Line, Column);
+ getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
}
- return DILineInfo(StringRef(FileName), StringRef(FunctionName),
- Line, Column);
+ return Result;
}
-DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
- uint64_t Size,
- DILineInfoSpecifier Specifier) {
+DILineInfoTable
+DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
+ DILineInfoSpecifier Spec) {
DILineInfoTable Lines;
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
if (!CU)
return Lines;
std::string FunctionName = "<invalid>";
- if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
- // The address may correspond to instruction in some inlined function,
- // so we have to build the chain of inlined functions and take the
- // name of the topmost function in it.
- const DWARFDebugInfoEntryInlinedChain &InlinedChain =
- CU->getInlinedChainForAddress(Address);
- if (InlinedChain.DIEs.size() > 0) {
- const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
- if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
- FunctionName = Name;
- }
- }
+ getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
// If the Specifier says we don't need FileLineInfo, just
// return the top-most function at the starting address.
- if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
- Lines.push_back(
- std::make_pair(Address, DILineInfo("<invalid>", FunctionName, 0, 0)));
+ if (Spec.FLIKind == FileLineInfoKind::None) {
+ DILineInfo Result;
+ Result.FunctionName = FunctionName;
+ Lines.push_back(std::make_pair(Address, Result));
return Lines;
}
const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
- const bool NeedsAbsoluteFilePath =
- Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
// Get the index of row we're looking for in the line table.
std::vector<uint32_t> RowVector;
if (!LineTable->lookupAddressRange(Address, Size, RowVector))
return Lines;
- uint32_t NumRows = RowVector.size();
- for (uint32_t i = 0; i < NumRows; ++i) {
- uint32_t RowIndex = RowVector[i];
+ for (uint32_t RowIndex : RowVector) {
// Take file number and line/column from the row.
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
- std::string FileName = "<invalid>";
- getFileNameForCompileUnit(CU, LineTable, Row.File,
- NeedsAbsoluteFilePath, FileName);
- Lines.push_back(std::make_pair(
- Row.Address, DILineInfo(FileName, FunctionName, Row.Line, Row.Column)));
+ DILineInfo Result;
+ getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind,
+ Result.FileName);
+ Result.FunctionName = FunctionName;
+ Result.Line = Row.Line;
+ Result.Column = Row.Column;
+ Lines.push_back(std::make_pair(Row.Address, Result));
}
return Lines;
}
-DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
- DILineInfoSpecifier Specifier) {
+DIInliningInfo
+DWARFContext::getInliningInfoForAddress(uint64_t Address,
+ DILineInfoSpecifier Spec) {
+ DIInliningInfo InliningInfo;
+
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
if (!CU)
- return DIInliningInfo();
+ return InliningInfo;
+ const DWARFLineTable *LineTable = nullptr;
const DWARFDebugInfoEntryInlinedChain &InlinedChain =
CU->getInlinedChainForAddress(Address);
- if (InlinedChain.DIEs.size() == 0)
- return DIInliningInfo();
+ if (InlinedChain.DIEs.size() == 0) {
+ // If there is no DIE for address (e.g. it is in unavailable .dwo file),
+ // try to at least get file/line info from symbol table.
+ if (Spec.FLIKind != FileLineInfoKind::None) {
+ DILineInfo Frame;
+ LineTable = getLineTableForCompileUnit(CU);
+ if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
+ Frame)) {
+ InliningInfo.addFrame(Frame);
+ }
+ }
+ return InliningInfo;
+ }
- DIInliningInfo InliningInfo;
uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
- const DWARFLineTable *LineTable = 0;
for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
- std::string FileName = "<invalid>";
- std::string FunctionName = "<invalid>";
- uint32_t Line = 0;
- uint32_t Column = 0;
+ DILineInfo Frame;
// Get function name if necessary.
- if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
- if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
- FunctionName = Name;
- }
- if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
- const bool NeedsAbsoluteFilePath =
- Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
+ if (const char *Name =
+ FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
+ Frame.FunctionName = Name;
+ if (Spec.FLIKind != FileLineInfoKind::None) {
if (i == 0) {
// For the topmost frame, initialize the line table of this
// compile unit and fetch file/line info from it.
LineTable = getLineTableForCompileUnit(CU);
// For the topmost routine, get file/line info from line table.
- getFileLineInfoForCompileUnit(CU, LineTable, Address,
- NeedsAbsoluteFilePath,
- FileName, Line, Column);
+ getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
+ Frame);
} else {
// Otherwise, use call file, call line and call column from
// previous DIE in inlined chain.
- getFileNameForCompileUnit(CU, LineTable, CallFile,
- NeedsAbsoluteFilePath, FileName);
- Line = CallLine;
- Column = CallColumn;
+ getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind,
+ Frame.FileName);
+ Frame.Line = CallLine;
+ Frame.Column = CallColumn;
}
// Get call file/line/column of a current DIE.
if (i + 1 < n) {
@@ -549,8 +600,6 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
CallColumn);
}
}
- DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
- Line, Column);
InliningInfo.addFrame(Frame);
}
return InliningInfo;
@@ -572,17 +621,14 @@ static bool consumeCompressedDebugSectionHeader(StringRef &data,
return true;
}
-DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
- IsLittleEndian(Obj->isLittleEndian()),
- AddressSize(Obj->getBytesInAddress()) {
- error_code ec;
- for (object::section_iterator i = Obj->begin_sections(),
- e = Obj->end_sections();
- i != e; i.increment(ec)) {
+DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
+ : IsLittleEndian(Obj->isLittleEndian()),
+ AddressSize(Obj->getBytesInAddress()) {
+ for (const SectionRef &Section : Obj->sections()) {
StringRef name;
- i->getName(name);
+ Section.getName(name);
StringRef data;
- i->getContents(data);
+ Section.getContents(data);
name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
@@ -592,17 +638,18 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
if (!zlib::isAvailable() ||
!consumeCompressedDebugSectionHeader(data, OriginalSize))
continue;
- OwningPtr<MemoryBuffer> UncompressedSection;
- if (zlib::uncompress(data, UncompressedSection, OriginalSize) !=
- zlib::StatusOK)
+ UncompressedSections.resize(UncompressedSections.size() + 1);
+ if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
+ zlib::StatusOK) {
+ UncompressedSections.pop_back();
continue;
+ }
// Make data point to uncompressed section contents and save its contents.
name = name.substr(1);
- data = UncompressedSection->getBuffer();
- UncompressedSections.push_back(UncompressedSection.take());
+ data = UncompressedSections.back();
}
- StringRef *Section =
+ StringRef *SectionData =
StringSwitch<StringRef *>(name)
.Case("debug_info", &InfoSection.Data)
.Case("debug_abbrev", &AbbrevSection)
@@ -618,13 +665,15 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
.Case("debug_gnu_pubtypes", &GnuPubTypesSection)
.Case("debug_info.dwo", &InfoDWOSection.Data)
.Case("debug_abbrev.dwo", &AbbrevDWOSection)
+ .Case("debug_loc.dwo", &LocDWOSection.Data)
+ .Case("debug_line.dwo", &LineDWOSection.Data)
.Case("debug_str.dwo", &StringDWOSection)
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
.Case("debug_addr", &AddrSection)
// Any more debug info sections go here.
- .Default(0);
- if (Section) {
- *Section = data;
+ .Default(nullptr);
+ if (SectionData) {
+ *SectionData = data;
if (name == "debug_ranges") {
// FIXME: Use the other dwo range section when we emit it.
RangeDWOSection = data;
@@ -632,11 +681,13 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
} else if (name == "debug_types") {
// Find debug_types data by section rather than name as there are
// multiple, comdat grouped, debug_types sections.
- TypesSections[*i].Data = data;
+ TypesSections[Section].Data = data;
+ } else if (name == "debug_types.dwo") {
+ TypesDWOSections[Section].Data = data;
}
- section_iterator RelocatedSection = i->getRelocatedSection();
- if (RelocatedSection == Obj->end_sections())
+ section_iterator RelocatedSection = Section.getRelocatedSection();
+ if (RelocatedSection == Obj->section_end())
continue;
StringRef RelSecName;
@@ -651,38 +702,39 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
.Case("debug_loc", &LocSection.Relocs)
.Case("debug_info.dwo", &InfoDWOSection.Relocs)
.Case("debug_line", &LineSection.Relocs)
- .Default(0);
+ .Default(nullptr);
if (!Map) {
- if (RelSecName != "debug_types")
- continue;
// Find debug_types relocs by section rather than name as there are
// multiple, comdat grouped, debug_types sections.
- Map = &TypesSections[*RelocatedSection].Relocs;
+ if (RelSecName == "debug_types")
+ Map = &TypesSections[*RelocatedSection].Relocs;
+ else if (RelSecName == "debug_types.dwo")
+ Map = &TypesDWOSections[*RelocatedSection].Relocs;
+ else
+ continue;
}
- if (i->begin_relocations() != i->end_relocations()) {
+ if (Section.relocation_begin() != Section.relocation_end()) {
uint64_t SectionSize;
RelocatedSection->getSize(SectionSize);
- for (object::relocation_iterator reloc_i = i->begin_relocations(),
- reloc_e = i->end_relocations();
- reloc_i != reloc_e; reloc_i.increment(ec)) {
+ for (const RelocationRef &Reloc : Section.relocations()) {
uint64_t Address;
- reloc_i->getOffset(Address);
+ Reloc.getOffset(Address);
uint64_t Type;
- reloc_i->getType(Type);
+ Reloc.getType(Type);
uint64_t SymAddr = 0;
// ELF relocations may need the symbol address
if (Obj->isELF()) {
- object::symbol_iterator Sym = reloc_i->getSymbol();
+ object::symbol_iterator Sym = Reloc.getSymbol();
Sym->getAddress(SymAddr);
}
object::RelocVisitor V(Obj->getFileFormatName());
// The section address is always 0 for debug sections.
- object::RelocToApply R(V.visit(Type, *reloc_i, 0, SymAddr));
+ object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
if (V.error()) {
SmallString<32> Name;
- error_code ec(reloc_i->getTypeName(Name));
+ std::error_code ec(Reloc.getTypeName(Name));
if (ec) {
errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
}
@@ -712,8 +764,4 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
}
}
-DWARFContextInMemory::~DWARFContextInMemory() {
- DeleteContainerPointers(UncompressedSections);
-}
-
void DWARFContextInMemory::anchor() { }
diff --git a/contrib/llvm/lib/DebugInfo/DWARFContext.h b/contrib/llvm/lib/DebugInfo/DWARFContext.h
index 03863ab8b1e2..6d1ae921cec5 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFContext.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFContext.h
@@ -17,7 +17,7 @@
#include "DWARFDebugLoc.h"
#include "DWARFDebugRangeList.h"
#include "DWARFTypeUnit.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/DIContext.h"
@@ -28,30 +28,41 @@ namespace llvm {
/// information parsing. The actual data is supplied through pure virtual
/// methods that a concrete implementation provides.
class DWARFContext : public DIContext {
- SmallVector<DWARFCompileUnit *, 1> CUs;
- SmallVector<DWARFTypeUnit *, 1> TUs;
- OwningPtr<DWARFDebugAbbrev> Abbrev;
- OwningPtr<DWARFDebugLoc> Loc;
- OwningPtr<DWARFDebugAranges> Aranges;
- OwningPtr<DWARFDebugLine> Line;
- OwningPtr<DWARFDebugFrame> DebugFrame;
-
- SmallVector<DWARFCompileUnit *, 1> DWOCUs;
- OwningPtr<DWARFDebugAbbrev> AbbrevDWO;
+ typedef SmallVector<std::unique_ptr<DWARFCompileUnit>, 1> CUVector;
+ typedef SmallVector<std::unique_ptr<DWARFTypeUnit>, 1> TUVector;
+
+ CUVector CUs;
+ TUVector TUs;
+ std::unique_ptr<DWARFDebugAbbrev> Abbrev;
+ std::unique_ptr<DWARFDebugLoc> Loc;
+ std::unique_ptr<DWARFDebugAranges> Aranges;
+ std::unique_ptr<DWARFDebugLine> Line;
+ std::unique_ptr<DWARFDebugFrame> DebugFrame;
+
+ CUVector DWOCUs;
+ TUVector DWOTUs;
+ std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
+ std::unique_ptr<DWARFDebugLocDWO> LocDWO;
DWARFContext(DWARFContext &) LLVM_DELETED_FUNCTION;
DWARFContext &operator=(DWARFContext &) LLVM_DELETED_FUNCTION;
- /// Read compile units from the debug_info section and store them in CUs.
+ /// Read compile units from the debug_info section (if necessary)
+ /// and store them in CUs.
void parseCompileUnits();
- /// Read type units from the debug_types sections and store them in CUs.
+ /// Read type units from the debug_types sections (if necessary)
+ /// and store them in TUs.
void parseTypeUnits();
- /// Read compile units from the debug_info.dwo section and store them in
- /// DWOCUs.
+ /// Read compile units from the debug_info.dwo section (if necessary)
+ /// and store them in DWOCUs.
void parseDWOCompileUnits();
+ /// Read type units from the debug_types.dwo section (if necessary)
+ /// and store them in DWOTUs.
+ void parseDWOTypeUnits();
+
public:
struct Section {
StringRef Data;
@@ -59,54 +70,74 @@ public:
};
DWARFContext() : DIContext(CK_DWARF) {}
- virtual ~DWARFContext();
static bool classof(const DIContext *DICtx) {
return DICtx->getKind() == CK_DWARF;
}
- virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All);
+ void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
+
+ typedef iterator_range<CUVector::iterator> cu_iterator_range;
+ typedef iterator_range<TUVector::iterator> tu_iterator_range;
+
+ /// Get compile units in this context.
+ cu_iterator_range compile_units() {
+ parseCompileUnits();
+ return cu_iterator_range(CUs.begin(), CUs.end());
+ }
+
+ /// Get type units in this context.
+ tu_iterator_range type_units() {
+ parseTypeUnits();
+ return tu_iterator_range(TUs.begin(), TUs.end());
+ }
+
+ /// Get compile units in the DWO context.
+ cu_iterator_range dwo_compile_units() {
+ parseDWOCompileUnits();
+ return cu_iterator_range(DWOCUs.begin(), DWOCUs.end());
+ }
+
+ /// Get type units in the DWO context.
+ tu_iterator_range dwo_type_units() {
+ parseDWOTypeUnits();
+ return tu_iterator_range(DWOTUs.begin(), DWOTUs.end());
+ }
/// Get the number of compile units in this context.
unsigned getNumCompileUnits() {
- if (CUs.empty())
- parseCompileUnits();
+ parseCompileUnits();
return CUs.size();
}
/// Get the number of compile units in this context.
unsigned getNumTypeUnits() {
- if (TUs.empty())
- parseTypeUnits();
+ parseTypeUnits();
return TUs.size();
}
/// Get the number of compile units in the DWO context.
unsigned getNumDWOCompileUnits() {
- if (DWOCUs.empty())
- parseDWOCompileUnits();
+ parseDWOCompileUnits();
return DWOCUs.size();
}
- /// Get the compile unit at the specified index for this compile unit.
- DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
- if (CUs.empty())
- parseCompileUnits();
- return CUs[index];
+ /// Get the number of compile units in the DWO context.
+ unsigned getNumDWOTypeUnits() {
+ parseDWOTypeUnits();
+ return DWOTUs.size();
}
- /// Get the type unit at the specified index for this compile unit.
- DWARFTypeUnit *getTypeUnitAtIndex(unsigned index) {
- if (TUs.empty())
- parseTypeUnits();
- return TUs[index];
+ /// Get the compile unit at the specified index for this compile unit.
+ DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
+ parseCompileUnits();
+ return CUs[index].get();
}
/// Get the compile unit at the specified index for the DWO compile units.
DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) {
- if (DWOCUs.empty())
- parseDWOCompileUnits();
- return DWOCUs[index];
+ parseDWOCompileUnits();
+ return DWOCUs[index].get();
}
/// Get a pointer to the parsed DebugAbbrev object.
@@ -118,6 +149,9 @@ public:
/// Get a pointer to the parsed dwo abbreviations object.
const DWARFDebugAbbrev *getDebugAbbrevDWO();
+ /// Get a pointer to the parsed DebugLoc object.
+ const DWARFDebugLocDWO *getDebugLocDWO();
+
/// Get a pointer to the parsed DebugAranges object.
const DWARFDebugAranges *getDebugAranges();
@@ -128,22 +162,26 @@ public:
const DWARFDebugLine::LineTable *
getLineTableForCompileUnit(DWARFCompileUnit *cu);
- virtual DILineInfo getLineInfoForAddress(uint64_t Address,
- DILineInfoSpecifier Specifier = DILineInfoSpecifier());
- virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
- uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier());
- virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
- DILineInfoSpecifier Specifier = DILineInfoSpecifier());
+ DILineInfo getLineInfoForAddress(uint64_t Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ DIInliningInfo getInliningInfoForAddress(uint64_t Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
virtual bool isLittleEndian() const = 0;
virtual uint8_t getAddressSize() const = 0;
virtual const Section &getInfoSection() = 0;
- virtual const std::map<object::SectionRef, Section> &getTypesSections() = 0;
+ typedef MapVector<object::SectionRef, Section,
+ std::map<object::SectionRef, unsigned> > TypeSectionMap;
+ virtual const TypeSectionMap &getTypesSections() = 0;
virtual StringRef getAbbrevSection() = 0;
virtual const Section &getLocSection() = 0;
+ virtual const Section &getLocDWOSection() = 0;
virtual StringRef getARangeSection() = 0;
virtual StringRef getDebugFrameSection() = 0;
virtual const Section &getLineSection() = 0;
+ virtual const Section &getLineDWOSection() = 0;
virtual StringRef getStringSection() = 0;
virtual StringRef getRangeSection() = 0;
virtual StringRef getPubNamesSection() = 0;
@@ -153,6 +191,7 @@ public:
// Sections for DWARF5 split dwarf proposal.
virtual const Section &getInfoDWOSection() = 0;
+ virtual const TypeSectionMap &getTypesDWOSections() = 0;
virtual StringRef getAbbrevDWOSection() = 0;
virtual StringRef getStringDWOSection() = 0;
virtual StringRef getStringOffsetDWOSection() = 0;
@@ -179,12 +218,14 @@ class DWARFContextInMemory : public DWARFContext {
bool IsLittleEndian;
uint8_t AddressSize;
Section InfoSection;
- std::map<object::SectionRef, Section> TypesSections;
+ TypeSectionMap TypesSections;
StringRef AbbrevSection;
Section LocSection;
+ Section LocDWOSection;
StringRef ARangeSection;
StringRef DebugFrameSection;
Section LineSection;
+ Section LineDWOSection;
StringRef StringSection;
StringRef RangeSection;
StringRef PubNamesSection;
@@ -194,44 +235,47 @@ class DWARFContextInMemory : public DWARFContext {
// Sections for DWARF5 split dwarf proposal.
Section InfoDWOSection;
+ TypeSectionMap TypesDWOSections;
StringRef AbbrevDWOSection;
StringRef StringDWOSection;
StringRef StringOffsetDWOSection;
StringRef RangeDWOSection;
StringRef AddrSection;
- SmallVector<MemoryBuffer*, 4> UncompressedSections;
+ SmallVector<SmallString<32>, 4> UncompressedSections;
public:
DWARFContextInMemory(object::ObjectFile *);
- ~DWARFContextInMemory();
- virtual bool isLittleEndian() const { return IsLittleEndian; }
- virtual uint8_t getAddressSize() const { return AddressSize; }
- virtual const Section &getInfoSection() { return InfoSection; }
- virtual const std::map<object::SectionRef, Section> &getTypesSections() {
- return TypesSections;
- }
- virtual StringRef getAbbrevSection() { return AbbrevSection; }
- virtual const Section &getLocSection() { return LocSection; }
- virtual StringRef getARangeSection() { return ARangeSection; }
- virtual StringRef getDebugFrameSection() { return DebugFrameSection; }
- virtual const Section &getLineSection() { return LineSection; }
- virtual StringRef getStringSection() { return StringSection; }
- virtual StringRef getRangeSection() { return RangeSection; }
- virtual StringRef getPubNamesSection() { return PubNamesSection; }
- virtual StringRef getPubTypesSection() { return PubTypesSection; }
- virtual StringRef getGnuPubNamesSection() { return GnuPubNamesSection; }
- virtual StringRef getGnuPubTypesSection() { return GnuPubTypesSection; }
+ bool isLittleEndian() const override { return IsLittleEndian; }
+ uint8_t getAddressSize() const override { return AddressSize; }
+ const Section &getInfoSection() override { return InfoSection; }
+ const TypeSectionMap &getTypesSections() override { return TypesSections; }
+ StringRef getAbbrevSection() override { return AbbrevSection; }
+ const Section &getLocSection() override { return LocSection; }
+ const Section &getLocDWOSection() override { return LocDWOSection; }
+ StringRef getARangeSection() override { return ARangeSection; }
+ StringRef getDebugFrameSection() override { return DebugFrameSection; }
+ const Section &getLineSection() override { return LineSection; }
+ const Section &getLineDWOSection() override { return LineDWOSection; }
+ StringRef getStringSection() override { return StringSection; }
+ StringRef getRangeSection() override { return RangeSection; }
+ StringRef getPubNamesSection() override { return PubNamesSection; }
+ StringRef getPubTypesSection() override { return PubTypesSection; }
+ StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
+ StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
// Sections for DWARF5 split dwarf proposal.
- virtual const Section &getInfoDWOSection() { return InfoDWOSection; }
- virtual StringRef getAbbrevDWOSection() { return AbbrevDWOSection; }
- virtual StringRef getStringDWOSection() { return StringDWOSection; }
- virtual StringRef getStringOffsetDWOSection() {
+ const Section &getInfoDWOSection() override { return InfoDWOSection; }
+ const TypeSectionMap &getTypesDWOSections() override {
+ return TypesDWOSections;
+ }
+ StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
+ StringRef getStringDWOSection() override { return StringDWOSection; }
+ StringRef getStringOffsetDWOSection() override {
return StringOffsetDWOSection;
}
- virtual StringRef getRangeDWOSection() { return RangeDWOSection; }
- virtual StringRef getAddrSection() {
+ StringRef getRangeDWOSection() override { return RangeDWOSection; }
+ StringRef getAddrSection() override {
return AddrSection;
}
};
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp
index 6e6c37e30945..8426bf95beda 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp
@@ -12,95 +12,104 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-bool DWARFAbbreviationDeclarationSet::extract(DataExtractor data,
- uint32_t* offset_ptr) {
- const uint32_t beginOffset = *offset_ptr;
- Offset = beginOffset;
+DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
clear();
- DWARFAbbreviationDeclaration abbrevDeclaration;
- uint32_t prevAbbrAode = 0;
- while (abbrevDeclaration.extract(data, offset_ptr)) {
- Decls.push_back(abbrevDeclaration);
- if (IdxOffset == 0) {
- IdxOffset = abbrevDeclaration.getCode();
+}
+
+void DWARFAbbreviationDeclarationSet::clear() {
+ Offset = 0;
+ FirstAbbrCode = 0;
+ Decls.clear();
+}
+
+bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
+ uint32_t *OffsetPtr) {
+ clear();
+ const uint32_t BeginOffset = *OffsetPtr;
+ Offset = BeginOffset;
+ DWARFAbbreviationDeclaration AbbrDecl;
+ uint32_t PrevAbbrCode = 0;
+ while (AbbrDecl.extract(Data, OffsetPtr)) {
+ Decls.push_back(AbbrDecl);
+ if (FirstAbbrCode == 0) {
+ FirstAbbrCode = AbbrDecl.getCode();
} else {
- if (prevAbbrAode + 1 != abbrevDeclaration.getCode())
- IdxOffset = UINT32_MAX;// Out of order indexes, we can't do O(1) lookups
+ if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
+ // Codes are not consecutive, can't do O(1) lookups.
+ FirstAbbrCode = UINT32_MAX;
+ }
}
- prevAbbrAode = abbrevDeclaration.getCode();
+ PrevAbbrCode = AbbrDecl.getCode();
}
- return beginOffset != *offset_ptr;
+ return BeginOffset != *OffsetPtr;
}
void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
- for (unsigned i = 0, e = Decls.size(); i != e; ++i)
- Decls[i].dump(OS);
+ for (const auto &Decl : Decls)
+ Decl.dump(OS);
}
-const DWARFAbbreviationDeclaration*
-DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(uint32_t abbrCode)
- const {
- if (IdxOffset == UINT32_MAX) {
- DWARFAbbreviationDeclarationCollConstIter pos;
- DWARFAbbreviationDeclarationCollConstIter end = Decls.end();
- for (pos = Decls.begin(); pos != end; ++pos) {
- if (pos->getCode() == abbrCode)
- return &(*pos);
+const DWARFAbbreviationDeclaration *
+DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
+ uint32_t AbbrCode) const {
+ if (FirstAbbrCode == UINT32_MAX) {
+ for (const auto &Decl : Decls) {
+ if (Decl.getCode() == AbbrCode)
+ return &Decl;
}
- } else {
- uint32_t idx = abbrCode - IdxOffset;
- if (idx < Decls.size())
- return &Decls[idx];
+ return nullptr;
}
- return NULL;
+ if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
+ return nullptr;
+ return &Decls[AbbrCode - FirstAbbrCode];
}
-DWARFDebugAbbrev::DWARFDebugAbbrev() :
- AbbrevCollMap(),
- PrevAbbrOffsetPos(AbbrevCollMap.end()) {}
-
+DWARFDebugAbbrev::DWARFDebugAbbrev() {
+ clear();
+}
-void DWARFDebugAbbrev::parse(DataExtractor data) {
- uint32_t offset = 0;
+void DWARFDebugAbbrev::clear() {
+ AbbrDeclSets.clear();
+ PrevAbbrOffsetPos = AbbrDeclSets.end();
+}
- while (data.isValidOffset(offset)) {
- uint32_t initial_cu_offset = offset;
- DWARFAbbreviationDeclarationSet abbrevDeclSet;
+void DWARFDebugAbbrev::extract(DataExtractor Data) {
+ clear();
- if (abbrevDeclSet.extract(data, &offset))
- AbbrevCollMap[initial_cu_offset] = abbrevDeclSet;
- else
+ uint32_t Offset = 0;
+ DWARFAbbreviationDeclarationSet AbbrDecls;
+ while (Data.isValidOffset(Offset)) {
+ uint32_t CUAbbrOffset = Offset;
+ if (!AbbrDecls.extract(Data, &Offset))
break;
+ AbbrDeclSets[CUAbbrOffset] = AbbrDecls;
}
- PrevAbbrOffsetPos = AbbrevCollMap.end();
}
void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
- if (AbbrevCollMap.empty()) {
+ if (AbbrDeclSets.empty()) {
OS << "< EMPTY >\n";
return;
}
- DWARFAbbreviationDeclarationCollMapConstIter pos;
- for (pos = AbbrevCollMap.begin(); pos != AbbrevCollMap.end(); ++pos) {
- OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", pos->first);
- pos->second.dump(OS);
+ for (const auto &I : AbbrDeclSets) {
+ OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
+ I.second.dump(OS);
}
}
const DWARFAbbreviationDeclarationSet*
-DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t cu_abbr_offset) const {
- DWARFAbbreviationDeclarationCollMapConstIter end = AbbrevCollMap.end();
- DWARFAbbreviationDeclarationCollMapConstIter pos;
- if (PrevAbbrOffsetPos != end &&
- PrevAbbrOffsetPos->first == cu_abbr_offset) {
+DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
+ const auto End = AbbrDeclSets.end();
+ if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
return &(PrevAbbrOffsetPos->second);
- } else {
- pos = AbbrevCollMap.find(cu_abbr_offset);
- PrevAbbrOffsetPos = pos;
}
- if (pos != AbbrevCollMap.end())
- return &(pos->second);
- return NULL;
+ const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
+ if (Pos != End) {
+ PrevAbbrOffsetPos = Pos;
+ return &(Pos->second);
+ }
+
+ return nullptr;
}
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.h b/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.h
index c7c0436866c4..3a9adba246f0 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.h
@@ -17,55 +17,45 @@
namespace llvm {
-typedef std::vector<DWARFAbbreviationDeclaration>
- DWARFAbbreviationDeclarationColl;
-typedef DWARFAbbreviationDeclarationColl::iterator
- DWARFAbbreviationDeclarationCollIter;
-typedef DWARFAbbreviationDeclarationColl::const_iterator
- DWARFAbbreviationDeclarationCollConstIter;
-
class DWARFAbbreviationDeclarationSet {
uint32_t Offset;
- uint32_t IdxOffset;
+ /// Code of the first abbreviation, if all abbreviations in the set have
+ /// consecutive codes. UINT32_MAX otherwise.
+ uint32_t FirstAbbrCode;
std::vector<DWARFAbbreviationDeclaration> Decls;
- public:
- DWARFAbbreviationDeclarationSet()
- : Offset(0), IdxOffset(0) {}
- DWARFAbbreviationDeclarationSet(uint32_t offset, uint32_t idxOffset)
- : Offset(offset), IdxOffset(idxOffset) {}
+public:
+ DWARFAbbreviationDeclarationSet();
- void clear() {
- IdxOffset = 0;
- Decls.clear();
- }
uint32_t getOffset() const { return Offset; }
void dump(raw_ostream &OS) const;
- bool extract(DataExtractor data, uint32_t* offset_ptr);
+ bool extract(DataExtractor Data, uint32_t *OffsetPtr);
const DWARFAbbreviationDeclaration *
- getAbbreviationDeclaration(uint32_t abbrCode) const;
+ getAbbreviationDeclaration(uint32_t AbbrCode) const;
+
+private:
+ void clear();
};
class DWARFDebugAbbrev {
-public:
typedef std::map<uint64_t, DWARFAbbreviationDeclarationSet>
- DWARFAbbreviationDeclarationCollMap;
- typedef DWARFAbbreviationDeclarationCollMap::iterator
- DWARFAbbreviationDeclarationCollMapIter;
- typedef DWARFAbbreviationDeclarationCollMap::const_iterator
- DWARFAbbreviationDeclarationCollMapConstIter;
+ DWARFAbbreviationDeclarationSetMap;
-private:
- DWARFAbbreviationDeclarationCollMap AbbrevCollMap;
- mutable DWARFAbbreviationDeclarationCollMapConstIter PrevAbbrOffsetPos;
+ DWARFAbbreviationDeclarationSetMap AbbrDeclSets;
+ mutable DWARFAbbreviationDeclarationSetMap::const_iterator PrevAbbrOffsetPos;
public:
DWARFDebugAbbrev();
+
const DWARFAbbreviationDeclarationSet *
- getAbbreviationDeclarationSet(uint64_t cu_abbr_offset) const;
+ getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const;
+
void dump(raw_ostream &OS) const;
- void parse(DataExtractor data);
+ void extract(DataExtractor Data);
+
+private:
+ void clear();
};
}
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp
index 229376e4a1c7..c0a33ceaf243 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp
@@ -67,7 +67,9 @@ DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) {
Descriptor arangeDescriptor;
- assert(sizeof(arangeDescriptor.Address) == sizeof(arangeDescriptor.Length));
+ static_assert(sizeof(arangeDescriptor.Address) ==
+ sizeof(arangeDescriptor.Length),
+ "Different datatypes for addresses and sizes!");
assert(sizeof(arangeDescriptor.Address) >= HeaderData.AddrSize);
while (data.isValidOffset(*offset_ptr)) {
@@ -94,9 +96,9 @@ void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
HeaderData.CuOffset, HeaderData.AddrSize, HeaderData.SegSize);
const uint32_t hex_width = HeaderData.AddrSize * 2;
- for (DescriptorConstIter pos = ArangeDescriptors.begin(),
- end = ArangeDescriptors.end(); pos != end; ++pos)
- OS << format("[0x%*.*" PRIx64 " -", hex_width, hex_width, pos->Address)
+ for (const auto &Desc : ArangeDescriptors) {
+ OS << format("[0x%*.*" PRIx64 " -", hex_width, hex_width, Desc.Address)
<< format(" 0x%*.*" PRIx64 ")\n",
- hex_width, hex_width, pos->getEndAddress());
+ hex_width, hex_width, Desc.getEndAddress());
+ }
}
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.h b/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.h
index 49a713201d1f..d6c2d8b27c52 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.h
@@ -10,6 +10,7 @@
#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/DataExtractor.h"
#include <vector>
@@ -44,7 +45,7 @@ public:
private:
typedef std::vector<Descriptor> DescriptorColl;
- typedef DescriptorColl::const_iterator DescriptorConstIter;
+ typedef iterator_range<DescriptorColl::const_iterator> desc_iterator_range;
uint32_t Offset;
Header HeaderData;
@@ -57,11 +58,10 @@ public:
void dump(raw_ostream &OS) const;
uint32_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; }
- uint32_t getNumDescriptors() const { return ArangeDescriptors.size(); }
- const Descriptor *getDescriptor(uint32_t i) const {
- if (i < ArangeDescriptors.size())
- return &ArangeDescriptors[i];
- return NULL;
+
+ desc_iterator_range descriptors() const {
+ return desc_iterator_range(ArangeDescriptors.begin(),
+ ArangeDescriptors.end());
}
};
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp
index 591d4bde7124..fe7e46d63ba1 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp
@@ -10,40 +10,28 @@
#include "DWARFDebugAranges.h"
#include "DWARFCompileUnit.h"
#include "DWARFContext.h"
+#include "DWARFDebugArangeSet.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
+#include <set>
using namespace llvm;
void DWARFDebugAranges::extract(DataExtractor DebugArangesData) {
if (!DebugArangesData.isValidOffset(0))
return;
uint32_t Offset = 0;
- typedef std::vector<DWARFDebugArangeSet> RangeSetColl;
- RangeSetColl Sets;
DWARFDebugArangeSet Set;
- uint32_t TotalRanges = 0;
while (Set.extract(DebugArangesData, &Offset)) {
- Sets.push_back(Set);
- TotalRanges += Set.getNumDescriptors();
- }
- if (TotalRanges == 0)
- return;
-
- Aranges.reserve(TotalRanges);
- for (RangeSetColl::const_iterator I = Sets.begin(), E = Sets.end(); I != E;
- ++I) {
- uint32_t CUOffset = I->getCompileUnitDIEOffset();
-
- for (uint32_t i = 0, n = I->getNumDescriptors(); i < n; ++i) {
- const DWARFDebugArangeSet::Descriptor *ArangeDescPtr =
- I->getDescriptor(i);
- uint64_t LowPC = ArangeDescPtr->Address;
- uint64_t HighPC = LowPC + ArangeDescPtr->Length;
+ uint32_t CUOffset = Set.getCompileUnitDIEOffset();
+ for (const auto &Desc : Set.descriptors()) {
+ uint64_t LowPC = Desc.Address;
+ uint64_t HighPC = Desc.getEndAddress();
appendRange(CUOffset, LowPC, HighPC);
}
+ ParsedCUOffsets.insert(CUOffset);
}
}
@@ -59,77 +47,66 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
// Generate aranges from DIEs: even if .debug_aranges section is present,
// it may describe only a small subset of compilation units, so we need to
// manually build aranges for the rest of them.
- for (uint32_t i = 0, n = CTX->getNumCompileUnits(); i < n; ++i) {
- if (DWARFCompileUnit *CU = CTX->getCompileUnitAtIndex(i)) {
- uint32_t CUOffset = CU->getOffset();
- if (ParsedCUOffsets.insert(CUOffset).second)
- CU->buildAddressRangeTable(this, true, CUOffset);
+ for (const auto &CU : CTX->compile_units()) {
+ uint32_t CUOffset = CU->getOffset();
+ if (ParsedCUOffsets.insert(CUOffset).second) {
+ DWARFAddressRangesVector CURanges;
+ CU->collectAddressRanges(CURanges);
+ for (const auto &R : CURanges) {
+ appendRange(CUOffset, R.first, R.second);
+ }
}
}
- sortAndMinimize();
+ construct();
}
-void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
- uint64_t HighPC) {
- if (!Aranges.empty()) {
- if (Aranges.back().CUOffset == CUOffset &&
- Aranges.back().HighPC() == LowPC) {
- Aranges.back().setHighPC(HighPC);
- return;
- }
- }
- Aranges.push_back(Range(LowPC, HighPC, CUOffset));
+void DWARFDebugAranges::clear() {
+ Endpoints.clear();
+ Aranges.clear();
+ ParsedCUOffsets.clear();
}
-void DWARFDebugAranges::sortAndMinimize() {
- const size_t orig_arange_size = Aranges.size();
- // Size of one? If so, no sorting is needed
- if (orig_arange_size <= 1)
- return;
- // Sort our address range entries
- std::stable_sort(Aranges.begin(), Aranges.end());
-
- // Most address ranges are contiguous from function to function
- // so our new ranges will likely be smaller. We calculate the size
- // of the new ranges since although std::vector objects can be resized,
- // the will never reduce their allocated block size and free any excesss
- // memory, so we might as well start a brand new collection so it is as
- // small as possible.
-
- // First calculate the size of the new minimal arange vector
- // so we don't have to do a bunch of re-allocations as we
- // copy the new minimal stuff over to the new collection.
- size_t minimal_size = 1;
- for (size_t i = 1; i < orig_arange_size; ++i) {
- if (!Range::SortedOverlapCheck(Aranges[i-1], Aranges[i]))
- ++minimal_size;
- }
-
- // If the sizes are the same, then no consecutive aranges can be
- // combined, we are done.
- if (minimal_size == orig_arange_size)
+void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
+ uint64_t HighPC) {
+ if (LowPC >= HighPC)
return;
+ Endpoints.emplace_back(LowPC, CUOffset, true);
+ Endpoints.emplace_back(HighPC, CUOffset, false);
+}
- // Else, make a new RangeColl that _only_ contains what we need.
- RangeColl minimal_aranges;
- minimal_aranges.resize(minimal_size);
- uint32_t j = 0;
- minimal_aranges[j] = Aranges[0];
- for (size_t i = 1; i < orig_arange_size; ++i) {
- if (Range::SortedOverlapCheck(minimal_aranges[j], Aranges[i])) {
- minimal_aranges[j].setHighPC(Aranges[i].HighPC());
+void DWARFDebugAranges::construct() {
+ std::multiset<uint32_t> ValidCUs; // Maintain the set of CUs describing
+ // a current address range.
+ std::sort(Endpoints.begin(), Endpoints.end());
+ uint64_t PrevAddress = -1ULL;
+ for (const auto &E : Endpoints) {
+ if (PrevAddress < E.Address && ValidCUs.size() > 0) {
+ // If the address range between two endpoints is described by some
+ // CU, first try to extend the last range in Aranges. If we can't
+ // do it, start a new range.
+ if (!Aranges.empty() && Aranges.back().HighPC() == PrevAddress &&
+ ValidCUs.find(Aranges.back().CUOffset) != ValidCUs.end()) {
+ Aranges.back().setHighPC(E.Address);
+ } else {
+ Aranges.emplace_back(PrevAddress, E.Address, *ValidCUs.begin());
+ }
+ }
+ // Update the set of valid CUs.
+ if (E.IsRangeStart) {
+ ValidCUs.insert(E.CUOffset);
} else {
- // Only increment j if we aren't merging
- minimal_aranges[++j] = Aranges[i];
+ auto CUPos = ValidCUs.find(E.CUOffset);
+ assert(CUPos != ValidCUs.end());
+ ValidCUs.erase(CUPos);
}
+ PrevAddress = E.Address;
}
- assert(j+1 == minimal_size);
+ assert(ValidCUs.empty());
- // Now swap our new minimal aranges into place. The local
- // minimal_aranges will then contian the old big collection
- // which will get freed.
- minimal_aranges.swap(Aranges);
+ // Endpoints are not needed now.
+ std::vector<RangeEndpoint> EmptyEndpoints;
+ EmptyEndpoints.swap(Endpoints);
}
uint32_t DWARFDebugAranges::findAddress(uint64_t Address) const {
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.h b/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.h
index 35ad8e53d63d..a9f37fe772c7 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.h
@@ -10,9 +10,9 @@
#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
-#include "DWARFDebugArangeSet.h"
#include "llvm/ADT/DenseSet.h"
-#include <list>
+#include "llvm/Support/DataExtractor.h"
+#include <vector>
namespace llvm {
@@ -20,21 +20,16 @@ class DWARFContext;
class DWARFDebugAranges {
public:
- void clear() {
- Aranges.clear();
- ParsedCUOffsets.clear();
- }
-
void generate(DWARFContext *CTX);
-
- // Use appendRange multiple times and then call sortAndMinimize.
- void appendRange(uint32_t CUOffset, uint64_t LowPC, uint64_t HighPC);
-
uint32_t findAddress(uint64_t Address) const;
private:
+ void clear();
void extract(DataExtractor DebugArangesData);
- void sortAndMinimize();
+
+ // Call appendRange multiple times and then call construct.
+ void appendRange(uint32_t CUOffset, uint64_t LowPC, uint64_t HighPC);
+ void construct();
struct Range {
explicit Range(uint64_t LowPC = -1ULL, uint64_t HighPC = -1ULL,
@@ -52,31 +47,39 @@ private:
return LowPC + Length;
return -1ULL;
}
+
bool containsAddress(uint64_t Address) const {
return LowPC <= Address && Address < HighPC();
}
-
- bool operator <(const Range &other) const {
+ bool operator<(const Range &other) const {
return LowPC < other.LowPC;
}
- static bool SortedOverlapCheck(const Range &Left, const Range &Right) {
- if (Left.CUOffset != Right.CUOffset)
- return false;
- return Left.HighPC() >= Right.LowPC;
- }
-
uint64_t LowPC; // Start of address range.
uint32_t Length; // End of address range (not including this address).
uint32_t CUOffset; // Offset of the compile unit or die.
};
+ struct RangeEndpoint {
+ uint64_t Address;
+ uint32_t CUOffset;
+ bool IsRangeStart;
+
+ RangeEndpoint(uint64_t Address, uint32_t CUOffset, bool IsRangeStart)
+ : Address(Address), CUOffset(CUOffset), IsRangeStart(IsRangeStart) {}
+
+ bool operator<(const RangeEndpoint &Other) const {
+ return Address < Other.Address;
+ }
+ };
+
+
typedef std::vector<Range> RangeColl;
typedef RangeColl::const_iterator RangeCollIterator;
- typedef DenseSet<uint32_t> ParsedCUOffsetColl;
+ std::vector<RangeEndpoint> Endpoints;
RangeColl Aranges;
- ParsedCUOffsetColl ParsedCUOffsets;
+ DenseSet<uint32_t> ParsedCUOffsets;
};
}
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp
index 3efe6a1ebd30..a33548e95b0b 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp
@@ -10,8 +10,8 @@
#include "DWARFDebugFrame.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
@@ -26,8 +26,8 @@ using namespace dwarf;
class llvm::FrameEntry {
public:
enum FrameKind {FK_CIE, FK_FDE};
- FrameEntry(FrameKind K, DataExtractor D, uint64_t Offset, uint64_t Length)
- : Kind(K), Data(D), Offset(Offset), Length(Length) {}
+ FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
+ : Kind(K), Offset(Offset), Length(Length) {}
virtual ~FrameEntry() {
}
@@ -35,11 +35,12 @@ public:
FrameKind getKind() const { return Kind; }
virtual uint64_t getOffset() const { return Offset; }
- /// \brief Parse and store a sequence of CFI instructions from our data
- /// stream, starting at *Offset and ending at EndOffset. If everything
+ /// \brief Parse and store a sequence of CFI instructions from Data,
+ /// starting at *Offset and ending at EndOffset. If everything
/// goes well, *Offset should be equal to EndOffset when this method
/// returns. Otherwise, an error occurred.
- virtual void parseInstructions(uint32_t *Offset, uint32_t EndOffset);
+ virtual void parseInstructions(DataExtractor Data, uint32_t *Offset,
+ uint32_t EndOffset);
/// \brief Dump the entry header to the given output stream.
virtual void dumpHeader(raw_ostream &OS) const = 0;
@@ -50,10 +51,6 @@ public:
protected:
const FrameKind Kind;
- /// \brief The data stream holding the section from which the entry was
- /// parsed.
- DataExtractor Data;
-
/// \brief Offset of this entry in the section.
uint64_t Offset;
@@ -97,8 +94,8 @@ protected:
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
-
-void FrameEntry::parseInstructions(uint32_t *Offset, uint32_t EndOffset) {
+void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
+ uint32_t EndOffset) {
while (*Offset < EndOffset) {
uint8_t Opcode = Data.getU8(Offset);
// Some instructions have a primary opcode encoded in the top bits.
@@ -125,6 +122,7 @@ void FrameEntry::parseInstructions(uint32_t *Offset, uint32_t EndOffset) {
case DW_CFA_nop:
case DW_CFA_remember_state:
case DW_CFA_restore_state:
+ case DW_CFA_GNU_window_save:
// No operands
addInstruction(Opcode);
break;
@@ -185,10 +183,8 @@ void FrameEntry::parseInstructions(uint32_t *Offset, uint32_t EndOffset) {
void FrameEntry::dumpInstructions(raw_ostream &OS) const {
// TODO: at the moment only instruction names are dumped. Expand this to
// dump operands as well.
- for (std::vector<Instruction>::const_iterator I = Instructions.begin(),
- E = Instructions.end();
- I != E; ++I) {
- uint8_t Opcode = I->Opcode;
+ for (const auto &Instr : Instructions) {
+ uint8_t Opcode = Instr.Opcode;
if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
OS << " " << CallFrameString(Opcode) << ":\n";
@@ -202,18 +198,18 @@ class CIE : public FrameEntry {
public:
// CIEs (and FDEs) are simply container classes, so the only sensible way to
// create them is by providing the full parsed contents in the constructor.
- CIE(DataExtractor D, uint64_t Offset, uint64_t Length, uint8_t Version,
+ CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
SmallString<8> Augmentation, uint64_t CodeAlignmentFactor,
int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister)
- : FrameEntry(FK_CIE, D, Offset, Length), Version(Version),
- Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor),
- DataAlignmentFactor(DataAlignmentFactor),
- ReturnAddressRegister(ReturnAddressRegister) {}
+ : FrameEntry(FK_CIE, Offset, Length), Version(Version),
+ Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor),
+ DataAlignmentFactor(DataAlignmentFactor),
+ ReturnAddressRegister(ReturnAddressRegister) {}
~CIE() {
}
- void dumpHeader(raw_ostream &OS) const {
+ void dumpHeader(raw_ostream &OS) const override {
OS << format("%08x %08x %08x CIE",
(uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)
<< "\n";
@@ -230,7 +226,7 @@ public:
static bool classof(const FrameEntry *FE) {
return FE->getKind() == FK_CIE;
- }
+ }
private:
/// The following fields are defined in section 6.4.1 of the DWARF standard v3
@@ -248,16 +244,16 @@ public:
// Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
// an offset to the CIE (provided by parsing the FDE header). The CIE itself
// is obtained lazily once it's actually required.
- FDE(DataExtractor D, uint64_t Offset, uint64_t Length,
- int64_t LinkedCIEOffset, uint64_t InitialLocation, uint64_t AddressRange)
- : FrameEntry(FK_FDE, D, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
- InitialLocation(InitialLocation), AddressRange(AddressRange),
- LinkedCIE(NULL) {}
+ FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
+ uint64_t InitialLocation, uint64_t AddressRange)
+ : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
+ InitialLocation(InitialLocation), AddressRange(AddressRange),
+ LinkedCIE(nullptr) {}
~FDE() {
}
- void dumpHeader(raw_ostream &OS) const {
+ void dumpHeader(raw_ostream &OS) const override {
OS << format("%08x %08x %08x FDE ",
(uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset);
OS << format("cie=%08x pc=%08x...%08x\n",
@@ -271,9 +267,9 @@ public:
static bool classof(const FrameEntry *FE) {
return FE->getKind() == FK_FDE;
- }
-private:
+ }
+private:
/// The following fields are defined in section 6.4.1 of the DWARF standard v3
uint64_t LinkedCIEOffset;
uint64_t InitialLocation;
@@ -286,15 +282,9 @@ private:
DWARFDebugFrame::DWARFDebugFrame() {
}
-
DWARFDebugFrame::~DWARFDebugFrame() {
- for (EntryVector::iterator I = Entries.begin(), E = Entries.end();
- I != E; ++I) {
- delete *I;
- }
}
-
static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
uint32_t Offset, int Length) {
errs() << "DUMP: ";
@@ -336,7 +326,6 @@ void DWARFDebugFrame::parse(DataExtractor Data) {
Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);
- FrameEntry *Entry = 0;
if (IsCIE) {
// Note: this is specifically DWARFv3 CIE header structure. It was
// changed in DWARFv4. We currently don't support reading DWARFv4
@@ -348,30 +337,25 @@ void DWARFDebugFrame::parse(DataExtractor Data) {
int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
- Entry = new CIE(Data, StartOffset, Length, Version,
- StringRef(Augmentation), CodeAlignmentFactor,
- DataAlignmentFactor, ReturnAddressRegister);
+ Entries.emplace_back(new CIE(StartOffset, Length, Version,
+ StringRef(Augmentation), CodeAlignmentFactor,
+ DataAlignmentFactor, ReturnAddressRegister));
} else {
// FDE
uint64_t CIEPointer = Id;
uint64_t InitialLocation = Data.getAddress(&Offset);
uint64_t AddressRange = Data.getAddress(&Offset);
- Entry = new FDE(Data, StartOffset, Length, CIEPointer,
- InitialLocation, AddressRange);
+ Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
+ InitialLocation, AddressRange));
}
- assert(Entry && "Expected Entry to be populated with CIE or FDE");
- Entry->parseInstructions(&Offset, EndStructureOffset);
+ Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
- if (Offset == EndStructureOffset) {
- // Entry instrucitons parsed successfully.
- Entries.push_back(Entry);
- } else {
+ if (Offset != EndStructureOffset) {
std::string Str;
raw_string_ostream OS(Str);
- OS << format("Parsing entry instructions at %lx failed",
- Entry->getOffset());
+ OS << format("Parsing entry instructions at %lx failed", StartOffset);
report_fatal_error(Str);
}
}
@@ -380,9 +364,7 @@ void DWARFDebugFrame::parse(DataExtractor Data) {
void DWARFDebugFrame::dump(raw_ostream &OS) const {
OS << "\n";
- for (EntryVector::const_iterator I = Entries.begin(), E = Entries.end();
- I != E; ++I) {
- FrameEntry *Entry = *I;
+ for (const auto &Entry : Entries) {
Entry->dumpHeader(OS);
Entry->dumpInstructions(OS);
OS << "\n";
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.h b/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.h
index 48b8d63a5a64..bd4ef45e4cfe 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.h
@@ -12,14 +12,13 @@
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/raw_ostream.h"
+#include <memory>
#include <vector>
-
namespace llvm {
class FrameEntry;
-
/// \brief A parsed .debug_frame section
///
class DWARFDebugFrame {
@@ -35,12 +34,10 @@ public:
void parse(DataExtractor Data);
private:
- typedef std::vector<FrameEntry *> EntryVector;
- EntryVector Entries;
+ std::vector<std::unique_ptr<FrameEntry>> Entries;
};
} // namespace llvm
-#endif
-
+#endif
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index babfd2ece067..2e7a54aeb858 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp
@@ -18,6 +18,7 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace dwarf;
+typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
unsigned recurseDepth,
@@ -40,11 +41,8 @@ void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
AbbrevDecl->hasChildren() ? '*' : ' ');
// Dump all data in the DIE for the attributes.
- const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
- for (uint32_t i = 0; i != numAttributes; ++i) {
- uint16_t attr = AbbrevDecl->getAttrByIndex(i);
- uint16_t form = AbbrevDecl->getFormByIndex(i);
- dumpAttribute(OS, u, &offset, attr, form, indent);
+ for (const auto &AttrSpec : AbbrevDecl->attributes()) {
+ dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent);
}
const DWARFDebugInfoEntryMinimal *child = getFirstChild();
@@ -102,11 +100,11 @@ bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U,
uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
if (0 == AbbrCode) {
// NULL debug tag entry.
- AbbrevDecl = NULL;
+ AbbrevDecl = nullptr;
return true;
}
AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
- if (0 == AbbrevDecl) {
+ if (nullptr == AbbrevDecl) {
// Restore the original offset.
*OffsetPtr = Offset;
return false;
@@ -116,8 +114,8 @@ bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U,
assert(FixedFormSizes.size() > 0);
// Skip all data in the .debug_info for the attributes
- for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) {
- uint16_t Form = AbbrevDecl->getFormByIndex(i);
+ for (const auto &AttrSpec : AbbrevDecl->attributes()) {
+ uint16_t Form = AttrSpec.Form;
uint8_t FixedFormSize =
(Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0;
@@ -212,6 +210,16 @@ uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset(
return Result.hasValue() ? Result.getValue() : FailValue;
}
+uint64_t
+DWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U,
+ uint64_t FailValue) const {
+ uint64_t Result =
+ getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL);
+ if (Result != -1ULL)
+ return Result;
+ return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue);
+}
+
bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
uint64_t &LowPC,
uint64_t &HighPC) const {
@@ -229,54 +237,66 @@ bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
return (HighPC != -1ULL);
}
-void DWARFDebugInfoEntryMinimal::buildAddressRangeTable(
- const DWARFUnit *U, DWARFDebugAranges *DebugAranges,
- uint32_t UOffsetInAranges) const {
- if (AbbrevDecl) {
- if (isSubprogramDIE()) {
- uint64_t LowPC, HighPC;
- if (getLowAndHighPC(U, LowPC, HighPC))
- DebugAranges->appendRange(UOffsetInAranges, LowPC, HighPC);
- // FIXME: try to append ranges from .debug_ranges section.
- }
-
- const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
- while (Child) {
- Child->buildAddressRangeTable(U, DebugAranges, UOffsetInAranges);
- Child = Child->getSibling();
- }
- }
-}
-
-bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
- const DWARFUnit *U, const uint64_t Address) const {
+DWARFAddressRangesVector
+DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
if (isNULL())
- return false;
+ return DWARFAddressRangesVector();
+ // Single range specified by low/high PC.
uint64_t LowPC, HighPC;
- if (getLowAndHighPC(U, LowPC, HighPC))
- return (LowPC <= Address && Address <= HighPC);
- // Try to get address ranges from .debug_ranges section.
+ if (getLowAndHighPC(U, LowPC, HighPC)) {
+ return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
+ }
+ // Multiple ranges from .debug_ranges section.
uint32_t RangesOffset =
getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
if (RangesOffset != -1U) {
DWARFDebugRangeList RangeList;
if (U->extractRangeList(RangesOffset, RangeList))
- return RangeList.containsAddress(U->getBaseAddress(), Address);
+ return RangeList.getAbsoluteRanges(U->getBaseAddress());
+ }
+ return DWARFAddressRangesVector();
+}
+
+void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
+ const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
+ if (isNULL())
+ return;
+ if (isSubprogramDIE()) {
+ const auto &DIERanges = getAddressRanges(U);
+ Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
+ }
+
+ const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
+ while (Child) {
+ Child->collectChildrenAddressRanges(U, Ranges);
+ Child = Child->getSibling();
+ }
+}
+
+bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
+ const DWARFUnit *U, const uint64_t Address) const {
+ for (const auto& R : getAddressRanges(U)) {
+ if (R.first <= Address && Address < R.second)
+ return true;
}
return false;
}
const char *
-DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
- if (!isSubroutineDIE())
- return 0;
- // Try to get mangled name if possible.
- if (const char *name =
- getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, 0))
- return name;
- if (const char *name = getAttributeValueAsString(U, DW_AT_linkage_name, 0))
- return name;
- if (const char *name = getAttributeValueAsString(U, DW_AT_name, 0))
+DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
+ FunctionNameKind Kind) const {
+ if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
+ return nullptr;
+ // Try to get mangled name only if it was asked for.
+ if (Kind == FunctionNameKind::LinkageName) {
+ if (const char *name =
+ getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
+ return name;
+ if (const char *name =
+ getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
+ return name;
+ }
+ if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
return name;
// Try to get name from specification DIE.
uint32_t spec_ref =
@@ -284,7 +304,7 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
if (spec_ref != -1U) {
DWARFDebugInfoEntryMinimal spec_die;
if (spec_die.extractFast(U, &spec_ref)) {
- if (const char *name = spec_die.getSubroutineName(U))
+ if (const char *name = spec_die.getSubroutineName(U, Kind))
return name;
}
}
@@ -294,11 +314,11 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
if (abs_origin_ref != -1U) {
DWARFDebugInfoEntryMinimal abs_origin_die;
if (abs_origin_die.extractFast(U, &abs_origin_ref)) {
- if (const char *name = abs_origin_die.getSubroutineName(U))
+ if (const char *name = abs_origin_die.getSubroutineName(U, Kind))
return name;
}
}
- return 0;
+ return nullptr;
}
void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U,
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h b/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h
index aa61056332ef..cc58eb652adc 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h
@@ -11,7 +11,9 @@
#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
#include "DWARFAbbreviationDeclaration.h"
+#include "DWARFDebugRangeList.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -28,17 +30,13 @@ class DWARFDebugInfoEntryMinimal {
/// Offset within the .debug_info of the start of this entry.
uint32_t Offset;
- /// How many to subtract from "this" to get the parent.
- /// If zero this die has no parent.
- uint32_t ParentIdx;
-
/// How many to add to "this" to get the sibling.
uint32_t SiblingIdx;
const DWARFAbbreviationDeclaration *AbbrevDecl;
public:
DWARFDebugInfoEntryMinimal()
- : Offset(0), ParentIdx(0), SiblingIdx(0), AbbrevDecl(0) {}
+ : Offset(0), SiblingIdx(0), AbbrevDecl(nullptr) {}
void dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth,
unsigned indent = 0) const;
@@ -51,7 +49,7 @@ public:
bool extractFast(const DWARFUnit *U, uint32_t *OffsetPtr);
uint32_t getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : 0; }
- bool isNULL() const { return AbbrevDecl == 0; }
+ bool isNULL() const { return AbbrevDecl == nullptr; }
/// Returns true if DIE represents a subprogram (not inlined).
bool isSubprogramDIE() const;
@@ -60,51 +58,26 @@ public:
bool isSubroutineDIE() const;
uint32_t getOffset() const { return Offset; }
- uint32_t getNumAttributes() const {
- return !isNULL() ? AbbrevDecl->getNumAttributes() : 0;
- }
bool hasChildren() const { return !isNULL() && AbbrevDecl->hasChildren(); }
// We know we are kept in a vector of contiguous entries, so we know
- // our parent will be some index behind "this".
- DWARFDebugInfoEntryMinimal *getParent() {
- return ParentIdx > 0 ? this - ParentIdx : 0;
- }
- const DWARFDebugInfoEntryMinimal *getParent() const {
- return ParentIdx > 0 ? this - ParentIdx : 0;
- }
- // We know we are kept in a vector of contiguous entries, so we know
// our sibling will be some index after "this".
- DWARFDebugInfoEntryMinimal *getSibling() {
- return SiblingIdx > 0 ? this + SiblingIdx : 0;
- }
const DWARFDebugInfoEntryMinimal *getSibling() const {
- return SiblingIdx > 0 ? this + SiblingIdx : 0;
+ return SiblingIdx > 0 ? this + SiblingIdx : nullptr;
}
+
// We know we are kept in a vector of contiguous entries, so we know
// we don't need to store our child pointer, if we have a child it will
// be the next entry in the list...
- DWARFDebugInfoEntryMinimal *getFirstChild() {
- return hasChildren() ? this + 1 : 0;
- }
const DWARFDebugInfoEntryMinimal *getFirstChild() const {
- return hasChildren() ? this + 1 : 0;
+ return hasChildren() ? this + 1 : nullptr;
}
- void setParent(DWARFDebugInfoEntryMinimal *parent) {
- if (parent) {
- // We know we are kept in a vector of contiguous entries, so we know
- // our parent will be some index behind "this".
- ParentIdx = this - parent;
- } else
- ParentIdx = 0;
- }
- void setSibling(DWARFDebugInfoEntryMinimal *sibling) {
- if (sibling) {
+ void setSibling(const DWARFDebugInfoEntryMinimal *Sibling) {
+ if (Sibling) {
// We know we are kept in a vector of contiguous entries, so we know
// our sibling will be some index after "this".
- SiblingIdx = sibling - this;
- sibling->setParent(getParent());
+ SiblingIdx = Sibling - this;
} else
SiblingIdx = 0;
}
@@ -133,14 +106,17 @@ public:
const uint16_t Attr,
uint64_t FailValue) const;
+ uint64_t getRangesBaseAttribute(const DWARFUnit *U, uint64_t FailValue) const;
+
/// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
/// Returns true if both attributes are present.
bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC,
uint64_t &HighPC) const;
- void buildAddressRangeTable(const DWARFUnit *U,
- DWARFDebugAranges *DebugAranges,
- uint32_t CUOffsetInAranges) const;
+ DWARFAddressRangesVector getAddressRanges(const DWARFUnit *U) const;
+
+ void collectChildrenAddressRanges(const DWARFUnit *U,
+ DWARFAddressRangesVector &Ranges) const;
bool addressRangeContainsAddress(const DWARFUnit *U,
const uint64_t Address) const;
@@ -149,7 +125,9 @@ public:
/// returns its mangled name (or short name, if mangled is missing).
/// This name may be fetched from specification or abstract origin
/// for this subprogram. Returns null if no name is found.
- const char *getSubroutineName(const DWARFUnit *U) const;
+ const char *
+ getSubroutineName(const DWARFUnit *U,
+ DILineInfoSpecifier::FunctionNameKind Kind) const;
/// Retrieves values of DW_AT_call_file, DW_AT_call_line and
/// DW_AT_call_column from DIE (or zeroes if they are missing).
@@ -169,7 +147,7 @@ public:
/// (except the last DIE) in this chain is contained in address
/// range for next DIE in the chain.
struct DWARFDebugInfoEntryInlinedChain {
- DWARFDebugInfoEntryInlinedChain() : U(0) {}
+ DWARFDebugInfoEntryInlinedChain() : U(nullptr) {}
SmallVector<DWARFDebugInfoEntryMinimal, 4> DIEs;
const DWARFUnit *U;
};
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp
index 13d09dd298b9..ce87635507e1 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp
@@ -15,17 +15,32 @@
#include <algorithm>
using namespace llvm;
using namespace dwarf;
+typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
+
+DWARFDebugLine::Prologue::Prologue() {
+ clear();
+}
+
+void DWARFDebugLine::Prologue::clear() {
+ TotalLength = Version = PrologueLength = 0;
+ MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
+ OpcodeBase = 0;
+ StandardOpcodeLengths.clear();
+ IncludeDirectories.clear();
+ FileNames.clear();
+}
void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
OS << "Line table prologue:\n"
- << format(" total_length: 0x%8.8x\n", TotalLength)
- << format(" version: %u\n", Version)
- << format("prologue_length: 0x%8.8x\n", PrologueLength)
- << format("min_inst_length: %u\n", MinInstLength)
- << format("default_is_stmt: %u\n", DefaultIsStmt)
- << format(" line_base: %i\n", LineBase)
- << format(" line_range: %u\n", LineRange)
- << format(" opcode_base: %u\n", OpcodeBase);
+ << format(" total_length: 0x%8.8x\n", TotalLength)
+ << format(" version: %u\n", Version)
+ << format(" prologue_length: 0x%8.8x\n", PrologueLength)
+ << format(" min_inst_length: %u\n", MinInstLength)
+ << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
+ << format(" default_is_stmt: %u\n", DefaultIsStmt)
+ << format(" line_base: %i\n", LineBase)
+ << format(" line_range: %u\n", LineRange)
+ << format(" opcode_base: %u\n", OpcodeBase);
for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i)
OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i+1),
@@ -50,6 +65,67 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
}
}
+bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data,
+ uint32_t *offset_ptr) {
+ const uint32_t prologue_offset = *offset_ptr;
+
+ clear();
+ TotalLength = debug_line_data.getU32(offset_ptr);
+ Version = debug_line_data.getU16(offset_ptr);
+ if (Version < 2)
+ return false;
+
+ PrologueLength = debug_line_data.getU32(offset_ptr);
+ const uint32_t end_prologue_offset = PrologueLength + *offset_ptr;
+ MinInstLength = debug_line_data.getU8(offset_ptr);
+ if (Version >= 4)
+ MaxOpsPerInst = debug_line_data.getU8(offset_ptr);
+ DefaultIsStmt = debug_line_data.getU8(offset_ptr);
+ LineBase = debug_line_data.getU8(offset_ptr);
+ LineRange = debug_line_data.getU8(offset_ptr);
+ OpcodeBase = debug_line_data.getU8(offset_ptr);
+
+ StandardOpcodeLengths.reserve(OpcodeBase - 1);
+ for (uint32_t i = 1; i < OpcodeBase; ++i) {
+ uint8_t op_len = debug_line_data.getU8(offset_ptr);
+ StandardOpcodeLengths.push_back(op_len);
+ }
+
+ while (*offset_ptr < end_prologue_offset) {
+ const char *s = debug_line_data.getCStr(offset_ptr);
+ if (s && s[0])
+ IncludeDirectories.push_back(s);
+ else
+ break;
+ }
+
+ while (*offset_ptr < end_prologue_offset) {
+ const char *name = debug_line_data.getCStr(offset_ptr);
+ if (name && name[0]) {
+ FileNameEntry fileEntry;
+ fileEntry.Name = name;
+ fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
+ fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
+ fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
+ FileNames.push_back(fileEntry);
+ } else {
+ break;
+ }
+ }
+
+ if (*offset_ptr != end_prologue_offset) {
+ fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should"
+ " have ended at 0x%8.8x but it ended at 0x%8.8x\n",
+ prologue_offset, end_prologue_offset, *offset_ptr);
+ return false;
+ }
+ return true;
+}
+
+DWARFDebugLine::Row::Row(bool default_is_stmt) {
+ reset(default_is_stmt);
+}
+
void DWARFDebugLine::Row::postAppend() {
BasicBlock = false;
PrologueEnd = false;
@@ -62,6 +138,7 @@ void DWARFDebugLine::Row::reset(bool default_is_stmt) {
Column = 0;
File = 1;
Isa = 0;
+ Discriminator = 0;
IsStmt = default_is_stmt;
BasicBlock = false;
EndSequence = false;
@@ -71,7 +148,7 @@ void DWARFDebugLine::Row::reset(bool default_is_stmt) {
void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
- << format(" %6u %3u ", File, Isa)
+ << format(" %6u %3u %13u ", File, Isa, Discriminator)
<< (IsStmt ? " is_stmt" : "")
<< (BasicBlock ? " basic_block" : "")
<< (PrologueEnd ? " prologue_end" : "")
@@ -80,63 +157,70 @@ void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
<< '\n';
}
+DWARFDebugLine::Sequence::Sequence() {
+ reset();
+}
+
+void DWARFDebugLine::Sequence::reset() {
+ LowPC = 0;
+ HighPC = 0;
+ FirstRowIndex = 0;
+ LastRowIndex = 0;
+ Empty = true;
+}
+
+DWARFDebugLine::LineTable::LineTable() {
+ clear();
+}
+
void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
Prologue.dump(OS);
OS << '\n';
if (!Rows.empty()) {
- OS << "Address Line Column File ISA Flags\n"
- << "------------------ ------ ------ ------ --- -------------\n";
- for (std::vector<Row>::const_iterator pos = Rows.begin(),
- end = Rows.end(); pos != end; ++pos)
- pos->dump(OS);
+ OS << "Address Line Column File ISA Discriminator Flags\n"
+ << "------------------ ------ ------ ------ --- ------------- "
+ "-------------\n";
+ for (const Row &R : Rows) {
+ R.dump(OS);
+ }
}
}
-DWARFDebugLine::State::~State() {}
-
-void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) {
- if (Sequence::Empty) {
- // Record the beginning of instruction sequence.
- Sequence::Empty = false;
- Sequence::LowPC = Address;
- Sequence::FirstRowIndex = row;
- }
- ++row; // Increase the row number.
- LineTable::appendRow(*this);
- if (EndSequence) {
- // Record the end of instruction sequence.
- Sequence::HighPC = Address;
- Sequence::LastRowIndex = row;
- if (Sequence::isValid())
- LineTable::appendSequence(*this);
- Sequence::reset();
- }
- Row::postAppend();
+void DWARFDebugLine::LineTable::clear() {
+ Prologue.clear();
+ Rows.clear();
+ Sequences.clear();
}
-void DWARFDebugLine::State::finalize() {
- row = DoneParsingLineTable;
- if (!Sequence::Empty) {
- fprintf(stderr, "warning: last sequence in debug line table is not"
- "terminated!\n");
- }
- // Sort all sequences so that address lookup will work faster.
- if (!Sequences.empty()) {
- std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
- // Note: actually, instruction address ranges of sequences should not
- // overlap (in shared objects and executables). If they do, the address
- // lookup would still work, though, but result would be ambiguous.
- // We don't report warning in this case. For example,
- // sometimes .so compiled from multiple object files contains a few
- // rudimentary sequences for address ranges [0x0, 0xsomething).
- }
+DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT)
+ : LineTable(LT), RowNumber(0) {
+ resetRowAndSequence();
}
-DWARFDebugLine::DumpingState::~DumpingState() {}
+void DWARFDebugLine::ParsingState::resetRowAndSequence() {
+ Row.reset(LineTable->Prologue.DefaultIsStmt);
+ Sequence.reset();
+}
-void DWARFDebugLine::DumpingState::finalize() {
- LineTable::dump(OS);
+void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) {
+ if (Sequence.Empty) {
+ // Record the beginning of instruction sequence.
+ Sequence.Empty = false;
+ Sequence.LowPC = Row.Address;
+ Sequence.FirstRowIndex = RowNumber;
+ }
+ ++RowNumber;
+ LineTable->appendRow(Row);
+ if (Row.EndSequence) {
+ // Record the end of instruction sequence.
+ Sequence.HighPC = Row.Address;
+ Sequence.LastRowIndex = RowNumber;
+ if (Sequence.isValid())
+ LineTable->appendSequence(Sequence);
+ Sequence.reset();
+ }
+ Row.postAppend();
}
const DWARFDebugLine::LineTable *
@@ -144,7 +228,7 @@ DWARFDebugLine::getLineTable(uint32_t offset) const {
LineTableConstIter pos = LineTableMap.find(offset);
if (pos != LineTableMap.end())
return &pos->second;
- return 0;
+ return nullptr;
}
const DWARFDebugLine::LineTable *
@@ -152,90 +236,31 @@ DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
uint32_t offset) {
std::pair<LineTableIter, bool> pos =
LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable()));
+ LineTable *LT = &pos.first->second;
if (pos.second) {
- // Parse and cache the line table for at this offset.
- State state;
- if (!parseStatementTable(debug_line_data, RelocMap, &offset, state))
- return 0;
- pos.first->second = state;
- }
- return &pos.first->second;
-}
-
-bool
-DWARFDebugLine::parsePrologue(DataExtractor debug_line_data,
- uint32_t *offset_ptr, Prologue *prologue) {
- const uint32_t prologue_offset = *offset_ptr;
-
- prologue->clear();
- prologue->TotalLength = debug_line_data.getU32(offset_ptr);
- prologue->Version = debug_line_data.getU16(offset_ptr);
- if (prologue->Version != 2)
- return false;
-
- prologue->PrologueLength = debug_line_data.getU32(offset_ptr);
- const uint32_t end_prologue_offset = prologue->PrologueLength + *offset_ptr;
- prologue->MinInstLength = debug_line_data.getU8(offset_ptr);
- prologue->DefaultIsStmt = debug_line_data.getU8(offset_ptr);
- prologue->LineBase = debug_line_data.getU8(offset_ptr);
- prologue->LineRange = debug_line_data.getU8(offset_ptr);
- prologue->OpcodeBase = debug_line_data.getU8(offset_ptr);
-
- prologue->StandardOpcodeLengths.reserve(prologue->OpcodeBase-1);
- for (uint32_t i = 1; i < prologue->OpcodeBase; ++i) {
- uint8_t op_len = debug_line_data.getU8(offset_ptr);
- prologue->StandardOpcodeLengths.push_back(op_len);
- }
-
- while (*offset_ptr < end_prologue_offset) {
- const char *s = debug_line_data.getCStr(offset_ptr);
- if (s && s[0])
- prologue->IncludeDirectories.push_back(s);
- else
- break;
- }
-
- while (*offset_ptr < end_prologue_offset) {
- const char *name = debug_line_data.getCStr(offset_ptr);
- if (name && name[0]) {
- FileNameEntry fileEntry;
- fileEntry.Name = name;
- fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
- fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
- fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
- prologue->FileNames.push_back(fileEntry);
- } else {
- break;
- }
- }
-
- if (*offset_ptr != end_prologue_offset) {
- fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should"
- " have ended at 0x%8.8x but it ended at 0x%8.8x\n",
- prologue_offset, end_prologue_offset, *offset_ptr);
- return false;
+ if (!LT->parse(debug_line_data, RelocMap, &offset))
+ return nullptr;
}
- return true;
+ return LT;
}
-bool
-DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
- const RelocAddrMap *RMap,
- uint32_t *offset_ptr, State &state) {
+bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
+ const RelocAddrMap *RMap,
+ uint32_t *offset_ptr) {
const uint32_t debug_line_offset = *offset_ptr;
- Prologue *prologue = &state.Prologue;
+ clear();
- if (!parsePrologue(debug_line_data, offset_ptr, prologue)) {
+ if (!Prologue.parse(debug_line_data, offset_ptr)) {
// Restore our offset and return false to indicate failure!
*offset_ptr = debug_line_offset;
return false;
}
- const uint32_t end_offset = debug_line_offset + prologue->TotalLength +
- sizeof(prologue->TotalLength);
+ const uint32_t end_offset = debug_line_offset + Prologue.TotalLength +
+ sizeof(Prologue.TotalLength);
- state.reset();
+ ParsingState State(this);
while (*offset_ptr < end_offset) {
uint8_t opcode = debug_line_data.getU8(offset_ptr);
@@ -257,9 +282,9 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
// with a DW_LNE_end_sequence instruction which creates a row whose
// address is that of the byte after the last target machine instruction
// of the sequence.
- state.EndSequence = true;
- state.appendRowToMatrix(*offset_ptr);
- state.reset();
+ State.Row.EndSequence = true;
+ State.appendRowToMatrix(*offset_ptr);
+ State.resetRowAndSequence();
break;
case DW_LNE_set_address:
@@ -274,9 +299,10 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
if (AI != RMap->end()) {
const std::pair<uint8_t, int64_t> &R = AI->second;
- state.Address = debug_line_data.getAddress(offset_ptr) + R.second;
+ State.Row.Address =
+ debug_line_data.getAddress(offset_ptr) + R.second;
} else
- state.Address = debug_line_data.getAddress(offset_ptr);
+ State.Row.Address = debug_line_data.getAddress(offset_ptr);
}
break;
@@ -307,62 +333,66 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
- prologue->FileNames.push_back(fileEntry);
+ Prologue.FileNames.push_back(fileEntry);
}
break;
+ case DW_LNE_set_discriminator:
+ State.Row.Discriminator = debug_line_data.getULEB128(offset_ptr);
+ break;
+
default:
// Length doesn't include the zero opcode byte or the length itself, but
// it does include the sub_opcode, so we have to adjust for that below
(*offset_ptr) += arg_size;
break;
}
- } else if (opcode < prologue->OpcodeBase) {
+ } else if (opcode < Prologue.OpcodeBase) {
switch (opcode) {
// Standard Opcodes
case DW_LNS_copy:
// Takes no arguments. Append a row to the matrix using the
// current values of the state-machine registers. Then set
// the basic_block register to false.
- state.appendRowToMatrix(*offset_ptr);
+ State.appendRowToMatrix(*offset_ptr);
break;
case DW_LNS_advance_pc:
// Takes a single unsigned LEB128 operand, multiplies it by the
// min_inst_length field of the prologue, and adds the
// result to the address register of the state machine.
- state.Address += debug_line_data.getULEB128(offset_ptr) *
- prologue->MinInstLength;
+ State.Row.Address +=
+ debug_line_data.getULEB128(offset_ptr) * Prologue.MinInstLength;
break;
case DW_LNS_advance_line:
// Takes a single signed LEB128 operand and adds that value to
// the line register of the state machine.
- state.Line += debug_line_data.getSLEB128(offset_ptr);
+ State.Row.Line += debug_line_data.getSLEB128(offset_ptr);
break;
case DW_LNS_set_file:
// Takes a single unsigned LEB128 operand and stores it in the file
// register of the state machine.
- state.File = debug_line_data.getULEB128(offset_ptr);
+ State.Row.File = debug_line_data.getULEB128(offset_ptr);
break;
case DW_LNS_set_column:
// Takes a single unsigned LEB128 operand and stores it in the
// column register of the state machine.
- state.Column = debug_line_data.getULEB128(offset_ptr);
+ State.Row.Column = debug_line_data.getULEB128(offset_ptr);
break;
case DW_LNS_negate_stmt:
// Takes no arguments. Set the is_stmt register of the state
// machine to the logical negation of its current value.
- state.IsStmt = !state.IsStmt;
+ State.Row.IsStmt = !State.Row.IsStmt;
break;
case DW_LNS_set_basic_block:
// Takes no arguments. Set the basic_block register of the
// state machine to true
- state.BasicBlock = true;
+ State.Row.BasicBlock = true;
break;
case DW_LNS_const_add_pc:
@@ -378,10 +408,10 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
// than twice that range will it need to use both DW_LNS_advance_pc
// and a special opcode, requiring three or more bytes.
{
- uint8_t adjust_opcode = 255 - prologue->OpcodeBase;
- uint64_t addr_offset = (adjust_opcode / prologue->LineRange) *
- prologue->MinInstLength;
- state.Address += addr_offset;
+ uint8_t adjust_opcode = 255 - Prologue.OpcodeBase;
+ uint64_t addr_offset =
+ (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
+ State.Row.Address += addr_offset;
}
break;
@@ -395,25 +425,25 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
// judge when the computation of a special opcode overflows and
// requires the use of DW_LNS_advance_pc. Such assemblers, however,
// can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
- state.Address += debug_line_data.getU16(offset_ptr);
+ State.Row.Address += debug_line_data.getU16(offset_ptr);
break;
case DW_LNS_set_prologue_end:
// Takes no arguments. Set the prologue_end register of the
// state machine to true
- state.PrologueEnd = true;
+ State.Row.PrologueEnd = true;
break;
case DW_LNS_set_epilogue_begin:
// Takes no arguments. Set the basic_block register of the
// state machine to true
- state.EpilogueBegin = true;
+ State.Row.EpilogueBegin = true;
break;
case DW_LNS_set_isa:
// Takes a single unsigned LEB128 operand and stores it in the
// column register of the state machine.
- state.Isa = debug_line_data.getULEB128(offset_ptr);
+ State.Row.Isa = debug_line_data.getULEB128(offset_ptr);
break;
default:
@@ -421,9 +451,9 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
// of such opcodes because they are specified in the prologue
// as a multiple of LEB128 operands for each opcode.
{
- assert(opcode - 1U < prologue->StandardOpcodeLengths.size());
- uint8_t opcode_length = prologue->StandardOpcodeLengths[opcode - 1];
- for (uint8_t i=0; i<opcode_length; ++i)
+ assert(opcode - 1U < Prologue.StandardOpcodeLengths.size());
+ uint8_t opcode_length = Prologue.StandardOpcodeLengths[opcode - 1];
+ for (uint8_t i = 0; i < opcode_length; ++i)
debug_line_data.getULEB128(offset_ptr);
}
break;
@@ -462,24 +492,37 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
//
// line increment = line_base + (adjusted opcode % line_range)
- uint8_t adjust_opcode = opcode - prologue->OpcodeBase;
- uint64_t addr_offset = (adjust_opcode / prologue->LineRange) *
- prologue->MinInstLength;
- int32_t line_offset = prologue->LineBase +
- (adjust_opcode % prologue->LineRange);
- state.Line += line_offset;
- state.Address += addr_offset;
- state.appendRowToMatrix(*offset_ptr);
+ uint8_t adjust_opcode = opcode - Prologue.OpcodeBase;
+ uint64_t addr_offset =
+ (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
+ int32_t line_offset =
+ Prologue.LineBase + (adjust_opcode % Prologue.LineRange);
+ State.Row.Line += line_offset;
+ State.Row.Address += addr_offset;
+ State.appendRowToMatrix(*offset_ptr);
}
}
- state.finalize();
+ if (!State.Sequence.Empty) {
+ fprintf(stderr, "warning: last sequence in debug line table is not"
+ "terminated!\n");
+ }
+
+ // Sort all sequences so that address lookup will work faster.
+ if (!Sequences.empty()) {
+ std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
+ // Note: actually, instruction address ranges of sequences should not
+ // overlap (in shared objects and executables). If they do, the address
+ // lookup would still work, though, but result would be ambiguous.
+ // We don't report warning in this case. For example,
+ // sometimes .so compiled from multiple object files contains a few
+ // rudimentary sequences for address ranges [0x0, 0xsomething).
+ }
return end_offset;
}
-uint32_t
-DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
+uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
uint32_t unknown_index = UINT32_MAX;
if (Sequences.empty())
return unknown_index;
@@ -524,10 +567,8 @@ DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
return index;
}
-bool
-DWARFDebugLine::LineTable::lookupAddressRange(uint64_t address,
- uint64_t size,
- std::vector<uint32_t>& result) const {
+bool DWARFDebugLine::LineTable::lookupAddressRange(
+ uint64_t address, uint64_t size, std::vector<uint32_t> &result) const {
if (Sequences.empty())
return false;
uint64_t end_addr = address + size;
@@ -603,13 +644,14 @@ DWARFDebugLine::LineTable::lookupAddressRange(uint64_t address,
bool
DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
- bool NeedsAbsoluteFilePath,
+ FileLineInfoKind Kind,
std::string &Result) const {
- if (FileIndex == 0 || FileIndex > Prologue.FileNames.size())
+ if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() ||
+ Kind == FileLineInfoKind::None)
return false;
const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
const char *FileName = Entry.Name;
- if (!NeedsAbsoluteFilePath ||
+ if (Kind != FileLineInfoKind::AbsoluteFilePath ||
sys::path::is_absolute(FileName)) {
Result = FileName;
return true;
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugLine.h b/contrib/llvm/lib/DebugInfo/DWARFDebugLine.h
index 2990756bd7c9..c7b7ec2c0e70 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugLine.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugLine.h
@@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
#include "DWARFRelocMap.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/DataExtractor.h"
#include <map>
#include <string>
@@ -24,7 +25,7 @@ class DWARFDebugLine {
public:
DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {}
struct FileNameEntry {
- FileNameEntry() : Name(0), DirIdx(0), ModTime(0), Length(0) {}
+ FileNameEntry() : Name(nullptr), DirIdx(0), ModTime(0), Length(0) {}
const char *Name;
uint64_t DirIdx;
@@ -33,9 +34,7 @@ public:
};
struct Prologue {
- Prologue()
- : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0),
- DefaultIsStmt(0), LineBase(0), LineRange(0), OpcodeBase(0) {}
+ Prologue();
// The size in bytes of the statement information for this compilation unit
// (not including the total_length field itself).
@@ -49,6 +48,9 @@ public:
// program opcodes that alter the address register first multiply their
// operands by this value.
uint8_t MinInstLength;
+ // The maximum number of individual operations that may be encoded in an
+ // instruction.
+ uint8_t MaxOpsPerInst;
// The initial value of theis_stmtregister.
uint8_t DefaultIsStmt;
// This parameter affects the meaning of the special opcodes. See below.
@@ -73,19 +75,16 @@ public:
int32_t getMaxLineIncrementForSpecialOpcode() const {
return LineBase + (int8_t)LineRange - 1;
}
+
+ void clear();
void dump(raw_ostream &OS) const;
- void clear() {
- TotalLength = Version = PrologueLength = 0;
- MinInstLength = LineBase = LineRange = OpcodeBase = 0;
- StandardOpcodeLengths.clear();
- IncludeDirectories.clear();
- FileNames.clear();
- }
+ bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr);
};
// Standard .debug_line state machine structure.
struct Row {
- Row(bool default_is_stmt = false) { reset(default_is_stmt); }
+ explicit Row(bool default_is_stmt = false);
+
/// Called after a row is appended to the matrix.
void postAppend();
void reset(bool default_is_stmt);
@@ -112,6 +111,9 @@ public:
// An unsigned integer whose value encodes the applicable instruction set
// architecture for the current instruction.
uint8_t Isa;
+ // An unsigned integer representing the DWARF path discriminator value
+ // for this location.
+ uint32_t Discriminator;
// A boolean indicating that the current instruction is the beginning of a
// statement.
uint8_t IsStmt:1,
@@ -144,14 +146,9 @@ public:
unsigned LastRowIndex;
bool Empty;
- Sequence() { reset(); }
- void reset() {
- LowPC = 0;
- HighPC = 0;
- FirstRowIndex = 0;
- LastRowIndex = 0;
- Empty = true;
- }
+ Sequence();
+ void reset();
+
static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
return LHS.LowPC < RHS.LowPC;
}
@@ -164,31 +161,34 @@ public:
};
struct LineTable {
- void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); }
- void appendSequence(const DWARFDebugLine::Sequence &sequence) {
- Sequences.push_back(sequence);
+ LineTable();
+
+ void appendRow(const DWARFDebugLine::Row &R) {
+ Rows.push_back(R);
}
- void clear() {
- Prologue.clear();
- Rows.clear();
- Sequences.clear();
+ void appendSequence(const DWARFDebugLine::Sequence &S) {
+ Sequences.push_back(S);
}
// Returns the index of the row with file/line info for a given address,
// or -1 if there is no such row.
uint32_t lookupAddress(uint64_t address) const;
- bool lookupAddressRange(uint64_t address,
- uint64_t size,
- std::vector<uint32_t>& result) const;
+ bool lookupAddressRange(uint64_t address, uint64_t size,
+ std::vector<uint32_t> &result) const;
// Extracts filename by its index in filename table in prologue.
// Returns true on success.
bool getFileNameByIndex(uint64_t FileIndex,
- bool NeedsAbsoluteFilePath,
+ DILineInfoSpecifier::FileLineInfoKind Kind,
std::string &Result) const;
void dump(raw_ostream &OS) const;
+ void clear();
+
+ /// Parse prologue and all rows.
+ bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap,
+ uint32_t *offset_ptr);
struct Prologue Prologue;
typedef std::vector<Row> RowVector;
@@ -199,48 +199,26 @@ public:
SequenceVector Sequences;
};
- struct State : public Row, public Sequence, public LineTable {
- // Special row codes.
- enum {
- StartParsingLineTable = 0,
- DoneParsingLineTable = -1
- };
-
- State() : row(StartParsingLineTable) {}
- virtual ~State();
-
- virtual void appendRowToMatrix(uint32_t offset);
- virtual void finalize();
- virtual void reset() {
- Row::reset(Prologue.DefaultIsStmt);
- Sequence::reset();
- }
-
- // The row number that starts at zero for the prologue, and increases for
- // each row added to the matrix.
- unsigned row;
- };
-
- struct DumpingState : public State {
- DumpingState(raw_ostream &OS) : OS(OS) {}
- virtual ~DumpingState();
- virtual void finalize();
- private:
- raw_ostream &OS;
- };
-
- static bool parsePrologue(DataExtractor debug_line_data, uint32_t *offset_ptr,
- Prologue *prologue);
- /// Parse a single line table (prologue and all rows).
- static bool parseStatementTable(DataExtractor debug_line_data,
- const RelocAddrMap *RMap,
- uint32_t *offset_ptr, State &state);
-
const LineTable *getLineTable(uint32_t offset) const;
const LineTable *getOrParseLineTable(DataExtractor debug_line_data,
uint32_t offset);
private:
+ struct ParsingState {
+ ParsingState(struct LineTable *LT);
+
+ void resetRowAndSequence();
+ void appendRowToMatrix(uint32_t offset);
+
+ // Line table we're currently parsing.
+ struct LineTable *LineTable;
+ // The row number that starts at zero for the prologue, and increases for
+ // each row added to the matrix.
+ unsigned RowNumber;
+ struct Row Row;
+ struct Sequence Sequence;
+ };
+
typedef std::map<uint32_t, LineTable> LineTableMapTy;
typedef LineTableMapTy::iterator LineTableIter;
typedef LineTableMapTy::const_iterator LineTableConstIter;
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp
index 3895ffa8d7a7..e4aa5dcce27e 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp
@@ -11,23 +11,24 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Dwarf.h"
using namespace llvm;
void DWARFDebugLoc::dump(raw_ostream &OS) const {
- for (LocationLists::const_iterator I = Locations.begin(), E = Locations.end(); I != E; ++I) {
- OS << format("0x%8.8x: ", I->Offset);
+ for (const LocationList &L : Locations) {
+ OS << format("0x%8.8x: ", L.Offset);
const unsigned Indent = 12;
- for (SmallVectorImpl<Entry>::const_iterator I2 = I->Entries.begin(), E2 = I->Entries.end(); I2 != E2; ++I2) {
- if (I2 != I->Entries.begin())
+ for (const Entry &E : L.Entries) {
+ if (&E != L.Entries.begin())
OS.indent(Indent);
- OS << "Beginning address offset: " << format("0x%016" PRIx64, I2->Begin)
+ OS << "Beginning address offset: " << format("0x%016" PRIx64, E.Begin)
<< '\n';
OS.indent(Indent) << " Ending address offset: "
- << format("0x%016" PRIx64, I2->End) << '\n';
+ << format("0x%016" PRIx64, E.End) << '\n';
OS.indent(Indent) << " Location description: ";
- for (SmallVectorImpl<unsigned char>::const_iterator I3 = I2->Loc.begin(), E3 = I2->Loc.end(); I3 != E3; ++I3) {
- OS << format("%2.2x ", *I3);
+ for (unsigned char Loc : E.Loc) {
+ OS << format("%2.2x ", Loc);
}
OS << "\n\n";
}
@@ -36,7 +37,7 @@ void DWARFDebugLoc::dump(raw_ostream &OS) const {
void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
uint32_t Offset = 0;
- while (data.isValidOffset(Offset)) {
+ while (data.isValidOffset(Offset+AddressSize-1)) {
Locations.resize(Locations.size() + 1);
LocationList &Loc = Locations.back();
Loc.Offset = Offset;
@@ -68,7 +69,60 @@ void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
Offset += Bytes;
E.Loc.reserve(str.size());
std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
- Loc.Entries.push_back(llvm_move(E));
+ Loc.Entries.push_back(std::move(E));
}
}
+ if (data.isValidOffset(Offset))
+ llvm::errs() << "error: failed to consume entire .debug_loc section\n";
}
+
+void DWARFDebugLocDWO::parse(DataExtractor data) {
+ uint32_t Offset = 0;
+ while (data.isValidOffset(Offset)) {
+ Locations.resize(Locations.size() + 1);
+ LocationList &Loc = Locations.back();
+ Loc.Offset = Offset;
+ dwarf::LocationListEntry Kind;
+ while ((Kind = static_cast<dwarf::LocationListEntry>(
+ data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list_entry) {
+
+ if (Kind != dwarf::DW_LLE_start_length_entry) {
+ llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind
+ << " not implemented\n";
+ return;
+ }
+
+ Entry E;
+
+ E.Start = data.getULEB128(&Offset);
+ E.Length = data.getU32(&Offset);
+
+ unsigned Bytes = data.getU16(&Offset);
+ // A single location description describing the location of the object...
+ StringRef str = data.getData().substr(Offset, Bytes);
+ Offset += Bytes;
+ E.Loc.resize(str.size());
+ std::copy(str.begin(), str.end(), E.Loc.begin());
+
+ Loc.Entries.push_back(std::move(E));
+ }
+ }
+}
+
+void DWARFDebugLocDWO::dump(raw_ostream &OS) const {
+ for (const LocationList &L : Locations) {
+ OS << format("0x%8.8x: ", L.Offset);
+ const unsigned Indent = 12;
+ for (const Entry &E : L.Entries) {
+ if (&E != L.Entries.begin())
+ OS.indent(Indent);
+ OS << "Beginning address index: " << E.Start << '\n';
+ OS.indent(Indent) << " Length: " << E.Length << '\n';
+ OS.indent(Indent) << " Location description: ";
+ for (unsigned char Loc : E.Loc)
+ OS << format("%2.2x ", Loc);
+ OS << "\n\n";
+ }
+ }
+}
+
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.h b/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.h
index d31aaaa12737..663acbb42f8d 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.h
@@ -55,6 +55,27 @@ public:
/// specified address size to interpret the address ranges.
void parse(DataExtractor data, unsigned AddressSize);
};
+
+class DWARFDebugLocDWO {
+ struct Entry {
+ uint64_t Start;
+ uint32_t Length;
+ SmallVector<unsigned char, 4> Loc;
+ };
+
+ struct LocationList {
+ unsigned Offset;
+ SmallVector<Entry, 2> Entries;
+ };
+
+ typedef SmallVector<LocationList, 4> LocationLists;
+
+ LocationLists Locations;
+
+public:
+ void parse(DataExtractor data);
+ void dump(raw_ostream &OS) const;
+};
}
#endif
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp
index 1806beee7285..07b23b32d1f3 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp
@@ -45,23 +45,25 @@ bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) {
}
void DWARFDebugRangeList::dump(raw_ostream &OS) const {
- for (int i = 0, n = Entries.size(); i != n; ++i) {
+ for (const RangeListEntry &RLE : Entries) {
const char *format_str = (AddressSize == 4
? "%08x %08" PRIx64 " %08" PRIx64 "\n"
: "%08x %016" PRIx64 " %016" PRIx64 "\n");
- OS << format(format_str, Offset, Entries[i].StartAddress,
- Entries[i].EndAddress);
+ OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);
}
OS << format("%08x <End of list>\n", Offset);
}
-bool DWARFDebugRangeList::containsAddress(uint64_t BaseAddress,
- uint64_t Address) const {
- for (int i = 0, n = Entries.size(); i != n; ++i) {
- if (Entries[i].isBaseAddressSelectionEntry(AddressSize))
- BaseAddress = Entries[i].EndAddress;
- else if (Entries[i].containsAddress(BaseAddress, Address))
- return true;
+DWARFAddressRangesVector
+DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
+ DWARFAddressRangesVector Res;
+ for (const RangeListEntry &RLE : Entries) {
+ if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
+ BaseAddress = RLE.EndAddress;
+ } else {
+ Res.push_back(std::make_pair(BaseAddress + RLE.StartAddress,
+ BaseAddress + RLE.EndAddress));
+ }
}
- return false;
+ return Res;
}
diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.h b/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.h
index 4e34a916f4a3..587b550a6688 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.h
@@ -17,6 +17,9 @@ namespace llvm {
class raw_ostream;
+/// DWARFAddressRangesVector - represents a set of absolute address ranges.
+typedef std::vector<std::pair<uint64_t, uint64_t>> DWARFAddressRangesVector;
+
class DWARFDebugRangeList {
public:
struct RangeListEntry {
@@ -50,10 +53,6 @@ public:
else
return StartAddress == -1ULL;
}
- bool containsAddress(uint64_t BaseAddress, uint64_t Address) const {
- return (BaseAddress + StartAddress <= Address) &&
- (Address < BaseAddress + EndAddress);
- }
};
private:
@@ -67,10 +66,10 @@ public:
void clear();
void dump(raw_ostream &OS) const;
bool extract(DataExtractor data, uint32_t *offset_ptr);
- /// containsAddress - Returns true if range list contains the given
- /// address. Has to be passed base address of the compile unit that
- /// references this range list.
- bool containsAddress(uint64_t BaseAddress, uint64_t Address) const;
+ /// getAbsoluteRanges - Returns absolute address ranges defined by this range
+ /// list. Has to be passed base address of the compile unit referencing this
+ /// range list.
+ DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const;
};
} // namespace llvm
diff --git a/contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp b/contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp
index da71fb3d1161..8d0f96620a49 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp
@@ -131,7 +131,7 @@ bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
const DWARFUnit *cu) {
bool indirect = false;
bool is_block = false;
- Value.data = NULL;
+ Value.data = nullptr;
// Read the value for the form into value and follow and DW_FORM_indirect
// instances we run into
do {
@@ -241,7 +241,7 @@ bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
if (is_block) {
StringRef str = data.getData().substr(*offset_ptr, Value.uval);
- Value.data = NULL;
+ Value.data = nullptr;
if (!str.empty()) {
Value.data = reinterpret_cast<const uint8_t *>(str.data());
*offset_ptr += Value.uval;
@@ -488,7 +488,7 @@ Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const {
return None;
if (Form == DW_FORM_string)
return Value.cstr;
- if (U == 0)
+ if (!U)
return None;
uint32_t Offset = Value.uval;
if (Form == DW_FORM_GNU_str_index) {
@@ -509,7 +509,7 @@ Optional<uint64_t> DWARFFormValue::getAsAddress(const DWARFUnit *U) const {
if (Form == DW_FORM_GNU_addr_index) {
uint32_t Index = Value.uval;
uint64_t Result;
- if (U == 0 || !U->getAddrOffsetSectionItem(Index, Result))
+ if (!U || !U->getAddrOffsetSectionItem(Index, Result))
return None;
return Result;
}
@@ -525,7 +525,7 @@ Optional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const {
case DW_FORM_ref4:
case DW_FORM_ref8:
case DW_FORM_ref_udata:
- if (U == 0)
+ if (!U)
return None;
return Value.uval + U->getOffset();
case DW_FORM_ref_addr:
diff --git a/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.h b/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.h
index 7a0dab204d0a..cf773b8d8ef3 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.h
@@ -19,14 +19,16 @@ private:
uint64_t TypeHash;
uint32_t TypeOffset;
public:
- DWARFTypeUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
- StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
+ DWARFTypeUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
+ StringRef SS, StringRef SOS, StringRef AOS,
const RelocAddrMap *M, bool LE)
- : DWARFUnit(DA, IS, AS, RS, SS, SOS, AOS, M, LE) {}
- uint32_t getSize() const LLVM_OVERRIDE { return DWARFUnit::getSize() + 12; }
+ : DWARFUnit(DA, IS, RS, SS, SOS, AOS, M, LE) {}
+ uint32_t getHeaderSize() const override {
+ return DWARFUnit::getHeaderSize() + 12;
+ }
void dump(raw_ostream &OS);
protected:
- bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) LLVM_OVERRIDE;
+ bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) override;
};
}
diff --git a/contrib/llvm/lib/DebugInfo/DWARFUnit.cpp b/contrib/llvm/lib/DebugInfo/DWARFUnit.cpp
index 5167eb947c41..39d0a0ff5a4c 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFUnit.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARFUnit.cpp
@@ -17,12 +17,12 @@
using namespace llvm;
using namespace dwarf;
-DWARFUnit::DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
- StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
+DWARFUnit::DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
+ StringRef SS, StringRef SOS, StringRef AOS,
const RelocAddrMap *M, bool LE)
- : Abbrev(DA), InfoSection(IS), AbbrevSection(AS), RangeSection(RS),
- StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
- RelocMap(M), isLittleEndian(LE) {
+ : Abbrev(DA), InfoSection(IS), RangeSection(RS), StringSection(SS),
+ StringOffsetSection(SOS), AddrOffsetSection(AOS), RelocMap(M),
+ isLittleEndian(LE) {
clear();
}
@@ -54,18 +54,20 @@ bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
Length = debug_info.getU32(offset_ptr);
Version = debug_info.getU16(offset_ptr);
- uint64_t abbrOffset = debug_info.getU32(offset_ptr);
+ uint64_t AbbrOffset = debug_info.getU32(offset_ptr);
AddrSize = debug_info.getU8(offset_ptr);
- bool lengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
- bool versionOK = DWARFContext::isSupportedVersion(Version);
- bool abbrOffsetOK = AbbrevSection.size() > abbrOffset;
- bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
+ bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
+ bool VersionOK = DWARFContext::isSupportedVersion(Version);
+ bool AddrSizeOK = AddrSize == 4 || AddrSize == 8;
- if (!lengthOK || !versionOK || !addrSizeOK || !abbrOffsetOK)
+ if (!LengthOK || !VersionOK || !AddrSizeOK)
+ return false;
+
+ Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
+ if (Abbrevs == nullptr)
return false;
- Abbrevs = Abbrev->getAbbreviationDeclarationSet(abbrOffset);
return true;
}
@@ -98,7 +100,7 @@ void DWARFUnit::clear() {
Offset = 0;
Length = 0;
Version = 0;
- Abbrevs = 0;
+ Abbrevs = nullptr;
AddrSize = 0;
BaseAddr = 0;
RangeSectionBase = 0;
@@ -110,8 +112,8 @@ void DWARFUnit::clear() {
const char *DWARFUnit::getCompilationDir() {
extractDIEsIfNeeded(true);
if (DieArray.empty())
- return 0;
- return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
+ return nullptr;
+ return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, nullptr);
}
uint64_t DWARFUnit::getDWOId() {
@@ -124,38 +126,32 @@ uint64_t DWARFUnit::getDWOId() {
}
void DWARFUnit::setDIERelations() {
- if (DieArray.empty())
+ if (DieArray.size() <= 1)
return;
- DWARFDebugInfoEntryMinimal *die_array_begin = &DieArray.front();
- DWARFDebugInfoEntryMinimal *die_array_end = &DieArray.back();
- DWARFDebugInfoEntryMinimal *curr_die;
- // We purposely are skipping the last element in the array in the loop below
- // so that we can always have a valid next item
- for (curr_die = die_array_begin; curr_die < die_array_end; ++curr_die) {
- // Since our loop doesn't include the last element, we can always
- // safely access the next die in the array.
- DWARFDebugInfoEntryMinimal *next_die = curr_die + 1;
-
- const DWARFAbbreviationDeclaration *curr_die_abbrev =
- curr_die->getAbbreviationDeclarationPtr();
-
- if (curr_die_abbrev) {
- // Normal DIE
- if (curr_die_abbrev->hasChildren())
- next_die->setParent(curr_die);
- else
- curr_die->setSibling(next_die);
+
+ std::vector<DWARFDebugInfoEntryMinimal *> ParentChain;
+ DWARFDebugInfoEntryMinimal *SiblingChain = nullptr;
+ for (auto &DIE : DieArray) {
+ if (SiblingChain) {
+ SiblingChain->setSibling(&DIE);
+ }
+ if (const DWARFAbbreviationDeclaration *AbbrDecl =
+ DIE.getAbbreviationDeclarationPtr()) {
+ // Normal DIE.
+ if (AbbrDecl->hasChildren()) {
+ ParentChain.push_back(&DIE);
+ SiblingChain = nullptr;
+ } else {
+ SiblingChain = &DIE;
+ }
} else {
- // NULL DIE that terminates a sibling chain
- DWARFDebugInfoEntryMinimal *parent = curr_die->getParent();
- if (parent)
- parent->setSibling(next_die);
+ // NULL entry terminates the sibling chain.
+ SiblingChain = ParentChain.back();
+ ParentChain.pop_back();
}
}
-
- // Since we skipped the last element, we need to fix it up!
- if (die_array_begin < die_array_end)
- curr_die->setParent(die_array_begin);
+ assert(SiblingChain == nullptr || SiblingChain == &DieArray[0]);
+ assert(ParentChain.empty());
}
void DWARFUnit::extractDIEsToVector(
@@ -166,13 +162,13 @@ void DWARFUnit::extractDIEsToVector(
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
- uint32_t Offset = getFirstDIEOffset();
+ uint32_t DIEOffset = Offset + getHeaderSize();
uint32_t NextCUOffset = getNextUnitOffset();
DWARFDebugInfoEntryMinimal DIE;
uint32_t Depth = 0;
bool IsCUDie = true;
- while (Offset < NextCUOffset && DIE.extractFast(this, &Offset)) {
+ while (DIEOffset < NextCUOffset && DIE.extractFast(this, &DIEOffset)) {
if (IsCUDie) {
if (AppendCUDie)
Dies.push_back(DIE);
@@ -187,9 +183,8 @@ void DWARFUnit::extractDIEsToVector(
Dies.push_back(DIE);
}
- const DWARFAbbreviationDeclaration *AbbrDecl =
- DIE.getAbbreviationDeclarationPtr();
- if (AbbrDecl) {
+ if (const DWARFAbbreviationDeclaration *AbbrDecl =
+ DIE.getAbbreviationDeclarationPtr()) {
// Normal DIE
if (AbbrDecl->hasChildren())
++Depth;
@@ -205,9 +200,9 @@ void DWARFUnit::extractDIEsToVector(
// Give a little bit of info if we encounter corrupt DWARF (our offset
// should always terminate at or before the start of the next compilation
// unit header).
- if (Offset > NextCUOffset)
+ if (DIEOffset > NextCUOffset)
fprintf(stderr, "warning: DWARF compile unit extends beyond its "
- "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), Offset);
+ "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), DIEOffset);
}
size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
@@ -231,7 +226,9 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
AddrOffsetSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
this, DW_AT_GNU_addr_base, 0);
RangeSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
- this, DW_AT_GNU_ranges_base, 0);
+ this, DW_AT_ranges_base, 0);
+ // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
+ // skeleton CU DIE, so that DWARF users not aware of it are not broken.
}
setDIERelations();
@@ -241,43 +238,44 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
DWARFUnit::DWOHolder::DWOHolder(object::ObjectFile *DWOFile)
: DWOFile(DWOFile),
DWOContext(cast<DWARFContext>(DIContext::getDWARFContext(DWOFile))),
- DWOU(0) {
+ DWOU(nullptr) {
if (DWOContext->getNumDWOCompileUnits() > 0)
DWOU = DWOContext->getDWOCompileUnitAtIndex(0);
}
bool DWARFUnit::parseDWO() {
- if (DWO.get() != 0)
+ if (DWO.get())
return false;
extractDIEsIfNeeded(true);
if (DieArray.empty())
return false;
const char *DWOFileName =
- DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, 0);
- if (DWOFileName == 0)
+ DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, nullptr);
+ if (!DWOFileName)
return false;
const char *CompilationDir =
- DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
+ DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, nullptr);
SmallString<16> AbsolutePath;
- if (sys::path::is_relative(DWOFileName) && CompilationDir != 0) {
+ if (sys::path::is_relative(DWOFileName) && CompilationDir != nullptr) {
sys::path::append(AbsolutePath, CompilationDir);
}
sys::path::append(AbsolutePath, DWOFileName);
- object::ObjectFile *DWOFile =
+ ErrorOr<object::ObjectFile *> DWOFile =
object::ObjectFile::createObjectFile(AbsolutePath);
if (!DWOFile)
return false;
// Reset DWOHolder.
- DWO.reset(new DWOHolder(DWOFile));
+ DWO.reset(new DWOHolder(DWOFile.get()));
DWARFUnit *DWOCU = DWO->getUnit();
// Verify that compile unit in .dwo file is valid.
- if (DWOCU == 0 || DWOCU->getDWOId() != getDWOId()) {
+ if (!DWOCU || DWOCU->getDWOId() != getDWOId()) {
DWO.reset();
return false;
}
// Share .debug_addr and .debug_ranges section with compile unit in .dwo
DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
- DWOCU->setRangesSection(RangeSection, RangeSectionBase);
+ uint32_t DWORangesBase = DieArray[0].getRangesBaseAttribute(this, 0);
+ DWOCU->setRangesSection(RangeSection, DWORangesBase);
return true;
}
@@ -298,52 +296,53 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) {
}
}
-void
-DWARFUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
- bool clear_dies_if_already_not_parsed,
- uint32_t CUOffsetInAranges) {
+void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
+ // First, check if CU DIE describes address ranges for the unit.
+ const auto &CUDIERanges = getCompileUnitDIE()->getAddressRanges(this);
+ if (!CUDIERanges.empty()) {
+ CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
+ return;
+ }
+
// This function is usually called if there in no .debug_aranges section
// in order to produce a compile unit level set of address ranges that
// is accurate. If the DIEs weren't parsed, then we don't want all dies for
// all compile units to stay loaded when they weren't needed. So we can end
// up parsing the DWARF and then throwing them all away to keep memory usage
// down.
- const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
- clear_dies_if_already_not_parsed;
- DieArray[0].buildAddressRangeTable(this, debug_aranges, CUOffsetInAranges);
+ const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
+ DieArray[0].collectChildrenAddressRanges(this, CURanges);
+
+ // Collect address ranges from DIEs in .dwo if necessary.
bool DWOCreated = parseDWO();
- if (DWO.get()) {
- // If there is a .dwo file for this compile unit, then skeleton CU DIE
- // doesn't have children, and we should instead build address range table
- // from DIEs in the .debug_info.dwo section of .dwo file.
- DWO->getUnit()->buildAddressRangeTable(
- debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
- }
- if (DWOCreated && clear_dies_if_already_not_parsed)
+ if (DWO.get())
+ DWO->getUnit()->collectAddressRanges(CURanges);
+ if (DWOCreated)
DWO.reset();
// Keep memory down by clearing DIEs if this generate function
// caused them to be parsed.
- if (clear_dies)
+ if (ClearDIEs)
clearDIEs(true);
}
const DWARFDebugInfoEntryMinimal *
DWARFUnit::getSubprogramForAddress(uint64_t Address) {
extractDIEsIfNeeded(false);
- for (size_t i = 0, n = DieArray.size(); i != n; i++)
- if (DieArray[i].isSubprogramDIE() &&
- DieArray[i].addressRangeContainsAddress(this, Address)) {
- return &DieArray[i];
+ for (const DWARFDebugInfoEntryMinimal &DIE : DieArray) {
+ if (DIE.isSubprogramDIE() &&
+ DIE.addressRangeContainsAddress(this, Address)) {
+ return &DIE;
}
- return 0;
+ }
+ return nullptr;
}
DWARFDebugInfoEntryInlinedChain
DWARFUnit::getInlinedChainForAddress(uint64_t Address) {
// First, find a subprogram that contains the given address (the root
// of inlined chain).
- const DWARFUnit *ChainCU = 0;
+ const DWARFUnit *ChainCU = nullptr;
const DWARFDebugInfoEntryMinimal *SubprogramDIE =
getSubprogramForAddress(Address);
if (SubprogramDIE) {
diff --git a/contrib/llvm/lib/DebugInfo/DWARFUnit.h b/contrib/llvm/lib/DebugInfo/DWARFUnit.h
index bd768a6bce4c..471da36af1cf 100644
--- a/contrib/llvm/lib/DebugInfo/DWARFUnit.h
+++ b/contrib/llvm/lib/DebugInfo/DWARFUnit.h
@@ -10,7 +10,6 @@
#ifndef LLVM_DEBUGINFO_DWARFUNIT_H
#define LLVM_DEBUGINFO_DWARFUNIT_H
-#include "llvm/ADT/OwningPtr.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugRangeList.h"
@@ -30,7 +29,6 @@ class raw_ostream;
class DWARFUnit {
const DWARFDebugAbbrev *Abbrev;
StringRef InfoSection;
- StringRef AbbrevSection;
StringRef RangeSection;
uint32_t RangeSectionBase;
StringRef StringSection;
@@ -50,23 +48,24 @@ class DWARFUnit {
std::vector<DWARFDebugInfoEntryMinimal> DieArray;
class DWOHolder {
- OwningPtr<object::ObjectFile> DWOFile;
- OwningPtr<DWARFContext> DWOContext;
+ std::unique_ptr<object::ObjectFile> DWOFile;
+ std::unique_ptr<DWARFContext> DWOContext;
DWARFUnit *DWOU;
public:
DWOHolder(object::ObjectFile *DWOFile);
DWARFUnit *getUnit() const { return DWOU; }
};
- OwningPtr<DWOHolder> DWO;
+ std::unique_ptr<DWOHolder> DWO;
protected:
virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
+ /// Size in bytes of the unit header.
+ virtual uint32_t getHeaderSize() const { return 11; }
public:
-
- DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
- StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
- const RelocAddrMap *M, bool LE);
+ DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
+ StringRef SS, StringRef SOS, StringRef AOS, const RelocAddrMap *M,
+ bool LE);
virtual ~DWARFUnit();
@@ -103,12 +102,7 @@ public:
DWARFDebugRangeList &RangeList) const;
void clear();
uint32_t getOffset() const { return Offset; }
- /// Size in bytes of the compile unit header.
- virtual uint32_t getSize() const { return 11; }
- uint32_t getFirstDIEOffset() const { return Offset + getSize(); }
uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
- /// Size in bytes of the .debug_info data associated with this compile unit.
- size_t getDebugInfoSize() const { return Length + 4 - getSize(); }
uint32_t getLength() const { return Length; }
uint16_t getVersion() const { return Version; }
const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
@@ -124,15 +118,13 @@ public:
const DWARFDebugInfoEntryMinimal *
getCompileUnitDIE(bool extract_cu_die_only = true) {
extractDIEsIfNeeded(extract_cu_die_only);
- return DieArray.empty() ? NULL : &DieArray[0];
+ return DieArray.empty() ? nullptr : &DieArray[0];
}
const char *getCompilationDir();
uint64_t getDWOId();
- void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
- bool clear_dies_if_already_not_parsed,
- uint32_t CUOffsetInAranges);
+ void collectAddressRanges(DWARFAddressRangesVector &CURanges);
/// getInlinedChainForAddress - fetches inlined chain for a given address.
/// Returns empty chain if there is no subprogram containing address. The
@@ -140,6 +132,9 @@ public:
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address);
private:
+ /// Size in bytes of the .debug_info data associated with this compile unit.
+ size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
+
/// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
/// hasn't already been done. Returns the number of DIEs parsed at this call.
size_t extractDIEsIfNeeded(bool CUDieOnly);
diff --git a/contrib/llvm/lib/DebugInfo/module.modulemap b/contrib/llvm/lib/DebugInfo/module.modulemap
new file mode 100644
index 000000000000..1fe5ab130fd7
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/module.modulemap
@@ -0,0 +1 @@
+module DebugInfo { requires cplusplus umbrella "." module * { export * } }