mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-03 07:38:57 +00:00
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
This commit is contained in:
parent
3254a001fc
commit
6025fc2243
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
246
llvm/test/tools/obj2yaml/macho-DWARF-debug-ranges.yaml
Normal file
246
llvm/test/tools/obj2yaml/macho-DWARF-debug-ranges.yaml
Normal file
@ -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: []
|
||||
...
|
@ -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 different 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user