1 //===-- DWARFDebugInfoEntry.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 "DWARFDebugInfoEntry.h"
11 
12 #include <assert.h>
13 
14 #include <algorithm>
15 
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Stream.h"
18 #include "lldb/Expression/DWARFExpression.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 
21 #include "DWARFCompileUnit.h"
22 #include "SymbolFileDWARF.h"
23 #include "DWARFDebugAbbrev.h"
24 #include "DWARFDebugAranges.h"
25 #include "DWARFDebugInfo.h"
26 #include "DWARFDeclContext.h"
27 #include "DWARFDIECollection.h"
28 #include "DWARFFormValue.h"
29 #include "DWARFLocationDescription.h"
30 #include "DWARFLocationList.h"
31 #include "DWARFDebugRanges.h"
32 
33 using namespace lldb_private;
34 using namespace std;
35 extern int g_verbose;
36 
37 
38 
39 DWARFDebugInfoEntry::Attributes::Attributes() :
40     m_infos()
41 {
42 }
43 
44 DWARFDebugInfoEntry::Attributes::~Attributes()
45 {
46 }
47 
48 
49 uint32_t
50 DWARFDebugInfoEntry::Attributes::FindAttributeIndex(dw_attr_t attr) const
51 {
52     collection::const_iterator end = m_infos.end();
53     collection::const_iterator beg = m_infos.begin();
54     collection::const_iterator pos;
55     for (pos = beg; pos != end; ++pos)
56     {
57         if (pos->attr == attr)
58             return std::distance(beg, pos);
59     }
60     return UINT32_MAX;
61 }
62 
63 void
64 DWARFDebugInfoEntry::Attributes::Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form)
65 {
66     Info info = { cu, attr_die_offset, attr, form };
67     m_infos.push_back(info);
68 }
69 
70 bool
71 DWARFDebugInfoEntry::Attributes::ContainsAttribute(dw_attr_t attr) const
72 {
73     return FindAttributeIndex(attr) != UINT32_MAX;
74 }
75 
76 bool
77 DWARFDebugInfoEntry::Attributes::RemoveAttribute(dw_attr_t attr)
78 {
79     uint32_t attr_index = FindAttributeIndex(attr);
80     if (attr_index != UINT32_MAX)
81     {
82         m_infos.erase(m_infos.begin() + attr_index);
83         return true;
84     }
85     return false;
86 }
87 
88 bool
89 DWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const
90 {
91     form_value.SetCompileUnit(CompileUnitAtIndex(i));
92     form_value.SetForm(FormAtIndex(i));
93     lldb::offset_t offset = DIEOffsetAtIndex(i);
94     return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset);
95 }
96 
97 uint64_t
98 DWARFDebugInfoEntry::Attributes::FormValueAsUnsigned (SymbolFileDWARF* dwarf2Data, dw_attr_t attr, uint64_t fail_value) const
99 {
100     const uint32_t attr_idx = FindAttributeIndex (attr);
101     if (attr_idx != UINT32_MAX)
102         return FormValueAsUnsignedAtIndex (dwarf2Data, attr_idx, fail_value);
103     return fail_value;
104 }
105 
106 uint64_t
107 DWARFDebugInfoEntry::Attributes::FormValueAsUnsignedAtIndex(SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const
108 {
109     DWARFFormValue form_value;
110     if (ExtractFormValueAtIndex(dwarf2Data, i, form_value))
111         return form_value.Reference();
112     return fail_value;
113 }
114 
115 
116 
117 bool
118 DWARFDebugInfoEntry::FastExtract
119 (
120     const DWARFDataExtractor& debug_info_data,
121     const DWARFCompileUnit* cu,
122     const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
123     lldb::offset_t *offset_ptr
124 )
125 {
126     m_offset = *offset_ptr;
127     m_parent_idx = 0;
128     m_sibling_idx = 0;
129     m_empty_children = false;
130     const uint64_t abbr_idx = debug_info_data.GetULEB128 (offset_ptr);
131     assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
132     m_abbr_idx = abbr_idx;
133 
134     //assert (fixed_form_sizes);  // For best performance this should be specified!
135 
136     if (m_abbr_idx)
137     {
138         lldb::offset_t offset = *offset_ptr;
139 
140         const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
141 
142         if (abbrevDecl == NULL)
143         {
144             cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid abbreviation code %u, please file a bug and attach the file at the start of this error message",
145                                                                                  m_offset,
146                                                                                  (unsigned)abbr_idx);
147             // WE can't parse anymore if the DWARF is borked...
148             *offset_ptr = UINT32_MAX;
149             return false;
150         }
151         m_tag = abbrevDecl->Tag();
152         m_has_children = abbrevDecl->HasChildren();
153         // Skip all data in the .debug_info for the attributes
154         const uint32_t numAttributes = abbrevDecl->NumAttributes();
155         uint32_t i;
156         dw_form_t form;
157         for (i=0; i<numAttributes; ++i)
158         {
159             form = abbrevDecl->GetFormByIndexUnchecked(i);
160 
161             const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
162             if (fixed_skip_size)
163                 offset += fixed_skip_size;
164             else
165             {
166                 bool form_is_indirect = false;
167                 do
168                 {
169                     form_is_indirect = false;
170                     uint32_t form_size = 0;
171                     switch (form)
172                     {
173                     // Blocks if inlined data that have a length field and the data bytes
174                     // inlined in the .debug_info
175                     case DW_FORM_exprloc     :
176                     case DW_FORM_block       : form_size = debug_info_data.GetULEB128 (&offset);      break;
177                     case DW_FORM_block1      : form_size = debug_info_data.GetU8_unchecked (&offset); break;
178                     case DW_FORM_block2      : form_size = debug_info_data.GetU16_unchecked (&offset);break;
179                     case DW_FORM_block4      : form_size = debug_info_data.GetU32_unchecked (&offset);break;
180 
181                     // Inlined NULL terminated C-strings
182                     case DW_FORM_string      :
183                         debug_info_data.GetCStr (&offset);
184                         break;
185 
186                     // Compile unit address sized values
187                     case DW_FORM_addr        :
188                         form_size = cu->GetAddressByteSize();
189                         break;
190                     case DW_FORM_ref_addr    :
191                         if (cu->GetVersion() <= 2)
192                             form_size = cu->GetAddressByteSize();
193                         else
194                             form_size = cu->IsDWARF64() ? 8 : 4;
195                         break;
196 
197                     // 0 sized form
198                     case DW_FORM_flag_present:
199                         form_size = 0;
200                         break;
201 
202                     // 1 byte values
203                     case DW_FORM_data1       :
204                     case DW_FORM_flag        :
205                     case DW_FORM_ref1        :
206                         form_size = 1;
207                         break;
208 
209                     // 2 byte values
210                     case DW_FORM_data2       :
211                     case DW_FORM_ref2        :
212                         form_size = 2;
213                         break;
214 
215                     // 4 byte values
216                     case DW_FORM_data4       :
217                     case DW_FORM_ref4        :
218                         form_size = 4;
219                         break;
220 
221                     // 8 byte values
222                     case DW_FORM_data8       :
223                     case DW_FORM_ref8        :
224                     case DW_FORM_ref_sig8    :
225                         form_size = 8;
226                         break;
227 
228                     // signed or unsigned LEB 128 values
229                     case DW_FORM_sdata         :
230                     case DW_FORM_udata         :
231                     case DW_FORM_ref_udata     :
232                     case DW_FORM_GNU_addr_index:
233                     case DW_FORM_GNU_str_index :
234                         debug_info_data.Skip_LEB128 (&offset);
235                         break;
236 
237                     case DW_FORM_indirect    :
238                         form_is_indirect = true;
239                         form = debug_info_data.GetULEB128 (&offset);
240                         break;
241 
242                     case DW_FORM_strp        :
243                     case DW_FORM_sec_offset  :
244                         if (cu->IsDWARF64 ())
245                             debug_info_data.GetU64 (offset_ptr);
246                         else
247                             debug_info_data.GetU32 (offset_ptr);
248                         break;
249 
250                     default:
251                         *offset_ptr = m_offset;
252                         return false;
253                     }
254                     offset += form_size;
255 
256                 } while (form_is_indirect);
257             }
258         }
259         *offset_ptr = offset;
260         return true;
261     }
262     else
263     {
264         m_tag = 0;
265         m_has_children = false;
266         return true;    // NULL debug tag entry
267     }
268 
269     return false;
270 }
271 
272 //----------------------------------------------------------------------
273 // Extract
274 //
275 // Extract a debug info entry for a given compile unit from the
276 // .debug_info and .debug_abbrev data within the SymbolFileDWARF class
277 // starting at the given offset
278 //----------------------------------------------------------------------
279 bool
280 DWARFDebugInfoEntry::Extract
281 (
282     SymbolFileDWARF* dwarf2Data,
283     const DWARFCompileUnit* cu,
284     lldb::offset_t *offset_ptr
285 )
286 {
287     const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
288 //    const DWARFDataExtractor& debug_str_data = dwarf2Data->get_debug_str_data();
289     const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
290     lldb::offset_t offset = *offset_ptr;
291 //  if (offset >= cu_end_offset)
292 //      Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset);
293     if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset))
294     {
295         m_offset = offset;
296 
297         const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
298         assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
299         m_abbr_idx = abbr_idx;
300         if (abbr_idx)
301         {
302             const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
303 
304             if (abbrevDecl)
305             {
306                 m_tag = abbrevDecl->Tag();
307                 m_has_children = abbrevDecl->HasChildren();
308 
309                 bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
310                 if (cu && isCompileUnitTag)
311                     ((DWARFCompileUnit*)cu)->SetBaseAddress(0);
312 
313                 // Skip all data in the .debug_info for the attributes
314                 const uint32_t numAttributes = abbrevDecl->NumAttributes();
315                 uint32_t i;
316                 dw_attr_t attr;
317                 dw_form_t form;
318                 for (i=0; i<numAttributes; ++i)
319                 {
320                     abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
321 
322                     if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc)))
323                     {
324                         DWARFFormValue form_value(cu, form);
325                         if (form_value.ExtractValue(debug_info_data, &offset))
326                         {
327                             if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
328                                 ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned());
329                         }
330                     }
331                     else
332                     {
333                         bool form_is_indirect = false;
334                         do
335                         {
336                             form_is_indirect = false;
337                             uint32_t form_size = 0;
338                             switch (form)
339                             {
340                             // Blocks if inlined data that have a length field and the data bytes
341                             // inlined in the .debug_info
342                             case DW_FORM_exprloc     :
343                             case DW_FORM_block       : form_size = debug_info_data.GetULEB128(&offset);  break;
344                             case DW_FORM_block1      : form_size = debug_info_data.GetU8(&offset);       break;
345                             case DW_FORM_block2      : form_size = debug_info_data.GetU16(&offset);      break;
346                             case DW_FORM_block4      : form_size = debug_info_data.GetU32(&offset);      break;
347 
348                             // Inlined NULL terminated C-strings
349                             case DW_FORM_string      : debug_info_data.GetCStr(&offset);                 break;
350 
351                             // Compile unit address sized values
352                             case DW_FORM_addr        :
353                                 form_size = cu->GetAddressByteSize();
354                                 break;
355                             case DW_FORM_ref_addr    :
356                                 if (cu->GetVersion() <= 2)
357                                     form_size = cu->GetAddressByteSize();
358                                 else
359                                     form_size = cu->IsDWARF64() ? 8 : 4;
360                                 break;
361 
362                             // 0 sized form
363                             case DW_FORM_flag_present:
364                                 form_size = 0;
365                                 break;
366 
367                             // 1 byte values
368                             case DW_FORM_data1       :
369                             case DW_FORM_flag        :
370                             case DW_FORM_ref1        :
371                                 form_size = 1;
372                                 break;
373 
374                             // 2 byte values
375                             case DW_FORM_data2       :
376                             case DW_FORM_ref2        :
377                                 form_size = 2;
378                                 break;
379 
380                             // 4 byte values
381                             case DW_FORM_data4       :
382                             case DW_FORM_ref4        :
383                                 form_size = 4;
384                                 break;
385 
386                             // 8 byte values
387                             case DW_FORM_data8       :
388                             case DW_FORM_ref8        :
389                             case DW_FORM_ref_sig8    :
390                                 form_size = 8;
391                                 break;
392 
393                             // signed or unsigned LEB 128 values
394                             case DW_FORM_sdata         :
395                             case DW_FORM_udata         :
396                             case DW_FORM_ref_udata     :
397                             case DW_FORM_GNU_addr_index:
398                             case DW_FORM_GNU_str_index :
399                                 debug_info_data.Skip_LEB128(&offset);
400                                 break;
401 
402                             case DW_FORM_indirect    :
403                                 form = debug_info_data.GetULEB128(&offset);
404                                 form_is_indirect = true;
405                                 break;
406 
407                             case DW_FORM_strp        :
408                             case DW_FORM_sec_offset  :
409                                 if (cu->IsDWARF64 ())
410                                     debug_info_data.GetU64 (offset_ptr);
411                                 else
412                                     debug_info_data.GetU32 (offset_ptr);
413                                 break;
414 
415                             default:
416                                 *offset_ptr = offset;
417                                 return false;
418                             }
419 
420                             offset += form_size;
421                         } while (form_is_indirect);
422                     }
423                 }
424                 *offset_ptr = offset;
425                 return true;
426             }
427         }
428         else
429         {
430             m_tag = 0;
431             m_has_children = false;
432             *offset_ptr = offset;
433             return true;    // NULL debug tag entry
434         }
435     }
436 
437     return false;
438 }
439 
440 //----------------------------------------------------------------------
441 // DumpAncestry
442 //
443 // Dumps all of a debug information entries parents up until oldest and
444 // all of it's attributes to the specified stream.
445 //----------------------------------------------------------------------
446 void
447 DWARFDebugInfoEntry::DumpAncestry
448 (
449     SymbolFileDWARF* dwarf2Data,
450     const DWARFCompileUnit* cu,
451     const DWARFDebugInfoEntry* oldest,
452     Stream &s,
453     uint32_t recurse_depth
454 ) const
455 {
456     const DWARFDebugInfoEntry* parent = GetParent();
457     if (parent && parent != oldest)
458         parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
459     Dump(dwarf2Data, cu, s, recurse_depth);
460 }
461 
462 //----------------------------------------------------------------------
463 // Compare two DIE by comparing all their attributes values, and
464 // following all DW_FORM_ref attributes and comparing their contents as
465 // well (except for DW_AT_sibling attributes.
466 //
467 //  DWARFDebugInfoEntry::CompareState compare_state;
468 //  int result = DWARFDebugInfoEntry::Compare(this, 0x00017ccb, 0x0001eb2b, compare_state, false, true);
469 //----------------------------------------------------------------------
470 //int
471 //DWARFDebugInfoEntry::Compare
472 //(
473 //    SymbolFileDWARF* dwarf2Data,
474 //    dw_offset_t a_die_offset,
475 //    dw_offset_t b_die_offset,
476 //    CompareState &compare_state,
477 //    bool compare_siblings,
478 //    bool compare_children
479 //)
480 //{
481 //    if (a_die_offset == b_die_offset)
482 //        return 0;
483 //
484 //    DWARFCompileUnitSP a_cu_sp;
485 //    DWARFCompileUnitSP b_cu_sp;
486 //    const DWARFDebugInfoEntry* a_die = dwarf2Data->DebugInfo()->GetDIEPtr(a_die_offset, &a_cu_sp);
487 //    const DWARFDebugInfoEntry* b_die = dwarf2Data->DebugInfo()->GetDIEPtr(b_die_offset, &b_cu_sp);
488 //
489 //    return Compare(dwarf2Data, a_cu_sp.get(), a_die, b_cu_sp.get(), b_die, compare_state, compare_siblings, compare_children);
490 //}
491 //
492 //int
493 //DWARFDebugInfoEntry::Compare
494 //(
495 //    SymbolFileDWARF* dwarf2Data,
496 //    DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die,
497 //    DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die,
498 //    CompareState &compare_state,
499 //    bool compare_siblings,
500 //    bool compare_children
501 //)
502 //{
503 //    if (a_die == b_die)
504 //        return 0;
505 //
506 //    if (!compare_state.AddTypePair(a_die->GetOffset(), b_die->GetOffset()))
507 //    {
508 //        // We are already comparing both of these types, so let
509 //        // compares complete for the real result
510 //        return 0;
511 //    }
512 //
513 //    //printf("DWARFDebugInfoEntry::Compare(0x%8.8x, 0x%8.8x)\n", a_die->GetOffset(), b_die->GetOffset());
514 //
515 //    // Do we have two valid DIEs?
516 //    if (a_die && b_die)
517 //    {
518 //        // Both DIE are valid
519 //        int result = 0;
520 //
521 //        const dw_tag_t a_tag = a_die->Tag();
522 //        const dw_tag_t b_tag = b_die->Tag();
523 //        if (a_tag == 0 && b_tag == 0)
524 //            return 0;
525 //
526 //        //printf("    comparing tags: %s and %s\n", DW_TAG_value_to_name(a_tag), DW_TAG_value_to_name(b_tag));
527 //
528 //        if (a_tag < b_tag)
529 //            return -1;
530 //        else if (a_tag > b_tag)
531 //            return 1;
532 //
533 //        DWARFDebugInfoEntry::Attributes a_attrs;
534 //        DWARFDebugInfoEntry::Attributes b_attrs;
535 //        size_t a_attr_count = a_die->GetAttributes(dwarf2Data, a_cu, a_attrs);
536 //        size_t b_attr_count = b_die->GetAttributes(dwarf2Data, b_cu, b_attrs);
537 //        if (a_attr_count != b_attr_count)
538 //        {
539 //            a_attrs.RemoveAttribute(DW_AT_sibling);
540 //            b_attrs.RemoveAttribute(DW_AT_sibling);
541 //        }
542 //
543 //        a_attr_count = a_attrs.Size();
544 //        b_attr_count = b_attrs.Size();
545 //
546 //        DWARFFormValue a_form_value;
547 //        DWARFFormValue b_form_value;
548 //
549 //        if (a_attr_count != b_attr_count)
550 //        {
551 //            uint32_t is_decl_index = a_attrs.FindAttributeIndex(DW_AT_declaration);
552 //            uint32_t a_name_index = UINT32_MAX;
553 //            uint32_t b_name_index = UINT32_MAX;
554 //            if (is_decl_index != UINT32_MAX)
555 //            {
556 //                if (a_attr_count == 2)
557 //                {
558 //                    a_name_index = a_attrs.FindAttributeIndex(DW_AT_name);
559 //                    b_name_index = b_attrs.FindAttributeIndex(DW_AT_name);
560 //                }
561 //            }
562 //            else
563 //            {
564 //                is_decl_index = b_attrs.FindAttributeIndex(DW_AT_declaration);
565 //                if (is_decl_index != UINT32_MAX && a_attr_count == 2)
566 //                {
567 //                    a_name_index = a_attrs.FindAttributeIndex(DW_AT_name);
568 //                    b_name_index = b_attrs.FindAttributeIndex(DW_AT_name);
569 //                }
570 //            }
571 //            if (a_name_index != UINT32_MAX && b_name_index != UINT32_MAX)
572 //            {
573 //                if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, a_name_index, a_form_value) &&
574 //                    b_attrs.ExtractFormValueAtIndex(dwarf2Data, b_name_index, b_form_value))
575 //                {
576 //                    result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, &dwarf2Data->get_debug_str_data());
577 //                    if (result == 0)
578 //                    {
579 //                        a_attr_count = b_attr_count = 0;
580 //                        compare_children = false;
581 //                    }
582 //                }
583 //            }
584 //        }
585 //
586 //        if (a_attr_count < b_attr_count)
587 //            return -1;
588 //        if (a_attr_count > b_attr_count)
589 //            return 1;
590 //
591 //
592 //        // The number of attributes are the same...
593 //        if (a_attr_count > 0)
594 //        {
595 //            const DWARFDataExtractor* debug_str_data_ptr = &dwarf2Data->get_debug_str_data();
596 //
597 //            uint32_t i;
598 //            for (i=0; i<a_attr_count; ++i)
599 //            {
600 //                const dw_attr_t a_attr = a_attrs.AttributeAtIndex(i);
601 //                const dw_attr_t b_attr = b_attrs.AttributeAtIndex(i);
602 //                //printf("    comparing attributes\n\t\t0x%8.8x: %s %s\t\t0x%8.8x: %s %s\n",
603 //                //                a_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(a_attrs.FormAtIndex(i)), DW_AT_value_to_name(a_attr),
604 //                //                b_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(b_attrs.FormAtIndex(i)), DW_AT_value_to_name(b_attr));
605 //
606 //                if (a_attr < b_attr)
607 //                    return -1;
608 //                else if (a_attr > b_attr)
609 //                    return 1;
610 //
611 //                switch (a_attr)
612 //                {
613 //                // Since we call a form of GetAttributes which inlines the
614 //                // attributes from DW_AT_abstract_origin and DW_AT_specification
615 //                // we don't care if their values mismatch...
616 //                case DW_AT_abstract_origin:
617 //                case DW_AT_specification:
618 //                case DW_AT_sibling:
619 //                case DW_AT_containing_type:
620 //                    //printf("        action = IGNORE\n");
621 //                    result = 0;
622 //                    break;  // ignore
623 //
624 //                default:
625 //                    if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, i, a_form_value) &&
626 //                        b_attrs.ExtractFormValueAtIndex(dwarf2Data, i, b_form_value))
627 //                        result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, debug_str_data_ptr);
628 //                    break;
629 //                }
630 //
631 //                //printf("\t  result = %i\n", result);
632 //
633 //                if (result != 0)
634 //                {
635 //                    // Attributes weren't equal, lets see if we care?
636 //                    switch (a_attr)
637 //                    {
638 //                    case DW_AT_decl_file:
639 //                        // TODO: add the ability to compare files in two different compile units
640 //                        if (a_cu == b_cu)
641 //                        {
642 //                            //printf("        action = RETURN RESULT\n");
643 //                            return result;  // Only return the compare results when the compile units are the same and the decl_file attributes can be compared
644 //                        }
645 //                        else
646 //                        {
647 //                            result = 0;
648 //                            //printf("        action = IGNORE\n");
649 //                        }
650 //                        break;
651 //
652 //                    default:
653 //                        switch (a_attrs.FormAtIndex(i))
654 //                        {
655 //                        case DW_FORM_ref1:
656 //                        case DW_FORM_ref2:
657 //                        case DW_FORM_ref4:
658 //                        case DW_FORM_ref8:
659 //                        case DW_FORM_ref_udata:
660 //                        case DW_FORM_ref_addr:
661 //                            //printf("    action = COMPARE DIEs 0x%8.8x 0x%8.8x\n", (dw_offset_t)a_form_value.Reference(a_cu), (dw_offset_t)b_form_value.Reference(b_cu));
662 //                            // These attribute values refer to other DIEs, so lets compare those instead of their DIE offsets...
663 //                            result = Compare(dwarf2Data, a_form_value.Reference(a_cu), b_form_value.Reference(b_cu), compare_state, false, true);
664 //                            if (result != 0)
665 //                                return result;
666 //                            break;
667 //
668 //                        default:
669 //                            // We do care that they were different, return this result...
670 //                            //printf("        action = RETURN RESULT\n");
671 //                            return result;
672 //                        }
673 //                    }
674 //                }
675 //            }
676 //        }
677 //        //printf("    SUCCESS\n\t\t0x%8.8x: %s\n\t\t0x%8.8x: %s\n", a_die->GetOffset(), DW_TAG_value_to_name(a_tag), b_die->GetOffset(), DW_TAG_value_to_name(b_tag));
678 //
679 //        if (compare_children)
680 //        {
681 //            bool a_has_children = a_die->HasChildren();
682 //            bool b_has_children = b_die->HasChildren();
683 //            if (a_has_children == b_has_children)
684 //            {
685 //                // Both either have kids or don't
686 //                if (a_has_children)
687 //                    result = Compare(   dwarf2Data,
688 //                                        a_cu, a_die->GetFirstChild(),
689 //                                        b_cu, b_die->GetFirstChild(),
690 //                                        compare_state, true, compare_children);
691 //                else
692 //                    result = 0;
693 //            }
694 //            else if (!a_has_children)
695 //                result = -1;    // A doesn't have kids, but B does
696 //            else
697 //                result = 1; // A has kids, but B doesn't
698 //        }
699 //
700 //        if (compare_siblings)
701 //        {
702 //            result = Compare(   dwarf2Data,
703 //                                a_cu, a_die->GetSibling(),
704 //                                b_cu, b_die->GetSibling(),
705 //                                compare_state, true, compare_children);
706 //        }
707 //
708 //        return result;
709 //    }
710 //
711 //    if (a_die == NULL)
712 //        return -1;  // a_die is NULL, yet b_die is non-NULL
713 //    else
714 //        return 1;   // a_die is non-NULL, yet b_die is NULL
715 //
716 //}
717 //
718 //
719 //int
720 //DWARFDebugInfoEntry::Compare
721 //(
722 //  SymbolFileDWARF* dwarf2Data,
723 //  const DWARFCompileUnit* cu_a,
724 //  const DWARFDebugInfoEntry* die_a,
725 //  const DWARFCompileUnit* cu_a,
726 //  const DWARFDebugInfoEntry* die_b,
727 //  CompareState &compare_state
728 //)
729 //{
730 //}
731 
732 //----------------------------------------------------------------------
733 // GetDIENamesAndRanges
734 //
735 // Gets the valid address ranges for a given DIE by looking for a
736 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges
737 // attributes.
738 //----------------------------------------------------------------------
739 bool
740 DWARFDebugInfoEntry::GetDIENamesAndRanges
741 (
742     SymbolFileDWARF* dwarf2Data,
743     const DWARFCompileUnit* cu,
744     const char * &name,
745     const char * &mangled,
746     DWARFDebugRanges::RangeList& ranges,
747     int& decl_file,
748     int& decl_line,
749     int& decl_column,
750     int& call_file,
751     int& call_line,
752     int& call_column,
753     DWARFExpression *frame_base
754 ) const
755 {
756     if (dwarf2Data == NULL)
757         return false;
758 
759     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
760     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
761     std::vector<dw_offset_t> die_offsets;
762     bool set_frame_base_loclist_addr = false;
763 
764     lldb::offset_t offset;
765     const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
766 
767     lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
768 
769     if (abbrevDecl)
770     {
771         const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
772 
773         if (!debug_info_data.ValidOffset(offset))
774             return false;
775 
776         const uint32_t numAttributes = abbrevDecl->NumAttributes();
777         uint32_t i;
778         dw_attr_t attr;
779         dw_form_t form;
780         bool do_offset = false;
781 
782         for (i=0; i<numAttributes; ++i)
783         {
784             abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
785             DWARFFormValue form_value(cu, form);
786             if (form_value.ExtractValue(debug_info_data, &offset))
787             {
788                 switch (attr)
789                 {
790                 case DW_AT_low_pc:
791                     lo_pc = form_value.Unsigned();
792 
793                     if (do_offset)
794                         hi_pc += lo_pc;
795                     do_offset = false;
796                     break;
797 
798                 case DW_AT_entry_pc:
799                     lo_pc = form_value.Unsigned();
800                     break;
801 
802                 case DW_AT_high_pc:
803                     hi_pc = form_value.Unsigned();
804                     if (form_value.Form() != DW_FORM_addr)
805                     {
806                         if (lo_pc == LLDB_INVALID_ADDRESS)
807                             do_offset = hi_pc != LLDB_INVALID_ADDRESS;
808                         else
809                             hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save on relocations
810                     }
811                     break;
812 
813                 case DW_AT_ranges:
814                     {
815                         const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
816                         debug_ranges->FindRanges(form_value.Unsigned(), ranges);
817                         // All DW_AT_ranges are relative to the base address of the
818                         // compile unit. We add the compile unit base address to make
819                         // sure all the addresses are properly fixed up.
820                         ranges.Slide(cu->GetBaseAddress());
821                     }
822                     break;
823 
824                 case DW_AT_name:
825                     if (name == NULL)
826                         name = form_value.AsCString(dwarf2Data);
827                     break;
828 
829                 case DW_AT_MIPS_linkage_name:
830                 case DW_AT_linkage_name:
831                     if (mangled == NULL)
832                         mangled = form_value.AsCString(dwarf2Data);
833                     break;
834 
835                 case DW_AT_abstract_origin:
836                     die_offsets.push_back(form_value.Reference());
837                     break;
838 
839                 case DW_AT_specification:
840                     die_offsets.push_back(form_value.Reference());
841                     break;
842 
843                 case DW_AT_decl_file:
844                     if (decl_file == 0)
845                         decl_file = form_value.Unsigned();
846                     break;
847 
848                 case DW_AT_decl_line:
849                     if (decl_line == 0)
850                         decl_line = form_value.Unsigned();
851                     break;
852 
853                 case DW_AT_decl_column:
854                     if (decl_column == 0)
855                         decl_column = form_value.Unsigned();
856                     break;
857 
858                 case DW_AT_call_file:
859                     if (call_file == 0)
860                         call_file = form_value.Unsigned();
861                     break;
862 
863                 case DW_AT_call_line:
864                     if (call_line == 0)
865                         call_line = form_value.Unsigned();
866                     break;
867 
868                 case DW_AT_call_column:
869                     if (call_column == 0)
870                         call_column = form_value.Unsigned();
871                     break;
872 
873                 case DW_AT_frame_base:
874                     if (frame_base)
875                     {
876                         if (form_value.BlockData())
877                         {
878                             uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
879                             uint32_t block_length = form_value.Unsigned();
880                             frame_base->SetOpcodeData(module, debug_info_data, block_offset, block_length);
881                         }
882                         else
883                         {
884                             const DWARFDataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data();
885                             const dw_offset_t debug_loc_offset = form_value.Unsigned();
886 
887                             size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
888                             if (loc_list_length > 0)
889                             {
890                                 frame_base->SetOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
891                                 if (lo_pc != LLDB_INVALID_ADDRESS)
892                                 {
893                                     assert (lo_pc >= cu->GetBaseAddress());
894                                     frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress());
895                                 }
896                                 else
897                                 {
898                                     set_frame_base_loclist_addr = true;
899                                 }
900                             }
901                         }
902                     }
903                     break;
904 
905                 default:
906                     break;
907                 }
908             }
909         }
910     }
911 
912     if (ranges.IsEmpty())
913     {
914         if (lo_pc != LLDB_INVALID_ADDRESS)
915         {
916             if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
917                 ranges.Append(DWARFDebugRanges::Range (lo_pc, hi_pc - lo_pc));
918             else
919                 ranges.Append(DWARFDebugRanges::Range (lo_pc, 0));
920         }
921     }
922 
923     if (set_frame_base_loclist_addr)
924     {
925         dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
926         assert (lowest_range_pc >= cu->GetBaseAddress());
927         frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress());
928     }
929 
930     if (ranges.IsEmpty() || name == NULL || mangled == NULL)
931     {
932         std::vector<dw_offset_t>::const_iterator pos;
933         std::vector<dw_offset_t>::const_iterator end = die_offsets.end();
934         for (pos = die_offsets.begin(); pos != end; ++pos)
935         {
936             DWARFCompileUnitSP cu_sp_ptr;
937             const DWARFDebugInfoEntry* die = NULL;
938             dw_offset_t die_offset = *pos;
939             if (die_offset != DW_INVALID_OFFSET)
940             {
941                 die = dwarf2Data->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
942                 if (die)
943                     die->GetDIENamesAndRanges(dwarf2Data, cu_sp_ptr.get(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
944             }
945         }
946     }
947     return !ranges.IsEmpty();
948 }
949 
950 //----------------------------------------------------------------------
951 // Dump
952 //
953 // Dumps a debug information entry and all of it's attributes to the
954 // specified stream.
955 //----------------------------------------------------------------------
956 void
957 DWARFDebugInfoEntry::Dump
958 (
959     SymbolFileDWARF* dwarf2Data,
960     const DWARFCompileUnit* cu,
961     Stream &s,
962     uint32_t recurse_depth
963 ) const
964 {
965     const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
966     lldb::offset_t offset = m_offset;
967 
968     if (debug_info_data.ValidOffset(offset))
969     {
970         dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
971 
972         s.Printf("\n0x%8.8x: ", m_offset);
973         s.Indent();
974         if (abbrCode != m_abbr_idx)
975         {
976             s.Printf( "error: DWARF has been modified\n");
977         }
978         else if (abbrCode)
979         {
980             const DWARFAbbreviationDeclaration* abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration (abbrCode);
981 
982             if (abbrevDecl)
983             {
984                 s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
985                 s.Printf( " [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*':' ');
986 
987                 // Dump all data in the .debug_info for the attributes
988                 const uint32_t numAttributes = abbrevDecl->NumAttributes();
989                 uint32_t i;
990                 dw_attr_t attr;
991                 dw_form_t form;
992                 for (i=0; i<numAttributes; ++i)
993                 {
994                     abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
995 
996                     DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form);
997                 }
998 
999                 const DWARFDebugInfoEntry* child = GetFirstChild();
1000                 if (recurse_depth > 0 && child)
1001                 {
1002                     s.IndentMore();
1003 
1004                     while (child)
1005                     {
1006                         child->Dump(dwarf2Data, cu, s, recurse_depth-1);
1007                         child = child->GetSibling();
1008                     }
1009                     s.IndentLess();
1010                 }
1011             }
1012             else
1013                 s.Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode);
1014         }
1015         else
1016         {
1017             s.Printf( "NULL\n");
1018         }
1019     }
1020 }
1021 
1022 void
1023 DWARFDebugInfoEntry::DumpLocation
1024 (
1025     SymbolFileDWARF* dwarf2Data,
1026     DWARFCompileUnit* cu,
1027     Stream &s
1028 ) const
1029 {
1030     const DWARFDebugInfoEntry *cu_die = cu->GetCompileUnitDIEOnly();
1031     const char *cu_name = NULL;
1032     if (cu_die != NULL)
1033         cu_name = cu_die->GetName (dwarf2Data, cu);
1034     const char *obj_file_name = NULL;
1035     ObjectFile *obj_file = dwarf2Data->GetObjectFile();
1036     if (obj_file)
1037         obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>");
1038     const char *die_name = GetName (dwarf2Data, cu);
1039     s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)",
1040               cu->GetOffset(),
1041               GetOffset(),
1042               die_name ? die_name : "",
1043               cu_name ? cu_name : "<NULL>",
1044               obj_file_name ? obj_file_name : "<NULL>");
1045 }
1046 
1047 //----------------------------------------------------------------------
1048 // DumpAttribute
1049 //
1050 // Dumps a debug information entry attribute along with it's form. Any
1051 // special display of attributes is done (disassemble location lists,
1052 // show enumeration values for attributes, etc).
1053 //----------------------------------------------------------------------
1054 void
1055 DWARFDebugInfoEntry::DumpAttribute
1056 (
1057     SymbolFileDWARF* dwarf2Data,
1058     const DWARFCompileUnit* cu,
1059     const DWARFDataExtractor& debug_info_data,
1060     lldb::offset_t *offset_ptr,
1061     Stream &s,
1062     dw_attr_t attr,
1063     dw_form_t form
1064 )
1065 {
1066     bool verbose    = s.GetVerbose();
1067     bool show_form  = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
1068 
1069     if (verbose)
1070         s.Offset (*offset_ptr);
1071     else
1072         s.Printf ("            ");
1073     s.Indent(DW_AT_value_to_name(attr));
1074 
1075     if (show_form)
1076     {
1077         s.Printf( "[%s", DW_FORM_value_to_name(form));
1078     }
1079 
1080     DWARFFormValue form_value(cu, form);
1081 
1082     if (!form_value.ExtractValue(debug_info_data, offset_ptr))
1083         return;
1084 
1085     if (show_form)
1086     {
1087         if (form == DW_FORM_indirect)
1088         {
1089             s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form()));
1090         }
1091 
1092         s.PutCString("] ");
1093     }
1094 
1095     s.PutCString("( ");
1096 
1097     // Always dump form value if verbose is enabled
1098     if (verbose)
1099     {
1100         form_value.Dump(s, dwarf2Data);
1101     }
1102 
1103 
1104     // Check to see if we have any special attribute formatters
1105     switch (attr)
1106     {
1107     case DW_AT_stmt_list:
1108         if ( verbose ) s.PutCString(" ( ");
1109         s.Printf( "0x%8.8" PRIx64, form_value.Unsigned());
1110         if ( verbose ) s.PutCString(" )");
1111         break;
1112 
1113     case DW_AT_language:
1114         if ( verbose ) s.PutCString(" ( ");
1115         s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
1116         if ( verbose ) s.PutCString(" )");
1117         break;
1118 
1119     case DW_AT_encoding:
1120         if ( verbose ) s.PutCString(" ( ");
1121         s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
1122         if ( verbose ) s.PutCString(" )");
1123         break;
1124 
1125     case DW_AT_frame_base:
1126     case DW_AT_location:
1127     case DW_AT_data_member_location:
1128         {
1129             const uint8_t* blockData = form_value.BlockData();
1130             if (blockData)
1131             {
1132                 if (!verbose)
1133                     form_value.Dump(s, dwarf2Data);
1134 
1135                 // Location description is inlined in data in the form value
1136                 DWARFDataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned());
1137                 if ( verbose ) s.PutCString(" ( ");
1138                 print_dwarf_expression (s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
1139                 if ( verbose ) s.PutCString(" )");
1140             }
1141             else
1142             {
1143                 // We have a location list offset as the value that is
1144                 // the offset into the .debug_loc section that describes
1145                 // the value over it's lifetime
1146                 uint64_t debug_loc_offset = form_value.Unsigned();
1147                 if (dwarf2Data)
1148                 {
1149                     if ( !verbose )
1150                         form_value.Dump(s, dwarf2Data);
1151                     DWARFLocationList::Dump(s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
1152                 }
1153                 else
1154                 {
1155                     if ( !verbose )
1156                         form_value.Dump(s, NULL);
1157                 }
1158             }
1159         }
1160         break;
1161 
1162     case DW_AT_abstract_origin:
1163     case DW_AT_specification:
1164         {
1165             uint64_t abstract_die_offset = form_value.Reference();
1166             form_value.Dump(s, dwarf2Data);
1167         //  *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
1168             if ( verbose ) s.PutCString(" ( ");
1169             GetName(dwarf2Data, cu, abstract_die_offset, s);
1170             if ( verbose ) s.PutCString(" )");
1171         }
1172         break;
1173 
1174     case DW_AT_type:
1175         {
1176             uint64_t type_die_offset = form_value.Reference();
1177             if (!verbose)
1178                 form_value.Dump(s, dwarf2Data);
1179             s.PutCString(" ( ");
1180             AppendTypeName(dwarf2Data, cu, type_die_offset, s);
1181             s.PutCString(" )");
1182         }
1183         break;
1184 
1185     case DW_AT_ranges:
1186         {
1187             if ( !verbose )
1188                 form_value.Dump(s, dwarf2Data);
1189             lldb::offset_t ranges_offset = form_value.Unsigned();
1190             dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
1191             if (dwarf2Data)
1192                 DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
1193         }
1194         break;
1195 
1196     default:
1197         if ( !verbose )
1198             form_value.Dump(s, dwarf2Data);
1199         break;
1200     }
1201 
1202     s.PutCString(" )\n");
1203 }
1204 
1205 //----------------------------------------------------------------------
1206 // Get all attribute values for a given DIE, including following any
1207 // specification or abstract origin attributes and including those in
1208 // the results. Any duplicate attributes will have the first instance
1209 // take precedence (this can happen for declaration attributes).
1210 //----------------------------------------------------------------------
1211 size_t
1212 DWARFDebugInfoEntry::GetAttributes
1213 (
1214     SymbolFileDWARF* dwarf2Data,
1215     const DWARFCompileUnit* cu,
1216     DWARFFormValue::FixedFormSizes fixed_form_sizes,
1217     DWARFDebugInfoEntry::Attributes& attributes,
1218     uint32_t curr_depth
1219 ) const
1220 {
1221     lldb::offset_t offset;
1222     const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
1223 
1224     if (abbrevDecl)
1225     {
1226         const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
1227 
1228         if (fixed_form_sizes.Empty())
1229             fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
1230                     cu->GetAddressByteSize(), cu->IsDWARF64());
1231 
1232         const uint32_t num_attributes = abbrevDecl->NumAttributes();
1233         uint32_t i;
1234         dw_attr_t attr;
1235         dw_form_t form;
1236         for (i=0; i<num_attributes; ++i)
1237         {
1238             abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form);
1239 
1240             // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
1241             // attributes, the depth will be non-zero. We need to omit certain
1242             // attributes that don't make sense.
1243             switch (attr)
1244             {
1245             case DW_AT_sibling:
1246             case DW_AT_declaration:
1247                 if (curr_depth > 0)
1248                 {
1249                     // This attribute doesn't make sense when combined with
1250                     // the DIE that references this DIE. We know a DIE is
1251                     // referencing this DIE because curr_depth is not zero
1252                     break;
1253                 }
1254                 // Fall through...
1255             default:
1256                 attributes.Append(cu, offset, attr, form);
1257                 break;
1258             }
1259 
1260             if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))
1261             {
1262                 DWARFFormValue form_value (cu, form);
1263                 if (form_value.ExtractValue(debug_info_data, &offset))
1264                 {
1265                     const DWARFDebugInfoEntry* die = NULL;
1266                     dw_offset_t die_offset = form_value.Reference();
1267                     if (cu->ContainsDIEOffset(die_offset))
1268                     {
1269                         die = const_cast<DWARFCompileUnit*>(cu)->GetDIEPtr(die_offset);
1270                         if (die)
1271                             die->GetAttributes(dwarf2Data, cu, fixed_form_sizes, attributes, curr_depth + 1);
1272                     }
1273                     else
1274                     {
1275                         DWARFCompileUnitSP cu_sp_ptr;
1276                         die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
1277                         if (die)
1278                             die->GetAttributes(dwarf2Data, cu_sp_ptr.get(), fixed_form_sizes, attributes, curr_depth + 1);
1279                     }
1280                 }
1281             }
1282             else
1283             {
1284                 const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
1285                 if (fixed_skip_size)
1286                     offset += fixed_skip_size;
1287                 else
1288                     DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
1289             }
1290         }
1291     }
1292     else
1293     {
1294         attributes.Clear();
1295     }
1296     return attributes.Size();
1297 
1298 }
1299 
1300 //----------------------------------------------------------------------
1301 // GetAttributeValue
1302 //
1303 // Get the value of an attribute and return the .debug_info offset of the
1304 // attribute if it was properly extracted into form_value, or zero
1305 // if we fail since an offset of zero is invalid for an attribute (it
1306 // would be a compile unit header).
1307 //----------------------------------------------------------------------
1308 dw_offset_t
1309 DWARFDebugInfoEntry::GetAttributeValue
1310 (
1311     SymbolFileDWARF* dwarf2Data,
1312     const DWARFCompileUnit* cu,
1313     const dw_attr_t attr,
1314     DWARFFormValue& form_value,
1315     dw_offset_t* end_attr_offset_ptr
1316 ) const
1317 {
1318     lldb::offset_t offset;
1319     const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
1320 
1321     if (abbrevDecl)
1322     {
1323         uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
1324 
1325         if (attr_idx != DW_INVALID_INDEX)
1326         {
1327             const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
1328 
1329             uint32_t idx=0;
1330             while (idx<attr_idx)
1331                 DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu);
1332 
1333             const dw_offset_t attr_offset = offset;
1334             form_value.SetCompileUnit(cu);
1335             form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
1336             if (form_value.ExtractValue(debug_info_data, &offset))
1337             {
1338                 if (end_attr_offset_ptr)
1339                     *end_attr_offset_ptr = offset;
1340                 return attr_offset;
1341             }
1342         }
1343     }
1344 
1345     return 0;
1346 }
1347 
1348 //----------------------------------------------------------------------
1349 // GetAttributeValueAsString
1350 //
1351 // Get the value of an attribute as a string return it. The resulting
1352 // pointer to the string data exists within the supplied SymbolFileDWARF
1353 // and will only be available as long as the SymbolFileDWARF is still around
1354 // and it's content doesn't change.
1355 //----------------------------------------------------------------------
1356 const char*
1357 DWARFDebugInfoEntry::GetAttributeValueAsString
1358 (
1359     SymbolFileDWARF* dwarf2Data,
1360     const DWARFCompileUnit* cu,
1361     const dw_attr_t attr,
1362     const char* fail_value) const
1363 {
1364     DWARFFormValue form_value;
1365     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1366         return form_value.AsCString(dwarf2Data);
1367     return fail_value;
1368 }
1369 
1370 //----------------------------------------------------------------------
1371 // GetAttributeValueAsUnsigned
1372 //
1373 // Get the value of an attribute as unsigned and return it.
1374 //----------------------------------------------------------------------
1375 uint64_t
1376 DWARFDebugInfoEntry::GetAttributeValueAsUnsigned
1377 (
1378     SymbolFileDWARF* dwarf2Data,
1379     const DWARFCompileUnit* cu,
1380     const dw_attr_t attr,
1381     uint64_t fail_value
1382 ) const
1383 {
1384     DWARFFormValue form_value;
1385     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1386         return form_value.Unsigned();
1387     return fail_value;
1388 }
1389 
1390 //----------------------------------------------------------------------
1391 // GetAttributeValueAsSigned
1392 //
1393 // Get the value of an attribute a signed value and return it.
1394 //----------------------------------------------------------------------
1395 int64_t
1396 DWARFDebugInfoEntry::GetAttributeValueAsSigned
1397 (
1398     SymbolFileDWARF* dwarf2Data,
1399     const DWARFCompileUnit* cu,
1400     const dw_attr_t attr,
1401     int64_t fail_value
1402 ) const
1403 {
1404     DWARFFormValue form_value;
1405     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1406         return form_value.Signed();
1407     return fail_value;
1408 }
1409 
1410 //----------------------------------------------------------------------
1411 // GetAttributeValueAsReference
1412 //
1413 // Get the value of an attribute as reference and fix up and compile
1414 // unit relative offsets as needed.
1415 //----------------------------------------------------------------------
1416 uint64_t
1417 DWARFDebugInfoEntry::GetAttributeValueAsReference
1418 (
1419     SymbolFileDWARF* dwarf2Data,
1420     const DWARFCompileUnit* cu,
1421     const dw_attr_t attr,
1422     uint64_t fail_value
1423 ) const
1424 {
1425     DWARFFormValue form_value;
1426     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1427         return form_value.Reference();
1428     return fail_value;
1429 }
1430 
1431 //----------------------------------------------------------------------
1432 // GetAttributeHighPC
1433 //
1434 // Get the hi_pc, adding hi_pc to lo_pc when specified
1435 // as an <offset-from-low-pc>.
1436 //
1437 // Returns the hi_pc or fail_value.
1438 //----------------------------------------------------------------------
1439 dw_addr_t
1440 DWARFDebugInfoEntry::GetAttributeHighPC
1441 (
1442     SymbolFileDWARF* dwarf2Data,
1443     const DWARFCompileUnit* cu,
1444     dw_addr_t lo_pc,
1445     uint64_t fail_value
1446 ) const
1447 {
1448     DWARFFormValue form_value;
1449     if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value))
1450     {
1451         dw_form_t form = form_value.Form();
1452         if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
1453             return form_value.Address(dwarf2Data);
1454 
1455         // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
1456         return lo_pc + form_value.Unsigned();
1457     }
1458     return fail_value;
1459 }
1460 
1461 //----------------------------------------------------------------------
1462 // GetAttributeAddressRange
1463 //
1464 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified
1465 // as an <offset-from-low-pc>.
1466 //
1467 // Returns true or sets lo_pc and hi_pc to fail_value.
1468 //----------------------------------------------------------------------
1469 bool
1470 DWARFDebugInfoEntry::GetAttributeAddressRange
1471 (
1472     SymbolFileDWARF* dwarf2Data,
1473     const DWARFCompileUnit* cu,
1474     dw_addr_t& lo_pc,
1475     dw_addr_t& hi_pc,
1476     uint64_t fail_value
1477 ) const
1478 {
1479     lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, fail_value);
1480     if (lo_pc != fail_value)
1481     {
1482         hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value);
1483         if (hi_pc != fail_value)
1484           return true;
1485     }
1486     lo_pc = fail_value;
1487     hi_pc = fail_value;
1488     return false;
1489 }
1490 
1491 size_t
1492 DWARFDebugInfoEntry::GetAttributeAddressRanges(SymbolFileDWARF* dwarf2Data,
1493                                                const DWARFCompileUnit* cu,
1494                                                DWARFDebugRanges::RangeList &ranges,
1495                                                bool check_hi_lo_pc) const
1496 {
1497     ranges.Clear();
1498 
1499     dw_offset_t ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
1500     if (ranges_offset != DW_INVALID_OFFSET)
1501     {
1502         dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
1503         if (debug_ranges_offset != DW_INVALID_OFFSET)
1504         {
1505             DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
1506 
1507             debug_ranges->FindRanges(debug_ranges_offset, ranges);
1508             ranges.Slide (cu->GetBaseAddress());
1509         }
1510     }
1511     else if (check_hi_lo_pc)
1512     {
1513         dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1514         dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1515         if (GetAttributeAddressRange (dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
1516         {
1517             if (lo_pc < hi_pc)
1518                 ranges.Append(DWARFDebugRanges::RangeList::Entry(lo_pc, hi_pc - lo_pc));
1519         }
1520     }
1521     return ranges.GetSize();
1522 }
1523 
1524 //----------------------------------------------------------------------
1525 // GetAttributeValueAsLocation
1526 //
1527 // Get the value of an attribute as reference and fix up and compile
1528 // unit relative offsets as needed.
1529 //----------------------------------------------------------------------
1530 dw_offset_t
1531 DWARFDebugInfoEntry::GetAttributeValueAsLocation
1532 (
1533     SymbolFileDWARF* dwarf2Data,
1534     const DWARFCompileUnit* cu,
1535     const dw_attr_t attr,
1536     DWARFDataExtractor& location_data,
1537     uint32_t &block_size
1538 ) const
1539 {
1540     block_size = 0;
1541     DWARFFormValue form_value;
1542 
1543     // Empty out data in case we don't find anything
1544     location_data.Clear();
1545     dw_offset_t end_addr_offset = DW_INVALID_OFFSET;
1546     const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset);
1547     if (attr_offset)
1548     {
1549         const uint8_t* blockData = form_value.BlockData();
1550         if (blockData)
1551         {
1552             // We have an inlined location list in the .debug_info section
1553             const DWARFDataExtractor& debug_info = dwarf2Data->get_debug_info_data();
1554             dw_offset_t block_offset = blockData - debug_info.GetDataStart();
1555             block_size = (end_addr_offset - attr_offset) - form_value.Unsigned();
1556             location_data.SetData(debug_info, block_offset, block_size);
1557         }
1558         else
1559         {
1560             // We have a location list offset as the value that is
1561             // the offset into the .debug_loc section that describes
1562             // the value over it's lifetime
1563             lldb::offset_t debug_loc_offset = form_value.Unsigned();
1564             if (dwarf2Data)
1565             {
1566                 assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
1567                 return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data);
1568             }
1569         }
1570     }
1571     return attr_offset;
1572 }
1573 
1574 //----------------------------------------------------------------------
1575 // GetName
1576 //
1577 // Get value of the DW_AT_name attribute and return it if one exists,
1578 // else return NULL.
1579 //----------------------------------------------------------------------
1580 const char*
1581 DWARFDebugInfoEntry::GetName
1582 (
1583     SymbolFileDWARF* dwarf2Data,
1584     const DWARFCompileUnit* cu
1585 ) const
1586 {
1587     DWARFFormValue form_value;
1588     if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1589         return form_value.AsCString(dwarf2Data);
1590     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
1591     {
1592         DWARFCompileUnitSP cu_sp_ptr;
1593         const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr);
1594         if (die)
1595             return die->GetName(dwarf2Data, cu_sp_ptr.get());
1596     }
1597     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value))
1598     {
1599         DWARFCompileUnitSP cu_sp_ptr;
1600         const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr);
1601         if (die)
1602             return die->GetName(dwarf2Data, cu_sp_ptr.get());
1603     }
1604     return nullptr;
1605 }
1606 
1607 
1608 //----------------------------------------------------------------------
1609 // GetMangledName
1610 //
1611 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if
1612 // one exists, else return the value of the DW_AT_name attribute
1613 //----------------------------------------------------------------------
1614 const char*
1615 DWARFDebugInfoEntry::GetMangledName
1616 (
1617     SymbolFileDWARF* dwarf2Data,
1618     const DWARFCompileUnit* cu,
1619     bool substitute_name_allowed
1620 ) const
1621 {
1622     const char* name = nullptr;
1623     DWARFFormValue form_value;
1624 
1625     if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
1626         name = form_value.AsCString(dwarf2Data);
1627 
1628     if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
1629         name = form_value.AsCString(dwarf2Data);
1630 
1631     if (substitute_name_allowed && name == nullptr)
1632     {
1633         if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1634             name = form_value.AsCString(dwarf2Data);
1635     }
1636     return name;
1637 }
1638 
1639 
1640 //----------------------------------------------------------------------
1641 // GetPubname
1642 //
1643 // Get value the name for a DIE as it should appear for a
1644 // .debug_pubnames or .debug_pubtypes section.
1645 //----------------------------------------------------------------------
1646 const char*
1647 DWARFDebugInfoEntry::GetPubname
1648 (
1649     SymbolFileDWARF* dwarf2Data,
1650     const DWARFCompileUnit* cu
1651 ) const
1652 {
1653     const char* name = NULL;
1654     if (!dwarf2Data)
1655         return name;
1656 
1657     DWARFFormValue form_value;
1658 
1659     if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
1660         name = form_value.AsCString(dwarf2Data);
1661     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
1662         name = form_value.AsCString(dwarf2Data);
1663     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1664         name = form_value.AsCString(dwarf2Data);
1665     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
1666     {
1667         // The specification DIE may be in another compile unit so we need
1668         // to get a die and its compile unit.
1669         DWARFCompileUnitSP cu_sp_ptr;
1670         const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr);
1671         if (die)
1672             return die->GetPubname(dwarf2Data, cu_sp_ptr.get());
1673     }
1674     return name;
1675 }
1676 
1677 
1678 //----------------------------------------------------------------------
1679 // GetName
1680 //
1681 // Get value of the DW_AT_name attribute for a debug information entry
1682 // that exists at offset "die_offset" and place that value into the
1683 // supplied stream object. If the DIE is a NULL object "NULL" is placed
1684 // into the stream, and if no DW_AT_name attribute exists for the DIE
1685 // then nothing is printed.
1686 //----------------------------------------------------------------------
1687 bool
1688 DWARFDebugInfoEntry::GetName
1689 (
1690     SymbolFileDWARF* dwarf2Data,
1691     const DWARFCompileUnit* cu,
1692     const dw_offset_t die_offset,
1693     Stream &s
1694 )
1695 {
1696     if (dwarf2Data == NULL)
1697     {
1698         s.PutCString("NULL");
1699         return false;
1700     }
1701 
1702     DWARFDebugInfoEntry die;
1703     lldb::offset_t offset = die_offset;
1704     if (die.Extract(dwarf2Data, cu, &offset))
1705     {
1706         if (die.IsNULL())
1707         {
1708             s.PutCString("NULL");
1709             return true;
1710         }
1711         else
1712         {
1713             DWARFFormValue form_value;
1714             if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1715             {
1716                 const char* name = form_value.AsCString(dwarf2Data);
1717                 if (name)
1718                 {
1719                     s.PutCString(name);
1720                     return true;
1721                 }
1722             }
1723         }
1724     }
1725     return false;
1726 }
1727 
1728 //----------------------------------------------------------------------
1729 // AppendTypeName
1730 //
1731 // Follows the type name definition down through all needed tags to
1732 // end up with a fully qualified type name and dump the results to
1733 // the supplied stream. This is used to show the name of types given
1734 // a type identifier.
1735 //----------------------------------------------------------------------
1736 bool
1737 DWARFDebugInfoEntry::AppendTypeName
1738 (
1739     SymbolFileDWARF* dwarf2Data,
1740     const DWARFCompileUnit* cu,
1741     const dw_offset_t die_offset,
1742     Stream &s
1743 )
1744 {
1745     if (dwarf2Data == NULL)
1746     {
1747         s.PutCString("NULL");
1748         return false;
1749     }
1750 
1751     DWARFDebugInfoEntry die;
1752     lldb::offset_t offset = die_offset;
1753     if (die.Extract(dwarf2Data, cu, &offset))
1754     {
1755         if (die.IsNULL())
1756         {
1757             s.PutCString("NULL");
1758             return true;
1759         }
1760         else
1761         {
1762             const char* name = die.GetPubname(dwarf2Data, cu);
1763         //  if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1764         //      name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1765             if (name)
1766                 s.PutCString(name);
1767             else
1768             {
1769                 bool result = true;
1770                 const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
1771 
1772                 if (abbrevDecl == NULL)
1773                     return false;
1774 
1775                 switch (abbrevDecl->Tag())
1776                 {
1777                 case DW_TAG_array_type:         break;  // print out a "[]" after printing the full type of the element below
1778                 case DW_TAG_base_type:          s.PutCString("base ");         break;
1779                 case DW_TAG_class_type:         s.PutCString("class ");            break;
1780                 case DW_TAG_const_type:         s.PutCString("const ");            break;
1781                 case DW_TAG_enumeration_type:   s.PutCString("enum ");         break;
1782                 case DW_TAG_file_type:          s.PutCString("file ");         break;
1783                 case DW_TAG_interface_type:     s.PutCString("interface ");        break;
1784                 case DW_TAG_packed_type:        s.PutCString("packed ");       break;
1785                 case DW_TAG_pointer_type:       break;  // print out a '*' after printing the full type below
1786                 case DW_TAG_ptr_to_member_type: break;  // print out a '*' after printing the full type below
1787                 case DW_TAG_reference_type:     break;  // print out a '&' after printing the full type below
1788                 case DW_TAG_restrict_type:      s.PutCString("restrict ");     break;
1789                 case DW_TAG_set_type:           s.PutCString("set ");          break;
1790                 case DW_TAG_shared_type:        s.PutCString("shared ");       break;
1791                 case DW_TAG_string_type:        s.PutCString("string ");       break;
1792                 case DW_TAG_structure_type:     s.PutCString("struct ");       break;
1793                 case DW_TAG_subrange_type:      s.PutCString("subrange ");     break;
1794                 case DW_TAG_subroutine_type:    s.PutCString("function ");     break;
1795                 case DW_TAG_thrown_type:        s.PutCString("thrown ");       break;
1796                 case DW_TAG_union_type:         s.PutCString("union ");            break;
1797                 case DW_TAG_unspecified_type:   s.PutCString("unspecified ");  break;
1798                 case DW_TAG_volatile_type:      s.PutCString("volatile ");     break;
1799                 default:
1800                     return false;
1801                 }
1802 
1803                 // Follow the DW_AT_type if possible
1804                 DWARFFormValue form_value;
1805                 if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value))
1806                 {
1807                     uint64_t next_die_offset = form_value.Reference();
1808                     result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
1809                 }
1810 
1811                 switch (abbrevDecl->Tag())
1812                 {
1813                 case DW_TAG_array_type:         s.PutCString("[]");    break;
1814                 case DW_TAG_pointer_type:       s.PutChar('*');    break;
1815                 case DW_TAG_ptr_to_member_type: s.PutChar('*');    break;
1816                 case DW_TAG_reference_type:     s.PutChar('&');    break;
1817                 default:
1818                     break;
1819                 }
1820                 return result;
1821             }
1822         }
1823     }
1824     return false;
1825 }
1826 
1827 bool
1828 DWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const
1829 {
1830     if (die)
1831     {
1832         const dw_offset_t die_offset = die->GetOffset();
1833         if (die_offset > GetOffset())
1834         {
1835             const DWARFDebugInfoEntry *sibling = GetSibling();
1836             assert (sibling); // TODO: take this out
1837             if (sibling)
1838                 return die_offset < sibling->GetOffset();
1839         }
1840     }
1841     return false;
1842 }
1843 
1844 //----------------------------------------------------------------------
1845 // BuildAddressRangeTable
1846 //----------------------------------------------------------------------
1847 void
1848 DWARFDebugInfoEntry::BuildAddressRangeTable
1849 (
1850     SymbolFileDWARF* dwarf2Data,
1851     const DWARFCompileUnit* cu,
1852     DWARFDebugAranges* debug_aranges
1853 ) const
1854 {
1855     if (m_tag)
1856     {
1857         if (m_tag == DW_TAG_subprogram)
1858         {
1859             dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1860             dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1861             if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
1862             {
1863                 /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
1864                 debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc);
1865             }
1866         }
1867 
1868 
1869         const DWARFDebugInfoEntry* child = GetFirstChild();
1870         while (child)
1871         {
1872             child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
1873             child = child->GetSibling();
1874         }
1875     }
1876 }
1877 
1878 //----------------------------------------------------------------------
1879 // BuildFunctionAddressRangeTable
1880 //
1881 // This function is very similar to the BuildAddressRangeTable function
1882 // except that the actual DIE offset for the function is placed in the
1883 // table instead of the compile unit offset (which is the way the
1884 // standard .debug_aranges section does it).
1885 //----------------------------------------------------------------------
1886 void
1887 DWARFDebugInfoEntry::BuildFunctionAddressRangeTable
1888 (
1889     SymbolFileDWARF* dwarf2Data,
1890     const DWARFCompileUnit* cu,
1891     DWARFDebugAranges* debug_aranges
1892 ) const
1893 {
1894     if (m_tag)
1895     {
1896         if (m_tag == DW_TAG_subprogram)
1897         {
1898             dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1899             dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1900             if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
1901             {
1902             //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
1903                 debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc);
1904             }
1905         }
1906 
1907         const DWARFDebugInfoEntry* child = GetFirstChild();
1908         while (child)
1909         {
1910             child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
1911             child = child->GetSibling();
1912         }
1913     }
1914 }
1915 
1916 void
1917 DWARFDebugInfoEntry::GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data,
1918                                          DWARFCompileUnit* cu,
1919                                          DWARFDIECollection &decl_context_dies) const
1920 {
1921     const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
1922     if (parent_decl_ctx_die && parent_decl_ctx_die != this)
1923     {
1924         decl_context_dies.Append(parent_decl_ctx_die);
1925         parent_decl_ctx_die->GetDeclContextDIEs (dwarf2Data, cu, decl_context_dies);
1926     }
1927 }
1928 
1929 void
1930 DWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
1931                                           DWARFCompileUnit* cu,
1932                                           DWARFDeclContext &dwarf_decl_ctx) const
1933 {
1934     const dw_tag_t tag = Tag();
1935     if (tag != DW_TAG_compile_unit)
1936     {
1937         dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
1938         const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
1939         if (parent_decl_ctx_die && parent_decl_ctx_die != this)
1940         {
1941             if (parent_decl_ctx_die->Tag() != DW_TAG_compile_unit)
1942                 parent_decl_ctx_die->GetDWARFDeclContext (dwarf2Data, cu, dwarf_decl_ctx);
1943         }
1944     }
1945 }
1946 
1947 
1948 bool
1949 DWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
1950                                               DWARFCompileUnit* cu,
1951                                               const DWARFDeclContext &dwarf_decl_ctx) const
1952 {
1953 
1954     DWARFDeclContext this_dwarf_decl_ctx;
1955     GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx);
1956     return this_dwarf_decl_ctx == dwarf_decl_ctx;
1957 }
1958 
1959 const DWARFDebugInfoEntry *
1960 DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
1961 											  DWARFCompileUnit* cu) const
1962 {
1963 	DWARFDebugInfoEntry::Attributes attributes;
1964 	GetAttributes(dwarf2Data, cu, DWARFFormValue::FixedFormSizes(), attributes);
1965 	return GetParentDeclContextDIE (dwarf2Data, cu, attributes);
1966 }
1967 
1968 const DWARFDebugInfoEntry *
1969 DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
1970 											  DWARFCompileUnit* cu,
1971 											  const DWARFDebugInfoEntry::Attributes& attributes) const
1972 {
1973 	const DWARFDebugInfoEntry * die = this;
1974 
1975 	while (die != NULL)
1976 	{
1977 		// If this is the original DIE that we are searching for a declaration
1978 		// for, then don't look in the cache as we don't want our own decl
1979 		// context to be our decl context...
1980 		if (die != this)
1981 		{
1982 			switch (die->Tag())
1983 			{
1984 				case DW_TAG_compile_unit:
1985 				case DW_TAG_namespace:
1986 				case DW_TAG_structure_type:
1987 				case DW_TAG_union_type:
1988 				case DW_TAG_class_type:
1989 					return die;
1990 
1991 				default:
1992 					break;
1993 			}
1994 		}
1995 
1996 		dw_offset_t die_offset;
1997 
1998 		die_offset = attributes.FormValueAsUnsigned(dwarf2Data, DW_AT_specification, DW_INVALID_OFFSET);
1999 		if (die_offset != DW_INVALID_OFFSET)
2000 		{
2001 			const DWARFDebugInfoEntry *spec_die = cu->GetDIEPtr (die_offset);
2002 			if (spec_die)
2003 			{
2004 				const DWARFDebugInfoEntry *spec_die_decl_ctx_die = spec_die->GetParentDeclContextDIE (dwarf2Data, cu);
2005 				if (spec_die_decl_ctx_die)
2006 					return spec_die_decl_ctx_die;
2007 			}
2008 		}
2009 
2010         die_offset = attributes.FormValueAsUnsigned(dwarf2Data, DW_AT_abstract_origin, DW_INVALID_OFFSET);
2011 		if (die_offset != DW_INVALID_OFFSET)
2012 		{
2013 			const DWARFDebugInfoEntry *abs_die = cu->GetDIEPtr (die_offset);
2014 			if (abs_die)
2015 			{
2016 				const DWARFDebugInfoEntry *abs_die_decl_ctx_die = abs_die->GetParentDeclContextDIE (dwarf2Data, cu);
2017 				if (abs_die_decl_ctx_die)
2018 					return abs_die_decl_ctx_die;
2019 			}
2020 		}
2021 
2022 		die = die->GetParent();
2023 	}
2024     return NULL;
2025 }
2026 
2027 
2028 const char *
2029 DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
2030 									   DWARFCompileUnit* cu,
2031 									   std::string &storage) const
2032 {
2033 	DWARFDebugInfoEntry::Attributes attributes;
2034 	GetAttributes(dwarf2Data, cu, DWARFFormValue::FixedFormSizes(), attributes);
2035 	return GetQualifiedName (dwarf2Data, cu, attributes, storage);
2036 }
2037 
2038 const char*
2039 DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
2040 									   DWARFCompileUnit* cu,
2041 									   const DWARFDebugInfoEntry::Attributes& attributes,
2042 									   std::string &storage) const
2043 {
2044 
2045 	const char *name = GetName (dwarf2Data, cu);
2046 
2047 	if (name)
2048 	{
2049 		const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
2050 		storage.clear();
2051 		// TODO: change this to get the correct decl context parent....
2052 		while (parent_decl_ctx_die)
2053 		{
2054 			const dw_tag_t parent_tag = parent_decl_ctx_die->Tag();
2055 			switch (parent_tag)
2056 			{
2057                 case DW_TAG_namespace:
2058 				{
2059 					const char *namespace_name = parent_decl_ctx_die->GetName (dwarf2Data, cu);
2060 					if (namespace_name)
2061 					{
2062 						storage.insert (0, "::");
2063 						storage.insert (0, namespace_name);
2064 					}
2065 					else
2066 					{
2067 						storage.insert (0, "(anonymous namespace)::");
2068 					}
2069 					parent_decl_ctx_die = parent_decl_ctx_die->GetParentDeclContextDIE(dwarf2Data, cu);
2070 				}
2071                     break;
2072 
2073                 case DW_TAG_class_type:
2074                 case DW_TAG_structure_type:
2075                 case DW_TAG_union_type:
2076 				{
2077 					const char *class_union_struct_name = parent_decl_ctx_die->GetName (dwarf2Data, cu);
2078 
2079 					if (class_union_struct_name)
2080 					{
2081 						storage.insert (0, "::");
2082 						storage.insert (0, class_union_struct_name);
2083 					}
2084 					parent_decl_ctx_die = parent_decl_ctx_die->GetParentDeclContextDIE(dwarf2Data, cu);
2085 				}
2086                     break;
2087 
2088                 default:
2089                     parent_decl_ctx_die = NULL;
2090                     break;
2091 			}
2092 		}
2093 
2094 		if (storage.empty())
2095 			storage.append ("::");
2096 
2097 		storage.append (name);
2098 	}
2099 	if (storage.empty())
2100 		return NULL;
2101 	return storage.c_str();
2102 }
2103 
2104 
2105 //----------------------------------------------------------------------
2106 // LookupAddress
2107 //----------------------------------------------------------------------
2108 bool
2109 DWARFDebugInfoEntry::LookupAddress
2110 (
2111     const dw_addr_t address,
2112     SymbolFileDWARF* dwarf2Data,
2113     const DWARFCompileUnit* cu,
2114     DWARFDebugInfoEntry** function_die,
2115     DWARFDebugInfoEntry** block_die
2116 )
2117 {
2118     bool found_address = false;
2119     if (m_tag)
2120     {
2121         bool check_children = false;
2122         bool match_addr_range = false;
2123     //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address);
2124         switch (m_tag)
2125         {
2126         case DW_TAG_array_type                 : break;
2127         case DW_TAG_class_type                 : check_children = true; break;
2128         case DW_TAG_entry_point                : break;
2129         case DW_TAG_enumeration_type           : break;
2130         case DW_TAG_formal_parameter           : break;
2131         case DW_TAG_imported_declaration       : break;
2132         case DW_TAG_label                      : break;
2133         case DW_TAG_lexical_block              : check_children = true; match_addr_range = true; break;
2134         case DW_TAG_member                     : break;
2135         case DW_TAG_pointer_type               : break;
2136         case DW_TAG_reference_type             : break;
2137         case DW_TAG_compile_unit               : match_addr_range = true; break;
2138         case DW_TAG_string_type                : break;
2139         case DW_TAG_structure_type             : check_children = true; break;
2140         case DW_TAG_subroutine_type            : break;
2141         case DW_TAG_typedef                    : break;
2142         case DW_TAG_union_type                 : break;
2143         case DW_TAG_unspecified_parameters     : break;
2144         case DW_TAG_variant                    : break;
2145         case DW_TAG_common_block               : check_children = true; break;
2146         case DW_TAG_common_inclusion           : break;
2147         case DW_TAG_inheritance                : break;
2148         case DW_TAG_inlined_subroutine         : check_children = true; match_addr_range = true; break;
2149         case DW_TAG_module                     : match_addr_range = true; break;
2150         case DW_TAG_ptr_to_member_type         : break;
2151         case DW_TAG_set_type                   : break;
2152         case DW_TAG_subrange_type              : break;
2153         case DW_TAG_with_stmt                  : break;
2154         case DW_TAG_access_declaration         : break;
2155         case DW_TAG_base_type                  : break;
2156         case DW_TAG_catch_block                : match_addr_range = true; break;
2157         case DW_TAG_const_type                 : break;
2158         case DW_TAG_constant                   : break;
2159         case DW_TAG_enumerator                 : break;
2160         case DW_TAG_file_type                  : break;
2161         case DW_TAG_friend                     : break;
2162         case DW_TAG_namelist                   : break;
2163         case DW_TAG_namelist_item              : break;
2164         case DW_TAG_packed_type                : break;
2165         case DW_TAG_subprogram                 : match_addr_range = true; break;
2166         case DW_TAG_template_type_parameter    : break;
2167         case DW_TAG_template_value_parameter   : break;
2168         case DW_TAG_thrown_type                : break;
2169         case DW_TAG_try_block                  : match_addr_range = true; break;
2170         case DW_TAG_variant_part               : break;
2171         case DW_TAG_variable                   : break;
2172         case DW_TAG_volatile_type              : break;
2173         case DW_TAG_dwarf_procedure            : break;
2174         case DW_TAG_restrict_type              : break;
2175         case DW_TAG_interface_type             : break;
2176         case DW_TAG_namespace                  : check_children = true; break;
2177         case DW_TAG_imported_module            : break;
2178         case DW_TAG_unspecified_type           : break;
2179         case DW_TAG_partial_unit               : break;
2180         case DW_TAG_imported_unit              : break;
2181         case DW_TAG_shared_type                : break;
2182         default: break;
2183         }
2184 
2185         if (match_addr_range)
2186         {
2187             dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
2188             if (lo_pc != LLDB_INVALID_ADDRESS)
2189             {
2190                 dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
2191                 if (hi_pc != LLDB_INVALID_ADDRESS)
2192                 {
2193                     //  printf("\n0x%8.8x: %30s: address = 0x%8.8x  [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
2194                     if ((lo_pc <= address) && (address < hi_pc))
2195                     {
2196                         found_address = true;
2197                     //  puts("***MATCH***");
2198                         switch (m_tag)
2199                         {
2200                         case DW_TAG_compile_unit:       // File
2201                             check_children = ((function_die != NULL) || (block_die != NULL));
2202                             break;
2203 
2204                         case DW_TAG_subprogram:         // Function
2205                             if (function_die)
2206                                 *function_die = this;
2207                             check_children = (block_die != NULL);
2208                             break;
2209 
2210                         case DW_TAG_inlined_subroutine: // Inlined Function
2211                         case DW_TAG_lexical_block:      // Block { } in code
2212                             if (block_die)
2213                             {
2214                                 *block_die = this;
2215                                 check_children = true;
2216                             }
2217                             break;
2218 
2219                         default:
2220                             check_children = true;
2221                             break;
2222                         }
2223                     }
2224                 }
2225                 else
2226                 {   // compile units may not have a valid high/low pc when there
2227                     // are address gaps in subroutines so we must always search
2228                     // if there is no valid high and low PC
2229                     check_children = (m_tag == DW_TAG_compile_unit) && ((function_die != NULL) || (block_die != NULL));
2230                 }
2231             }
2232             else
2233             {
2234                 dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
2235                 if (debug_ranges_offset != DW_INVALID_OFFSET)
2236                 {
2237                     DWARFDebugRanges::RangeList ranges;
2238                     DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
2239                     debug_ranges->FindRanges(debug_ranges_offset, ranges);
2240                     // All DW_AT_ranges are relative to the base address of the
2241                     // compile unit. We add the compile unit base address to make
2242                     // sure all the addresses are properly fixed up.
2243                     ranges.Slide (cu->GetBaseAddress());
2244                     if (ranges.FindEntryThatContains(address))
2245                     {
2246                         found_address = true;
2247                     //  puts("***MATCH***");
2248                         switch (m_tag)
2249                         {
2250                         case DW_TAG_compile_unit:       // File
2251                             check_children = ((function_die != NULL) || (block_die != NULL));
2252                             break;
2253 
2254                         case DW_TAG_subprogram:         // Function
2255                             if (function_die)
2256                                 *function_die = this;
2257                             check_children = (block_die != NULL);
2258                             break;
2259 
2260                         case DW_TAG_inlined_subroutine: // Inlined Function
2261                         case DW_TAG_lexical_block:      // Block { } in code
2262                             if (block_die)
2263                             {
2264                                 *block_die = this;
2265                                 check_children = true;
2266                             }
2267                             break;
2268 
2269                         default:
2270                             check_children = true;
2271                             break;
2272                         }
2273                     }
2274                     else
2275                     {
2276                         check_children = false;
2277                     }
2278                 }
2279             }
2280         }
2281 
2282 
2283         if (check_children)
2284         {
2285         //  printf("checking children\n");
2286             DWARFDebugInfoEntry* child = GetFirstChild();
2287             while (child)
2288             {
2289                 if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die))
2290                     return true;
2291                 child = child->GetSibling();
2292             }
2293         }
2294     }
2295     return found_address;
2296 }
2297 
2298 const DWARFAbbreviationDeclaration*
2299 DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
2300                                                     const DWARFCompileUnit *cu,
2301                                                     lldb::offset_t &offset) const
2302 {
2303     if (dwarf2Data)
2304     {
2305         offset = GetOffset();
2306 
2307         const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
2308         if (abbrev_set)
2309         {
2310             const DWARFAbbreviationDeclaration* abbrev_decl = abbrev_set->GetAbbreviationDeclaration (m_abbr_idx);
2311             if (abbrev_decl)
2312             {
2313                 // Make sure the abbreviation code still matches. If it doesn't and
2314                 // the DWARF data was mmap'ed, the backing file might have been modified
2315                 // which is bad news.
2316                 const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
2317 
2318                 if (abbrev_decl->Code() == abbrev_code)
2319                     return abbrev_decl;
2320 
2321                 dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
2322                                                                                        GetOffset(),
2323                                                                                        (uint32_t)abbrev_decl->Code(),
2324                                                                                        (uint32_t)abbrev_code);
2325             }
2326         }
2327     }
2328     offset = DW_INVALID_OFFSET;
2329     return NULL;
2330 }
2331 
2332 
2333 bool
2334 DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b)
2335 {
2336     return a.GetOffset() < b.GetOffset();
2337 }
2338 
2339 void
2340 DWARFDebugInfoEntry::DumpDIECollection (Stream &strm, DWARFDebugInfoEntry::collection &die_collection)
2341 {
2342     DWARFDebugInfoEntry::const_iterator pos;
2343     DWARFDebugInfoEntry::const_iterator end = die_collection.end();
2344     strm.PutCString("\noffset    parent   sibling  child\n");
2345     strm.PutCString("--------  -------- -------- --------\n");
2346     for (pos = die_collection.begin(); pos != end; ++pos)
2347     {
2348         const DWARFDebugInfoEntry& die_ref = *pos;
2349         const DWARFDebugInfoEntry* p = die_ref.GetParent();
2350         const DWARFDebugInfoEntry* s = die_ref.GetSibling();
2351         const DWARFDebugInfoEntry* c = die_ref.GetFirstChild();
2352         strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n",
2353                     die_ref.GetOffset(),
2354                     p ? p->GetOffset() : 0,
2355                     s ? s->GetOffset() : 0,
2356                     c ? c->GetOffset() : 0,
2357                     die_ref.Tag(),
2358                     DW_TAG_value_to_name(die_ref.Tag()),
2359                     die_ref.HasChildren() ? " *" : "");
2360     }
2361 }
2362 
2363 
2364