1 //===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "DWARFDebugInfoEntry.h"
10 
11 #include <assert.h>
12 
13 #include <algorithm>
14 
15 #include "llvm/Support/LEB128.h"
16 
17 #include "lldb/Core/Module.h"
18 #include "lldb/Expression/DWARFExpression.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Utility/Stream.h"
21 
22 #include "DWARFUnit.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 // Extract a debug info entry for a given compile unit from the .debug_info and
37 // .debug_abbrev data within the SymbolFileDWARF class starting at the given
38 // offset
39 bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &debug_info_data,
40                                   const DWARFUnit *cu,
41                                   lldb::offset_t *offset_ptr) {
42   m_offset = *offset_ptr;
43   m_parent_idx = 0;
44   m_sibling_idx = 0;
45   const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr);
46   lldbassert(abbr_idx <= UINT16_MAX);
47   m_abbr_idx = abbr_idx;
48 
49   // assert (fixed_form_sizes);  // For best performance this should be
50   // specified!
51 
52   if (m_abbr_idx) {
53     lldb::offset_t offset = *offset_ptr;
54 
55     const DWARFAbbreviationDeclaration *abbrevDecl =
56         cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
57 
58     if (abbrevDecl == nullptr) {
59       cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
60           "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
61           "attach the file at the start of this error message",
62           m_offset, (unsigned)abbr_idx);
63       // WE can't parse anymore if the DWARF is borked...
64       *offset_ptr = UINT32_MAX;
65       return false;
66     }
67     m_tag = abbrevDecl->Tag();
68     m_has_children = abbrevDecl->HasChildren();
69     // Skip all data in the .debug_info for the attributes
70     const uint32_t numAttributes = abbrevDecl->NumAttributes();
71     uint32_t i;
72     dw_form_t form;
73     for (i = 0; i < numAttributes; ++i) {
74       form = abbrevDecl->GetFormByIndexUnchecked(i);
75 
76       llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
77       if (fixed_skip_size)
78         offset += *fixed_skip_size;
79       else {
80         bool form_is_indirect = false;
81         do {
82           form_is_indirect = false;
83           uint32_t form_size = 0;
84           switch (form) {
85           // Blocks if inlined data that have a length field and the data bytes
86           // inlined in the .debug_info
87           case DW_FORM_exprloc:
88           case DW_FORM_block:
89             form_size = debug_info_data.GetULEB128(&offset);
90             break;
91           case DW_FORM_block1:
92             form_size = debug_info_data.GetU8_unchecked(&offset);
93             break;
94           case DW_FORM_block2:
95             form_size = debug_info_data.GetU16_unchecked(&offset);
96             break;
97           case DW_FORM_block4:
98             form_size = debug_info_data.GetU32_unchecked(&offset);
99             break;
100 
101           // Inlined NULL terminated C-strings
102           case DW_FORM_string:
103             debug_info_data.GetCStr(&offset);
104             break;
105 
106           // Compile unit address sized values
107           case DW_FORM_addr:
108             form_size = cu->GetAddressByteSize();
109             break;
110           case DW_FORM_ref_addr:
111             if (cu->GetVersion() <= 2)
112               form_size = cu->GetAddressByteSize();
113             else
114               form_size = 4;
115             break;
116 
117           // 0 sized form
118           case DW_FORM_flag_present:
119             form_size = 0;
120             break;
121 
122           // 1 byte values
123           case DW_FORM_addrx1:
124           case DW_FORM_data1:
125           case DW_FORM_flag:
126           case DW_FORM_ref1:
127           case DW_FORM_strx1:
128             form_size = 1;
129             break;
130 
131           // 2 byte values
132           case DW_FORM_addrx2:
133           case DW_FORM_data2:
134           case DW_FORM_ref2:
135           case DW_FORM_strx2:
136             form_size = 2;
137             break;
138 
139           // 3 byte values
140           case DW_FORM_addrx3:
141           case DW_FORM_strx3:
142             form_size = 3;
143             break;
144 
145           // 4 byte values
146           case DW_FORM_addrx4:
147           case DW_FORM_data4:
148           case DW_FORM_ref4:
149           case DW_FORM_strx4:
150             form_size = 4;
151             break;
152 
153           // 8 byte values
154           case DW_FORM_data8:
155           case DW_FORM_ref8:
156           case DW_FORM_ref_sig8:
157             form_size = 8;
158             break;
159 
160           // signed or unsigned LEB 128 values
161           case DW_FORM_addrx:
162           case DW_FORM_rnglistx:
163           case DW_FORM_sdata:
164           case DW_FORM_udata:
165           case DW_FORM_ref_udata:
166           case DW_FORM_GNU_addr_index:
167           case DW_FORM_GNU_str_index:
168           case DW_FORM_strx:
169             debug_info_data.Skip_LEB128(&offset);
170             break;
171 
172           case DW_FORM_indirect:
173             form_is_indirect = true;
174             form = debug_info_data.GetULEB128(&offset);
175             break;
176 
177           case DW_FORM_strp:
178           case DW_FORM_sec_offset:
179             debug_info_data.GetU32(&offset);
180             break;
181 
182           case DW_FORM_implicit_const:
183             form_size = 0;
184             break;
185 
186           default:
187             *offset_ptr = m_offset;
188             return false;
189           }
190           offset += form_size;
191 
192         } while (form_is_indirect);
193       }
194     }
195     *offset_ptr = offset;
196     return true;
197   } else {
198     m_tag = 0;
199     m_has_children = false;
200     return true; // NULL debug tag entry
201   }
202 
203   return false;
204 }
205 
206 static DWARFRangeList GetRangesOrReportError(const DWARFUnit &unit,
207                                              const DWARFDebugInfoEntry &die,
208                                              const DWARFFormValue &value) {
209   llvm::Expected<DWARFRangeList> expected_ranges =
210       (value.Form() == DW_FORM_rnglistx)
211           ? unit.FindRnglistFromIndex(value.Unsigned())
212           : unit.FindRnglistFromOffset(value.Unsigned());
213   if (expected_ranges)
214     return std::move(*expected_ranges);
215   unit.GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
216       "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but "
217       "range extraction failed (%s), please file a bug "
218       "and attach the file at the start of this error message",
219       die.GetOffset(), value.Unsigned(),
220       toString(expected_ranges.takeError()).c_str());
221   return DWARFRangeList();
222 }
223 
224 // GetDIENamesAndRanges
225 //
226 // Gets the valid address ranges for a given DIE by looking for a
227 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
228 bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
229     const DWARFUnit *cu, const char *&name, const char *&mangled,
230     DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
231     int &call_file, int &call_line, int &call_column,
232     DWARFExpression *frame_base) const {
233   SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
234   if (dwo_symbol_file)
235     return GetDIENamesAndRanges(
236         dwo_symbol_file->GetCompileUnit(), name, mangled, ranges, decl_file,
237         decl_line, decl_column, call_file, call_line, call_column, frame_base);
238 
239   dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
240   dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
241   std::vector<DIERef> die_refs;
242   bool set_frame_base_loclist_addr = false;
243 
244   auto abbrevDecl = GetAbbreviationDeclarationPtr(cu);
245 
246   SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF();
247   lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
248 
249   if (abbrevDecl) {
250     const DWARFDataExtractor &debug_info_data = cu->GetData();
251     lldb::offset_t offset = GetFirstAttributeOffset();
252 
253     if (!debug_info_data.ValidOffset(offset))
254       return false;
255 
256     const uint32_t numAttributes = abbrevDecl->NumAttributes();
257     bool do_offset = false;
258 
259     for (uint32_t i = 0; i < numAttributes; ++i) {
260       DWARFFormValue form_value(cu);
261       dw_attr_t attr;
262       abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
263 
264       if (form_value.ExtractValue(debug_info_data, &offset)) {
265         switch (attr) {
266         case DW_AT_low_pc:
267           lo_pc = form_value.Address();
268 
269           if (do_offset)
270             hi_pc += lo_pc;
271           do_offset = false;
272           break;
273 
274         case DW_AT_entry_pc:
275           lo_pc = form_value.Address();
276           break;
277 
278         case DW_AT_high_pc:
279           if (form_value.Form() == DW_FORM_addr ||
280               form_value.Form() == DW_FORM_addrx ||
281               form_value.Form() == DW_FORM_GNU_addr_index) {
282             hi_pc = form_value.Address();
283           } else {
284             hi_pc = form_value.Unsigned();
285             if (lo_pc == LLDB_INVALID_ADDRESS)
286               do_offset = hi_pc != LLDB_INVALID_ADDRESS;
287             else
288               hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
289                               // on relocations
290           }
291           break;
292 
293         case DW_AT_ranges:
294           ranges = GetRangesOrReportError(*cu, *this, form_value);
295           break;
296 
297         case DW_AT_name:
298           if (name == nullptr)
299             name = form_value.AsCString();
300           break;
301 
302         case DW_AT_MIPS_linkage_name:
303         case DW_AT_linkage_name:
304           if (mangled == nullptr)
305             mangled = form_value.AsCString();
306           break;
307 
308         case DW_AT_abstract_origin:
309           die_refs.emplace_back(form_value);
310           break;
311 
312         case DW_AT_specification:
313           die_refs.emplace_back(form_value);
314           break;
315 
316         case DW_AT_decl_file:
317           if (decl_file == 0)
318             decl_file = form_value.Unsigned();
319           break;
320 
321         case DW_AT_decl_line:
322           if (decl_line == 0)
323             decl_line = form_value.Unsigned();
324           break;
325 
326         case DW_AT_decl_column:
327           if (decl_column == 0)
328             decl_column = form_value.Unsigned();
329           break;
330 
331         case DW_AT_call_file:
332           if (call_file == 0)
333             call_file = form_value.Unsigned();
334           break;
335 
336         case DW_AT_call_line:
337           if (call_line == 0)
338             call_line = form_value.Unsigned();
339           break;
340 
341         case DW_AT_call_column:
342           if (call_column == 0)
343             call_column = form_value.Unsigned();
344           break;
345 
346         case DW_AT_frame_base:
347           if (frame_base) {
348             if (form_value.BlockData()) {
349               uint32_t block_offset =
350                   form_value.BlockData() - debug_info_data.GetDataStart();
351               uint32_t block_length = form_value.Unsigned();
352               *frame_base = DWARFExpression(module, debug_info_data, cu,
353                                             block_offset, block_length);
354             } else {
355               const DWARFDataExtractor &debug_loc_data =
356                   dwarf2Data->DebugLocData();
357               const dw_offset_t debug_loc_offset = form_value.Unsigned();
358 
359               size_t loc_list_length = DWARFExpression::LocationListSize(
360                   cu, debug_loc_data, debug_loc_offset);
361               if (loc_list_length > 0) {
362                 *frame_base =
363                     DWARFExpression(module, debug_loc_data, cu,
364                                     debug_loc_offset, loc_list_length);
365                 if (lo_pc != LLDB_INVALID_ADDRESS) {
366                   assert(lo_pc >= cu->GetBaseAddress());
367                   frame_base->SetLocationListSlide(lo_pc -
368                                                    cu->GetBaseAddress());
369                 } else {
370                   set_frame_base_loclist_addr = true;
371                 }
372               }
373             }
374           }
375           break;
376 
377         default:
378           break;
379         }
380       }
381     }
382   }
383 
384   if (ranges.IsEmpty()) {
385     if (lo_pc != LLDB_INVALID_ADDRESS) {
386       if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
387         ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
388       else
389         ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
390     }
391   }
392 
393   if (set_frame_base_loclist_addr) {
394     dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
395     assert(lowest_range_pc >= cu->GetBaseAddress());
396     frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
397   }
398 
399   if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
400     for (const DIERef &die_ref : die_refs) {
401       if (die_ref.die_offset != DW_INVALID_OFFSET) {
402         DWARFDIE die = dwarf2Data->GetDIE(die_ref);
403         if (die)
404           die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
405                                              decl_file, decl_line, decl_column,
406                                              call_file, call_line, call_column);
407       }
408     }
409   }
410   return !ranges.IsEmpty();
411 }
412 
413 // Dump
414 //
415 // Dumps a debug information entry and all of it's attributes to the specified
416 // stream.
417 void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s,
418                                uint32_t recurse_depth) const {
419   const DWARFDataExtractor &debug_info_data = cu->GetData();
420   lldb::offset_t offset = m_offset;
421 
422   if (debug_info_data.ValidOffset(offset)) {
423     dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
424 
425     s.Printf("\n0x%8.8x: ", m_offset);
426     s.Indent();
427     if (abbrCode != m_abbr_idx) {
428       s.Printf("error: DWARF has been modified\n");
429     } else if (abbrCode) {
430       const DWARFAbbreviationDeclaration *abbrevDecl =
431           cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode);
432 
433       if (abbrevDecl) {
434         s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
435         s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');
436 
437         // Dump all data in the .debug_info for the attributes
438         const uint32_t numAttributes = abbrevDecl->NumAttributes();
439         for (uint32_t i = 0; i < numAttributes; ++i) {
440           DWARFFormValue form_value(cu);
441           dw_attr_t attr;
442           abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
443 
444           DumpAttribute(cu, debug_info_data, &offset, s, attr, form_value);
445         }
446 
447         const DWARFDebugInfoEntry *child = GetFirstChild();
448         if (recurse_depth > 0 && child) {
449           s.IndentMore();
450 
451           while (child) {
452             child->Dump(cu, s, recurse_depth - 1);
453             child = child->GetSibling();
454           }
455           s.IndentLess();
456         }
457       } else
458         s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
459                  "code: %u\n",
460                  abbrCode);
461     } else {
462       s.Printf("NULL\n");
463     }
464   }
465 }
466 
467 // DumpAttribute
468 //
469 // Dumps a debug information entry attribute along with it's form. Any special
470 // display of attributes is done (disassemble location lists, show enumeration
471 // values for attributes, etc).
472 void DWARFDebugInfoEntry::DumpAttribute(
473     const DWARFUnit *cu, const DWARFDataExtractor &debug_info_data,
474     lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr,
475     DWARFFormValue &form_value) {
476   bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
477 
478   s.Printf("            ");
479   s.Indent(DW_AT_value_to_name(attr));
480 
481   if (show_form) {
482     s.Printf("[%s", DW_FORM_value_to_name(form_value.Form()));
483   }
484 
485   if (!form_value.ExtractValue(debug_info_data, offset_ptr))
486     return;
487 
488   if (show_form) {
489     if (form_value.Form() == DW_FORM_indirect) {
490       s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
491     }
492 
493     s.PutCString("] ");
494   }
495 
496   s.PutCString("( ");
497 
498   SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF();
499 
500   // Check to see if we have any special attribute formatters
501   switch (attr) {
502   case DW_AT_stmt_list:
503     s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
504     break;
505 
506   case DW_AT_language:
507     s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
508     break;
509 
510   case DW_AT_encoding:
511     s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
512     break;
513 
514   case DW_AT_frame_base:
515   case DW_AT_location:
516   case DW_AT_data_member_location: {
517     const uint8_t *blockData = form_value.BlockData();
518     if (blockData) {
519       // Location description is inlined in data in the form value
520       DWARFDataExtractor locationData(debug_info_data,
521                                       (*offset_ptr) - form_value.Unsigned(),
522                                       form_value.Unsigned());
523       DWARFExpression::PrintDWARFExpression(
524           s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
525     } else {
526       // We have a location list offset as the value that is the offset into
527       // the .debug_loc section that describes the value over it's lifetime
528       uint64_t debug_loc_offset = form_value.Unsigned();
529       if (dwarf2Data) {
530         DWARFExpression::PrintDWARFLocationList(
531             s, cu, dwarf2Data->DebugLocData(), debug_loc_offset);
532       }
533     }
534   } break;
535 
536   case DW_AT_abstract_origin:
537   case DW_AT_specification: {
538     DWARFDIE abstract_die = form_value.Reference();
539     form_value.Dump(s);
540     //  *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( ";
541     abstract_die.GetName(s);
542   } break;
543 
544   case DW_AT_type: {
545     DWARFDIE type_die = form_value.Reference();
546     s.PutCString(" ( ");
547     type_die.AppendTypeName(s);
548     s.PutCString(" )");
549   } break;
550 
551   default:
552     break;
553   }
554 
555   s.PutCString(" )\n");
556 }
557 
558 // Get all attribute values for a given DIE, including following any
559 // specification or abstract origin attributes and including those in the
560 // results. Any duplicate attributes will have the first instance take
561 // precedence (this can happen for declaration attributes).
562 size_t DWARFDebugInfoEntry::GetAttributes(
563     const DWARFUnit *cu, DWARFAttributes &attributes,
564     uint32_t curr_depth) const {
565   auto abbrevDecl = GetAbbreviationDeclarationPtr(cu);
566   if (abbrevDecl) {
567     const DWARFDataExtractor &debug_info_data = cu->GetData();
568     lldb::offset_t offset = GetFirstAttributeOffset();
569 
570     const uint32_t num_attributes = abbrevDecl->NumAttributes();
571     for (uint32_t i = 0; i < num_attributes; ++i) {
572       DWARFFormValue form_value(cu);
573       dw_attr_t attr;
574       abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
575       const dw_form_t form = form_value.Form();
576 
577       // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
578       // attributes, the depth will be non-zero. We need to omit certain
579       // attributes that don't make sense.
580       switch (attr) {
581       case DW_AT_sibling:
582       case DW_AT_declaration:
583         if (curr_depth > 0) {
584           // This attribute doesn't make sense when combined with the DIE that
585           // references this DIE. We know a DIE is referencing this DIE because
586           // curr_depth is not zero
587           break;
588         }
589         LLVM_FALLTHROUGH;
590       default:
591         attributes.Append(cu, offset, attr, form);
592         break;
593       }
594 
595       if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
596         if (form_value.ExtractValue(debug_info_data, &offset)) {
597           DWARFDIE spec_die = form_value.Reference();
598           if (spec_die)
599             spec_die.GetAttributes(attributes, curr_depth + 1);
600         }
601       } else {
602         llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
603         if (fixed_skip_size)
604           offset += *fixed_skip_size;
605         else
606           DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
607       }
608     }
609   } else {
610     attributes.Clear();
611   }
612   return attributes.Size();
613 }
614 
615 // GetAttributeValue
616 //
617 // Get the value of an attribute and return the .debug_info offset of the
618 // attribute if it was properly extracted into form_value, or zero if we fail
619 // since an offset of zero is invalid for an attribute (it would be a compile
620 // unit header).
621 dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
622     const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &form_value,
623     dw_offset_t *end_attr_offset_ptr,
624     bool check_specification_or_abstract_origin) const {
625   SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
626   if (dwo_symbol_file && m_tag != DW_TAG_compile_unit &&
627                          m_tag != DW_TAG_partial_unit)
628     return GetAttributeValue(dwo_symbol_file->GetCompileUnit(), attr,
629                              form_value, end_attr_offset_ptr,
630                              check_specification_or_abstract_origin);
631 
632   auto abbrevDecl = GetAbbreviationDeclarationPtr(cu);
633 
634   if (abbrevDecl) {
635     uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
636 
637     if (attr_idx != DW_INVALID_INDEX) {
638       const DWARFDataExtractor &debug_info_data = cu->GetData();
639       lldb::offset_t offset = GetFirstAttributeOffset();
640 
641       uint32_t idx = 0;
642       while (idx < attr_idx)
643         DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
644                                   debug_info_data, &offset, cu);
645 
646       const dw_offset_t attr_offset = offset;
647       form_value.SetUnit(cu);
648       form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
649       if (form_value.ExtractValue(debug_info_data, &offset)) {
650         if (end_attr_offset_ptr)
651           *end_attr_offset_ptr = offset;
652         return attr_offset;
653       }
654     }
655   }
656 
657   if (check_specification_or_abstract_origin) {
658     if (GetAttributeValue(cu, DW_AT_specification, form_value)) {
659       DWARFDIE die = form_value.Reference();
660       if (die) {
661         dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
662             die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
663         if (die_offset)
664           return die_offset;
665       }
666     }
667 
668     if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) {
669       DWARFDIE die = form_value.Reference();
670       if (die) {
671         dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
672             die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
673         if (die_offset)
674           return die_offset;
675       }
676     }
677   }
678 
679   if (!dwo_symbol_file)
680     return 0;
681 
682   DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
683   if (!dwo_cu)
684     return 0;
685 
686   DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
687   if (!dwo_cu_die.IsValid())
688     return 0;
689 
690   return dwo_cu_die.GetDIE()->GetAttributeValue(
691       dwo_cu, attr, form_value, end_attr_offset_ptr,
692       check_specification_or_abstract_origin);
693 }
694 
695 // GetAttributeValueAsString
696 //
697 // Get the value of an attribute as a string return it. The resulting pointer
698 // to the string data exists within the supplied SymbolFileDWARF and will only
699 // be available as long as the SymbolFileDWARF is still around and it's content
700 // doesn't change.
701 const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
702     const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
703     bool check_specification_or_abstract_origin) const {
704   DWARFFormValue form_value;
705   if (GetAttributeValue(cu, attr, form_value, nullptr,
706                         check_specification_or_abstract_origin))
707     return form_value.AsCString();
708   return fail_value;
709 }
710 
711 // GetAttributeValueAsUnsigned
712 //
713 // Get the value of an attribute as unsigned and return it.
714 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
715     const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
716     bool check_specification_or_abstract_origin) const {
717   DWARFFormValue form_value;
718   if (GetAttributeValue(cu, attr, form_value, nullptr,
719                         check_specification_or_abstract_origin))
720     return form_value.Unsigned();
721   return fail_value;
722 }
723 
724 // GetAttributeValueAsReference
725 //
726 // Get the value of an attribute as reference and fix up and compile unit
727 // relative offsets as needed.
728 DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
729     const DWARFUnit *cu, const dw_attr_t attr,
730     bool check_specification_or_abstract_origin) const {
731   DWARFFormValue form_value;
732   if (GetAttributeValue(cu, attr, form_value, nullptr,
733                         check_specification_or_abstract_origin))
734     return form_value.Reference();
735   return {};
736 }
737 
738 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
739     const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
740     bool check_specification_or_abstract_origin) const {
741   DWARFFormValue form_value;
742   if (GetAttributeValue(cu, attr, form_value, nullptr,
743                         check_specification_or_abstract_origin))
744     return form_value.Address();
745   return fail_value;
746 }
747 
748 // GetAttributeHighPC
749 //
750 // Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
751 // pc>.
752 //
753 // Returns the hi_pc or fail_value.
754 dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
755     const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
756     bool check_specification_or_abstract_origin) const {
757   DWARFFormValue form_value;
758   if (GetAttributeValue(cu, DW_AT_high_pc, form_value, nullptr,
759                         check_specification_or_abstract_origin)) {
760     dw_form_t form = form_value.Form();
761     if (form == DW_FORM_addr || form == DW_FORM_addrx ||
762         form == DW_FORM_GNU_addr_index)
763       return form_value.Address();
764 
765     // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
766     return lo_pc + form_value.Unsigned();
767   }
768   return fail_value;
769 }
770 
771 // GetAttributeAddressRange
772 //
773 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
774 // from-low-pc>.
775 //
776 // Returns true or sets lo_pc and hi_pc to fail_value.
777 bool DWARFDebugInfoEntry::GetAttributeAddressRange(
778     const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
779     uint64_t fail_value, bool check_specification_or_abstract_origin) const {
780   lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value,
781                                      check_specification_or_abstract_origin);
782   if (lo_pc != fail_value) {
783     hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value,
784                                check_specification_or_abstract_origin);
785     if (hi_pc != fail_value)
786       return true;
787   }
788   lo_pc = fail_value;
789   hi_pc = fail_value;
790   return false;
791 }
792 
793 size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
794     const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
795     bool check_specification_or_abstract_origin) const {
796   ranges.Clear();
797 
798   DWARFFormValue form_value;
799   if (GetAttributeValue(cu, DW_AT_ranges, form_value)) {
800     ranges = GetRangesOrReportError(*cu, *this, form_value);
801   } else if (check_hi_lo_pc) {
802     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
803     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
804     if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS,
805                                  check_specification_or_abstract_origin)) {
806       if (lo_pc < hi_pc)
807         ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
808     }
809   }
810   return ranges.GetSize();
811 }
812 
813 // GetName
814 //
815 // Get value of the DW_AT_name attribute and return it if one exists, else
816 // return NULL.
817 const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const {
818   return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
819 }
820 
821 // GetMangledName
822 //
823 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
824 // exists, else return the value of the DW_AT_name attribute
825 const char *
826 DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu,
827                                     bool substitute_name_allowed) const {
828   const char *name = nullptr;
829 
830   name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
831   if (name)
832     return name;
833 
834   name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
835   if (name)
836     return name;
837 
838   if (!substitute_name_allowed)
839     return nullptr;
840 
841   name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
842   return name;
843 }
844 
845 // GetPubname
846 //
847 // Get value the name for a DIE as it should appear for a .debug_pubnames or
848 // .debug_pubtypes section.
849 const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
850   const char *name = nullptr;
851   if (!cu)
852     return name;
853 
854   name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
855   if (name)
856     return name;
857 
858   name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
859   if (name)
860     return name;
861 
862   name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
863   return name;
864 }
865 
866 // BuildAddressRangeTable
867 void DWARFDebugInfoEntry::BuildAddressRangeTable(
868     const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
869   if (m_tag) {
870     if (m_tag == DW_TAG_subprogram) {
871       dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
872       dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
873       if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
874         /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
875         /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
876         debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
877       }
878     }
879 
880     const DWARFDebugInfoEntry *child = GetFirstChild();
881     while (child) {
882       child->BuildAddressRangeTable(cu, debug_aranges);
883       child = child->GetSibling();
884     }
885   }
886 }
887 
888 // BuildFunctionAddressRangeTable
889 //
890 // This function is very similar to the BuildAddressRangeTable function except
891 // that the actual DIE offset for the function is placed in the table instead
892 // of the compile unit offset (which is the way the standard .debug_aranges
893 // section does it).
894 void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
895     const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
896   if (m_tag) {
897     if (m_tag == DW_TAG_subprogram) {
898       dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
899       dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
900       if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
901         //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
902         //  0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
903         debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
904       }
905     }
906 
907     const DWARFDebugInfoEntry *child = GetFirstChild();
908     while (child) {
909       child->BuildFunctionAddressRangeTable(cu, debug_aranges);
910       child = child->GetSibling();
911     }
912   }
913 }
914 
915 void DWARFDebugInfoEntry::GetDWARFDeclContext(
916     DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const {
917   const dw_tag_t tag = Tag();
918   if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) {
919     dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu));
920     DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
921     if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
922       if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit &&
923           parent_decl_ctx_die.Tag() != DW_TAG_partial_unit)
924         parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
925             parent_decl_ctx_die.GetCU(), dwarf_decl_ctx);
926     }
927   }
928 }
929 
930 DWARFDIE
931 DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
932   DWARFAttributes attributes;
933   GetAttributes(cu, attributes);
934   return GetParentDeclContextDIE(cu, attributes);
935 }
936 
937 DWARFDIE
938 DWARFDebugInfoEntry::GetParentDeclContextDIE(
939     DWARFUnit *cu, const DWARFAttributes &attributes) const {
940   DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
941 
942   while (die) {
943     // If this is the original DIE that we are searching for a declaration for,
944     // then don't look in the cache as we don't want our own decl context to be
945     // our decl context...
946     if (die.GetDIE() != this) {
947       switch (die.Tag()) {
948       case DW_TAG_compile_unit:
949       case DW_TAG_partial_unit:
950       case DW_TAG_namespace:
951       case DW_TAG_structure_type:
952       case DW_TAG_union_type:
953       case DW_TAG_class_type:
954         return die;
955 
956       default:
957         break;
958       }
959     }
960 
961     DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
962     if (spec_die) {
963       DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
964       if (decl_ctx_die)
965         return decl_ctx_die;
966     }
967 
968     DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
969     if (abs_die) {
970       DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
971       if (decl_ctx_die)
972         return decl_ctx_die;
973     }
974 
975     die = die.GetParent();
976   }
977   return DWARFDIE();
978 }
979 
980 const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
981                                                   std::string &storage) const {
982   DWARFAttributes attributes;
983   GetAttributes(cu, attributes);
984   return GetQualifiedName(cu, attributes, storage);
985 }
986 
987 const char *
988 DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
989                                       const DWARFAttributes &attributes,
990                                       std::string &storage) const {
991 
992   const char *name = GetName(cu);
993 
994   if (name) {
995     DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
996     storage.clear();
997     // TODO: change this to get the correct decl context parent....
998     while (parent_decl_ctx_die) {
999       const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
1000       switch (parent_tag) {
1001       case DW_TAG_namespace: {
1002         const char *namespace_name = parent_decl_ctx_die.GetName();
1003         if (namespace_name) {
1004           storage.insert(0, "::");
1005           storage.insert(0, namespace_name);
1006         } else {
1007           storage.insert(0, "(anonymous namespace)::");
1008         }
1009         parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1010       } break;
1011 
1012       case DW_TAG_class_type:
1013       case DW_TAG_structure_type:
1014       case DW_TAG_union_type: {
1015         const char *class_union_struct_name = parent_decl_ctx_die.GetName();
1016 
1017         if (class_union_struct_name) {
1018           storage.insert(0, "::");
1019           storage.insert(0, class_union_struct_name);
1020         }
1021         parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1022       } break;
1023 
1024       default:
1025         parent_decl_ctx_die.Clear();
1026         break;
1027       }
1028     }
1029 
1030     if (storage.empty())
1031       storage.append("::");
1032 
1033     storage.append(name);
1034   }
1035   if (storage.empty())
1036     return nullptr;
1037   return storage.c_str();
1038 }
1039 
1040 bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
1041                                         const DWARFUnit *cu,
1042                                         DWARFDebugInfoEntry **function_die,
1043                                         DWARFDebugInfoEntry **block_die) {
1044   bool found_address = false;
1045   if (m_tag) {
1046     bool check_children = false;
1047     bool match_addr_range = false;
1048     //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
1049     //  DW_TAG_value_to_name(tag), address);
1050     switch (m_tag) {
1051     case DW_TAG_array_type:
1052       break;
1053     case DW_TAG_class_type:
1054       check_children = true;
1055       break;
1056     case DW_TAG_entry_point:
1057     case DW_TAG_enumeration_type:
1058     case DW_TAG_formal_parameter:
1059     case DW_TAG_imported_declaration:
1060     case DW_TAG_label:
1061       break;
1062     case DW_TAG_lexical_block:
1063       check_children = true;
1064       match_addr_range = true;
1065       break;
1066     case DW_TAG_member:
1067     case DW_TAG_pointer_type:
1068     case DW_TAG_reference_type:
1069       break;
1070     case DW_TAG_compile_unit:
1071       match_addr_range = true;
1072       break;
1073     case DW_TAG_string_type:
1074       break;
1075     case DW_TAG_structure_type:
1076       check_children = true;
1077       break;
1078     case DW_TAG_subroutine_type:
1079     case DW_TAG_typedef:
1080     case DW_TAG_union_type:
1081     case DW_TAG_unspecified_parameters:
1082     case DW_TAG_variant:
1083       break;
1084     case DW_TAG_common_block:
1085       check_children = true;
1086       break;
1087     case DW_TAG_common_inclusion:
1088     case DW_TAG_inheritance:
1089       break;
1090     case DW_TAG_inlined_subroutine:
1091       check_children = true;
1092       match_addr_range = true;
1093       break;
1094     case DW_TAG_module:
1095       match_addr_range = true;
1096       break;
1097     case DW_TAG_ptr_to_member_type:
1098     case DW_TAG_set_type:
1099     case DW_TAG_subrange_type:
1100     case DW_TAG_with_stmt:
1101     case DW_TAG_access_declaration:
1102     case DW_TAG_base_type:
1103       break;
1104     case DW_TAG_catch_block:
1105       match_addr_range = true;
1106       break;
1107     case DW_TAG_const_type:
1108     case DW_TAG_constant:
1109     case DW_TAG_enumerator:
1110     case DW_TAG_file_type:
1111     case DW_TAG_friend:
1112     case DW_TAG_namelist:
1113     case DW_TAG_namelist_item:
1114     case DW_TAG_packed_type:
1115       break;
1116     case DW_TAG_subprogram:
1117       match_addr_range = true;
1118       break;
1119     case DW_TAG_template_type_parameter:
1120     case DW_TAG_template_value_parameter:
1121     case DW_TAG_GNU_template_parameter_pack:
1122     case DW_TAG_thrown_type:
1123       break;
1124     case DW_TAG_try_block:
1125       match_addr_range = true;
1126       break;
1127     case DW_TAG_variant_part:
1128     case DW_TAG_variable:
1129     case DW_TAG_volatile_type:
1130     case DW_TAG_dwarf_procedure:
1131     case DW_TAG_restrict_type:
1132     case DW_TAG_interface_type:
1133       break;
1134     case DW_TAG_namespace:
1135       check_children = true;
1136       break;
1137     case DW_TAG_imported_module:
1138     case DW_TAG_unspecified_type:
1139       break;
1140     case DW_TAG_partial_unit:
1141       match_addr_range = true;
1142       break;
1143     case DW_TAG_imported_unit:
1144     case DW_TAG_shared_type:
1145     default:
1146       break;
1147     }
1148 
1149     if (match_addr_range) {
1150       dw_addr_t lo_pc =
1151           GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
1152       if (lo_pc != LLDB_INVALID_ADDRESS) {
1153         dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS);
1154         if (hi_pc != LLDB_INVALID_ADDRESS) {
1155           //  printf("\n0x%8.8x: %30s: address = 0x%8.8x  [0x%8.8x - 0x%8.8x) ",
1156           //  m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
1157           if ((lo_pc <= address) && (address < hi_pc)) {
1158             found_address = true;
1159             //  puts("***MATCH***");
1160             switch (m_tag) {
1161             case DW_TAG_compile_unit: // File
1162             case DW_TAG_partial_unit: // File
1163               check_children =
1164                   ((function_die != nullptr) || (block_die != nullptr));
1165               break;
1166 
1167             case DW_TAG_subprogram: // Function
1168               if (function_die)
1169                 *function_die = this;
1170               check_children = (block_die != nullptr);
1171               break;
1172 
1173             case DW_TAG_inlined_subroutine: // Inlined Function
1174             case DW_TAG_lexical_block:      // Block { } in code
1175               if (block_die) {
1176                 *block_die = this;
1177                 check_children = true;
1178               }
1179               break;
1180 
1181             default:
1182               check_children = true;
1183               break;
1184             }
1185           }
1186         } else {
1187           // Compile units may not have a valid high/low pc when there
1188           // are address gaps in subroutines so we must always search
1189           // if there is no valid high and low PC.
1190           check_children =
1191               (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) &&
1192               ((function_die != nullptr) || (block_die != nullptr));
1193         }
1194       } else {
1195         DWARFRangeList ranges;
1196         if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) &&
1197             ranges.FindEntryThatContains(address)) {
1198           found_address = true;
1199           //  puts("***MATCH***");
1200           switch (m_tag) {
1201           case DW_TAG_compile_unit: // File
1202           case DW_TAG_partial_unit: // File
1203               check_children =
1204                   ((function_die != nullptr) || (block_die != nullptr));
1205               break;
1206 
1207           case DW_TAG_subprogram: // Function
1208             if (function_die)
1209               *function_die = this;
1210             check_children = (block_die != nullptr);
1211             break;
1212 
1213           case DW_TAG_inlined_subroutine: // Inlined Function
1214           case DW_TAG_lexical_block:      // Block { } in code
1215             if (block_die) {
1216               *block_die = this;
1217               check_children = true;
1218             }
1219             break;
1220 
1221           default:
1222             check_children = true;
1223             break;
1224           }
1225         } else {
1226           check_children = false;
1227         }
1228       }
1229     }
1230 
1231     if (check_children) {
1232       //  printf("checking children\n");
1233       DWARFDebugInfoEntry *child = GetFirstChild();
1234       while (child) {
1235         if (child->LookupAddress(address, cu, function_die, block_die))
1236           return true;
1237         child = child->GetSibling();
1238       }
1239     }
1240   }
1241   return found_address;
1242 }
1243 
1244 lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
1245   return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
1246 }
1247 
1248 const DWARFAbbreviationDeclaration *
1249 DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
1250   if (cu) {
1251     const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
1252     if (abbrev_set)
1253       return abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
1254   }
1255   return nullptr;
1256 }
1257 
1258 bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const {
1259   return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
1260          m_sibling_idx == rhs.m_sibling_idx &&
1261          m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children &&
1262          m_tag == rhs.m_tag;
1263 }
1264 
1265 bool DWARFDebugInfoEntry::operator!=(const DWARFDebugInfoEntry &rhs) const {
1266   return !(*this == rhs);
1267 }
1268