1 //===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "DWARFDebugInfoEntry.h"
11 
12 #include <assert.h>
13 
14 #include <algorithm>
15 
16 #include "lldb/Core/Module.h"
17 #include "lldb/Expression/DWARFExpression.h"
18 #include "lldb/Symbol/ObjectFile.h"
19 #include "lldb/Utility/Stream.h"
20 
21 #include "DWARFUnit.h"
22 #include "DWARFDIECollection.h"
23 #include "DWARFDebugAbbrev.h"
24 #include "DWARFDebugAranges.h"
25 #include "DWARFDebugInfo.h"
26 #include "DWARFDebugRanges.h"
27 #include "DWARFDeclContext.h"
28 #include "DWARFFormValue.h"
29 #include "SymbolFileDWARF.h"
30 #include "SymbolFileDWARFDwo.h"
31 
32 using namespace lldb_private;
33 using namespace std;
34 extern int g_verbose;
35 
36 bool DWARFDebugInfoEntry::FastExtract(
37     const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu,
38     const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
39     lldb::offset_t *offset_ptr) {
40   m_offset = *offset_ptr;
41   m_parent_idx = 0;
42   m_sibling_idx = 0;
43   m_empty_children = false;
44   const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr);
45   assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
46   m_abbr_idx = abbr_idx;
47 
48   // assert (fixed_form_sizes);  // For best performance this should be
49   // specified!
50 
51   if (m_abbr_idx) {
52     lldb::offset_t offset = *offset_ptr;
53 
54     const DWARFAbbreviationDeclaration *abbrevDecl =
55         cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
56 
57     if (abbrevDecl == NULL) {
58       cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
59           "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
60           "attach the file at the start of this error message",
61           m_offset, (unsigned)abbr_idx);
62       // WE can't parse anymore if the DWARF is borked...
63       *offset_ptr = UINT32_MAX;
64       return false;
65     }
66     m_tag = abbrevDecl->Tag();
67     m_has_children = abbrevDecl->HasChildren();
68     // Skip all data in the .debug_info for the attributes
69     const uint32_t numAttributes = abbrevDecl->NumAttributes();
70     uint32_t i;
71     dw_form_t form;
72     for (i = 0; i < numAttributes; ++i) {
73       form = abbrevDecl->GetFormByIndexUnchecked(i);
74 
75       const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
76       if (fixed_skip_size)
77         offset += fixed_skip_size;
78       else {
79         bool form_is_indirect = false;
80         do {
81           form_is_indirect = false;
82           uint32_t form_size = 0;
83           switch (form) {
84           // Blocks if inlined data that have a length field and the data bytes
85           // inlined in the .debug_info
86           case DW_FORM_exprloc:
87           case DW_FORM_block:
88             form_size = debug_info_data.GetULEB128(&offset);
89             break;
90           case DW_FORM_block1:
91             form_size = debug_info_data.GetU8_unchecked(&offset);
92             break;
93           case DW_FORM_block2:
94             form_size = debug_info_data.GetU16_unchecked(&offset);
95             break;
96           case DW_FORM_block4:
97             form_size = debug_info_data.GetU32_unchecked(&offset);
98             break;
99 
100           // Inlined NULL terminated C-strings
101           case DW_FORM_string:
102             debug_info_data.GetCStr(&offset);
103             break;
104 
105           // Compile unit address sized values
106           case DW_FORM_addr:
107             form_size = cu->GetAddressByteSize();
108             break;
109           case DW_FORM_ref_addr:
110             if (cu->GetVersion() <= 2)
111               form_size = cu->GetAddressByteSize();
112             else
113               form_size = cu->IsDWARF64() ? 8 : 4;
114             break;
115 
116           // 0 sized form
117           case DW_FORM_flag_present:
118             form_size = 0;
119             break;
120 
121           // 1 byte values
122           case DW_FORM_data1:
123           case DW_FORM_flag:
124           case DW_FORM_ref1:
125             form_size = 1;
126             break;
127 
128           // 2 byte values
129           case DW_FORM_data2:
130           case DW_FORM_ref2:
131             form_size = 2;
132             break;
133 
134           // 4 byte values
135           case DW_FORM_data4:
136           case DW_FORM_ref4:
137             form_size = 4;
138             break;
139 
140           // 8 byte values
141           case DW_FORM_data8:
142           case DW_FORM_ref8:
143           case DW_FORM_ref_sig8:
144             form_size = 8;
145             break;
146 
147           // signed or unsigned LEB 128 values
148           case DW_FORM_sdata:
149           case DW_FORM_udata:
150           case DW_FORM_ref_udata:
151           case DW_FORM_GNU_addr_index:
152           case DW_FORM_GNU_str_index:
153             debug_info_data.Skip_LEB128(&offset);
154             break;
155 
156           case DW_FORM_indirect:
157             form_is_indirect = true;
158             form = debug_info_data.GetULEB128(&offset);
159             break;
160 
161           case DW_FORM_strp:
162           case DW_FORM_sec_offset:
163             if (cu->IsDWARF64())
164               debug_info_data.GetU64(&offset);
165             else
166               debug_info_data.GetU32(&offset);
167             break;
168 
169           default:
170             *offset_ptr = m_offset;
171             return false;
172           }
173           offset += form_size;
174 
175         } while (form_is_indirect);
176       }
177     }
178     *offset_ptr = offset;
179     return true;
180   } else {
181     m_tag = 0;
182     m_has_children = false;
183     return true; // NULL debug tag entry
184   }
185 
186   return false;
187 }
188 
189 //----------------------------------------------------------------------
190 // Extract
191 //
192 // Extract a debug info entry for a given compile unit from the .debug_info and
193 // .debug_abbrev data within the SymbolFileDWARF class starting at the given
194 // offset
195 //----------------------------------------------------------------------
196 bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
197                                   const DWARFUnit *cu,
198                                   lldb::offset_t *offset_ptr) {
199   const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
200   //    const DWARFDataExtractor& debug_str_data =
201   //    dwarf2Data->get_debug_str_data();
202   const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
203   lldb::offset_t offset = *offset_ptr;
204   //  if (offset >= cu_end_offset)
205   //      Log::Status("DIE at offset 0x%8.8x is beyond the end of the current
206   //      compile unit (0x%8.8x)", m_offset, cu_end_offset);
207   if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) {
208     m_offset = offset;
209 
210     const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
211     assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
212     m_abbr_idx = abbr_idx;
213     if (abbr_idx) {
214       const DWARFAbbreviationDeclaration *abbrevDecl =
215           cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
216 
217       if (abbrevDecl) {
218         m_tag = abbrevDecl->Tag();
219         m_has_children = abbrevDecl->HasChildren();
220 
221         bool isCompileUnitTag = (m_tag == DW_TAG_compile_unit ||
222                                  m_tag == DW_TAG_partial_unit);
223         if (cu && isCompileUnitTag)
224           const_cast<DWARFUnit *>(cu)->SetBaseAddress(0);
225 
226         // Skip all data in the .debug_info for the attributes
227         const uint32_t numAttributes = abbrevDecl->NumAttributes();
228         uint32_t i;
229         dw_attr_t attr;
230         dw_form_t form;
231         for (i = 0; i < numAttributes; ++i) {
232           abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
233 
234           if (isCompileUnitTag &&
235               ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
236             DWARFFormValue form_value(cu, form);
237             if (form_value.ExtractValue(debug_info_data, &offset)) {
238               if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
239                 const_cast<DWARFUnit *>(cu)->SetBaseAddress(
240                     form_value.Address());
241             }
242           } else {
243             bool form_is_indirect = false;
244             do {
245               form_is_indirect = false;
246               uint32_t form_size = 0;
247               switch (form) {
248               // Blocks if inlined data that have a length field and the data
249               // bytes inlined in the .debug_info
250               case DW_FORM_exprloc:
251               case DW_FORM_block:
252                 form_size = debug_info_data.GetULEB128(&offset);
253                 break;
254               case DW_FORM_block1:
255                 form_size = debug_info_data.GetU8(&offset);
256                 break;
257               case DW_FORM_block2:
258                 form_size = debug_info_data.GetU16(&offset);
259                 break;
260               case DW_FORM_block4:
261                 form_size = debug_info_data.GetU32(&offset);
262                 break;
263 
264               // Inlined NULL terminated C-strings
265               case DW_FORM_string:
266                 debug_info_data.GetCStr(&offset);
267                 break;
268 
269               // Compile unit address sized values
270               case DW_FORM_addr:
271                 form_size = cu->GetAddressByteSize();
272                 break;
273               case DW_FORM_ref_addr:
274                 if (cu->GetVersion() <= 2)
275                   form_size = cu->GetAddressByteSize();
276                 else
277                   form_size = cu->IsDWARF64() ? 8 : 4;
278                 break;
279 
280               // 0 sized form
281               case DW_FORM_flag_present:
282                 form_size = 0;
283                 break;
284 
285               // 1 byte values
286               case DW_FORM_data1:
287               case DW_FORM_flag:
288               case DW_FORM_ref1:
289                 form_size = 1;
290                 break;
291 
292               // 2 byte values
293               case DW_FORM_data2:
294               case DW_FORM_ref2:
295                 form_size = 2;
296                 break;
297 
298               // 4 byte values
299               case DW_FORM_data4:
300               case DW_FORM_ref4:
301                 form_size = 4;
302                 break;
303 
304               // 8 byte values
305               case DW_FORM_data8:
306               case DW_FORM_ref8:
307               case DW_FORM_ref_sig8:
308                 form_size = 8;
309                 break;
310 
311               // signed or unsigned LEB 128 values
312               case DW_FORM_sdata:
313               case DW_FORM_udata:
314               case DW_FORM_ref_udata:
315               case DW_FORM_GNU_addr_index:
316               case DW_FORM_GNU_str_index:
317                 debug_info_data.Skip_LEB128(&offset);
318                 break;
319 
320               case DW_FORM_indirect:
321                 form = debug_info_data.GetULEB128(&offset);
322                 form_is_indirect = true;
323                 break;
324 
325               case DW_FORM_strp:
326               case DW_FORM_sec_offset:
327                 if (cu->IsDWARF64())
328                   debug_info_data.GetU64(&offset);
329                 else
330                   debug_info_data.GetU32(&offset);
331                 break;
332 
333               default:
334                 *offset_ptr = offset;
335                 return false;
336               }
337 
338               offset += form_size;
339             } while (form_is_indirect);
340           }
341         }
342         *offset_ptr = offset;
343         return true;
344       }
345     } else {
346       m_tag = 0;
347       m_has_children = false;
348       *offset_ptr = offset;
349       return true; // NULL debug tag entry
350     }
351   }
352 
353   return false;
354 }
355 
356 //----------------------------------------------------------------------
357 // DumpAncestry
358 //
359 // Dumps all of a debug information entries parents up until oldest and all of
360 // it's attributes to the specified stream.
361 //----------------------------------------------------------------------
362 void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
363                                        const DWARFUnit *cu,
364                                        const DWARFDebugInfoEntry *oldest,
365                                        Stream &s,
366                                        uint32_t recurse_depth) const {
367   const DWARFDebugInfoEntry *parent = GetParent();
368   if (parent && parent != oldest)
369     parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
370   Dump(dwarf2Data, cu, s, recurse_depth);
371 }
372 
373 //----------------------------------------------------------------------
374 // GetDIENamesAndRanges
375 //
376 // Gets the valid address ranges for a given DIE by looking for a
377 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
378 //----------------------------------------------------------------------
379 bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
380     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const char *&name,
381     const char *&mangled, DWARFRangeList &ranges, int &decl_file,
382     int &decl_line, int &decl_column, int &call_file, int &call_line,
383     int &call_column, DWARFExpression *frame_base) const {
384   if (dwarf2Data == nullptr)
385     return false;
386 
387   SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
388   if (dwo_symbol_file)
389     return GetDIENamesAndRanges(
390         dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled,
391         ranges, decl_file, decl_line, decl_column, call_file, call_line,
392         call_column, frame_base);
393 
394   dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
395   dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
396   std::vector<DIERef> die_refs;
397   bool set_frame_base_loclist_addr = false;
398 
399   lldb::offset_t offset;
400   const DWARFAbbreviationDeclaration *abbrevDecl =
401       GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
402 
403   lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
404 
405   if (abbrevDecl) {
406     const DWARFDataExtractor &debug_info_data =
407         dwarf2Data->get_debug_info_data();
408 
409     if (!debug_info_data.ValidOffset(offset))
410       return false;
411 
412     const uint32_t numAttributes = abbrevDecl->NumAttributes();
413     uint32_t i;
414     dw_attr_t attr;
415     dw_form_t form;
416     bool do_offset = false;
417 
418     for (i = 0; i < numAttributes; ++i) {
419       abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
420       DWARFFormValue form_value(cu, form);
421       if (form_value.ExtractValue(debug_info_data, &offset)) {
422         switch (attr) {
423         case DW_AT_low_pc:
424           lo_pc = form_value.Address();
425 
426           if (do_offset)
427             hi_pc += lo_pc;
428           do_offset = false;
429           break;
430 
431         case DW_AT_entry_pc:
432           lo_pc = form_value.Address();
433           break;
434 
435         case DW_AT_high_pc:
436           if (form_value.Form() == DW_FORM_addr ||
437               form_value.Form() == DW_FORM_GNU_addr_index) {
438             hi_pc = form_value.Address();
439           } else {
440             hi_pc = form_value.Unsigned();
441             if (lo_pc == LLDB_INVALID_ADDRESS)
442               do_offset = hi_pc != LLDB_INVALID_ADDRESS;
443             else
444               hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
445                               // on relocations
446           }
447           break;
448 
449         case DW_AT_ranges: {
450           const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
451           if (debug_ranges) {
452             debug_ranges->FindRanges(cu->GetRangesBase(), form_value.Unsigned(), ranges);
453             // All DW_AT_ranges are relative to the base address of the compile
454             // unit. We add the compile unit base address to make sure all the
455             // addresses are properly fixed up.
456             ranges.Slide(cu->GetBaseAddress());
457           } else {
458             cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
459                 "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
460                 ") attribute yet DWARF has no .debug_ranges, please file a bug "
461                 "and attach the file at the start of this error message",
462                 m_offset, form_value.Unsigned());
463           }
464         } break;
465 
466         case DW_AT_name:
467           if (name == NULL)
468             name = form_value.AsCString();
469           break;
470 
471         case DW_AT_MIPS_linkage_name:
472         case DW_AT_linkage_name:
473           if (mangled == NULL)
474             mangled = form_value.AsCString();
475           break;
476 
477         case DW_AT_abstract_origin:
478           die_refs.emplace_back(form_value);
479           break;
480 
481         case DW_AT_specification:
482           die_refs.emplace_back(form_value);
483           break;
484 
485         case DW_AT_decl_file:
486           if (decl_file == 0)
487             decl_file = form_value.Unsigned();
488           break;
489 
490         case DW_AT_decl_line:
491           if (decl_line == 0)
492             decl_line = form_value.Unsigned();
493           break;
494 
495         case DW_AT_decl_column:
496           if (decl_column == 0)
497             decl_column = form_value.Unsigned();
498           break;
499 
500         case DW_AT_call_file:
501           if (call_file == 0)
502             call_file = form_value.Unsigned();
503           break;
504 
505         case DW_AT_call_line:
506           if (call_line == 0)
507             call_line = form_value.Unsigned();
508           break;
509 
510         case DW_AT_call_column:
511           if (call_column == 0)
512             call_column = form_value.Unsigned();
513           break;
514 
515         case DW_AT_frame_base:
516           if (frame_base) {
517             if (form_value.BlockData()) {
518               uint32_t block_offset =
519                   form_value.BlockData() - debug_info_data.GetDataStart();
520               uint32_t block_length = form_value.Unsigned();
521               frame_base->SetOpcodeData(module, debug_info_data, block_offset,
522                                         block_length);
523             } else {
524               const DWARFDataExtractor &debug_loc_data =
525                   dwarf2Data->get_debug_loc_data();
526               const dw_offset_t debug_loc_offset = form_value.Unsigned();
527 
528               size_t loc_list_length = DWARFExpression::LocationListSize(
529                   cu, debug_loc_data, debug_loc_offset);
530               if (loc_list_length > 0) {
531                 frame_base->SetOpcodeData(module, debug_loc_data,
532                                           debug_loc_offset, loc_list_length);
533                 if (lo_pc != LLDB_INVALID_ADDRESS) {
534                   assert(lo_pc >= cu->GetBaseAddress());
535                   frame_base->SetLocationListSlide(lo_pc -
536                                                    cu->GetBaseAddress());
537                 } else {
538                   set_frame_base_loclist_addr = true;
539                 }
540               }
541             }
542           }
543           break;
544 
545         default:
546           break;
547         }
548       }
549     }
550   }
551 
552   if (ranges.IsEmpty()) {
553     if (lo_pc != LLDB_INVALID_ADDRESS) {
554       if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
555         ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
556       else
557         ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
558     }
559   }
560 
561   if (set_frame_base_loclist_addr) {
562     dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
563     assert(lowest_range_pc >= cu->GetBaseAddress());
564     frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
565   }
566 
567   if (ranges.IsEmpty() || name == NULL || mangled == NULL) {
568     for (const DIERef &die_ref : die_refs) {
569       if (die_ref.die_offset != DW_INVALID_OFFSET) {
570         DWARFDIE die = dwarf2Data->GetDIE(die_ref);
571         if (die)
572           die.GetDIE()->GetDIENamesAndRanges(
573               die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file,
574               decl_line, decl_column, call_file, call_line, call_column);
575       }
576     }
577   }
578   return !ranges.IsEmpty();
579 }
580 
581 //----------------------------------------------------------------------
582 // Dump
583 //
584 // Dumps a debug information entry and all of it's attributes to the specified
585 // stream.
586 //----------------------------------------------------------------------
587 void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
588                                const DWARFUnit *cu, Stream &s,
589                                uint32_t recurse_depth) const {
590   const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
591   lldb::offset_t offset = m_offset;
592 
593   if (debug_info_data.ValidOffset(offset)) {
594     dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
595 
596     s.Printf("\n0x%8.8x: ", m_offset);
597     s.Indent();
598     if (abbrCode != m_abbr_idx) {
599       s.Printf("error: DWARF has been modified\n");
600     } else if (abbrCode) {
601       const DWARFAbbreviationDeclaration *abbrevDecl =
602           cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode);
603 
604       if (abbrevDecl) {
605         s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
606         s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');
607 
608         // Dump all data in the .debug_info for the attributes
609         const uint32_t numAttributes = abbrevDecl->NumAttributes();
610         uint32_t i;
611         dw_attr_t attr;
612         dw_form_t form;
613         for (i = 0; i < numAttributes; ++i) {
614           abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
615 
616           DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
617                         form);
618         }
619 
620         const DWARFDebugInfoEntry *child = GetFirstChild();
621         if (recurse_depth > 0 && child) {
622           s.IndentMore();
623 
624           while (child) {
625             child->Dump(dwarf2Data, cu, s, recurse_depth - 1);
626             child = child->GetSibling();
627           }
628           s.IndentLess();
629         }
630       } else
631         s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
632                  "code: %u\n",
633                  abbrCode);
634     } else {
635       s.Printf("NULL\n");
636     }
637   }
638 }
639 
640 void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data,
641                                        DWARFUnit *cu, Stream &s) const {
642   const DWARFDIE cu_die = cu->GetUnitDIEOnly();
643   const char *cu_name = NULL;
644   if (cu_die)
645     cu_name = cu_die.GetName();
646   const char *obj_file_name = NULL;
647   ObjectFile *obj_file = dwarf2Data->GetObjectFile();
648   if (obj_file)
649     obj_file_name =
650         obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>");
651   const char *die_name = GetName(dwarf2Data, cu);
652   s.Printf("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", cu->GetOffset(),
653            GetOffset(), die_name ? die_name : "", cu_name ? cu_name : "<NULL>",
654            obj_file_name ? obj_file_name : "<NULL>");
655 }
656 
657 //----------------------------------------------------------------------
658 // DumpAttribute
659 //
660 // Dumps a debug information entry attribute along with it's form. Any special
661 // display of attributes is done (disassemble location lists, show enumeration
662 // values for attributes, etc).
663 //----------------------------------------------------------------------
664 void DWARFDebugInfoEntry::DumpAttribute(
665     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
666     const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr,
667     Stream &s, dw_attr_t attr, dw_form_t form) {
668   bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
669 
670   s.Printf("            ");
671   s.Indent(DW_AT_value_to_name(attr));
672 
673   if (show_form) {
674     s.Printf("[%s", DW_FORM_value_to_name(form));
675   }
676 
677   DWARFFormValue form_value(cu, form);
678 
679   if (!form_value.ExtractValue(debug_info_data, offset_ptr))
680     return;
681 
682   if (show_form) {
683     if (form == DW_FORM_indirect) {
684       s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
685     }
686 
687     s.PutCString("] ");
688   }
689 
690   s.PutCString("( ");
691 
692   // Check to see if we have any special attribute formatters
693   switch (attr) {
694   case DW_AT_stmt_list:
695     s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
696     break;
697 
698   case DW_AT_language:
699     s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
700     break;
701 
702   case DW_AT_encoding:
703     s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
704     break;
705 
706   case DW_AT_frame_base:
707   case DW_AT_location:
708   case DW_AT_data_member_location: {
709     const uint8_t *blockData = form_value.BlockData();
710     if (blockData) {
711       // Location description is inlined in data in the form value
712       DWARFDataExtractor locationData(debug_info_data,
713                                       (*offset_ptr) - form_value.Unsigned(),
714                                       form_value.Unsigned());
715       DWARFExpression::PrintDWARFExpression(
716           s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
717     } else {
718       // We have a location list offset as the value that is the offset into
719       // the .debug_loc section that describes the value over it's lifetime
720       uint64_t debug_loc_offset = form_value.Unsigned();
721       if (dwarf2Data) {
722         DWARFExpression::PrintDWARFLocationList(
723             s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
724       }
725     }
726   } break;
727 
728   case DW_AT_abstract_origin:
729   case DW_AT_specification: {
730     uint64_t abstract_die_offset = form_value.Reference();
731     form_value.Dump(s);
732     //  *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
733     GetName(dwarf2Data, cu, abstract_die_offset, s);
734   } break;
735 
736   case DW_AT_type: {
737     uint64_t type_die_offset = form_value.Reference();
738     s.PutCString(" ( ");
739     AppendTypeName(dwarf2Data, cu, type_die_offset, s);
740     s.PutCString(" )");
741   } break;
742 
743   case DW_AT_ranges: {
744     lldb::offset_t ranges_offset = form_value.Unsigned();
745     dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
746     if (dwarf2Data)
747       DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
748                              &ranges_offset, base_addr);
749   } break;
750 
751   default:
752     break;
753   }
754 
755   s.PutCString(" )\n");
756 }
757 
758 //----------------------------------------------------------------------
759 // Get all attribute values for a given DIE, including following any
760 // specification or abstract origin attributes and including those in the
761 // results. Any duplicate attributes will have the first instance take
762 // precedence (this can happen for declaration attributes).
763 //----------------------------------------------------------------------
764 size_t DWARFDebugInfoEntry::GetAttributes(
765     const DWARFUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
766     DWARFAttributes &attributes, uint32_t curr_depth) const {
767   SymbolFileDWARF *dwarf2Data = nullptr;
768   const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
769   lldb::offset_t offset = 0;
770   if (cu) {
771     if (m_tag != DW_TAG_compile_unit && m_tag != DW_TAG_partial_unit) {
772       SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
773       if (dwo_symbol_file)
774         return GetAttributes(dwo_symbol_file->GetCompileUnit(),
775                              fixed_form_sizes, attributes, curr_depth);
776     }
777 
778     dwarf2Data = cu->GetSymbolFileDWARF();
779     abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
780   }
781 
782   if (abbrevDecl) {
783     const DWARFDataExtractor &debug_info_data =
784         dwarf2Data->get_debug_info_data();
785 
786     if (fixed_form_sizes.Empty())
787       fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
788           cu->GetAddressByteSize(), cu->IsDWARF64());
789 
790     const uint32_t num_attributes = abbrevDecl->NumAttributes();
791     uint32_t i;
792     dw_attr_t attr;
793     dw_form_t form;
794     for (i = 0; i < num_attributes; ++i) {
795       abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
796 
797       // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
798       // attributes, the depth will be non-zero. We need to omit certain
799       // attributes that don't make sense.
800       switch (attr) {
801       case DW_AT_sibling:
802       case DW_AT_declaration:
803         if (curr_depth > 0) {
804           // This attribute doesn't make sense when combined with the DIE that
805           // references this DIE. We know a DIE is referencing this DIE because
806           // curr_depth is not zero
807           break;
808         }
809         LLVM_FALLTHROUGH;
810       default:
811         attributes.Append(cu, offset, attr, form);
812         break;
813       }
814 
815       if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
816         DWARFFormValue form_value(cu, form);
817         if (form_value.ExtractValue(debug_info_data, &offset)) {
818           dw_offset_t die_offset = form_value.Reference();
819           DWARFDIE spec_die =
820               const_cast<DWARFUnit *>(cu)->GetDIE(die_offset);
821           if (spec_die)
822             spec_die.GetAttributes(attributes, curr_depth + 1);
823         }
824       } else {
825         const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
826         if (fixed_skip_size)
827           offset += fixed_skip_size;
828         else
829           DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
830       }
831     }
832   } else {
833     attributes.Clear();
834   }
835   return attributes.Size();
836 }
837 
838 //----------------------------------------------------------------------
839 // GetAttributeValue
840 //
841 // Get the value of an attribute and return the .debug_info offset of the
842 // attribute if it was properly extracted into form_value, or zero if we fail
843 // since an offset of zero is invalid for an attribute (it would be a compile
844 // unit header).
845 //----------------------------------------------------------------------
846 dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
847     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
848     const dw_attr_t attr, DWARFFormValue &form_value,
849     dw_offset_t *end_attr_offset_ptr,
850     bool check_specification_or_abstract_origin) const {
851   SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
852   if (dwo_symbol_file && m_tag != DW_TAG_compile_unit &&
853                          m_tag != DW_TAG_partial_unit)
854     return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(),
855                              attr, form_value, end_attr_offset_ptr,
856                              check_specification_or_abstract_origin);
857 
858   lldb::offset_t offset;
859   const DWARFAbbreviationDeclaration *abbrevDecl =
860       GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
861 
862   if (abbrevDecl) {
863     uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
864 
865     if (attr_idx != DW_INVALID_INDEX) {
866       const DWARFDataExtractor &debug_info_data =
867           dwarf2Data->get_debug_info_data();
868 
869       uint32_t idx = 0;
870       while (idx < attr_idx)
871         DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
872                                   debug_info_data, &offset, cu);
873 
874       const dw_offset_t attr_offset = offset;
875       form_value.SetCompileUnit(cu);
876       form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
877       if (form_value.ExtractValue(debug_info_data, &offset)) {
878         if (end_attr_offset_ptr)
879           *end_attr_offset_ptr = offset;
880         return attr_offset;
881       }
882     }
883   }
884 
885   if (check_specification_or_abstract_origin) {
886     if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) {
887       DWARFDIE die =
888           const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
889       if (die) {
890         dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
891             die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
892             false);
893         if (die_offset)
894           return die_offset;
895       }
896     }
897 
898     if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) {
899       DWARFDIE die =
900           const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
901       if (die) {
902         dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
903             die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
904             false);
905         if (die_offset)
906           return die_offset;
907       }
908     }
909   }
910 
911   if (!dwo_symbol_file)
912     return 0;
913 
914   DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
915   if (!dwo_cu)
916     return 0;
917 
918   DWARFDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
919   if (!dwo_cu_die.IsValid())
920     return 0;
921 
922   return dwo_cu_die.GetDIE()->GetAttributeValue(
923       dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr,
924       check_specification_or_abstract_origin);
925 }
926 
927 //----------------------------------------------------------------------
928 // GetAttributeValueAsString
929 //
930 // Get the value of an attribute as a string return it. The resulting pointer
931 // to the string data exists within the supplied SymbolFileDWARF and will only
932 // be available as long as the SymbolFileDWARF is still around and it's content
933 // doesn't change.
934 //----------------------------------------------------------------------
935 const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
936     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
937     const dw_attr_t attr, const char *fail_value,
938     bool check_specification_or_abstract_origin) const {
939   DWARFFormValue form_value;
940   if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
941                         check_specification_or_abstract_origin))
942     return form_value.AsCString();
943   return fail_value;
944 }
945 
946 //----------------------------------------------------------------------
947 // GetAttributeValueAsUnsigned
948 //
949 // Get the value of an attribute as unsigned and return it.
950 //----------------------------------------------------------------------
951 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
952     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
953     const dw_attr_t attr, uint64_t fail_value,
954     bool check_specification_or_abstract_origin) const {
955   DWARFFormValue form_value;
956   if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
957                         check_specification_or_abstract_origin))
958     return form_value.Unsigned();
959   return fail_value;
960 }
961 
962 //----------------------------------------------------------------------
963 // GetAttributeValueAsSigned
964 //
965 // Get the value of an attribute a signed value and return it.
966 //----------------------------------------------------------------------
967 int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned(
968     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
969     const dw_attr_t attr, int64_t fail_value,
970     bool check_specification_or_abstract_origin) const {
971   DWARFFormValue form_value;
972   if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
973                         check_specification_or_abstract_origin))
974     return form_value.Signed();
975   return fail_value;
976 }
977 
978 //----------------------------------------------------------------------
979 // GetAttributeValueAsReference
980 //
981 // Get the value of an attribute as reference and fix up and compile unit
982 // relative offsets as needed.
983 //----------------------------------------------------------------------
984 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference(
985     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
986     const dw_attr_t attr, uint64_t fail_value,
987     bool check_specification_or_abstract_origin) const {
988   DWARFFormValue form_value;
989   if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
990                         check_specification_or_abstract_origin))
991     return form_value.Reference();
992   return fail_value;
993 }
994 
995 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
996     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
997     const dw_attr_t attr, uint64_t fail_value,
998     bool check_specification_or_abstract_origin) const {
999   DWARFFormValue form_value;
1000   if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
1001                         check_specification_or_abstract_origin))
1002     return form_value.Address();
1003   return fail_value;
1004 }
1005 
1006 //----------------------------------------------------------------------
1007 // GetAttributeHighPC
1008 //
1009 // Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
1010 // pc>.
1011 //
1012 // Returns the hi_pc or fail_value.
1013 //----------------------------------------------------------------------
1014 dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
1015     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t lo_pc,
1016     uint64_t fail_value, bool check_specification_or_abstract_origin) const {
1017   DWARFFormValue form_value;
1018   if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr,
1019                         check_specification_or_abstract_origin)) {
1020     dw_form_t form = form_value.Form();
1021     if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
1022       return form_value.Address();
1023 
1024     // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
1025     return lo_pc + form_value.Unsigned();
1026   }
1027   return fail_value;
1028 }
1029 
1030 //----------------------------------------------------------------------
1031 // GetAttributeAddressRange
1032 //
1033 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
1034 // from-low-pc>.
1035 //
1036 // Returns true or sets lo_pc and hi_pc to fail_value.
1037 //----------------------------------------------------------------------
1038 bool DWARFDebugInfoEntry::GetAttributeAddressRange(
1039     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, dw_addr_t &lo_pc,
1040     dw_addr_t &hi_pc, uint64_t fail_value,
1041     bool check_specification_or_abstract_origin) const {
1042   lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value,
1043                                      check_specification_or_abstract_origin);
1044   if (lo_pc != fail_value) {
1045     hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value,
1046                                check_specification_or_abstract_origin);
1047     if (hi_pc != fail_value)
1048       return true;
1049   }
1050   lo_pc = fail_value;
1051   hi_pc = fail_value;
1052   return false;
1053 }
1054 
1055 size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
1056     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
1057     DWARFRangeList &ranges, bool check_hi_lo_pc,
1058     bool check_specification_or_abstract_origin) const {
1059   ranges.Clear();
1060 
1061   dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
1062       dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET,
1063       check_specification_or_abstract_origin);
1064   if (debug_ranges_offset != DW_INVALID_OFFSET) {
1065     DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
1066 
1067     debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
1068     ranges.Slide(cu->GetBaseAddress());
1069   } else if (check_hi_lo_pc) {
1070     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1071     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1072     if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
1073                                  LLDB_INVALID_ADDRESS,
1074                                  check_specification_or_abstract_origin)) {
1075       if (lo_pc < hi_pc)
1076         ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
1077     }
1078   }
1079   return ranges.GetSize();
1080 }
1081 
1082 //----------------------------------------------------------------------
1083 // GetName
1084 //
1085 // Get value of the DW_AT_name attribute and return it if one exists, else
1086 // return NULL.
1087 //----------------------------------------------------------------------
1088 const char *DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
1089                                          const DWARFUnit *cu) const {
1090   return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
1091 }
1092 
1093 //----------------------------------------------------------------------
1094 // GetMangledName
1095 //
1096 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
1097 // exists, else return the value of the DW_AT_name attribute
1098 //----------------------------------------------------------------------
1099 const char *
1100 DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data,
1101                                     const DWARFUnit *cu,
1102                                     bool substitute_name_allowed) const {
1103   const char *name = nullptr;
1104 
1105   name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
1106                                    nullptr, true);
1107   if (name)
1108     return name;
1109 
1110   name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
1111                                    true);
1112   if (name)
1113     return name;
1114 
1115   if (!substitute_name_allowed)
1116     return nullptr;
1117 
1118   name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
1119   return name;
1120 }
1121 
1122 //----------------------------------------------------------------------
1123 // GetPubname
1124 //
1125 // Get value the name for a DIE as it should appear for a .debug_pubnames or
1126 // .debug_pubtypes section.
1127 //----------------------------------------------------------------------
1128 const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data,
1129                                             const DWARFUnit *cu) const {
1130   const char *name = nullptr;
1131   if (!dwarf2Data)
1132     return name;
1133 
1134   name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
1135                                    nullptr, true);
1136   if (name)
1137     return name;
1138 
1139   name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
1140                                    true);
1141   if (name)
1142     return name;
1143 
1144   name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
1145   return name;
1146 }
1147 
1148 //----------------------------------------------------------------------
1149 // GetName
1150 //
1151 // Get value of the DW_AT_name attribute for a debug information entry that
1152 // exists at offset "die_offset" and place that value into the supplied stream
1153 // object. If the DIE is a NULL object "NULL" is placed into the stream, and if
1154 // no DW_AT_name attribute exists for the DIE then nothing is printed.
1155 //----------------------------------------------------------------------
1156 bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
1157                                   const DWARFUnit *cu,
1158                                   const dw_offset_t die_offset, Stream &s) {
1159   if (dwarf2Data == NULL) {
1160     s.PutCString("NULL");
1161     return false;
1162   }
1163 
1164   DWARFDebugInfoEntry die;
1165   lldb::offset_t offset = die_offset;
1166   if (die.Extract(dwarf2Data, cu, &offset)) {
1167     if (die.IsNULL()) {
1168       s.PutCString("NULL");
1169       return true;
1170     } else {
1171       const char *name = die.GetAttributeValueAsString(
1172           dwarf2Data, cu, DW_AT_name, nullptr, true);
1173       if (name) {
1174         s.PutCString(name);
1175         return true;
1176       }
1177     }
1178   }
1179   return false;
1180 }
1181 
1182 //----------------------------------------------------------------------
1183 // AppendTypeName
1184 //
1185 // Follows the type name definition down through all needed tags to end up with
1186 // a fully qualified type name and dump the results to the supplied stream.
1187 // This is used to show the name of types given a type identifier.
1188 //----------------------------------------------------------------------
1189 bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
1190                                          const DWARFUnit *cu,
1191                                          const dw_offset_t die_offset,
1192                                          Stream &s) {
1193   if (dwarf2Data == NULL) {
1194     s.PutCString("NULL");
1195     return false;
1196   }
1197 
1198   DWARFDebugInfoEntry die;
1199   lldb::offset_t offset = die_offset;
1200   if (die.Extract(dwarf2Data, cu, &offset)) {
1201     if (die.IsNULL()) {
1202       s.PutCString("NULL");
1203       return true;
1204     } else {
1205       const char *name = die.GetPubname(dwarf2Data, cu);
1206       if (name)
1207         s.PutCString(name);
1208       else {
1209         bool result = true;
1210         const DWARFAbbreviationDeclaration *abbrevDecl =
1211             die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
1212 
1213         if (abbrevDecl == NULL)
1214           return false;
1215 
1216         switch (abbrevDecl->Tag()) {
1217         case DW_TAG_array_type:
1218           break; // print out a "[]" after printing the full type of the element
1219                  // below
1220         case DW_TAG_base_type:
1221           s.PutCString("base ");
1222           break;
1223         case DW_TAG_class_type:
1224           s.PutCString("class ");
1225           break;
1226         case DW_TAG_const_type:
1227           s.PutCString("const ");
1228           break;
1229         case DW_TAG_enumeration_type:
1230           s.PutCString("enum ");
1231           break;
1232         case DW_TAG_file_type:
1233           s.PutCString("file ");
1234           break;
1235         case DW_TAG_interface_type:
1236           s.PutCString("interface ");
1237           break;
1238         case DW_TAG_packed_type:
1239           s.PutCString("packed ");
1240           break;
1241         case DW_TAG_pointer_type:
1242           break; // print out a '*' after printing the full type below
1243         case DW_TAG_ptr_to_member_type:
1244           break; // print out a '*' after printing the full type below
1245         case DW_TAG_reference_type:
1246           break; // print out a '&' after printing the full type below
1247         case DW_TAG_restrict_type:
1248           s.PutCString("restrict ");
1249           break;
1250         case DW_TAG_set_type:
1251           s.PutCString("set ");
1252           break;
1253         case DW_TAG_shared_type:
1254           s.PutCString("shared ");
1255           break;
1256         case DW_TAG_string_type:
1257           s.PutCString("string ");
1258           break;
1259         case DW_TAG_structure_type:
1260           s.PutCString("struct ");
1261           break;
1262         case DW_TAG_subrange_type:
1263           s.PutCString("subrange ");
1264           break;
1265         case DW_TAG_subroutine_type:
1266           s.PutCString("function ");
1267           break;
1268         case DW_TAG_thrown_type:
1269           s.PutCString("thrown ");
1270           break;
1271         case DW_TAG_union_type:
1272           s.PutCString("union ");
1273           break;
1274         case DW_TAG_unspecified_type:
1275           s.PutCString("unspecified ");
1276           break;
1277         case DW_TAG_volatile_type:
1278           s.PutCString("volatile ");
1279           break;
1280         default:
1281           return false;
1282         }
1283 
1284         // Follow the DW_AT_type if possible
1285         DWARFFormValue form_value;
1286         if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) {
1287           uint64_t next_die_offset = form_value.Reference();
1288           result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
1289         }
1290 
1291         switch (abbrevDecl->Tag()) {
1292         case DW_TAG_array_type:
1293           s.PutCString("[]");
1294           break;
1295         case DW_TAG_pointer_type:
1296           s.PutChar('*');
1297           break;
1298         case DW_TAG_ptr_to_member_type:
1299           s.PutChar('*');
1300           break;
1301         case DW_TAG_reference_type:
1302           s.PutChar('&');
1303           break;
1304         default:
1305           break;
1306         }
1307         return result;
1308       }
1309     }
1310   }
1311   return false;
1312 }
1313 
1314 //----------------------------------------------------------------------
1315 // BuildAddressRangeTable
1316 //----------------------------------------------------------------------
1317 void DWARFDebugInfoEntry::BuildAddressRangeTable(
1318     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
1319     DWARFDebugAranges *debug_aranges) const {
1320   if (m_tag) {
1321     if (m_tag == DW_TAG_subprogram) {
1322       dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1323       dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1324       if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
1325                                    LLDB_INVALID_ADDRESS)) {
1326         /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
1327         /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
1328         debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
1329       }
1330     }
1331 
1332     const DWARFDebugInfoEntry *child = GetFirstChild();
1333     while (child) {
1334       child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
1335       child = child->GetSibling();
1336     }
1337   }
1338 }
1339 
1340 //----------------------------------------------------------------------
1341 // BuildFunctionAddressRangeTable
1342 //
1343 // This function is very similar to the BuildAddressRangeTable function except
1344 // that the actual DIE offset for the function is placed in the table instead
1345 // of the compile unit offset (which is the way the standard .debug_aranges
1346 // section does it).
1347 //----------------------------------------------------------------------
1348 void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
1349     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
1350     DWARFDebugAranges *debug_aranges) const {
1351   if (m_tag) {
1352     if (m_tag == DW_TAG_subprogram) {
1353       dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1354       dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1355       if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
1356                                    LLDB_INVALID_ADDRESS)) {
1357         //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
1358         //  0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
1359         debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
1360       }
1361     }
1362 
1363     const DWARFDebugInfoEntry *child = GetFirstChild();
1364     while (child) {
1365       child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
1366       child = child->GetSibling();
1367     }
1368   }
1369 }
1370 
1371 void DWARFDebugInfoEntry::GetDeclContextDIEs(
1372     DWARFUnit *cu, DWARFDIECollection &decl_context_dies) const {
1373 
1374   DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
1375   die.GetDeclContextDIEs(decl_context_dies);
1376 }
1377 
1378 void DWARFDebugInfoEntry::GetDWARFDeclContext(
1379     SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
1380     DWARFDeclContext &dwarf_decl_ctx) const {
1381   const dw_tag_t tag = Tag();
1382   if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) {
1383     dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
1384     DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
1385     if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
1386       if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit &&
1387           parent_decl_ctx_die.Tag() != DW_TAG_partial_unit)
1388         parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
1389             parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(),
1390             dwarf_decl_ctx);
1391     }
1392   }
1393 }
1394 
1395 bool DWARFDebugInfoEntry::MatchesDWARFDeclContext(
1396     SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
1397     const DWARFDeclContext &dwarf_decl_ctx) const {
1398 
1399   DWARFDeclContext this_dwarf_decl_ctx;
1400   GetDWARFDeclContext(dwarf2Data, cu, this_dwarf_decl_ctx);
1401   return this_dwarf_decl_ctx == dwarf_decl_ctx;
1402 }
1403 
1404 DWARFDIE
1405 DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
1406                                              DWARFUnit *cu) const {
1407   DWARFAttributes attributes;
1408   GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
1409   return GetParentDeclContextDIE(dwarf2Data, cu, attributes);
1410 }
1411 
1412 DWARFDIE
1413 DWARFDebugInfoEntry::GetParentDeclContextDIE(
1414     SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
1415     const DWARFAttributes &attributes) const {
1416   DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
1417 
1418   while (die) {
1419     // If this is the original DIE that we are searching for a declaration for,
1420     // then don't look in the cache as we don't want our own decl context to be
1421     // our decl context...
1422     if (die.GetDIE() != this) {
1423       switch (die.Tag()) {
1424       case DW_TAG_compile_unit:
1425       case DW_TAG_partial_unit:
1426       case DW_TAG_namespace:
1427       case DW_TAG_structure_type:
1428       case DW_TAG_union_type:
1429       case DW_TAG_class_type:
1430         return die;
1431 
1432       default:
1433         break;
1434       }
1435     }
1436 
1437     dw_offset_t die_offset;
1438 
1439     die_offset =
1440         attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
1441     if (die_offset != DW_INVALID_OFFSET) {
1442       DWARFDIE spec_die = cu->GetDIE(die_offset);
1443       if (spec_die) {
1444         DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
1445         if (decl_ctx_die)
1446           return decl_ctx_die;
1447       }
1448     }
1449 
1450     die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin,
1451                                                 DW_INVALID_OFFSET);
1452     if (die_offset != DW_INVALID_OFFSET) {
1453       DWARFDIE abs_die = cu->GetDIE(die_offset);
1454       if (abs_die) {
1455         DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
1456         if (decl_ctx_die)
1457           return decl_ctx_die;
1458       }
1459     }
1460 
1461     die = die.GetParent();
1462   }
1463   return DWARFDIE();
1464 }
1465 
1466 const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data,
1467                                                   DWARFUnit *cu,
1468                                                   std::string &storage) const {
1469   DWARFAttributes attributes;
1470   GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
1471   return GetQualifiedName(dwarf2Data, cu, attributes, storage);
1472 }
1473 
1474 const char *DWARFDebugInfoEntry::GetQualifiedName(
1475     SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
1476     const DWARFAttributes &attributes, std::string &storage) const {
1477 
1478   const char *name = GetName(dwarf2Data, cu);
1479 
1480   if (name) {
1481     DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
1482     storage.clear();
1483     // TODO: change this to get the correct decl context parent....
1484     while (parent_decl_ctx_die) {
1485       const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
1486       switch (parent_tag) {
1487       case DW_TAG_namespace: {
1488         const char *namespace_name = parent_decl_ctx_die.GetName();
1489         if (namespace_name) {
1490           storage.insert(0, "::");
1491           storage.insert(0, namespace_name);
1492         } else {
1493           storage.insert(0, "(anonymous namespace)::");
1494         }
1495         parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1496       } break;
1497 
1498       case DW_TAG_class_type:
1499       case DW_TAG_structure_type:
1500       case DW_TAG_union_type: {
1501         const char *class_union_struct_name = parent_decl_ctx_die.GetName();
1502 
1503         if (class_union_struct_name) {
1504           storage.insert(0, "::");
1505           storage.insert(0, class_union_struct_name);
1506         }
1507         parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1508       } break;
1509 
1510       default:
1511         parent_decl_ctx_die.Clear();
1512         break;
1513       }
1514     }
1515 
1516     if (storage.empty())
1517       storage.append("::");
1518 
1519     storage.append(name);
1520   }
1521   if (storage.empty())
1522     return NULL;
1523   return storage.c_str();
1524 }
1525 
1526 //----------------------------------------------------------------------
1527 // LookupAddress
1528 //----------------------------------------------------------------------
1529 bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
1530                                         SymbolFileDWARF *dwarf2Data,
1531                                         const DWARFUnit *cu,
1532                                         DWARFDebugInfoEntry **function_die,
1533                                         DWARFDebugInfoEntry **block_die) {
1534   bool found_address = false;
1535   if (m_tag) {
1536     bool check_children = false;
1537     bool match_addr_range = false;
1538     //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
1539     //  DW_TAG_value_to_name(tag), address);
1540     switch (m_tag) {
1541     case DW_TAG_array_type:
1542       break;
1543     case DW_TAG_class_type:
1544       check_children = true;
1545       break;
1546     case DW_TAG_entry_point:
1547       break;
1548     case DW_TAG_enumeration_type:
1549       break;
1550     case DW_TAG_formal_parameter:
1551       break;
1552     case DW_TAG_imported_declaration:
1553       break;
1554     case DW_TAG_label:
1555       break;
1556     case DW_TAG_lexical_block:
1557       check_children = true;
1558       match_addr_range = true;
1559       break;
1560     case DW_TAG_member:
1561       break;
1562     case DW_TAG_pointer_type:
1563       break;
1564     case DW_TAG_reference_type:
1565       break;
1566     case DW_TAG_compile_unit:
1567       match_addr_range = true;
1568       break;
1569     case DW_TAG_string_type:
1570       break;
1571     case DW_TAG_structure_type:
1572       check_children = true;
1573       break;
1574     case DW_TAG_subroutine_type:
1575       break;
1576     case DW_TAG_typedef:
1577       break;
1578     case DW_TAG_union_type:
1579       break;
1580     case DW_TAG_unspecified_parameters:
1581       break;
1582     case DW_TAG_variant:
1583       break;
1584     case DW_TAG_common_block:
1585       check_children = true;
1586       break;
1587     case DW_TAG_common_inclusion:
1588       break;
1589     case DW_TAG_inheritance:
1590       break;
1591     case DW_TAG_inlined_subroutine:
1592       check_children = true;
1593       match_addr_range = true;
1594       break;
1595     case DW_TAG_module:
1596       match_addr_range = true;
1597       break;
1598     case DW_TAG_ptr_to_member_type:
1599       break;
1600     case DW_TAG_set_type:
1601       break;
1602     case DW_TAG_subrange_type:
1603       break;
1604     case DW_TAG_with_stmt:
1605       break;
1606     case DW_TAG_access_declaration:
1607       break;
1608     case DW_TAG_base_type:
1609       break;
1610     case DW_TAG_catch_block:
1611       match_addr_range = true;
1612       break;
1613     case DW_TAG_const_type:
1614       break;
1615     case DW_TAG_constant:
1616       break;
1617     case DW_TAG_enumerator:
1618       break;
1619     case DW_TAG_file_type:
1620       break;
1621     case DW_TAG_friend:
1622       break;
1623     case DW_TAG_namelist:
1624       break;
1625     case DW_TAG_namelist_item:
1626       break;
1627     case DW_TAG_packed_type:
1628       break;
1629     case DW_TAG_subprogram:
1630       match_addr_range = true;
1631       break;
1632     case DW_TAG_template_type_parameter:
1633       break;
1634     case DW_TAG_template_value_parameter:
1635       break;
1636     case DW_TAG_GNU_template_parameter_pack:
1637       break;
1638     case DW_TAG_thrown_type:
1639       break;
1640     case DW_TAG_try_block:
1641       match_addr_range = true;
1642       break;
1643     case DW_TAG_variant_part:
1644       break;
1645     case DW_TAG_variable:
1646       break;
1647     case DW_TAG_volatile_type:
1648       break;
1649     case DW_TAG_dwarf_procedure:
1650       break;
1651     case DW_TAG_restrict_type:
1652       break;
1653     case DW_TAG_interface_type:
1654       break;
1655     case DW_TAG_namespace:
1656       check_children = true;
1657       break;
1658     case DW_TAG_imported_module:
1659       break;
1660     case DW_TAG_unspecified_type:
1661       break;
1662     case DW_TAG_partial_unit:
1663       match_addr_range = true;
1664       break;
1665     case DW_TAG_imported_unit:
1666       break;
1667     case DW_TAG_shared_type:
1668       break;
1669     default:
1670       break;
1671     }
1672 
1673     if (match_addr_range) {
1674       dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc,
1675                                                    LLDB_INVALID_ADDRESS);
1676       if (lo_pc != LLDB_INVALID_ADDRESS) {
1677         dw_addr_t hi_pc =
1678             GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
1679         if (hi_pc != LLDB_INVALID_ADDRESS) {
1680           //  printf("\n0x%8.8x: %30s: address = 0x%8.8x  [0x%8.8x - 0x%8.8x) ",
1681           //  m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
1682           if ((lo_pc <= address) && (address < hi_pc)) {
1683             found_address = true;
1684             //  puts("***MATCH***");
1685             switch (m_tag) {
1686             case DW_TAG_compile_unit: // File
1687             case DW_TAG_partial_unit: // File
1688               check_children = ((function_die != NULL) || (block_die != NULL));
1689               break;
1690 
1691             case DW_TAG_subprogram: // Function
1692               if (function_die)
1693                 *function_die = this;
1694               check_children = (block_die != NULL);
1695               break;
1696 
1697             case DW_TAG_inlined_subroutine: // Inlined Function
1698             case DW_TAG_lexical_block:      // Block { } in code
1699               if (block_die) {
1700                 *block_die = this;
1701                 check_children = true;
1702               }
1703               break;
1704 
1705             default:
1706               check_children = true;
1707               break;
1708             }
1709           }
1710         } else {
1711           // Compile units may not have a valid high/low pc when there
1712           // are address gaps in subroutines so we must always search
1713           // if there is no valid high and low PC.
1714           check_children = (m_tag == DW_TAG_compile_unit ||
1715                             m_tag == DW_TAG_partial_unit) &&
1716                            ((function_die != NULL) || (block_die != NULL));
1717         }
1718       } else {
1719         dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
1720             dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
1721         if (debug_ranges_offset != DW_INVALID_OFFSET) {
1722           DWARFRangeList ranges;
1723           DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
1724           debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
1725           // All DW_AT_ranges are relative to the base address of the compile
1726           // unit. We add the compile unit base address to make sure all the
1727           // addresses are properly fixed up.
1728           ranges.Slide(cu->GetBaseAddress());
1729           if (ranges.FindEntryThatContains(address)) {
1730             found_address = true;
1731             //  puts("***MATCH***");
1732             switch (m_tag) {
1733             case DW_TAG_compile_unit: // File
1734             case DW_TAG_partial_unit: // File
1735               check_children = ((function_die != NULL) || (block_die != NULL));
1736               break;
1737 
1738             case DW_TAG_subprogram: // Function
1739               if (function_die)
1740                 *function_die = this;
1741               check_children = (block_die != NULL);
1742               break;
1743 
1744             case DW_TAG_inlined_subroutine: // Inlined Function
1745             case DW_TAG_lexical_block:      // Block { } in code
1746               if (block_die) {
1747                 *block_die = this;
1748                 check_children = true;
1749               }
1750               break;
1751 
1752             default:
1753               check_children = true;
1754               break;
1755             }
1756           } else {
1757             check_children = false;
1758           }
1759         }
1760       }
1761     }
1762 
1763     if (check_children) {
1764       //  printf("checking children\n");
1765       DWARFDebugInfoEntry *child = GetFirstChild();
1766       while (child) {
1767         if (child->LookupAddress(address, dwarf2Data, cu, function_die,
1768                                  block_die))
1769           return true;
1770         child = child->GetSibling();
1771       }
1772     }
1773   }
1774   return found_address;
1775 }
1776 
1777 const DWARFAbbreviationDeclaration *
1778 DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
1779     SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
1780     lldb::offset_t &offset) const {
1781   if (dwarf2Data) {
1782     offset = GetOffset();
1783 
1784     const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
1785     if (abbrev_set) {
1786       const DWARFAbbreviationDeclaration *abbrev_decl =
1787           abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
1788       if (abbrev_decl) {
1789         // Make sure the abbreviation code still matches. If it doesn't and the
1790         // DWARF data was mmap'ed, the backing file might have been modified
1791         // which is bad news.
1792         const uint64_t abbrev_code =
1793             dwarf2Data->get_debug_info_data().GetULEB128(&offset);
1794 
1795         if (abbrev_decl->Code() == abbrev_code)
1796           return abbrev_decl;
1797 
1798         dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
1799             "0x%8.8x: the DWARF debug information has been modified (abbrev "
1800             "code was %u, and is now %u)",
1801             GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code);
1802       }
1803     }
1804   }
1805   offset = DW_INVALID_OFFSET;
1806   return NULL;
1807 }
1808 
1809 bool DWARFDebugInfoEntry::OffsetLessThan(const DWARFDebugInfoEntry &a,
1810                                          const DWARFDebugInfoEntry &b) {
1811   return a.GetOffset() < b.GetOffset();
1812 }
1813 
1814 void DWARFDebugInfoEntry::DumpDIECollection(
1815     Stream &strm, DWARFDebugInfoEntry::collection &die_collection) {
1816   DWARFDebugInfoEntry::const_iterator pos;
1817   DWARFDebugInfoEntry::const_iterator end = die_collection.end();
1818   strm.PutCString("\noffset    parent   sibling  child\n");
1819   strm.PutCString("--------  -------- -------- --------\n");
1820   for (pos = die_collection.begin(); pos != end; ++pos) {
1821     const DWARFDebugInfoEntry &die_ref = *pos;
1822     const DWARFDebugInfoEntry *p = die_ref.GetParent();
1823     const DWARFDebugInfoEntry *s = die_ref.GetSibling();
1824     const DWARFDebugInfoEntry *c = die_ref.GetFirstChild();
1825     strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", die_ref.GetOffset(),
1826                 p ? p->GetOffset() : 0, s ? s->GetOffset() : 0,
1827                 c ? c->GetOffset() : 0, die_ref.Tag(),
1828                 DW_TAG_value_to_name(die_ref.Tag()),
1829                 die_ref.HasChildren() ? " *" : "");
1830   }
1831 }
1832