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