efc2d9661307111c6a4acba395386e145c9fef7f
[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 = data.getUnsigned(offset_ptr, cu->getAddressByteSize()) +
112                      R.second;
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 = data.getU32(offset_ptr) + R.second;
160       } else
161         Value.uval = data.getU32(offset_ptr);
162       break;
163     }
164     case DW_FORM_udata:
165     case DW_FORM_ref_udata:
166       Value.uval = data.getULEB128(offset_ptr);
167       break;
168     case DW_FORM_string:
169       Value.cstr = data.getCStr(offset_ptr);
170       // Set the string value to also be the data for inlined cstr form
171       // values only so we can tell the differnence between DW_FORM_string
172       // and DW_FORM_strp form values
173       Value.data = (const uint8_t*)Value.cstr;
174       break;
175     case DW_FORM_indirect:
176       Form = data.getULEB128(offset_ptr);
177       indirect = true;
178       break;
179     case DW_FORM_sec_offset:
180       if (cu->getAddressByteSize() == 4)
181         Value.uval = data.getU32(offset_ptr);
182       else
183         Value.uval = data.getU64(offset_ptr);
184       break;
185     case DW_FORM_flag_present:
186       Value.uval = 1;
187       break;
188     case DW_FORM_ref_sig8:
189       Value.uval = data.getU64(offset_ptr);
190       break;
191     case DW_FORM_GNU_addr_index:
192       Value.uval = data.getULEB128(offset_ptr);
193       break;
194     case DW_FORM_GNU_str_index:
195       Value.uval = data.getULEB128(offset_ptr);
196       break;
197     default:
198       return false;
199     }
200   } while (indirect);
201
202   if (is_block) {
203     StringRef str = data.getData().substr(*offset_ptr, Value.uval);
204     Value.data = NULL;
205     if (!str.empty()) {
206       Value.data = reinterpret_cast<const uint8_t *>(str.data());
207       *offset_ptr += Value.uval;
208     }
209   }
210
211   return true;
212 }
213
214 bool
215 DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
216                           const DWARFCompileUnit *cu) const {
217   return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
218 }
219
220 bool
221 DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
222                           uint32_t *offset_ptr, const DWARFCompileUnit *cu) {
223   bool indirect = false;
224   do {
225     indirect = false;
226     switch (form) {
227     // Blocks if inlined data that have a length field and the data bytes
228     // inlined in the .debug_info
229     case DW_FORM_exprloc:
230     case DW_FORM_block: {
231       uint64_t size = debug_info_data.getULEB128(offset_ptr);
232       *offset_ptr += size;
233       return true;
234     }
235     case DW_FORM_block1: {
236       uint8_t size = debug_info_data.getU8(offset_ptr);
237       *offset_ptr += size;
238       return true;
239     }
240     case DW_FORM_block2: {
241       uint16_t size = debug_info_data.getU16(offset_ptr);
242       *offset_ptr += size;
243       return true;
244     }
245     case DW_FORM_block4: {
246       uint32_t size = debug_info_data.getU32(offset_ptr);
247       *offset_ptr += size;
248       return true;
249     }
250
251     // Inlined NULL terminated C-strings
252     case DW_FORM_string:
253       debug_info_data.getCStr(offset_ptr);
254       return true;
255
256     // Compile unit address sized values
257     case DW_FORM_addr:
258     case DW_FORM_ref_addr:
259       *offset_ptr += cu->getAddressByteSize();
260       return true;
261
262     // 0 byte values - implied from the form.
263     case DW_FORM_flag_present:
264       return true;
265       
266     // 1 byte values
267     case DW_FORM_data1:
268     case DW_FORM_flag:
269     case DW_FORM_ref1:
270       *offset_ptr += 1;
271       return true;
272
273     // 2 byte values
274     case DW_FORM_data2:
275     case DW_FORM_ref2:
276       *offset_ptr += 2;
277       return true;
278
279     // 4 byte values
280     case DW_FORM_strp:
281     case DW_FORM_data4:
282     case DW_FORM_ref4:
283       *offset_ptr += 4;
284       return true;
285
286     // 8 byte values
287     case DW_FORM_data8:
288     case DW_FORM_ref8:
289     case DW_FORM_ref_sig8:
290       *offset_ptr += 8;
291       return true;
292
293     // signed or unsigned LEB 128 values
294     //  case DW_FORM_APPLE_db_str:
295     case DW_FORM_sdata:
296     case DW_FORM_udata:
297     case DW_FORM_ref_udata:
298       debug_info_data.getULEB128(offset_ptr);
299       return true;
300
301     case DW_FORM_indirect:
302       indirect = true;
303       form = debug_info_data.getULEB128(offset_ptr);
304       break;
305
306     // 4 for DWARF32, 8 for DWARF64.
307     case DW_FORM_sec_offset:
308       if (cu->getAddressByteSize() == 4)
309         *offset_ptr += 4;
310       else
311         *offset_ptr += 8;
312       return true;
313       
314     default:
315       return false;
316     }
317   } while (indirect);
318   return true;
319 }
320
321 void
322 DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
323   DataExtractor debug_str_data(cu->getContext().getStringSection(), true, 0);
324   uint64_t uvalue = getUnsigned();
325   bool cu_relative_offset = false;
326
327   switch (Form) {
328   case DW_FORM_addr:      OS << format("0x%016" PRIx64, uvalue); break;
329   case DW_FORM_flag_present: OS << "true"; break;
330   case DW_FORM_flag:
331   case DW_FORM_data1:     OS << format("0x%02x", (uint8_t)uvalue); break;
332   case DW_FORM_data2:     OS << format("0x%04x", (uint16_t)uvalue); break;
333   case DW_FORM_data4:     OS << format("0x%08x", (uint32_t)uvalue); break;
334   case DW_FORM_ref_sig8:
335   case DW_FORM_data8:     OS << format("0x%016" PRIx64, uvalue); break;
336   case DW_FORM_string:
337     OS << '"';
338     OS.write_escaped(getAsCString(NULL));
339     OS << '"';
340     break;
341   case DW_FORM_exprloc:
342   case DW_FORM_block:
343   case DW_FORM_block1:
344   case DW_FORM_block2:
345   case DW_FORM_block4:
346     if (uvalue > 0) {
347       switch (Form) {
348       case DW_FORM_exprloc:
349       case DW_FORM_block:  OS << format("<0x%" PRIx64 "> ", uvalue);     break;
350       case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue);  break;
351       case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
352       case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
353       default: break;
354       }
355
356       const uint8_t* data_ptr = Value.data;
357       if (data_ptr) {
358         // uvalue contains size of block
359         const uint8_t* end_data_ptr = data_ptr + uvalue;
360         while (data_ptr < end_data_ptr) {
361           OS << format("%2.2x ", *data_ptr);
362           ++data_ptr;
363         }
364       }
365       else
366         OS << "NULL";
367     }
368     break;
369
370   case DW_FORM_sdata:     OS << getSigned();   break;
371   case DW_FORM_udata:     OS << getUnsigned(); break;
372   case DW_FORM_strp: {
373     OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
374     const char* dbg_str = getAsCString(&debug_str_data);
375     if (dbg_str) {
376       OS << '"';
377       OS.write_escaped(dbg_str);
378       OS << '"';
379     }
380     break;
381   }
382   case DW_FORM_ref_addr:
383     OS << format("0x%016" PRIx64, uvalue);
384     break;
385   case DW_FORM_ref1:
386     cu_relative_offset = true;
387     OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
388     break;
389   case DW_FORM_ref2:
390     cu_relative_offset = true;
391     OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
392     break;
393   case DW_FORM_ref4:
394     cu_relative_offset = true;
395     OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
396     break;
397   case DW_FORM_ref8:
398     cu_relative_offset = true;
399     OS << format("cu + 0x%8.8" PRIx64, uvalue);
400     break;
401   case DW_FORM_ref_udata:
402     cu_relative_offset = true;
403     OS << format("cu + 0x%" PRIx64, uvalue);
404     break;
405
406     // All DW_FORM_indirect attributes should be resolved prior to calling
407     // this function
408   case DW_FORM_indirect:
409     OS << "DW_FORM_indirect";
410     break;
411
412   case DW_FORM_sec_offset:
413     if (cu->getAddressByteSize() == 4)
414       OS << format("0x%08x", (uint32_t)uvalue);
415     else
416       OS << format("0x%016" PRIx64, uvalue);
417     break;
418     
419   default:
420     OS << format("DW_FORM(0x%4.4x)", Form);
421     break;
422   }
423
424   if (cu_relative_offset)
425     OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0));
426 }
427
428 const char*
429 DWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const {
430   if (isInlinedCStr()) {
431     return Value.cstr;
432   } else if (debug_str_data_ptr) {
433     uint32_t offset = Value.uval;
434     return debug_str_data_ptr->getCStr(&offset);
435   }
436   return NULL;
437 }
438
439 uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {
440   uint64_t die_offset = Value.uval;
441   switch (Form) {
442   case DW_FORM_ref1:
443   case DW_FORM_ref2:
444   case DW_FORM_ref4:
445   case DW_FORM_ref8:
446   case DW_FORM_ref_udata:
447       die_offset += (cu ? cu->getOffset() : 0);
448       break;
449   default:
450       break;
451   }
452
453   return die_offset;
454 }
455
456 bool
457 DWARFFormValue::resolveCompileUnitReferences(const DWARFCompileUnit *cu) {
458   switch (Form) {
459   case DW_FORM_ref1:
460   case DW_FORM_ref2:
461   case DW_FORM_ref4:
462   case DW_FORM_ref8:
463   case DW_FORM_ref_udata:
464     Value.uval += cu->getOffset();
465     Form = DW_FORM_ref_addr;
466     return true;
467   default:
468     break;
469   }
470   return false;
471 }
472
473 const uint8_t *DWARFFormValue::BlockData() const {
474   if (!isInlinedCStr())
475     return Value.data;
476   return NULL;
477 }
478
479 bool DWARFFormValue::isBlockForm(uint16_t form) {
480   switch (form) {
481   case DW_FORM_exprloc:
482   case DW_FORM_block:
483   case DW_FORM_block1:
484   case DW_FORM_block2:
485   case DW_FORM_block4:
486     return true;
487   }
488   return false;
489 }
490
491 bool DWARFFormValue::isDataForm(uint16_t form) {
492   switch (form) {
493   case DW_FORM_sdata:
494   case DW_FORM_udata:
495   case DW_FORM_data1:
496   case DW_FORM_data2:
497   case DW_FORM_data4:
498   case DW_FORM_data8:
499     return true;
500   }
501   return false;
502 }