[llvm] [dwarf2yaml] Correctly emit type and split unit headers (PR #102471)
Pavel Labath via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 8 07:10:20 PDT 2024
https://github.com/labath created https://github.com/llvm/llvm-project/pull/102471
(DWARFv5) split units have an extra `dwo_id` field in the header. Type units have `type_signature` and `type_offset`.
>From e9fa7c9b8f45d99086c9f836bf1ed804eb9840e4 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 8 Aug 2024 16:04:50 +0200
Subject: [PATCH] [dwarf2yaml] Correctly emit type and split unit headers
(DWARFv5) split units have an extra `dwo_id` field in the header. Type
units have `type_signature` and `type_offset`.
---
llvm/include/llvm/ObjectYAML/DWARFYAML.h | 5 +-
llvm/lib/ObjectYAML/DWARFEmitter.cpp | 37 +++++++-
llvm/lib/ObjectYAML/DWARFYAML.cpp | 20 +++-
.../tools/yaml2obj/ELF/DWARF/debug-info.yaml | 92 ++++++++++++++-----
llvm/tools/obj2yaml/dwarf2yaml.cpp | 2 +-
5 files changed, 128 insertions(+), 28 deletions(-)
diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index 7b65e325ef05d2..69f8c4f27d7a39 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -115,6 +115,9 @@ struct Unit {
llvm::dwarf::UnitType Type; // Added in DWARF 5
std::optional<uint64_t> AbbrevTableID;
std::optional<yaml::Hex64> AbbrOffset;
+ yaml::Hex64 TypeSignatureOrDwoID; // For type or split units
+ yaml::Hex64 TypeOffset; // For type units
+
std::vector<Entry> Entries;
};
@@ -245,7 +248,7 @@ struct Data {
std::optional<PubSection> GNUPubNames;
std::optional<PubSection> GNUPubTypes;
- std::vector<Unit> CompileUnits;
+ std::vector<Unit> Units;
std::vector<LineTable> DebugLines;
std::optional<std::vector<ListTable<RnglistEntry>>> DebugRnglists;
diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
index 39195bf63f2f46..15100f3f569fab 100644
--- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -405,8 +405,8 @@ static Expected<uint64_t> writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex,
}
Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
- for (uint64_t I = 0; I < DI.CompileUnits.size(); ++I) {
- const DWARFYAML::Unit &Unit = DI.CompileUnits[I];
+ for (uint64_t I = 0; I < DI.Units.size(); ++I) {
+ const DWARFYAML::Unit &Unit = DI.Units[I];
uint8_t AddrSize;
if (Unit.AddrSize)
AddrSize = *Unit.AddrSize;
@@ -414,8 +414,24 @@ Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
AddrSize = DI.Is64BitAddrSize ? 8 : 4;
dwarf::FormParams Params = {Unit.Version, AddrSize, Unit.Format};
uint64_t Length = 3; // sizeof(version) + sizeof(address_size)
- Length += Unit.Version >= 5 ? 1 : 0; // sizeof(unit_type)
Length += Params.getDwarfOffsetByteSize(); // sizeof(debug_abbrev_offset)
+ if (Unit.Version >= 5) {
+ ++Length; // sizeof(unit_type)
+ switch (Unit.Type) {
+ case dwarf::DW_UT_compile:
+ case dwarf::DW_UT_partial:
+ default:
+ break;
+ case dwarf::DW_UT_type:
+ case dwarf::DW_UT_split_type:
+ // sizeof(type_signature) + sizeof(type_offset)
+ Length += 8 + Params.getDwarfOffsetByteSize();
+ break;
+ case dwarf::DW_UT_skeleton:
+ case dwarf::DW_UT_split_compile:
+ Length += 8; // sizeof(dwo_id)
+ }
+ }
// Since the length of the current compilation unit is undetermined yet, we
// firstly write the content of the compilation unit to a buffer to
@@ -461,6 +477,21 @@ Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
writeInteger((uint8_t)Unit.Type, OS, DI.IsLittleEndian);
writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
+ switch (Unit.Type) {
+ case dwarf::DW_UT_compile:
+ case dwarf::DW_UT_partial:
+ default:
+ break;
+ case dwarf::DW_UT_type:
+ case dwarf::DW_UT_split_type:
+ writeInteger(Unit.TypeSignatureOrDwoID, OS, DI.IsLittleEndian);
+ writeDWARFOffset(Unit.TypeOffset, Unit.Format, OS, DI.IsLittleEndian);
+ break;
+ case dwarf::DW_UT_skeleton:
+ case dwarf::DW_UT_split_compile:
+ writeInteger(Unit.TypeSignatureOrDwoID, OS, DI.IsLittleEndian);
+ break;
+ }
} else {
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 5207671f57d930..c65a494bd41720 100644
--- a/llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -36,7 +36,7 @@ SetVector<StringRef> DWARFYAML::Data::getNonEmptySectionNames() const {
SecNames.insert("debug_addr");
if (!DebugAbbrev.empty())
SecNames.insert("debug_abbrev");
- if (!CompileUnits.empty())
+ if (!Units.empty())
SecNames.insert("debug_info");
if (PubNames)
SecNames.insert("debug_pubnames");
@@ -101,7 +101,7 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
DWARFCtx.IsGNUPubSec = true;
IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
- IO.mapOptional("debug_info", DWARF.CompileUnits);
+ IO.mapOptional("debug_info", DWARF.Units);
IO.mapOptional("debug_line", DWARF.DebugLines);
IO.mapOptional("debug_addr", DWARF.DebugAddr);
IO.mapOptional("debug_str_offsets", DWARF.DebugStrOffsets);
@@ -216,6 +216,22 @@ void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {
IO.mapOptional("AbbrevTableID", Unit.AbbrevTableID);
IO.mapOptional("AbbrOffset", Unit.AbbrOffset);
IO.mapOptional("AddrSize", Unit.AddrSize);
+ if (Unit.Version >= 5) {
+ switch (Unit.Type) {
+ case dwarf::DW_UT_compile:
+ case dwarf::DW_UT_partial:
+ default:
+ break;
+ case dwarf::DW_UT_type:
+ case dwarf::DW_UT_split_type:
+ IO.mapRequired("TypeSignature", Unit.TypeSignatureOrDwoID);
+ IO.mapRequired("TypeOffset", Unit.TypeOffset);
+ break;
+ case dwarf::DW_UT_skeleton:
+ case dwarf::DW_UT_split_compile:
+ IO.mapRequired("DwoID", Unit.TypeSignatureOrDwoID);
+ }
+ }
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 48b9411715e69f..218e1837af73ee 100644
--- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
@@ -21,7 +21,7 @@
# SHDR-NEXT: AddressAlignment: [[ADDRALIGN]]
# SHDR-NEXT: EntrySize: 0
# DWARF32-LE-CONTENT-NEXT: SectionData (
-# DWARF32-LE-CONTENT-NEXT: 0000: 34120000 05000204 34120000 01785634
+# DWARF32-LE-CONTENT-NEXT: 0000: 34120000 05000304 34120000 01785634
## ^------- unit_length (4-byte)
## ^--- version (2-byte)
## ^- unit_type (1-byte) DW_UT_type
@@ -208,7 +208,7 @@ DWARF:
debug_info:
- Length: 0x1234
Version: 5
- UnitType: DW_UT_type
+ UnitType: DW_UT_partial
AbbrOffset: 0x1234
AddrSize: 4
Entries:
@@ -297,7 +297,7 @@ DWARF:
# RUN: FileCheck -DINDEX=2 -DNAME=15 -DOFFSET=0x9B -DSIZE=179 -DADDRALIGN=1 %s --check-prefixes=SHDR,DWARF32-BE-CONTENT
# DWARF32-BE-CONTENT-NEXT: SectionData (
-# DWARF32-BE-CONTENT-NEXT: 0000: 00001234 00050204 00001234 01123456
+# DWARF32-BE-CONTENT-NEXT: 0000: 00001234 00050304 00001234 01123456
## ^------- unit_length (4-byte)
## ^--- version (2-byte)
## ^- unit_type (1-byte) DW_UT_type
@@ -449,7 +449,7 @@ DWARF:
debug_info:
- Length: 0x1234
Version: 5
- UnitType: DW_UT_type
+ UnitType: DW_UT_compile
AbbrOffset: 0x1234
Entries: []
@@ -476,7 +476,7 @@ DWARF:
debug_info:
- Length: 0x1234
Version: 5
- UnitType: DW_UT_type
+ UnitType: DW_UT_compile
AbbrOffset: 0x1234
Entries: []
@@ -541,7 +541,7 @@ DWARF:
debug_info:
- Length: 0x1234
Version: 5
- UnitType: DW_UT_type
+ UnitType: DW_UT_compile
AbbrOffset: 0x1234
Entries:
- AbbrCode: 0
@@ -554,7 +554,7 @@ DWARF:
# RUN: FileCheck %s --check-prefix=EMPTY-ENTRIES --match-full-lines
# EMPTY-ENTRIES: Hex dump of section '.debug_info':
-# EMPTY-ENTRIES-NEXT: 0x00000000 34120000 05000204 34120000 4.......4...
+# EMPTY-ENTRIES-NEXT: 0x00000000 34120000 05000104 34120000 4.......4...
# EMPTY-ENTRIES-EMPTY:
## ^- 'Entries' is empty
@@ -567,7 +567,7 @@ DWARF:
debug_info:
- Length: 0x1234
Version: 5
- UnitType: DW_UT_type
+ UnitType: DW_UT_compile
AbbrOffset: 0x1234
Entries: []
@@ -579,7 +579,7 @@ DWARF:
# RUN: FileCheck %s --check-prefix=FORM --match-full-lines
# FORM: Hex dump of section '.debug_info':
-# FORM-NEXT: 0x00000000 34120000 05000204 34120000 02341221 4.......4....4.!
+# FORM-NEXT: 0x00000000 34120000 05000104 34120000 02341221 4.......4....4.!
## ^------- unit_length (4-byte)
## ^- abbreviation code (ULEB128)
## ^--- Form: DW_FORM_data2 (2-byte)
@@ -617,7 +617,7 @@ DWARF:
debug_info:
- Length: 0x1234
Version: 5
- UnitType: DW_UT_type
+ UnitType: DW_UT_compile
AbbrOffset: 0x1234
Entries:
## Test that yaml2obj emits values when the abbrev code is specified.
@@ -655,29 +655,58 @@ DWARF:
debug_info:
- Length: 0x1234
Version: 5
- UnitType: DW_UT_type
+ UnitType: DW_UT_compile
AbbrOffset: 0x1234
Entries:
- AbbrCode: 1
Values:
- Value: 0x1234
-## j) Test that yaml2obj emits the correct DWARF64 unit headers.
-
-## DWARFv5 unit header.
+## j) Test that yaml2obj emits the correct DWARFv5 unit headers.
# RUN: yaml2obj --docnum=11 %s -o %t11.o
# RUN: llvm-readelf --hex-dump=.debug_info %t11.o | \
# RUN: FileCheck %s --check-prefix=DWARFV5-HEADER
# DWARFV5-HEADER: Hex dump of section '.debug_info':
-# DWARFV5-HEADER-NEXT: 0x00000000 ffffffff 0c000000 00000000 05000208 ................
+# DWARFV5-HEADER-NEXT: 0x00000000 ffffffff 0d000000 00000000 05000108 ................
## ^------------------------- unit_length (12-byte)
## ^--- version (2-byte)
## ^- unit_type (1-byte)
## ^- address_size (1-byte)
-# DWARFV5-HEADER-NEXT: 0x00000010 34120000 00000000 4.......
+# DWARFV5-HEADER-NEXT: 0x00000010 34120000 00000000 00150000 00050002 4...............
## ^---------------- debug_abbrev_offset (8-byte)
+## ^- End of children (1-byte)
+## ^-------- unit_length (4-byte)
+## ^--- version (2-byte)
+## ^- unit_type (1-byte)
+# DWARFV5-HEADER-NEXT: 0x00000020 08341200 000df0ad baefbead de180000 .4..............
+## ^- address_size (1-byte)
+## ^-------- debug_abbrev_offset (4-byte)
+## ^----------------- type_signature (8-byte)
+## \/ ^----- type_offset (4-byte)
+# DWARFV5-HEADER-NEXT: 0x00000030 0000ffff ffff1d00 00000000 00000500 ................
+## ^- End of children (1-byte)
+## ^-------------------------- unit_length (12-byte)
+## ^--- version (2-byte)
+# DWARFV5-HEADER-NEXT: 0x00000040 02083412 00000000 00000df0 adbaefbe ..4.............
+## ^- unit_type (1-byte)
+## ^- address_size (1-byte)
+## ^----------------- debug_abbrev_offset (8-byte)
+## \/-- ^------------ type_signature (8-byte)
+# DWARFV5-HEADER-NEXT: 0x00000050 adde2800 00000000 00000011 00000005 ..(.............
+## ^----------------- type_offset (8-byte)
+## ^- End of children (1-byte)
+## ^-------- unit_length (4-byte)
+## \/ ^- version (2-byte)
+# DWARFV5-HEADER-NEXT: 0x00000060 00040834 1200000d f0adbaef beadde00 ...4............
+## ^- unit_type (1-byte)
+## ^- address_size (1-byte)
+## ^-------- debug_abbrev_offset (4-byte)
+## ^----------------- type_signature (8-byte)
+## ^- End of children (1-byte)
+
+
--- !ELF
FileHeader:
@@ -686,12 +715,33 @@ FileHeader:
Type: ET_EXEC
DWARF:
debug_info:
+ - Format: DWARF64
+ Version: 5
+ UnitType: DW_UT_compile
+ AbbrOffset: 0x1234
+ Entries:
+ - AbbrCode: 0
+ - Version: 5
+ UnitType: DW_UT_type
+ AbbrOffset: 0x1234
+ TypeSignature: 0xdeadbeefbaadf00d
+ TypeOffset: 24
+ Entries:
+ - AbbrCode: 0
- Format: DWARF64
- Length: 0x0c
- Version: 5
- UnitType: DW_UT_type
- AbbrOffset: 0x1234
- Entries: []
+ Version: 5
+ UnitType: DW_UT_type
+ AbbrOffset: 0x1234
+ TypeSignature: 0xdeadbeefbaadf00d
+ TypeOffset: 40
+ Entries:
+ - AbbrCode: 0
+ - Version: 5
+ UnitType: DW_UT_skeleton
+ AbbrOffset: 0x1234
+ DwoID: 0xdeadbeefbaadf00d
+ Entries:
+ - AbbrCode: 0
## DWARFv4 unit header.
diff --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp
index b3062c40fd2432..f19004bdcde389 100644
--- a/llvm/tools/obj2yaml/dwarf2yaml.cpp
+++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp
@@ -338,7 +338,7 @@ void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {
NewUnit.Entries.push_back(NewEntry);
}
- Y.CompileUnits.push_back(NewUnit);
+ Y.Units.push_back(NewUnit);
}
}
More information about the llvm-commits
mailing list