1*9880d681SAndroid Build Coastguard Worker //===-- DWARFFormValue.cpp ------------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "SyntaxHighlighting.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringRef.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFContext.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Dwarf.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
20*9880d681SAndroid Build Coastguard Worker #include <cassert>
21*9880d681SAndroid Build Coastguard Worker #include <limits>
22*9880d681SAndroid Build Coastguard Worker using namespace llvm;
23*9880d681SAndroid Build Coastguard Worker using namespace dwarf;
24*9880d681SAndroid Build Coastguard Worker using namespace syntax;
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker namespace {
getRefAddrSize(uint8_t AddrSize,uint16_t Version)27*9880d681SAndroid Build Coastguard Worker uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
28*9880d681SAndroid Build Coastguard Worker // FIXME: Support DWARF64.
29*9880d681SAndroid Build Coastguard Worker return (Version == 2) ? AddrSize : 4;
30*9880d681SAndroid Build Coastguard Worker }
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker template <uint8_t AddrSize, uint8_t RefAddrSize>
makeFixedFormSizesArrayRef()33*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> makeFixedFormSizesArrayRef() {
34*9880d681SAndroid Build Coastguard Worker static const uint8_t sizes[] = {
35*9880d681SAndroid Build Coastguard Worker 0, // 0x00 unused
36*9880d681SAndroid Build Coastguard Worker AddrSize, // 0x01 DW_FORM_addr
37*9880d681SAndroid Build Coastguard Worker 0, // 0x02 unused
38*9880d681SAndroid Build Coastguard Worker 0, // 0x03 DW_FORM_block2
39*9880d681SAndroid Build Coastguard Worker 0, // 0x04 DW_FORM_block4
40*9880d681SAndroid Build Coastguard Worker 2, // 0x05 DW_FORM_data2
41*9880d681SAndroid Build Coastguard Worker 4, // 0x06 DW_FORM_data4
42*9880d681SAndroid Build Coastguard Worker 8, // 0x07 DW_FORM_data8
43*9880d681SAndroid Build Coastguard Worker 0, // 0x08 DW_FORM_string
44*9880d681SAndroid Build Coastguard Worker 0, // 0x09 DW_FORM_block
45*9880d681SAndroid Build Coastguard Worker 0, // 0x0a DW_FORM_block1
46*9880d681SAndroid Build Coastguard Worker 1, // 0x0b DW_FORM_data1
47*9880d681SAndroid Build Coastguard Worker 1, // 0x0c DW_FORM_flag
48*9880d681SAndroid Build Coastguard Worker 0, // 0x0d DW_FORM_sdata
49*9880d681SAndroid Build Coastguard Worker 4, // 0x0e DW_FORM_strp
50*9880d681SAndroid Build Coastguard Worker 0, // 0x0f DW_FORM_udata
51*9880d681SAndroid Build Coastguard Worker RefAddrSize, // 0x10 DW_FORM_ref_addr
52*9880d681SAndroid Build Coastguard Worker 1, // 0x11 DW_FORM_ref1
53*9880d681SAndroid Build Coastguard Worker 2, // 0x12 DW_FORM_ref2
54*9880d681SAndroid Build Coastguard Worker 4, // 0x13 DW_FORM_ref4
55*9880d681SAndroid Build Coastguard Worker 8, // 0x14 DW_FORM_ref8
56*9880d681SAndroid Build Coastguard Worker 0, // 0x15 DW_FORM_ref_udata
57*9880d681SAndroid Build Coastguard Worker 0, // 0x16 DW_FORM_indirect
58*9880d681SAndroid Build Coastguard Worker 4, // 0x17 DW_FORM_sec_offset
59*9880d681SAndroid Build Coastguard Worker 0, // 0x18 DW_FORM_exprloc
60*9880d681SAndroid Build Coastguard Worker 0, // 0x19 DW_FORM_flag_present
61*9880d681SAndroid Build Coastguard Worker };
62*9880d681SAndroid Build Coastguard Worker return makeArrayRef(sizes);
63*9880d681SAndroid Build Coastguard Worker }
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker
getFixedFormSizes(uint8_t AddrSize,uint16_t Version)66*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> DWARFFormValue::getFixedFormSizes(uint8_t AddrSize,
67*9880d681SAndroid Build Coastguard Worker uint16_t Version) {
68*9880d681SAndroid Build Coastguard Worker uint8_t RefAddrSize = getRefAddrSize(AddrSize, Version);
69*9880d681SAndroid Build Coastguard Worker if (AddrSize == 4 && RefAddrSize == 4)
70*9880d681SAndroid Build Coastguard Worker return makeFixedFormSizesArrayRef<4, 4>();
71*9880d681SAndroid Build Coastguard Worker if (AddrSize == 4 && RefAddrSize == 8)
72*9880d681SAndroid Build Coastguard Worker return makeFixedFormSizesArrayRef<4, 8>();
73*9880d681SAndroid Build Coastguard Worker if (AddrSize == 8 && RefAddrSize == 4)
74*9880d681SAndroid Build Coastguard Worker return makeFixedFormSizesArrayRef<8, 4>();
75*9880d681SAndroid Build Coastguard Worker if (AddrSize == 8 && RefAddrSize == 8)
76*9880d681SAndroid Build Coastguard Worker return makeFixedFormSizesArrayRef<8, 8>();
77*9880d681SAndroid Build Coastguard Worker return None;
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker static const DWARFFormValue::FormClass DWARF4FormClasses[] = {
81*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Unknown, // 0x0
82*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr
83*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Unknown, // 0x02 unused
84*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2
85*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4
86*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
87*9880d681SAndroid Build Coastguard Worker // --- These can be FC_SectionOffset in DWARF3 and below:
88*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
89*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
90*9880d681SAndroid Build Coastguard Worker // ---
91*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_String, // 0x08 DW_FORM_string
92*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Block, // 0x09 DW_FORM_block
93*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1
94*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1
95*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag
96*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata
97*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_String, // 0x0e DW_FORM_strp
98*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata
99*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr
100*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1
101*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2
102*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4
103*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8
104*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata
105*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect
106*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
107*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc
108*9880d681SAndroid Build Coastguard Worker DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
109*9880d681SAndroid Build Coastguard Worker };
110*9880d681SAndroid Build Coastguard Worker
isFormClass(DWARFFormValue::FormClass FC) const111*9880d681SAndroid Build Coastguard Worker bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
112*9880d681SAndroid Build Coastguard Worker // First, check DWARF4 form classes.
113*9880d681SAndroid Build Coastguard Worker if (Form < makeArrayRef(DWARF4FormClasses).size() &&
114*9880d681SAndroid Build Coastguard Worker DWARF4FormClasses[Form] == FC)
115*9880d681SAndroid Build Coastguard Worker return true;
116*9880d681SAndroid Build Coastguard Worker // Check more forms from DWARF4 and DWARF5 proposals.
117*9880d681SAndroid Build Coastguard Worker switch (Form) {
118*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_sig8:
119*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_ref_alt:
120*9880d681SAndroid Build Coastguard Worker return (FC == FC_Reference);
121*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_addr_index:
122*9880d681SAndroid Build Coastguard Worker return (FC == FC_Address);
123*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_str_index:
124*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_strp_alt:
125*9880d681SAndroid Build Coastguard Worker return (FC == FC_String);
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
128*9880d681SAndroid Build Coastguard Worker // Don't check for DWARF version here, as some producers may still do this
129*9880d681SAndroid Build Coastguard Worker // by mistake.
130*9880d681SAndroid Build Coastguard Worker return (Form == DW_FORM_data4 || Form == DW_FORM_data8) &&
131*9880d681SAndroid Build Coastguard Worker FC == FC_SectionOffset;
132*9880d681SAndroid Build Coastguard Worker }
133*9880d681SAndroid Build Coastguard Worker
extractValue(DataExtractor data,uint32_t * offset_ptr,const DWARFUnit * cu)134*9880d681SAndroid Build Coastguard Worker bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
135*9880d681SAndroid Build Coastguard Worker const DWARFUnit *cu) {
136*9880d681SAndroid Build Coastguard Worker bool indirect = false;
137*9880d681SAndroid Build Coastguard Worker bool is_block = false;
138*9880d681SAndroid Build Coastguard Worker Value.data = nullptr;
139*9880d681SAndroid Build Coastguard Worker // Read the value for the form into value and follow and DW_FORM_indirect
140*9880d681SAndroid Build Coastguard Worker // instances we run into
141*9880d681SAndroid Build Coastguard Worker do {
142*9880d681SAndroid Build Coastguard Worker indirect = false;
143*9880d681SAndroid Build Coastguard Worker switch (Form) {
144*9880d681SAndroid Build Coastguard Worker case DW_FORM_addr:
145*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_addr: {
146*9880d681SAndroid Build Coastguard Worker if (!cu)
147*9880d681SAndroid Build Coastguard Worker return false;
148*9880d681SAndroid Build Coastguard Worker uint16_t AddrSize =
149*9880d681SAndroid Build Coastguard Worker (Form == DW_FORM_addr)
150*9880d681SAndroid Build Coastguard Worker ? cu->getAddressByteSize()
151*9880d681SAndroid Build Coastguard Worker : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
152*9880d681SAndroid Build Coastguard Worker RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
153*9880d681SAndroid Build Coastguard Worker if (AI != cu->getRelocMap()->end()) {
154*9880d681SAndroid Build Coastguard Worker const std::pair<uint8_t, int64_t> &R = AI->second;
155*9880d681SAndroid Build Coastguard Worker Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second;
156*9880d681SAndroid Build Coastguard Worker } else
157*9880d681SAndroid Build Coastguard Worker Value.uval = data.getUnsigned(offset_ptr, AddrSize);
158*9880d681SAndroid Build Coastguard Worker break;
159*9880d681SAndroid Build Coastguard Worker }
160*9880d681SAndroid Build Coastguard Worker case DW_FORM_exprloc:
161*9880d681SAndroid Build Coastguard Worker case DW_FORM_block:
162*9880d681SAndroid Build Coastguard Worker Value.uval = data.getULEB128(offset_ptr);
163*9880d681SAndroid Build Coastguard Worker is_block = true;
164*9880d681SAndroid Build Coastguard Worker break;
165*9880d681SAndroid Build Coastguard Worker case DW_FORM_block1:
166*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU8(offset_ptr);
167*9880d681SAndroid Build Coastguard Worker is_block = true;
168*9880d681SAndroid Build Coastguard Worker break;
169*9880d681SAndroid Build Coastguard Worker case DW_FORM_block2:
170*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU16(offset_ptr);
171*9880d681SAndroid Build Coastguard Worker is_block = true;
172*9880d681SAndroid Build Coastguard Worker break;
173*9880d681SAndroid Build Coastguard Worker case DW_FORM_block4:
174*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU32(offset_ptr);
175*9880d681SAndroid Build Coastguard Worker is_block = true;
176*9880d681SAndroid Build Coastguard Worker break;
177*9880d681SAndroid Build Coastguard Worker case DW_FORM_data1:
178*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref1:
179*9880d681SAndroid Build Coastguard Worker case DW_FORM_flag:
180*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU8(offset_ptr);
181*9880d681SAndroid Build Coastguard Worker break;
182*9880d681SAndroid Build Coastguard Worker case DW_FORM_data2:
183*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref2:
184*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU16(offset_ptr);
185*9880d681SAndroid Build Coastguard Worker break;
186*9880d681SAndroid Build Coastguard Worker case DW_FORM_data4:
187*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref4: {
188*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU32(offset_ptr);
189*9880d681SAndroid Build Coastguard Worker if (!cu)
190*9880d681SAndroid Build Coastguard Worker break;
191*9880d681SAndroid Build Coastguard Worker RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
192*9880d681SAndroid Build Coastguard Worker if (AI != cu->getRelocMap()->end())
193*9880d681SAndroid Build Coastguard Worker Value.uval += AI->second.second;
194*9880d681SAndroid Build Coastguard Worker break;
195*9880d681SAndroid Build Coastguard Worker }
196*9880d681SAndroid Build Coastguard Worker case DW_FORM_data8:
197*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref8:
198*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU64(offset_ptr);
199*9880d681SAndroid Build Coastguard Worker break;
200*9880d681SAndroid Build Coastguard Worker case DW_FORM_sdata:
201*9880d681SAndroid Build Coastguard Worker Value.sval = data.getSLEB128(offset_ptr);
202*9880d681SAndroid Build Coastguard Worker break;
203*9880d681SAndroid Build Coastguard Worker case DW_FORM_udata:
204*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_udata:
205*9880d681SAndroid Build Coastguard Worker Value.uval = data.getULEB128(offset_ptr);
206*9880d681SAndroid Build Coastguard Worker break;
207*9880d681SAndroid Build Coastguard Worker case DW_FORM_string:
208*9880d681SAndroid Build Coastguard Worker Value.cstr = data.getCStr(offset_ptr);
209*9880d681SAndroid Build Coastguard Worker break;
210*9880d681SAndroid Build Coastguard Worker case DW_FORM_indirect:
211*9880d681SAndroid Build Coastguard Worker Form = data.getULEB128(offset_ptr);
212*9880d681SAndroid Build Coastguard Worker indirect = true;
213*9880d681SAndroid Build Coastguard Worker break;
214*9880d681SAndroid Build Coastguard Worker case DW_FORM_sec_offset:
215*9880d681SAndroid Build Coastguard Worker case DW_FORM_strp:
216*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_ref_alt:
217*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_strp_alt: {
218*9880d681SAndroid Build Coastguard Worker // FIXME: This is 64-bit for DWARF64.
219*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU32(offset_ptr);
220*9880d681SAndroid Build Coastguard Worker if (!cu)
221*9880d681SAndroid Build Coastguard Worker break;
222*9880d681SAndroid Build Coastguard Worker RelocAddrMap::const_iterator AI =
223*9880d681SAndroid Build Coastguard Worker cu->getRelocMap()->find(*offset_ptr - 4);
224*9880d681SAndroid Build Coastguard Worker if (AI != cu->getRelocMap()->end())
225*9880d681SAndroid Build Coastguard Worker Value.uval += AI->second.second;
226*9880d681SAndroid Build Coastguard Worker break;
227*9880d681SAndroid Build Coastguard Worker }
228*9880d681SAndroid Build Coastguard Worker case DW_FORM_flag_present:
229*9880d681SAndroid Build Coastguard Worker Value.uval = 1;
230*9880d681SAndroid Build Coastguard Worker break;
231*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_sig8:
232*9880d681SAndroid Build Coastguard Worker Value.uval = data.getU64(offset_ptr);
233*9880d681SAndroid Build Coastguard Worker break;
234*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_addr_index:
235*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_str_index:
236*9880d681SAndroid Build Coastguard Worker Value.uval = data.getULEB128(offset_ptr);
237*9880d681SAndroid Build Coastguard Worker break;
238*9880d681SAndroid Build Coastguard Worker default:
239*9880d681SAndroid Build Coastguard Worker return false;
240*9880d681SAndroid Build Coastguard Worker }
241*9880d681SAndroid Build Coastguard Worker } while (indirect);
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker if (is_block) {
244*9880d681SAndroid Build Coastguard Worker StringRef str = data.getData().substr(*offset_ptr, Value.uval);
245*9880d681SAndroid Build Coastguard Worker Value.data = nullptr;
246*9880d681SAndroid Build Coastguard Worker if (!str.empty()) {
247*9880d681SAndroid Build Coastguard Worker Value.data = reinterpret_cast<const uint8_t *>(str.data());
248*9880d681SAndroid Build Coastguard Worker *offset_ptr += Value.uval;
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker }
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker return true;
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker bool
skipValue(DataExtractor debug_info_data,uint32_t * offset_ptr,const DWARFUnit * cu) const256*9880d681SAndroid Build Coastguard Worker DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
257*9880d681SAndroid Build Coastguard Worker const DWARFUnit *cu) const {
258*9880d681SAndroid Build Coastguard Worker return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker bool
skipValue(uint16_t form,DataExtractor debug_info_data,uint32_t * offset_ptr,const DWARFUnit * cu)262*9880d681SAndroid Build Coastguard Worker DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
263*9880d681SAndroid Build Coastguard Worker uint32_t *offset_ptr, const DWARFUnit *cu) {
264*9880d681SAndroid Build Coastguard Worker return skipValue(form, debug_info_data, offset_ptr, cu->getVersion(),
265*9880d681SAndroid Build Coastguard Worker cu->getAddressByteSize());
266*9880d681SAndroid Build Coastguard Worker }
skipValue(uint16_t form,DataExtractor debug_info_data,uint32_t * offset_ptr,uint16_t Version,uint8_t AddrSize)267*9880d681SAndroid Build Coastguard Worker bool DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
268*9880d681SAndroid Build Coastguard Worker uint32_t *offset_ptr, uint16_t Version,
269*9880d681SAndroid Build Coastguard Worker uint8_t AddrSize) {
270*9880d681SAndroid Build Coastguard Worker bool indirect = false;
271*9880d681SAndroid Build Coastguard Worker do {
272*9880d681SAndroid Build Coastguard Worker switch (form) {
273*9880d681SAndroid Build Coastguard Worker // Blocks if inlined data that have a length field and the data bytes
274*9880d681SAndroid Build Coastguard Worker // inlined in the .debug_info
275*9880d681SAndroid Build Coastguard Worker case DW_FORM_exprloc:
276*9880d681SAndroid Build Coastguard Worker case DW_FORM_block: {
277*9880d681SAndroid Build Coastguard Worker uint64_t size = debug_info_data.getULEB128(offset_ptr);
278*9880d681SAndroid Build Coastguard Worker *offset_ptr += size;
279*9880d681SAndroid Build Coastguard Worker return true;
280*9880d681SAndroid Build Coastguard Worker }
281*9880d681SAndroid Build Coastguard Worker case DW_FORM_block1: {
282*9880d681SAndroid Build Coastguard Worker uint8_t size = debug_info_data.getU8(offset_ptr);
283*9880d681SAndroid Build Coastguard Worker *offset_ptr += size;
284*9880d681SAndroid Build Coastguard Worker return true;
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker case DW_FORM_block2: {
287*9880d681SAndroid Build Coastguard Worker uint16_t size = debug_info_data.getU16(offset_ptr);
288*9880d681SAndroid Build Coastguard Worker *offset_ptr += size;
289*9880d681SAndroid Build Coastguard Worker return true;
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker case DW_FORM_block4: {
292*9880d681SAndroid Build Coastguard Worker uint32_t size = debug_info_data.getU32(offset_ptr);
293*9880d681SAndroid Build Coastguard Worker *offset_ptr += size;
294*9880d681SAndroid Build Coastguard Worker return true;
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker // Inlined NULL terminated C-strings
298*9880d681SAndroid Build Coastguard Worker case DW_FORM_string:
299*9880d681SAndroid Build Coastguard Worker debug_info_data.getCStr(offset_ptr);
300*9880d681SAndroid Build Coastguard Worker return true;
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker // Compile unit address sized values
303*9880d681SAndroid Build Coastguard Worker case DW_FORM_addr:
304*9880d681SAndroid Build Coastguard Worker *offset_ptr += AddrSize;
305*9880d681SAndroid Build Coastguard Worker return true;
306*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_addr:
307*9880d681SAndroid Build Coastguard Worker *offset_ptr += getRefAddrSize(AddrSize, Version);
308*9880d681SAndroid Build Coastguard Worker return true;
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Worker // 0 byte values - implied from the form.
311*9880d681SAndroid Build Coastguard Worker case DW_FORM_flag_present:
312*9880d681SAndroid Build Coastguard Worker return true;
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker // 1 byte values
315*9880d681SAndroid Build Coastguard Worker case DW_FORM_data1:
316*9880d681SAndroid Build Coastguard Worker case DW_FORM_flag:
317*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref1:
318*9880d681SAndroid Build Coastguard Worker *offset_ptr += 1;
319*9880d681SAndroid Build Coastguard Worker return true;
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker // 2 byte values
322*9880d681SAndroid Build Coastguard Worker case DW_FORM_data2:
323*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref2:
324*9880d681SAndroid Build Coastguard Worker *offset_ptr += 2;
325*9880d681SAndroid Build Coastguard Worker return true;
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker // 4 byte values
328*9880d681SAndroid Build Coastguard Worker case DW_FORM_data4:
329*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref4:
330*9880d681SAndroid Build Coastguard Worker *offset_ptr += 4;
331*9880d681SAndroid Build Coastguard Worker return true;
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker // 8 byte values
334*9880d681SAndroid Build Coastguard Worker case DW_FORM_data8:
335*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref8:
336*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_sig8:
337*9880d681SAndroid Build Coastguard Worker *offset_ptr += 8;
338*9880d681SAndroid Build Coastguard Worker return true;
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker // signed or unsigned LEB 128 values
341*9880d681SAndroid Build Coastguard Worker // case DW_FORM_APPLE_db_str:
342*9880d681SAndroid Build Coastguard Worker case DW_FORM_sdata:
343*9880d681SAndroid Build Coastguard Worker case DW_FORM_udata:
344*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_udata:
345*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_str_index:
346*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_addr_index:
347*9880d681SAndroid Build Coastguard Worker debug_info_data.getULEB128(offset_ptr);
348*9880d681SAndroid Build Coastguard Worker return true;
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker case DW_FORM_indirect:
351*9880d681SAndroid Build Coastguard Worker indirect = true;
352*9880d681SAndroid Build Coastguard Worker form = debug_info_data.getULEB128(offset_ptr);
353*9880d681SAndroid Build Coastguard Worker break;
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker // FIXME: 4 for DWARF32, 8 for DWARF64.
356*9880d681SAndroid Build Coastguard Worker case DW_FORM_sec_offset:
357*9880d681SAndroid Build Coastguard Worker case DW_FORM_strp:
358*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_ref_alt:
359*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_strp_alt:
360*9880d681SAndroid Build Coastguard Worker *offset_ptr += 4;
361*9880d681SAndroid Build Coastguard Worker return true;
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker default:
364*9880d681SAndroid Build Coastguard Worker return false;
365*9880d681SAndroid Build Coastguard Worker }
366*9880d681SAndroid Build Coastguard Worker } while (indirect);
367*9880d681SAndroid Build Coastguard Worker return true;
368*9880d681SAndroid Build Coastguard Worker }
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker void
dump(raw_ostream & OS,const DWARFUnit * cu) const371*9880d681SAndroid Build Coastguard Worker DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
372*9880d681SAndroid Build Coastguard Worker uint64_t uvalue = Value.uval;
373*9880d681SAndroid Build Coastguard Worker bool cu_relative_offset = false;
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker switch (Form) {
376*9880d681SAndroid Build Coastguard Worker case DW_FORM_addr: OS << format("0x%016" PRIx64, uvalue); break;
377*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_addr_index: {
378*9880d681SAndroid Build Coastguard Worker OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
379*9880d681SAndroid Build Coastguard Worker uint64_t Address;
380*9880d681SAndroid Build Coastguard Worker if (cu->getAddrOffsetSectionItem(uvalue, Address))
381*9880d681SAndroid Build Coastguard Worker OS << format("0x%016" PRIx64, Address);
382*9880d681SAndroid Build Coastguard Worker else
383*9880d681SAndroid Build Coastguard Worker OS << "<no .debug_addr section>";
384*9880d681SAndroid Build Coastguard Worker break;
385*9880d681SAndroid Build Coastguard Worker }
386*9880d681SAndroid Build Coastguard Worker case DW_FORM_flag_present: OS << "true"; break;
387*9880d681SAndroid Build Coastguard Worker case DW_FORM_flag:
388*9880d681SAndroid Build Coastguard Worker case DW_FORM_data1: OS << format("0x%02x", (uint8_t)uvalue); break;
389*9880d681SAndroid Build Coastguard Worker case DW_FORM_data2: OS << format("0x%04x", (uint16_t)uvalue); break;
390*9880d681SAndroid Build Coastguard Worker case DW_FORM_data4: OS << format("0x%08x", (uint32_t)uvalue); break;
391*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_sig8:
392*9880d681SAndroid Build Coastguard Worker case DW_FORM_data8: OS << format("0x%016" PRIx64, uvalue); break;
393*9880d681SAndroid Build Coastguard Worker case DW_FORM_string:
394*9880d681SAndroid Build Coastguard Worker OS << '"';
395*9880d681SAndroid Build Coastguard Worker OS.write_escaped(Value.cstr);
396*9880d681SAndroid Build Coastguard Worker OS << '"';
397*9880d681SAndroid Build Coastguard Worker break;
398*9880d681SAndroid Build Coastguard Worker case DW_FORM_exprloc:
399*9880d681SAndroid Build Coastguard Worker case DW_FORM_block:
400*9880d681SAndroid Build Coastguard Worker case DW_FORM_block1:
401*9880d681SAndroid Build Coastguard Worker case DW_FORM_block2:
402*9880d681SAndroid Build Coastguard Worker case DW_FORM_block4:
403*9880d681SAndroid Build Coastguard Worker if (uvalue > 0) {
404*9880d681SAndroid Build Coastguard Worker switch (Form) {
405*9880d681SAndroid Build Coastguard Worker case DW_FORM_exprloc:
406*9880d681SAndroid Build Coastguard Worker case DW_FORM_block: OS << format("<0x%" PRIx64 "> ", uvalue); break;
407*9880d681SAndroid Build Coastguard Worker case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue); break;
408*9880d681SAndroid Build Coastguard Worker case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
409*9880d681SAndroid Build Coastguard Worker case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
410*9880d681SAndroid Build Coastguard Worker default: break;
411*9880d681SAndroid Build Coastguard Worker }
412*9880d681SAndroid Build Coastguard Worker
413*9880d681SAndroid Build Coastguard Worker const uint8_t* data_ptr = Value.data;
414*9880d681SAndroid Build Coastguard Worker if (data_ptr) {
415*9880d681SAndroid Build Coastguard Worker // uvalue contains size of block
416*9880d681SAndroid Build Coastguard Worker const uint8_t* end_data_ptr = data_ptr + uvalue;
417*9880d681SAndroid Build Coastguard Worker while (data_ptr < end_data_ptr) {
418*9880d681SAndroid Build Coastguard Worker OS << format("%2.2x ", *data_ptr);
419*9880d681SAndroid Build Coastguard Worker ++data_ptr;
420*9880d681SAndroid Build Coastguard Worker }
421*9880d681SAndroid Build Coastguard Worker }
422*9880d681SAndroid Build Coastguard Worker else
423*9880d681SAndroid Build Coastguard Worker OS << "NULL";
424*9880d681SAndroid Build Coastguard Worker }
425*9880d681SAndroid Build Coastguard Worker break;
426*9880d681SAndroid Build Coastguard Worker
427*9880d681SAndroid Build Coastguard Worker case DW_FORM_sdata: OS << Value.sval; break;
428*9880d681SAndroid Build Coastguard Worker case DW_FORM_udata: OS << Value.uval; break;
429*9880d681SAndroid Build Coastguard Worker case DW_FORM_strp: {
430*9880d681SAndroid Build Coastguard Worker OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
431*9880d681SAndroid Build Coastguard Worker dumpString(OS, cu);
432*9880d681SAndroid Build Coastguard Worker break;
433*9880d681SAndroid Build Coastguard Worker }
434*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_str_index: {
435*9880d681SAndroid Build Coastguard Worker OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
436*9880d681SAndroid Build Coastguard Worker dumpString(OS, cu);
437*9880d681SAndroid Build Coastguard Worker break;
438*9880d681SAndroid Build Coastguard Worker }
439*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_strp_alt: {
440*9880d681SAndroid Build Coastguard Worker OS << format("alt indirect string, offset: 0x%" PRIx64 "", uvalue);
441*9880d681SAndroid Build Coastguard Worker dumpString(OS, cu);
442*9880d681SAndroid Build Coastguard Worker break;
443*9880d681SAndroid Build Coastguard Worker }
444*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_addr:
445*9880d681SAndroid Build Coastguard Worker OS << format("0x%016" PRIx64, uvalue);
446*9880d681SAndroid Build Coastguard Worker break;
447*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref1:
448*9880d681SAndroid Build Coastguard Worker cu_relative_offset = true;
449*9880d681SAndroid Build Coastguard Worker OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
450*9880d681SAndroid Build Coastguard Worker break;
451*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref2:
452*9880d681SAndroid Build Coastguard Worker cu_relative_offset = true;
453*9880d681SAndroid Build Coastguard Worker OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
454*9880d681SAndroid Build Coastguard Worker break;
455*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref4:
456*9880d681SAndroid Build Coastguard Worker cu_relative_offset = true;
457*9880d681SAndroid Build Coastguard Worker OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
458*9880d681SAndroid Build Coastguard Worker break;
459*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref8:
460*9880d681SAndroid Build Coastguard Worker cu_relative_offset = true;
461*9880d681SAndroid Build Coastguard Worker OS << format("cu + 0x%8.8" PRIx64, uvalue);
462*9880d681SAndroid Build Coastguard Worker break;
463*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_udata:
464*9880d681SAndroid Build Coastguard Worker cu_relative_offset = true;
465*9880d681SAndroid Build Coastguard Worker OS << format("cu + 0x%" PRIx64, uvalue);
466*9880d681SAndroid Build Coastguard Worker break;
467*9880d681SAndroid Build Coastguard Worker case DW_FORM_GNU_ref_alt:
468*9880d681SAndroid Build Coastguard Worker OS << format("<alt 0x%" PRIx64 ">", uvalue);
469*9880d681SAndroid Build Coastguard Worker break;
470*9880d681SAndroid Build Coastguard Worker
471*9880d681SAndroid Build Coastguard Worker // All DW_FORM_indirect attributes should be resolved prior to calling
472*9880d681SAndroid Build Coastguard Worker // this function
473*9880d681SAndroid Build Coastguard Worker case DW_FORM_indirect:
474*9880d681SAndroid Build Coastguard Worker OS << "DW_FORM_indirect";
475*9880d681SAndroid Build Coastguard Worker break;
476*9880d681SAndroid Build Coastguard Worker
477*9880d681SAndroid Build Coastguard Worker // Should be formatted to 64-bit for DWARF64.
478*9880d681SAndroid Build Coastguard Worker case DW_FORM_sec_offset:
479*9880d681SAndroid Build Coastguard Worker OS << format("0x%08x", (uint32_t)uvalue);
480*9880d681SAndroid Build Coastguard Worker break;
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Worker default:
483*9880d681SAndroid Build Coastguard Worker OS << format("DW_FORM(0x%4.4x)", Form);
484*9880d681SAndroid Build Coastguard Worker break;
485*9880d681SAndroid Build Coastguard Worker }
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Worker if (cu_relative_offset) {
488*9880d681SAndroid Build Coastguard Worker OS << " => {";
489*9880d681SAndroid Build Coastguard Worker WithColor(OS, syntax::Address).get()
490*9880d681SAndroid Build Coastguard Worker << format("0x%8.8" PRIx64, uvalue + (cu ? cu->getOffset() : 0));
491*9880d681SAndroid Build Coastguard Worker OS << "}";
492*9880d681SAndroid Build Coastguard Worker }
493*9880d681SAndroid Build Coastguard Worker }
494*9880d681SAndroid Build Coastguard Worker
dumpString(raw_ostream & OS,const DWARFUnit * U) const495*9880d681SAndroid Build Coastguard Worker void DWARFFormValue::dumpString(raw_ostream &OS, const DWARFUnit *U) const {
496*9880d681SAndroid Build Coastguard Worker Optional<const char *> DbgStr = getAsCString(U);
497*9880d681SAndroid Build Coastguard Worker if (DbgStr.hasValue()) {
498*9880d681SAndroid Build Coastguard Worker raw_ostream &COS = WithColor(OS, syntax::String);
499*9880d681SAndroid Build Coastguard Worker COS << '"';
500*9880d681SAndroid Build Coastguard Worker COS.write_escaped(DbgStr.getValue());
501*9880d681SAndroid Build Coastguard Worker COS << '"';
502*9880d681SAndroid Build Coastguard Worker }
503*9880d681SAndroid Build Coastguard Worker }
504*9880d681SAndroid Build Coastguard Worker
getAsCString(const DWARFUnit * U) const505*9880d681SAndroid Build Coastguard Worker Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const {
506*9880d681SAndroid Build Coastguard Worker if (!isFormClass(FC_String))
507*9880d681SAndroid Build Coastguard Worker return None;
508*9880d681SAndroid Build Coastguard Worker if (Form == DW_FORM_string)
509*9880d681SAndroid Build Coastguard Worker return Value.cstr;
510*9880d681SAndroid Build Coastguard Worker // FIXME: Add support for DW_FORM_GNU_strp_alt
511*9880d681SAndroid Build Coastguard Worker if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
512*9880d681SAndroid Build Coastguard Worker return None;
513*9880d681SAndroid Build Coastguard Worker uint32_t Offset = Value.uval;
514*9880d681SAndroid Build Coastguard Worker if (Form == DW_FORM_GNU_str_index) {
515*9880d681SAndroid Build Coastguard Worker uint32_t StrOffset;
516*9880d681SAndroid Build Coastguard Worker if (!U->getStringOffsetSectionItem(Offset, StrOffset))
517*9880d681SAndroid Build Coastguard Worker return None;
518*9880d681SAndroid Build Coastguard Worker Offset = StrOffset;
519*9880d681SAndroid Build Coastguard Worker }
520*9880d681SAndroid Build Coastguard Worker if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
521*9880d681SAndroid Build Coastguard Worker return Str;
522*9880d681SAndroid Build Coastguard Worker }
523*9880d681SAndroid Build Coastguard Worker return None;
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker
getAsAddress(const DWARFUnit * U) const526*9880d681SAndroid Build Coastguard Worker Optional<uint64_t> DWARFFormValue::getAsAddress(const DWARFUnit *U) const {
527*9880d681SAndroid Build Coastguard Worker if (!isFormClass(FC_Address))
528*9880d681SAndroid Build Coastguard Worker return None;
529*9880d681SAndroid Build Coastguard Worker if (Form == DW_FORM_GNU_addr_index) {
530*9880d681SAndroid Build Coastguard Worker uint32_t Index = Value.uval;
531*9880d681SAndroid Build Coastguard Worker uint64_t Result;
532*9880d681SAndroid Build Coastguard Worker if (!U || !U->getAddrOffsetSectionItem(Index, Result))
533*9880d681SAndroid Build Coastguard Worker return None;
534*9880d681SAndroid Build Coastguard Worker return Result;
535*9880d681SAndroid Build Coastguard Worker }
536*9880d681SAndroid Build Coastguard Worker return Value.uval;
537*9880d681SAndroid Build Coastguard Worker }
538*9880d681SAndroid Build Coastguard Worker
getAsReference(const DWARFUnit * U) const539*9880d681SAndroid Build Coastguard Worker Optional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const {
540*9880d681SAndroid Build Coastguard Worker if (!isFormClass(FC_Reference))
541*9880d681SAndroid Build Coastguard Worker return None;
542*9880d681SAndroid Build Coastguard Worker switch (Form) {
543*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref1:
544*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref2:
545*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref4:
546*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref8:
547*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_udata:
548*9880d681SAndroid Build Coastguard Worker if (!U)
549*9880d681SAndroid Build Coastguard Worker return None;
550*9880d681SAndroid Build Coastguard Worker return Value.uval + U->getOffset();
551*9880d681SAndroid Build Coastguard Worker case DW_FORM_ref_addr:
552*9880d681SAndroid Build Coastguard Worker return Value.uval;
553*9880d681SAndroid Build Coastguard Worker // FIXME: Add proper support for DW_FORM_ref_sig8 and DW_FORM_GNU_ref_alt.
554*9880d681SAndroid Build Coastguard Worker default:
555*9880d681SAndroid Build Coastguard Worker return None;
556*9880d681SAndroid Build Coastguard Worker }
557*9880d681SAndroid Build Coastguard Worker }
558*9880d681SAndroid Build Coastguard Worker
getAsSectionOffset() const559*9880d681SAndroid Build Coastguard Worker Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
560*9880d681SAndroid Build Coastguard Worker if (!isFormClass(FC_SectionOffset))
561*9880d681SAndroid Build Coastguard Worker return None;
562*9880d681SAndroid Build Coastguard Worker return Value.uval;
563*9880d681SAndroid Build Coastguard Worker }
564*9880d681SAndroid Build Coastguard Worker
getAsUnsignedConstant() const565*9880d681SAndroid Build Coastguard Worker Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
566*9880d681SAndroid Build Coastguard Worker if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag))
567*9880d681SAndroid Build Coastguard Worker || Form == DW_FORM_sdata)
568*9880d681SAndroid Build Coastguard Worker return None;
569*9880d681SAndroid Build Coastguard Worker return Value.uval;
570*9880d681SAndroid Build Coastguard Worker }
571*9880d681SAndroid Build Coastguard Worker
getAsSignedConstant() const572*9880d681SAndroid Build Coastguard Worker Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
573*9880d681SAndroid Build Coastguard Worker if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
574*9880d681SAndroid Build Coastguard Worker (Form == DW_FORM_udata && uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
575*9880d681SAndroid Build Coastguard Worker return None;
576*9880d681SAndroid Build Coastguard Worker switch (Form) {
577*9880d681SAndroid Build Coastguard Worker case DW_FORM_data4:
578*9880d681SAndroid Build Coastguard Worker return int32_t(Value.uval);
579*9880d681SAndroid Build Coastguard Worker case DW_FORM_data2:
580*9880d681SAndroid Build Coastguard Worker return int16_t(Value.uval);
581*9880d681SAndroid Build Coastguard Worker case DW_FORM_data1:
582*9880d681SAndroid Build Coastguard Worker return int8_t(Value.uval);
583*9880d681SAndroid Build Coastguard Worker case DW_FORM_sdata:
584*9880d681SAndroid Build Coastguard Worker case DW_FORM_data8:
585*9880d681SAndroid Build Coastguard Worker default:
586*9880d681SAndroid Build Coastguard Worker return Value.sval;
587*9880d681SAndroid Build Coastguard Worker }
588*9880d681SAndroid Build Coastguard Worker }
589*9880d681SAndroid Build Coastguard Worker
getAsBlock() const590*9880d681SAndroid Build Coastguard Worker Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
591*9880d681SAndroid Build Coastguard Worker if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
592*9880d681SAndroid Build Coastguard Worker return None;
593*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Value.data, Value.uval);
594*9880d681SAndroid Build Coastguard Worker }
595*9880d681SAndroid Build Coastguard Worker
596