1 //===- DWARFDataExtractor.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/DWARFDataExtractor.h"
10 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
14 std::pair
<uint64_t, dwarf::DwarfFormat
>
15 DWARFDataExtractor::getInitialLength(uint64_t *Off
, Error
*Err
) const {
16 ErrorAsOutParameter
ErrAsOut(Err
);
18 return {0, dwarf::DWARF32
};
21 uint64_t Length
= getRelocatedValue(C
, 4);
22 dwarf::DwarfFormat Format
= dwarf::DWARF32
;
23 if (Length
== dwarf::DW_LENGTH_DWARF64
) {
24 Length
= getRelocatedValue(C
, 8);
25 Format
= dwarf::DWARF64
;
26 } else if (Length
>= dwarf::DW_LENGTH_lo_reserved
) {
27 cantFail(C
.takeError());
29 *Err
= createStringError(
30 errc::invalid_argument
,
31 "unsupported reserved unit length of value 0x%8.8" PRIx64
, Length
);
32 return {0, dwarf::DWARF32
};
37 return {Length
, Format
};
42 consumeError(C
.takeError());
43 return {0, dwarf::DWARF32
};
46 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size
, uint64_t *Off
,
50 *SecNdx
= object::SectionedAddress::UndefSection
;
52 return getUnsigned(Off
, Size
, Err
);
54 ErrorAsOutParameter
ErrAsOut(Err
);
55 Optional
<RelocAddrEntry
> E
= Obj
->find(*Section
, *Off
);
56 uint64_t LocData
= getUnsigned(Off
, Size
, Err
);
57 if (!E
|| (Err
&& *Err
))
60 *SecNdx
= E
->SectionIndex
;
63 object::resolveRelocation(E
->Resolver
, E
->Reloc
, E
->SymbolValue
, LocData
);
65 R
= object::resolveRelocation(E
->Resolver
, *E
->Reloc2
, E
->SymbolValue2
, R
);
70 DWARFDataExtractor::getEncodedPointer(uint64_t *Offset
, uint8_t Encoding
,
71 uint64_t PCRelOffset
) const {
72 if (Encoding
== dwarf::DW_EH_PE_omit
)
76 uint64_t OldOffset
= *Offset
;
78 switch (Encoding
& 0x0F) {
79 case dwarf::DW_EH_PE_absptr
:
80 switch (getAddressSize()) {
84 Result
= getUnsigned(Offset
, getAddressSize());
90 case dwarf::DW_EH_PE_uleb128
:
91 Result
= getULEB128(Offset
);
93 case dwarf::DW_EH_PE_sleb128
:
94 Result
= getSLEB128(Offset
);
96 case dwarf::DW_EH_PE_udata2
:
97 Result
= getUnsigned(Offset
, 2);
99 case dwarf::DW_EH_PE_udata4
:
100 Result
= getUnsigned(Offset
, 4);
102 case dwarf::DW_EH_PE_udata8
:
103 Result
= getUnsigned(Offset
, 8);
105 case dwarf::DW_EH_PE_sdata2
:
106 Result
= getSigned(Offset
, 2);
108 case dwarf::DW_EH_PE_sdata4
:
109 Result
= SignExtend64
<32>(getRelocatedValue(4, Offset
));
111 case dwarf::DW_EH_PE_sdata8
:
112 Result
= getRelocatedValue(8, Offset
);
117 // Then add relative offset, if required
118 switch (Encoding
& 0x70) {
119 case dwarf::DW_EH_PE_absptr
:
122 case dwarf::DW_EH_PE_pcrel
:
123 Result
+= PCRelOffset
;
125 case dwarf::DW_EH_PE_datarel
:
126 case dwarf::DW_EH_PE_textrel
:
127 case dwarf::DW_EH_PE_funcrel
:
128 case dwarf::DW_EH_PE_aligned
: