]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / DWARFFormValue.cpp
1 //===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===//
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 <assert.h>
11
12 #include "lldb/Core/dwarf.h"
13 #include "lldb/Core/Stream.h"
14
15 #include "DWARFFormValue.h"
16 #include "DWARFCompileUnit.h"
17
18 class DWARFCompileUnit;
19
20 using namespace lldb_private;
21
22
23 static uint8_t g_form_sizes_addr4[] = 
24 {
25     0, // 0x00 unused
26     4, // 0x01 DW_FORM_addr
27     0, // 0x02 unused
28     0, // 0x03 DW_FORM_block2
29     0, // 0x04 DW_FORM_block4
30     2, // 0x05 DW_FORM_data2
31     4, // 0x06 DW_FORM_data4
32     8, // 0x07 DW_FORM_data8
33     0, // 0x08 DW_FORM_string
34     0, // 0x09 DW_FORM_block
35     0, // 0x0a DW_FORM_block1
36     1, // 0x0b DW_FORM_data1
37     1, // 0x0c DW_FORM_flag
38     0, // 0x0d DW_FORM_sdata
39     4, // 0x0e DW_FORM_strp
40     0, // 0x0f DW_FORM_udata
41     0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
42     1, // 0x11 DW_FORM_ref1
43     2, // 0x12 DW_FORM_ref2
44     4, // 0x13 DW_FORM_ref4
45     8, // 0x14 DW_FORM_ref8
46     0, // 0x15 DW_FORM_ref_udata
47     0, // 0x16 DW_FORM_indirect
48     4, // 0x17 DW_FORM_sec_offset
49     0, // 0x18 DW_FORM_exprloc
50     0, // 0x19 DW_FORM_flag_present
51     0, // 0x1a
52     0, // 0x1b
53     0, // 0x1c
54     0, // 0x1d
55     0, // 0x1e
56     0, // 0x1f
57     8, // 0x20 DW_FORM_ref_sig8
58
59 };
60
61 static uint8_t
62 g_form_sizes_addr8[] = 
63 {
64     0, // 0x00 unused
65     8, // 0x01 DW_FORM_addr
66     0, // 0x02 unused
67     0, // 0x03 DW_FORM_block2
68     0, // 0x04 DW_FORM_block4
69     2, // 0x05 DW_FORM_data2
70     4, // 0x06 DW_FORM_data4
71     8, // 0x07 DW_FORM_data8
72     0, // 0x08 DW_FORM_string
73     0, // 0x09 DW_FORM_block
74     0, // 0x0a DW_FORM_block1
75     1, // 0x0b DW_FORM_data1
76     1, // 0x0c DW_FORM_flag
77     0, // 0x0d DW_FORM_sdata
78     4, // 0x0e DW_FORM_strp
79     0, // 0x0f DW_FORM_udata
80     0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
81     1, // 0x11 DW_FORM_ref1
82     2, // 0x12 DW_FORM_ref2
83     4, // 0x13 DW_FORM_ref4
84     8, // 0x14 DW_FORM_ref8
85     0, // 0x15 DW_FORM_ref_udata
86     0, // 0x16 DW_FORM_indirect
87     4, // 0x17 DW_FORM_sec_offset
88     0, // 0x18 DW_FORM_exprloc
89     0, // 0x19 DW_FORM_flag_present
90     0, // 0x1a
91     0, // 0x1b
92     0, // 0x1c
93     0, // 0x1d
94     0, // 0x1e
95     0, // 0x1f
96     8, // 0x20 DW_FORM_ref_sig8
97 };
98
99 const uint8_t * 
100 DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size)
101 {
102     switch (addr_size)
103     {
104     case 4: return g_form_sizes_addr4;
105     case 8: return g_form_sizes_addr8;
106     }
107     return NULL;
108 }
109
110 DWARFFormValue::DWARFFormValue(dw_form_t form) :
111     m_form(form),
112     m_value()
113 {
114 }
115
116 bool
117 DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu)
118 {
119     bool indirect = false;
120     bool is_block = false;
121     m_value.data = NULL;
122     // Read the value for the form into value and follow and DW_FORM_indirect instances we run into
123     do
124     {
125         indirect = false;
126         switch (m_form)
127         {
128         case DW_FORM_addr:      m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu));  break;
129         case DW_FORM_block2:    m_value.value.uval = data.GetU16(offset_ptr); is_block = true;          break;
130         case DW_FORM_block4:    m_value.value.uval = data.GetU32(offset_ptr); is_block = true;          break;
131         case DW_FORM_data2:     m_value.value.uval = data.GetU16(offset_ptr);                           break;
132         case DW_FORM_data4:     m_value.value.uval = data.GetU32(offset_ptr);                           break;
133         case DW_FORM_data8:     m_value.value.uval = data.GetU64(offset_ptr);                           break;
134         case DW_FORM_string:    m_value.value.cstr = data.GetCStr(offset_ptr);
135                                 // Set the string value to also be the data for inlined cstr form values only
136                                 // so we can tell the differnence between DW_FORM_string and DW_FORM_strp form
137                                 // values;
138                                 m_value.data = (uint8_t*)m_value.value.cstr;                            break;
139         case DW_FORM_exprloc:
140         case DW_FORM_block:     m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true;      break;
141         case DW_FORM_block1:    m_value.value.uval = data.GetU8(offset_ptr); is_block = true;           break;
142         case DW_FORM_data1:     m_value.value.uval = data.GetU8(offset_ptr);                            break;
143         case DW_FORM_flag:      m_value.value.uval = data.GetU8(offset_ptr);                            break;
144         case DW_FORM_sdata:     m_value.value.sval = data.GetSLEB128(offset_ptr);                       break;
145         case DW_FORM_strp:      m_value.value.uval = data.GetU32(offset_ptr);                           break;
146     //  case DW_FORM_APPLE_db_str:
147         case DW_FORM_udata:     m_value.value.uval = data.GetULEB128(offset_ptr);                       break;
148         case DW_FORM_ref_addr:
149             if (cu->GetVersion() <= 2)
150                 m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu));
151             else
152                 m_value.value.uval = data.GetU32(offset_ptr); // 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
153             break;
154         case DW_FORM_ref1:      m_value.value.uval = data.GetU8(offset_ptr);                            break;
155         case DW_FORM_ref2:      m_value.value.uval = data.GetU16(offset_ptr);                           break;
156         case DW_FORM_ref4:      m_value.value.uval = data.GetU32(offset_ptr);                           break;
157         case DW_FORM_ref8:      m_value.value.uval = data.GetU64(offset_ptr);                           break;
158         case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr);                       break;
159         case DW_FORM_indirect:
160             m_form = data.GetULEB128(offset_ptr);
161             indirect = true;
162             break;
163
164         case DW_FORM_sec_offset:    m_value.value.uval = data.GetU32(offset_ptr);                       break;
165         case DW_FORM_flag_present:  m_value.value.uval = 1;                                             break;
166         case DW_FORM_ref_sig8:      m_value.value.uval = data.GetU64(offset_ptr);                       break;
167         default:
168             return false;
169             break;
170         }
171     } while (indirect);
172
173     if (is_block)
174     {
175         m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
176         if (m_value.data != NULL)
177         {
178             *offset_ptr += m_value.value.uval;
179         }
180     }
181
182     return true;
183 }
184
185 bool
186 DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const
187 {
188     return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu);
189 }
190
191 bool
192 DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu)
193 {
194     switch (form)
195     {
196     // Blocks if inlined data that have a length field and the data bytes
197     // inlined in the .debug_info
198     case DW_FORM_exprloc:
199     case DW_FORM_block:  { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true;
200     case DW_FORM_block1: { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr);      *offset_ptr += size; } return true;
201     case DW_FORM_block2: { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr);     *offset_ptr += size; } return true;
202     case DW_FORM_block4: { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr);     *offset_ptr += size; } return true;
203
204     // Inlined NULL terminated C-strings
205     case DW_FORM_string:
206         debug_info_data.GetCStr(offset_ptr);
207         return true;
208
209     // Compile unit address sized values
210     case DW_FORM_addr:
211         *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
212         return true;
213
214     case DW_FORM_ref_addr:
215         if (cu->GetVersion() <= 2)
216             *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
217         else
218             *offset_ptr += 4;// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
219         return true;
220
221     // 0 bytes values (implied from DW_FORM)
222     case DW_FORM_flag_present:
223         return true;
224
225     // 1 byte values
226     case DW_FORM_data1:
227     case DW_FORM_flag:
228     case DW_FORM_ref1:
229         *offset_ptr += 1;
230         return true;
231
232     // 2 byte values
233     case DW_FORM_data2:
234     case DW_FORM_ref2:
235         *offset_ptr += 2;
236         return true;
237
238     // 32 bit for DWARF 32, 64 for DWARF 64
239     case DW_FORM_sec_offset:
240         *offset_ptr += 4;
241         return true;
242
243     // 4 byte values
244     case DW_FORM_strp:
245     case DW_FORM_data4:
246     case DW_FORM_ref4:
247         *offset_ptr += 4;
248         return true;
249
250     // 8 byte values
251     case DW_FORM_data8:
252     case DW_FORM_ref8:
253     case DW_FORM_ref_sig8:
254         *offset_ptr += 8;
255         return true;
256
257     // signed or unsigned LEB 128 values
258     case DW_FORM_sdata:
259     case DW_FORM_udata:
260     case DW_FORM_ref_udata:
261         debug_info_data.Skip_LEB128(offset_ptr);
262         return true;
263
264     case DW_FORM_indirect:
265         {
266             dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
267             return DWARFFormValue::SkipValue (indirect_form,
268                                               debug_info_data,
269                                               offset_ptr,
270                                               cu);
271         }
272
273     default:
274         break;
275     }
276     return false;
277 }
278
279
280 void
281 DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const DWARFCompileUnit* cu) const
282 {
283     uint64_t uvalue = Unsigned();
284     bool cu_relative_offset = false;
285
286     bool verbose = s.GetVerbose();
287
288     switch (m_form)
289     {
290     case DW_FORM_addr:      s.Address(uvalue, sizeof (uint64_t)); break;
291     case DW_FORM_flag:
292     case DW_FORM_data1:     s.PutHex8(uvalue);     break;
293     case DW_FORM_data2:     s.PutHex16(uvalue);        break;
294     case DW_FORM_sec_offset:
295     case DW_FORM_data4:     s.PutHex32(uvalue);        break;
296     case DW_FORM_ref_sig8:
297     case DW_FORM_data8:     s.PutHex64(uvalue);        break;
298     case DW_FORM_string:    s.QuotedCString(AsCString(NULL));          break;
299     case DW_FORM_exprloc:
300     case DW_FORM_block:
301     case DW_FORM_block1:
302     case DW_FORM_block2:
303     case DW_FORM_block4:
304         if (uvalue > 0)
305         {
306             switch (m_form)
307             {
308             case DW_FORM_exprloc:
309             case DW_FORM_block:  s.Printf("<0x%" PRIx64 "> ", uvalue);                break;
310             case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue);      break;
311             case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue);     break;
312             case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue);     break;
313             default:                                                            break;
314             }
315
316             const uint8_t* data_ptr = m_value.data;
317             if (data_ptr)
318             {
319                 const uint8_t* end_data_ptr = data_ptr + uvalue;    // uvalue contains size of block
320                 while (data_ptr < end_data_ptr)
321                 {
322                     s.Printf("%2.2x ", *data_ptr);
323                     ++data_ptr;
324                 }
325             }
326             else
327                 s.PutCString("NULL");
328         }
329         break;
330
331     case DW_FORM_sdata:     s.PutSLEB128(uvalue); break;
332     case DW_FORM_udata:     s.PutULEB128(uvalue); break;
333     case DW_FORM_strp:
334         if (debug_str_data)
335         {
336             if (verbose)
337                 s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
338
339             const char* dbg_str = AsCString(debug_str_data);
340             if (dbg_str)
341                 s.QuotedCString(dbg_str);
342         }
343         else
344         {
345             s.PutHex32(uvalue);
346         }
347         break;
348
349     case DW_FORM_ref_addr:
350     {
351         if (cu->GetVersion() <= 2)
352             s.Address(uvalue, sizeof (uint64_t) * 2);
353         else
354             s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
355         break;
356     }
357     case DW_FORM_ref1:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break;
358     case DW_FORM_ref2:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break;
359     case DW_FORM_ref4:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break;
360     case DW_FORM_ref8:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break;
361     case DW_FORM_ref_udata: cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break;
362
363     // All DW_FORM_indirect attributes should be resolved prior to calling this function
364     case DW_FORM_indirect:  s.PutCString("DW_FORM_indirect"); break;
365     case DW_FORM_flag_present: break;
366     default:
367         s.Printf("DW_FORM(0x%4.4x)", m_form);
368         break;
369     }
370
371     if (cu_relative_offset)
372     {
373         if (verbose)
374             s.PutCString(" => ");
375
376         s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0)));
377     }
378 }
379
380 const char*
381 DWARFFormValue::AsCString(const DWARFDataExtractor* debug_str_data_ptr) const
382 {
383     if (IsInlinedCStr())
384         return m_value.value.cstr;
385     else if (debug_str_data_ptr)
386         return debug_str_data_ptr->PeekCStr(m_value.value.uval);
387     return NULL;
388 }
389
390 uint64_t
391 DWARFFormValue::Reference(const DWARFCompileUnit* cu) const
392 {
393     uint64_t die_offset = m_value.value.uval;
394     switch (m_form)
395     {
396     case DW_FORM_ref1:
397     case DW_FORM_ref2:
398     case DW_FORM_ref4:
399     case DW_FORM_ref8:
400     case DW_FORM_ref_udata:
401         die_offset += (cu ? cu->GetOffset() : 0);
402         break;
403
404     default:
405         break;
406     }
407
408     return die_offset;
409 }
410
411 uint64_t
412 DWARFFormValue::Reference (dw_offset_t base_offset) const
413 {
414     uint64_t die_offset = m_value.value.uval;
415     switch (m_form)
416     {
417         case DW_FORM_ref1:
418         case DW_FORM_ref2:
419         case DW_FORM_ref4:
420         case DW_FORM_ref8:
421         case DW_FORM_ref_udata:
422             die_offset += base_offset;
423             break;
424             
425         default:
426             break;
427     }
428     
429     return die_offset;
430 }
431
432 //----------------------------------------------------------------------
433 // Resolve any compile unit specific references so that we don't need
434 // the compile unit at a later time in order to work with the form
435 // value.
436 //----------------------------------------------------------------------
437 bool
438 DWARFFormValue::ResolveCompileUnitReferences(const DWARFCompileUnit* cu)
439 {
440     switch (m_form)
441     {
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         m_value.value.uval += cu->GetOffset();
448         m_form = DW_FORM_ref_addr;
449         return true;
450         break;
451
452     default:
453         break;
454     }
455
456     return false;
457 }
458
459 const uint8_t*
460 DWARFFormValue::BlockData() const
461 {
462     if (!IsInlinedCStr())
463         return m_value.data;
464     return NULL;
465 }
466
467
468 bool
469 DWARFFormValue::IsBlockForm(const dw_form_t form)
470 {
471     switch (form)
472     {
473     case DW_FORM_block:
474     case DW_FORM_block1:
475     case DW_FORM_block2:
476     case DW_FORM_block4:
477         return true;
478     }
479     return false;
480 }
481
482 bool
483 DWARFFormValue::IsDataForm(const dw_form_t form)
484 {
485     switch (form)
486     {
487     case DW_FORM_sdata:
488     case DW_FORM_udata:
489     case DW_FORM_data1:
490     case DW_FORM_data2:
491     case DW_FORM_data4:
492     case DW_FORM_data8:
493         return true;
494     }
495     return false;
496 }
497
498 int
499 DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const DWARFDataExtractor* debug_str_data_ptr)
500 {
501     dw_form_t a_form = a_value.Form();
502     dw_form_t b_form = b_value.Form();
503     if (a_form < b_form)
504         return -1;
505     if (a_form > b_form)
506         return 1;
507     switch (a_form)
508     {
509     case DW_FORM_addr:
510     case DW_FORM_flag:
511     case DW_FORM_data1:
512     case DW_FORM_data2:
513     case DW_FORM_data4:
514     case DW_FORM_data8:
515     case DW_FORM_udata:
516     case DW_FORM_ref_addr:
517     case DW_FORM_sec_offset:
518     case DW_FORM_flag_present:
519     case DW_FORM_ref_sig8:
520         {
521             uint64_t a = a_value.Unsigned();
522             uint64_t b = b_value.Unsigned();
523             if (a < b)
524                 return -1;
525             if (a > b)
526                 return 1;
527             return 0;
528         }
529
530     case DW_FORM_sdata:
531         {
532             int64_t a = a_value.Signed();
533             int64_t b = b_value.Signed();
534             if (a < b)
535                 return -1;
536             if (a > b)
537                 return 1;
538             return 0;
539         }
540
541     case DW_FORM_string:
542     case DW_FORM_strp:
543         {
544             const char *a_string = a_value.AsCString(debug_str_data_ptr);
545             const char *b_string = b_value.AsCString(debug_str_data_ptr);
546             if (a_string == b_string)
547                 return 0;
548             else if (a_string && b_string)
549                 return strcmp(a_string, b_string);
550             else if (a_string == NULL)
551                 return -1;  // A string is NULL, and B is valid
552             else
553                 return 1;   // A string valid, and B is NULL
554         }
555
556
557     case DW_FORM_block:
558     case DW_FORM_block1:
559     case DW_FORM_block2:
560     case DW_FORM_block4:
561     case DW_FORM_exprloc:
562         {
563             uint64_t a_len = a_value.Unsigned();
564             uint64_t b_len = b_value.Unsigned();
565             if (a_len < b_len)
566                 return -1;
567             if (a_len > b_len)
568                 return 1;
569             // The block lengths are the same
570             return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
571         }
572         break;
573
574     case DW_FORM_ref1:
575     case DW_FORM_ref2:
576     case DW_FORM_ref4:
577     case DW_FORM_ref8:
578     case DW_FORM_ref_udata:
579         {
580             uint64_t a = a_value.Reference(a_cu);
581             uint64_t b = b_value.Reference(b_cu);
582             if (a < b)
583                 return -1;
584             if (a > b)
585                 return 1;
586             return 0;
587         }
588
589     case DW_FORM_indirect:
590         assert(!"This shouldn't happen after the form has been extracted...");
591         break;
592
593     default:
594         assert(!"Unhandled DW_FORM");
595         break;
596     }
597     return -1;
598 }
599