[llvm] 6025fc2 - Add .debug_ranges support to the DWARF YAML.

Greg Clayton via llvm-commits llvm-commits at lists.llvm.org
Wed May 13 16:22:08 PDT 2020


Author: Greg Clayton
Date: 2020-05-13T16:21:45-07:00
New Revision: 6025fc2243c6b7c00f07bdadcea6658e1b63518a

URL: https://github.com/llvm/llvm-project/commit/6025fc2243c6b7c00f07bdadcea6658e1b63518a
DIFF: https://github.com/llvm/llvm-project/commit/6025fc2243c6b7c00f07bdadcea6658e1b63518a.diff

LOG: Add .debug_ranges support to the DWARF YAML.

Summary: This allows DIEs with DW_AT_ranges to be encoded and decoded _and_ actually have their address ranges be included instead of having DW_AT_ranges with a section offset value for a section that doesn't exist.

Reviewers: labath, aprantl, JDevlieghere, dblaikie, probinson

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

Added: 
    llvm/test/tools/obj2yaml/macho-DWARF-debug-ranges.yaml

Modified: 
    llvm/include/llvm/ObjectYAML/DWARFEmitter.h
    llvm/include/llvm/ObjectYAML/DWARFYAML.h
    llvm/lib/ObjectYAML/DWARFEmitter.cpp
    llvm/lib/ObjectYAML/DWARFYAML.cpp
    llvm/lib/ObjectYAML/MachOEmitter.cpp
    llvm/tools/obj2yaml/dwarf2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
index 2ccc876d5023..092aa0040f95 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
@@ -32,6 +32,7 @@ void EmitDebugAbbrev(raw_ostream &OS, const Data &DI);
 void EmitDebugStr(raw_ostream &OS, const Data &DI);
 
 void EmitDebugAranges(raw_ostream &OS, const Data &DI);
+void EmitDebugRanges(raw_ostream &OS, const Data &DI);
 void EmitPubSection(raw_ostream &OS, const PubSection &Sect,
                     bool IsLittleEndian);
 void EmitDebugInfo(raw_ostream &OS, const Data &DI);

diff  --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index 26dabfcf27fe..3c87a5f0c499 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -71,6 +71,20 @@ struct ARange {
   std::vector<ARangeDescriptor> Descriptors;
 };
 
+/// Class that describes a range list entry, or a base address selection entry
+/// within a range list in the .debug_ranges section.
+struct RangeEntry {
+  llvm::yaml::Hex64 LowOffset;
+  llvm::yaml::Hex64 HighOffset;
+};
+
+/// Class that describes a single range list inside the .debug_ranges section.
+struct Ranges {
+  llvm::yaml::Hex32 Offset;
+  llvm::yaml::Hex8 AddrSize;
+  std::vector<RangeEntry> Entries;
+};
+
 struct PubEntry {
   llvm::yaml::Hex32 DieOffset;
   llvm::yaml::Hex8 Descriptor;
@@ -145,6 +159,7 @@ struct Data {
   std::vector<Abbrev> AbbrevDecls;
   std::vector<StringRef> DebugStrings;
   std::vector<ARange> ARanges;
+  std::vector<Ranges> Ranges;
   PubSection PubNames;
   PubSection PubTypes;
 
@@ -165,6 +180,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RangeEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Ranges)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
@@ -196,6 +213,14 @@ template <> struct MappingTraits<DWARFYAML::ARange> {
   static void mapping(IO &IO, DWARFYAML::ARange &Range);
 };
 
+template <> struct MappingTraits<DWARFYAML::RangeEntry> {
+  static void mapping(IO &IO, DWARFYAML::RangeEntry &Entry);
+};
+
+template <> struct MappingTraits<DWARFYAML::Ranges> {
+  static void mapping(IO &IO, DWARFYAML::Ranges &Ranges);
+};
+
 template <> struct MappingTraits<DWARFYAML::PubEntry> {
   static void mapping(IO &IO, DWARFYAML::PubEntry &Entry);
 };

diff  --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
index b410fed16f09..645558d9ddd0 100644
--- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -114,6 +114,23 @@ void DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
   }
 }
 
+void DWARFYAML::EmitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
+  const size_t RangesOffset = OS.tell();
+  for (auto Ranges : DI.Ranges) {
+    const size_t CurrOffset = OS.tell() - RangesOffset;
+    assert(Ranges.Offset <= CurrOffset);
+    if (Ranges.Offset > CurrOffset)
+      ZeroFillBytes(OS, Ranges.Offset - CurrOffset);
+    for (auto Entry : Ranges.Entries) {
+      writeVariableSizedInteger(Entry.LowOffset, Ranges.AddrSize, OS,
+                                DI.IsLittleEndian);
+      writeVariableSizedInteger(Entry.HighOffset, Ranges.AddrSize, OS,
+                                DI.IsLittleEndian);
+    }
+    ZeroFillBytes(OS, Ranges.AddrSize * 2);
+  }
+}
+
 void DWARFYAML::EmitPubSection(raw_ostream &OS,
                                const DWARFYAML::PubSection &Sect,
                                bool IsLittleEndian) {
@@ -377,5 +394,7 @@ DWARFYAML::EmitDebugSections(StringRef YAMLString, bool ApplyFixups,
                        DebugSections);
   EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAranges, "debug_aranges",
                        DebugSections);
+  EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugRanges, "debug_ranges",
+                       DebugSections);
   return std::move(DebugSections);
 }

diff  --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp
index bb3b1422eb62..82033b4f90c6 100644
--- a/llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -28,6 +28,8 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
   IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
   if (!DWARF.ARanges.empty() || !IO.outputting())
     IO.mapOptional("debug_aranges", DWARF.ARanges);
+  if (!DWARF.Ranges.empty() || !IO.outputting())
+    IO.mapOptional("debug_ranges", DWARF.Ranges);
   if (!DWARF.PubNames.Entries.empty() || !IO.outputting())
     IO.mapOptional("debug_pubnames", DWARF.PubNames);
   if (!DWARF.PubTypes.Entries.empty() || !IO.outputting())
@@ -73,6 +75,19 @@ void MappingTraits<DWARFYAML::ARange>::mapping(IO &IO,
   IO.mapRequired("Descriptors", Range.Descriptors);
 }
 
+void MappingTraits<DWARFYAML::RangeEntry>::mapping(
+    IO &IO, DWARFYAML::RangeEntry &Descriptor) {
+  IO.mapRequired("LowOffset", Descriptor.LowOffset);
+  IO.mapRequired("HighOffset", Descriptor.HighOffset);
+}
+
+void MappingTraits<DWARFYAML::Ranges>::mapping(IO &IO,
+                                               DWARFYAML::Ranges &Ranges) {
+  IO.mapRequired("Offset", Ranges.Offset);
+  IO.mapRequired("AddrSize", Ranges.AddrSize);
+  IO.mapRequired("Entries", Ranges.Entries);
+}
+
 void MappingTraits<DWARFYAML::PubEntry>::mapping(IO &IO,
                                                  DWARFYAML::PubEntry &Entry) {
   IO.mapRequired("DieOffset", Entry.DieOffset);

diff  --git a/llvm/lib/ObjectYAML/MachOEmitter.cpp b/llvm/lib/ObjectYAML/MachOEmitter.cpp
index 3cf6dc067e70..5a38fef50854 100644
--- a/llvm/lib/ObjectYAML/MachOEmitter.cpp
+++ b/llvm/lib/ObjectYAML/MachOEmitter.cpp
@@ -287,6 +287,8 @@ void MachOWriter::writeSectionData(raw_ostream &OS) {
             DWARFYAML::EmitDebugAbbrev(OS, Obj.DWARF);
           } else if (0 == strncmp(&Sec.sectname[0], "__debug_aranges", 16)) {
             DWARFYAML::EmitDebugAranges(OS, Obj.DWARF);
+          } else if (0 == strncmp(&Sec.sectname[0], "__debug_ranges", 16)) {
+            DWARFYAML::EmitDebugRanges(OS, Obj.DWARF);
           } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubnames", 16)) {
             DWARFYAML::EmitPubSection(OS, Obj.DWARF.PubNames,
                                       Obj.IsLittleEndian);

diff  --git a/llvm/test/tools/obj2yaml/macho-DWARF-debug-ranges.yaml b/llvm/test/tools/obj2yaml/macho-DWARF-debug-ranges.yaml
new file mode 100644
index 000000000000..be1a52a22efa
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/macho-DWARF-debug-ranges.yaml
@@ -0,0 +1,246 @@
+## Test that yaml2obj and obj2yaml can create mach-o files with valid
+## __debug_ranges section.
+##
+## The DWARF should end up looking like:
+##
+## 0x0000000b: DW_TAG_compile_unit
+##               DW_AT_name        ("/tmp/main.c")
+##               DW_AT_language    (DW_LANG_C_plus_plus)
+##               DW_AT_low_pc      (0x0000000000000000)
+##               DW_AT_ranges      (0x00000000
+##                  [0x0000000000000000, 0x0000000000000020)
+##                  [0x0000000000000000, 0x0000000000000030)
+##                  [0x0000000000001000, 0x0000000000002000))
+##               DW_AT_stmt_list   (0x00000000)
+##
+## 0x00000022:   DW_TAG_subprogram
+##                 DW_AT_name      ("stripped1")
+##                 DW_AT_low_pc    (0x0000000000000000)
+##                 DW_AT_high_pc   (0x0000000000000020)
+##
+## 0x00000033:   DW_TAG_subprogram
+##                 DW_AT_name      ("stripped2")
+##                 DW_AT_low_pc    (0x0000000000000000)
+##                 DW_AT_high_pc   (0x0000000000000030)
+##
+## 0x00000048:   DW_TAG_subprogram
+##                 DW_AT_name      ("main")
+##                 DW_AT_low_pc    (0x0000000000001000)
+##                 DW_AT_high_pc   (0x0000000000002000)
+##
+## 0x00000059:   NULL
+
+# RUN: yaml2obj %s > %t
+# RUN: llvm-dwarfdump %t | FileCheck %s
+# RUN: obj2yaml %t | FileCheck --check-prefix=YAML %s
+
+# CHECK:      DW_AT_ranges	(0x00000000
+# CHECK-NEXT: [0x0000000000000000, 0x0000000000000020)
+# CHECK-NEXT: [0x0000000000000000, 0x0000000000000030)
+# CHECK-NEXT: [0x0000000000001000, 0x0000000000002000))
+
+# YAML:      - sectname:        __debug_ranges
+# YAML-NEXT:   segname:         __DWARF
+# YAML-NEXT:   addr:            0x000000000000007A
+# YAML-NEXT:   size:            80
+# YAML-NEXT:   offset:          0x0000028A
+
+# YAML:      debug_ranges:
+# YAML-NEXT:   - Offset:          0x00000000
+# YAML-NEXT:     AddrSize:        0x08
+# YAML-NEXT:     Entries:
+# YAML-NEXT:       - LowOffset:       0x0000000000000000
+# YAML-NEXT:         HighOffset:      0x0000000000000020
+# YAML-NEXT:       - LowOffset:       0x0000000000000000
+# YAML-NEXT:         HighOffset:      0x0000000000000030
+# YAML-NEXT:       - LowOffset:       0xFFFFFFFFFFFFFFFF
+# YAML-NEXT:         HighOffset:      0x0000000000001000
+# YAML-NEXT:       - LowOffset:       0x0000000000000000
+# YAML-NEXT:         HighOffset:      0x0000000000001000
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           4
+  sizeofcmds:      464
+  flags:           0x00002000
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         392
+    segname:         ''
+    vmaddr:          0
+    vmsize:          240
+    fileoff:         528
+    filesize:        240
+    maxprot:         7
+    initprot:        7
+    nsects:          4
+    flags:           0
+    Sections:
+      - sectname:        __debug_abbrev
+        segname:         __DWARF
+        addr:            0x0000000000000000
+        size:            36
+        offset:          0x00000210
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         011101030E1305110155170000022E00030E110112060000032E00030E11011201000000
+      - sectname:        __debug_info
+        segname:         __DWARF
+        addr:            0x0000000000000024
+        size:            86
+        offset:          0x00000234
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         520000000400000000000801010000000400000000000000000000000000020D000000000000000000000020000000031700000000000000000000003000000000000000022100000000100000000000000010000000
+      - sectname:        __debug_ranges
+        segname:         __DWARF
+        addr:            0x000000000000007A
+        size:            80
+        offset:          0x0000028A
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         0000000000000000200000000000000000000000000000003000000000000000FFFFFFFFFFFFFFFF00100000000000000000000000000000001000000000000000000000000000000000000000000000
+      - sectname:        __debug_str
+        segname:         __DWARF
+        addr:            0x00000000000000CA
+        size:            38
+        offset:          0x000002DA
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         002F746D702F6D61696E2E630073747269707065643100737472697070656432006D61696E00
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          0
+    nsyms:           0
+    stroff:          768
+    strsize:         8
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         32
+    platform:        1
+    minos:           658944
+    sdk:             658944
+    ntools:          1
+    Tools:
+      - tool:            3
+        version:         34734080
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+    dataoff:         768
+    datasize:        0
+LinkEditData:
+  StringTable:
+    - ' '
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+DWARF:
+  debug_str:
+    - ''
+    - '/tmp/main.c'
+    - stripped1
+    - stripped2
+    - main
+  debug_abbrev:
+    - Code:            0x00000001
+      Tag:             DW_TAG_compile_unit
+      Children:        DW_CHILDREN_yes
+      Attributes:
+        - Attribute:       DW_AT_name
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_language
+          Form:            DW_FORM_data2
+        - Attribute:       DW_AT_low_pc
+          Form:            DW_FORM_addr
+        - Attribute:       DW_AT_ranges
+          Form:            DW_FORM_sec_offset
+    - Code:            0x00000002
+      Tag:             DW_TAG_subprogram
+      Children:        DW_CHILDREN_no
+      Attributes:
+        - Attribute:       DW_AT_name
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_low_pc
+          Form:            DW_FORM_addr
+        - Attribute:       DW_AT_high_pc
+          Form:            DW_FORM_data4
+    - Code:            0x00000003
+      Tag:             DW_TAG_subprogram
+      Children:        DW_CHILDREN_no
+      Attributes:
+        - Attribute:       DW_AT_name
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_low_pc
+          Form:            DW_FORM_addr
+        - Attribute:       DW_AT_high_pc
+          Form:            DW_FORM_addr
+  debug_ranges:
+    - Offset:          0x00000000
+      AddrSize:        0x08
+      Entries:
+        - LowOffset:       0x0000000000000000
+          HighOffset:      0x0000000000000020
+        - LowOffset:       0x0000000000000000
+          HighOffset:      0x0000000000000030
+        - LowOffset:       0xFFFFFFFFFFFFFFFF
+          HighOffset:      0x0000000000001000
+        - LowOffset:       0x0000000000000000
+          HighOffset:      0x0000000000001000
+  debug_info:
+    - Length:
+        TotalLength:     82
+      Version:         4
+      AbbrOffset:      0
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x00000001
+          Values:
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000004
+            - Value:           0x0000000000000000
+            - Value:           0x0000000000000000
+        - AbbrCode:        0x00000002
+          Values:
+            - Value:           0x000000000000000D
+            - Value:           0x0000000000000000
+            - Value:           0x0000000000000020
+        - AbbrCode:        0x00000003
+          Values:
+            - Value:           0x0000000000000017
+            - Value:           0x0000000000000000
+            - Value:           0x0000000000000030
+        - AbbrCode:        0x00000002
+          Values:
+            - Value:           0x0000000000000021
+            - Value:           0x0000000000001000
+            - Value:           0x0000000000001000
+        - AbbrCode:        0x00000000
+          Values:          []
+...

diff  --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp
index edb1b547b0f5..df876853fd31 100644
--- a/llvm/tools/obj2yaml/dwarf2yaml.cpp
+++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp
@@ -9,6 +9,7 @@
 #include "Error.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/ObjectYAML/DWARFYAML.h"
 
@@ -82,6 +83,37 @@ Error dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   return ErrorSuccess();
 }
 
+Error dumpDebugRanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
+  // We are assuming all address byte sizes will be consistent across all
+  // compile units.
+  uint8_t AddrSize = 0;
+  for (const auto &CU : DCtx.compile_units()) {
+    const uint8_t CUAddrSize = CU->getAddressByteSize();
+    if (AddrSize == 0)
+      AddrSize = CUAddrSize;
+    else if (CUAddrSize != AddrSize)
+      return createStringError(std::errc::invalid_argument,
+                               "address sizes vary in 
diff erent compile units");
+  }
+
+  DWARFDataExtractor Data(DCtx.getDWARFObj().getRangesSection().Data,
+                          DCtx.isLittleEndian(), AddrSize);
+  uint64_t Offset = 0;
+  DWARFDebugRangeList DwarfRanges;
+
+  while (Data.isValidOffset(Offset)) {
+    DWARFYAML::Ranges YamlRanges;
+    YamlRanges.Offset = Offset;
+    YamlRanges.AddrSize = AddrSize;
+    if (Error E = DwarfRanges.extract(Data, &Offset))
+      return E;
+    for (const auto &RLE : DwarfRanges.getEntries())
+      YamlRanges.Entries.push_back({RLE.StartAddress, RLE.EndAddress});
+    Y.Ranges.push_back(std::move(YamlRanges));
+  }
+  return ErrorSuccess();
+}
+
 void dumpPubSection(DWARFContext &DCtx, DWARFYAML::PubSection &Y,
                     DWARFSection Section) {
   DWARFDataExtractor PubSectionData(DCtx.getDWARFObj(), Section,
@@ -354,6 +386,8 @@ llvm::Error dwarf2yaml(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   dumpDebugStrings(DCtx, Y);
   if (Error E = dumpDebugARanges(DCtx, Y))
     return E;
+  if (Error E = dumpDebugRanges(DCtx, Y))
+    return E;
   dumpDebugPubSections(DCtx, Y);
   dumpDebugInfo(DCtx, Y);
   dumpDebugLines(DCtx, Y);


        


More information about the llvm-commits mailing list