1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +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:
Xing GUO 2020-07-03 17:56:02 +08:00
parent 2593b6907b
commit 120aef86f5
6 changed files with 178 additions and 14 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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');

View File

@ -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) {

View File

@ -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);

View File

@ -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'"));
}