1 //===- DWARFFormValue.cpp -------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/BinaryFormat/Dwarf.h"
13 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
14 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
15 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
16 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
17 #include "llvm/DebugInfo/DWARF/DWARFSection.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"
29 using namespace dwarf
;
31 static const DWARFFormValue::FormClass DWARF5FormClasses
[] = {
32 DWARFFormValue::FC_Unknown
, // 0x0
33 DWARFFormValue::FC_Address
, // 0x01 DW_FORM_addr
34 DWARFFormValue::FC_Unknown
, // 0x02 unused
35 DWARFFormValue::FC_Block
, // 0x03 DW_FORM_block2
36 DWARFFormValue::FC_Block
, // 0x04 DW_FORM_block4
37 DWARFFormValue::FC_Constant
, // 0x05 DW_FORM_data2
38 // --- These can be FC_SectionOffset in DWARF3 and below:
39 DWARFFormValue::FC_Constant
, // 0x06 DW_FORM_data4
40 DWARFFormValue::FC_Constant
, // 0x07 DW_FORM_data8
42 DWARFFormValue::FC_String
, // 0x08 DW_FORM_string
43 DWARFFormValue::FC_Block
, // 0x09 DW_FORM_block
44 DWARFFormValue::FC_Block
, // 0x0a DW_FORM_block1
45 DWARFFormValue::FC_Constant
, // 0x0b DW_FORM_data1
46 DWARFFormValue::FC_Flag
, // 0x0c DW_FORM_flag
47 DWARFFormValue::FC_Constant
, // 0x0d DW_FORM_sdata
48 DWARFFormValue::FC_String
, // 0x0e DW_FORM_strp
49 DWARFFormValue::FC_Constant
, // 0x0f DW_FORM_udata
50 DWARFFormValue::FC_Reference
, // 0x10 DW_FORM_ref_addr
51 DWARFFormValue::FC_Reference
, // 0x11 DW_FORM_ref1
52 DWARFFormValue::FC_Reference
, // 0x12 DW_FORM_ref2
53 DWARFFormValue::FC_Reference
, // 0x13 DW_FORM_ref4
54 DWARFFormValue::FC_Reference
, // 0x14 DW_FORM_ref8
55 DWARFFormValue::FC_Reference
, // 0x15 DW_FORM_ref_udata
56 DWARFFormValue::FC_Indirect
, // 0x16 DW_FORM_indirect
57 DWARFFormValue::FC_SectionOffset
, // 0x17 DW_FORM_sec_offset
58 DWARFFormValue::FC_Exprloc
, // 0x18 DW_FORM_exprloc
59 DWARFFormValue::FC_Flag
, // 0x19 DW_FORM_flag_present
60 DWARFFormValue::FC_String
, // 0x1a DW_FORM_strx
61 DWARFFormValue::FC_Address
, // 0x1b DW_FORM_addrx
62 DWARFFormValue::FC_Reference
, // 0x1c DW_FORM_ref_sup4
63 DWARFFormValue::FC_String
, // 0x1d DW_FORM_strp_sup
64 DWARFFormValue::FC_Constant
, // 0x1e DW_FORM_data16
65 DWARFFormValue::FC_String
, // 0x1f DW_FORM_line_strp
66 DWARFFormValue::FC_Reference
, // 0x20 DW_FORM_ref_sig8
67 DWARFFormValue::FC_Constant
, // 0x21 DW_FORM_implicit_const
68 DWARFFormValue::FC_SectionOffset
, // 0x22 DW_FORM_loclistx
69 DWARFFormValue::FC_SectionOffset
, // 0x23 DW_FORM_rnglistx
70 DWARFFormValue::FC_Reference
, // 0x24 DW_FORM_ref_sup8
71 DWARFFormValue::FC_String
, // 0x25 DW_FORM_strx1
72 DWARFFormValue::FC_String
, // 0x26 DW_FORM_strx2
73 DWARFFormValue::FC_String
, // 0x27 DW_FORM_strx3
74 DWARFFormValue::FC_String
, // 0x28 DW_FORM_strx4
75 DWARFFormValue::FC_Address
, // 0x29 DW_FORM_addrx1
76 DWARFFormValue::FC_Address
, // 0x2a DW_FORM_addrx2
77 DWARFFormValue::FC_Address
, // 0x2b DW_FORM_addrx3
78 DWARFFormValue::FC_Address
, // 0x2c DW_FORM_addrx4
79 DWARFFormValue::FC_Address
, // 0x2001 DW_FORM_addrx_offset
82 DWARFFormValue
DWARFFormValue::createFromSValue(dwarf::Form F
, int64_t V
) {
83 return DWARFFormValue(F
, ValueType(V
));
86 DWARFFormValue
DWARFFormValue::createFromUValue(dwarf::Form F
, uint64_t V
) {
87 return DWARFFormValue(F
, ValueType(V
));
90 DWARFFormValue
DWARFFormValue::createFromPValue(dwarf::Form F
, const char *V
) {
91 return DWARFFormValue(F
, ValueType(V
));
94 DWARFFormValue
DWARFFormValue::createFromBlockValue(dwarf::Form F
,
95 ArrayRef
<uint8_t> D
) {
99 return DWARFFormValue(F
, V
);
102 DWARFFormValue
DWARFFormValue::createFromUnit(dwarf::Form F
, const DWARFUnit
*U
,
103 uint64_t *OffsetPtr
) {
104 DWARFFormValue
FormValue(F
);
105 FormValue
.extractValue(U
->getDebugInfoExtractor(), OffsetPtr
,
106 U
->getFormParams(), U
);
110 bool DWARFFormValue::skipValue(dwarf::Form Form
, DataExtractor DebugInfoData
,
112 const dwarf::FormParams Params
) {
113 bool Indirect
= false;
116 // Blocks of inlined data that have a length field and the data bytes
117 // inlined in the .debug_info.
118 case DW_FORM_exprloc
:
119 case DW_FORM_block
: {
120 uint64_t size
= DebugInfoData
.getULEB128(OffsetPtr
);
124 case DW_FORM_block1
: {
125 uint8_t size
= DebugInfoData
.getU8(OffsetPtr
);
129 case DW_FORM_block2
: {
130 uint16_t size
= DebugInfoData
.getU16(OffsetPtr
);
134 case DW_FORM_block4
: {
135 uint32_t size
= DebugInfoData
.getU32(OffsetPtr
);
140 // Inlined NULL terminated C-strings.
142 DebugInfoData
.getCStr(OffsetPtr
);
146 case DW_FORM_ref_addr
:
147 case DW_FORM_flag_present
:
158 case DW_FORM_ref_sig8
:
159 case DW_FORM_ref_sup4
:
160 case DW_FORM_ref_sup8
:
169 case DW_FORM_sec_offset
:
171 case DW_FORM_strp_sup
:
172 case DW_FORM_line_strp
:
173 case DW_FORM_GNU_ref_alt
:
174 case DW_FORM_GNU_strp_alt
:
175 case DW_FORM_implicit_const
:
176 if (std::optional
<uint8_t> FixedSize
=
177 dwarf::getFixedFormByteSize(Form
, Params
)) {
178 *OffsetPtr
+= *FixedSize
;
183 // signed or unsigned LEB 128 values.
185 DebugInfoData
.getSLEB128(OffsetPtr
);
189 case DW_FORM_ref_udata
:
192 case DW_FORM_loclistx
:
193 case DW_FORM_rnglistx
:
194 case DW_FORM_GNU_addr_index
:
195 case DW_FORM_GNU_str_index
:
196 DebugInfoData
.getULEB128(OffsetPtr
);
199 case DW_FORM_LLVM_addrx_offset
:
200 DebugInfoData
.getULEB128(OffsetPtr
);
204 case DW_FORM_indirect
:
206 Form
= static_cast<dwarf::Form
>(DebugInfoData
.getULEB128(OffsetPtr
));
216 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC
) const {
217 return doesFormBelongToClass(Form
, FC
, U
? U
->getVersion() : 3);
220 bool DWARFFormValue::extractValue(const DWARFDataExtractor
&Data
,
221 uint64_t *OffsetPtr
, dwarf::FormParams FP
,
222 const DWARFContext
*Ctx
,
223 const DWARFUnit
*CU
) {
225 Ctx
= &CU
->getContext();
229 bool Indirect
= false;
230 bool IsBlock
= false;
231 Value
.data
= nullptr;
232 // Read the value for the form into value and follow and DW_FORM_indirect
233 // instances we run into
234 Error Err
= Error::success();
239 case DW_FORM_ref_addr
: {
241 (Form
== DW_FORM_addr
) ? FP
.AddrSize
: FP
.getRefAddrByteSize();
243 Data
.getRelocatedValue(Size
, OffsetPtr
, &Value
.SectionIndex
, &Err
);
246 case DW_FORM_exprloc
:
248 Value
.uval
= Data
.getULEB128(OffsetPtr
, &Err
);
252 Value
.uval
= Data
.getU8(OffsetPtr
, &Err
);
256 Value
.uval
= Data
.getU16(OffsetPtr
, &Err
);
260 Value
.uval
= Data
.getU32(OffsetPtr
, &Err
);
268 Value
.uval
= Data
.getU8(OffsetPtr
, &Err
);
274 Value
.uval
= Data
.getU16(OffsetPtr
, &Err
);
278 Value
.uval
= Data
.getU24(OffsetPtr
, &Err
);
282 case DW_FORM_ref_sup4
:
285 Value
.uval
= Data
.getRelocatedValue(4, OffsetPtr
, nullptr, &Err
);
289 case DW_FORM_ref_sup8
:
290 Value
.uval
= Data
.getRelocatedValue(8, OffsetPtr
, nullptr, &Err
);
293 // Treat this like a 16-byte block.
298 Value
.sval
= Data
.getSLEB128(OffsetPtr
, &Err
);
301 case DW_FORM_ref_udata
:
302 case DW_FORM_rnglistx
:
303 case DW_FORM_loclistx
:
304 case DW_FORM_GNU_addr_index
:
305 case DW_FORM_GNU_str_index
:
308 Value
.uval
= Data
.getULEB128(OffsetPtr
, &Err
);
310 case DW_FORM_LLVM_addrx_offset
:
311 Value
.uval
= Data
.getULEB128(OffsetPtr
, &Err
) << 32;
312 Value
.uval
|= Data
.getU32(OffsetPtr
, &Err
);
315 Value
.cstr
= Data
.getCStr(OffsetPtr
, &Err
);
317 case DW_FORM_indirect
:
318 Form
= static_cast<dwarf::Form
>(Data
.getULEB128(OffsetPtr
, &Err
));
322 case DW_FORM_sec_offset
:
323 case DW_FORM_GNU_ref_alt
:
324 case DW_FORM_GNU_strp_alt
:
325 case DW_FORM_line_strp
:
326 case DW_FORM_strp_sup
: {
327 Value
.uval
= Data
.getRelocatedValue(FP
.getDwarfOffsetByteSize(),
328 OffsetPtr
, nullptr, &Err
);
331 case DW_FORM_flag_present
:
334 case DW_FORM_ref_sig8
:
335 Value
.uval
= Data
.getU64(OffsetPtr
, &Err
);
337 case DW_FORM_implicit_const
:
338 // Value has been already set by DWARFFormValue::createFromSValue.
341 // DWARFFormValue::skipValue() will have caught this and caused all
342 // DWARF DIEs to fail to be parsed, so this code is not be reachable.
343 llvm_unreachable("unsupported form");
345 } while (Indirect
&& !Err
);
348 Value
.data
= Data
.getBytes(OffsetPtr
, Value
.uval
, &Err
).bytes_begin();
350 return !errorToBool(std::move(Err
));
353 void DWARFFormValue::dumpAddress(raw_ostream
&OS
, uint8_t AddressSize
,
355 uint8_t HexDigits
= AddressSize
* 2;
356 OS
<< format("0x%*.*" PRIx64
, HexDigits
, HexDigits
, Address
);
359 void DWARFFormValue::dumpSectionedAddress(raw_ostream
&OS
,
360 DIDumpOptions DumpOpts
,
361 object::SectionedAddress SA
) const {
362 dumpAddress(OS
, U
->getAddressByteSize(), SA
.Address
);
363 dumpAddressSection(U
->getContext().getDWARFObj(), OS
, DumpOpts
,
367 void DWARFFormValue::dumpAddressSection(const DWARFObject
&Obj
, raw_ostream
&OS
,
368 DIDumpOptions DumpOpts
,
369 uint64_t SectionIndex
) {
370 if (!DumpOpts
.Verbose
|| SectionIndex
== -1ULL)
372 ArrayRef
<SectionName
> SectionNames
= Obj
.getSectionNames();
373 const auto &SecRef
= SectionNames
[SectionIndex
];
375 OS
<< " \"" << SecRef
.Name
<< '\"';
377 // Print section index if name is not unique.
378 if (!SecRef
.IsNameUnique
)
379 OS
<< format(" [%" PRIu64
"]", SectionIndex
);
382 void DWARFFormValue::dump(raw_ostream
&OS
, DIDumpOptions DumpOpts
) const {
383 uint64_t UValue
= Value
.uval
;
384 bool CURelativeOffset
= false;
385 raw_ostream
&AddrOS
= DumpOpts
.ShowAddresses
386 ? WithColor(OS
, HighlightColor::Address
).get()
388 int OffsetDumpWidth
= 2 * dwarf::getDwarfOffsetByteSize(Format
);
391 dumpSectionedAddress(AddrOS
, DumpOpts
, {Value
.uval
, Value
.SectionIndex
});
398 case DW_FORM_GNU_addr_index
:
399 case DW_FORM_LLVM_addrx_offset
: {
401 OS
<< "<invalid dwarf unit>";
404 std::optional
<object::SectionedAddress
> A
= getAsSectionedAddress();
405 if (!A
|| DumpOpts
.Verbose
) {
406 if (Form
== DW_FORM_LLVM_addrx_offset
) {
407 uint32_t Index
= UValue
>> 32;
408 uint32_t Offset
= UValue
& 0xffffffff;
409 AddrOS
<< format("indexed (%8.8x) + 0x%x address = ", Index
, Offset
);
411 AddrOS
<< format("indexed (%8.8x) address = ", (uint32_t)UValue
);
414 dumpSectionedAddress(AddrOS
, DumpOpts
, *A
);
416 OS
<< "<unresolved>";
419 case DW_FORM_flag_present
:
424 OS
<< format("0x%02x", (uint8_t)UValue
);
427 OS
<< format("0x%04x", (uint16_t)UValue
);
430 OS
<< format("0x%08x", (uint32_t)UValue
);
432 case DW_FORM_ref_sig8
:
433 AddrOS
<< format("0x%016" PRIx64
, UValue
);
436 OS
<< format("0x%016" PRIx64
, UValue
);
439 OS
<< format_bytes(ArrayRef
<uint8_t>(Value
.data
, 16), std::nullopt
, 16, 16);
443 OS
.write_escaped(Value
.cstr
);
446 case DW_FORM_exprloc
:
453 case DW_FORM_exprloc
:
455 AddrOS
<< format("<0x%" PRIx64
"> ", UValue
);
458 AddrOS
<< format("<0x%2.2x> ", (uint8_t)UValue
);
461 AddrOS
<< format("<0x%4.4x> ", (uint16_t)UValue
);
464 AddrOS
<< format("<0x%8.8x> ", (uint32_t)UValue
);
470 const uint8_t *DataPtr
= Value
.data
;
472 // UValue contains size of block
473 const uint8_t *EndDataPtr
= DataPtr
+ UValue
;
474 while (DataPtr
< EndDataPtr
) {
475 AddrOS
<< format("%2.2x ", *DataPtr
);
484 case DW_FORM_implicit_const
:
491 if (DumpOpts
.Verbose
)
492 OS
<< format(" .debug_str[0x%0*" PRIx64
"] = ", OffsetDumpWidth
, UValue
);
495 case DW_FORM_line_strp
:
496 if (DumpOpts
.Verbose
)
497 OS
<< format(" .debug_line_str[0x%0*" PRIx64
"] = ", OffsetDumpWidth
,
506 case DW_FORM_GNU_str_index
:
507 if (DumpOpts
.Verbose
)
508 OS
<< format("indexed (%8.8x) string = ", (uint32_t)UValue
);
511 case DW_FORM_GNU_strp_alt
:
512 if (DumpOpts
.Verbose
)
513 OS
<< format("alt indirect string, offset: 0x%" PRIx64
"", UValue
);
516 case DW_FORM_ref_addr
:
517 AddrOS
<< format("0x%016" PRIx64
, UValue
);
520 CURelativeOffset
= true;
521 if (DumpOpts
.Verbose
)
522 AddrOS
<< format("cu + 0x%2.2x", (uint8_t)UValue
);
525 CURelativeOffset
= true;
526 if (DumpOpts
.Verbose
)
527 AddrOS
<< format("cu + 0x%4.4x", (uint16_t)UValue
);
530 CURelativeOffset
= true;
531 if (DumpOpts
.Verbose
)
532 AddrOS
<< format("cu + 0x%4.4x", (uint32_t)UValue
);
535 CURelativeOffset
= true;
536 if (DumpOpts
.Verbose
)
537 AddrOS
<< format("cu + 0x%8.8" PRIx64
, UValue
);
539 case DW_FORM_ref_udata
:
540 CURelativeOffset
= true;
541 if (DumpOpts
.Verbose
)
542 AddrOS
<< format("cu + 0x%" PRIx64
, UValue
);
544 case DW_FORM_GNU_ref_alt
:
545 AddrOS
<< format("<alt 0x%" PRIx64
">", UValue
);
548 // All DW_FORM_indirect attributes should be resolved prior to calling
550 case DW_FORM_indirect
:
551 OS
<< "DW_FORM_indirect";
554 case DW_FORM_rnglistx
:
555 OS
<< format("indexed (0x%x) rangelist = ", (uint32_t)UValue
);
558 case DW_FORM_loclistx
:
559 OS
<< format("indexed (0x%x) loclist = ", (uint32_t)UValue
);
562 case DW_FORM_sec_offset
:
563 AddrOS
<< format("0x%0*" PRIx64
, OffsetDumpWidth
, UValue
);
567 OS
<< format("DW_FORM(0x%4.4x)", Form
);
571 if (CURelativeOffset
) {
572 if (DumpOpts
.Verbose
)
574 if (DumpOpts
.ShowAddresses
)
575 WithColor(OS
, HighlightColor::Address
).get()
576 << format("0x%8.8" PRIx64
, UValue
+ (U
? U
->getOffset() : 0));
577 if (DumpOpts
.Verbose
)
582 void DWARFFormValue::dumpString(raw_ostream
&OS
) const {
583 if (auto DbgStr
= dwarf::toString(*this)) {
584 auto COS
= WithColor(OS
, HighlightColor::String
);
586 COS
.get().write_escaped(*DbgStr
);
591 Expected
<const char *> DWARFFormValue::getAsCString() const {
592 if (!isFormClass(FC_String
))
593 return make_error
<StringError
>("Invalid form for string attribute",
594 inconvertibleErrorCode());
595 if (Form
== DW_FORM_string
)
597 // FIXME: Add support for DW_FORM_GNU_strp_alt
598 if (Form
== DW_FORM_GNU_strp_alt
|| C
== nullptr)
599 return make_error
<StringError
>("Unsupported form for string attribute",
600 inconvertibleErrorCode());
601 uint64_t Offset
= Value
.uval
;
602 std::optional
<uint32_t> Index
;
603 if (Form
== DW_FORM_GNU_str_index
|| Form
== DW_FORM_strx
||
604 Form
== DW_FORM_strx1
|| Form
== DW_FORM_strx2
|| Form
== DW_FORM_strx3
||
605 Form
== DW_FORM_strx4
) {
607 return make_error
<StringError
>("API limitation - string extraction not "
608 "available without a DWARFUnit",
609 inconvertibleErrorCode());
610 Expected
<uint64_t> StrOffset
= U
->getStringOffsetSectionItem(Offset
);
613 return StrOffset
.takeError();
616 // Prefer the Unit's string extractor, because for .dwo it will point to
617 // .debug_str.dwo, while the Context's extractor always uses .debug_str.
618 bool IsDebugLineString
= Form
== DW_FORM_line_strp
;
619 DataExtractor StrData
=
620 IsDebugLineString
? C
->getLineStringExtractor()
621 : U
? U
->getStringExtractor() : C
->getStringExtractor();
622 if (const char *Str
= StrData
.getCStr(&Offset
))
624 std::string Msg
= FormEncodingString(Form
).str();
626 Msg
+= (" uses index " + Twine(*Index
) + ", but the referenced string").str();
627 Msg
+= (" offset " + Twine(Offset
) + " is beyond " +
628 (IsDebugLineString
? ".debug_line_str" : ".debug_str") + " bounds")
630 return make_error
<StringError
>(Msg
,
631 inconvertibleErrorCode());
634 std::optional
<uint64_t> DWARFFormValue::getAsAddress() const {
635 if (auto SA
= getAsSectionedAddress())
640 std::optional
<object::SectionedAddress
> DWARFFormValue::getAsSectionedAddress(
641 const ValueType
&Value
, const dwarf::Form Form
, const DWARFUnit
*U
) {
642 if (!doesFormBelongToClass(Form
, FC_Address
, U
? U
->getVersion() : 3))
644 bool AddrOffset
= Form
== dwarf::DW_FORM_LLVM_addrx_offset
;
645 if (Form
== DW_FORM_GNU_addr_index
|| Form
== DW_FORM_addrx
||
646 Form
== DW_FORM_addrx1
|| Form
== DW_FORM_addrx2
||
647 Form
== DW_FORM_addrx3
|| Form
== DW_FORM_addrx4
|| AddrOffset
) {
649 uint32_t Index
= AddrOffset
? (Value
.uval
>> 32) : Value
.uval
;
652 std::optional
<object::SectionedAddress
> SA
=
653 U
->getAddrOffsetSectionItem(Index
);
657 SA
->Address
+= (Value
.uval
& 0xffffffff);
660 return {{Value
.uval
, Value
.SectionIndex
}};
663 std::optional
<object::SectionedAddress
>
664 DWARFFormValue::getAsSectionedAddress() const {
665 return getAsSectionedAddress(Value
, Form
, U
);
668 std::optional
<uint64_t> DWARFFormValue::getAsRelativeReference() const {
674 case DW_FORM_ref_udata
:
683 std::optional
<uint64_t> DWARFFormValue::getAsDebugInfoReference() const {
684 if (Form
== DW_FORM_ref_addr
)
689 std::optional
<uint64_t> DWARFFormValue::getAsSignatureReference() const {
690 if (Form
== DW_FORM_ref_sig8
)
695 std::optional
<uint64_t> DWARFFormValue::getAsSupplementaryReference() const {
697 case DW_FORM_GNU_ref_alt
:
698 case DW_FORM_ref_sup4
:
699 case DW_FORM_ref_sup8
:
706 std::optional
<uint64_t> DWARFFormValue::getAsSectionOffset() const {
707 if (!isFormClass(FC_SectionOffset
))
712 std::optional
<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
713 if ((!isFormClass(FC_Constant
) && !isFormClass(FC_Flag
)) ||
714 Form
== DW_FORM_sdata
)
719 std::optional
<int64_t> DWARFFormValue::getAsSignedConstant() const {
720 if ((!isFormClass(FC_Constant
) && !isFormClass(FC_Flag
)) ||
721 (Form
== DW_FORM_udata
&&
722 uint64_t(std::numeric_limits
<int64_t>::max()) < Value
.uval
))
726 return int32_t(Value
.uval
);
728 return int16_t(Value
.uval
);
730 return int8_t(Value
.uval
);
738 std::optional
<ArrayRef
<uint8_t>> DWARFFormValue::getAsBlock() const {
739 if (!isFormClass(FC_Block
) && !isFormClass(FC_Exprloc
) &&
740 Form
!= DW_FORM_data16
)
742 return ArrayRef(Value
.data
, Value
.uval
);
745 std::optional
<uint64_t> DWARFFormValue::getAsCStringOffset() const {
746 if (!isFormClass(FC_String
) && Form
== DW_FORM_string
)
751 std::optional
<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
752 if (!isFormClass(FC_Reference
))
757 std::optional
<std::string
>
758 DWARFFormValue::getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind
) const {
759 if (U
== nullptr || !isFormClass(FC_Constant
))
761 DWARFUnit
*DLU
= const_cast<DWARFUnit
*>(U
)->getLinkedUnit();
762 if (auto *LT
= DLU
->getContext().getLineTableForUnit(DLU
)) {
763 std::string FileName
;
764 if (LT
->getFileNameByIndex(Value
.uval
, DLU
->getCompilationDir(), Kind
,
771 bool llvm::dwarf::doesFormBelongToClass(dwarf::Form Form
, DWARFFormValue::FormClass FC
,
772 uint16_t DwarfVersion
) {
773 // First, check DWARF5 form classes.
774 if (Form
< std::size(DWARF5FormClasses
) && DWARF5FormClasses
[Form
] == FC
)
776 // Check more forms from extensions and proposals.
778 case DW_FORM_GNU_ref_alt
:
779 return (FC
== DWARFFormValue::FC_Reference
);
780 case DW_FORM_GNU_addr_index
:
781 return (FC
== DWARFFormValue::FC_Address
);
782 case DW_FORM_GNU_str_index
:
783 case DW_FORM_GNU_strp_alt
:
784 return (FC
== DWARFFormValue::FC_String
);
785 case DW_FORM_LLVM_addrx_offset
:
786 return (FC
== DWARFFormValue::FC_Address
);
788 case DW_FORM_line_strp
:
789 return (FC
== DWARFFormValue::FC_SectionOffset
);
792 // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section
794 return (FC
== DWARFFormValue::FC_SectionOffset
) && (DwarfVersion
<= 3);