1 //===-- DWARFDebugInfoEntry.cpp -------------------------------------------===//
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 <cassert>
12 
13 #include <algorithm>
14 #include <optional>
15 
16 #include "llvm/Support/LEB128.h"
17 
18 #include "lldb/Core/Module.h"
19 #include "lldb/Expression/DWARFExpression.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Utility/Stream.h"
22 #include "lldb/Utility/StreamString.h"
23 
24 #include "DWARFCompileUnit.h"
25 #include "DWARFDebugAbbrev.h"
26 #include "DWARFDebugAranges.h"
27 #include "DWARFDebugInfo.h"
28 #include "DWARFDebugRanges.h"
29 #include "DWARFDeclContext.h"
30 #include "DWARFFormValue.h"
31 #include "DWARFUnit.h"
32 #include "SymbolFileDWARF.h"
33 #include "SymbolFileDWARFDwo.h"
34 
35 using namespace lldb_private;
36 using namespace lldb_private::dwarf;
37 extern int g_verbose;
38 
39 // Extract a debug info entry for a given DWARFUnit from the data
40 // starting at the offset in offset_ptr
41 bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
42                                   const DWARFUnit *cu,
43                                   lldb::offset_t *offset_ptr) {
44   m_offset = *offset_ptr;
45   m_parent_idx = 0;
46   m_sibling_idx = 0;
47   const uint64_t abbr_idx = data.GetULEB128(offset_ptr);
48   lldbassert(abbr_idx <= UINT16_MAX);
49   m_abbr_idx = abbr_idx;
50 
51   // assert (fixed_form_sizes);  // For best performance this should be
52   // specified!
53 
54   if (m_abbr_idx == 0) {
55     m_tag = llvm::dwarf::DW_TAG_null;
56     m_has_children = false;
57     return true; // NULL debug tag entry
58   }
59 
60   lldb::offset_t offset = *offset_ptr;
61   const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
62   if (abbrevDecl == nullptr) {
63     cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
64         "[{0:x16}]: invalid abbreviation code {1}, "
65         "please file a bug and "
66         "attach the file at the start of this error message",
67         (uint64_t)m_offset, (unsigned)abbr_idx);
68     // WE can't parse anymore if the DWARF is borked...
69     *offset_ptr = UINT32_MAX;
70     return false;
71   }
72   m_tag = abbrevDecl->getTag();
73   m_has_children = abbrevDecl->hasChildren();
74   // Skip all data in the .debug_info or .debug_types for the attributes
75   dw_form_t form;
76   for (const auto &attribute : abbrevDecl->attributes()) {
77     form = attribute.Form;
78     std::optional<uint8_t> fixed_skip_size =
79         DWARFFormValue::GetFixedSize(form, cu);
80     if (fixed_skip_size)
81       offset += *fixed_skip_size;
82     else {
83       bool form_is_indirect = false;
84       do {
85         form_is_indirect = false;
86         uint32_t form_size = 0;
87         switch (form) {
88         // Blocks if inlined data that have a length field and the data bytes
89         // inlined in the .debug_info/.debug_types
90         case DW_FORM_exprloc:
91         case DW_FORM_block:
92           form_size = data.GetULEB128(&offset);
93           break;
94         case DW_FORM_block1:
95           form_size = data.GetU8_unchecked(&offset);
96           break;
97         case DW_FORM_block2:
98           form_size = data.GetU16_unchecked(&offset);
99           break;
100         case DW_FORM_block4:
101           form_size = data.GetU32_unchecked(&offset);
102           break;
103 
104         // Inlined NULL terminated C-strings
105         case DW_FORM_string:
106           data.GetCStr(&offset);
107           break;
108 
109         // Compile unit address sized values
110         case DW_FORM_addr:
111           form_size = cu->GetAddressByteSize();
112           break;
113         case DW_FORM_ref_addr:
114           if (cu->GetVersion() <= 2)
115             form_size = cu->GetAddressByteSize();
116           else
117             form_size = 4;
118           break;
119 
120         // 0 sized form
121         case DW_FORM_flag_present:
122           form_size = 0;
123           break;
124 
125         // 1 byte values
126         case DW_FORM_addrx1:
127         case DW_FORM_data1:
128         case DW_FORM_flag:
129         case DW_FORM_ref1:
130         case DW_FORM_strx1:
131           form_size = 1;
132           break;
133 
134         // 2 byte values
135         case DW_FORM_addrx2:
136         case DW_FORM_data2:
137         case DW_FORM_ref2:
138         case DW_FORM_strx2:
139           form_size = 2;
140           break;
141 
142         // 3 byte values
143         case DW_FORM_addrx3:
144         case DW_FORM_strx3:
145           form_size = 3;
146           break;
147 
148         // 4 byte values
149         case DW_FORM_addrx4:
150         case DW_FORM_data4:
151         case DW_FORM_ref4:
152         case DW_FORM_strx4:
153           form_size = 4;
154           break;
155 
156         // 8 byte values
157         case DW_FORM_data8:
158         case DW_FORM_ref8:
159         case DW_FORM_ref_sig8:
160           form_size = 8;
161           break;
162 
163         // signed or unsigned LEB 128 values
164         case DW_FORM_addrx:
165         case DW_FORM_loclistx:
166         case DW_FORM_rnglistx:
167         case DW_FORM_sdata:
168         case DW_FORM_udata:
169         case DW_FORM_ref_udata:
170         case DW_FORM_GNU_addr_index:
171         case DW_FORM_GNU_str_index:
172         case DW_FORM_strx:
173           data.Skip_LEB128(&offset);
174           break;
175 
176         case DW_FORM_indirect:
177           form_is_indirect = true;
178           form = static_cast<dw_form_t>(data.GetULEB128(&offset));
179           break;
180 
181         case DW_FORM_strp:
182         case DW_FORM_line_strp:
183         case DW_FORM_sec_offset:
184           data.GetU32(&offset);
185           break;
186 
187         case DW_FORM_implicit_const:
188           form_size = 0;
189           break;
190 
191         default:
192           cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
193               "[{0:x16}]: Unsupported DW_FORM_{1:x}, please file a bug "
194               "and "
195               "attach the file at the start of this error message",
196               (uint64_t)m_offset, (unsigned)form);
197           *offset_ptr = m_offset;
198           return false;
199         }
200         offset += form_size;
201 
202       } while (form_is_indirect);
203     }
204   }
205   *offset_ptr = offset;
206   return true;
207 }
208 
209 static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit,
210                                              const DWARFDebugInfoEntry &die,
211                                              const DWARFFormValue &value) {
212   llvm::Expected<DWARFRangeList> expected_ranges =
213       (value.Form() == DW_FORM_rnglistx)
214           ? unit.FindRnglistFromIndex(value.Unsigned())
215           : unit.FindRnglistFromOffset(value.Unsigned());
216   if (expected_ranges)
217     return std::move(*expected_ranges);
218 
219   unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
220       "[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
221       "range extraction failed ({3}), please file a bug "
222       "and attach the file at the start of this error message",
223       die.GetOffset(),
224       llvm::dwarf::FormEncodingString(value.Form()).str().c_str(),
225       value.Unsigned(), toString(expected_ranges.takeError()).c_str());
226   return DWARFRangeList();
227 }
228 
229 static void ExtractAttrAndFormValue(
230     const llvm::DWARFAbbreviationDeclaration::AttributeSpec &attr_spec,
231     dw_attr_t &attr, DWARFFormValue &form_value) {
232   attr = attr_spec.Attr;
233   form_value.FormRef() = attr_spec.Form;
234   if (attr_spec.isImplicitConst())
235     form_value.SetSigned(attr_spec.getImplicitConstValue());
236 }
237 
238 // GetDIENamesAndRanges
239 //
240 // Gets the valid address ranges for a given DIE by looking for a
241 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
242 bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
243     DWARFUnit *cu, const char *&name, const char *&mangled,
244     DWARFRangeList &ranges, std::optional<int> &decl_file,
245     std::optional<int> &decl_line, std::optional<int> &decl_column,
246     std::optional<int> &call_file, std::optional<int> &call_line,
247     std::optional<int> &call_column, DWARFExpressionList *frame_base) const {
248   dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
249   dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
250   std::vector<DWARFDIE> dies;
251   bool set_frame_base_loclist_addr = false;
252 
253   SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF();
254   lldb::ModuleSP module = dwarf.GetObjectFile()->GetModule();
255 
256   if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) {
257     const DWARFDataExtractor &data = cu->GetData();
258     lldb::offset_t offset = GetFirstAttributeOffset();
259 
260     if (!data.ValidOffset(offset))
261       return false;
262 
263     bool do_offset = false;
264 
265     for (const auto &attribute : abbrevDecl->attributes()) {
266       DWARFFormValue form_value(cu);
267       dw_attr_t attr;
268       ExtractAttrAndFormValue(attribute, attr, form_value);
269 
270       if (form_value.ExtractValue(data, &offset)) {
271         switch (attr) {
272         case DW_AT_low_pc:
273           lo_pc = form_value.Address();
274 
275           if (do_offset)
276             hi_pc += lo_pc;
277           do_offset = false;
278           break;
279 
280         case DW_AT_entry_pc:
281           lo_pc = form_value.Address();
282           break;
283 
284         case DW_AT_high_pc:
285           if (form_value.Form() == DW_FORM_addr ||
286               form_value.Form() == DW_FORM_addrx ||
287               form_value.Form() == DW_FORM_GNU_addr_index) {
288             hi_pc = form_value.Address();
289           } else {
290             hi_pc = form_value.Unsigned();
291             if (lo_pc == LLDB_INVALID_ADDRESS)
292               do_offset = hi_pc != LLDB_INVALID_ADDRESS;
293             else
294               hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
295                               // on relocations
296           }
297           break;
298 
299         case DW_AT_ranges:
300           ranges = GetRangesOrReportError(*cu, *this, form_value);
301           break;
302 
303         case DW_AT_name:
304           if (name == nullptr)
305             name = form_value.AsCString();
306           break;
307 
308         case DW_AT_MIPS_linkage_name:
309         case DW_AT_linkage_name:
310           if (mangled == nullptr)
311             mangled = form_value.AsCString();
312           break;
313 
314         case DW_AT_abstract_origin:
315           dies.push_back(form_value.Reference());
316           break;
317 
318         case DW_AT_specification:
319           dies.push_back(form_value.Reference());
320           break;
321 
322         case DW_AT_decl_file:
323           if (!decl_file)
324             decl_file = form_value.Unsigned();
325           break;
326 
327         case DW_AT_decl_line:
328           if (!decl_line)
329             decl_line = form_value.Unsigned();
330           break;
331 
332         case DW_AT_decl_column:
333           if (!decl_column)
334             decl_column = form_value.Unsigned();
335           break;
336 
337         case DW_AT_call_file:
338           if (!call_file)
339             call_file = form_value.Unsigned();
340           break;
341 
342         case DW_AT_call_line:
343           if (!call_line)
344             call_line = form_value.Unsigned();
345           break;
346 
347         case DW_AT_call_column:
348           if (!call_column)
349             call_column = form_value.Unsigned();
350           break;
351 
352         case DW_AT_frame_base:
353           if (frame_base) {
354             if (form_value.BlockData()) {
355               uint32_t block_offset =
356                   form_value.BlockData() - data.GetDataStart();
357               uint32_t block_length = form_value.Unsigned();
358               *frame_base =
359                   DWARFExpressionList(module,
360                                       DWARFExpression(DataExtractor(
361                                           data, block_offset, block_length)),
362                                       cu);
363             } else {
364               DataExtractor data = cu->GetLocationData();
365               const dw_offset_t offset = form_value.Unsigned();
366               if (data.ValidOffset(offset)) {
367                 data = DataExtractor(data, offset, data.GetByteSize() - offset);
368                 if (lo_pc != LLDB_INVALID_ADDRESS) {
369                   assert(lo_pc >= cu->GetBaseAddress());
370                   DWARFExpression::ParseDWARFLocationList(cu, data, frame_base);
371                   frame_base->SetFuncFileAddress(lo_pc);
372                 } else
373                   set_frame_base_loclist_addr = true;
374               }
375             }
376           }
377           break;
378 
379         default:
380           break;
381         }
382       }
383     }
384   }
385 
386   if (ranges.IsEmpty()) {
387     if (lo_pc != LLDB_INVALID_ADDRESS) {
388       if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
389         ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
390       else
391         ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
392     }
393   }
394 
395   if (set_frame_base_loclist_addr) {
396     dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
397     assert(lowest_range_pc >= cu->GetBaseAddress());
398     frame_base->SetFuncFileAddress(lowest_range_pc);
399   }
400 
401   if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
402     for (const DWARFDIE &die : dies) {
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 // Get all attribute values for a given DIE, including following any
414 // specification or abstract origin attributes and including those in the
415 // results. Any duplicate attributes will have the first instance take
416 // precedence (this can happen for declaration attributes).
417 void DWARFDebugInfoEntry::GetAttributes(DWARFUnit *cu,
418                                         DWARFAttributes &attributes,
419                                         Recurse recurse,
420                                         uint32_t curr_depth) const {
421   const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
422   if (!abbrevDecl) {
423     attributes.Clear();
424     return;
425   }
426 
427   const DWARFDataExtractor &data = cu->GetData();
428   lldb::offset_t offset = GetFirstAttributeOffset();
429 
430   for (const auto &attribute : abbrevDecl->attributes()) {
431     DWARFFormValue form_value(cu);
432     dw_attr_t attr;
433     ExtractAttrAndFormValue(attribute, attr, form_value);
434 
435     // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
436     // attributes, the depth will be non-zero. We need to omit certain
437     // attributes that don't make sense.
438     switch (attr) {
439     case DW_AT_sibling:
440     case DW_AT_declaration:
441       if (curr_depth > 0) {
442         // This attribute doesn't make sense when combined with the DIE that
443         // references this DIE. We know a DIE is referencing this DIE because
444         // curr_depth is not zero
445         break;
446       }
447       [[fallthrough]];
448     default:
449       attributes.Append(form_value, offset, attr);
450       break;
451     }
452 
453     if (recurse == Recurse::yes &&
454         ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) {
455       if (form_value.ExtractValue(data, &offset)) {
456         DWARFDIE spec_die = form_value.Reference();
457         if (spec_die)
458           spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes,
459                                            recurse, curr_depth + 1);
460       }
461     } else {
462       const dw_form_t form = form_value.Form();
463       std::optional<uint8_t> fixed_skip_size =
464           DWARFFormValue::GetFixedSize(form, cu);
465       if (fixed_skip_size)
466         offset += *fixed_skip_size;
467       else
468         DWARFFormValue::SkipValue(form, data, &offset, cu);
469     }
470   }
471 }
472 
473 // GetAttributeValue
474 //
475 // Get the value of an attribute and return the .debug_info or .debug_types
476 // offset of the attribute if it was properly extracted into form_value,
477 // or zero if we fail since an offset of zero is invalid for an attribute (it
478 // would be a compile unit header).
479 dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
480     const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &form_value,
481     dw_offset_t *end_attr_offset_ptr,
482     bool check_specification_or_abstract_origin) const {
483   if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) {
484     std::optional<uint32_t> attr_idx = abbrevDecl->findAttributeIndex(attr);
485 
486     if (attr_idx) {
487       const DWARFDataExtractor &data = cu->GetData();
488       lldb::offset_t offset = GetFirstAttributeOffset();
489 
490       uint32_t idx = 0;
491       while (idx < *attr_idx)
492         DWARFFormValue::SkipValue(abbrevDecl->getFormByIndex(idx++), data,
493                                   &offset, cu);
494 
495       const dw_offset_t attr_offset = offset;
496       form_value.SetUnit(cu);
497       form_value.SetForm(abbrevDecl->getFormByIndex(idx));
498       if (form_value.ExtractValue(data, &offset)) {
499         if (end_attr_offset_ptr)
500           *end_attr_offset_ptr = offset;
501         return attr_offset;
502       }
503     }
504   }
505 
506   if (check_specification_or_abstract_origin) {
507     if (GetAttributeValue(cu, DW_AT_specification, form_value)) {
508       DWARFDIE die = form_value.Reference();
509       if (die) {
510         dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
511             die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
512         if (die_offset)
513           return die_offset;
514       }
515     }
516 
517     if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) {
518       DWARFDIE die = form_value.Reference();
519       if (die) {
520         dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
521             die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
522         if (die_offset)
523           return die_offset;
524       }
525     }
526   }
527   return 0;
528 }
529 
530 // GetAttributeValueAsString
531 //
532 // Get the value of an attribute as a string return it. The resulting pointer
533 // to the string data exists within the supplied SymbolFileDWARF and will only
534 // be available as long as the SymbolFileDWARF is still around and it's content
535 // doesn't change.
536 const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
537     const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value,
538     bool check_specification_or_abstract_origin) const {
539   DWARFFormValue form_value;
540   if (GetAttributeValue(cu, attr, form_value, nullptr,
541                         check_specification_or_abstract_origin))
542     return form_value.AsCString();
543   return fail_value;
544 }
545 
546 // GetAttributeValueAsUnsigned
547 //
548 // Get the value of an attribute as unsigned and return it.
549 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
550     const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
551     bool check_specification_or_abstract_origin) const {
552   DWARFFormValue form_value;
553   if (GetAttributeValue(cu, attr, form_value, nullptr,
554                         check_specification_or_abstract_origin))
555     return form_value.Unsigned();
556   return fail_value;
557 }
558 
559 std::optional<uint64_t>
560 DWARFDebugInfoEntry::GetAttributeValueAsOptionalUnsigned(
561     const DWARFUnit *cu, const dw_attr_t attr,
562     bool check_specification_or_abstract_origin) const {
563   DWARFFormValue form_value;
564   if (GetAttributeValue(cu, attr, form_value, nullptr,
565                         check_specification_or_abstract_origin))
566     return form_value.Unsigned();
567   return std::nullopt;
568 }
569 
570 // GetAttributeValueAsReference
571 //
572 // Get the value of an attribute as reference and fix up and compile unit
573 // relative offsets as needed.
574 DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
575     const DWARFUnit *cu, const dw_attr_t attr,
576     bool check_specification_or_abstract_origin) const {
577   DWARFFormValue form_value;
578   if (GetAttributeValue(cu, attr, form_value, nullptr,
579                         check_specification_or_abstract_origin))
580     return form_value.Reference();
581   return {};
582 }
583 
584 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
585     const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
586     bool check_specification_or_abstract_origin) const {
587   DWARFFormValue form_value;
588   if (GetAttributeValue(cu, attr, form_value, nullptr,
589                         check_specification_or_abstract_origin))
590     return form_value.Address();
591   return fail_value;
592 }
593 
594 // GetAttributeHighPC
595 //
596 // Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low-
597 // pc>.
598 //
599 // Returns the hi_pc or fail_value.
600 dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
601     const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value,
602     bool check_specification_or_abstract_origin) const {
603   DWARFFormValue form_value;
604   if (GetAttributeValue(cu, DW_AT_high_pc, form_value, nullptr,
605                         check_specification_or_abstract_origin)) {
606     dw_form_t form = form_value.Form();
607     if (form == DW_FORM_addr || form == DW_FORM_addrx ||
608         form == DW_FORM_GNU_addr_index)
609       return form_value.Address();
610 
611     // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
612     return lo_pc + form_value.Unsigned();
613   }
614   return fail_value;
615 }
616 
617 // GetAttributeAddressRange
618 //
619 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset-
620 // from-low-pc>.
621 //
622 // Returns true or sets lo_pc and hi_pc to fail_value.
623 bool DWARFDebugInfoEntry::GetAttributeAddressRange(
624     const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc,
625     uint64_t fail_value, bool check_specification_or_abstract_origin) const {
626   lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value,
627                                      check_specification_or_abstract_origin);
628   if (lo_pc != fail_value) {
629     hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value,
630                                check_specification_or_abstract_origin);
631     if (hi_pc != fail_value)
632       return true;
633   }
634   lo_pc = fail_value;
635   hi_pc = fail_value;
636   return false;
637 }
638 
639 DWARFRangeList DWARFDebugInfoEntry::GetAttributeAddressRanges(
640     DWARFUnit *cu, bool check_hi_lo_pc,
641     bool check_specification_or_abstract_origin) const {
642 
643   DWARFFormValue form_value;
644   if (GetAttributeValue(cu, DW_AT_ranges, form_value))
645     return GetRangesOrReportError(*cu, *this, form_value);
646 
647   DWARFRangeList ranges;
648   if (check_hi_lo_pc) {
649     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
650     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
651     if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS,
652                                  check_specification_or_abstract_origin)) {
653       if (lo_pc < hi_pc)
654         ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
655     }
656   }
657   return ranges;
658 }
659 
660 // GetName
661 //
662 // Get value of the DW_AT_name attribute and return it if one exists, else
663 // return NULL.
664 const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const {
665   return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
666 }
667 
668 // GetMangledName
669 //
670 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
671 // exists, else return the value of the DW_AT_name attribute
672 const char *
673 DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu,
674                                     bool substitute_name_allowed) const {
675   const char *name = nullptr;
676 
677   name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
678   if (name)
679     return name;
680 
681   name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
682   if (name)
683     return name;
684 
685   if (!substitute_name_allowed)
686     return nullptr;
687 
688   name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
689   return name;
690 }
691 
692 // GetPubname
693 //
694 // Get value the name for a DIE as it should appear for a .debug_pubnames or
695 // .debug_pubtypes section.
696 const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
697   const char *name = nullptr;
698   if (!cu)
699     return name;
700 
701   name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true);
702   if (name)
703     return name;
704 
705   name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true);
706   if (name)
707     return name;
708 
709   name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
710   return name;
711 }
712 
713 /// This function is builds a table very similar to the standard .debug_aranges
714 /// table, except that the actual DIE offset for the function is placed in the
715 /// table instead of the compile unit offset.
716 void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
717     DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
718   if (m_tag) {
719     if (m_tag == DW_TAG_subprogram) {
720       DWARFRangeList ranges =
721           GetAttributeAddressRanges(cu, /*check_hi_lo_pc=*/true);
722       for (const auto &r : ranges) {
723         debug_aranges->AppendRange(GetOffset(), r.GetRangeBase(),
724                                    r.GetRangeEnd());
725       }
726     }
727 
728     const DWARFDebugInfoEntry *child = GetFirstChild();
729     while (child) {
730       child->BuildFunctionAddressRangeTable(cu, debug_aranges);
731       child = child->GetSibling();
732     }
733   }
734 }
735 
736 DWARFDeclContext
737 DWARFDebugInfoEntry::GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die,
738                                                DWARFUnit *cu) {
739   DWARFDeclContext dwarf_decl_ctx;
740   for (;;) {
741     const dw_tag_t tag = die->Tag();
742     if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
743       return dwarf_decl_ctx;
744     dwarf_decl_ctx.AppendDeclContext(tag, die->GetName(cu));
745     DWARFDIE parent_decl_ctx_die = die->GetParentDeclContextDIE(cu);
746     if (!parent_decl_ctx_die || parent_decl_ctx_die.GetDIE() == die)
747       return dwarf_decl_ctx;
748     if (parent_decl_ctx_die.Tag() == DW_TAG_compile_unit ||
749         parent_decl_ctx_die.Tag() == DW_TAG_partial_unit)
750       return dwarf_decl_ctx;
751     die = parent_decl_ctx_die.GetDIE();
752     cu = parent_decl_ctx_die.GetCU();
753   }
754 }
755 
756 DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const {
757   return GetDWARFDeclContextStatic(this, cu);
758 }
759 
760 DWARFDIE
761 DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
762   DWARFAttributes attributes = GetAttributes(cu, Recurse::yes);
763   return GetParentDeclContextDIE(cu, attributes);
764 }
765 
766 DWARFDIE
767 DWARFDebugInfoEntry::GetParentDeclContextDIE(
768     DWARFUnit *cu, const DWARFAttributes &attributes) const {
769   DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
770 
771   while (die) {
772     // If this is the original DIE that we are searching for a declaration for,
773     // then don't look in the cache as we don't want our own decl context to be
774     // our decl context...
775     if (die.GetDIE() != this) {
776       switch (die.Tag()) {
777       case DW_TAG_compile_unit:
778       case DW_TAG_partial_unit:
779       case DW_TAG_namespace:
780       case DW_TAG_structure_type:
781       case DW_TAG_union_type:
782       case DW_TAG_class_type:
783         return die;
784 
785       default:
786         break;
787       }
788     }
789 
790     DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
791     if (spec_die) {
792       DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
793       if (decl_ctx_die)
794         return decl_ctx_die;
795     }
796 
797     DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
798     if (abs_die) {
799       DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
800       if (decl_ctx_die)
801         return decl_ctx_die;
802     }
803 
804     die = die.GetParent();
805   }
806   return DWARFDIE();
807 }
808 
809 lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
810   return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
811 }
812 
813 const DWARFAbbreviationDeclaration *
814 DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
815   if (!cu)
816     return nullptr;
817 
818   const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
819   if (!abbrev_set)
820     return nullptr;
821 
822   return abbrev_set->getAbbreviationDeclaration(m_abbr_idx);
823 }
824 
825 bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const {
826   if (Tag() != DW_TAG_variable)
827     return false;
828   const DWARFDebugInfoEntry *parent_die = GetParent();
829   while (parent_die != nullptr) {
830     switch (parent_die->Tag()) {
831     case DW_TAG_subprogram:
832     case DW_TAG_lexical_block:
833     case DW_TAG_inlined_subroutine:
834       return false;
835 
836     case DW_TAG_compile_unit:
837     case DW_TAG_partial_unit:
838       return true;
839 
840     default:
841       break;
842     }
843     parent_die = parent_die->GetParent();
844   }
845   return false;
846 }
847 
848 bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const {
849   return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
850          m_sibling_idx == rhs.m_sibling_idx &&
851          m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children &&
852          m_tag == rhs.m_tag;
853 }
854 
855 bool DWARFDebugInfoEntry::operator!=(const DWARFDebugInfoEntry &rhs) const {
856   return !(*this == rhs);
857 }
858