llvm.org GIT mirror llvm / cf24fcb
[ObjectYAML] Support for DWARF __debug_abbrev section This patch adds support for round-tripping DWARF debug abbreviations through the obj<->yaml tools. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288955 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Bieneman 2 years ago
6 changed file(s) with 571 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
2222 uint32_t FirstAbbrCode;
2323 std::vector Decls;
2424
25 typedef std::vector::const_iterator
26 const_iterator;
27
2528 public:
2629 DWARFAbbreviationDeclarationSet();
2730
3134
3235 const DWARFAbbreviationDeclaration *
3336 getAbbreviationDeclaration(uint32_t AbbrCode) const;
37
38 const_iterator begin() const {
39 return Decls.begin();
40 }
41
42 const_iterator end() const {
43 return Decls.end();
44 }
3445
3546 private:
3647 void clear();
5263 void dump(raw_ostream &OS) const;
5364 void extract(DataExtractor Data);
5465
66 DWARFAbbreviationDeclarationSetMap::const_iterator begin() const {
67 return AbbrDeclSets.begin();
68 }
69
70 DWARFAbbreviationDeclarationSetMap::const_iterator end() const {
71 return AbbrDeclSets.end();
72 }
73
5574 private:
5675 void clear();
5776 };
1717
1818 #include "llvm/ObjectYAML/YAML.h"
1919 #include "llvm/Support/MachO.h"
20 #include "llvm/Support/Dwarf.h"
2021
2122 namespace llvm {
2223 namespace MachOYAML {
103104 bool isEmpty() const;
104105 };
105106
107 struct DWARFAttributeAbbrev {
108 llvm::dwarf::Attribute Attribute;
109 llvm::dwarf::Form Form;
110 };
111
112 struct DWARFAbbrev {
113 llvm::yaml::Hex32 Code;
114 llvm::dwarf::Tag Tag;
115 llvm::dwarf::Constants Children;
116 std::vector Attributes;
117 };
118
106119 struct DWARFData {
120 std::vector AbbrevDecls;
107121 std::vector DebugStrings;
108122
109123 bool isEmpty() const;
152166 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
153167 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Object)
154168 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::FatArch)
169 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::DWARFAttributeAbbrev)
170 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::DWARFAbbrev)
155171
156172 namespace llvm {
157173 namespace yaml {
206222
207223 template <> struct MappingTraits {
208224 static void mapping(IO &IO, MachOYAML::DWARFData &DWARF);
225 };
226
227 template <> struct MappingTraits {
228 static void mapping(IO &IO, MachOYAML::DWARFAbbrev &Abbrev);
229 };
230
231 template <> struct MappingTraits {
232 static void mapping(IO &IO, MachOYAML::DWARFAttributeAbbrev &AttAbbrev);
209233 };
210234
211235 #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
254278 }
255279 };
256280
281 #define HANDLE_DW_TAG(unused, name) \
282 io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
283
284 template <> struct ScalarEnumerationTraits {
285 static void enumeration(IO &io, dwarf::Tag &value) {
286 #include "llvm/Support/Dwarf.def"
287 io.enumFallback(value);
288 }
289 };
290
291 #define HANDLE_DW_AT(unused, name) \
292 io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
293
294 template <> struct ScalarEnumerationTraits {
295 static void enumeration(IO &io, dwarf::Attribute &value) {
296 #include "llvm/Support/Dwarf.def"
297 io.enumFallback(value);
298 }
299 };
300
301 #define HANDLE_DW_FORM(unused, name) \
302 io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
303
304 template <> struct ScalarEnumerationTraits {
305 static void enumeration(IO &io, dwarf::Form &value) {
306 #include "llvm/Support/Dwarf.def"
307 io.enumFallback(value);
308 }
309 };
310
311 template <> struct ScalarEnumerationTraits {
312 static void enumeration(IO &io, dwarf::Constants &value) {
313 io.enumCase(value, "DW_CHILDREN_no", dwarf::DW_CHILDREN_no);
314 io.enumCase(value, "DW_CHILDREN_yes", dwarf::DW_CHILDREN_yes);
315 io.enumFallback(value);
316 }
317 };
318
257319 // This trait is used for 16-byte chars in Mach structures used for strings
258320 typedef char char_16[16];
259321
2929 }
3030
3131 bool MachOYAML::DWARFData::isEmpty() const {
32 return 0 == DebugStrings.size();
32 return 0 == DebugStrings.size() + AbbrevDecls.size();
3333 }
3434
3535 namespace yaml {
558558
559559 void MappingTraits::mapping(
560560 IO &IO, MachOYAML::DWARFData &DWARF) {
561 IO.mapRequired("DebugStrings", DWARF.DebugStrings);
561 IO.mapOptional("DebugStrings", DWARF.DebugStrings);
562 IO.mapOptional("AbbrevDecls", DWARF.AbbrevDecls);
563 }
564
565 void MappingTraits::mapping(
566 IO &IO, MachOYAML::DWARFAbbrev &Abbrev) {
567 IO.mapRequired("Code", Abbrev.Code);
568 IO.mapRequired("Tag", Abbrev.Tag);
569 IO.mapRequired("Children", Abbrev.Children);
570 IO.mapRequired("Attributes", Abbrev.Attributes);
571 }
572
573 void MappingTraits::mapping(
574 IO &IO, MachOYAML::DWARFAttributeAbbrev &AttAbbrev) {
575 IO.mapRequired("Attribute", AttAbbrev.Attribute);
576 IO.mapRequired("Form", AttAbbrev.Form);
562577 }
563578
564579 } // namespace llvm::yaml
0 # RUN: yaml2obj %s | obj2yaml | FileCheck %s
1
2 --- !mach-o
3 FileHeader:
4 magic: 0xFEEDFACF
5 cputype: 0x01000007
6 cpusubtype: 0x00000003
7 filetype: 0x0000000A
8 ncmds: 5
9 sizeofcmds: 1800
10 flags: 0x00000000
11 reserved: 0x00000000
12 LoadCommands:
13 - cmd: LC_SEGMENT_64
14 cmdsize: 72
15 segname: __PAGEZERO
16 vmaddr: 0
17 vmsize: 4294967296
18 fileoff: 0
19 filesize: 0
20 maxprot: 0
21 initprot: 0
22 nsects: 0
23 flags: 0
24 - cmd: LC_SEGMENT_64
25 cmdsize: 472
26 segname: __TEXT
27 vmaddr: 4294967296
28 vmsize: 4096
29 fileoff: 0
30 filesize: 0
31 maxprot: 7
32 initprot: 5
33 nsects: 5
34 flags: 0
35 Sections:
36 - sectname: __text
37 segname: __TEXT
38 addr: 0x0000000100000F50
39 size: 52
40 offset: 0x00000000
41 align: 4
42 reloff: 0x00000000
43 nreloc: 0
44 flags: 0x80000400
45 reserved1: 0x00000000
46 reserved2: 0x00000000
47 reserved3: 0x00000000
48 - sectname: __stubs
49 segname: __TEXT
50 addr: 0x0000000100000F84
51 size: 6
52 offset: 0x00000000
53 align: 1
54 reloff: 0x00000000
55 nreloc: 0
56 flags: 0x80000408
57 reserved1: 0x00000000
58 reserved2: 0x00000006
59 reserved3: 0x00000000
60 - sectname: __stub_helper
61 segname: __TEXT
62 addr: 0x0000000100000F8C
63 size: 26
64 offset: 0x00000000
65 align: 2
66 reloff: 0x00000000
67 nreloc: 0
68 flags: 0x80000400
69 reserved1: 0x00000000
70 reserved2: 0x00000000
71 reserved3: 0x00000000
72 - sectname: __cstring
73 segname: __TEXT
74 addr: 0x0000000100000FA6
75 size: 14
76 offset: 0x00000000
77 align: 0
78 reloff: 0x00000000
79 nreloc: 0
80 flags: 0x00000002
81 reserved1: 0x00000000
82 reserved2: 0x00000000
83 reserved3: 0x00000000
84 - sectname: __unwind_info
85 segname: __TEXT
86 addr: 0x0000000100000FB4
87 size: 72
88 offset: 0x00000000
89 align: 2
90 reloff: 0x00000000
91 nreloc: 0
92 flags: 0x00000000
93 reserved1: 0x00000000
94 reserved2: 0x00000000
95 reserved3: 0x00000000
96 - cmd: LC_SEGMENT_64
97 cmdsize: 232
98 segname: __DATA
99 vmaddr: 4294971392
100 vmsize: 4096
101 fileoff: 0
102 filesize: 0
103 maxprot: 7
104 initprot: 3
105 nsects: 2
106 flags: 0
107 Sections:
108 - sectname: __nl_symbol_ptr
109 segname: __DATA
110 addr: 0x0000000100001000
111 size: 16
112 offset: 0x00000000
113 align: 3
114 reloff: 0x00000000
115 nreloc: 0
116 flags: 0x00000006
117 reserved1: 0x00000001
118 reserved2: 0x00000000
119 reserved3: 0x00000000
120 - sectname: __la_symbol_ptr
121 segname: __DATA
122 addr: 0x0000000100001010
123 size: 8
124 offset: 0x00000000
125 align: 3
126 reloff: 0x00000000
127 nreloc: 0
128 flags: 0x00000007
129 reserved1: 0x00000003
130 reserved2: 0x00000000
131 reserved3: 0x00000000
132 - cmd: LC_SEGMENT_64
133 cmdsize: 72
134 segname: __LINKEDIT
135 vmaddr: 4294975488
136 vmsize: 4096
137 fileoff: 4096
138 filesize: 60
139 maxprot: 7
140 initprot: 1
141 nsects: 0
142 flags: 0
143 - cmd: LC_SEGMENT_64
144 cmdsize: 952
145 segname: __DWARF
146 vmaddr: 4294979584
147 vmsize: 4096
148 fileoff: 8192
149 filesize: 764
150 maxprot: 7
151 initprot: 3
152 nsects: 11
153 flags: 0
154 Sections:
155 - sectname: __debug_line
156 segname: __DWARF
157 addr: 0x0000000100003000
158 size: 69
159 offset: 0x00002000
160 align: 0
161 reloff: 0x00000000
162 nreloc: 0
163 flags: 0x00000000
164 reserved1: 0x00000000
165 reserved2: 0x00000000
166 reserved3: 0x00000000
167 - sectname: __debug_pubnames
168 segname: __DWARF
169 addr: 0x0000000100003045
170 size: 27
171 offset: 0x00002045
172 align: 0
173 reloff: 0x00000000
174 nreloc: 0
175 flags: 0x00000000
176 reserved1: 0x00000000
177 reserved2: 0x00000000
178 reserved3: 0x00000000
179 - sectname: __debug_pubtypes
180 segname: __DWARF
181 addr: 0x0000000100003060
182 size: 35
183 offset: 0x00002060
184 align: 0
185 reloff: 0x00000000
186 nreloc: 0
187 flags: 0x00000000
188 reserved1: 0x00000000
189 reserved2: 0x00000000
190 reserved3: 0x00000000
191 - sectname: __debug_aranges
192 segname: __DWARF
193 addr: 0x0000000100003083
194 size: 48
195 offset: 0x00002083
196 align: 0
197 reloff: 0x00000000
198 nreloc: 0
199 flags: 0x00000000
200 reserved1: 0x00000000
201 reserved2: 0x00000000
202 reserved3: 0x00000000
203 - sectname: __debug_info
204 segname: __DWARF
205 addr: 0x00000001000030B3
206 size: 121
207 offset: 0x000020B3
208 align: 0
209 reloff: 0x00000000
210 nreloc: 0
211 flags: 0x00000000
212 reserved1: 0x00000000
213 reserved2: 0x00000000
214 reserved3: 0x00000000
215 - sectname: __debug_abbrev
216 segname: __DWARF
217 addr: 0x000000010000312C
218 size: 76
219 offset: 0x0000212C
220 align: 0
221 reloff: 0x00000000
222 nreloc: 0
223 flags: 0x00000000
224 reserved1: 0x00000000
225 reserved2: 0x00000000
226 reserved3: 0x00000000
227 - sectname: __debug_str
228 segname: __DWARF
229 addr: 0x0000000100003178
230 size: 142
231 offset: 0x00002178
232 align: 0
233 reloff: 0x00000000
234 nreloc: 0
235 flags: 0x00000000
236 reserved1: 0x00000000
237 reserved2: 0x00000000
238 reserved3: 0x00000000
239 - sectname: __apple_names
240 segname: __DWARF
241 addr: 0x0000000100003206
242 size: 60
243 offset: 0x00002206
244 align: 0
245 reloff: 0x00000000
246 nreloc: 0
247 flags: 0x00000000
248 reserved1: 0x00000000
249 reserved2: 0x00000000
250 reserved3: 0x00000000
251 - sectname: __apple_namespac
252 segname: __DWARF
253 addr: 0x0000000100003242
254 size: 36
255 offset: 0x00002242
256 align: 0
257 reloff: 0x00000000
258 nreloc: 0
259 flags: 0x00000000
260 reserved1: 0x00000000
261 reserved2: 0x00000000
262 reserved3: 0x00000000
263 - sectname: __apple_types
264 segname: __DWARF
265 addr: 0x0000000100003266
266 size: 114
267 offset: 0x00002266
268 align: 0
269 reloff: 0x00000000
270 nreloc: 0
271 flags: 0x00000000
272 reserved1: 0x00000000
273 reserved2: 0x00000000
274 reserved3: 0x00000000
275 - sectname: __apple_objc
276 segname: __DWARF
277 addr: 0x00000001000032D8
278 size: 36
279 offset: 0x000022D8
280 align: 0
281 reloff: 0x00000000
282 nreloc: 0
283 flags: 0x00000000
284 reserved1: 0x00000000
285 reserved2: 0x00000000
286 reserved3: 0x00000000
287 DWARF:
288 AbbrevDecls:
289 - Code: 0x00000001
290 Tag: DW_TAG_compile_unit
291 Children: DW_CHILDREN_yes
292 Attributes:
293 - Attribute: DW_AT_producer
294 Form: DW_FORM_strp
295 - Attribute: DW_AT_language
296 Form: DW_FORM_data2
297 - Attribute: DW_AT_name
298 Form: DW_FORM_strp
299 - Attribute: DW_AT_stmt_list
300 Form: DW_FORM_sec_offset
301 - Attribute: DW_AT_comp_dir
302 Form: DW_FORM_strp
303 - Attribute: DW_AT_low_pc
304 Form: DW_FORM_addr
305 - Attribute: DW_AT_high_pc
306 Form: DW_FORM_data4
307 - Code: 0x00000002
308 Tag: DW_TAG_subprogram
309 Children: DW_CHILDREN_yes
310 Attributes:
311 - Attribute: DW_AT_low_pc
312 Form: DW_FORM_addr
313 - Attribute: DW_AT_high_pc
314 Form: DW_FORM_data4
315 - Attribute: DW_AT_frame_base
316 Form: DW_FORM_exprloc
317 - Attribute: DW_AT_name
318 Form: DW_FORM_strp
319 - Attribute: DW_AT_decl_file
320 Form: DW_FORM_data1
321 - Attribute: DW_AT_decl_line
322 Form: DW_FORM_data1
323 - Attribute: DW_AT_prototyped
324 Form: DW_FORM_flag_present
325 - Attribute: DW_AT_type
326 Form: DW_FORM_ref4
327 - Attribute: DW_AT_external
328 Form: DW_FORM_flag_present
329 - Code: 0x00000003
330 Tag: DW_TAG_formal_parameter
331 Children: DW_CHILDREN_no
332 Attributes:
333 - Attribute: DW_AT_location
334 Form: DW_FORM_exprloc
335 - Attribute: DW_AT_name
336 Form: DW_FORM_strp
337 - Attribute: DW_AT_decl_file
338 Form: DW_FORM_data1
339 - Attribute: DW_AT_decl_line
340 Form: DW_FORM_data1
341 - Attribute: DW_AT_type
342 Form: DW_FORM_ref4
343 - Code: 0x00000004
344 Tag: DW_TAG_base_type
345 Children: DW_CHILDREN_no
346 Attributes:
347 - Attribute: DW_AT_name
348 Form: DW_FORM_strp
349 - Attribute: DW_AT_encoding
350 Form: DW_FORM_data1
351 - Attribute: DW_AT_byte_size
352 Form: DW_FORM_data1
353 - Code: 0x00000005
354 Tag: DW_TAG_pointer_type
355 Children: DW_CHILDREN_no
356 Attributes:
357 - Attribute: DW_AT_type
358 Form: DW_FORM_ref4
359 ...
360
361 #CHECK: DWARF:
362 #CHECK: AbbrevDecls:
363 #CHECK: - Code: 0x00000001
364 #CHECK: Tag: DW_TAG_compile_unit
365 #CHECK: Children: DW_CHILDREN_yes
366 #CHECK: Attributes:
367 #CHECK: - Attribute: DW_AT_producer
368 #CHECK: Form: DW_FORM_strp
369 #CHECK: - Attribute: DW_AT_language
370 #CHECK: Form: DW_FORM_data2
371 #CHECK: - Attribute: DW_AT_name
372 #CHECK: Form: DW_FORM_strp
373 #CHECK: - Attribute: DW_AT_stmt_list
374 #CHECK: Form: DW_FORM_sec_offset
375 #CHECK: - Attribute: DW_AT_comp_dir
376 #CHECK: Form: DW_FORM_strp
377 #CHECK: - Attribute: DW_AT_low_pc
378 #CHECK: Form: DW_FORM_addr
379 #CHECK: - Attribute: DW_AT_high_pc
380 #CHECK: Form: DW_FORM_data4
381 #CHECK: - Code: 0x00000002
382 #CHECK: Tag: DW_TAG_subprogram
383 #CHECK: Children: DW_CHILDREN_yes
384 #CHECK: Attributes:
385 #CHECK: - Attribute: DW_AT_low_pc
386 #CHECK: Form: DW_FORM_addr
387 #CHECK: - Attribute: DW_AT_high_pc
388 #CHECK: Form: DW_FORM_data4
389 #CHECK: - Attribute: DW_AT_frame_base
390 #CHECK: Form: DW_FORM_exprloc
391 #CHECK: - Attribute: DW_AT_name
392 #CHECK: Form: DW_FORM_strp
393 #CHECK: - Attribute: DW_AT_decl_file
394 #CHECK: Form: DW_FORM_data1
395 #CHECK: - Attribute: DW_AT_decl_line
396 #CHECK: Form: DW_FORM_data1
397 #CHECK: - Attribute: DW_AT_prototyped
398 #CHECK: Form: DW_FORM_flag_present
399 #CHECK: - Attribute: DW_AT_type
400 #CHECK: Form: DW_FORM_ref4
401 #CHECK: - Attribute: DW_AT_external
402 #CHECK: Form: DW_FORM_flag_present
403 #CHECK: - Code: 0x00000003
404 #CHECK: Tag: DW_TAG_formal_parameter
405 #CHECK: Children: DW_CHILDREN_no
406 #CHECK: Attributes:
407 #CHECK: - Attribute: DW_AT_location
408 #CHECK: Form: DW_FORM_exprloc
409 #CHECK: - Attribute: DW_AT_name
410 #CHECK: Form: DW_FORM_strp
411 #CHECK: - Attribute: DW_AT_decl_file
412 #CHECK: Form: DW_FORM_data1
413 #CHECK: - Attribute: DW_AT_decl_line
414 #CHECK: Form: DW_FORM_data1
415 #CHECK: - Attribute: DW_AT_type
416 #CHECK: Form: DW_FORM_ref4
417 #CHECK: - Code: 0x00000004
418 #CHECK: Tag: DW_TAG_base_type
419 #CHECK: Children: DW_CHILDREN_no
420 #CHECK: Attributes:
421 #CHECK: - Attribute: DW_AT_name
422 #CHECK: Form: DW_FORM_strp
423 #CHECK: - Attribute: DW_AT_encoding
424 #CHECK: Form: DW_FORM_data1
425 #CHECK: - Attribute: DW_AT_byte_size
426 #CHECK: Form: DW_FORM_data1
427 #CHECK: - Code: 0x00000005
428 #CHECK: Tag: DW_TAG_pointer_type
429 #CHECK: Children: DW_CHILDREN_no
430 #CHECK: Attributes:
431 #CHECK: - Attribute: DW_AT_type
432 #CHECK: Form: DW_FORM_ref4
3535 void dumpExportTrie(std::unique_ptr &Y);
3636 void dumpSymbols(std::unique_ptr &Y);
3737 void dumpDWARF(std::unique_ptr &Y);
38 void dumpDebugStrings(DWARFContextInMemory &DCtx, std::unique_ptr &Y);
38 void dumpDebugAbbrev(DWARFContextInMemory &DCtx,
39 std::unique_ptr &Y);
40 void dumpDebugStrings(DWARFContextInMemory &DCtx,
41 std::unique_ptr &Y);
3942
4043 public:
4144 MachODumper(const object::MachOObjectFile &O) : Obj(O) {}
465468 void MachODumper::dumpDWARF(std::unique_ptr &Y) {
466469 DWARFContextInMemory DICtx(Obj);
467470 dumpDebugStrings(DICtx, Y);
471 dumpDebugAbbrev(DICtx, Y);
468472 }
469473
470474 void MachODumper::dumpDebugStrings(DWARFContextInMemory &DICtx,
474478 auto SymbolPair = RemainingTable.split('\0');
475479 RemainingTable = SymbolPair.second;
476480 Y->DWARF.DebugStrings.push_back(SymbolPair.first);
481 }
482 }
483
484 void MachODumper::dumpDebugAbbrev(DWARFContextInMemory &DCtx,
485 std::unique_ptr &Y) {
486 auto AbbrevSetPtr = DCtx.getDebugAbbrev();
487 if(AbbrevSetPtr) {
488 for(auto AbbrvDeclSet : *AbbrevSetPtr) {
489 for(auto AbbrvDecl : AbbrvDeclSet.second) {
490 MachOYAML::DWARFAbbrev Abbrv;
491 Abbrv.Code = AbbrvDecl.getCode();
492 Abbrv.Tag = AbbrvDecl.getTag();
493 Abbrv.Children = AbbrvDecl.hasChildren() ? dwarf::DW_CHILDREN_yes
494 : dwarf::DW_CHILDREN_no;
495 for(auto Attribute : AbbrvDecl.attributes()) {
496 MachOYAML::DWARFAttributeAbbrev AttAbrv;
497 AttAbrv.Attribute = Attribute.Attr;
498 AttAbrv.Form = Attribute.Form;
499 Abbrv.Attributes.push_back(AttAbrv);
500 }
501 Y->DWARF.AbbrevDecls.push_back(Abbrv);
502 }
503 }
477504 }
478505 }
479506
392392 OS.write(Str.data(), Str.size());
393393 OS.write('\0');
394394 }
395 } else if (0 == strncmp(&Section.sectname[0], "__debug_abbrev", 16)) {
396 for (auto AbbrevDecl : Obj.DWARF.AbbrevDecls) {
397 encodeULEB128(AbbrevDecl.Code, OS);
398 encodeULEB128(AbbrevDecl.Tag, OS);
399 OS.write(AbbrevDecl.Children);
400 for (auto Attr : AbbrevDecl.Attributes) {
401 encodeULEB128(Attr.Attribute, OS);
402 encodeULEB128(Attr.Form, OS);
403 }
404 encodeULEB128(0, OS);
405 encodeULEB128(0, OS);
406 }
395407 }
396408 }
397409 return Error::success();