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