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