Skip to content

Commit b6f08b7

Browse files
committed
[DWARFYAML][debug_gnu_*] Add the missing context IsGNUStyle. NFC.
This patch helps add the missing context `IsGNUStyle`. Before this patch, yaml2obj cannot parse the YAML description of 'debug_gnu_pubnames' and 'debug_gnu_pubtypes' correctly due to the missing context. In other words, if we have ``` DWARF: debug_gnu_pubtypes: Length: TotalLength: 0x1234 Version: 2 UnitOffset: 0x1234 UnitSize: 0x4321 Entries: - DieOffset: 0x12345678 Name: abc Descriptor: 0x00 ## Descriptor can never be mapped into Entry.Descriptor ``` yaml2obj will complain that "error: unknown key 'Descriptor'". This patch helps resolve this problem. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D82435
1 parent f181c66 commit b6f08b7

File tree

6 files changed

+178
-14
lines changed

6 files changed

+178
-14
lines changed

llvm/include/llvm/ObjectYAML/DWARFEmitter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Error emitDebugStr(raw_ostream &OS, const Data &DI);
3434
Error emitDebugAranges(raw_ostream &OS, const Data &DI);
3535
Error emitDebugRanges(raw_ostream &OS, const Data &DI);
3636
Error emitPubSection(raw_ostream &OS, const PubSection &Sect,
37-
bool IsLittleEndian);
37+
bool IsLittleEndian, bool IsGNUPubSec = false);
3838
Error emitDebugInfo(raw_ostream &OS, const Data &DI);
3939
Error emitDebugLine(raw_ostream &OS, const Data &DI);
4040
Error emitDebugAddr(raw_ostream &OS, const Data &DI);

llvm/include/llvm/ObjectYAML/DWARFYAML.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,7 @@ struct PubSection {
9898
uint16_t Version;
9999
uint32_t UnitOffset;
100100
uint32_t UnitSize;
101-
bool IsGNUStyle = false;
102101
std::vector<PubEntry> Entries;
103-
104-
PubSection() = default;
105-
PubSection(bool IsGNUStyle) : IsGNUStyle(IsGNUStyle) {}
106102
};
107103

108104
struct FormValue {
@@ -116,6 +112,12 @@ struct Entry {
116112
std::vector<FormValue> Values;
117113
};
118114

115+
/// Class that contains helpful context information when mapping YAML into DWARF
116+
/// data structures.
117+
struct DWARFContext {
118+
bool IsGNUPubSec = false;
119+
};
120+
119121
struct Unit {
120122
dwarf::DwarfFormat Format;
121123
uint64_t Length;

llvm/lib/ObjectYAML/DWARFEmitter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,14 @@ Error DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
188188

189189
Error DWARFYAML::emitPubSection(raw_ostream &OS,
190190
const DWARFYAML::PubSection &Sect,
191-
bool IsLittleEndian) {
191+
bool IsLittleEndian, bool IsGNUPubSec) {
192192
writeInitialLength(Sect.Length, OS, IsLittleEndian);
193193
writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
194194
writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
195195
writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
196196
for (auto Entry : Sect.Entries) {
197197
writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
198-
if (Sect.IsGNUStyle)
198+
if (IsGNUPubSec)
199199
writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian);
200200
OS.write(Entry.Name.data(), Entry.Name.size());
201201
OS.write('\0');

llvm/lib/ObjectYAML/DWARFYAML.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ SetVector<StringRef> DWARFYAML::Data::getUsedSectionNames() const {
4848
namespace yaml {
4949

5050
void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
51+
void *OldContext = IO.getContext();
52+
DWARFYAML::DWARFContext DWARFCtx;
53+
IO.setContext(&DWARFCtx);
5154
IO.mapOptional("debug_str", DWARF.DebugStrings);
5255
IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
5356
if (!DWARF.ARanges.empty() || !IO.outputting())
@@ -56,11 +59,13 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
5659
IO.mapOptional("debug_ranges", DWARF.DebugRanges);
5760
IO.mapOptional("debug_pubnames", DWARF.PubNames);
5861
IO.mapOptional("debug_pubtypes", DWARF.PubTypes);
62+
DWARFCtx.IsGNUPubSec = true;
5963
IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
6064
IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
6165
IO.mapOptional("debug_info", DWARF.CompileUnits);
6266
IO.mapOptional("debug_line", DWARF.DebugLines);
6367
IO.mapOptional("debug_addr", DWARF.DebugAddr);
68+
IO.setContext(OldContext);
6469
}
6570

6671
void MappingTraits<DWARFYAML::Abbrev>::mapping(IO &IO,
@@ -112,23 +117,18 @@ void MappingTraits<DWARFYAML::Ranges>::mapping(IO &IO,
112117
void MappingTraits<DWARFYAML::PubEntry>::mapping(IO &IO,
113118
DWARFYAML::PubEntry &Entry) {
114119
IO.mapRequired("DieOffset", Entry.DieOffset);
115-
if (reinterpret_cast<DWARFYAML::PubSection *>(IO.getContext())->IsGNUStyle)
120+
if (static_cast<DWARFYAML::DWARFContext *>(IO.getContext())->IsGNUPubSec)
116121
IO.mapRequired("Descriptor", Entry.Descriptor);
117122
IO.mapRequired("Name", Entry.Name);
118123
}
119124

120125
void MappingTraits<DWARFYAML::PubSection>::mapping(
121126
IO &IO, DWARFYAML::PubSection &Section) {
122-
auto OldContext = IO.getContext();
123-
IO.setContext(&Section);
124-
125127
IO.mapRequired("Length", Section.Length);
126128
IO.mapRequired("Version", Section.Version);
127129
IO.mapRequired("UnitOffset", Section.UnitOffset);
128130
IO.mapRequired("UnitSize", Section.UnitSize);
129131
IO.mapRequired("Entries", Section.Entries);
130-
131-
IO.setContext(OldContext);
132132
}
133133

134134
void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {

llvm/tools/obj2yaml/dwarf2yaml.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static DWARFYAML::PubSection dumpPubSection(const DWARFContext &DCtx,
122122
bool IsGNUStyle) {
123123
DWARFDataExtractor PubSectionData(DCtx.getDWARFObj(), Section,
124124
DCtx.isLittleEndian(), 0);
125-
DWARFYAML::PubSection Y(IsGNUStyle);
125+
DWARFYAML::PubSection Y;
126126
uint64_t Offset = 0;
127127
dumpInitialLength(PubSectionData, Offset, Y.Length);
128128
Y.Version = PubSectionData.getU16(&Offset);

llvm/unittests/ObjectYAML/DWARFYAMLTest.cpp

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,36 @@
88

99
#include "llvm/ObjectYAML/DWARFYAML.h"
1010
#include "llvm/ObjectYAML/DWARFEmitter.h"
11+
#include "llvm/Support/Error.h"
12+
#include "llvm/Support/SourceMgr.h"
13+
#include "llvm/Support/YAMLTraits.h"
1114
#include "llvm/Testing/Support/Error.h"
1215
#include "gtest/gtest.h"
1316

1417
using namespace llvm;
1518

19+
static Expected<DWARFYAML::Data> parseDWARFYAML(StringRef Yaml,
20+
bool IsLittleEndian = false,
21+
bool Is64bit = true) {
22+
DWARFYAML::Data Data;
23+
Data.IsLittleEndian = IsLittleEndian;
24+
Data.Is64bit = Is64bit;
25+
26+
SMDiagnostic GenerateDiag;
27+
yaml::Input YIn(
28+
Yaml, /*Ctxt=*/nullptr,
29+
[](const SMDiagnostic &Diag, void *DiagContext) {
30+
*static_cast<SMDiagnostic *>(DiagContext) = Diag;
31+
},
32+
&GenerateDiag);
33+
34+
YIn >> Data;
35+
if (YIn.error())
36+
return createStringError(YIn.error(), GenerateDiag.getMessage());
37+
38+
return Data;
39+
}
40+
1641
TEST(DebugAddrSection, TestParseDebugAddrYAML) {
1742
StringRef Yaml = R"(
1843
debug_addr:
@@ -47,3 +72,140 @@ TEST(DebugAddrSection, TestUnexpectedKey) {
4772
EXPECT_THAT_ERROR(SectionsOrErr.takeError(),
4873
FailedWithMessage("unknown key 'Blah'"));
4974
}
75+
76+
TEST(DebugPubSection, TestDebugPubSection) {
77+
StringRef Yaml = R"(
78+
debug_pubnames:
79+
Length:
80+
TotalLength: 0x1234
81+
Version: 2
82+
UnitOffset: 0x4321
83+
UnitSize: 0x00
84+
Entries:
85+
- DieOffset: 0x1234
86+
Name: abc
87+
- DieOffset: 0x4321
88+
Name: def
89+
debug_pubtypes:
90+
Length:
91+
TotalLength: 0x1234
92+
Version: 2
93+
UnitOffset: 0x4321
94+
UnitSize: 0x00
95+
Entries:
96+
- DieOffset: 0x1234
97+
Name: abc
98+
- DieOffset: 0x4321
99+
Name: def
100+
)";
101+
auto DWARFOrErr = parseDWARFYAML(Yaml);
102+
ASSERT_THAT_EXPECTED(DWARFOrErr, Succeeded());
103+
104+
ASSERT_TRUE(DWARFOrErr->PubNames.hasValue());
105+
DWARFYAML::PubSection PubNames = DWARFOrErr->PubNames.getValue();
106+
107+
ASSERT_EQ(PubNames.Entries.size(), 2u);
108+
EXPECT_EQ((uint32_t)PubNames.Entries[0].DieOffset, 0x1234u);
109+
EXPECT_EQ(PubNames.Entries[0].Name, "abc");
110+
EXPECT_EQ((uint32_t)PubNames.Entries[1].DieOffset, 0x4321u);
111+
EXPECT_EQ(PubNames.Entries[1].Name, "def");
112+
113+
ASSERT_TRUE(DWARFOrErr->PubTypes.hasValue());
114+
DWARFYAML::PubSection PubTypes = DWARFOrErr->PubTypes.getValue();
115+
116+
ASSERT_EQ(PubTypes.Entries.size(), 2u);
117+
EXPECT_EQ((uint32_t)PubTypes.Entries[0].DieOffset, 0x1234u);
118+
EXPECT_EQ(PubTypes.Entries[0].Name, "abc");
119+
EXPECT_EQ((uint32_t)PubTypes.Entries[1].DieOffset, 0x4321u);
120+
EXPECT_EQ(PubTypes.Entries[1].Name, "def");
121+
}
122+
123+
TEST(DebugPubSection, TestUnexpectedDescriptor) {
124+
StringRef Yaml = R"(
125+
debug_pubnames:
126+
Length:
127+
TotalLength: 0x1234
128+
Version: 2
129+
UnitOffset: 0x4321
130+
UnitSize: 0x00
131+
Entries:
132+
- DieOffset: 0x1234
133+
Descriptor: 0x12
134+
Name: abcd
135+
)";
136+
auto DWARFOrErr = parseDWARFYAML(Yaml);
137+
EXPECT_THAT_ERROR(DWARFOrErr.takeError(),
138+
FailedWithMessage("unknown key 'Descriptor'"));
139+
}
140+
141+
TEST(DebugGNUPubSection, TestDebugGNUPubSections) {
142+
StringRef Yaml = R"(
143+
debug_gnu_pubnames:
144+
Length:
145+
TotalLength: 0x1234
146+
Version: 2
147+
UnitOffset: 0x4321
148+
UnitSize: 0x00
149+
Entries:
150+
- DieOffset: 0x1234
151+
Descriptor: 0x12
152+
Name: abc
153+
- DieOffset: 0x4321
154+
Descriptor: 0x34
155+
Name: def
156+
debug_gnu_pubtypes:
157+
Length:
158+
TotalLength: 0x1234
159+
Version: 2
160+
UnitOffset: 0x4321
161+
UnitSize: 0x00
162+
Entries:
163+
- DieOffset: 0x1234
164+
Descriptor: 0x12
165+
Name: abc
166+
- DieOffset: 0x4321
167+
Descriptor: 0x34
168+
Name: def
169+
)";
170+
auto DWARFOrErr = parseDWARFYAML(Yaml);
171+
ASSERT_THAT_EXPECTED(DWARFOrErr, Succeeded());
172+
173+
ASSERT_TRUE(DWARFOrErr->GNUPubNames.hasValue());
174+
DWARFYAML::PubSection GNUPubNames = DWARFOrErr->GNUPubNames.getValue();
175+
176+
ASSERT_EQ(GNUPubNames.Entries.size(), 2u);
177+
EXPECT_EQ((uint32_t)GNUPubNames.Entries[0].DieOffset, 0x1234u);
178+
EXPECT_EQ((uint8_t)GNUPubNames.Entries[0].Descriptor, 0x12);
179+
EXPECT_EQ(GNUPubNames.Entries[0].Name, "abc");
180+
EXPECT_EQ((uint32_t)GNUPubNames.Entries[1].DieOffset, 0x4321u);
181+
EXPECT_EQ((uint8_t)GNUPubNames.Entries[1].Descriptor, 0x34);
182+
EXPECT_EQ(GNUPubNames.Entries[1].Name, "def");
183+
184+
ASSERT_TRUE(DWARFOrErr->GNUPubTypes.hasValue());
185+
DWARFYAML::PubSection GNUPubTypes = DWARFOrErr->GNUPubTypes.getValue();
186+
187+
ASSERT_EQ(GNUPubTypes.Entries.size(), 2u);
188+
EXPECT_EQ((uint32_t)GNUPubTypes.Entries[0].DieOffset, 0x1234u);
189+
EXPECT_EQ((uint8_t)GNUPubTypes.Entries[0].Descriptor, 0x12);
190+
EXPECT_EQ(GNUPubTypes.Entries[0].Name, "abc");
191+
EXPECT_EQ((uint32_t)GNUPubTypes.Entries[1].DieOffset, 0x4321u);
192+
EXPECT_EQ((uint8_t)GNUPubTypes.Entries[1].Descriptor, 0x34);
193+
EXPECT_EQ(GNUPubTypes.Entries[1].Name, "def");
194+
}
195+
196+
TEST(DebugGNUPubSection, TestMissingDescriptor) {
197+
StringRef Yaml = R"(
198+
debug_gnu_pubnames:
199+
Length:
200+
TotalLength: 0x1234
201+
Version: 2
202+
UnitOffset: 0x4321
203+
UnitSize: 0x00
204+
Entries:
205+
- DieOffset: 0x1234
206+
Name: abcd
207+
)";
208+
auto DWARFOrErr = parseDWARFYAML(Yaml);
209+
EXPECT_THAT_ERROR(DWARFOrErr.takeError(),
210+
FailedWithMessage("missing required key 'Descriptor'"));
211+
}

0 commit comments

Comments
 (0)