Skip to content

Commit 6025fc2

Browse files
committed
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
1 parent 3254a00 commit 6025fc2

File tree

7 files changed

+342
-0
lines changed

7 files changed

+342
-0
lines changed

llvm/include/llvm/ObjectYAML/DWARFEmitter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ void EmitDebugAbbrev(raw_ostream &OS, const Data &DI);
3232
void EmitDebugStr(raw_ostream &OS, const Data &DI);
3333

3434
void EmitDebugAranges(raw_ostream &OS, const Data &DI);
35+
void EmitDebugRanges(raw_ostream &OS, const Data &DI);
3536
void EmitPubSection(raw_ostream &OS, const PubSection &Sect,
3637
bool IsLittleEndian);
3738
void EmitDebugInfo(raw_ostream &OS, const Data &DI);

llvm/include/llvm/ObjectYAML/DWARFYAML.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,20 @@ struct ARange {
7171
std::vector<ARangeDescriptor> Descriptors;
7272
};
7373

74+
/// Class that describes a range list entry, or a base address selection entry
75+
/// within a range list in the .debug_ranges section.
76+
struct RangeEntry {
77+
llvm::yaml::Hex64 LowOffset;
78+
llvm::yaml::Hex64 HighOffset;
79+
};
80+
81+
/// Class that describes a single range list inside the .debug_ranges section.
82+
struct Ranges {
83+
llvm::yaml::Hex32 Offset;
84+
llvm::yaml::Hex8 AddrSize;
85+
std::vector<RangeEntry> Entries;
86+
};
87+
7488
struct PubEntry {
7589
llvm::yaml::Hex32 DieOffset;
7690
llvm::yaml::Hex8 Descriptor;
@@ -145,6 +159,7 @@ struct Data {
145159
std::vector<Abbrev> AbbrevDecls;
146160
std::vector<StringRef> DebugStrings;
147161
std::vector<ARange> ARanges;
162+
std::vector<Ranges> Ranges;
148163
PubSection PubNames;
149164
PubSection PubTypes;
150165

@@ -165,6 +180,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
165180
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
166181
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
167182
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
183+
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RangeEntry)
184+
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Ranges)
168185
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
169186
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
170187
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
@@ -196,6 +213,14 @@ template <> struct MappingTraits<DWARFYAML::ARange> {
196213
static void mapping(IO &IO, DWARFYAML::ARange &Range);
197214
};
198215

216+
template <> struct MappingTraits<DWARFYAML::RangeEntry> {
217+
static void mapping(IO &IO, DWARFYAML::RangeEntry &Entry);
218+
};
219+
220+
template <> struct MappingTraits<DWARFYAML::Ranges> {
221+
static void mapping(IO &IO, DWARFYAML::Ranges &Ranges);
222+
};
223+
199224
template <> struct MappingTraits<DWARFYAML::PubEntry> {
200225
static void mapping(IO &IO, DWARFYAML::PubEntry &Entry);
201226
};

llvm/lib/ObjectYAML/DWARFEmitter.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,23 @@ void DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
114114
}
115115
}
116116

117+
void DWARFYAML::EmitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
118+
const size_t RangesOffset = OS.tell();
119+
for (auto Ranges : DI.Ranges) {
120+
const size_t CurrOffset = OS.tell() - RangesOffset;
121+
assert(Ranges.Offset <= CurrOffset);
122+
if (Ranges.Offset > CurrOffset)
123+
ZeroFillBytes(OS, Ranges.Offset - CurrOffset);
124+
for (auto Entry : Ranges.Entries) {
125+
writeVariableSizedInteger(Entry.LowOffset, Ranges.AddrSize, OS,
126+
DI.IsLittleEndian);
127+
writeVariableSizedInteger(Entry.HighOffset, Ranges.AddrSize, OS,
128+
DI.IsLittleEndian);
129+
}
130+
ZeroFillBytes(OS, Ranges.AddrSize * 2);
131+
}
132+
}
133+
117134
void DWARFYAML::EmitPubSection(raw_ostream &OS,
118135
const DWARFYAML::PubSection &Sect,
119136
bool IsLittleEndian) {
@@ -377,5 +394,7 @@ DWARFYAML::EmitDebugSections(StringRef YAMLString, bool ApplyFixups,
377394
DebugSections);
378395
EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAranges, "debug_aranges",
379396
DebugSections);
397+
EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugRanges, "debug_ranges",
398+
DebugSections);
380399
return std::move(DebugSections);
381400
}

llvm/lib/ObjectYAML/DWARFYAML.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
2828
IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
2929
if (!DWARF.ARanges.empty() || !IO.outputting())
3030
IO.mapOptional("debug_aranges", DWARF.ARanges);
31+
if (!DWARF.Ranges.empty() || !IO.outputting())
32+
IO.mapOptional("debug_ranges", DWARF.Ranges);
3133
if (!DWARF.PubNames.Entries.empty() || !IO.outputting())
3234
IO.mapOptional("debug_pubnames", DWARF.PubNames);
3335
if (!DWARF.PubTypes.Entries.empty() || !IO.outputting())
@@ -73,6 +75,19 @@ void MappingTraits<DWARFYAML::ARange>::mapping(IO &IO,
7375
IO.mapRequired("Descriptors", Range.Descriptors);
7476
}
7577

78+
void MappingTraits<DWARFYAML::RangeEntry>::mapping(
79+
IO &IO, DWARFYAML::RangeEntry &Descriptor) {
80+
IO.mapRequired("LowOffset", Descriptor.LowOffset);
81+
IO.mapRequired("HighOffset", Descriptor.HighOffset);
82+
}
83+
84+
void MappingTraits<DWARFYAML::Ranges>::mapping(IO &IO,
85+
DWARFYAML::Ranges &Ranges) {
86+
IO.mapRequired("Offset", Ranges.Offset);
87+
IO.mapRequired("AddrSize", Ranges.AddrSize);
88+
IO.mapRequired("Entries", Ranges.Entries);
89+
}
90+
7691
void MappingTraits<DWARFYAML::PubEntry>::mapping(IO &IO,
7792
DWARFYAML::PubEntry &Entry) {
7893
IO.mapRequired("DieOffset", Entry.DieOffset);

llvm/lib/ObjectYAML/MachOEmitter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ void MachOWriter::writeSectionData(raw_ostream &OS) {
287287
DWARFYAML::EmitDebugAbbrev(OS, Obj.DWARF);
288288
} else if (0 == strncmp(&Sec.sectname[0], "__debug_aranges", 16)) {
289289
DWARFYAML::EmitDebugAranges(OS, Obj.DWARF);
290+
} else if (0 == strncmp(&Sec.sectname[0], "__debug_ranges", 16)) {
291+
DWARFYAML::EmitDebugRanges(OS, Obj.DWARF);
290292
} else if (0 == strncmp(&Sec.sectname[0], "__debug_pubnames", 16)) {
291293
DWARFYAML::EmitPubSection(OS, Obj.DWARF.PubNames,
292294
Obj.IsLittleEndian);
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
## Test that yaml2obj and obj2yaml can create mach-o files with valid
2+
## __debug_ranges section.
3+
##
4+
## The DWARF should end up looking like:
5+
##
6+
## 0x0000000b: DW_TAG_compile_unit
7+
## DW_AT_name ("/tmp/main.c")
8+
## DW_AT_language (DW_LANG_C_plus_plus)
9+
## DW_AT_low_pc (0x0000000000000000)
10+
## DW_AT_ranges (0x00000000
11+
## [0x0000000000000000, 0x0000000000000020)
12+
## [0x0000000000000000, 0x0000000000000030)
13+
## [0x0000000000001000, 0x0000000000002000))
14+
## DW_AT_stmt_list (0x00000000)
15+
##
16+
## 0x00000022: DW_TAG_subprogram
17+
## DW_AT_name ("stripped1")
18+
## DW_AT_low_pc (0x0000000000000000)
19+
## DW_AT_high_pc (0x0000000000000020)
20+
##
21+
## 0x00000033: DW_TAG_subprogram
22+
## DW_AT_name ("stripped2")
23+
## DW_AT_low_pc (0x0000000000000000)
24+
## DW_AT_high_pc (0x0000000000000030)
25+
##
26+
## 0x00000048: DW_TAG_subprogram
27+
## DW_AT_name ("main")
28+
## DW_AT_low_pc (0x0000000000001000)
29+
## DW_AT_high_pc (0x0000000000002000)
30+
##
31+
## 0x00000059: NULL
32+
33+
# RUN: yaml2obj %s > %t
34+
# RUN: llvm-dwarfdump %t | FileCheck %s
35+
# RUN: obj2yaml %t | FileCheck --check-prefix=YAML %s
36+
37+
# CHECK: DW_AT_ranges (0x00000000
38+
# CHECK-NEXT: [0x0000000000000000, 0x0000000000000020)
39+
# CHECK-NEXT: [0x0000000000000000, 0x0000000000000030)
40+
# CHECK-NEXT: [0x0000000000001000, 0x0000000000002000))
41+
42+
# YAML: - sectname: __debug_ranges
43+
# YAML-NEXT: segname: __DWARF
44+
# YAML-NEXT: addr: 0x000000000000007A
45+
# YAML-NEXT: size: 80
46+
# YAML-NEXT: offset: 0x0000028A
47+
48+
# YAML: debug_ranges:
49+
# YAML-NEXT: - Offset: 0x00000000
50+
# YAML-NEXT: AddrSize: 0x08
51+
# YAML-NEXT: Entries:
52+
# YAML-NEXT: - LowOffset: 0x0000000000000000
53+
# YAML-NEXT: HighOffset: 0x0000000000000020
54+
# YAML-NEXT: - LowOffset: 0x0000000000000000
55+
# YAML-NEXT: HighOffset: 0x0000000000000030
56+
# YAML-NEXT: - LowOffset: 0xFFFFFFFFFFFFFFFF
57+
# YAML-NEXT: HighOffset: 0x0000000000001000
58+
# YAML-NEXT: - LowOffset: 0x0000000000000000
59+
# YAML-NEXT: HighOffset: 0x0000000000001000
60+
61+
--- !mach-o
62+
FileHeader:
63+
magic: 0xFEEDFACF
64+
cputype: 0x01000007
65+
cpusubtype: 0x00000003
66+
filetype: 0x00000001
67+
ncmds: 4
68+
sizeofcmds: 464
69+
flags: 0x00002000
70+
reserved: 0x00000000
71+
LoadCommands:
72+
- cmd: LC_SEGMENT_64
73+
cmdsize: 392
74+
segname: ''
75+
vmaddr: 0
76+
vmsize: 240
77+
fileoff: 528
78+
filesize: 240
79+
maxprot: 7
80+
initprot: 7
81+
nsects: 4
82+
flags: 0
83+
Sections:
84+
- sectname: __debug_abbrev
85+
segname: __DWARF
86+
addr: 0x0000000000000000
87+
size: 36
88+
offset: 0x00000210
89+
align: 0
90+
reloff: 0x00000000
91+
nreloc: 0
92+
flags: 0x00000000
93+
reserved1: 0x00000000
94+
reserved2: 0x00000000
95+
reserved3: 0x00000000
96+
content: 011101030E1305110155170000022E00030E110112060000032E00030E11011201000000
97+
- sectname: __debug_info
98+
segname: __DWARF
99+
addr: 0x0000000000000024
100+
size: 86
101+
offset: 0x00000234
102+
align: 0
103+
reloff: 0x00000000
104+
nreloc: 0
105+
flags: 0x00000000
106+
reserved1: 0x00000000
107+
reserved2: 0x00000000
108+
reserved3: 0x00000000
109+
content: 520000000400000000000801010000000400000000000000000000000000020D000000000000000000000020000000031700000000000000000000003000000000000000022100000000100000000000000010000000
110+
- sectname: __debug_ranges
111+
segname: __DWARF
112+
addr: 0x000000000000007A
113+
size: 80
114+
offset: 0x0000028A
115+
align: 0
116+
reloff: 0x00000000
117+
nreloc: 0
118+
flags: 0x00000000
119+
reserved1: 0x00000000
120+
reserved2: 0x00000000
121+
reserved3: 0x00000000
122+
content: 0000000000000000200000000000000000000000000000003000000000000000FFFFFFFFFFFFFFFF00100000000000000000000000000000001000000000000000000000000000000000000000000000
123+
- sectname: __debug_str
124+
segname: __DWARF
125+
addr: 0x00000000000000CA
126+
size: 38
127+
offset: 0x000002DA
128+
align: 0
129+
reloff: 0x00000000
130+
nreloc: 0
131+
flags: 0x00000000
132+
reserved1: 0x00000000
133+
reserved2: 0x00000000
134+
reserved3: 0x00000000
135+
content: 002F746D702F6D61696E2E630073747269707065643100737472697070656432006D61696E00
136+
- cmd: LC_SYMTAB
137+
cmdsize: 24
138+
symoff: 0
139+
nsyms: 0
140+
stroff: 768
141+
strsize: 8
142+
- cmd: LC_BUILD_VERSION
143+
cmdsize: 32
144+
platform: 1
145+
minos: 658944
146+
sdk: 658944
147+
ntools: 1
148+
Tools:
149+
- tool: 3
150+
version: 34734080
151+
- cmd: LC_DATA_IN_CODE
152+
cmdsize: 16
153+
dataoff: 768
154+
datasize: 0
155+
LinkEditData:
156+
StringTable:
157+
- ' '
158+
- ''
159+
- ''
160+
- ''
161+
- ''
162+
- ''
163+
- ''
164+
DWARF:
165+
debug_str:
166+
- ''
167+
- '/tmp/main.c'
168+
- stripped1
169+
- stripped2
170+
- main
171+
debug_abbrev:
172+
- Code: 0x00000001
173+
Tag: DW_TAG_compile_unit
174+
Children: DW_CHILDREN_yes
175+
Attributes:
176+
- Attribute: DW_AT_name
177+
Form: DW_FORM_strp
178+
- Attribute: DW_AT_language
179+
Form: DW_FORM_data2
180+
- Attribute: DW_AT_low_pc
181+
Form: DW_FORM_addr
182+
- Attribute: DW_AT_ranges
183+
Form: DW_FORM_sec_offset
184+
- Code: 0x00000002
185+
Tag: DW_TAG_subprogram
186+
Children: DW_CHILDREN_no
187+
Attributes:
188+
- Attribute: DW_AT_name
189+
Form: DW_FORM_strp
190+
- Attribute: DW_AT_low_pc
191+
Form: DW_FORM_addr
192+
- Attribute: DW_AT_high_pc
193+
Form: DW_FORM_data4
194+
- Code: 0x00000003
195+
Tag: DW_TAG_subprogram
196+
Children: DW_CHILDREN_no
197+
Attributes:
198+
- Attribute: DW_AT_name
199+
Form: DW_FORM_strp
200+
- Attribute: DW_AT_low_pc
201+
Form: DW_FORM_addr
202+
- Attribute: DW_AT_high_pc
203+
Form: DW_FORM_addr
204+
debug_ranges:
205+
- Offset: 0x00000000
206+
AddrSize: 0x08
207+
Entries:
208+
- LowOffset: 0x0000000000000000
209+
HighOffset: 0x0000000000000020
210+
- LowOffset: 0x0000000000000000
211+
HighOffset: 0x0000000000000030
212+
- LowOffset: 0xFFFFFFFFFFFFFFFF
213+
HighOffset: 0x0000000000001000
214+
- LowOffset: 0x0000000000000000
215+
HighOffset: 0x0000000000001000
216+
debug_info:
217+
- Length:
218+
TotalLength: 82
219+
Version: 4
220+
AbbrOffset: 0
221+
AddrSize: 8
222+
Entries:
223+
- AbbrCode: 0x00000001
224+
Values:
225+
- Value: 0x0000000000000001
226+
- Value: 0x0000000000000004
227+
- Value: 0x0000000000000000
228+
- Value: 0x0000000000000000
229+
- AbbrCode: 0x00000002
230+
Values:
231+
- Value: 0x000000000000000D
232+
- Value: 0x0000000000000000
233+
- Value: 0x0000000000000020
234+
- AbbrCode: 0x00000003
235+
Values:
236+
- Value: 0x0000000000000017
237+
- Value: 0x0000000000000000
238+
- Value: 0x0000000000000030
239+
- AbbrCode: 0x00000002
240+
Values:
241+
- Value: 0x0000000000000021
242+
- Value: 0x0000000000001000
243+
- Value: 0x0000000000001000
244+
- AbbrCode: 0x00000000
245+
Values: []
246+
...

0 commit comments

Comments
 (0)