[llvm] 419326a - [obj2yaml] Refactor the .debug_pub* sections dumper.

Xing GUO via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 19 06:14:31 PDT 2020


Author: Xing GUO
Date: 2020-08-19T21:13:52+08:00
New Revision: 419326a4452650089e5e36c2200c349d5a63bda5

URL: https://github.com/llvm/llvm-project/commit/419326a4452650089e5e36c2200c349d5a63bda5
DIFF: https://github.com/llvm/llvm-project/commit/419326a4452650089e5e36c2200c349d5a63bda5.diff

LOG: [obj2yaml] Refactor the .debug_pub* sections dumper.

It's good to reuse the DWARF parser in lib/DebugInfo so that we don't
need to maintain a separate parser in client side (obj2yaml). Besides,
A test case is added whose length field is a very huge value which makes
obj2yaml stuck when parsing the section.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D86192

Added: 
    

Modified: 
    llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml
    llvm/tools/obj2yaml/dwarf2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml b/llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml
index 4350fcc6cad1..42919a866bd5 100644
--- a/llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml
+++ b/llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml
@@ -430,3 +430,62 @@ LoadCommands:
         reserved2: 0x00000000
         reserved3: 0x00000000
 DWARF:
+
+## c) Test that obj2yaml is able to dump a __debug_pubnames section whose length field is greater than the section size.
+
+# RUN: yaml2obj --docnum=3 %s | obj2yaml | FileCheck %s --check-prefix=INVALID-LENGTH
+
+#      INVALID-LENGTH: DWARF:
+# INVALID-LENGTH-NEXT:   debug_pubnames:
+# INVALID-LENGTH-NEXT:     Length:          0x00000000DEADBEEF
+# INVALID-LENGTH-NEXT:     Version:         2
+# INVALID-LENGTH-NEXT:     UnitOffset:      0
+# INVALID-LENGTH-NEXT:     UnitSize:        121
+# INVALID-LENGTH-NEXT:     Entries:
+# INVALID-LENGTH-NEXT:       - DieOffset:       0x0000002A
+# INVALID-LENGTH-NEXT:         Name:            main
+
+--- !mach-o
+FileHeader:
+  magic:      0xFEEDFACF
+  cputype:    0x01000007
+  cpusubtype: 0x00000003
+  filetype:   0x0000000A
+  ncmds:      1
+  sizeofcmds: 1888
+  flags:      0x00000000
+  reserved:   0x00000000
+LoadCommands:
+  - cmd:      LC_SEGMENT_64
+    cmdsize:  152
+    segname:  __DWARF
+    vmaddr:   0x00000000
+    vmsize:   0x00000000
+    fileoff:  0
+    filesize: 0xffff
+    maxprot:  0
+    initprot: 0
+    nsects:   1
+    flags:    0
+    Sections:
+      - sectname:  __debug_pubnames
+        segname:   __DWARF
+        addr:      0x0000000000000000
+        size:      24
+        offset:    0x000000b8
+        align:     0
+        reloff:    0x00000000
+        nreloc:    0
+        flags:     0x00000000
+        reserved1: 0x00000000
+        reserved2: 0x00000000
+        reserved3: 0x00000000
+DWARF:
+  debug_pubnames:
+    Length:     0xdeadbeef
+    Version:    2
+    UnitOffset: 0
+    UnitSize:   121
+    Entries:
+      - DieOffset: 0x0000002A
+        Name:      main

diff  --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp
index 6ae94bf340f1..045623227698 100644
--- a/llvm/tools/obj2yaml/dwarf2yaml.cpp
+++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp
@@ -10,6 +10,7 @@
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
@@ -118,32 +119,31 @@ Error dumpDebugRanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   return ErrorSuccess();
 }
 
-static DWARFYAML::PubSection dumpPubSection(const DWARFContext &DCtx,
-                                            const DWARFSection &Section,
-                                            bool IsGNUStyle) {
+static Optional<DWARFYAML::PubSection>
+dumpPubSection(const DWARFContext &DCtx, const DWARFSection &Section,
+               bool IsGNUStyle) {
+  DWARFYAML::PubSection Y;
   DWARFDataExtractor PubSectionData(DCtx.getDWARFObj(), Section,
                                     DCtx.isLittleEndian(), 0);
-  DWARFYAML::PubSection Y;
-  uint64_t Offset = 0;
-  uint64_t Length = PubSectionData.getU32(&Offset);
-  if (Length == dwarf::DW_LENGTH_DWARF64) {
-    Y.Format = dwarf::DWARF64;
-    Y.Length = PubSectionData.getU64(&Offset);
-  } else {
-    Y.Format = dwarf::DWARF32;
-    Y.Length = Length;
-  }
-  Y.Version = PubSectionData.getU16(&Offset);
-  Y.UnitOffset = PubSectionData.getU32(&Offset);
-  Y.UnitSize = PubSectionData.getU32(&Offset);
-  while (Offset < Y.Length) {
-    DWARFYAML::PubEntry NewEntry;
-    NewEntry.DieOffset = PubSectionData.getU32(&Offset);
-    if (IsGNUStyle)
-      NewEntry.Descriptor = PubSectionData.getU8(&Offset);
-    NewEntry.Name = PubSectionData.getCStr(&Offset);
-    Y.Entries.push_back(NewEntry);
-  }
+  DWARFDebugPubTable Table;
+  // We ignore any errors that don't prevent parsing the section, since we can
+  // still represent such sections.
+  Table.extract(PubSectionData, IsGNUStyle,
+                [](Error Err) { consumeError(std::move(Err)); });
+  ArrayRef<DWARFDebugPubTable::Set> Sets = Table.getData();
+  if (Sets.empty())
+    return None;
+
+  // FIXME: Currently, obj2yaml only supports dumping the first pubtable.
+  Y.Format = Sets[0].Format;
+  Y.Length = Sets[0].Length;
+  Y.Version = Sets[0].Version;
+  Y.UnitOffset = Sets[0].Offset;
+  Y.UnitSize = Sets[0].Size;
+
+  for (const DWARFDebugPubTable::Entry &E : Sets[0].Entries)
+    Y.Entries.push_back(
+        DWARFYAML::PubEntry{E.SecOffset, E.Descriptor.toBits(), E.Name});
 
   return Y;
 }
@@ -151,23 +151,16 @@ static DWARFYAML::PubSection dumpPubSection(const DWARFContext &DCtx,
 void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   const DWARFObject &D = DCtx.getDWARFObj();
 
-  const DWARFSection PubNames = D.getPubnamesSection();
-  if (!PubNames.Data.empty())
-    Y.PubNames = dumpPubSection(DCtx, PubNames, /*IsGNUStyle=*/false);
-
-  const DWARFSection PubTypes = D.getPubtypesSection();
-  if (!PubTypes.Data.empty())
-    Y.PubTypes = dumpPubSection(DCtx, PubTypes, /*IsGNUStyle=*/false);
-
-  const DWARFSection GNUPubNames = D.getGnuPubnamesSection();
-  if (!GNUPubNames.Data.empty())
-    // TODO: Test dumping .debug_gnu_pubnames section.
-    Y.GNUPubNames = dumpPubSection(DCtx, GNUPubNames, /*IsGNUStyle=*/true);
-
-  const DWARFSection GNUPubTypes = D.getGnuPubtypesSection();
-  if (!GNUPubTypes.Data.empty())
-    // TODO: Test dumping .debug_gnu_pubtypes section.
-    Y.GNUPubTypes = dumpPubSection(DCtx, GNUPubTypes, /*IsGNUStyle=*/true);
+  Y.PubNames =
+      dumpPubSection(DCtx, D.getPubnamesSection(), /*IsGNUStyle=*/false);
+  Y.PubTypes =
+      dumpPubSection(DCtx, D.getPubtypesSection(), /*IsGNUStyle=*/false);
+  // TODO: Test dumping .debug_gnu_pubnames section.
+  Y.GNUPubNames =
+      dumpPubSection(DCtx, D.getGnuPubnamesSection(), /*IsGNUStyle=*/true);
+  // TODO: Test dumping .debug_gnu_pubtypes section.
+  Y.GNUPubTypes =
+      dumpPubSection(DCtx, D.getGnuPubtypesSection(), /*IsGNUStyle=*/true);
 }
 
 void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {


        


More information about the llvm-commits mailing list