1 | //===-- llvm/BinaryFormat/Dwarf.cpp - Dwarf Framework ------------*- C++-*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file contains support for generic dwarf information. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/BinaryFormat/Dwarf.h" |
14 | #include "llvm/ADT/StringSwitch.h" |
15 | #include "llvm/Support/ErrorHandling.h" |
16 | #include "llvm/TargetParser/Triple.h" |
17 | |
18 | using namespace llvm; |
19 | using namespace dwarf; |
20 | |
21 | StringRef llvm::dwarf::TagString(unsigned Tag) { |
22 | switch (Tag) { |
23 | default: |
24 | return StringRef(); |
25 | #define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \ |
26 | case DW_TAG_##NAME: \ |
27 | return "DW_TAG_" #NAME; |
28 | #include "llvm/BinaryFormat/Dwarf.def" |
29 | } |
30 | } |
31 | |
32 | unsigned llvm::dwarf::getTag(StringRef TagString) { |
33 | return StringSwitch<unsigned>(TagString) |
34 | #define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \ |
35 | .Case("DW_TAG_" #NAME, DW_TAG_##NAME) |
36 | #include "llvm/BinaryFormat/Dwarf.def" |
37 | .Default(Value: DW_TAG_invalid); |
38 | } |
39 | |
40 | unsigned llvm::dwarf::TagVersion(dwarf::Tag Tag) { |
41 | switch (Tag) { |
42 | default: |
43 | return 0; |
44 | #define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \ |
45 | case DW_TAG_##NAME: \ |
46 | return VERSION; |
47 | #include "llvm/BinaryFormat/Dwarf.def" |
48 | } |
49 | } |
50 | |
51 | unsigned llvm::dwarf::TagVendor(dwarf::Tag Tag) { |
52 | switch (Tag) { |
53 | default: |
54 | return 0; |
55 | #define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \ |
56 | case DW_TAG_##NAME: \ |
57 | return DWARF_VENDOR_##VENDOR; |
58 | #include "llvm/BinaryFormat/Dwarf.def" |
59 | } |
60 | } |
61 | |
62 | StringRef llvm::dwarf::ChildrenString(unsigned Children) { |
63 | switch (Children) { |
64 | case DW_CHILDREN_no: |
65 | return "DW_CHILDREN_no" ; |
66 | case DW_CHILDREN_yes: |
67 | return "DW_CHILDREN_yes" ; |
68 | } |
69 | return StringRef(); |
70 | } |
71 | |
72 | StringRef llvm::dwarf::AttributeString(unsigned Attribute) { |
73 | switch (Attribute) { |
74 | default: |
75 | return StringRef(); |
76 | #define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \ |
77 | case DW_AT_##NAME: \ |
78 | return "DW_AT_" #NAME; |
79 | #include "llvm/BinaryFormat/Dwarf.def" |
80 | } |
81 | } |
82 | |
83 | unsigned llvm::dwarf::AttributeVersion(dwarf::Attribute Attribute) { |
84 | switch (Attribute) { |
85 | default: |
86 | return 0; |
87 | #define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \ |
88 | case DW_AT_##NAME: \ |
89 | return VERSION; |
90 | #include "llvm/BinaryFormat/Dwarf.def" |
91 | } |
92 | } |
93 | |
94 | unsigned llvm::dwarf::AttributeVendor(dwarf::Attribute Attribute) { |
95 | switch (Attribute) { |
96 | default: |
97 | return 0; |
98 | #define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \ |
99 | case DW_AT_##NAME: \ |
100 | return DWARF_VENDOR_##VENDOR; |
101 | #include "llvm/BinaryFormat/Dwarf.def" |
102 | } |
103 | } |
104 | |
105 | StringRef llvm::dwarf::FormEncodingString(unsigned Encoding) { |
106 | switch (Encoding) { |
107 | default: |
108 | return StringRef(); |
109 | #define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \ |
110 | case DW_FORM_##NAME: \ |
111 | return "DW_FORM_" #NAME; |
112 | #include "llvm/BinaryFormat/Dwarf.def" |
113 | } |
114 | } |
115 | |
116 | unsigned llvm::dwarf::FormVersion(dwarf::Form Form) { |
117 | switch (Form) { |
118 | default: |
119 | return 0; |
120 | #define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \ |
121 | case DW_FORM_##NAME: \ |
122 | return VERSION; |
123 | #include "llvm/BinaryFormat/Dwarf.def" |
124 | } |
125 | } |
126 | |
127 | unsigned llvm::dwarf::FormVendor(dwarf::Form Form) { |
128 | switch (Form) { |
129 | default: |
130 | return 0; |
131 | #define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \ |
132 | case DW_FORM_##NAME: \ |
133 | return DWARF_VENDOR_##VENDOR; |
134 | #include "llvm/BinaryFormat/Dwarf.def" |
135 | } |
136 | } |
137 | |
138 | StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) { |
139 | switch (Encoding) { |
140 | default: |
141 | return StringRef(); |
142 | #define HANDLE_DW_OP(ID, NAME, OPERANDS, ARITY, VERSION, VENDOR) \ |
143 | case DW_OP_##NAME: \ |
144 | return "DW_OP_" #NAME; |
145 | #include "llvm/BinaryFormat/Dwarf.def" |
146 | case DW_OP_LLVM_convert: |
147 | return "DW_OP_LLVM_convert" ; |
148 | case DW_OP_LLVM_fragment: |
149 | return "DW_OP_LLVM_fragment" ; |
150 | case DW_OP_LLVM_tag_offset: |
151 | return "DW_OP_LLVM_tag_offset" ; |
152 | case DW_OP_LLVM_entry_value: |
153 | return "DW_OP_LLVM_entry_value" ; |
154 | case DW_OP_LLVM_implicit_pointer: |
155 | return "DW_OP_LLVM_implicit_pointer" ; |
156 | case DW_OP_LLVM_arg: |
157 | return "DW_OP_LLVM_arg" ; |
158 | case DW_OP_LLVM_extract_bits_sext: |
159 | return "DW_OP_LLVM_extract_bits_sext" ; |
160 | case DW_OP_LLVM_extract_bits_zext: |
161 | return "DW_OP_LLVM_extract_bits_zext" ; |
162 | } |
163 | } |
164 | |
165 | unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) { |
166 | return StringSwitch<unsigned>(OperationEncodingString) |
167 | #define HANDLE_DW_OP(ID, NAME, OPERANDS, ARITY, VERSION, VENDOR) \ |
168 | .Case("DW_OP_" #NAME, DW_OP_##NAME) |
169 | #include "llvm/BinaryFormat/Dwarf.def" |
170 | .Case(S: "DW_OP_LLVM_convert" , Value: DW_OP_LLVM_convert) |
171 | .Case(S: "DW_OP_LLVM_fragment" , Value: DW_OP_LLVM_fragment) |
172 | .Case(S: "DW_OP_LLVM_tag_offset" , Value: DW_OP_LLVM_tag_offset) |
173 | .Case(S: "DW_OP_LLVM_entry_value" , Value: DW_OP_LLVM_entry_value) |
174 | .Case(S: "DW_OP_LLVM_implicit_pointer" , Value: DW_OP_LLVM_implicit_pointer) |
175 | .Case(S: "DW_OP_LLVM_arg" , Value: DW_OP_LLVM_arg) |
176 | .Case(S: "DW_OP_LLVM_extract_bits_sext" , Value: DW_OP_LLVM_extract_bits_sext) |
177 | .Case(S: "DW_OP_LLVM_extract_bits_zext" , Value: DW_OP_LLVM_extract_bits_zext) |
178 | .Default(Value: 0); |
179 | } |
180 | |
181 | static StringRef LlvmUserOperationEncodingString(unsigned Encoding) { |
182 | switch (Encoding) { |
183 | default: |
184 | llvm_unreachable("unhandled DWARF operation with LLVM user op" ); |
185 | #define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) \ |
186 | case DW_OP_LLVM_##NAME: \ |
187 | return "DW_OP_LLVM_" #NAME; |
188 | #include "llvm/BinaryFormat/Dwarf.def" |
189 | } |
190 | } |
191 | |
192 | static unsigned |
193 | getLlvmUserOperationEncoding(StringRef LlvmUserOperationEncodingString) { |
194 | unsigned E = StringSwitch<unsigned>(LlvmUserOperationEncodingString) |
195 | #define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) .Case(#NAME, DW_OP_LLVM_##NAME) |
196 | #include "llvm/BinaryFormat/Dwarf.def" |
197 | .Default(Value: 0); |
198 | assert(E && "unhandled DWARF operation string with LLVM user op" ); |
199 | return E; |
200 | } |
201 | |
202 | StringRef llvm::dwarf::SubOperationEncodingString(unsigned OpEncoding, |
203 | unsigned SubOpEncoding) { |
204 | assert(OpEncoding == DW_OP_LLVM_user); |
205 | return LlvmUserOperationEncodingString(Encoding: SubOpEncoding); |
206 | } |
207 | |
208 | unsigned |
209 | llvm::dwarf::getSubOperationEncoding(unsigned OpEncoding, |
210 | StringRef SubOperationEncodingString) { |
211 | assert(OpEncoding == DW_OP_LLVM_user); |
212 | return getLlvmUserOperationEncoding(LlvmUserOperationEncodingString: SubOperationEncodingString); |
213 | } |
214 | |
215 | unsigned llvm::dwarf::OperationVersion(dwarf::LocationAtom Op) { |
216 | switch (Op) { |
217 | default: |
218 | return 0; |
219 | #define HANDLE_DW_OP(ID, NAME, OPERANDS, ARITY, VERSION, VENDOR) \ |
220 | case DW_OP_##NAME: \ |
221 | return VERSION; |
222 | #include "llvm/BinaryFormat/Dwarf.def" |
223 | } |
224 | } |
225 | |
226 | std::optional<unsigned> llvm::dwarf::OperationOperands(dwarf::LocationAtom Op) { |
227 | switch (Op) { |
228 | default: |
229 | return std::nullopt; |
230 | #define HANDLE_DW_OP(ID, NAME, OPERANDS, ARITY, VERSION, VENDOR) \ |
231 | case DW_OP_##NAME: \ |
232 | if (OPERANDS == -1) \ |
233 | return std::nullopt; \ |
234 | return OPERANDS; |
235 | #include "llvm/BinaryFormat/Dwarf.def" |
236 | } |
237 | } |
238 | |
239 | std::optional<unsigned> llvm::dwarf::OperationArity(dwarf::LocationAtom Op) { |
240 | switch (Op) { |
241 | default: |
242 | return std::nullopt; |
243 | #define HANDLE_DW_OP(ID, NAME, OPERANDS, ARITY, VERSION, VENDOR) \ |
244 | case DW_OP_##NAME: \ |
245 | if (ARITY == -1) \ |
246 | return std::nullopt; \ |
247 | return ARITY; |
248 | #include "llvm/BinaryFormat/Dwarf.def" |
249 | } |
250 | } |
251 | |
252 | unsigned llvm::dwarf::OperationVendor(dwarf::LocationAtom Op) { |
253 | switch (Op) { |
254 | default: |
255 | return 0; |
256 | #define HANDLE_DW_OP(ID, NAME, OPERANDS, ARITY, VERSION, VENDOR) \ |
257 | case DW_OP_##NAME: \ |
258 | return DWARF_VENDOR_##VENDOR; |
259 | #include "llvm/BinaryFormat/Dwarf.def" |
260 | } |
261 | } |
262 | |
263 | StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) { |
264 | switch (Encoding) { |
265 | default: |
266 | return StringRef(); |
267 | #define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \ |
268 | case DW_ATE_##NAME: \ |
269 | return "DW_ATE_" #NAME; |
270 | #include "llvm/BinaryFormat/Dwarf.def" |
271 | } |
272 | } |
273 | |
274 | unsigned llvm::dwarf::getAttributeEncoding(StringRef EncodingString) { |
275 | return StringSwitch<unsigned>(EncodingString) |
276 | #define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \ |
277 | .Case("DW_ATE_" #NAME, DW_ATE_##NAME) |
278 | #include "llvm/BinaryFormat/Dwarf.def" |
279 | .Default(Value: 0); |
280 | } |
281 | |
282 | unsigned llvm::dwarf::AttributeEncodingVersion(dwarf::TypeKind ATE) { |
283 | switch (ATE) { |
284 | default: |
285 | return 0; |
286 | #define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \ |
287 | case DW_ATE_##NAME: \ |
288 | return VERSION; |
289 | #include "llvm/BinaryFormat/Dwarf.def" |
290 | } |
291 | } |
292 | |
293 | unsigned llvm::dwarf::AttributeEncodingVendor(dwarf::TypeKind ATE) { |
294 | switch (ATE) { |
295 | default: |
296 | return 0; |
297 | #define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \ |
298 | case DW_ATE_##NAME: \ |
299 | return DWARF_VENDOR_##VENDOR; |
300 | #include "llvm/BinaryFormat/Dwarf.def" |
301 | } |
302 | } |
303 | |
304 | StringRef llvm::dwarf::DecimalSignString(unsigned Sign) { |
305 | switch (Sign) { |
306 | case DW_DS_unsigned: |
307 | return "DW_DS_unsigned" ; |
308 | case DW_DS_leading_overpunch: |
309 | return "DW_DS_leading_overpunch" ; |
310 | case DW_DS_trailing_overpunch: |
311 | return "DW_DS_trailing_overpunch" ; |
312 | case DW_DS_leading_separate: |
313 | return "DW_DS_leading_separate" ; |
314 | case DW_DS_trailing_separate: |
315 | return "DW_DS_trailing_separate" ; |
316 | } |
317 | return StringRef(); |
318 | } |
319 | |
320 | StringRef llvm::dwarf::EndianityString(unsigned Endian) { |
321 | switch (Endian) { |
322 | case DW_END_default: |
323 | return "DW_END_default" ; |
324 | case DW_END_big: |
325 | return "DW_END_big" ; |
326 | case DW_END_little: |
327 | return "DW_END_little" ; |
328 | case DW_END_lo_user: |
329 | return "DW_END_lo_user" ; |
330 | case DW_END_hi_user: |
331 | return "DW_END_hi_user" ; |
332 | } |
333 | return StringRef(); |
334 | } |
335 | |
336 | StringRef llvm::dwarf::AccessibilityString(unsigned Access) { |
337 | switch (Access) { |
338 | // Accessibility codes |
339 | case DW_ACCESS_public: |
340 | return "DW_ACCESS_public" ; |
341 | case DW_ACCESS_protected: |
342 | return "DW_ACCESS_protected" ; |
343 | case DW_ACCESS_private: |
344 | return "DW_ACCESS_private" ; |
345 | } |
346 | return StringRef(); |
347 | } |
348 | |
349 | StringRef llvm::dwarf::DefaultedMemberString(unsigned DefaultedEncodings) { |
350 | switch (DefaultedEncodings) { |
351 | // Defaulted Member Encodings codes |
352 | case DW_DEFAULTED_no: |
353 | return "DW_DEFAULTED_no" ; |
354 | case DW_DEFAULTED_in_class: |
355 | return "DW_DEFAULTED_in_class" ; |
356 | case DW_DEFAULTED_out_of_class: |
357 | return "DW_DEFAULTED_out_of_class" ; |
358 | } |
359 | return StringRef(); |
360 | } |
361 | |
362 | StringRef llvm::dwarf::VisibilityString(unsigned Visibility) { |
363 | switch (Visibility) { |
364 | case DW_VIS_local: |
365 | return "DW_VIS_local" ; |
366 | case DW_VIS_exported: |
367 | return "DW_VIS_exported" ; |
368 | case DW_VIS_qualified: |
369 | return "DW_VIS_qualified" ; |
370 | } |
371 | return StringRef(); |
372 | } |
373 | |
374 | StringRef llvm::dwarf::VirtualityString(unsigned Virtuality) { |
375 | switch (Virtuality) { |
376 | default: |
377 | return StringRef(); |
378 | #define HANDLE_DW_VIRTUALITY(ID, NAME) \ |
379 | case DW_VIRTUALITY_##NAME: \ |
380 | return "DW_VIRTUALITY_" #NAME; |
381 | #include "llvm/BinaryFormat/Dwarf.def" |
382 | } |
383 | } |
384 | |
385 | unsigned llvm::dwarf::getVirtuality(StringRef VirtualityString) { |
386 | return StringSwitch<unsigned>(VirtualityString) |
387 | #define HANDLE_DW_VIRTUALITY(ID, NAME) \ |
388 | .Case("DW_VIRTUALITY_" #NAME, DW_VIRTUALITY_##NAME) |
389 | #include "llvm/BinaryFormat/Dwarf.def" |
390 | .Default(Value: DW_VIRTUALITY_invalid); |
391 | } |
392 | |
393 | StringRef llvm::dwarf::LanguageString(unsigned Language) { |
394 | switch (Language) { |
395 | default: |
396 | return StringRef(); |
397 | #define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \ |
398 | case DW_LANG_##NAME: \ |
399 | return "DW_LANG_" #NAME; |
400 | #include "llvm/BinaryFormat/Dwarf.def" |
401 | } |
402 | } |
403 | |
404 | unsigned llvm::dwarf::getLanguage(StringRef LanguageString) { |
405 | return StringSwitch<unsigned>(LanguageString) |
406 | #define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \ |
407 | .Case("DW_LANG_" #NAME, DW_LANG_##NAME) |
408 | #include "llvm/BinaryFormat/Dwarf.def" |
409 | .Default(Value: 0); |
410 | } |
411 | |
412 | unsigned llvm::dwarf::LanguageVersion(dwarf::SourceLanguage Lang) { |
413 | switch (Lang) { |
414 | default: |
415 | return 0; |
416 | #define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \ |
417 | case DW_LANG_##NAME: \ |
418 | return VERSION; |
419 | #include "llvm/BinaryFormat/Dwarf.def" |
420 | } |
421 | } |
422 | |
423 | unsigned llvm::dwarf::LanguageVendor(dwarf::SourceLanguage Lang) { |
424 | switch (Lang) { |
425 | default: |
426 | return 0; |
427 | #define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \ |
428 | case DW_LANG_##NAME: \ |
429 | return DWARF_VENDOR_##VENDOR; |
430 | #include "llvm/BinaryFormat/Dwarf.def" |
431 | } |
432 | } |
433 | |
434 | std::optional<unsigned> |
435 | llvm::dwarf::LanguageLowerBound(dwarf::SourceLanguage Lang) { |
436 | switch (Lang) { |
437 | default: |
438 | return std::nullopt; |
439 | #define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \ |
440 | case DW_LANG_##NAME: \ |
441 | return LOWER_BOUND; |
442 | #include "llvm/BinaryFormat/Dwarf.def" |
443 | } |
444 | } |
445 | |
446 | StringRef llvm::dwarf::LanguageDescription(dwarf::SourceLanguageName lname) { |
447 | switch (lname) { |
448 | #define HANDLE_DW_LNAME(ID, NAME, DESC, LOWER_BOUND) \ |
449 | case DW_LNAME_##NAME: \ |
450 | return DESC; |
451 | #include "llvm/BinaryFormat/Dwarf.def" |
452 | } |
453 | return "Unknown" ; |
454 | } |
455 | |
456 | StringRef llvm::dwarf::CaseString(unsigned Case) { |
457 | switch (Case) { |
458 | case DW_ID_case_sensitive: |
459 | return "DW_ID_case_sensitive" ; |
460 | case DW_ID_up_case: |
461 | return "DW_ID_up_case" ; |
462 | case DW_ID_down_case: |
463 | return "DW_ID_down_case" ; |
464 | case DW_ID_case_insensitive: |
465 | return "DW_ID_case_insensitive" ; |
466 | } |
467 | return StringRef(); |
468 | } |
469 | |
470 | StringRef llvm::dwarf::ConventionString(unsigned CC) { |
471 | switch (CC) { |
472 | default: |
473 | return StringRef(); |
474 | #define HANDLE_DW_CC(ID, NAME) \ |
475 | case DW_CC_##NAME: \ |
476 | return "DW_CC_" #NAME; |
477 | #include "llvm/BinaryFormat/Dwarf.def" |
478 | } |
479 | } |
480 | |
481 | unsigned llvm::dwarf::getCallingConvention(StringRef CCString) { |
482 | return StringSwitch<unsigned>(CCString) |
483 | #define HANDLE_DW_CC(ID, NAME) .Case("DW_CC_" #NAME, DW_CC_##NAME) |
484 | #include "llvm/BinaryFormat/Dwarf.def" |
485 | .Default(Value: 0); |
486 | } |
487 | |
488 | StringRef llvm::dwarf::InlineCodeString(unsigned Code) { |
489 | switch (Code) { |
490 | case DW_INL_not_inlined: |
491 | return "DW_INL_not_inlined" ; |
492 | case DW_INL_inlined: |
493 | return "DW_INL_inlined" ; |
494 | case DW_INL_declared_not_inlined: |
495 | return "DW_INL_declared_not_inlined" ; |
496 | case DW_INL_declared_inlined: |
497 | return "DW_INL_declared_inlined" ; |
498 | } |
499 | return StringRef(); |
500 | } |
501 | |
502 | StringRef llvm::dwarf::ArrayOrderString(unsigned Order) { |
503 | switch (Order) { |
504 | case DW_ORD_row_major: |
505 | return "DW_ORD_row_major" ; |
506 | case DW_ORD_col_major: |
507 | return "DW_ORD_col_major" ; |
508 | } |
509 | return StringRef(); |
510 | } |
511 | |
512 | StringRef llvm::dwarf::LNStandardString(unsigned Standard) { |
513 | switch (Standard) { |
514 | default: |
515 | return StringRef(); |
516 | #define HANDLE_DW_LNS(ID, NAME) \ |
517 | case DW_LNS_##NAME: \ |
518 | return "DW_LNS_" #NAME; |
519 | #include "llvm/BinaryFormat/Dwarf.def" |
520 | } |
521 | } |
522 | |
523 | StringRef llvm::dwarf::LNExtendedString(unsigned Encoding) { |
524 | switch (Encoding) { |
525 | default: |
526 | return StringRef(); |
527 | #define HANDLE_DW_LNE(ID, NAME) \ |
528 | case DW_LNE_##NAME: \ |
529 | return "DW_LNE_" #NAME; |
530 | #include "llvm/BinaryFormat/Dwarf.def" |
531 | } |
532 | } |
533 | |
534 | StringRef llvm::dwarf::MacinfoString(unsigned Encoding) { |
535 | switch (Encoding) { |
536 | // Macinfo Type Encodings |
537 | case DW_MACINFO_define: |
538 | return "DW_MACINFO_define" ; |
539 | case DW_MACINFO_undef: |
540 | return "DW_MACINFO_undef" ; |
541 | case DW_MACINFO_start_file: |
542 | return "DW_MACINFO_start_file" ; |
543 | case DW_MACINFO_end_file: |
544 | return "DW_MACINFO_end_file" ; |
545 | case DW_MACINFO_vendor_ext: |
546 | return "DW_MACINFO_vendor_ext" ; |
547 | case DW_MACINFO_invalid: |
548 | return "DW_MACINFO_invalid" ; |
549 | } |
550 | return StringRef(); |
551 | } |
552 | |
553 | unsigned llvm::dwarf::getMacinfo(StringRef MacinfoString) { |
554 | return StringSwitch<unsigned>(MacinfoString) |
555 | .Case(S: "DW_MACINFO_define" , Value: DW_MACINFO_define) |
556 | .Case(S: "DW_MACINFO_undef" , Value: DW_MACINFO_undef) |
557 | .Case(S: "DW_MACINFO_start_file" , Value: DW_MACINFO_start_file) |
558 | .Case(S: "DW_MACINFO_end_file" , Value: DW_MACINFO_end_file) |
559 | .Case(S: "DW_MACINFO_vendor_ext" , Value: DW_MACINFO_vendor_ext) |
560 | .Default(Value: DW_MACINFO_invalid); |
561 | } |
562 | |
563 | StringRef llvm::dwarf::MacroString(unsigned Encoding) { |
564 | switch (Encoding) { |
565 | default: |
566 | return StringRef(); |
567 | #define HANDLE_DW_MACRO(ID, NAME) \ |
568 | case DW_MACRO_##NAME: \ |
569 | return "DW_MACRO_" #NAME; |
570 | #include "llvm/BinaryFormat/Dwarf.def" |
571 | } |
572 | } |
573 | |
574 | StringRef llvm::dwarf::GnuMacroString(unsigned Encoding) { |
575 | switch (Encoding) { |
576 | default: |
577 | return StringRef(); |
578 | #define HANDLE_DW_MACRO_GNU(ID, NAME) \ |
579 | case DW_MACRO_GNU_##NAME: \ |
580 | return "DW_MACRO_GNU_" #NAME; |
581 | #include "llvm/BinaryFormat/Dwarf.def" |
582 | } |
583 | } |
584 | |
585 | unsigned llvm::dwarf::getMacro(StringRef MacroString) { |
586 | return StringSwitch<unsigned>(MacroString) |
587 | #define HANDLE_DW_MACRO(ID, NAME) .Case("DW_MACRO_" #NAME, ID) |
588 | #include "llvm/BinaryFormat/Dwarf.def" |
589 | .Default(Value: DW_MACINFO_invalid); |
590 | } |
591 | StringRef llvm::dwarf::RangeListEncodingString(unsigned Encoding) { |
592 | switch (Encoding) { |
593 | default: |
594 | return StringRef(); |
595 | #define HANDLE_DW_RLE(ID, NAME) \ |
596 | case DW_RLE_##NAME: \ |
597 | return "DW_RLE_" #NAME; |
598 | #include "llvm/BinaryFormat/Dwarf.def" |
599 | } |
600 | } |
601 | |
602 | StringRef llvm::dwarf::LocListEncodingString(unsigned Encoding) { |
603 | switch (Encoding) { |
604 | default: |
605 | return StringRef(); |
606 | #define HANDLE_DW_LLE(ID, NAME) \ |
607 | case DW_LLE_##NAME: \ |
608 | return "DW_LLE_" #NAME; |
609 | #include "llvm/BinaryFormat/Dwarf.def" |
610 | } |
611 | } |
612 | |
613 | StringRef llvm::dwarf::CallFrameString(unsigned Encoding, |
614 | Triple::ArchType Arch) { |
615 | assert(Arch != llvm::Triple::ArchType::UnknownArch); |
616 | #define SELECT_AARCH64 (Arch == llvm::Triple::aarch64_be || Arch == llvm::Triple::aarch64) |
617 | #define SELECT_MIPS64 Arch == llvm::Triple::mips64 |
618 | #define SELECT_SPARC (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) |
619 | #define SELECT_X86 (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) |
620 | #define HANDLE_DW_CFA(ID, NAME) |
621 | #define HANDLE_DW_CFA_PRED(ID, NAME, PRED) \ |
622 | if (ID == Encoding && PRED) \ |
623 | return "DW_CFA_" #NAME; |
624 | #include "llvm/BinaryFormat/Dwarf.def" |
625 | |
626 | switch (Encoding) { |
627 | default: |
628 | return StringRef(); |
629 | #define HANDLE_DW_CFA_PRED(ID, NAME, PRED) |
630 | #define HANDLE_DW_CFA(ID, NAME) \ |
631 | case DW_CFA_##NAME: \ |
632 | return "DW_CFA_" #NAME; |
633 | #include "llvm/BinaryFormat/Dwarf.def" |
634 | |
635 | #undef SELECT_X86 |
636 | #undef SELECT_SPARC |
637 | #undef SELECT_MIPS64 |
638 | #undef SELECT_AARCH64 |
639 | } |
640 | } |
641 | |
642 | StringRef llvm::dwarf::ApplePropertyString(unsigned Prop) { |
643 | switch (Prop) { |
644 | default: |
645 | return StringRef(); |
646 | #define HANDLE_DW_APPLE_PROPERTY(ID, NAME) \ |
647 | case DW_APPLE_PROPERTY_##NAME: \ |
648 | return "DW_APPLE_PROPERTY_" #NAME; |
649 | #include "llvm/BinaryFormat/Dwarf.def" |
650 | } |
651 | } |
652 | |
653 | StringRef llvm::dwarf::UnitTypeString(unsigned UT) { |
654 | switch (UT) { |
655 | default: |
656 | return StringRef(); |
657 | #define HANDLE_DW_UT(ID, NAME) \ |
658 | case DW_UT_##NAME: \ |
659 | return "DW_UT_" #NAME; |
660 | #include "llvm/BinaryFormat/Dwarf.def" |
661 | } |
662 | } |
663 | |
664 | StringRef llvm::dwarf::AtomTypeString(unsigned AT) { |
665 | switch (AT) { |
666 | case dwarf::DW_ATOM_null: |
667 | return "DW_ATOM_null" ; |
668 | case dwarf::DW_ATOM_die_offset: |
669 | return "DW_ATOM_die_offset" ; |
670 | case DW_ATOM_cu_offset: |
671 | return "DW_ATOM_cu_offset" ; |
672 | case DW_ATOM_die_tag: |
673 | return "DW_ATOM_die_tag" ; |
674 | case DW_ATOM_type_flags: |
675 | case DW_ATOM_type_type_flags: |
676 | return "DW_ATOM_type_flags" ; |
677 | case DW_ATOM_qual_name_hash: |
678 | return "DW_ATOM_qual_name_hash" ; |
679 | } |
680 | return StringRef(); |
681 | } |
682 | |
683 | StringRef llvm::dwarf::GDBIndexEntryKindString(GDBIndexEntryKind Kind) { |
684 | switch (Kind) { |
685 | case GIEK_NONE: |
686 | return "NONE" ; |
687 | case GIEK_TYPE: |
688 | return "TYPE" ; |
689 | case GIEK_VARIABLE: |
690 | return "VARIABLE" ; |
691 | case GIEK_FUNCTION: |
692 | return "FUNCTION" ; |
693 | case GIEK_OTHER: |
694 | return "OTHER" ; |
695 | case GIEK_UNUSED5: |
696 | return "UNUSED5" ; |
697 | case GIEK_UNUSED6: |
698 | return "UNUSED6" ; |
699 | case GIEK_UNUSED7: |
700 | return "UNUSED7" ; |
701 | } |
702 | llvm_unreachable("Unknown GDBIndexEntryKind value" ); |
703 | } |
704 | |
705 | StringRef |
706 | llvm::dwarf::GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage) { |
707 | switch (Linkage) { |
708 | case GIEL_EXTERNAL: |
709 | return "EXTERNAL" ; |
710 | case GIEL_STATIC: |
711 | return "STATIC" ; |
712 | } |
713 | llvm_unreachable("Unknown GDBIndexEntryLinkage value" ); |
714 | } |
715 | |
716 | StringRef llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) { |
717 | switch (Attr) { |
718 | case DW_AT_accessibility: |
719 | return AccessibilityString(Access: Val); |
720 | case DW_AT_virtuality: |
721 | return VirtualityString(Virtuality: Val); |
722 | case DW_AT_language: |
723 | return LanguageString(Language: Val); |
724 | case DW_AT_encoding: |
725 | return AttributeEncodingString(Encoding: Val); |
726 | case DW_AT_decimal_sign: |
727 | return DecimalSignString(Sign: Val); |
728 | case DW_AT_endianity: |
729 | return EndianityString(Endian: Val); |
730 | case DW_AT_visibility: |
731 | return VisibilityString(Visibility: Val); |
732 | case DW_AT_identifier_case: |
733 | return CaseString(Case: Val); |
734 | case DW_AT_calling_convention: |
735 | return ConventionString(CC: Val); |
736 | case DW_AT_inline: |
737 | return InlineCodeString(Code: Val); |
738 | case DW_AT_ordering: |
739 | return ArrayOrderString(Order: Val); |
740 | case DW_AT_APPLE_runtime_class: |
741 | return LanguageString(Language: Val); |
742 | case DW_AT_defaulted: |
743 | return DefaultedMemberString(DefaultedEncodings: Val); |
744 | } |
745 | |
746 | return StringRef(); |
747 | } |
748 | |
749 | StringRef llvm::dwarf::AtomValueString(uint16_t Atom, unsigned Val) { |
750 | switch (Atom) { |
751 | case DW_ATOM_null: |
752 | return "NULL" ; |
753 | case DW_ATOM_die_tag: |
754 | return TagString(Tag: Val); |
755 | } |
756 | |
757 | return StringRef(); |
758 | } |
759 | |
760 | StringRef llvm::dwarf::IndexString(unsigned Idx) { |
761 | switch (Idx) { |
762 | default: |
763 | return StringRef(); |
764 | #define HANDLE_DW_IDX(ID, NAME) \ |
765 | case DW_IDX_##NAME: \ |
766 | return "DW_IDX_" #NAME; |
767 | #include "llvm/BinaryFormat/Dwarf.def" |
768 | } |
769 | } |
770 | |
771 | std::optional<uint8_t> llvm::dwarf::getFixedFormByteSize(dwarf::Form Form, |
772 | FormParams Params) { |
773 | switch (Form) { |
774 | case DW_FORM_addr: |
775 | if (Params) |
776 | return Params.AddrSize; |
777 | return std::nullopt; |
778 | |
779 | case DW_FORM_block: // ULEB128 length L followed by L bytes. |
780 | case DW_FORM_block1: // 1 byte length L followed by L bytes. |
781 | case DW_FORM_block2: // 2 byte length L followed by L bytes. |
782 | case DW_FORM_block4: // 4 byte length L followed by L bytes. |
783 | case DW_FORM_string: // C-string with null terminator. |
784 | case DW_FORM_sdata: // SLEB128. |
785 | case DW_FORM_udata: // ULEB128. |
786 | case DW_FORM_ref_udata: // ULEB128. |
787 | case DW_FORM_indirect: // ULEB128. |
788 | case DW_FORM_exprloc: // ULEB128 length L followed by L bytes. |
789 | case DW_FORM_strx: // ULEB128. |
790 | case DW_FORM_addrx: // ULEB128. |
791 | case DW_FORM_loclistx: // ULEB128. |
792 | case DW_FORM_rnglistx: // ULEB128. |
793 | case DW_FORM_GNU_addr_index: // ULEB128. |
794 | case DW_FORM_GNU_str_index: // ULEB128. |
795 | return std::nullopt; |
796 | |
797 | case DW_FORM_ref_addr: |
798 | if (Params) |
799 | return Params.getRefAddrByteSize(); |
800 | return std::nullopt; |
801 | |
802 | case DW_FORM_flag: |
803 | case DW_FORM_data1: |
804 | case DW_FORM_ref1: |
805 | case DW_FORM_strx1: |
806 | case DW_FORM_addrx1: |
807 | return 1; |
808 | |
809 | case DW_FORM_data2: |
810 | case DW_FORM_ref2: |
811 | case DW_FORM_strx2: |
812 | case DW_FORM_addrx2: |
813 | return 2; |
814 | |
815 | case DW_FORM_strx3: |
816 | case DW_FORM_addrx3: |
817 | return 3; |
818 | |
819 | case DW_FORM_data4: |
820 | case DW_FORM_ref4: |
821 | case DW_FORM_ref_sup4: |
822 | case DW_FORM_strx4: |
823 | case DW_FORM_addrx4: |
824 | return 4; |
825 | |
826 | case DW_FORM_strp: |
827 | case DW_FORM_GNU_ref_alt: |
828 | case DW_FORM_GNU_strp_alt: |
829 | case DW_FORM_line_strp: |
830 | case DW_FORM_sec_offset: |
831 | case DW_FORM_strp_sup: |
832 | if (Params) |
833 | return Params.getDwarfOffsetByteSize(); |
834 | return std::nullopt; |
835 | |
836 | case DW_FORM_data8: |
837 | case DW_FORM_ref8: |
838 | case DW_FORM_ref_sig8: |
839 | case DW_FORM_ref_sup8: |
840 | return 8; |
841 | |
842 | case DW_FORM_flag_present: |
843 | return 0; |
844 | |
845 | case DW_FORM_data16: |
846 | return 16; |
847 | |
848 | case DW_FORM_implicit_const: |
849 | // The implicit value is stored in the abbreviation as a SLEB128, and |
850 | // there no data in debug info. |
851 | return 0; |
852 | |
853 | default: |
854 | break; |
855 | } |
856 | return std::nullopt; |
857 | } |
858 | |
859 | bool llvm::dwarf::isValidFormForVersion(Form F, unsigned Version, |
860 | bool ExtensionsOk) { |
861 | if (FormVendor(Form: F) == DWARF_VENDOR_DWARF) { |
862 | unsigned FV = FormVersion(Form: F); |
863 | return FV > 0 && FV <= Version; |
864 | } |
865 | return ExtensionsOk; |
866 | } |
867 | |
868 | StringRef llvm::dwarf::FormatString(DwarfFormat Format) { |
869 | switch (Format) { |
870 | case DWARF32: |
871 | return "DWARF32" ; |
872 | case DWARF64: |
873 | return "DWARF64" ; |
874 | } |
875 | return StringRef(); |
876 | } |
877 | |
878 | StringRef llvm::dwarf::FormatString(bool IsDWARF64) { |
879 | return FormatString(Format: IsDWARF64 ? DWARF64 : DWARF32); |
880 | } |
881 | |
882 | StringRef llvm::dwarf::RLEString(unsigned RLE) { |
883 | switch (RLE) { |
884 | default: |
885 | return StringRef(); |
886 | #define HANDLE_DW_RLE(ID, NAME) \ |
887 | case DW_RLE_##NAME: \ |
888 | return "DW_RLE_" #NAME; |
889 | #include "llvm/BinaryFormat/Dwarf.def" |
890 | } |
891 | } |
892 | |
893 | constexpr char llvm::dwarf::EnumTraits<Attribute>::Type[]; |
894 | constexpr char llvm::dwarf::EnumTraits<Form>::Type[]; |
895 | constexpr char llvm::dwarf::EnumTraits<Index>::Type[]; |
896 | constexpr char llvm::dwarf::EnumTraits<Tag>::Type[]; |
897 | constexpr char llvm::dwarf::EnumTraits<LineNumberOps>::Type[]; |
898 | constexpr char llvm::dwarf::EnumTraits<LocationAtom>::Type[]; |
899 | |