[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / DebugInfo / DWARF / DWARFDataExtractor.cpp
blobda6f6ad903f42ede980d5eb106879a993b9098ce
1 //===- DWARFDataExtractor.cpp ---------------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
10 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
12 using namespace llvm;
14 std::pair<uint64_t, dwarf::DwarfFormat>
15 DWARFDataExtractor::getInitialLength(uint64_t *Off, Error *Err) const {
16 ErrorAsOutParameter ErrAsOut(Err);
17 if (Err && *Err)
18 return {0, dwarf::DWARF32};
20 Cursor C(*Off);
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());
28 if (Err)
29 *Err = createStringError(
30 errc::invalid_argument,
31 "unsupported reserved unit length of value 0x%8.8" PRIx64, Length);
32 return {0, dwarf::DWARF32};
35 if (C) {
36 *Off = C.tell();
37 return {Length, Format};
39 if (Err)
40 *Err = C.takeError();
41 else
42 consumeError(C.takeError());
43 return {0, dwarf::DWARF32};
46 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
47 uint64_t *SecNdx,
48 Error *Err) const {
49 if (SecNdx)
50 *SecNdx = object::SectionedAddress::UndefSection;
51 if (!Section)
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))
58 return LocData;
59 if (SecNdx)
60 *SecNdx = E->SectionIndex;
62 uint64_t R =
63 object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData);
64 if (E->Reloc2)
65 R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R);
66 return R;
69 Optional<uint64_t>
70 DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
71 uint64_t PCRelOffset) const {
72 if (Encoding == dwarf::DW_EH_PE_omit)
73 return None;
75 uint64_t Result = 0;
76 uint64_t OldOffset = *Offset;
77 // First get value
78 switch (Encoding & 0x0F) {
79 case dwarf::DW_EH_PE_absptr:
80 switch (getAddressSize()) {
81 case 2:
82 case 4:
83 case 8:
84 Result = getUnsigned(Offset, getAddressSize());
85 break;
86 default:
87 return None;
89 break;
90 case dwarf::DW_EH_PE_uleb128:
91 Result = getULEB128(Offset);
92 break;
93 case dwarf::DW_EH_PE_sleb128:
94 Result = getSLEB128(Offset);
95 break;
96 case dwarf::DW_EH_PE_udata2:
97 Result = getUnsigned(Offset, 2);
98 break;
99 case dwarf::DW_EH_PE_udata4:
100 Result = getUnsigned(Offset, 4);
101 break;
102 case dwarf::DW_EH_PE_udata8:
103 Result = getUnsigned(Offset, 8);
104 break;
105 case dwarf::DW_EH_PE_sdata2:
106 Result = getSigned(Offset, 2);
107 break;
108 case dwarf::DW_EH_PE_sdata4:
109 Result = SignExtend64<32>(getRelocatedValue(4, Offset));
110 break;
111 case dwarf::DW_EH_PE_sdata8:
112 Result = getRelocatedValue(8, Offset);
113 break;
114 default:
115 return None;
117 // Then add relative offset, if required
118 switch (Encoding & 0x70) {
119 case dwarf::DW_EH_PE_absptr:
120 // do nothing
121 break;
122 case dwarf::DW_EH_PE_pcrel:
123 Result += PCRelOffset;
124 break;
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:
129 default:
130 *Offset = OldOffset;
131 return None;
134 return Result;