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