[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