Add some basic support for the fission addr forms to DebugInfo.
[oota-llvm.git] / lib / DebugInfo / DWARFFormValue.cpp
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
10 #include "DWARFFormValue.h"
11 #include "DWARFCompileUnit.h"
12 #include "DWARFContext.h"
13 #include "llvm/Support/Debug.h"
14 #include "llvm/Support/Dwarf.h"
15 #include "llvm/Support/Format.h"
16 #include "llvm/Support/raw_ostream.h"
17 #include <cassert>
18 using namespace llvm;
19 using namespace dwarf;
20
21 static const uint8_t form_sizes_addr4[] = {
22   0, // 0x00 unused
23   4, // 0x01 DW_FORM_addr
24   0, // 0x02 unused
25   0, // 0x03 DW_FORM_block2
26   0, // 0x04 DW_FORM_block4
27   2, // 0x05 DW_FORM_data2
28   4, // 0x06 DW_FORM_data4
29   8, // 0x07 DW_FORM_data8
30   0, // 0x08 DW_FORM_string
31   0, // 0x09 DW_FORM_block
32   0, // 0x0a DW_FORM_block1
33   1, // 0x0b DW_FORM_data1
34   1, // 0x0c DW_FORM_flag
35   0, // 0x0d DW_FORM_sdata
36   4, // 0x0e DW_FORM_strp
37   0, // 0x0f DW_FORM_udata
38   4, // 0x10 DW_FORM_ref_addr
39   1, // 0x11 DW_FORM_ref1
40   2, // 0x12 DW_FORM_ref2
41   4, // 0x13 DW_FORM_ref4
42   8, // 0x14 DW_FORM_ref8
43   0, // 0x15 DW_FORM_ref_udata
44   0, // 0x16 DW_FORM_indirect
45   4, // 0x17 DW_FORM_sec_offset
46   0, // 0x18 DW_FORM_exprloc
47   0, // 0x19 DW_FORM_flag_present
48   8, // 0x20 DW_FORM_ref_sig8
49   4, // 0x1f01 DW_FORM_GNU_addr_index
50   4, // 0x1f02 DW_FORM_GNU_str_index
51 };
52
53 static const uint8_t form_sizes_addr8[] = {
54   0, // 0x00 unused
55   8, // 0x01 DW_FORM_addr
56   0, // 0x02 unused
57   0, // 0x03 DW_FORM_block2
58   0, // 0x04 DW_FORM_block4
59   2, // 0x05 DW_FORM_data2
60   4, // 0x06 DW_FORM_data4
61   8, // 0x07 DW_FORM_data8
62   0, // 0x08 DW_FORM_string
63   0, // 0x09 DW_FORM_block
64   0, // 0x0a DW_FORM_block1
65   1, // 0x0b DW_FORM_data1
66   1, // 0x0c DW_FORM_flag
67   0, // 0x0d DW_FORM_sdata
68   4, // 0x0e DW_FORM_strp
69   0, // 0x0f DW_FORM_udata
70   8, // 0x10 DW_FORM_ref_addr
71   1, // 0x11 DW_FORM_ref1
72   2, // 0x12 DW_FORM_ref2
73   4, // 0x13 DW_FORM_ref4
74   8, // 0x14 DW_FORM_ref8
75   0, // 0x15 DW_FORM_ref_udata
76   0, // 0x16 DW_FORM_indirect
77   8, // 0x17 DW_FORM_sec_offset
78   0, // 0x18 DW_FORM_exprloc
79   0, // 0x19 DW_FORM_flag_present
80   8, // 0x20 DW_FORM_ref_sig8
81   8, // 0x1f01 DW_FORM_GNU_addr_index
82   8, // 0x1f01 DW_FORM_GNU_str_index
83 };
84
85 const uint8_t *
86 DWARFFormValue::getFixedFormSizesForAddressSize(uint8_t addr_size) {
87   switch (addr_size) {
88   case 4: return form_sizes_addr4;
89   case 8: return form_sizes_addr8;
90   }
91   return NULL;
92 }
93
94 bool
95 DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
96                              const DWARFCompileUnit *cu) {
97   bool indirect = false;
98   bool is_block = false;
99   Value.data = NULL;
100   // Read the value for the form into value and follow and DW_FORM_indirect
101   // instances we run into
102   do {
103     indirect = false;
104     switch (Form) {
105     case DW_FORM_addr:
106     case DW_FORM_ref_addr: {
107       RelocAddrMap::const_iterator AI
108         = cu->getContext().relocMap().find(*offset_ptr);
109       if (AI != cu->getContext().relocMap().end()) {
110         const std::pair<uint8_t, int64_t> &R = AI->second;
111         Value.uval = R.second;
112         *offset_ptr += R.first;
113       } else
114         Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize());
115       break;
116     }
117     case DW_FORM_exprloc:
118     case DW_FORM_block:
119       Value.uval = data.getULEB128(offset_ptr);
120       is_block = true;
121       break;
122     case DW_FORM_block1:
123       Value.uval = data.getU8(offset_ptr);
124       is_block = true;
125       break;
126     case DW_FORM_block2:
127       Value.uval = data.getU16(offset_ptr);
128       is_block = true;
129       break;
130     case DW_FORM_block4:
131       Value.uval = data.getU32(offset_ptr);
132       is_block = true;
133       break;
134     case DW_FORM_data1:
135     case DW_FORM_ref1:
136     case DW_FORM_flag:
137       Value.uval = data.getU8(offset_ptr);
138       break;
139     case DW_FORM_data2:
140     case DW_FORM_ref2:
141       Value.uval = data.getU16(offset_ptr);
142       break;
143     case DW_FORM_data4:
144     case DW_FORM_ref4:
145       Value.uval = data.getU32(offset_ptr);
146       break;
147     case DW_FORM_data8:
148     case DW_FORM_ref8:
149       Value.uval = data.getU64(offset_ptr);
150       break;
151     case DW_FORM_sdata:
152       Value.sval = data.getSLEB128(offset_ptr);
153       break;
154     case DW_FORM_strp: {
155       RelocAddrMap::const_iterator AI
156         = cu->getContext().relocMap().find(*offset_ptr);
157       if (AI != cu->getContext().relocMap().end()) {
158         const std::pair<uint8_t, int64_t> &R = AI->second;
159         Value.uval = R.second;
160         *offset_ptr += R.first;
161       } else
162         Value.uval = data.getU32(offset_ptr);
163       break;
164     }
165     case DW_FORM_udata:
166     case DW_FORM_ref_udata:
167       Value.uval = data.getULEB128(offset_ptr);
168       break;
169     case DW_FORM_string:
170       Value.cstr = data.getCStr(offset_ptr);
171       // Set the string value to also be the data for inlined cstr form
172       // values only so we can tell the differnence between DW_FORM_string
173       // and DW_FORM_strp form values
174       Value.data = (const uint8_t*)Value.cstr;
175       break;
176     case DW_FORM_indirect:
177       Form = data.getULEB128(offset_ptr);
178       indirect = true;
179       break;
180     case DW_FORM_sec_offset:
181       if (cu->getAddressByteSize() == 4)
182         Value.uval = data.getU32(offset_ptr);
183       else
184         Value.uval = data.getU64(offset_ptr);
185       break;
186     case DW_FORM_flag_present:
187       Value.uval = 1;
188       break;
189     case DW_FORM_ref_sig8:
190       Value.uval = data.getU64(offset_ptr);
191       break;
192     case DW_FORM_GNU_addr_index:
193       Value.uval = data.getULEB128(offset_ptr);
194       break;
195     case DW_FORM_GNU_str_index:
196       Value.uval = data.getULEB128(offset_ptr);
197       break;
198     default:
199       return false;
200     }
201   } while (indirect);
202
203   if (is_block) {
204     StringRef str = data.getData().substr(*offset_ptr, Value.uval);
205     Value.data = NULL;
206     if (!str.empty()) {
207       Value.data = reinterpret_cast<const uint8_t *>(str.data());
208       *offset_ptr += Value.uval;
209     }
210   }
211
212   return true;
213 }
214
215 bool
216 DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
217                           const DWARFCompileUnit *cu) const {
218   return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
219 }
220
221 bool
222 DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
223                           uint32_t *offset_ptr, const DWARFCompileUnit *cu) {
224   bool indirect = false;
225   do {
226     indirect = false;
227     switch (form) {
228     // Blocks if inlined data that have a length field and the data bytes
229     // inlined in the .debug_info
230     case DW_FORM_exprloc:
231     case DW_FORM_block: {
232       uint64_t size = debug_info_data.getULEB128(offset_ptr);
233       *offset_ptr += size;
234       return true;
235     }
236     case DW_FORM_block1: {
237       uint8_t size = debug_info_data.getU8(offset_ptr);
238       *offset_ptr += size;
239       return true;
240     }
241     case DW_FORM_block2: {
242       uint16_t size = debug_info_data.getU16(offset_ptr);
243       *offset_ptr += size;
244       return true;
245     }
246     case DW_FORM_block4: {
247       uint32_t size = debug_info_data.getU32(offset_ptr);
248       *offset_ptr += size;
249       return true;
250     }
251
252     // Inlined NULL terminated C-strings
253     case DW_FORM_string:
254       debug_info_data.getCStr(offset_ptr);
255       return true;
256
257     // Compile unit address sized values
258     case DW_FORM_addr:
259     case DW_FORM_ref_addr:
260       *offset_ptr += cu->getAddressByteSize();
261       return true;
262
263     // 0 byte values - implied from the form.
264     case DW_FORM_flag_present:
265       return true;
266       
267     // 1 byte values
268     case DW_FORM_data1:
269     case DW_FORM_flag:
270     case DW_FORM_ref1:
271       *offset_ptr += 1;
272       return true;
273
274     // 2 byte values
275     case DW_FORM_data2:
276     case DW_FORM_ref2:
277       *offset_ptr += 2;
278       return true;
279
280     // 4 byte values
281     case DW_FORM_strp:
282     case DW_FORM_data4:
283     case DW_FORM_ref4:
284       *offset_ptr += 4;
285       return true;
286
287     // 8 byte values
288     case DW_FORM_data8:
289     case DW_FORM_ref8:
290     case DW_FORM_ref_sig8:
291       *offset_ptr += 8;
292       return true;
293
294     // signed or unsigned LEB 128 values
295     //  case DW_FORM_APPLE_db_str:
296     case DW_FORM_sdata:
297     case DW_FORM_udata:
298     case DW_FORM_ref_udata:
299       debug_info_data.getULEB128(offset_ptr);
300       return true;
301
302     case DW_FORM_indirect:
303       indirect = true;
304       form = debug_info_data.getULEB128(offset_ptr);
305       break;
306
307     // 4 for DWARF32, 8 for DWARF64.
308     case DW_FORM_sec_offset:
309       if (cu->getAddressByteSize() == 4)
310         *offset_ptr += 4;
311       else
312         *offset_ptr += 8;
313       return true;
314       
315     default:
316       return false;
317     }
318   } while (indirect);
319   return true;
320 }
321
322 void
323 DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
324   DataExtractor debug_str_data(cu->getContext().getStringSection(), true, 0);
325   uint64_t uvalue = getUnsigned();
326   bool cu_relative_offset = false;
327
328   switch (Form) {
329   case DW_FORM_addr:      OS << format("0x%016" PRIx64, uvalue); break;
330   case DW_FORM_flag_present: OS << "true"; break;
331   case DW_FORM_flag:
332   case DW_FORM_data1:     OS << format("0x%02x", (uint8_t)uvalue); break;
333   case DW_FORM_data2:     OS << format("0x%04x", (uint16_t)uvalue); break;
334   case DW_FORM_data4:     OS << format("0x%08x", (uint32_t)uvalue); break;
335   case DW_FORM_ref_sig8:
336   case DW_FORM_data8:     OS << format("0x%016" PRIx64, uvalue); break;
337   case DW_FORM_string:
338     OS << '"';
339     OS.write_escaped(getAsCString(NULL));
340     OS << '"';
341     break;
342   case DW_FORM_exprloc:
343   case DW_FORM_block:
344   case DW_FORM_block1:
345   case DW_FORM_block2:
346   case DW_FORM_block4:
347     if (uvalue > 0) {
348       switch (Form) {
349       case DW_FORM_exprloc:
350       case DW_FORM_block:  OS << format("<0x%" PRIx64 "> ", uvalue);     break;
351       case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue);  break;
352       case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
353       case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
354       default: break;
355       }
356
357       const uint8_t* data_ptr = Value.data;
358       if (data_ptr) {
359         // uvalue contains size of block
360         const uint8_t* end_data_ptr = data_ptr + uvalue;
361         while (data_ptr < end_data_ptr) {
362           OS << format("%2.2x ", *data_ptr);
363           ++data_ptr;
364         }
365       }
366       else
367         OS << "NULL";
368     }
369     break;
370
371   case DW_FORM_sdata:     OS << getSigned();   break;
372   case DW_FORM_udata:     OS << getUnsigned(); break;
373   case DW_FORM_strp: {
374     OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
375     const char* dbg_str = getAsCString(&debug_str_data);
376     if (dbg_str) {
377       OS << '"';
378       OS.write_escaped(dbg_str);
379       OS << '"';
380     }
381     break;
382   }
383   case DW_FORM_ref_addr:
384     OS << format("0x%016" PRIx64, uvalue);
385     break;
386   case DW_FORM_ref1:
387     cu_relative_offset = true;
388     OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
389     break;
390   case DW_FORM_ref2:
391     cu_relative_offset = true;
392     OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
393     break;
394   case DW_FORM_ref4:
395     cu_relative_offset = true;
396     OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
397     break;
398   case DW_FORM_ref8:
399     cu_relative_offset = true;
400     OS << format("cu + 0x%8.8" PRIx64, uvalue);
401     break;
402   case DW_FORM_ref_udata:
403     cu_relative_offset = true;
404     OS << format("cu + 0x%" PRIx64, uvalue);
405     break;
406
407     // All DW_FORM_indirect attributes should be resolved prior to calling
408     // this function
409   case DW_FORM_indirect:
410     OS << "DW_FORM_indirect";
411     break;
412
413   case DW_FORM_sec_offset:
414     if (cu->getAddressByteSize() == 4)
415       OS << format("0x%08x", (uint32_t)uvalue);
416     else
417       OS << format("0x%016" PRIx64, uvalue);
418     break;
419     
420   default:
421     OS << format("DW_FORM(0x%4.4x)", Form);
422     break;
423   }
424
425   if (cu_relative_offset)
426     OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0));
427 }
428
429 const char*
430 DWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const {
431   if (isInlinedCStr()) {
432     return Value.cstr;
433   } else if (debug_str_data_ptr) {
434     uint32_t offset = Value.uval;
435     return debug_str_data_ptr->getCStr(&offset);
436   }
437   return NULL;
438 }
439
440 uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {
441   uint64_t die_offset = Value.uval;
442   switch (Form) {
443   case DW_FORM_ref1:
444   case DW_FORM_ref2:
445   case DW_FORM_ref4:
446   case DW_FORM_ref8:
447   case DW_FORM_ref_udata:
448       die_offset += (cu ? cu->getOffset() : 0);
449       break;
450   default:
451       break;
452   }
453
454   return die_offset;
455 }
456
457 bool
458 DWARFFormValue::resolveCompileUnitReferences(const DWARFCompileUnit *cu) {
459   switch (Form) {
460   case DW_FORM_ref1:
461   case DW_FORM_ref2:
462   case DW_FORM_ref4:
463   case DW_FORM_ref8:
464   case DW_FORM_ref_udata:
465     Value.uval += cu->getOffset();
466     Form = DW_FORM_ref_addr;
467     return true;
468   default:
469     break;
470   }
471   return false;
472 }
473
474 const uint8_t *DWARFFormValue::BlockData() const {
475   if (!isInlinedCStr())
476     return Value.data;
477   return NULL;
478 }
479
480 bool DWARFFormValue::isBlockForm(uint16_t form) {
481   switch (form) {
482   case DW_FORM_exprloc:
483   case DW_FORM_block:
484   case DW_FORM_block1:
485   case DW_FORM_block2:
486   case DW_FORM_block4:
487     return true;
488   }
489   return false;
490 }
491
492 bool DWARFFormValue::isDataForm(uint16_t form) {
493   switch (form) {
494   case DW_FORM_sdata:
495   case DW_FORM_udata:
496   case DW_FORM_data1:
497   case DW_FORM_data2:
498   case DW_FORM_data4:
499   case DW_FORM_data8:
500     return true;
501   }
502   return false;
503 }