[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