[llvm] b6f08b7 - [DWARFYAML][debug_gnu_*] Add the missing context `IsGNUStyle`. NFC.
Xing GUO via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 3 03:08:44 PDT 2020
Author: Xing GUO
Date: 2020-07-03T18:12:58+08:00
New Revision: b6f08b7cfd05f6a58b4e30d90bc0e630ff6a7aa5
URL: https://github.com/llvm/llvm-project/commit/b6f08b7cfd05f6a58b4e30d90bc0e630ff6a7aa5
DIFF: https://github.com/llvm/llvm-project/commit/b6f08b7cfd05f6a58b4e30d90bc0e630ff6a7aa5.diff
LOG: [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
Added:
Modified:
llvm/include/llvm/ObjectYAML/DWARFEmitter.h
llvm/include/llvm/ObjectYAML/DWARFYAML.h
llvm/lib/ObjectYAML/DWARFEmitter.cpp
llvm/lib/ObjectYAML/DWARFYAML.cpp
llvm/tools/obj2yaml/dwarf2yaml.cpp
llvm/unittests/ObjectYAML/DWARFYAMLTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
index 716386992c29..0ec3f90e1686 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
@@ -34,7 +34,7 @@ Error emitDebugStr(raw_ostream &OS, const Data &DI);
Error emitDebugAranges(raw_ostream &OS, const Data &DI);
Error emitDebugRanges(raw_ostream &OS, const Data &DI);
Error emitPubSection(raw_ostream &OS, const PubSection &Sect,
- bool IsLittleEndian);
+ bool IsLittleEndian, bool IsGNUPubSec = false);
Error emitDebugInfo(raw_ostream &OS, const Data &DI);
Error emitDebugLine(raw_ostream &OS, const Data &DI);
Error emitDebugAddr(raw_ostream &OS, const Data &DI);
diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index a492972082ee..259152ff5d03 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -98,11 +98,7 @@ struct PubSection {
uint16_t Version;
uint32_t UnitOffset;
uint32_t UnitSize;
- bool IsGNUStyle = false;
std::vector<PubEntry> Entries;
-
- PubSection() = default;
- PubSection(bool IsGNUStyle) : IsGNUStyle(IsGNUStyle) {}
};
struct FormValue {
@@ -116,6 +112,12 @@ struct Entry {
std::vector<FormValue> Values;
};
+/// Class that contains helpful context information when mapping YAML into DWARF
+/// data structures.
+struct DWARFContext {
+ bool IsGNUPubSec = false;
+};
+
struct Unit {
dwarf::DwarfFormat Format;
uint64_t Length;
diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
index 7a86143b260b..6cbb90bb10f2 100644
--- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -188,14 +188,14 @@ Error DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
Error DWARFYAML::emitPubSection(raw_ostream &OS,
const DWARFYAML::PubSection &Sect,
- bool IsLittleEndian) {
+ bool IsLittleEndian, bool IsGNUPubSec) {
writeInitialLength(Sect.Length, OS, IsLittleEndian);
writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
for (auto Entry : Sect.Entries) {
writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
- if (Sect.IsGNUStyle)
+ if (IsGNUPubSec)
writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian);
OS.write(Entry.Name.data(), Entry.Name.size());
OS.write('\0');
diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp
index 51827563a120..892f9b6e8de0 100644
--- a/llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -48,6 +48,9 @@ SetVector<StringRef> DWARFYAML::Data::getUsedSectionNames() const {
namespace yaml {
void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
+ void *OldContext = IO.getContext();
+ DWARFYAML::DWARFContext DWARFCtx;
+ IO.setContext(&DWARFCtx);
IO.mapOptional("debug_str", DWARF.DebugStrings);
IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
if (!DWARF.ARanges.empty() || !IO.outputting())
@@ -56,11 +59,13 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
IO.mapOptional("debug_ranges", DWARF.DebugRanges);
IO.mapOptional("debug_pubnames", DWARF.PubNames);
IO.mapOptional("debug_pubtypes", DWARF.PubTypes);
+ 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_line", DWARF.DebugLines);
IO.mapOptional("debug_addr", DWARF.DebugAddr);
+ IO.setContext(OldContext);
}
void MappingTraits<DWARFYAML::Abbrev>::mapping(IO &IO,
@@ -112,23 +117,18 @@ void MappingTraits<DWARFYAML::Ranges>::mapping(IO &IO,
void MappingTraits<DWARFYAML::PubEntry>::mapping(IO &IO,
DWARFYAML::PubEntry &Entry) {
IO.mapRequired("DieOffset", Entry.DieOffset);
- if (reinterpret_cast<DWARFYAML::PubSection *>(IO.getContext())->IsGNUStyle)
+ if (static_cast<DWARFYAML::DWARFContext *>(IO.getContext())->IsGNUPubSec)
IO.mapRequired("Descriptor", Entry.Descriptor);
IO.mapRequired("Name", Entry.Name);
}
void MappingTraits<DWARFYAML::PubSection>::mapping(
IO &IO, DWARFYAML::PubSection &Section) {
- auto OldContext = IO.getContext();
- IO.setContext(&Section);
-
IO.mapRequired("Length", Section.Length);
IO.mapRequired("Version", Section.Version);
IO.mapRequired("UnitOffset", Section.UnitOffset);
IO.mapRequired("UnitSize", Section.UnitSize);
IO.mapRequired("Entries", Section.Entries);
-
- IO.setContext(OldContext);
}
void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {
diff --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp
index e79787ef89f6..a318a547e32c 100644
--- a/llvm/tools/obj2yaml/dwarf2yaml.cpp
+++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp
@@ -122,7 +122,7 @@ static DWARFYAML::PubSection dumpPubSection(const DWARFContext &DCtx,
bool IsGNUStyle) {
DWARFDataExtractor PubSectionData(DCtx.getDWARFObj(), Section,
DCtx.isLittleEndian(), 0);
- DWARFYAML::PubSection Y(IsGNUStyle);
+ DWARFYAML::PubSection Y;
uint64_t Offset = 0;
dumpInitialLength(PubSectionData, Offset, Y.Length);
Y.Version = PubSectionData.getU16(&Offset);
diff --git a/llvm/unittests/ObjectYAML/DWARFYAMLTest.cpp b/llvm/unittests/ObjectYAML/DWARFYAMLTest.cpp
index 92a148fffdb9..138c0999c1cc 100644
--- a/llvm/unittests/ObjectYAML/DWARFYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DWARFYAMLTest.cpp
@@ -8,11 +8,36 @@
#include "llvm/ObjectYAML/DWARFYAML.h"
#include "llvm/ObjectYAML/DWARFEmitter.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLTraits.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
using namespace llvm;
+static Expected<DWARFYAML::Data> parseDWARFYAML(StringRef Yaml,
+ bool IsLittleEndian = false,
+ bool Is64bit = true) {
+ DWARFYAML::Data Data;
+ Data.IsLittleEndian = IsLittleEndian;
+ Data.Is64bit = Is64bit;
+
+ SMDiagnostic GenerateDiag;
+ yaml::Input YIn(
+ Yaml, /*Ctxt=*/nullptr,
+ [](const SMDiagnostic &Diag, void *DiagContext) {
+ *static_cast<SMDiagnostic *>(DiagContext) = Diag;
+ },
+ &GenerateDiag);
+
+ YIn >> Data;
+ if (YIn.error())
+ return createStringError(YIn.error(), GenerateDiag.getMessage());
+
+ return Data;
+}
+
TEST(DebugAddrSection, TestParseDebugAddrYAML) {
StringRef Yaml = R"(
debug_addr:
@@ -47,3 +72,140 @@ TEST(DebugAddrSection, TestUnexpectedKey) {
EXPECT_THAT_ERROR(SectionsOrErr.takeError(),
FailedWithMessage("unknown key 'Blah'"));
}
+
+TEST(DebugPubSection, TestDebugPubSection) {
+ StringRef Yaml = R"(
+debug_pubnames:
+ Length:
+ TotalLength: 0x1234
+ Version: 2
+ UnitOffset: 0x4321
+ UnitSize: 0x00
+ Entries:
+ - DieOffset: 0x1234
+ Name: abc
+ - DieOffset: 0x4321
+ Name: def
+debug_pubtypes:
+ Length:
+ TotalLength: 0x1234
+ Version: 2
+ UnitOffset: 0x4321
+ UnitSize: 0x00
+ Entries:
+ - DieOffset: 0x1234
+ Name: abc
+ - DieOffset: 0x4321
+ Name: def
+)";
+ auto DWARFOrErr = parseDWARFYAML(Yaml);
+ ASSERT_THAT_EXPECTED(DWARFOrErr, Succeeded());
+
+ ASSERT_TRUE(DWARFOrErr->PubNames.hasValue());
+ DWARFYAML::PubSection PubNames = DWARFOrErr->PubNames.getValue();
+
+ ASSERT_EQ(PubNames.Entries.size(), 2u);
+ EXPECT_EQ((uint32_t)PubNames.Entries[0].DieOffset, 0x1234u);
+ EXPECT_EQ(PubNames.Entries[0].Name, "abc");
+ EXPECT_EQ((uint32_t)PubNames.Entries[1].DieOffset, 0x4321u);
+ EXPECT_EQ(PubNames.Entries[1].Name, "def");
+
+ ASSERT_TRUE(DWARFOrErr->PubTypes.hasValue());
+ DWARFYAML::PubSection PubTypes = DWARFOrErr->PubTypes.getValue();
+
+ ASSERT_EQ(PubTypes.Entries.size(), 2u);
+ EXPECT_EQ((uint32_t)PubTypes.Entries[0].DieOffset, 0x1234u);
+ EXPECT_EQ(PubTypes.Entries[0].Name, "abc");
+ EXPECT_EQ((uint32_t)PubTypes.Entries[1].DieOffset, 0x4321u);
+ EXPECT_EQ(PubTypes.Entries[1].Name, "def");
+}
+
+TEST(DebugPubSection, TestUnexpectedDescriptor) {
+ StringRef Yaml = R"(
+debug_pubnames:
+ Length:
+ TotalLength: 0x1234
+ Version: 2
+ UnitOffset: 0x4321
+ UnitSize: 0x00
+ Entries:
+ - DieOffset: 0x1234
+ Descriptor: 0x12
+ Name: abcd
+)";
+ auto DWARFOrErr = parseDWARFYAML(Yaml);
+ EXPECT_THAT_ERROR(DWARFOrErr.takeError(),
+ FailedWithMessage("unknown key 'Descriptor'"));
+}
+
+TEST(DebugGNUPubSection, TestDebugGNUPubSections) {
+ StringRef Yaml = R"(
+debug_gnu_pubnames:
+ Length:
+ TotalLength: 0x1234
+ Version: 2
+ UnitOffset: 0x4321
+ UnitSize: 0x00
+ Entries:
+ - DieOffset: 0x1234
+ Descriptor: 0x12
+ Name: abc
+ - DieOffset: 0x4321
+ Descriptor: 0x34
+ Name: def
+debug_gnu_pubtypes:
+ Length:
+ TotalLength: 0x1234
+ Version: 2
+ UnitOffset: 0x4321
+ UnitSize: 0x00
+ Entries:
+ - DieOffset: 0x1234
+ Descriptor: 0x12
+ Name: abc
+ - DieOffset: 0x4321
+ Descriptor: 0x34
+ Name: def
+)";
+ auto DWARFOrErr = parseDWARFYAML(Yaml);
+ ASSERT_THAT_EXPECTED(DWARFOrErr, Succeeded());
+
+ ASSERT_TRUE(DWARFOrErr->GNUPubNames.hasValue());
+ DWARFYAML::PubSection GNUPubNames = DWARFOrErr->GNUPubNames.getValue();
+
+ ASSERT_EQ(GNUPubNames.Entries.size(), 2u);
+ EXPECT_EQ((uint32_t)GNUPubNames.Entries[0].DieOffset, 0x1234u);
+ EXPECT_EQ((uint8_t)GNUPubNames.Entries[0].Descriptor, 0x12);
+ EXPECT_EQ(GNUPubNames.Entries[0].Name, "abc");
+ EXPECT_EQ((uint32_t)GNUPubNames.Entries[1].DieOffset, 0x4321u);
+ EXPECT_EQ((uint8_t)GNUPubNames.Entries[1].Descriptor, 0x34);
+ EXPECT_EQ(GNUPubNames.Entries[1].Name, "def");
+
+ ASSERT_TRUE(DWARFOrErr->GNUPubTypes.hasValue());
+ DWARFYAML::PubSection GNUPubTypes = DWARFOrErr->GNUPubTypes.getValue();
+
+ ASSERT_EQ(GNUPubTypes.Entries.size(), 2u);
+ EXPECT_EQ((uint32_t)GNUPubTypes.Entries[0].DieOffset, 0x1234u);
+ EXPECT_EQ((uint8_t)GNUPubTypes.Entries[0].Descriptor, 0x12);
+ EXPECT_EQ(GNUPubTypes.Entries[0].Name, "abc");
+ EXPECT_EQ((uint32_t)GNUPubTypes.Entries[1].DieOffset, 0x4321u);
+ EXPECT_EQ((uint8_t)GNUPubTypes.Entries[1].Descriptor, 0x34);
+ EXPECT_EQ(GNUPubTypes.Entries[1].Name, "def");
+}
+
+TEST(DebugGNUPubSection, TestMissingDescriptor) {
+ StringRef Yaml = R"(
+debug_gnu_pubnames:
+ Length:
+ TotalLength: 0x1234
+ Version: 2
+ UnitOffset: 0x4321
+ UnitSize: 0x00
+ Entries:
+ - DieOffset: 0x1234
+ Name: abcd
+)";
+ auto DWARFOrErr = parseDWARFYAML(Yaml);
+ EXPECT_THAT_ERROR(DWARFOrErr.takeError(),
+ FailedWithMessage("missing required key 'Descriptor'"));
+}
More information about the llvm-commits
mailing list