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 void
1133 DWARFDebugInfoEntry::DumpLocation
1134 (
1135     SymbolFileDWARF* dwarf2Data,
1136     DWARFCompileUnit* cu,
1137     Stream &s
1138 ) const
1139 {
1140     const DWARFDebugInfoEntry *cu_die = cu->GetCompileUnitDIEOnly();
1141     const char *cu_name = NULL;
1142     if (cu_die != NULL)
1143         cu_name = cu_die->GetName (dwarf2Data, cu);
1144     const char *obj_file_name = NULL;
1145     ObjectFile *obj_file = dwarf2Data->GetObjectFile();
1146     if (obj_file)
1147         obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString();
1148     const char *die_name = GetName (dwarf2Data, cu);
1149     s.Printf ("CU: %s OBJFILE: %s DIE: %s (0x%llx).",
1150                 cu_name ? cu_name : "<UNKNOWN>",
1151                 obj_file_name ? obj_file_name : "<UNKNOWN>",
1152                 die_name ? die_name : "<NO NAME>",
1153                 GetOffset());
1154 }
1155 
1156 //----------------------------------------------------------------------
1157 // DumpAttribute
1158 //
1159 // Dumps a debug information entry attribute along with it's form. Any
1160 // special display of attributes is done (disassemble location lists,
1161 // show enumeration values for attributes, etc).
1162 //----------------------------------------------------------------------
1163 void
1164 DWARFDebugInfoEntry::DumpAttribute
1165 (
1166     SymbolFileDWARF* dwarf2Data,
1167     const DWARFCompileUnit* cu,
1168     const DataExtractor& debug_info_data,
1169     uint32_t* offset_ptr,
1170     Stream &s,
1171     dw_attr_t attr,
1172     dw_form_t form
1173 )
1174 {
1175     bool verbose    = s.GetVerbose();
1176     bool show_form  = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
1177     const DataExtractor* debug_str_data = dwarf2Data ? &dwarf2Data->get_debug_str_data() : NULL;
1178     if (verbose)
1179         s.Offset (*offset_ptr);
1180     else
1181         s.Printf ("            ");
1182     s.Indent(DW_AT_value_to_name(attr));
1183 
1184     if (show_form)
1185     {
1186         s.Printf( "[%s", DW_FORM_value_to_name(form));
1187     }
1188 
1189     DWARFFormValue form_value(form);
1190 
1191     if (!form_value.ExtractValue(debug_info_data, offset_ptr, cu))
1192         return;
1193 
1194     if (show_form)
1195     {
1196         if (form == DW_FORM_indirect)
1197         {
1198             s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form()));
1199         }
1200 
1201         s.PutCString("] ");
1202     }
1203 
1204     s.PutCString("( ");
1205 
1206     // Always dump form value if verbose is enabled
1207     if (verbose)
1208     {
1209         form_value.Dump(s, debug_str_data, cu);
1210     }
1211 
1212 
1213     // Check to see if we have any special attribute formatters
1214     switch (attr)
1215     {
1216     case DW_AT_stmt_list:
1217         if ( verbose ) s.PutCString(" ( ");
1218         s.Printf( "0x%8.8x", form_value.Unsigned());
1219         if ( verbose ) s.PutCString(" )");
1220         break;
1221 
1222     case DW_AT_language:
1223         if ( verbose ) s.PutCString(" ( ");
1224         s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
1225         if ( verbose ) s.PutCString(" )");
1226         break;
1227 
1228     case DW_AT_encoding:
1229         if ( verbose ) s.PutCString(" ( ");
1230         s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
1231         if ( verbose ) s.PutCString(" )");
1232         break;
1233 
1234     case DW_AT_frame_base:
1235     case DW_AT_location:
1236     case DW_AT_data_member_location:
1237         {
1238             const uint8_t* blockData = form_value.BlockData();
1239             if (blockData)
1240             {
1241                 if (!verbose)
1242                     form_value.Dump(s, debug_str_data, cu);
1243 
1244                 // Location description is inlined in data in the form value
1245                 DataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned());
1246                 if ( verbose ) s.PutCString(" ( ");
1247                 print_dwarf_expression (s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
1248                 if ( verbose ) s.PutCString(" )");
1249             }
1250             else
1251             {
1252                 // We have a location list offset as the value that is
1253                 // the offset into the .debug_loc section that describes
1254                 // the value over it's lifetime
1255                 uint64_t debug_loc_offset = form_value.Unsigned();
1256                 if (dwarf2Data)
1257                 {
1258                     if ( !verbose )
1259                         form_value.Dump(s, debug_str_data, cu);
1260                     DWARFLocationList::Dump(s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
1261                 }
1262                 else
1263                 {
1264                     if ( !verbose )
1265                         form_value.Dump(s, NULL, cu);
1266                 }
1267             }
1268         }
1269         break;
1270 
1271     case DW_AT_abstract_origin:
1272     case DW_AT_specification:
1273         {
1274             uint64_t abstract_die_offset = form_value.Reference(cu);
1275             form_value.Dump(s, debug_str_data, cu);
1276         //  *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
1277             if ( verbose ) s.PutCString(" ( ");
1278             GetName(dwarf2Data, cu, abstract_die_offset, s);
1279             if ( verbose ) s.PutCString(" )");
1280         }
1281         break;
1282 
1283     case DW_AT_type:
1284         {
1285             uint64_t type_die_offset = form_value.Reference(cu);
1286             if (!verbose)
1287                 form_value.Dump(s, debug_str_data, cu);
1288             s.PutCString(" ( ");
1289             AppendTypeName(dwarf2Data, cu, type_die_offset, s);
1290             s.PutCString(" )");
1291         }
1292         break;
1293 
1294     case DW_AT_ranges:
1295         {
1296             if ( !verbose )
1297                 form_value.Dump(s, debug_str_data, cu);
1298             uint32_t ranges_offset = form_value.Unsigned();
1299             dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
1300             DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
1301         }
1302         break;
1303 
1304     default:
1305         if ( !verbose )
1306             form_value.Dump(s, debug_str_data, cu);
1307         break;
1308     }
1309 
1310     s.PutCString(" )\n");
1311 }
1312 
1313 //----------------------------------------------------------------------
1314 // Get all attribute values for a given DIE, including following any
1315 // specification or abstract origin attributes and including those in
1316 // the results. Any duplicate attributes will have the first instance
1317 // take precedence (this can happen for declaration attributes).
1318 //----------------------------------------------------------------------
1319 size_t
1320 DWARFDebugInfoEntry::GetAttributes
1321 (
1322     SymbolFileDWARF* dwarf2Data,
1323     const DWARFCompileUnit* cu,
1324     const uint8_t *fixed_form_sizes,
1325     DWARFDebugInfoEntry::Attributes& attributes,
1326     uint32_t curr_depth
1327 ) const
1328 {
1329     if (m_abbrevDecl)
1330     {
1331         if (fixed_form_sizes == NULL)
1332             fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize());
1333         uint32_t offset = GetOffset();
1334         const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
1335 
1336         // Skip the abbreviation code so we are at the data for the attributes
1337         debug_info_data.Skip_LEB128(&offset);
1338 
1339         const uint32_t num_attributes = m_abbrevDecl->NumAttributes();
1340         uint32_t i;
1341         dw_attr_t attr;
1342         dw_form_t form;
1343         DWARFFormValue form_value;
1344         for (i=0; i<num_attributes; ++i)
1345         {
1346             m_abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form);
1347 
1348             // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
1349             // attributes, the depth will be non-zero. We need to omit certain
1350             // attributes that don't make sense.
1351             switch (attr)
1352             {
1353             case DW_AT_sibling:
1354             case DW_AT_declaration:
1355                 if (curr_depth > 0)
1356                 {
1357                     // This attribute doesn't make sense when combined with
1358                     // the DIE that references this DIE. We know a DIE is
1359                     // referencing this DIE because curr_depth is not zero
1360                     break;
1361                 }
1362                 // Fall through...
1363             default:
1364                 attributes.Append(cu, offset, attr, form);
1365                 break;
1366             }
1367 
1368             if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))
1369             {
1370                 form_value.SetForm(form);
1371                 if (form_value.ExtractValue(debug_info_data, &offset, cu))
1372                 {
1373                     const DWARFDebugInfoEntry* die = NULL;
1374                     dw_offset_t die_offset = form_value.Reference(cu);
1375                     if (cu->ContainsDIEOffset(die_offset))
1376                     {
1377                         die = const_cast<DWARFCompileUnit*>(cu)->GetDIEPtr(die_offset);
1378                         if (die)
1379                             die->GetAttributes(dwarf2Data, cu, fixed_form_sizes, attributes, curr_depth + 1);
1380                     }
1381                     else
1382                     {
1383                         DWARFCompileUnitSP cu_sp_ptr;
1384                         die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
1385                         if (die)
1386                             die->GetAttributes(dwarf2Data, cu_sp_ptr.get(), fixed_form_sizes, attributes, curr_depth + 1);
1387                     }
1388                 }
1389             }
1390             else
1391             {
1392                 const uint8_t fixed_skip_size = fixed_form_sizes [form];
1393                 if (fixed_skip_size)
1394                     offset += fixed_skip_size;
1395                 else
1396                     DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
1397             }
1398         }
1399     }
1400     else
1401     {
1402         attributes.Clear();
1403     }
1404     return attributes.Size();
1405 
1406 }
1407 
1408 //----------------------------------------------------------------------
1409 // GetAttributeValue
1410 //
1411 // Get the value of an attribute and return the .debug_info offset of the
1412 // attribute if it was properly extracted into form_value, or zero
1413 // if we fail since an offset of zero is invalid for an attribute (it
1414 // would be a compile unit header).
1415 //----------------------------------------------------------------------
1416 dw_offset_t
1417 DWARFDebugInfoEntry::GetAttributeValue
1418 (
1419     SymbolFileDWARF* dwarf2Data,
1420     const DWARFCompileUnit* cu,
1421     const dw_attr_t attr,
1422     DWARFFormValue& form_value,
1423     dw_offset_t* end_attr_offset_ptr
1424 ) const
1425 {
1426     if (m_abbrevDecl)
1427     {
1428         uint32_t attr_idx = m_abbrevDecl->FindAttributeIndex(attr);
1429 
1430         if (attr_idx != DW_INVALID_INDEX)
1431         {
1432             uint32_t offset = GetOffset();
1433 
1434             const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
1435 
1436             // Skip the abbreviation code so we are at the data for the attributes
1437             debug_info_data.Skip_LEB128(&offset);
1438 
1439             uint32_t idx=0;
1440             while (idx<attr_idx)
1441                 DWARFFormValue::SkipValue(m_abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu);
1442 
1443             const dw_offset_t attr_offset = offset;
1444             form_value.SetForm(m_abbrevDecl->GetFormByIndex(idx));
1445             if (form_value.ExtractValue(debug_info_data, &offset, cu))
1446             {
1447                 if (end_attr_offset_ptr)
1448                     *end_attr_offset_ptr = offset;
1449                 return attr_offset;
1450             }
1451         }
1452     }
1453 
1454     return 0;
1455 }
1456 
1457 //----------------------------------------------------------------------
1458 // GetAttributeValueAsString
1459 //
1460 // Get the value of an attribute as a string return it. The resulting
1461 // pointer to the string data exists within the supplied SymbolFileDWARF
1462 // and will only be available as long as the SymbolFileDWARF is still around
1463 // and it's content doesn't change.
1464 //----------------------------------------------------------------------
1465 const char*
1466 DWARFDebugInfoEntry::GetAttributeValueAsString
1467 (
1468     SymbolFileDWARF* dwarf2Data,
1469     const DWARFCompileUnit* cu,
1470     const dw_attr_t attr,
1471     const char* fail_value) const
1472 {
1473     DWARFFormValue form_value;
1474     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1475         return form_value.AsCString(&dwarf2Data->get_debug_str_data());
1476     return fail_value;
1477 }
1478 
1479 //----------------------------------------------------------------------
1480 // GetAttributeValueAsUnsigned
1481 //
1482 // Get the value of an attribute as unsigned and return it.
1483 //----------------------------------------------------------------------
1484 uint64_t
1485 DWARFDebugInfoEntry::GetAttributeValueAsUnsigned
1486 (
1487     SymbolFileDWARF* dwarf2Data,
1488     const DWARFCompileUnit* cu,
1489     const dw_attr_t attr,
1490     uint64_t fail_value
1491 ) const
1492 {
1493     DWARFFormValue form_value;
1494     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1495         return form_value.Unsigned();
1496     return fail_value;
1497 }
1498 
1499 //----------------------------------------------------------------------
1500 // GetAttributeValueAsSigned
1501 //
1502 // Get the value of an attribute a signed value and return it.
1503 //----------------------------------------------------------------------
1504 int64_t
1505 DWARFDebugInfoEntry::GetAttributeValueAsSigned
1506 (
1507     SymbolFileDWARF* dwarf2Data,
1508     const DWARFCompileUnit* cu,
1509     const dw_attr_t attr,
1510     int64_t fail_value
1511 ) const
1512 {
1513     DWARFFormValue form_value;
1514     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1515         return form_value.Signed();
1516     return fail_value;
1517 }
1518 
1519 //----------------------------------------------------------------------
1520 // GetAttributeValueAsReference
1521 //
1522 // Get the value of an attribute as reference and fix up and compile
1523 // unit relative offsets as needed.
1524 //----------------------------------------------------------------------
1525 uint64_t
1526 DWARFDebugInfoEntry::GetAttributeValueAsReference
1527 (
1528     SymbolFileDWARF* dwarf2Data,
1529     const DWARFCompileUnit* cu,
1530     const dw_attr_t attr,
1531     uint64_t fail_value
1532 ) const
1533 {
1534     DWARFFormValue form_value;
1535     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1536         return form_value.Reference(cu);
1537     return fail_value;
1538 }
1539 
1540 //----------------------------------------------------------------------
1541 // GetAttributeValueAsLocation
1542 //
1543 // Get the value of an attribute as reference and fix up and compile
1544 // unit relative offsets as needed.
1545 //----------------------------------------------------------------------
1546 dw_offset_t
1547 DWARFDebugInfoEntry::GetAttributeValueAsLocation
1548 (
1549     SymbolFileDWARF* dwarf2Data,
1550     const DWARFCompileUnit* cu,
1551     const dw_attr_t attr,
1552     DataExtractor& location_data,
1553     uint32_t &block_size
1554 ) const
1555 {
1556     block_size = 0;
1557     DWARFFormValue form_value;
1558 
1559     // Empty out data in case we don't find anything
1560     location_data.Clear();
1561     dw_offset_t end_addr_offset = DW_INVALID_OFFSET;
1562     const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset);
1563     if (attr_offset)
1564     {
1565         const uint8_t* blockData = form_value.BlockData();
1566         if (blockData)
1567         {
1568             // We have an inlined location list in the .debug_info section
1569             const DataExtractor& debug_info = dwarf2Data->get_debug_info_data();
1570             dw_offset_t block_offset = blockData - debug_info.GetDataStart();
1571             block_size = (end_addr_offset - attr_offset) - form_value.Unsigned();
1572             location_data.SetData(debug_info, block_offset, block_size);
1573         }
1574         else
1575         {
1576             // We have a location list offset as the value that is
1577             // the offset into the .debug_loc section that describes
1578             // the value over it's lifetime
1579             dw_offset_t debug_loc_offset = form_value.Unsigned();
1580             if (dwarf2Data)
1581             {
1582                 assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
1583                 return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data);
1584             }
1585         }
1586     }
1587     return attr_offset;
1588 }
1589 
1590 //----------------------------------------------------------------------
1591 // GetName
1592 //
1593 // Get value of the DW_AT_name attribute and return it if one exists,
1594 // else return NULL.
1595 //----------------------------------------------------------------------
1596 const char*
1597 DWARFDebugInfoEntry::GetName
1598 (
1599     SymbolFileDWARF* dwarf2Data,
1600     const DWARFCompileUnit* cu
1601 ) const
1602 {
1603     DWARFFormValue form_value;
1604     if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1605         return form_value.AsCString(&dwarf2Data->get_debug_str_data());
1606     return NULL;
1607 }
1608 
1609 
1610 //----------------------------------------------------------------------
1611 // GetMangledName
1612 //
1613 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if
1614 // one exists, else return the value of the DW_AT_name attribute
1615 //----------------------------------------------------------------------
1616 const char*
1617 DWARFDebugInfoEntry::GetMangledName
1618 (
1619     SymbolFileDWARF* dwarf2Data,
1620     const DWARFCompileUnit* cu,
1621     bool substitute_name_allowed
1622 ) const
1623 {
1624     const char* name = NULL;
1625     DWARFFormValue form_value;
1626 
1627     if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
1628         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1629 
1630     if (substitute_name_allowed && name == NULL)
1631     {
1632         if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1633             name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1634     }
1635     return name;
1636 }
1637 
1638 
1639 //----------------------------------------------------------------------
1640 // GetPubname
1641 //
1642 // Get value the name for a DIE as it should appear for a
1643 // .debug_pubnames or .debug_pubtypes section.
1644 //----------------------------------------------------------------------
1645 const char*
1646 DWARFDebugInfoEntry::GetPubname
1647 (
1648     SymbolFileDWARF* dwarf2Data,
1649     const DWARFCompileUnit* cu
1650 ) const
1651 {
1652     const char* name = NULL;
1653     DWARFFormValue form_value;
1654 
1655     if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
1656         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1657     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1658         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1659     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
1660     {
1661         // The specification DIE may be in another compile unit so we need
1662         // to get a die and its compile unit.
1663         DWARFCompileUnitSP cu_sp_ptr;
1664         const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr);
1665         if (die)
1666             return die->GetPubname(dwarf2Data, cu_sp_ptr.get());
1667     }
1668     return name;
1669 }
1670 
1671 
1672 //----------------------------------------------------------------------
1673 // GetName
1674 //
1675 // Get value of the DW_AT_name attribute for a debug information entry
1676 // that exists at offset "die_offset" and place that value into the
1677 // supplied stream object. If the DIE is a NULL object "NULL" is placed
1678 // into the stream, and if no DW_AT_name attribute exists for the DIE
1679 // then nothing is printed.
1680 //----------------------------------------------------------------------
1681 bool
1682 DWARFDebugInfoEntry::GetName
1683 (
1684     SymbolFileDWARF* dwarf2Data,
1685     const DWARFCompileUnit* cu,
1686     const uint32_t die_offset,
1687     Stream &s
1688 )
1689 {
1690     DWARFDebugInfoEntry die;
1691     uint32_t offset = die_offset;
1692     if (die.Extract(dwarf2Data, cu, &offset))
1693     {
1694         if (die.IsNULL())
1695         {
1696             s.PutCString("NULL");
1697             return true;
1698         }
1699         else
1700         {
1701             DWARFFormValue form_value;
1702             if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1703             {
1704                 const char* name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1705                 if (name)
1706                 {
1707                     s.PutCString(name);
1708                     return true;
1709                 }
1710             }
1711         }
1712     }
1713     return false;
1714 }
1715 
1716 //----------------------------------------------------------------------
1717 // AppendTypeName
1718 //
1719 // Follows the type name definition down through all needed tags to
1720 // end up with a fully qualified type name and dump the results to
1721 // the supplied stream. This is used to show the name of types given
1722 // a type identifier.
1723 //----------------------------------------------------------------------
1724 bool
1725 DWARFDebugInfoEntry::AppendTypeName
1726 (
1727     SymbolFileDWARF* dwarf2Data,
1728     const DWARFCompileUnit* cu,
1729     const uint32_t die_offset,
1730     Stream &s
1731 )
1732 {
1733     DWARFDebugInfoEntry die;
1734     uint32_t offset = die_offset;
1735     if (die.Extract(dwarf2Data, cu, &offset))
1736     {
1737         if (die.IsNULL())
1738         {
1739             s.PutCString("NULL");
1740             return true;
1741         }
1742         else
1743         {
1744             const char* name = die.GetPubname(dwarf2Data, cu);
1745         //  if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1746         //      name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1747             if (name)
1748                 s.PutCString(name);
1749             else
1750             {
1751                 bool result = true;
1752                 const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr();
1753 
1754                 switch (abbrevDecl->Tag())
1755                 {
1756                 case DW_TAG_array_type:         break;  // print out a "[]" after printing the full type of the element below
1757                 case DW_TAG_base_type:          s.PutCString("base ");         break;
1758                 case DW_TAG_class_type:         s.PutCString("class ");            break;
1759                 case DW_TAG_const_type:         s.PutCString("const ");            break;
1760                 case DW_TAG_enumeration_type:   s.PutCString("enum ");         break;
1761                 case DW_TAG_file_type:          s.PutCString("file ");         break;
1762                 case DW_TAG_interface_type:     s.PutCString("interface ");        break;
1763                 case DW_TAG_packed_type:        s.PutCString("packed ");       break;
1764                 case DW_TAG_pointer_type:       break;  // print out a '*' after printing the full type below
1765                 case DW_TAG_ptr_to_member_type: break;  // print out a '*' after printing the full type below
1766                 case DW_TAG_reference_type:     break;  // print out a '&' after printing the full type below
1767                 case DW_TAG_restrict_type:      s.PutCString("restrict ");     break;
1768                 case DW_TAG_set_type:           s.PutCString("set ");          break;
1769                 case DW_TAG_shared_type:        s.PutCString("shared ");       break;
1770                 case DW_TAG_string_type:        s.PutCString("string ");       break;
1771                 case DW_TAG_structure_type:     s.PutCString("struct ");       break;
1772                 case DW_TAG_subrange_type:      s.PutCString("subrange ");     break;
1773                 case DW_TAG_subroutine_type:    s.PutCString("function ");     break;
1774                 case DW_TAG_thrown_type:        s.PutCString("thrown ");       break;
1775                 case DW_TAG_union_type:         s.PutCString("union ");            break;
1776                 case DW_TAG_unspecified_type:   s.PutCString("unspecified ");  break;
1777                 case DW_TAG_volatile_type:      s.PutCString("volatile ");     break;
1778                 default:
1779                     return false;
1780                 }
1781 
1782                 // Follow the DW_AT_type if possible
1783                 DWARFFormValue form_value;
1784                 if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value))
1785                 {
1786                     uint64_t next_die_offset = form_value.Reference(cu);
1787                     result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
1788                 }
1789 
1790                 switch (abbrevDecl->Tag())
1791                 {
1792                 case DW_TAG_array_type:         s.PutCString("[]");    break;
1793                 case DW_TAG_pointer_type:       s.PutChar('*');    break;
1794                 case DW_TAG_ptr_to_member_type: s.PutChar('*');    break;
1795                 case DW_TAG_reference_type:     s.PutChar('&');    break;
1796                 default:
1797                     break;
1798                 }
1799                 return result;
1800             }
1801         }
1802     }
1803     return false;
1804 }
1805 
1806 bool
1807 DWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const
1808 {
1809     if (die)
1810     {
1811         const dw_offset_t die_offset = die->GetOffset();
1812         if (die_offset > GetOffset())
1813         {
1814             const DWARFDebugInfoEntry *sibling = GetSibling();
1815             assert (sibling); // TODO: take this out
1816             if (sibling)
1817                 return die_offset < sibling->GetOffset();
1818         }
1819     }
1820     return false;
1821 }
1822 
1823 //----------------------------------------------------------------------
1824 // BuildAddressRangeTable
1825 //----------------------------------------------------------------------
1826 void
1827 DWARFDebugInfoEntry::BuildAddressRangeTable
1828 (
1829     SymbolFileDWARF* dwarf2Data,
1830     const DWARFCompileUnit* cu,
1831     DWARFDebugAranges* debug_aranges
1832 ) const
1833 {
1834     if (m_abbrevDecl)
1835     {
1836         dw_tag_t tag = m_abbrevDecl->Tag();
1837         if (tag == DW_TAG_subprogram)
1838         {
1839             dw_addr_t hi_pc = DW_INVALID_ADDRESS;
1840             dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
1841             if (lo_pc != DW_INVALID_ADDRESS)
1842                 hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
1843             if (hi_pc != DW_INVALID_ADDRESS)
1844             {
1845             /// 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);
1846                 debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc);
1847             }
1848         }
1849 
1850 
1851         const DWARFDebugInfoEntry* child = GetFirstChild();
1852         while (child)
1853         {
1854             child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
1855             child = child->GetSibling();
1856         }
1857     }
1858 }
1859 
1860 //----------------------------------------------------------------------
1861 // BuildFunctionAddressRangeTable
1862 //
1863 // This function is very similar to the BuildAddressRangeTable function
1864 // except that the actual DIE offset for the function is placed in the
1865 // table instead of the compile unit offset (which is the way the
1866 // standard .debug_aranges section does it).
1867 //----------------------------------------------------------------------
1868 void
1869 DWARFDebugInfoEntry::BuildFunctionAddressRangeTable
1870 (
1871     SymbolFileDWARF* dwarf2Data,
1872     const DWARFCompileUnit* cu,
1873     DWARFDebugAranges* debug_aranges
1874 ) const
1875 {
1876     if (m_abbrevDecl)
1877     {
1878         dw_tag_t tag = m_abbrevDecl->Tag();
1879         if (tag == DW_TAG_subprogram)
1880         {
1881             dw_addr_t hi_pc = DW_INVALID_ADDRESS;
1882             dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
1883             if (lo_pc != DW_INVALID_ADDRESS)
1884                 hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
1885             if (hi_pc != DW_INVALID_ADDRESS)
1886             {
1887             //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16llx - 0x%16.16llx)\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
1888                 debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc);
1889             }
1890         }
1891 
1892         const DWARFDebugInfoEntry* child = GetFirstChild();
1893         while (child)
1894         {
1895             child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
1896             child = child->GetSibling();
1897         }
1898     }
1899 }
1900 
1901 
1902 //----------------------------------------------------------------------
1903 // LookupAddress
1904 //----------------------------------------------------------------------
1905 bool
1906 DWARFDebugInfoEntry::LookupAddress
1907 (
1908     const dw_addr_t address,
1909     SymbolFileDWARF* dwarf2Data,
1910     const DWARFCompileUnit* cu,
1911     DWARFDebugInfoEntry** function_die,
1912     DWARFDebugInfoEntry** block_die
1913 )
1914 {
1915     bool found_address = false;
1916     if (m_abbrevDecl)
1917     {
1918         bool check_children = false;
1919         bool match_addr_range = false;
1920         dw_tag_t tag = m_abbrevDecl->Tag();
1921     //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address);
1922         switch (tag)
1923         {
1924         case DW_TAG_array_type                 : break;
1925         case DW_TAG_class_type                 : check_children = true; break;
1926         case DW_TAG_entry_point                : break;
1927         case DW_TAG_enumeration_type           : break;
1928         case DW_TAG_formal_parameter           : break;
1929         case DW_TAG_imported_declaration       : break;
1930         case DW_TAG_label                      : break;
1931         case DW_TAG_lexical_block              : check_children = true; match_addr_range = true; break;
1932         case DW_TAG_member                     : break;
1933         case DW_TAG_pointer_type               : break;
1934         case DW_TAG_reference_type             : break;
1935         case DW_TAG_compile_unit               : match_addr_range = true; break;
1936         case DW_TAG_string_type                : break;
1937         case DW_TAG_structure_type             : check_children = true; break;
1938         case DW_TAG_subroutine_type            : break;
1939         case DW_TAG_typedef                    : break;
1940         case DW_TAG_union_type                 : break;
1941         case DW_TAG_unspecified_parameters     : break;
1942         case DW_TAG_variant                    : break;
1943         case DW_TAG_common_block               : check_children = true; break;
1944         case DW_TAG_common_inclusion           : break;
1945         case DW_TAG_inheritance                : break;
1946         case DW_TAG_inlined_subroutine         : check_children = true; match_addr_range = true; break;
1947         case DW_TAG_module                     : match_addr_range = true; break;
1948         case DW_TAG_ptr_to_member_type         : break;
1949         case DW_TAG_set_type                   : break;
1950         case DW_TAG_subrange_type              : break;
1951         case DW_TAG_with_stmt                  : break;
1952         case DW_TAG_access_declaration         : break;
1953         case DW_TAG_base_type                  : break;
1954         case DW_TAG_catch_block                : match_addr_range = true; break;
1955         case DW_TAG_const_type                 : break;
1956         case DW_TAG_constant                   : break;
1957         case DW_TAG_enumerator                 : break;
1958         case DW_TAG_file_type                  : break;
1959         case DW_TAG_friend                     : break;
1960         case DW_TAG_namelist                   : break;
1961         case DW_TAG_namelist_item              : break;
1962         case DW_TAG_packed_type                : break;
1963         case DW_TAG_subprogram                 : match_addr_range = true; break;
1964         case DW_TAG_template_type_parameter    : break;
1965         case DW_TAG_template_value_parameter   : break;
1966         case DW_TAG_thrown_type                : break;
1967         case DW_TAG_try_block                  : match_addr_range = true; break;
1968         case DW_TAG_variant_part               : break;
1969         case DW_TAG_variable                   : break;
1970         case DW_TAG_volatile_type              : break;
1971         case DW_TAG_dwarf_procedure            : break;
1972         case DW_TAG_restrict_type              : break;
1973         case DW_TAG_interface_type             : break;
1974         case DW_TAG_namespace                  : check_children = true; break;
1975         case DW_TAG_imported_module            : break;
1976         case DW_TAG_unspecified_type           : break;
1977         case DW_TAG_partial_unit               : break;
1978         case DW_TAG_imported_unit              : break;
1979         case DW_TAG_shared_type                : break;
1980         default: break;
1981         }
1982 
1983         if (match_addr_range)
1984         {
1985             dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
1986             if (lo_pc != DW_INVALID_ADDRESS)
1987             {
1988                 dw_addr_t hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
1989                 if (hi_pc != DW_INVALID_ADDRESS)
1990                 {
1991                     //  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);
1992                     if ((lo_pc <= address) && (address < hi_pc))
1993                     {
1994                         found_address = true;
1995                     //  puts("***MATCH***");
1996                         switch (tag)
1997                         {
1998                         case DW_TAG_compile_unit:       // File
1999                             check_children = ((function_die != NULL) || (block_die != NULL));
2000                             break;
2001 
2002                         case DW_TAG_subprogram:         // Function
2003                             if (function_die)
2004                                 *function_die = this;
2005                             check_children = (block_die != NULL);
2006                             break;
2007 
2008                         case DW_TAG_inlined_subroutine: // Inlined Function
2009                         case DW_TAG_lexical_block:      // Block { } in code
2010                             if (block_die)
2011                             {
2012                                 *block_die = this;
2013                                 check_children = true;
2014                             }
2015                             break;
2016 
2017                         default:
2018                             check_children = true;
2019                             break;
2020                         }
2021                     }
2022                 }
2023                 else
2024                 {   // compile units may not have a valid high/low pc when there
2025                     // are address gaps in subroutines so we must always search
2026                     // if there is no valid high and low PC
2027                     check_children = (tag == DW_TAG_compile_unit) && ((function_die != NULL) || (block_die != NULL));
2028                 }
2029             }
2030             else
2031             {
2032                 dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
2033                 if (debug_ranges_offset != DW_INVALID_OFFSET)
2034                 {
2035                     DWARFDebugRanges::RangeList ranges;
2036                     DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
2037                     debug_ranges->FindRanges(debug_ranges_offset, ranges);
2038                     // All DW_AT_ranges are relative to the base address of the
2039                     // compile unit. We add the compile unit base address to make
2040                     // sure all the addresses are properly fixed up.
2041                     ranges.AddOffset(cu->GetBaseAddress());
2042                     if (ranges.Lookup(address))
2043                     {
2044                         found_address = true;
2045                     //  puts("***MATCH***");
2046                         switch (tag)
2047                         {
2048                         case DW_TAG_compile_unit:       // File
2049                             check_children = ((function_die != NULL) || (block_die != NULL));
2050                             break;
2051 
2052                         case DW_TAG_subprogram:         // Function
2053                             if (function_die)
2054                                 *function_die = this;
2055                             check_children = (block_die != NULL);
2056                             break;
2057 
2058                         case DW_TAG_inlined_subroutine: // Inlined Function
2059                         case DW_TAG_lexical_block:      // Block { } in code
2060                             if (block_die)
2061                             {
2062                                 *block_die = this;
2063                                 check_children = true;
2064                             }
2065                             break;
2066 
2067                         default:
2068                             check_children = true;
2069                             break;
2070                         }
2071                     }
2072                     else
2073                     {
2074                         check_children = false;
2075                     }
2076                 }
2077             }
2078         }
2079 
2080 
2081         if (check_children)
2082         {
2083         //  printf("checking children\n");
2084             DWARFDebugInfoEntry* child = GetFirstChild();
2085             while (child)
2086             {
2087                 if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die))
2088                     return true;
2089                 child = child->GetSibling();
2090             }
2091         }
2092     }
2093     return found_address;
2094 }
2095 
2096 
2097 bool
2098 DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b)
2099 {
2100     return a.GetOffset() < b.GetOffset();
2101 }
2102 
2103