[llvm] 12e832c - [DWARFYAML] Make the debug_abbrev_offset field optional.
Xing GUO via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 28 23:55:23 PDT 2020
Author: Xing GUO
Date: 2020-08-29T14:54:52+08:00
New Revision: 12e832cbcb62e43810e8bf2d58db8f1d1ce41b3c
URL: https://github.com/llvm/llvm-project/commit/12e832cbcb62e43810e8bf2d58db8f1d1ce41b3c
DIFF: https://github.com/llvm/llvm-project/commit/12e832cbcb62e43810e8bf2d58db8f1d1ce41b3c.diff
LOG: [DWARFYAML] Make the debug_abbrev_offset field optional.
This patch helps make the debug_abbrev_offset field optional. We don't
need to calculate the value of this field in the future.
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D86614
Added:
Modified:
llvm/include/llvm/ObjectYAML/DWARFYAML.h
llvm/lib/ObjectYAML/DWARFEmitter.cpp
llvm/lib/ObjectYAML/DWARFYAML.cpp
llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index 9625d02ea324..d1bfb3e6c657 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -113,7 +113,7 @@ struct Unit {
Optional<uint8_t> AddrSize;
llvm::dwarf::UnitType Type; // Added in DWARF 5
Optional<uint64_t> AbbrevTableID;
- yaml::Hex64 AbbrOffset;
+ Optional<yaml::Hex64> AbbrOffset;
std::vector<Entry> Entries;
};
@@ -231,10 +231,17 @@ struct Data {
bool isEmpty() const;
SetVector<StringRef> getNonEmptySectionNames() const;
- Expected<uint64_t> getAbbrevTableIndexByID(uint64_t ID) const;
+
+ struct AbbrevTableInfo {
+ uint64_t Index;
+ uint64_t Offset;
+ };
+ Expected<AbbrevTableInfo> getAbbrevTableInfoByID(uint64_t ID) const;
+ StringRef getAbbrevTableContentByIndex(uint64_t Index) const;
private:
- mutable std::unordered_map<uint64_t, uint64_t> AbbrevTableID2Index;
+ mutable std::unordered_map<uint64_t, AbbrevTableInfo> AbbrevTableInfoMap;
+ mutable std::unordered_map<uint64_t, std::string> AbbrevTableContents;
};
} // end namespace DWARFYAML
diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
index 912213517334..8375efe66abc 100644
--- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -94,28 +94,45 @@ Error DWARFYAML::emitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) {
return Error::success();
}
-Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
- for (const DWARFYAML::AbbrevTable &AbbrevTable : DI.DebugAbbrev) {
- uint64_t AbbrevCode = 0;
- for (const DWARFYAML::Abbrev &AbbrevDecl : AbbrevTable.Table) {
- AbbrevCode =
- AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
- encodeULEB128(AbbrevCode, OS);
- encodeULEB128(AbbrevDecl.Tag, OS);
- OS.write(AbbrevDecl.Children);
- for (auto Attr : AbbrevDecl.Attributes) {
- encodeULEB128(Attr.Attribute, OS);
- encodeULEB128(Attr.Form, OS);
- if (Attr.Form == dwarf::DW_FORM_implicit_const)
- encodeSLEB128(Attr.Value, OS);
- }
- encodeULEB128(0, OS);
- encodeULEB128(0, OS);
+StringRef DWARFYAML::Data::getAbbrevTableContentByIndex(uint64_t Index) const {
+ assert(Index < DebugAbbrev.size() &&
+ "Index should be less than the size of DebugAbbrev array");
+ auto It = AbbrevTableContents.find(Index);
+ if (It != AbbrevTableContents.cend())
+ return It->second;
+
+ std::string AbbrevTableBuffer;
+ raw_string_ostream OS(AbbrevTableBuffer);
+
+ uint64_t AbbrevCode = 0;
+ for (const DWARFYAML::Abbrev &AbbrevDecl : DebugAbbrev[Index].Table) {
+ AbbrevCode = AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
+ encodeULEB128(AbbrevCode, OS);
+ encodeULEB128(AbbrevDecl.Tag, OS);
+ OS.write(AbbrevDecl.Children);
+ for (auto Attr : AbbrevDecl.Attributes) {
+ encodeULEB128(Attr.Attribute, OS);
+ encodeULEB128(Attr.Form, OS);
+ if (Attr.Form == dwarf::DW_FORM_implicit_const)
+ encodeSLEB128(Attr.Value, OS);
}
+ encodeULEB128(0, OS);
+ encodeULEB128(0, OS);
+ }
+
+ // The abbreviations for a given compilation unit end with an entry
+ // consisting of a 0 byte for the abbreviation code.
+ OS.write_zeros(1);
+
+ AbbrevTableContents.insert({Index, AbbrevTableBuffer});
+
+ return AbbrevTableContents[Index];
+}
- // The abbreviations for a given compilation unit end with an entry
- // consisting of a 0 byte for the abbreviation code.
- OS.write_zeros(1);
+Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
+ for (uint64_t I = 0; I < DI.DebugAbbrev.size(); ++I) {
+ StringRef AbbrevTableContent = DI.getAbbrevTableContentByIndex(I);
+ OS.write(AbbrevTableContent.data(), AbbrevTableContent.size());
}
return Error::success();
@@ -257,16 +274,16 @@ static Expected<uint64_t> writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex,
if (AbbrCode == 0 || Entry.Values.empty())
return OS.tell() - EntryBegin;
- Expected<uint64_t> AbbrevTableIndexOrErr =
- DI.getAbbrevTableIndexByID(AbbrevTableID);
- if (!AbbrevTableIndexOrErr)
+ Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
+ DI.getAbbrevTableInfoByID(AbbrevTableID);
+ if (!AbbrevTableInfoOrErr)
return createStringError(errc::invalid_argument,
- toString(AbbrevTableIndexOrErr.takeError()) +
+ toString(AbbrevTableInfoOrErr.takeError()) +
" for compilation unit with index " +
utostr(CUIndex));
ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(
- DI.DebugAbbrev[*AbbrevTableIndexOrErr].Table);
+ DI.DebugAbbrev[AbbrevTableInfoOrErr->Index].Table);
if (AbbrCode > AbbrevDecls.size())
return createStringError(
@@ -425,12 +442,28 @@ Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
writeInitialLength(Unit.Format, Length, OS, DI.IsLittleEndian);
writeInteger((uint16_t)Unit.Version, OS, DI.IsLittleEndian);
+
+ uint64_t AbbrevTableOffset = 0;
+ if (Unit.AbbrOffset) {
+ AbbrevTableOffset = *Unit.AbbrOffset;
+ } else {
+ if (Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
+ DI.getAbbrevTableInfoByID(AbbrevTableID)) {
+ AbbrevTableOffset = AbbrevTableInfoOrErr->Offset;
+ } else {
+ // The current compilation unit may not have DIEs and it will not be
+ // able to find the associated abbrev table. We consume the error and
+ // assign 0 to the debug_abbrev_offset in such circumstances.
+ consumeError(AbbrevTableInfoOrErr.takeError());
+ }
+ }
+
if (Unit.Version >= 5) {
writeInteger((uint8_t)Unit.Type, OS, DI.IsLittleEndian);
writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
- writeDWARFOffset(Unit.AbbrOffset, Unit.Format, OS, DI.IsLittleEndian);
+ writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
} else {
- writeDWARFOffset(Unit.AbbrOffset, Unit.Format, OS, DI.IsLittleEndian);
+ writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
}
diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp
index 39de3ff18f37..25ddf6b988b5 100644
--- a/llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -55,25 +55,31 @@ SetVector<StringRef> DWARFYAML::Data::getNonEmptySectionNames() const {
return SecNames;
}
-Expected<uint64_t> DWARFYAML::Data::getAbbrevTableIndexByID(uint64_t ID) const {
- if (AbbrevTableID2Index.empty()) {
+Expected<DWARFYAML::Data::AbbrevTableInfo>
+DWARFYAML::Data::getAbbrevTableInfoByID(uint64_t ID) const {
+ if (AbbrevTableInfoMap.empty()) {
+ uint64_t AbbrevTableOffset = 0;
for (auto &AbbrevTable : enumerate(DebugAbbrev)) {
// If the abbrev table's ID isn't specified, we use the index as its ID.
uint64_t AbbrevTableID =
AbbrevTable.value().ID.getValueOr(AbbrevTable.index());
- auto It =
- AbbrevTableID2Index.insert({AbbrevTableID, AbbrevTable.index()});
+ auto It = AbbrevTableInfoMap.insert(
+ {AbbrevTableID, AbbrevTableInfo{/*Index=*/AbbrevTable.index(),
+ /*Offset=*/AbbrevTableOffset}});
if (!It.second)
return createStringError(
errc::invalid_argument,
"the ID (%" PRIu64 ") of abbrev table with index %zu has been used "
"by abbrev table with index %" PRIu64,
- AbbrevTableID, AbbrevTable.index(), It.first->second);
+ AbbrevTableID, AbbrevTable.index(), It.first->second.Index);
+
+ AbbrevTableOffset +=
+ getAbbrevTableContentByIndex(AbbrevTable.index()).size();
}
}
- auto It = AbbrevTableID2Index.find(ID);
- if (It == AbbrevTableID2Index.end())
+ auto It = AbbrevTableInfoMap.find(ID);
+ if (It == AbbrevTableInfoMap.end())
return createStringError(errc::invalid_argument,
"cannot find abbrev table whose ID is %" PRIu64,
ID);
@@ -182,7 +188,7 @@ void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {
if (Unit.Version >= 5)
IO.mapRequired("UnitType", Unit.Type);
IO.mapOptional("AbbrevTableID", Unit.AbbrevTableID);
- IO.mapRequired("AbbrOffset", Unit.AbbrOffset);
+ IO.mapOptional("AbbrOffset", Unit.AbbrOffset);
IO.mapOptional("AddrSize", Unit.AddrSize);
IO.mapOptional("Entries", Unit.Entries);
}
diff --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
index ed3f5b212244..48b9411715e6 100644
--- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
@@ -902,7 +902,8 @@ DWARF:
- Value: 0x1234
## o) Test that yaml2obj is able to generate compilation units according to the
-## associated abbrev table that is referenced by the 'AbbrevTableID'.
+## associated abbrev table that is referenced by the 'AbbrevTableID' and infer
+## the value of the debug_abbrev_offset field.
# RUN: yaml2obj --docnum=17 %s -o %t17.o
# RUN: llvm-readelf --hex-dump=.debug_info %t17.o | FileCheck %s --check-prefix=MULTI-TABLES
@@ -972,29 +973,54 @@ DWARF:
debug_info:
- Version: 4
AbbrevTableID: 2
- AbbrOffset: 8
Entries:
- AbbrCode: 1
Values:
- Value: 0x1234
- Version: 4
AbbrevTableID: 2
- AbbrOffset: 8
Entries:
- AbbrCode: 1
Values:
- Value: 0x4321
- Version: 4
AbbrevTableID: 0
- AbbrOffset: 0
Entries:
- AbbrCode: 1
Values:
- Value: 0x5678
- Version: 4
AbbrevTableID: 1
- AbbrOffset: 16
Entries:
- AbbrCode: 1
Values:
- Value: 0x8765
+
+## p) Test that when the debug_abbrev_offset field isn't specified and there is no associated
+## abbrev table, yaml2obj will assign 0 to the debug_abbrev_offset field.
+
+# RUN: yaml2obj --docnum=18 %s -o %t18.o
+# RUN: llvm-readelf --hex-dump=.debug_info %t18.o | FileCheck %s --check-prefix=ZERO-OFFSET
+
+# ZERO-OFFSET: Hex dump of section '.debug_info':
+# ZERO-OFFSET-NEXT: 0x00000000 07000000 04000000 000008 ...........
+## ^------- unit_length (4-byte)
+## ^--- version (2-byte)
+## ^-------- debug_abbrev_offset (4-byte)
+## ^- address_size (1-byte)
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+DWARF:
+ debug_info:
+ - Version: 4
+ AbbrevTableID: [[ABBREVID=<none>]]
+
+## q) Test that when we assign an invalid 'AbbrevTableID' that doesn't point to an abbrev table,
+## yaml2obj will assign 0 to the debug_abbrev_offset field.
+
+# RUN: yaml2obj --docnum=18 -DABBREVID=2 %s -o %t18.o
+# RUN: llvm-readelf --hex-dump=.debug_info %t18.o | FileCheck %s --check-prefix=ZERO-OFFSET
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
index 9bc278c60412..fb3bea43180c 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -1369,7 +1369,6 @@ TEST(DWARFDebugInfo, TestEmptyChildren) {
" Children: DW_CHILDREN_yes\n"
"debug_info:\n"
" - Version: 4\n"
- " AbbrOffset: 0\n"
" AddrSize: 8\n"
" Entries:\n"
" - AbbrCode: 0x00000001\n"
@@ -1903,7 +1902,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) {
debug_info:
- Length: 22
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -1952,7 +1950,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddr) {
debug_info:
- Length: 22
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -1993,7 +1990,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRanges) {
debug_info:
- Length: 16
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2032,7 +2028,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRnglists) {
- Length: 17
Version: 5
UnitType: DW_UT_compile
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2069,7 +2064,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidStmtList) {
debug_info:
- Length: 16
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2104,7 +2098,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidStrp) {
debug_info:
- Length: 12
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2146,7 +2139,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddrBetween) {
debug_info:
- Length: 22
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2188,7 +2180,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineSequence) {
debug_info:
- Length: 16
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2255,7 +2246,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineFileIndex) {
debug_info:
- Length: 16
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2324,7 +2314,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineTablePorlogueDirIndex) {
debug_info:
- Length: 16
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2394,7 +2383,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyDuplicateFileWarning) {
debug_info:
- Length: 16
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2469,7 +2457,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {
debug_info:
- Length: 16
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2479,7 +2466,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {
- Length: 16
Version: 4
AbbrevTableID: 0
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2594,7 +2580,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyCURangesIncomplete) {
debug_info:
- Length: 46
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2654,7 +2639,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyLexicalBlockRanges) {
debug_info:
- Length: 52
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2712,7 +2696,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyOverlappingFunctionRanges) {
debug_info:
- Length: 55
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2779,7 +2762,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyOverlappingLexicalBlockRanges) {
debug_info:
- Length: 85
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2841,7 +2823,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidDIERange) {
debug_info:
- Length: 34
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2898,7 +2879,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyElidedDoesntFail) {
debug_info:
- Length: 71
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
@@ -2961,7 +2941,6 @@ TEST(DWARFDebugInfo, TestDwarfVerifyNestedFunctions) {
debug_info:
- Length: 73
Version: 4
- AbbrOffset: 0
AddrSize: 8
Entries:
- AbbrCode: 0x00000001
More information about the llvm-commits
mailing list