LLVM API Documentation

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