Line data Source code
1 : //===- DWARFFormValue.cpp -------------------------------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
11 : #include "llvm/ADT/ArrayRef.h"
12 : #include "llvm/ADT/None.h"
13 : #include "llvm/ADT/Optional.h"
14 : #include "llvm/ADT/StringRef.h"
15 : #include "llvm/BinaryFormat/Dwarf.h"
16 : #include "llvm/DebugInfo/DWARF/DWARFContext.h"
17 : #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
18 : #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
19 : #include "llvm/Support/ErrorHandling.h"
20 : #include "llvm/Support/Format.h"
21 : #include "llvm/Support/WithColor.h"
22 : #include "llvm/Support/raw_ostream.h"
23 : #include <cinttypes>
24 : #include <cstdint>
25 : #include <limits>
26 :
27 : using namespace llvm;
28 : using namespace dwarf;
29 :
30 : static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
31 : DWARFFormValue::FC_Unknown, // 0x0
32 : DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr
33 : DWARFFormValue::FC_Unknown, // 0x02 unused
34 : DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2
35 : DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4
36 : DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
37 : // --- These can be FC_SectionOffset in DWARF3 and below:
38 : DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
39 : DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
40 : // ---
41 : DWARFFormValue::FC_String, // 0x08 DW_FORM_string
42 : DWARFFormValue::FC_Block, // 0x09 DW_FORM_block
43 : DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1
44 : DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1
45 : DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag
46 : DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata
47 : DWARFFormValue::FC_String, // 0x0e DW_FORM_strp
48 : DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata
49 : DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr
50 : DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1
51 : DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2
52 : DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4
53 : DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8
54 : DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata
55 : DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect
56 : DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
57 : DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc
58 : DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
59 : DWARFFormValue::FC_String, // 0x1a DW_FORM_strx
60 : DWARFFormValue::FC_Address, // 0x1b DW_FORM_addrx
61 : DWARFFormValue::FC_Reference, // 0x1c DW_FORM_ref_sup4
62 : DWARFFormValue::FC_String, // 0x1d DW_FORM_strp_sup
63 : DWARFFormValue::FC_Constant, // 0x1e DW_FORM_data16
64 : DWARFFormValue::FC_String, // 0x1f DW_FORM_line_strp
65 : DWARFFormValue::FC_Reference, // 0x20 DW_FORM_ref_sig8
66 : DWARFFormValue::FC_Constant, // 0x21 DW_FORM_implicit_const
67 : DWARFFormValue::FC_SectionOffset, // 0x22 DW_FORM_loclistx
68 : DWARFFormValue::FC_SectionOffset, // 0x23 DW_FORM_rnglistx
69 : DWARFFormValue::FC_Reference, // 0x24 DW_FORM_ref_sup8
70 : DWARFFormValue::FC_String, // 0x25 DW_FORM_strx1
71 : DWARFFormValue::FC_String, // 0x26 DW_FORM_strx2
72 : DWARFFormValue::FC_String, // 0x27 DW_FORM_strx3
73 : DWARFFormValue::FC_String, // 0x28 DW_FORM_strx4
74 : DWARFFormValue::FC_Address, // 0x29 DW_FORM_addrx1
75 : DWARFFormValue::FC_Address, // 0x2a DW_FORM_addrx2
76 : DWARFFormValue::FC_Address, // 0x2b DW_FORM_addrx3
77 : DWARFFormValue::FC_Address, // 0x2c DW_FORM_addrx4
78 :
79 : };
80 :
81 19775 : bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
82 : uint32_t *OffsetPtr,
83 : const dwarf::FormParams Params) {
84 : bool Indirect = false;
85 : do {
86 19775 : switch (Form) {
87 : // Blocks of inlined data that have a length field and the data bytes
88 : // inlined in the .debug_info.
89 4541 : case DW_FORM_exprloc:
90 : case DW_FORM_block: {
91 4541 : uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
92 4541 : *OffsetPtr += size;
93 4541 : return true;
94 : }
95 3481 : case DW_FORM_block1: {
96 3481 : uint8_t size = DebugInfoData.getU8(OffsetPtr);
97 3481 : *OffsetPtr += size;
98 3481 : return true;
99 : }
100 209 : case DW_FORM_block2: {
101 209 : uint16_t size = DebugInfoData.getU16(OffsetPtr);
102 209 : *OffsetPtr += size;
103 209 : return true;
104 : }
105 200 : case DW_FORM_block4: {
106 200 : uint32_t size = DebugInfoData.getU32(OffsetPtr);
107 200 : *OffsetPtr += size;
108 200 : return true;
109 : }
110 :
111 : // Inlined NULL terminated C-strings.
112 581 : case DW_FORM_string:
113 581 : DebugInfoData.getCStr(OffsetPtr);
114 581 : return true;
115 :
116 8510 : case DW_FORM_addr:
117 : case DW_FORM_ref_addr:
118 : case DW_FORM_flag_present:
119 : case DW_FORM_data1:
120 : case DW_FORM_data2:
121 : case DW_FORM_data4:
122 : case DW_FORM_data8:
123 : case DW_FORM_data16:
124 : case DW_FORM_flag:
125 : case DW_FORM_ref1:
126 : case DW_FORM_ref2:
127 : case DW_FORM_ref4:
128 : case DW_FORM_ref8:
129 : case DW_FORM_ref_sig8:
130 : case DW_FORM_ref_sup4:
131 : case DW_FORM_ref_sup8:
132 : case DW_FORM_strx1:
133 : case DW_FORM_strx2:
134 : case DW_FORM_strx4:
135 : case DW_FORM_addrx1:
136 : case DW_FORM_addrx2:
137 : case DW_FORM_addrx4:
138 : case DW_FORM_sec_offset:
139 : case DW_FORM_strp:
140 : case DW_FORM_strp_sup:
141 : case DW_FORM_line_strp:
142 : case DW_FORM_GNU_ref_alt:
143 : case DW_FORM_GNU_strp_alt:
144 8510 : if (Optional<uint8_t> FixedSize =
145 8510 : dwarf::getFixedFormByteSize(Form, Params)) {
146 8509 : *OffsetPtr += *FixedSize;
147 : return true;
148 8509 : }
149 1 : return false;
150 :
151 : // signed or unsigned LEB 128 values.
152 412 : case DW_FORM_sdata:
153 412 : DebugInfoData.getSLEB128(OffsetPtr);
154 412 : return true;
155 :
156 1841 : case DW_FORM_udata:
157 : case DW_FORM_ref_udata:
158 : case DW_FORM_strx:
159 : case DW_FORM_addrx:
160 : case DW_FORM_loclistx:
161 : case DW_FORM_rnglistx:
162 : case DW_FORM_GNU_addr_index:
163 : case DW_FORM_GNU_str_index:
164 1841 : DebugInfoData.getULEB128(OffsetPtr);
165 1841 : return true;
166 :
167 0 : case DW_FORM_indirect:
168 : Indirect = true;
169 0 : Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
170 : break;
171 :
172 : default:
173 : return false;
174 : }
175 : } while (Indirect);
176 : return true;
177 : }
178 :
179 120634 : bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
180 : // First, check DWARF5 form classes.
181 120634 : if (Form < makeArrayRef(DWARF5FormClasses).size() &&
182 119023 : DWARF5FormClasses[Form] == FC)
183 72676 : return true;
184 : // Check more forms from extensions and proposals.
185 47958 : switch (Form) {
186 9 : case DW_FORM_GNU_ref_alt:
187 9 : return (FC == FC_Reference);
188 178 : case DW_FORM_GNU_addr_index:
189 178 : return (FC == FC_Address);
190 1422 : case DW_FORM_GNU_str_index:
191 : case DW_FORM_GNU_strp_alt:
192 1422 : return (FC == FC_String);
193 : default:
194 : break;
195 : }
196 : // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
197 : // Don't check for DWARF version here, as some producers may still do this
198 : // by mistake. Also accept DW_FORM_[line_]strp since these are
199 : // .debug_[line_]str section offsets.
200 46349 : return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
201 46349 : Form == DW_FORM_strp || Form == DW_FORM_line_strp) &&
202 : FC == FC_SectionOffset;
203 : }
204 :
205 72965 : bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
206 : uint32_t *OffsetPtr, dwarf::FormParams FP,
207 : const DWARFContext *Ctx,
208 : const DWARFUnit *CU) {
209 72965 : if (!Ctx && CU)
210 68870 : Ctx = &CU->getContext();
211 72965 : C = Ctx;
212 72965 : U = CU;
213 : bool Indirect = false;
214 : bool IsBlock = false;
215 72965 : Value.data = nullptr;
216 : // Read the value for the form into value and follow and DW_FORM_indirect
217 : // instances we run into
218 : do {
219 : Indirect = false;
220 72965 : switch (Form) {
221 8950 : case DW_FORM_addr:
222 : case DW_FORM_ref_addr: {
223 : uint16_t Size =
224 9728 : (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
225 8950 : Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
226 : break;
227 : }
228 1641 : case DW_FORM_exprloc:
229 : case DW_FORM_block:
230 1641 : Value.uval = Data.getULEB128(OffsetPtr);
231 : IsBlock = true;
232 : break;
233 1527 : case DW_FORM_block1:
234 1527 : Value.uval = Data.getU8(OffsetPtr);
235 : IsBlock = true;
236 : break;
237 9 : case DW_FORM_block2:
238 9 : Value.uval = Data.getU16(OffsetPtr);
239 : IsBlock = true;
240 : break;
241 9 : case DW_FORM_block4:
242 9 : Value.uval = Data.getU32(OffsetPtr);
243 : IsBlock = true;
244 : break;
245 14637 : case DW_FORM_data1:
246 : case DW_FORM_ref1:
247 : case DW_FORM_flag:
248 : case DW_FORM_strx1:
249 : case DW_FORM_addrx1:
250 14637 : Value.uval = Data.getU8(OffsetPtr);
251 : break;
252 2326 : case DW_FORM_data2:
253 : case DW_FORM_ref2:
254 : case DW_FORM_strx2:
255 : case DW_FORM_addrx2:
256 2326 : Value.uval = Data.getU16(OffsetPtr);
257 : break;
258 4 : case DW_FORM_strx3:
259 4 : Value.uval = Data.getU24(OffsetPtr);
260 : break;
261 16660 : case DW_FORM_data4:
262 : case DW_FORM_ref4:
263 : case DW_FORM_ref_sup4:
264 : case DW_FORM_strx4:
265 : case DW_FORM_addrx4:
266 16660 : Value.uval = Data.getRelocatedValue(4, OffsetPtr);
267 : break;
268 399 : case DW_FORM_data8:
269 : case DW_FORM_ref8:
270 : case DW_FORM_ref_sup8:
271 399 : Value.uval = Data.getU64(OffsetPtr);
272 : break;
273 74 : case DW_FORM_data16:
274 : // Treat this like a 16-byte block.
275 74 : Value.uval = 16;
276 : IsBlock = true;
277 : break;
278 368 : case DW_FORM_sdata:
279 368 : Value.sval = Data.getSLEB128(OffsetPtr);
280 : break;
281 572 : case DW_FORM_udata:
282 : case DW_FORM_ref_udata:
283 : case DW_FORM_rnglistx:
284 572 : Value.uval = Data.getULEB128(OffsetPtr);
285 : break;
286 248 : case DW_FORM_string:
287 248 : Value.cstr = Data.getCStr(OffsetPtr);
288 : break;
289 0 : case DW_FORM_indirect:
290 0 : Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr));
291 : Indirect = true;
292 : break;
293 22658 : case DW_FORM_strp:
294 : case DW_FORM_sec_offset:
295 : case DW_FORM_GNU_ref_alt:
296 : case DW_FORM_GNU_strp_alt:
297 : case DW_FORM_line_strp:
298 : case DW_FORM_strp_sup: {
299 22658 : Value.uval =
300 22658 : Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
301 : break;
302 : }
303 2058 : case DW_FORM_flag_present:
304 2058 : Value.uval = 1;
305 : break;
306 69 : case DW_FORM_ref_sig8:
307 69 : Value.uval = Data.getU64(OffsetPtr);
308 : break;
309 756 : case DW_FORM_GNU_addr_index:
310 : case DW_FORM_GNU_str_index:
311 : case DW_FORM_strx:
312 756 : Value.uval = Data.getULEB128(OffsetPtr);
313 : break;
314 0 : default:
315 : // DWARFFormValue::skipValue() will have caught this and caused all
316 : // DWARF DIEs to fail to be parsed, so this code is not be reachable.
317 0 : llvm_unreachable("unsupported form");
318 : }
319 : } while (Indirect);
320 :
321 72965 : if (IsBlock) {
322 3260 : StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
323 3260 : Value.data = nullptr;
324 3260 : if (!Str.empty()) {
325 3259 : Value.data = reinterpret_cast<const uint8_t *>(Str.data());
326 3259 : *OffsetPtr += Value.uval;
327 : }
328 : }
329 :
330 72965 : return true;
331 : }
332 :
333 20993 : void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
334 20993 : uint64_t UValue = Value.uval;
335 : bool CURelativeOffset = false;
336 20993 : raw_ostream &AddrOS = DumpOpts.ShowAddresses
337 20993 : ? WithColor(OS, HighlightColor::Address).get()
338 66 : : nulls();
339 20993 : switch (Form) {
340 1847 : case DW_FORM_addr:
341 1847 : AddrOS << format("0x%016" PRIx64, UValue);
342 : break;
343 64 : case DW_FORM_GNU_addr_index: {
344 128 : AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
345 : uint64_t Address;
346 64 : if (U == nullptr)
347 0 : OS << "<invalid dwarf unit>";
348 64 : else if (U->getAddrOffsetSectionItem(UValue, Address))
349 100 : AddrOS << format("0x%016" PRIx64, Address);
350 : else
351 14 : OS << "<no .debug_addr section>";
352 : break;
353 : }
354 1758 : case DW_FORM_flag_present:
355 1758 : OS << "true";
356 : break;
357 2602 : case DW_FORM_flag:
358 : case DW_FORM_data1:
359 5204 : OS << format("0x%02x", (uint8_t)UValue);
360 : break;
361 514 : case DW_FORM_data2:
362 1028 : OS << format("0x%04x", (uint16_t)UValue);
363 : break;
364 1743 : case DW_FORM_data4:
365 3486 : OS << format("0x%08x", (uint32_t)UValue);
366 : break;
367 58 : case DW_FORM_ref_sig8:
368 58 : AddrOS << format("0x%016" PRIx64, UValue);
369 : break;
370 103 : case DW_FORM_data8:
371 103 : OS << format("0x%016" PRIx64, UValue);
372 : break;
373 : case DW_FORM_data16:
374 2 : OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16);
375 : break;
376 : case DW_FORM_string:
377 : OS << '"';
378 1088 : OS.write_escaped(Value.cstr);
379 : OS << '"';
380 : break;
381 7 : case DW_FORM_exprloc:
382 : case DW_FORM_block:
383 : case DW_FORM_block1:
384 : case DW_FORM_block2:
385 : case DW_FORM_block4:
386 7 : if (UValue > 0) {
387 : switch (Form) {
388 4 : case DW_FORM_exprloc:
389 : case DW_FORM_block:
390 4 : AddrOS << format("<0x%" PRIx64 "> ", UValue);
391 4 : break;
392 3 : case DW_FORM_block1:
393 6 : AddrOS << format("<0x%2.2x> ", (uint8_t)UValue);
394 3 : break;
395 0 : case DW_FORM_block2:
396 0 : AddrOS << format("<0x%4.4x> ", (uint16_t)UValue);
397 0 : break;
398 0 : case DW_FORM_block4:
399 0 : AddrOS << format("<0x%8.8x> ", (uint32_t)UValue);
400 0 : break;
401 : default:
402 : break;
403 : }
404 :
405 7 : const uint8_t *DataPtr = Value.data;
406 7 : if (DataPtr) {
407 : // UValue contains size of block
408 7 : const uint8_t *EndDataPtr = DataPtr + UValue;
409 21 : while (DataPtr < EndDataPtr) {
410 14 : AddrOS << format("%2.2x ", *DataPtr);
411 14 : ++DataPtr;
412 : }
413 : } else
414 0 : OS << "NULL";
415 : }
416 : break;
417 :
418 354 : case DW_FORM_sdata:
419 354 : OS << Value.sval;
420 : break;
421 397 : case DW_FORM_udata:
422 397 : OS << Value.uval;
423 : break;
424 5418 : case DW_FORM_strp:
425 5418 : if (DumpOpts.Verbose)
426 6612 : OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
427 5418 : dumpString(OS);
428 : break;
429 118 : case DW_FORM_line_strp:
430 118 : if (DumpOpts.Verbose)
431 184 : OS << format(" .debug_line_str[0x%8.8x] = ", (uint32_t)UValue);
432 118 : dumpString(OS);
433 : break;
434 921 : case DW_FORM_strx:
435 : case DW_FORM_strx1:
436 : case DW_FORM_strx2:
437 : case DW_FORM_strx3:
438 : case DW_FORM_strx4:
439 : case DW_FORM_GNU_str_index:
440 921 : if (DumpOpts.Verbose)
441 1654 : OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
442 921 : dumpString(OS);
443 : break;
444 0 : case DW_FORM_GNU_strp_alt:
445 0 : if (DumpOpts.Verbose)
446 0 : OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
447 0 : dumpString(OS);
448 : break;
449 224 : case DW_FORM_ref_addr:
450 224 : AddrOS << format("0x%016" PRIx64, UValue);
451 : break;
452 0 : case DW_FORM_ref1:
453 : CURelativeOffset = true;
454 0 : if (DumpOpts.Verbose)
455 0 : AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue);
456 : break;
457 0 : case DW_FORM_ref2:
458 : CURelativeOffset = true;
459 0 : if (DumpOpts.Verbose)
460 0 : AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue);
461 : break;
462 3624 : case DW_FORM_ref4:
463 : CURelativeOffset = true;
464 3624 : if (DumpOpts.Verbose)
465 4386 : AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue);
466 : break;
467 0 : case DW_FORM_ref8:
468 : CURelativeOffset = true;
469 0 : if (DumpOpts.Verbose)
470 0 : AddrOS << format("cu + 0x%8.8" PRIx64, UValue);
471 : break;
472 0 : case DW_FORM_ref_udata:
473 : CURelativeOffset = true;
474 0 : if (DumpOpts.Verbose)
475 0 : AddrOS << format("cu + 0x%" PRIx64, UValue);
476 : break;
477 0 : case DW_FORM_GNU_ref_alt:
478 0 : AddrOS << format("<alt 0x%" PRIx64 ">", UValue);
479 : break;
480 :
481 : // All DW_FORM_indirect attributes should be resolved prior to calling
482 : // this function
483 0 : case DW_FORM_indirect:
484 0 : OS << "DW_FORM_indirect";
485 : break;
486 :
487 3 : case DW_FORM_rnglistx:
488 6 : OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue);
489 : break;
490 :
491 : // Should be formatted to 64-bit for DWARF64.
492 693 : case DW_FORM_sec_offset:
493 1386 : AddrOS << format("0x%08x", (uint32_t)UValue);
494 : break;
495 :
496 0 : default:
497 0 : OS << format("DW_FORM(0x%4.4x)", Form);
498 : break;
499 : }
500 :
501 : if (CURelativeOffset) {
502 3624 : if (DumpOpts.Verbose)
503 2193 : OS << " => {";
504 3624 : if (DumpOpts.ShowAddresses)
505 7220 : WithColor(OS, HighlightColor::Address).get()
506 3610 : << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
507 3624 : if (DumpOpts.Verbose)
508 2193 : OS << "}";
509 : }
510 20993 : }
511 :
512 6457 : void DWARFFormValue::dumpString(raw_ostream &OS) const {
513 6457 : Optional<const char *> DbgStr = getAsCString();
514 6457 : if (DbgStr.hasValue()) {
515 12870 : auto COS = WithColor(OS, HighlightColor::String);
516 6435 : COS.get() << '"';
517 12870 : COS.get().write_escaped(DbgStr.getValue());
518 6435 : COS.get() << '"';
519 : }
520 6457 : }
521 :
522 23474 : Optional<const char *> DWARFFormValue::getAsCString() const {
523 23474 : if (!isFormClass(FC_String))
524 : return None;
525 22769 : if (Form == DW_FORM_string)
526 : return Value.cstr;
527 : // FIXME: Add support for DW_FORM_GNU_strp_alt
528 18631 : if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
529 : return None;
530 18631 : uint32_t Offset = Value.uval;
531 18631 : if (Form == DW_FORM_line_strp) {
532 : // .debug_line_str is tracked in the Context.
533 220 : if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
534 : return Str;
535 : return None;
536 : }
537 18411 : if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
538 17131 : Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
539 : Form == DW_FORM_strx4) {
540 : uint64_t StrOffset;
541 1295 : if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset))
542 1 : return None;
543 1294 : Offset = StrOffset;
544 : }
545 : // Prefer the Unit's string extractor, because for .dwo it will point to
546 : // .debug_str.dwo, while the Context's extractor always uses .debug_str.
547 18410 : if (U) {
548 18408 : if (const char *Str = U->getStringExtractor().getCStr(&Offset))
549 : return Str;
550 : return None;
551 : }
552 2 : if (const char *Str = C->getStringExtractor().getCStr(&Offset))
553 : return Str;
554 : return None;
555 : }
556 :
557 7529 : Optional<uint64_t> DWARFFormValue::getAsAddress() const {
558 7529 : if (!isFormClass(FC_Address))
559 : return None;
560 6107 : if (Form == DW_FORM_GNU_addr_index) {
561 49 : uint32_t Index = Value.uval;
562 : uint64_t Result;
563 49 : if (!U || !U->getAddrOffsetSectionItem(Index, Result))
564 : return None;
565 : return Result;
566 : }
567 : return Value.uval;
568 : }
569 :
570 8367 : Optional<uint64_t> DWARFFormValue::getAsReference() const {
571 8367 : if (!isFormClass(FC_Reference))
572 : return None;
573 8359 : switch (Form) {
574 7699 : case DW_FORM_ref1:
575 : case DW_FORM_ref2:
576 : case DW_FORM_ref4:
577 : case DW_FORM_ref8:
578 : case DW_FORM_ref_udata:
579 7699 : if (!U)
580 : return None;
581 15398 : return Value.uval + U->getOffset();
582 660 : case DW_FORM_ref_addr:
583 : case DW_FORM_ref_sig8:
584 : case DW_FORM_GNU_ref_alt:
585 : return Value.uval;
586 : default:
587 : return None;
588 : }
589 : }
590 :
591 6353 : Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
592 6353 : if (!isFormClass(FC_SectionOffset))
593 : return None;
594 : return Value.uval;
595 : }
596 :
597 39583 : Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
598 39583 : if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
599 24860 : Form == DW_FORM_sdata)
600 : return None;
601 : return Value.uval;
602 : }
603 :
604 39 : Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
605 39 : if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
606 33 : (Form == DW_FORM_udata &&
607 6 : uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
608 : return None;
609 32 : switch (Form) {
610 2 : case DW_FORM_data4:
611 2 : return int32_t(Value.uval);
612 2 : case DW_FORM_data2:
613 2 : return int16_t(Value.uval);
614 2 : case DW_FORM_data1:
615 2 : return int8_t(Value.uval);
616 26 : case DW_FORM_sdata:
617 : case DW_FORM_data8:
618 : default:
619 : return Value.sval;
620 : }
621 : }
622 :
623 3162 : Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
624 3162 : if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
625 89 : Form != DW_FORM_data16)
626 : return None;
627 3146 : return makeArrayRef(Value.data, Value.uval);
628 : }
629 :
630 30 : Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
631 30 : if (!isFormClass(FC_String) && Form == DW_FORM_string)
632 : return None;
633 : return Value.uval;
634 : }
635 :
636 755 : Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
637 755 : if (!isFormClass(FC_Reference))
638 : return None;
639 : return Value.uval;
640 : }
|