mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[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
This commit is contained in:
parent
2593b6907b
commit
120aef86f5
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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');
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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 @@ debug_addr:
|
||||
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'"));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user