DWARFDebugInfoEntry.cpp revision 276479
1254721Semaste//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "DWARFDebugInfoEntry.h"
11254721Semaste
12254721Semaste#include <assert.h>
13254721Semaste
14254721Semaste#include <algorithm>
15254721Semaste
16254721Semaste#include "lldb/Core/Module.h"
17254721Semaste#include "lldb/Core/Stream.h"
18254721Semaste#include "lldb/Expression/DWARFExpression.h"
19254721Semaste#include "lldb/Symbol/ObjectFile.h"
20254721Semaste
21254721Semaste#include "DWARFCompileUnit.h"
22254721Semaste#include "SymbolFileDWARF.h"
23254721Semaste#include "DWARFDebugAbbrev.h"
24254721Semaste#include "DWARFDebugAranges.h"
25254721Semaste#include "DWARFDebugInfo.h"
26254721Semaste#include "DWARFDeclContext.h"
27254721Semaste#include "DWARFDIECollection.h"
28254721Semaste#include "DWARFFormValue.h"
29254721Semaste#include "DWARFLocationDescription.h"
30254721Semaste#include "DWARFLocationList.h"
31254721Semaste#include "DWARFDebugRanges.h"
32254721Semaste
33254721Semasteusing namespace lldb_private;
34254721Semasteusing namespace std;
35254721Semasteextern int g_verbose;
36254721Semaste
37254721Semaste
38254721Semaste
39254721SemasteDWARFDebugInfoEntry::Attributes::Attributes() :
40254721Semaste    m_infos()
41254721Semaste{
42254721Semaste}
43254721Semaste
44254721SemasteDWARFDebugInfoEntry::Attributes::~Attributes()
45254721Semaste{
46254721Semaste}
47254721Semaste
48254721Semaste
49254721Semasteuint32_t
50254721SemasteDWARFDebugInfoEntry::Attributes::FindAttributeIndex(dw_attr_t attr) const
51254721Semaste{
52254721Semaste    collection::const_iterator end = m_infos.end();
53254721Semaste    collection::const_iterator beg = m_infos.begin();
54254721Semaste    collection::const_iterator pos;
55254721Semaste    for (pos = beg; pos != end; ++pos)
56254721Semaste    {
57254721Semaste        if (pos->attr == attr)
58254721Semaste            return std::distance(beg, pos);
59254721Semaste    }
60254721Semaste    return UINT32_MAX;
61254721Semaste}
62254721Semaste
63254721Semastevoid
64254721SemasteDWARFDebugInfoEntry::Attributes::Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form)
65254721Semaste{
66254721Semaste    Info info = { cu, attr_die_offset, attr, form };
67254721Semaste    m_infos.push_back(info);
68254721Semaste}
69254721Semaste
70254721Semastebool
71254721SemasteDWARFDebugInfoEntry::Attributes::ContainsAttribute(dw_attr_t attr) const
72254721Semaste{
73254721Semaste    return FindAttributeIndex(attr) != UINT32_MAX;
74254721Semaste}
75254721Semaste
76254721Semastebool
77254721SemasteDWARFDebugInfoEntry::Attributes::RemoveAttribute(dw_attr_t attr)
78254721Semaste{
79254721Semaste    uint32_t attr_index = FindAttributeIndex(attr);
80254721Semaste    if (attr_index != UINT32_MAX)
81254721Semaste    {
82254721Semaste        m_infos.erase(m_infos.begin() + attr_index);
83254721Semaste        return true;
84254721Semaste    }
85254721Semaste    return false;
86254721Semaste}
87254721Semaste
88254721Semastebool
89254721SemasteDWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const
90254721Semaste{
91254721Semaste    form_value.SetForm(FormAtIndex(i));
92254721Semaste    lldb::offset_t offset = DIEOffsetAtIndex(i);
93254721Semaste    return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset, CompileUnitAtIndex(i));
94254721Semaste}
95254721Semaste
96254721Semasteuint64_t
97254721SemasteDWARFDebugInfoEntry::Attributes::FormValueAsUnsigned (SymbolFileDWARF* dwarf2Data, dw_attr_t attr, uint64_t fail_value) const
98254721Semaste{
99254721Semaste    const uint32_t attr_idx = FindAttributeIndex (attr);
100254721Semaste    if (attr_idx != UINT32_MAX)
101254721Semaste        return FormValueAsUnsignedAtIndex (dwarf2Data, attr_idx, fail_value);
102254721Semaste    return fail_value;
103254721Semaste}
104254721Semaste
105254721Semasteuint64_t
106254721SemasteDWARFDebugInfoEntry::Attributes::FormValueAsUnsignedAtIndex(SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const
107254721Semaste{
108254721Semaste    DWARFFormValue form_value;
109254721Semaste    if (ExtractFormValueAtIndex(dwarf2Data, i, form_value))
110254721Semaste        return form_value.Reference(CompileUnitAtIndex(i));
111254721Semaste    return fail_value;
112254721Semaste}
113254721Semaste
114254721Semaste
115254721Semaste
116254721Semastebool
117254721SemasteDWARFDebugInfoEntry::FastExtract
118254721Semaste(
119258054Semaste    const DWARFDataExtractor& debug_info_data,
120254721Semaste    const DWARFCompileUnit* cu,
121254721Semaste    const uint8_t *fixed_form_sizes,
122254721Semaste    lldb::offset_t *offset_ptr
123254721Semaste)
124254721Semaste{
125254721Semaste    m_offset = *offset_ptr;
126254721Semaste    m_parent_idx = 0;
127254721Semaste    m_sibling_idx = 0;
128254721Semaste    m_empty_children = false;
129254721Semaste    const uint64_t abbr_idx = debug_info_data.GetULEB128 (offset_ptr);
130254721Semaste    assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
131254721Semaste    m_abbr_idx = abbr_idx;
132254721Semaste
133254721Semaste    //assert (fixed_form_sizes);  // For best performance this should be specified!
134254721Semaste
135254721Semaste    if (m_abbr_idx)
136254721Semaste    {
137254721Semaste        lldb::offset_t offset = *offset_ptr;
138254721Semaste
139254721Semaste        const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
140254721Semaste
141254721Semaste        if (abbrevDecl == NULL)
142254721Semaste        {
143254721Semaste            cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid abbreviation code %u, please file a bug and attach the file at the start of this error message",
144254721Semaste                                                                                 m_offset,
145254721Semaste                                                                                 (unsigned)abbr_idx);
146254721Semaste            // WE can't parse anymore if the DWARF is borked...
147254721Semaste            *offset_ptr = UINT32_MAX;
148254721Semaste            return false;
149254721Semaste        }
150254721Semaste        m_tag = abbrevDecl->Tag();
151254721Semaste        m_has_children = abbrevDecl->HasChildren();
152254721Semaste        // Skip all data in the .debug_info for the attributes
153254721Semaste        const uint32_t numAttributes = abbrevDecl->NumAttributes();
154258054Semaste        uint32_t i;
155258054Semaste        dw_form_t form;
156254721Semaste        for (i=0; i<numAttributes; ++i)
157254721Semaste        {
158254721Semaste            form = abbrevDecl->GetFormByIndexUnchecked(i);
159254721Semaste
160254721Semaste            const uint8_t fixed_skip_size = fixed_form_sizes [form];
161254721Semaste            if (fixed_skip_size)
162254721Semaste                offset += fixed_skip_size;
163254721Semaste            else
164254721Semaste            {
165254721Semaste                bool form_is_indirect = false;
166254721Semaste                do
167254721Semaste                {
168254721Semaste                    form_is_indirect = false;
169258054Semaste                    uint32_t form_size = 0;
170254721Semaste                    switch (form)
171254721Semaste                    {
172254721Semaste                    // Blocks if inlined data that have a length field and the data bytes
173254721Semaste                    // inlined in the .debug_info
174254721Semaste                    case DW_FORM_exprloc     :
175254721Semaste                    case DW_FORM_block       : form_size = debug_info_data.GetULEB128 (&offset);      break;
176254721Semaste                    case DW_FORM_block1      : form_size = debug_info_data.GetU8_unchecked (&offset); break;
177254721Semaste                    case DW_FORM_block2      : form_size = debug_info_data.GetU16_unchecked (&offset);break;
178254721Semaste                    case DW_FORM_block4      : form_size = debug_info_data.GetU32_unchecked (&offset);break;
179254721Semaste
180254721Semaste                    // Inlined NULL terminated C-strings
181254721Semaste                    case DW_FORM_string      :
182254721Semaste                        debug_info_data.GetCStr (&offset);
183254721Semaste                        break;
184254721Semaste
185254721Semaste                    // Compile unit address sized values
186254721Semaste                    case DW_FORM_addr        :
187254721Semaste                        form_size = cu->GetAddressByteSize();
188254721Semaste                        break;
189254721Semaste                    case DW_FORM_ref_addr    :
190254721Semaste                        if (cu->GetVersion() <= 2)
191254721Semaste                            form_size = cu->GetAddressByteSize();
192254721Semaste                        else
193254721Semaste                            form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet
194254721Semaste                        break;
195254721Semaste
196254721Semaste                    // 0 sized form
197254721Semaste                    case DW_FORM_flag_present:
198254721Semaste                        form_size = 0;
199254721Semaste                        break;
200254721Semaste
201254721Semaste                    // 1 byte values
202254721Semaste                    case DW_FORM_data1       :
203254721Semaste                    case DW_FORM_flag        :
204254721Semaste                    case DW_FORM_ref1        :
205254721Semaste                        form_size = 1;
206254721Semaste                        break;
207254721Semaste
208254721Semaste                    // 2 byte values
209254721Semaste                    case DW_FORM_data2       :
210254721Semaste                    case DW_FORM_ref2        :
211254721Semaste                        form_size = 2;
212254721Semaste                        break;
213254721Semaste
214254721Semaste                    // 4 byte values
215254721Semaste                    case DW_FORM_strp        :
216254721Semaste                    case DW_FORM_data4       :
217254721Semaste                    case DW_FORM_ref4        :
218254721Semaste                        form_size = 4;
219254721Semaste                        break;
220254721Semaste
221254721Semaste                    // 8 byte values
222254721Semaste                    case DW_FORM_data8       :
223254721Semaste                    case DW_FORM_ref8        :
224254721Semaste                    case DW_FORM_ref_sig8    :
225254721Semaste                        form_size = 8;
226254721Semaste                        break;
227254721Semaste
228254721Semaste                    // signed or unsigned LEB 128 values
229254721Semaste                    case DW_FORM_sdata       :
230254721Semaste                    case DW_FORM_udata       :
231254721Semaste                    case DW_FORM_ref_udata   :
232254721Semaste                        debug_info_data.Skip_LEB128 (&offset);
233254721Semaste                        break;
234254721Semaste
235254721Semaste                    case DW_FORM_indirect    :
236254721Semaste                        form_is_indirect = true;
237254721Semaste                        form = debug_info_data.GetULEB128 (&offset);
238254721Semaste                        break;
239254721Semaste
240254721Semaste                    case DW_FORM_sec_offset  :
241254721Semaste                        if (cu->GetAddressByteSize () == 4)
242254721Semaste                            debug_info_data.GetU32 (offset_ptr);
243254721Semaste                        else
244254721Semaste                            debug_info_data.GetU64 (offset_ptr);
245254721Semaste                        break;
246254721Semaste
247254721Semaste                    default:
248254721Semaste                        *offset_ptr = m_offset;
249254721Semaste                        return false;
250254721Semaste                    }
251254721Semaste                    offset += form_size;
252254721Semaste
253254721Semaste                } while (form_is_indirect);
254254721Semaste            }
255254721Semaste        }
256254721Semaste        *offset_ptr = offset;
257254721Semaste        return true;
258254721Semaste    }
259254721Semaste    else
260254721Semaste    {
261254721Semaste        m_tag = 0;
262254721Semaste        m_has_children = false;
263254721Semaste        return true;    // NULL debug tag entry
264254721Semaste    }
265254721Semaste
266254721Semaste    return false;
267254721Semaste}
268254721Semaste
269254721Semaste//----------------------------------------------------------------------
270254721Semaste// Extract
271254721Semaste//
272254721Semaste// Extract a debug info entry for a given compile unit from the
273254721Semaste// .debug_info and .debug_abbrev data within the SymbolFileDWARF class
274254721Semaste// starting at the given offset
275254721Semaste//----------------------------------------------------------------------
276254721Semastebool
277254721SemasteDWARFDebugInfoEntry::Extract
278254721Semaste(
279254721Semaste    SymbolFileDWARF* dwarf2Data,
280254721Semaste    const DWARFCompileUnit* cu,
281254721Semaste    lldb::offset_t *offset_ptr
282254721Semaste)
283254721Semaste{
284258054Semaste    const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
285258054Semaste//    const DWARFDataExtractor& debug_str_data = dwarf2Data->get_debug_str_data();
286254721Semaste    const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
287254721Semaste    const uint8_t cu_addr_size = cu->GetAddressByteSize();
288254721Semaste    lldb::offset_t offset = *offset_ptr;
289254721Semaste//  if (offset >= cu_end_offset)
290254721Semaste//      Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset);
291254721Semaste    if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset))
292254721Semaste    {
293254721Semaste        m_offset = offset;
294254721Semaste
295254721Semaste        const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
296254721Semaste        assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
297254721Semaste        m_abbr_idx = abbr_idx;
298254721Semaste        if (abbr_idx)
299254721Semaste        {
300254721Semaste            const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
301254721Semaste
302254721Semaste            if (abbrevDecl)
303254721Semaste            {
304254721Semaste                m_tag = abbrevDecl->Tag();
305254721Semaste                m_has_children = abbrevDecl->HasChildren();
306254721Semaste
307254721Semaste                bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
308254721Semaste                if (cu && isCompileUnitTag)
309254721Semaste                    ((DWARFCompileUnit*)cu)->SetBaseAddress(0);
310254721Semaste
311254721Semaste                // Skip all data in the .debug_info for the attributes
312254721Semaste                const uint32_t numAttributes = abbrevDecl->NumAttributes();
313254721Semaste                uint32_t i;
314254721Semaste                dw_attr_t attr;
315254721Semaste                dw_form_t form;
316254721Semaste                for (i=0; i<numAttributes; ++i)
317254721Semaste                {
318254721Semaste                    abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
319254721Semaste
320254721Semaste                    if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc)))
321254721Semaste                    {
322254721Semaste                        DWARFFormValue form_value(form);
323254721Semaste                        if (form_value.ExtractValue(debug_info_data, &offset, cu))
324254721Semaste                        {
325254721Semaste                            if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
326254721Semaste                                ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned());
327254721Semaste                        }
328254721Semaste                    }
329254721Semaste                    else
330254721Semaste                    {
331254721Semaste                        bool form_is_indirect = false;
332254721Semaste                        do
333254721Semaste                        {
334254721Semaste                            form_is_indirect = false;
335258054Semaste                            uint32_t form_size = 0;
336254721Semaste                            switch (form)
337254721Semaste                            {
338254721Semaste                            // Blocks if inlined data that have a length field and the data bytes
339254721Semaste                            // inlined in the .debug_info
340254721Semaste                            case DW_FORM_exprloc     :
341254721Semaste                            case DW_FORM_block       : form_size = debug_info_data.GetULEB128(&offset);  break;
342254721Semaste                            case DW_FORM_block1      : form_size = debug_info_data.GetU8(&offset);       break;
343254721Semaste                            case DW_FORM_block2      : form_size = debug_info_data.GetU16(&offset);      break;
344254721Semaste                            case DW_FORM_block4      : form_size = debug_info_data.GetU32(&offset);      break;
345254721Semaste
346254721Semaste                            // Inlined NULL terminated C-strings
347254721Semaste                            case DW_FORM_string      : debug_info_data.GetCStr(&offset);                 break;
348254721Semaste
349254721Semaste                            // Compile unit address sized values
350254721Semaste                            case DW_FORM_addr        :
351254721Semaste                                form_size = cu_addr_size;
352254721Semaste                                break;
353254721Semaste                            case DW_FORM_ref_addr    :
354254721Semaste                                if (cu->GetVersion() <= 2)
355254721Semaste                                    form_size = cu_addr_size;
356254721Semaste                                else
357254721Semaste                                    form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet
358254721Semaste                                break;
359254721Semaste
360254721Semaste                            // 0 sized form
361254721Semaste                            case DW_FORM_flag_present:
362254721Semaste                                form_size = 0;
363254721Semaste                                break;
364254721Semaste
365254721Semaste                            // 1 byte values
366254721Semaste                            case DW_FORM_data1       :
367254721Semaste                            case DW_FORM_flag        :
368254721Semaste                            case DW_FORM_ref1        :
369254721Semaste                                form_size = 1;
370254721Semaste                                break;
371254721Semaste
372254721Semaste                            // 2 byte values
373254721Semaste                            case DW_FORM_data2       :
374254721Semaste                            case DW_FORM_ref2        :
375254721Semaste                                form_size = 2;
376254721Semaste                                break;
377254721Semaste
378254721Semaste                            // 4 byte values
379254721Semaste                            case DW_FORM_strp        :
380254721Semaste                                form_size = 4;
381254721Semaste                                break;
382254721Semaste
383254721Semaste                            case DW_FORM_data4       :
384254721Semaste                            case DW_FORM_ref4        :
385254721Semaste                                form_size = 4;
386254721Semaste                                break;
387254721Semaste
388254721Semaste                            // 8 byte values
389254721Semaste                            case DW_FORM_data8       :
390254721Semaste                            case DW_FORM_ref8        :
391254721Semaste                            case DW_FORM_ref_sig8    :
392254721Semaste                                form_size = 8;
393254721Semaste                                break;
394254721Semaste
395254721Semaste                            // signed or unsigned LEB 128 values
396254721Semaste                            case DW_FORM_sdata       :
397254721Semaste                            case DW_FORM_udata       :
398254721Semaste                            case DW_FORM_ref_udata   :
399254721Semaste                                debug_info_data.Skip_LEB128(&offset);
400254721Semaste                                break;
401254721Semaste
402254721Semaste                            case DW_FORM_indirect    :
403254721Semaste                                form = debug_info_data.GetULEB128(&offset);
404254721Semaste                                form_is_indirect = true;
405254721Semaste                                break;
406254721Semaste
407254721Semaste                            case DW_FORM_sec_offset  :
408254721Semaste                                if (cu->GetAddressByteSize () == 4)
409254721Semaste                                    debug_info_data.GetU32 (offset_ptr);
410254721Semaste                                else
411254721Semaste                                    debug_info_data.GetU64 (offset_ptr);
412254721Semaste                                break;
413254721Semaste
414254721Semaste                            default:
415254721Semaste                                *offset_ptr = offset;
416254721Semaste                                return false;
417254721Semaste                            }
418254721Semaste
419254721Semaste                            offset += form_size;
420254721Semaste                        } while (form_is_indirect);
421254721Semaste                    }
422254721Semaste                }
423254721Semaste                *offset_ptr = offset;
424254721Semaste                return true;
425254721Semaste            }
426254721Semaste        }
427254721Semaste        else
428254721Semaste        {
429254721Semaste            m_tag = 0;
430254721Semaste            m_has_children = false;
431254721Semaste            *offset_ptr = offset;
432254721Semaste            return true;    // NULL debug tag entry
433254721Semaste        }
434254721Semaste    }
435254721Semaste
436254721Semaste    return false;
437254721Semaste}
438254721Semaste
439254721Semaste//----------------------------------------------------------------------
440254721Semaste// DumpAncestry
441254721Semaste//
442254721Semaste// Dumps all of a debug information entries parents up until oldest and
443254721Semaste// all of it's attributes to the specified stream.
444254721Semaste//----------------------------------------------------------------------
445254721Semastevoid
446254721SemasteDWARFDebugInfoEntry::DumpAncestry
447254721Semaste(
448254721Semaste    SymbolFileDWARF* dwarf2Data,
449254721Semaste    const DWARFCompileUnit* cu,
450254721Semaste    const DWARFDebugInfoEntry* oldest,
451254721Semaste    Stream &s,
452254721Semaste    uint32_t recurse_depth
453254721Semaste) const
454254721Semaste{
455254721Semaste    const DWARFDebugInfoEntry* parent = GetParent();
456254721Semaste    if (parent && parent != oldest)
457254721Semaste        parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
458254721Semaste    Dump(dwarf2Data, cu, s, recurse_depth);
459254721Semaste}
460254721Semaste
461254721Semaste//----------------------------------------------------------------------
462254721Semaste// Compare two DIE by comparing all their attributes values, and
463254721Semaste// following all DW_FORM_ref attributes and comparing their contents as
464254721Semaste// well (except for DW_AT_sibling attributes.
465254721Semaste//
466254721Semaste//  DWARFDebugInfoEntry::CompareState compare_state;
467254721Semaste//  int result = DWARFDebugInfoEntry::Compare(this, 0x00017ccb, 0x0001eb2b, compare_state, false, true);
468254721Semaste//----------------------------------------------------------------------
469254721Semaste//int
470254721Semaste//DWARFDebugInfoEntry::Compare
471254721Semaste//(
472254721Semaste//    SymbolFileDWARF* dwarf2Data,
473254721Semaste//    dw_offset_t a_die_offset,
474254721Semaste//    dw_offset_t b_die_offset,
475254721Semaste//    CompareState &compare_state,
476254721Semaste//    bool compare_siblings,
477254721Semaste//    bool compare_children
478254721Semaste//)
479254721Semaste//{
480254721Semaste//    if (a_die_offset == b_die_offset)
481254721Semaste//        return 0;
482254721Semaste//
483254721Semaste//    DWARFCompileUnitSP a_cu_sp;
484254721Semaste//    DWARFCompileUnitSP b_cu_sp;
485254721Semaste//    const DWARFDebugInfoEntry* a_die = dwarf2Data->DebugInfo()->GetDIEPtr(a_die_offset, &a_cu_sp);
486254721Semaste//    const DWARFDebugInfoEntry* b_die = dwarf2Data->DebugInfo()->GetDIEPtr(b_die_offset, &b_cu_sp);
487254721Semaste//
488254721Semaste//    return Compare(dwarf2Data, a_cu_sp.get(), a_die, b_cu_sp.get(), b_die, compare_state, compare_siblings, compare_children);
489254721Semaste//}
490254721Semaste//
491254721Semaste//int
492254721Semaste//DWARFDebugInfoEntry::Compare
493254721Semaste//(
494254721Semaste//    SymbolFileDWARF* dwarf2Data,
495254721Semaste//    DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die,
496254721Semaste//    DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die,
497254721Semaste//    CompareState &compare_state,
498254721Semaste//    bool compare_siblings,
499254721Semaste//    bool compare_children
500254721Semaste//)
501254721Semaste//{
502254721Semaste//    if (a_die == b_die)
503254721Semaste//        return 0;
504254721Semaste//
505254721Semaste//    if (!compare_state.AddTypePair(a_die->GetOffset(), b_die->GetOffset()))
506254721Semaste//    {
507254721Semaste//        // We are already comparing both of these types, so let
508254721Semaste//        // compares complete for the real result
509254721Semaste//        return 0;
510254721Semaste//    }
511254721Semaste//
512254721Semaste//    //printf("DWARFDebugInfoEntry::Compare(0x%8.8x, 0x%8.8x)\n", a_die->GetOffset(), b_die->GetOffset());
513254721Semaste//
514254721Semaste//    // Do we have two valid DIEs?
515254721Semaste//    if (a_die && b_die)
516254721Semaste//    {
517254721Semaste//        // Both DIE are valid
518254721Semaste//        int result = 0;
519254721Semaste//
520254721Semaste//        const dw_tag_t a_tag = a_die->Tag();
521254721Semaste//        const dw_tag_t b_tag = b_die->Tag();
522254721Semaste//        if (a_tag == 0 && b_tag == 0)
523254721Semaste//            return 0;
524254721Semaste//
525254721Semaste//        //printf("    comparing tags: %s and %s\n", DW_TAG_value_to_name(a_tag), DW_TAG_value_to_name(b_tag));
526254721Semaste//
527254721Semaste//        if (a_tag < b_tag)
528254721Semaste//            return -1;
529254721Semaste//        else if (a_tag > b_tag)
530254721Semaste//            return 1;
531254721Semaste//
532254721Semaste//        DWARFDebugInfoEntry::Attributes a_attrs;
533254721Semaste//        DWARFDebugInfoEntry::Attributes b_attrs;
534254721Semaste//        size_t a_attr_count = a_die->GetAttributes(dwarf2Data, a_cu, a_attrs);
535254721Semaste//        size_t b_attr_count = b_die->GetAttributes(dwarf2Data, b_cu, b_attrs);
536254721Semaste//        if (a_attr_count != b_attr_count)
537254721Semaste//        {
538254721Semaste//            a_attrs.RemoveAttribute(DW_AT_sibling);
539254721Semaste//            b_attrs.RemoveAttribute(DW_AT_sibling);
540254721Semaste//        }
541254721Semaste//
542254721Semaste//        a_attr_count = a_attrs.Size();
543254721Semaste//        b_attr_count = b_attrs.Size();
544254721Semaste//
545254721Semaste//        DWARFFormValue a_form_value;
546254721Semaste//        DWARFFormValue b_form_value;
547254721Semaste//
548254721Semaste//        if (a_attr_count != b_attr_count)
549254721Semaste//        {
550254721Semaste//            uint32_t is_decl_index = a_attrs.FindAttributeIndex(DW_AT_declaration);
551254721Semaste//            uint32_t a_name_index = UINT32_MAX;
552254721Semaste//            uint32_t b_name_index = UINT32_MAX;
553254721Semaste//            if (is_decl_index != UINT32_MAX)
554254721Semaste//            {
555254721Semaste//                if (a_attr_count == 2)
556254721Semaste//                {
557254721Semaste//                    a_name_index = a_attrs.FindAttributeIndex(DW_AT_name);
558254721Semaste//                    b_name_index = b_attrs.FindAttributeIndex(DW_AT_name);
559254721Semaste//                }
560254721Semaste//            }
561254721Semaste//            else
562254721Semaste//            {
563254721Semaste//                is_decl_index = b_attrs.FindAttributeIndex(DW_AT_declaration);
564254721Semaste//                if (is_decl_index != UINT32_MAX && a_attr_count == 2)
565254721Semaste//                {
566254721Semaste//                    a_name_index = a_attrs.FindAttributeIndex(DW_AT_name);
567254721Semaste//                    b_name_index = b_attrs.FindAttributeIndex(DW_AT_name);
568254721Semaste//                }
569254721Semaste//            }
570254721Semaste//            if (a_name_index != UINT32_MAX && b_name_index != UINT32_MAX)
571254721Semaste//            {
572254721Semaste//                if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, a_name_index, a_form_value) &&
573254721Semaste//                    b_attrs.ExtractFormValueAtIndex(dwarf2Data, b_name_index, b_form_value))
574254721Semaste//                {
575254721Semaste//                    result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, &dwarf2Data->get_debug_str_data());
576254721Semaste//                    if (result == 0)
577254721Semaste//                    {
578254721Semaste//                        a_attr_count = b_attr_count = 0;
579254721Semaste//                        compare_children = false;
580254721Semaste//                    }
581254721Semaste//                }
582254721Semaste//            }
583254721Semaste//        }
584254721Semaste//
585254721Semaste//        if (a_attr_count < b_attr_count)
586254721Semaste//            return -1;
587254721Semaste//        if (a_attr_count > b_attr_count)
588254721Semaste//            return 1;
589254721Semaste//
590254721Semaste//
591254721Semaste//        // The number of attributes are the same...
592254721Semaste//        if (a_attr_count > 0)
593254721Semaste//        {
594258054Semaste//            const DWARFDataExtractor* debug_str_data_ptr = &dwarf2Data->get_debug_str_data();
595254721Semaste//
596254721Semaste//            uint32_t i;
597254721Semaste//            for (i=0; i<a_attr_count; ++i)
598254721Semaste//            {
599254721Semaste//                const dw_attr_t a_attr = a_attrs.AttributeAtIndex(i);
600254721Semaste//                const dw_attr_t b_attr = b_attrs.AttributeAtIndex(i);
601254721Semaste//                //printf("    comparing attributes\n\t\t0x%8.8x: %s %s\t\t0x%8.8x: %s %s\n",
602254721Semaste//                //                a_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(a_attrs.FormAtIndex(i)), DW_AT_value_to_name(a_attr),
603254721Semaste//                //                b_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(b_attrs.FormAtIndex(i)), DW_AT_value_to_name(b_attr));
604254721Semaste//
605254721Semaste//                if (a_attr < b_attr)
606254721Semaste//                    return -1;
607254721Semaste//                else if (a_attr > b_attr)
608254721Semaste//                    return 1;
609254721Semaste//
610254721Semaste//                switch (a_attr)
611254721Semaste//                {
612254721Semaste//                // Since we call a form of GetAttributes which inlines the
613254721Semaste//                // attributes from DW_AT_abstract_origin and DW_AT_specification
614254721Semaste//                // we don't care if their values mismatch...
615254721Semaste//                case DW_AT_abstract_origin:
616254721Semaste//                case DW_AT_specification:
617254721Semaste//                case DW_AT_sibling:
618254721Semaste//                case DW_AT_containing_type:
619254721Semaste//                    //printf("        action = IGNORE\n");
620254721Semaste//                    result = 0;
621254721Semaste//                    break;  // ignore
622254721Semaste//
623254721Semaste//                default:
624254721Semaste//                    if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, i, a_form_value) &&
625254721Semaste//                        b_attrs.ExtractFormValueAtIndex(dwarf2Data, i, b_form_value))
626254721Semaste//                        result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, debug_str_data_ptr);
627254721Semaste//                    break;
628254721Semaste//                }
629254721Semaste//
630254721Semaste//                //printf("\t  result = %i\n", result);
631254721Semaste//
632254721Semaste//                if (result != 0)
633254721Semaste//                {
634254721Semaste//                    // Attributes weren't equal, lets see if we care?
635254721Semaste//                    switch (a_attr)
636254721Semaste//                    {
637254721Semaste//                    case DW_AT_decl_file:
638254721Semaste//                        // TODO: add the ability to compare files in two different compile units
639254721Semaste//                        if (a_cu == b_cu)
640254721Semaste//                        {
641254721Semaste//                            //printf("        action = RETURN RESULT\n");
642254721Semaste//                            return result;  // Only return the compare results when the compile units are the same and the decl_file attributes can be compared
643254721Semaste//                        }
644254721Semaste//                        else
645254721Semaste//                        {
646254721Semaste//                            result = 0;
647254721Semaste//                            //printf("        action = IGNORE\n");
648254721Semaste//                        }
649254721Semaste//                        break;
650254721Semaste//
651254721Semaste//                    default:
652254721Semaste//                        switch (a_attrs.FormAtIndex(i))
653254721Semaste//                        {
654254721Semaste//                        case DW_FORM_ref1:
655254721Semaste//                        case DW_FORM_ref2:
656254721Semaste//                        case DW_FORM_ref4:
657254721Semaste//                        case DW_FORM_ref8:
658254721Semaste//                        case DW_FORM_ref_udata:
659254721Semaste//                        case DW_FORM_ref_addr:
660254721Semaste//                            //printf("    action = COMPARE DIEs 0x%8.8x 0x%8.8x\n", (dw_offset_t)a_form_value.Reference(a_cu), (dw_offset_t)b_form_value.Reference(b_cu));
661254721Semaste//                            // These attribute values refer to other DIEs, so lets compare those instead of their DIE offsets...
662254721Semaste//                            result = Compare(dwarf2Data, a_form_value.Reference(a_cu), b_form_value.Reference(b_cu), compare_state, false, true);
663254721Semaste//                            if (result != 0)
664254721Semaste//                                return result;
665254721Semaste//                            break;
666254721Semaste//
667254721Semaste//                        default:
668254721Semaste//                            // We do care that they were different, return this result...
669254721Semaste//                            //printf("        action = RETURN RESULT\n");
670254721Semaste//                            return result;
671254721Semaste//                        }
672254721Semaste//                    }
673254721Semaste//                }
674254721Semaste//            }
675254721Semaste//        }
676254721Semaste//        //printf("    SUCCESS\n\t\t0x%8.8x: %s\n\t\t0x%8.8x: %s\n", a_die->GetOffset(), DW_TAG_value_to_name(a_tag), b_die->GetOffset(), DW_TAG_value_to_name(b_tag));
677254721Semaste//
678254721Semaste//        if (compare_children)
679254721Semaste//        {
680254721Semaste//            bool a_has_children = a_die->HasChildren();
681254721Semaste//            bool b_has_children = b_die->HasChildren();
682254721Semaste//            if (a_has_children == b_has_children)
683254721Semaste//            {
684254721Semaste//                // Both either have kids or don't
685254721Semaste//                if (a_has_children)
686254721Semaste//                    result = Compare(   dwarf2Data,
687254721Semaste//                                        a_cu, a_die->GetFirstChild(),
688254721Semaste//                                        b_cu, b_die->GetFirstChild(),
689254721Semaste//                                        compare_state, true, compare_children);
690254721Semaste//                else
691254721Semaste//                    result = 0;
692254721Semaste//            }
693254721Semaste//            else if (!a_has_children)
694254721Semaste//                result = -1;    // A doesn't have kids, but B does
695254721Semaste//            else
696254721Semaste//                result = 1; // A has kids, but B doesn't
697254721Semaste//        }
698254721Semaste//
699254721Semaste//        if (compare_siblings)
700254721Semaste//        {
701254721Semaste//            result = Compare(   dwarf2Data,
702254721Semaste//                                a_cu, a_die->GetSibling(),
703254721Semaste//                                b_cu, b_die->GetSibling(),
704254721Semaste//                                compare_state, true, compare_children);
705254721Semaste//        }
706254721Semaste//
707254721Semaste//        return result;
708254721Semaste//    }
709254721Semaste//
710254721Semaste//    if (a_die == NULL)
711254721Semaste//        return -1;  // a_die is NULL, yet b_die is non-NULL
712254721Semaste//    else
713254721Semaste//        return 1;   // a_die is non-NULL, yet b_die is NULL
714254721Semaste//
715254721Semaste//}
716254721Semaste//
717254721Semaste//
718254721Semaste//int
719254721Semaste//DWARFDebugInfoEntry::Compare
720254721Semaste//(
721254721Semaste//  SymbolFileDWARF* dwarf2Data,
722254721Semaste//  const DWARFCompileUnit* cu_a,
723254721Semaste//  const DWARFDebugInfoEntry* die_a,
724254721Semaste//  const DWARFCompileUnit* cu_a,
725254721Semaste//  const DWARFDebugInfoEntry* die_b,
726254721Semaste//  CompareState &compare_state
727254721Semaste//)
728254721Semaste//{
729254721Semaste//}
730254721Semaste
731254721Semaste//----------------------------------------------------------------------
732254721Semaste// GetDIENamesAndRanges
733254721Semaste//
734254721Semaste// Gets the valid address ranges for a given DIE by looking for a
735254721Semaste// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges
736254721Semaste// attributes.
737254721Semaste//----------------------------------------------------------------------
738254721Semastebool
739254721SemasteDWARFDebugInfoEntry::GetDIENamesAndRanges
740254721Semaste(
741254721Semaste    SymbolFileDWARF* dwarf2Data,
742254721Semaste    const DWARFCompileUnit* cu,
743254721Semaste    const char * &name,
744254721Semaste    const char * &mangled,
745254721Semaste    DWARFDebugRanges::RangeList& ranges,
746254721Semaste    int& decl_file,
747254721Semaste    int& decl_line,
748254721Semaste    int& decl_column,
749254721Semaste    int& call_file,
750254721Semaste    int& call_line,
751254721Semaste    int& call_column,
752254721Semaste    DWARFExpression *frame_base
753254721Semaste) const
754254721Semaste{
755254721Semaste    if (dwarf2Data == NULL)
756254721Semaste        return false;
757254721Semaste
758254721Semaste    dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
759254721Semaste    dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
760254721Semaste    std::vector<dw_offset_t> die_offsets;
761254721Semaste    bool set_frame_base_loclist_addr = false;
762254721Semaste
763254721Semaste    lldb::offset_t offset;
764254721Semaste    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
765254721Semaste
766258054Semaste    lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
767258054Semaste
768254721Semaste    if (abbrevDecl)
769254721Semaste    {
770258054Semaste        const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
771254721Semaste
772254721Semaste        if (!debug_info_data.ValidOffset(offset))
773254721Semaste            return false;
774254721Semaste
775254721Semaste        const uint32_t numAttributes = abbrevDecl->NumAttributes();
776254721Semaste        uint32_t i;
777254721Semaste        dw_attr_t attr;
778254721Semaste        dw_form_t form;
779254721Semaste        bool do_offset = false;
780254721Semaste
781254721Semaste        for (i=0; i<numAttributes; ++i)
782254721Semaste        {
783254721Semaste            abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
784254721Semaste            DWARFFormValue form_value(form);
785254721Semaste            if (form_value.ExtractValue(debug_info_data, &offset, cu))
786254721Semaste            {
787254721Semaste                switch (attr)
788254721Semaste                {
789254721Semaste                case DW_AT_low_pc:
790254721Semaste                    lo_pc = form_value.Unsigned();
791254721Semaste
792254721Semaste                    if (do_offset)
793254721Semaste                        hi_pc += lo_pc;
794254721Semaste                    do_offset = false;
795254721Semaste                    break;
796254721Semaste
797254721Semaste                case DW_AT_entry_pc:
798254721Semaste                    lo_pc = form_value.Unsigned();
799254721Semaste                    break;
800254721Semaste
801254721Semaste                case DW_AT_high_pc:
802254721Semaste                    hi_pc = form_value.Unsigned();
803254721Semaste                    if (form_value.Form() != DW_FORM_addr)
804254721Semaste                    {
805254721Semaste                        if (lo_pc == LLDB_INVALID_ADDRESS)
806254721Semaste                            do_offset = hi_pc != LLDB_INVALID_ADDRESS;
807254721Semaste                        else
808254721Semaste                            hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save on relocations
809254721Semaste                    }
810254721Semaste                    break;
811254721Semaste
812254721Semaste                case DW_AT_ranges:
813254721Semaste                    {
814254721Semaste                        const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
815254721Semaste                        debug_ranges->FindRanges(form_value.Unsigned(), ranges);
816254721Semaste                        // All DW_AT_ranges are relative to the base address of the
817254721Semaste                        // compile unit. We add the compile unit base address to make
818254721Semaste                        // sure all the addresses are properly fixed up.
819254721Semaste                        ranges.Slide(cu->GetBaseAddress());
820254721Semaste                    }
821254721Semaste                    break;
822254721Semaste
823254721Semaste                case DW_AT_name:
824254721Semaste                    if (name == NULL)
825254721Semaste                        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
826254721Semaste                    break;
827254721Semaste
828254721Semaste                case DW_AT_MIPS_linkage_name:
829254721Semaste                case DW_AT_linkage_name:
830254721Semaste                    if (mangled == NULL)
831254721Semaste                        mangled = form_value.AsCString(&dwarf2Data->get_debug_str_data());
832254721Semaste                    break;
833254721Semaste
834254721Semaste                case DW_AT_abstract_origin:
835254721Semaste                    die_offsets.push_back(form_value.Reference(cu));
836254721Semaste                    break;
837254721Semaste
838254721Semaste                case DW_AT_specification:
839254721Semaste                    die_offsets.push_back(form_value.Reference(cu));
840254721Semaste                    break;
841254721Semaste
842254721Semaste                case DW_AT_decl_file:
843254721Semaste                    if (decl_file == 0)
844254721Semaste                        decl_file = form_value.Unsigned();
845254721Semaste                    break;
846254721Semaste
847254721Semaste                case DW_AT_decl_line:
848254721Semaste                    if (decl_line == 0)
849254721Semaste                        decl_line = form_value.Unsigned();
850254721Semaste                    break;
851254721Semaste
852254721Semaste                case DW_AT_decl_column:
853254721Semaste                    if (decl_column == 0)
854254721Semaste                        decl_column = form_value.Unsigned();
855254721Semaste                    break;
856254721Semaste
857254721Semaste                case DW_AT_call_file:
858254721Semaste                    if (call_file == 0)
859254721Semaste                        call_file = form_value.Unsigned();
860254721Semaste                    break;
861254721Semaste
862254721Semaste                case DW_AT_call_line:
863254721Semaste                    if (call_line == 0)
864254721Semaste                        call_line = form_value.Unsigned();
865254721Semaste                    break;
866254721Semaste
867254721Semaste                case DW_AT_call_column:
868254721Semaste                    if (call_column == 0)
869254721Semaste                        call_column = form_value.Unsigned();
870254721Semaste                    break;
871254721Semaste
872254721Semaste                case DW_AT_frame_base:
873254721Semaste                    if (frame_base)
874254721Semaste                    {
875254721Semaste                        if (form_value.BlockData())
876254721Semaste                        {
877254721Semaste                            uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
878254721Semaste                            uint32_t block_length = form_value.Unsigned();
879258054Semaste                            frame_base->SetOpcodeData(module, debug_info_data, block_offset, block_length);
880254721Semaste                        }
881254721Semaste                        else
882254721Semaste                        {
883258054Semaste                            const DWARFDataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data();
884254721Semaste                            const dw_offset_t debug_loc_offset = form_value.Unsigned();
885254721Semaste
886254721Semaste                            size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
887254721Semaste                            if (loc_list_length > 0)
888254721Semaste                            {
889258054Semaste                                frame_base->SetOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
890254721Semaste                                if (lo_pc != LLDB_INVALID_ADDRESS)
891254721Semaste                                {
892254721Semaste                                    assert (lo_pc >= cu->GetBaseAddress());
893254721Semaste                                    frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress());
894254721Semaste                                }
895254721Semaste                                else
896254721Semaste                                {
897254721Semaste                                    set_frame_base_loclist_addr = true;
898254721Semaste                                }
899254721Semaste                            }
900254721Semaste                        }
901254721Semaste                    }
902254721Semaste                    break;
903254721Semaste
904254721Semaste                default:
905254721Semaste                    break;
906254721Semaste                }
907254721Semaste            }
908254721Semaste        }
909254721Semaste    }
910254721Semaste
911254721Semaste    if (ranges.IsEmpty())
912254721Semaste    {
913254721Semaste        if (lo_pc != LLDB_INVALID_ADDRESS)
914254721Semaste        {
915254721Semaste            if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
916254721Semaste                ranges.Append(DWARFDebugRanges::Range (lo_pc, hi_pc - lo_pc));
917254721Semaste            else
918254721Semaste                ranges.Append(DWARFDebugRanges::Range (lo_pc, 0));
919254721Semaste        }
920254721Semaste    }
921254721Semaste
922254721Semaste    if (set_frame_base_loclist_addr)
923254721Semaste    {
924254721Semaste        dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
925254721Semaste        assert (lowest_range_pc >= cu->GetBaseAddress());
926254721Semaste        frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress());
927254721Semaste    }
928254721Semaste
929254721Semaste    if (ranges.IsEmpty() || name == NULL || mangled == NULL)
930254721Semaste    {
931254721Semaste        std::vector<dw_offset_t>::const_iterator pos;
932254721Semaste        std::vector<dw_offset_t>::const_iterator end = die_offsets.end();
933254721Semaste        for (pos = die_offsets.begin(); pos != end; ++pos)
934254721Semaste        {
935254721Semaste            DWARFCompileUnitSP cu_sp_ptr;
936254721Semaste            const DWARFDebugInfoEntry* die = NULL;
937254721Semaste            dw_offset_t die_offset = *pos;
938254721Semaste            if (die_offset != DW_INVALID_OFFSET)
939254721Semaste            {
940254721Semaste                die = dwarf2Data->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
941254721Semaste                if (die)
942254721Semaste                    die->GetDIENamesAndRanges(dwarf2Data, cu_sp_ptr.get(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
943254721Semaste            }
944254721Semaste        }
945254721Semaste    }
946254721Semaste    return !ranges.IsEmpty();
947254721Semaste}
948254721Semaste
949254721Semaste//----------------------------------------------------------------------
950254721Semaste// Dump
951254721Semaste//
952254721Semaste// Dumps a debug information entry and all of it's attributes to the
953254721Semaste// specified stream.
954254721Semaste//----------------------------------------------------------------------
955254721Semastevoid
956254721SemasteDWARFDebugInfoEntry::Dump
957254721Semaste(
958254721Semaste    SymbolFileDWARF* dwarf2Data,
959254721Semaste    const DWARFCompileUnit* cu,
960254721Semaste    Stream &s,
961254721Semaste    uint32_t recurse_depth
962254721Semaste) const
963254721Semaste{
964258054Semaste    const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
965254721Semaste    lldb::offset_t offset = m_offset;
966254721Semaste
967254721Semaste    if (debug_info_data.ValidOffset(offset))
968254721Semaste    {
969254721Semaste        dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
970254721Semaste
971254721Semaste        s.Printf("\n0x%8.8x: ", m_offset);
972254721Semaste        s.Indent();
973254721Semaste        if (abbrCode != m_abbr_idx)
974254721Semaste        {
975254721Semaste            s.Printf( "error: DWARF has been modified\n");
976254721Semaste        }
977254721Semaste        else if (abbrCode)
978254721Semaste        {
979254721Semaste            const DWARFAbbreviationDeclaration* abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration (abbrCode);
980254721Semaste
981254721Semaste            if (abbrevDecl)
982254721Semaste            {
983254721Semaste                s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
984254721Semaste                s.Printf( " [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*':' ');
985254721Semaste
986254721Semaste                // Dump all data in the .debug_info for the attributes
987254721Semaste                const uint32_t numAttributes = abbrevDecl->NumAttributes();
988254721Semaste                uint32_t i;
989254721Semaste                dw_attr_t attr;
990254721Semaste                dw_form_t form;
991254721Semaste                for (i=0; i<numAttributes; ++i)
992254721Semaste                {
993254721Semaste                    abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
994254721Semaste
995254721Semaste                    DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form);
996254721Semaste                }
997254721Semaste
998254721Semaste                const DWARFDebugInfoEntry* child = GetFirstChild();
999254721Semaste                if (recurse_depth > 0 && child)
1000254721Semaste                {
1001254721Semaste                    s.IndentMore();
1002254721Semaste
1003254721Semaste                    while (child)
1004254721Semaste                    {
1005254721Semaste                        child->Dump(dwarf2Data, cu, s, recurse_depth-1);
1006254721Semaste                        child = child->GetSibling();
1007254721Semaste                    }
1008254721Semaste                    s.IndentLess();
1009254721Semaste                }
1010254721Semaste            }
1011254721Semaste            else
1012254721Semaste                s.Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode);
1013254721Semaste        }
1014254721Semaste        else
1015254721Semaste        {
1016254721Semaste            s.Printf( "NULL\n");
1017254721Semaste        }
1018254721Semaste    }
1019254721Semaste}
1020254721Semaste
1021254721Semastevoid
1022254721SemasteDWARFDebugInfoEntry::DumpLocation
1023254721Semaste(
1024254721Semaste    SymbolFileDWARF* dwarf2Data,
1025254721Semaste    DWARFCompileUnit* cu,
1026254721Semaste    Stream &s
1027254721Semaste) const
1028254721Semaste{
1029254721Semaste    const DWARFDebugInfoEntry *cu_die = cu->GetCompileUnitDIEOnly();
1030254721Semaste    const char *cu_name = NULL;
1031254721Semaste    if (cu_die != NULL)
1032254721Semaste        cu_name = cu_die->GetName (dwarf2Data, cu);
1033254721Semaste    const char *obj_file_name = NULL;
1034254721Semaste    ObjectFile *obj_file = dwarf2Data->GetObjectFile();
1035254721Semaste    if (obj_file)
1036254721Semaste        obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString();
1037254721Semaste    const char *die_name = GetName (dwarf2Data, cu);
1038254721Semaste    s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)",
1039254721Semaste              cu->GetOffset(),
1040254721Semaste              GetOffset(),
1041254721Semaste              die_name ? die_name : "",
1042254721Semaste              cu_name ? cu_name : "<NULL>",
1043254721Semaste              obj_file_name ? obj_file_name : "<NULL>");
1044254721Semaste}
1045254721Semaste
1046254721Semaste//----------------------------------------------------------------------
1047254721Semaste// DumpAttribute
1048254721Semaste//
1049254721Semaste// Dumps a debug information entry attribute along with it's form. Any
1050254721Semaste// special display of attributes is done (disassemble location lists,
1051254721Semaste// show enumeration values for attributes, etc).
1052254721Semaste//----------------------------------------------------------------------
1053254721Semastevoid
1054254721SemasteDWARFDebugInfoEntry::DumpAttribute
1055254721Semaste(
1056254721Semaste    SymbolFileDWARF* dwarf2Data,
1057254721Semaste    const DWARFCompileUnit* cu,
1058258054Semaste    const DWARFDataExtractor& debug_info_data,
1059254721Semaste    lldb::offset_t *offset_ptr,
1060254721Semaste    Stream &s,
1061254721Semaste    dw_attr_t attr,
1062254721Semaste    dw_form_t form
1063254721Semaste)
1064254721Semaste{
1065254721Semaste    bool verbose    = s.GetVerbose();
1066254721Semaste    bool show_form  = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
1067254721Semaste
1068258054Semaste    const DWARFDataExtractor* debug_str_data = dwarf2Data ? &dwarf2Data->get_debug_str_data() : NULL;
1069254721Semaste    if (verbose)
1070254721Semaste        s.Offset (*offset_ptr);
1071254721Semaste    else
1072254721Semaste        s.Printf ("            ");
1073254721Semaste    s.Indent(DW_AT_value_to_name(attr));
1074254721Semaste
1075254721Semaste    if (show_form)
1076254721Semaste    {
1077254721Semaste        s.Printf( "[%s", DW_FORM_value_to_name(form));
1078254721Semaste    }
1079254721Semaste
1080254721Semaste    DWARFFormValue form_value(form);
1081254721Semaste
1082254721Semaste    if (!form_value.ExtractValue(debug_info_data, offset_ptr, cu))
1083254721Semaste        return;
1084254721Semaste
1085254721Semaste    if (show_form)
1086254721Semaste    {
1087254721Semaste        if (form == DW_FORM_indirect)
1088254721Semaste        {
1089254721Semaste            s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form()));
1090254721Semaste        }
1091254721Semaste
1092254721Semaste        s.PutCString("] ");
1093254721Semaste    }
1094254721Semaste
1095254721Semaste    s.PutCString("( ");
1096254721Semaste
1097254721Semaste    // Always dump form value if verbose is enabled
1098254721Semaste    if (verbose)
1099254721Semaste    {
1100254721Semaste        form_value.Dump(s, debug_str_data, cu);
1101254721Semaste    }
1102254721Semaste
1103254721Semaste
1104254721Semaste    // Check to see if we have any special attribute formatters
1105254721Semaste    switch (attr)
1106254721Semaste    {
1107254721Semaste    case DW_AT_stmt_list:
1108254721Semaste        if ( verbose ) s.PutCString(" ( ");
1109254721Semaste        s.Printf( "0x%8.8" PRIx64, form_value.Unsigned());
1110254721Semaste        if ( verbose ) s.PutCString(" )");
1111254721Semaste        break;
1112254721Semaste
1113254721Semaste    case DW_AT_language:
1114254721Semaste        if ( verbose ) s.PutCString(" ( ");
1115254721Semaste        s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
1116254721Semaste        if ( verbose ) s.PutCString(" )");
1117254721Semaste        break;
1118254721Semaste
1119254721Semaste    case DW_AT_encoding:
1120254721Semaste        if ( verbose ) s.PutCString(" ( ");
1121254721Semaste        s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
1122254721Semaste        if ( verbose ) s.PutCString(" )");
1123254721Semaste        break;
1124254721Semaste
1125254721Semaste    case DW_AT_frame_base:
1126254721Semaste    case DW_AT_location:
1127254721Semaste    case DW_AT_data_member_location:
1128254721Semaste        {
1129254721Semaste            const uint8_t* blockData = form_value.BlockData();
1130254721Semaste            if (blockData)
1131254721Semaste            {
1132254721Semaste                if (!verbose)
1133254721Semaste                    form_value.Dump(s, debug_str_data, cu);
1134254721Semaste
1135254721Semaste                // Location description is inlined in data in the form value
1136258054Semaste                DWARFDataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned());
1137254721Semaste                if ( verbose ) s.PutCString(" ( ");
1138254721Semaste                print_dwarf_expression (s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
1139254721Semaste                if ( verbose ) s.PutCString(" )");
1140254721Semaste            }
1141254721Semaste            else
1142254721Semaste            {
1143254721Semaste                // We have a location list offset as the value that is
1144254721Semaste                // the offset into the .debug_loc section that describes
1145254721Semaste                // the value over it's lifetime
1146254721Semaste                uint64_t debug_loc_offset = form_value.Unsigned();
1147254721Semaste                if (dwarf2Data)
1148254721Semaste                {
1149254721Semaste                    if ( !verbose )
1150254721Semaste                        form_value.Dump(s, debug_str_data, cu);
1151254721Semaste                    DWARFLocationList::Dump(s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
1152254721Semaste                }
1153254721Semaste                else
1154254721Semaste                {
1155254721Semaste                    if ( !verbose )
1156254721Semaste                        form_value.Dump(s, NULL, cu);
1157254721Semaste                }
1158254721Semaste            }
1159254721Semaste        }
1160254721Semaste        break;
1161254721Semaste
1162254721Semaste    case DW_AT_abstract_origin:
1163254721Semaste    case DW_AT_specification:
1164254721Semaste        {
1165254721Semaste            uint64_t abstract_die_offset = form_value.Reference(cu);
1166254721Semaste            form_value.Dump(s, debug_str_data, cu);
1167254721Semaste        //  *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
1168254721Semaste            if ( verbose ) s.PutCString(" ( ");
1169254721Semaste            GetName(dwarf2Data, cu, abstract_die_offset, s);
1170254721Semaste            if ( verbose ) s.PutCString(" )");
1171254721Semaste        }
1172254721Semaste        break;
1173254721Semaste
1174254721Semaste    case DW_AT_type:
1175254721Semaste        {
1176254721Semaste            uint64_t type_die_offset = form_value.Reference(cu);
1177254721Semaste            if (!verbose)
1178254721Semaste                form_value.Dump(s, debug_str_data, cu);
1179254721Semaste            s.PutCString(" ( ");
1180254721Semaste            AppendTypeName(dwarf2Data, cu, type_die_offset, s);
1181254721Semaste            s.PutCString(" )");
1182254721Semaste        }
1183254721Semaste        break;
1184254721Semaste
1185254721Semaste    case DW_AT_ranges:
1186254721Semaste        {
1187254721Semaste            if ( !verbose )
1188254721Semaste                form_value.Dump(s, debug_str_data, cu);
1189254721Semaste            lldb::offset_t ranges_offset = form_value.Unsigned();
1190254721Semaste            dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
1191254721Semaste            if (dwarf2Data)
1192254721Semaste                DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
1193254721Semaste        }
1194254721Semaste        break;
1195254721Semaste
1196254721Semaste    default:
1197254721Semaste        if ( !verbose )
1198254721Semaste            form_value.Dump(s, debug_str_data, cu);
1199254721Semaste        break;
1200254721Semaste    }
1201254721Semaste
1202254721Semaste    s.PutCString(" )\n");
1203254721Semaste}
1204254721Semaste
1205254721Semaste//----------------------------------------------------------------------
1206254721Semaste// Get all attribute values for a given DIE, including following any
1207254721Semaste// specification or abstract origin attributes and including those in
1208254721Semaste// the results. Any duplicate attributes will have the first instance
1209254721Semaste// take precedence (this can happen for declaration attributes).
1210254721Semaste//----------------------------------------------------------------------
1211254721Semastesize_t
1212254721SemasteDWARFDebugInfoEntry::GetAttributes
1213254721Semaste(
1214254721Semaste    SymbolFileDWARF* dwarf2Data,
1215254721Semaste    const DWARFCompileUnit* cu,
1216254721Semaste    const uint8_t *fixed_form_sizes,
1217254721Semaste    DWARFDebugInfoEntry::Attributes& attributes,
1218254721Semaste    uint32_t curr_depth
1219254721Semaste) const
1220254721Semaste{
1221254721Semaste    lldb::offset_t offset;
1222254721Semaste    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
1223254721Semaste
1224254721Semaste    if (abbrevDecl)
1225254721Semaste    {
1226258054Semaste        const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
1227254721Semaste
1228254721Semaste        if (fixed_form_sizes == NULL)
1229254721Semaste            fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize());
1230254721Semaste
1231254721Semaste        const uint32_t num_attributes = abbrevDecl->NumAttributes();
1232254721Semaste        uint32_t i;
1233254721Semaste        dw_attr_t attr;
1234254721Semaste        dw_form_t form;
1235254721Semaste        DWARFFormValue form_value;
1236254721Semaste        for (i=0; i<num_attributes; ++i)
1237254721Semaste        {
1238254721Semaste            abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form);
1239254721Semaste
1240254721Semaste            // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
1241254721Semaste            // attributes, the depth will be non-zero. We need to omit certain
1242254721Semaste            // attributes that don't make sense.
1243254721Semaste            switch (attr)
1244254721Semaste            {
1245254721Semaste            case DW_AT_sibling:
1246254721Semaste            case DW_AT_declaration:
1247254721Semaste                if (curr_depth > 0)
1248254721Semaste                {
1249254721Semaste                    // This attribute doesn't make sense when combined with
1250254721Semaste                    // the DIE that references this DIE. We know a DIE is
1251254721Semaste                    // referencing this DIE because curr_depth is not zero
1252254721Semaste                    break;
1253254721Semaste                }
1254254721Semaste                // Fall through...
1255254721Semaste            default:
1256254721Semaste                attributes.Append(cu, offset, attr, form);
1257254721Semaste                break;
1258254721Semaste            }
1259254721Semaste
1260254721Semaste            if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))
1261254721Semaste            {
1262254721Semaste                form_value.SetForm(form);
1263254721Semaste                if (form_value.ExtractValue(debug_info_data, &offset, cu))
1264254721Semaste                {
1265254721Semaste                    const DWARFDebugInfoEntry* die = NULL;
1266254721Semaste                    dw_offset_t die_offset = form_value.Reference(cu);
1267254721Semaste                    if (cu->ContainsDIEOffset(die_offset))
1268254721Semaste                    {
1269254721Semaste                        die = const_cast<DWARFCompileUnit*>(cu)->GetDIEPtr(die_offset);
1270254721Semaste                        if (die)
1271254721Semaste                            die->GetAttributes(dwarf2Data, cu, fixed_form_sizes, attributes, curr_depth + 1);
1272254721Semaste                    }
1273254721Semaste                    else
1274254721Semaste                    {
1275254721Semaste                        DWARFCompileUnitSP cu_sp_ptr;
1276254721Semaste                        die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
1277254721Semaste                        if (die)
1278254721Semaste                            die->GetAttributes(dwarf2Data, cu_sp_ptr.get(), fixed_form_sizes, attributes, curr_depth + 1);
1279254721Semaste                    }
1280254721Semaste                }
1281254721Semaste            }
1282254721Semaste            else
1283254721Semaste            {
1284254721Semaste                const uint8_t fixed_skip_size = fixed_form_sizes [form];
1285254721Semaste                if (fixed_skip_size)
1286254721Semaste                    offset += fixed_skip_size;
1287254721Semaste                else
1288254721Semaste                    DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
1289254721Semaste            }
1290254721Semaste        }
1291254721Semaste    }
1292254721Semaste    else
1293254721Semaste    {
1294254721Semaste        attributes.Clear();
1295254721Semaste    }
1296254721Semaste    return attributes.Size();
1297254721Semaste
1298254721Semaste}
1299254721Semaste
1300254721Semaste//----------------------------------------------------------------------
1301254721Semaste// GetAttributeValue
1302254721Semaste//
1303254721Semaste// Get the value of an attribute and return the .debug_info offset of the
1304254721Semaste// attribute if it was properly extracted into form_value, or zero
1305254721Semaste// if we fail since an offset of zero is invalid for an attribute (it
1306254721Semaste// would be a compile unit header).
1307254721Semaste//----------------------------------------------------------------------
1308254721Semastedw_offset_t
1309254721SemasteDWARFDebugInfoEntry::GetAttributeValue
1310254721Semaste(
1311254721Semaste    SymbolFileDWARF* dwarf2Data,
1312254721Semaste    const DWARFCompileUnit* cu,
1313254721Semaste    const dw_attr_t attr,
1314254721Semaste    DWARFFormValue& form_value,
1315254721Semaste    dw_offset_t* end_attr_offset_ptr
1316254721Semaste) const
1317254721Semaste{
1318254721Semaste    lldb::offset_t offset;
1319254721Semaste    const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
1320254721Semaste
1321254721Semaste    if (abbrevDecl)
1322254721Semaste    {
1323254721Semaste        uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
1324254721Semaste
1325254721Semaste        if (attr_idx != DW_INVALID_INDEX)
1326254721Semaste        {
1327258054Semaste            const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
1328254721Semaste
1329254721Semaste            uint32_t idx=0;
1330254721Semaste            while (idx<attr_idx)
1331254721Semaste                DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu);
1332254721Semaste
1333254721Semaste            const dw_offset_t attr_offset = offset;
1334254721Semaste            form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
1335254721Semaste            if (form_value.ExtractValue(debug_info_data, &offset, cu))
1336254721Semaste            {
1337254721Semaste                if (end_attr_offset_ptr)
1338254721Semaste                    *end_attr_offset_ptr = offset;
1339254721Semaste                return attr_offset;
1340254721Semaste            }
1341254721Semaste        }
1342254721Semaste    }
1343254721Semaste
1344254721Semaste    return 0;
1345254721Semaste}
1346254721Semaste
1347254721Semaste//----------------------------------------------------------------------
1348254721Semaste// GetAttributeValueAsString
1349254721Semaste//
1350254721Semaste// Get the value of an attribute as a string return it. The resulting
1351254721Semaste// pointer to the string data exists within the supplied SymbolFileDWARF
1352254721Semaste// and will only be available as long as the SymbolFileDWARF is still around
1353254721Semaste// and it's content doesn't change.
1354254721Semaste//----------------------------------------------------------------------
1355254721Semasteconst char*
1356254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsString
1357254721Semaste(
1358254721Semaste    SymbolFileDWARF* dwarf2Data,
1359254721Semaste    const DWARFCompileUnit* cu,
1360254721Semaste    const dw_attr_t attr,
1361254721Semaste    const char* fail_value) const
1362254721Semaste{
1363254721Semaste    DWARFFormValue form_value;
1364254721Semaste    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1365254721Semaste        return form_value.AsCString(&dwarf2Data->get_debug_str_data());
1366254721Semaste    return fail_value;
1367254721Semaste}
1368254721Semaste
1369254721Semaste//----------------------------------------------------------------------
1370254721Semaste// GetAttributeValueAsUnsigned
1371254721Semaste//
1372254721Semaste// Get the value of an attribute as unsigned and return it.
1373254721Semaste//----------------------------------------------------------------------
1374254721Semasteuint64_t
1375254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsUnsigned
1376254721Semaste(
1377254721Semaste    SymbolFileDWARF* dwarf2Data,
1378254721Semaste    const DWARFCompileUnit* cu,
1379254721Semaste    const dw_attr_t attr,
1380254721Semaste    uint64_t fail_value
1381254721Semaste) const
1382254721Semaste{
1383254721Semaste    DWARFFormValue form_value;
1384254721Semaste    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1385254721Semaste        return form_value.Unsigned();
1386254721Semaste    return fail_value;
1387254721Semaste}
1388254721Semaste
1389254721Semaste//----------------------------------------------------------------------
1390254721Semaste// GetAttributeValueAsSigned
1391254721Semaste//
1392254721Semaste// Get the value of an attribute a signed value and return it.
1393254721Semaste//----------------------------------------------------------------------
1394254721Semasteint64_t
1395254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsSigned
1396254721Semaste(
1397254721Semaste    SymbolFileDWARF* dwarf2Data,
1398254721Semaste    const DWARFCompileUnit* cu,
1399254721Semaste    const dw_attr_t attr,
1400254721Semaste    int64_t fail_value
1401254721Semaste) const
1402254721Semaste{
1403254721Semaste    DWARFFormValue form_value;
1404254721Semaste    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1405254721Semaste        return form_value.Signed();
1406254721Semaste    return fail_value;
1407254721Semaste}
1408254721Semaste
1409254721Semaste//----------------------------------------------------------------------
1410254721Semaste// GetAttributeValueAsReference
1411254721Semaste//
1412254721Semaste// Get the value of an attribute as reference and fix up and compile
1413254721Semaste// unit relative offsets as needed.
1414254721Semaste//----------------------------------------------------------------------
1415254721Semasteuint64_t
1416254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsReference
1417254721Semaste(
1418254721Semaste    SymbolFileDWARF* dwarf2Data,
1419254721Semaste    const DWARFCompileUnit* cu,
1420254721Semaste    const dw_attr_t attr,
1421254721Semaste    uint64_t fail_value
1422254721Semaste) const
1423254721Semaste{
1424254721Semaste    DWARFFormValue form_value;
1425254721Semaste    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
1426254721Semaste        return form_value.Reference(cu);
1427254721Semaste    return fail_value;
1428254721Semaste}
1429254721Semaste
1430254721Semaste//----------------------------------------------------------------------
1431254721Semaste// GetAttributeHighPC
1432254721Semaste//
1433254721Semaste// Get the hi_pc, adding hi_pc to lo_pc when specified
1434254721Semaste// as an <offset-from-low-pc>.
1435254721Semaste//
1436254721Semaste// Returns the hi_pc or fail_value.
1437254721Semaste//----------------------------------------------------------------------
1438254721Semastedw_addr_t
1439254721SemasteDWARFDebugInfoEntry::GetAttributeHighPC
1440254721Semaste(
1441254721Semaste    SymbolFileDWARF* dwarf2Data,
1442254721Semaste    const DWARFCompileUnit* cu,
1443254721Semaste    dw_addr_t lo_pc,
1444254721Semaste    uint64_t fail_value
1445254721Semaste) const
1446254721Semaste{
1447254721Semaste    DWARFFormValue form_value;
1448254721Semaste
1449254721Semaste    if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value))
1450254721Semaste    {
1451254721Semaste        dw_addr_t hi_pc = form_value.Unsigned();
1452254721Semaste        if (form_value.Form() != DW_FORM_addr)
1453254721Semaste            hi_pc += lo_pc; // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
1454254721Semaste        return hi_pc;
1455254721Semaste    }
1456254721Semaste    return fail_value;
1457254721Semaste}
1458254721Semaste
1459254721Semaste//----------------------------------------------------------------------
1460254721Semaste// GetAttributeAddressRange
1461254721Semaste//
1462254721Semaste// Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified
1463254721Semaste// as an <offset-from-low-pc>.
1464254721Semaste//
1465254721Semaste// Returns true or sets lo_pc and hi_pc to fail_value.
1466254721Semaste//----------------------------------------------------------------------
1467254721Semastebool
1468254721SemasteDWARFDebugInfoEntry::GetAttributeAddressRange
1469254721Semaste(
1470254721Semaste    SymbolFileDWARF* dwarf2Data,
1471254721Semaste    const DWARFCompileUnit* cu,
1472254721Semaste    dw_addr_t& lo_pc,
1473254721Semaste    dw_addr_t& hi_pc,
1474254721Semaste    uint64_t fail_value
1475254721Semaste) const
1476254721Semaste{
1477254721Semaste    lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, fail_value);
1478254721Semaste    if (lo_pc != fail_value)
1479254721Semaste    {
1480254721Semaste        hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value);
1481254721Semaste        if (hi_pc != fail_value)
1482254721Semaste          return true;
1483254721Semaste    }
1484254721Semaste    lo_pc = fail_value;
1485254721Semaste    hi_pc = fail_value;
1486254721Semaste    return false;
1487254721Semaste}
1488276479Sdim
1489276479Sdimsize_t
1490276479SdimDWARFDebugInfoEntry::GetAttributeAddressRanges(SymbolFileDWARF* dwarf2Data,
1491276479Sdim                                               const DWARFCompileUnit* cu,
1492276479Sdim                                               DWARFDebugRanges::RangeList &ranges,
1493276479Sdim                                               bool check_hi_lo_pc) const
1494276479Sdim{
1495276479Sdim    ranges.Clear();
1496276479Sdim
1497276479Sdim    dw_offset_t ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
1498276479Sdim    if (ranges_offset != DW_INVALID_OFFSET)
1499276479Sdim    {
1500276479Sdim        dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
1501276479Sdim        if (debug_ranges_offset != DW_INVALID_OFFSET)
1502276479Sdim        {
1503276479Sdim            DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
1504276479Sdim
1505276479Sdim            debug_ranges->FindRanges(debug_ranges_offset, ranges);
1506276479Sdim            ranges.Slide (cu->GetBaseAddress());
1507276479Sdim        }
1508276479Sdim    }
1509276479Sdim    else if (check_hi_lo_pc)
1510276479Sdim    {
1511276479Sdim        dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1512276479Sdim        dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1513276479Sdim        if (GetAttributeAddressRange (dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
1514276479Sdim        {
1515276479Sdim            if (lo_pc < hi_pc)
1516276479Sdim                ranges.Append(DWARFDebugRanges::RangeList::Entry(lo_pc, hi_pc - lo_pc));
1517276479Sdim        }
1518276479Sdim    }
1519276479Sdim    return ranges.GetSize();
1520276479Sdim}
1521276479Sdim
1522254721Semaste//----------------------------------------------------------------------
1523254721Semaste// GetAttributeValueAsLocation
1524254721Semaste//
1525254721Semaste// Get the value of an attribute as reference and fix up and compile
1526254721Semaste// unit relative offsets as needed.
1527254721Semaste//----------------------------------------------------------------------
1528254721Semastedw_offset_t
1529254721SemasteDWARFDebugInfoEntry::GetAttributeValueAsLocation
1530254721Semaste(
1531254721Semaste    SymbolFileDWARF* dwarf2Data,
1532254721Semaste    const DWARFCompileUnit* cu,
1533254721Semaste    const dw_attr_t attr,
1534258054Semaste    DWARFDataExtractor& location_data,
1535254721Semaste    uint32_t &block_size
1536254721Semaste) const
1537254721Semaste{
1538254721Semaste    block_size = 0;
1539254721Semaste    DWARFFormValue form_value;
1540254721Semaste
1541254721Semaste    // Empty out data in case we don't find anything
1542254721Semaste    location_data.Clear();
1543254721Semaste    dw_offset_t end_addr_offset = DW_INVALID_OFFSET;
1544254721Semaste    const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset);
1545254721Semaste    if (attr_offset)
1546254721Semaste    {
1547254721Semaste        const uint8_t* blockData = form_value.BlockData();
1548254721Semaste        if (blockData)
1549254721Semaste        {
1550254721Semaste            // We have an inlined location list in the .debug_info section
1551258054Semaste            const DWARFDataExtractor& debug_info = dwarf2Data->get_debug_info_data();
1552254721Semaste            dw_offset_t block_offset = blockData - debug_info.GetDataStart();
1553254721Semaste            block_size = (end_addr_offset - attr_offset) - form_value.Unsigned();
1554254721Semaste            location_data.SetData(debug_info, block_offset, block_size);
1555254721Semaste        }
1556254721Semaste        else
1557254721Semaste        {
1558254721Semaste            // We have a location list offset as the value that is
1559254721Semaste            // the offset into the .debug_loc section that describes
1560254721Semaste            // the value over it's lifetime
1561254721Semaste            lldb::offset_t debug_loc_offset = form_value.Unsigned();
1562254721Semaste            if (dwarf2Data)
1563254721Semaste            {
1564254721Semaste                assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
1565254721Semaste                return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data);
1566254721Semaste            }
1567254721Semaste        }
1568254721Semaste    }
1569254721Semaste    return attr_offset;
1570254721Semaste}
1571254721Semaste
1572254721Semaste//----------------------------------------------------------------------
1573254721Semaste// GetName
1574254721Semaste//
1575254721Semaste// Get value of the DW_AT_name attribute and return it if one exists,
1576254721Semaste// else return NULL.
1577254721Semaste//----------------------------------------------------------------------
1578254721Semasteconst char*
1579254721SemasteDWARFDebugInfoEntry::GetName
1580254721Semaste(
1581254721Semaste    SymbolFileDWARF* dwarf2Data,
1582254721Semaste    const DWARFCompileUnit* cu
1583254721Semaste) const
1584254721Semaste{
1585254721Semaste    DWARFFormValue form_value;
1586254721Semaste    if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1587254721Semaste        return form_value.AsCString(&dwarf2Data->get_debug_str_data());
1588254721Semaste    else
1589254721Semaste    {
1590254721Semaste        if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
1591254721Semaste        {
1592254721Semaste            DWARFCompileUnitSP cu_sp_ptr;
1593254721Semaste            const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr);
1594254721Semaste            if (die)
1595254721Semaste                return die->GetName(dwarf2Data, cu_sp_ptr.get());
1596254721Semaste        }
1597254721Semaste    }
1598254721Semaste    return NULL;
1599254721Semaste}
1600254721Semaste
1601254721Semaste
1602254721Semaste//----------------------------------------------------------------------
1603254721Semaste// GetMangledName
1604254721Semaste//
1605254721Semaste// Get value of the DW_AT_MIPS_linkage_name attribute and return it if
1606254721Semaste// one exists, else return the value of the DW_AT_name attribute
1607254721Semaste//----------------------------------------------------------------------
1608254721Semasteconst char*
1609254721SemasteDWARFDebugInfoEntry::GetMangledName
1610254721Semaste(
1611254721Semaste    SymbolFileDWARF* dwarf2Data,
1612254721Semaste    const DWARFCompileUnit* cu,
1613254721Semaste    bool substitute_name_allowed
1614254721Semaste) const
1615254721Semaste{
1616254721Semaste    const char* name = NULL;
1617254721Semaste    DWARFFormValue form_value;
1618254721Semaste
1619254721Semaste    if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
1620254721Semaste        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1621254721Semaste
1622254721Semaste    if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
1623254721Semaste        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1624254721Semaste
1625254721Semaste    if (substitute_name_allowed && name == NULL)
1626254721Semaste    {
1627254721Semaste        if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1628254721Semaste            name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1629254721Semaste    }
1630254721Semaste    return name;
1631254721Semaste}
1632254721Semaste
1633254721Semaste
1634254721Semaste//----------------------------------------------------------------------
1635254721Semaste// GetPubname
1636254721Semaste//
1637254721Semaste// Get value the name for a DIE as it should appear for a
1638254721Semaste// .debug_pubnames or .debug_pubtypes section.
1639254721Semaste//----------------------------------------------------------------------
1640254721Semasteconst char*
1641254721SemasteDWARFDebugInfoEntry::GetPubname
1642254721Semaste(
1643254721Semaste    SymbolFileDWARF* dwarf2Data,
1644254721Semaste    const DWARFCompileUnit* cu
1645254721Semaste) const
1646254721Semaste{
1647254721Semaste    const char* name = NULL;
1648254721Semaste    if (!dwarf2Data)
1649254721Semaste        return name;
1650254721Semaste
1651254721Semaste    DWARFFormValue form_value;
1652254721Semaste
1653254721Semaste    if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
1654254721Semaste        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1655254721Semaste    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
1656254721Semaste        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1657254721Semaste    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1658254721Semaste        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1659254721Semaste    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
1660254721Semaste    {
1661254721Semaste        // The specification DIE may be in another compile unit so we need
1662254721Semaste        // to get a die and its compile unit.
1663254721Semaste        DWARFCompileUnitSP cu_sp_ptr;
1664254721Semaste        const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr);
1665254721Semaste        if (die)
1666254721Semaste            return die->GetPubname(dwarf2Data, cu_sp_ptr.get());
1667254721Semaste    }
1668254721Semaste    return name;
1669254721Semaste}
1670254721Semaste
1671254721Semaste
1672254721Semaste//----------------------------------------------------------------------
1673254721Semaste// GetName
1674254721Semaste//
1675254721Semaste// Get value of the DW_AT_name attribute for a debug information entry
1676254721Semaste// that exists at offset "die_offset" and place that value into the
1677254721Semaste// supplied stream object. If the DIE is a NULL object "NULL" is placed
1678254721Semaste// into the stream, and if no DW_AT_name attribute exists for the DIE
1679254721Semaste// then nothing is printed.
1680254721Semaste//----------------------------------------------------------------------
1681254721Semastebool
1682254721SemasteDWARFDebugInfoEntry::GetName
1683254721Semaste(
1684254721Semaste    SymbolFileDWARF* dwarf2Data,
1685254721Semaste    const DWARFCompileUnit* cu,
1686254721Semaste    const dw_offset_t die_offset,
1687254721Semaste    Stream &s
1688254721Semaste)
1689254721Semaste{
1690254721Semaste    if (dwarf2Data == NULL)
1691254721Semaste    {
1692254721Semaste        s.PutCString("NULL");
1693254721Semaste        return false;
1694254721Semaste    }
1695254721Semaste
1696254721Semaste    DWARFDebugInfoEntry die;
1697254721Semaste    lldb::offset_t offset = die_offset;
1698254721Semaste    if (die.Extract(dwarf2Data, cu, &offset))
1699254721Semaste    {
1700254721Semaste        if (die.IsNULL())
1701254721Semaste        {
1702254721Semaste            s.PutCString("NULL");
1703254721Semaste            return true;
1704254721Semaste        }
1705254721Semaste        else
1706254721Semaste        {
1707254721Semaste            DWARFFormValue form_value;
1708254721Semaste            if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1709254721Semaste            {
1710254721Semaste                const char* name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1711254721Semaste                if (name)
1712254721Semaste                {
1713254721Semaste                    s.PutCString(name);
1714254721Semaste                    return true;
1715254721Semaste                }
1716254721Semaste            }
1717254721Semaste        }
1718254721Semaste    }
1719254721Semaste    return false;
1720254721Semaste}
1721254721Semaste
1722254721Semaste//----------------------------------------------------------------------
1723254721Semaste// AppendTypeName
1724254721Semaste//
1725254721Semaste// Follows the type name definition down through all needed tags to
1726254721Semaste// end up with a fully qualified type name and dump the results to
1727254721Semaste// the supplied stream. This is used to show the name of types given
1728254721Semaste// a type identifier.
1729254721Semaste//----------------------------------------------------------------------
1730254721Semastebool
1731254721SemasteDWARFDebugInfoEntry::AppendTypeName
1732254721Semaste(
1733254721Semaste    SymbolFileDWARF* dwarf2Data,
1734254721Semaste    const DWARFCompileUnit* cu,
1735254721Semaste    const dw_offset_t die_offset,
1736254721Semaste    Stream &s
1737254721Semaste)
1738254721Semaste{
1739254721Semaste    if (dwarf2Data == NULL)
1740254721Semaste    {
1741254721Semaste        s.PutCString("NULL");
1742254721Semaste        return false;
1743254721Semaste    }
1744254721Semaste
1745254721Semaste    DWARFDebugInfoEntry die;
1746254721Semaste    lldb::offset_t offset = die_offset;
1747254721Semaste    if (die.Extract(dwarf2Data, cu, &offset))
1748254721Semaste    {
1749254721Semaste        if (die.IsNULL())
1750254721Semaste        {
1751254721Semaste            s.PutCString("NULL");
1752254721Semaste            return true;
1753254721Semaste        }
1754254721Semaste        else
1755254721Semaste        {
1756254721Semaste            const char* name = die.GetPubname(dwarf2Data, cu);
1757254721Semaste        //  if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
1758254721Semaste        //      name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
1759254721Semaste            if (name)
1760254721Semaste                s.PutCString(name);
1761254721Semaste            else
1762254721Semaste            {
1763254721Semaste                bool result = true;
1764254721Semaste                const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
1765254721Semaste
1766254721Semaste                if (abbrevDecl == NULL)
1767254721Semaste                    return false;
1768254721Semaste
1769254721Semaste                switch (abbrevDecl->Tag())
1770254721Semaste                {
1771254721Semaste                case DW_TAG_array_type:         break;  // print out a "[]" after printing the full type of the element below
1772254721Semaste                case DW_TAG_base_type:          s.PutCString("base ");         break;
1773254721Semaste                case DW_TAG_class_type:         s.PutCString("class ");            break;
1774254721Semaste                case DW_TAG_const_type:         s.PutCString("const ");            break;
1775254721Semaste                case DW_TAG_enumeration_type:   s.PutCString("enum ");         break;
1776254721Semaste                case DW_TAG_file_type:          s.PutCString("file ");         break;
1777254721Semaste                case DW_TAG_interface_type:     s.PutCString("interface ");        break;
1778254721Semaste                case DW_TAG_packed_type:        s.PutCString("packed ");       break;
1779254721Semaste                case DW_TAG_pointer_type:       break;  // print out a '*' after printing the full type below
1780254721Semaste                case DW_TAG_ptr_to_member_type: break;  // print out a '*' after printing the full type below
1781254721Semaste                case DW_TAG_reference_type:     break;  // print out a '&' after printing the full type below
1782254721Semaste                case DW_TAG_restrict_type:      s.PutCString("restrict ");     break;
1783254721Semaste                case DW_TAG_set_type:           s.PutCString("set ");          break;
1784254721Semaste                case DW_TAG_shared_type:        s.PutCString("shared ");       break;
1785254721Semaste                case DW_TAG_string_type:        s.PutCString("string ");       break;
1786254721Semaste                case DW_TAG_structure_type:     s.PutCString("struct ");       break;
1787254721Semaste                case DW_TAG_subrange_type:      s.PutCString("subrange ");     break;
1788254721Semaste                case DW_TAG_subroutine_type:    s.PutCString("function ");     break;
1789254721Semaste                case DW_TAG_thrown_type:        s.PutCString("thrown ");       break;
1790254721Semaste                case DW_TAG_union_type:         s.PutCString("union ");            break;
1791254721Semaste                case DW_TAG_unspecified_type:   s.PutCString("unspecified ");  break;
1792254721Semaste                case DW_TAG_volatile_type:      s.PutCString("volatile ");     break;
1793254721Semaste                default:
1794254721Semaste                    return false;
1795254721Semaste                }
1796254721Semaste
1797254721Semaste                // Follow the DW_AT_type if possible
1798254721Semaste                DWARFFormValue form_value;
1799254721Semaste                if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value))
1800254721Semaste                {
1801254721Semaste                    uint64_t next_die_offset = form_value.Reference(cu);
1802254721Semaste                    result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
1803254721Semaste                }
1804254721Semaste
1805254721Semaste                switch (abbrevDecl->Tag())
1806254721Semaste                {
1807254721Semaste                case DW_TAG_array_type:         s.PutCString("[]");    break;
1808254721Semaste                case DW_TAG_pointer_type:       s.PutChar('*');    break;
1809254721Semaste                case DW_TAG_ptr_to_member_type: s.PutChar('*');    break;
1810254721Semaste                case DW_TAG_reference_type:     s.PutChar('&');    break;
1811254721Semaste                default:
1812254721Semaste                    break;
1813254721Semaste                }
1814254721Semaste                return result;
1815254721Semaste            }
1816254721Semaste        }
1817254721Semaste    }
1818254721Semaste    return false;
1819254721Semaste}
1820254721Semaste
1821254721Semastebool
1822254721SemasteDWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const
1823254721Semaste{
1824254721Semaste    if (die)
1825254721Semaste    {
1826254721Semaste        const dw_offset_t die_offset = die->GetOffset();
1827254721Semaste        if (die_offset > GetOffset())
1828254721Semaste        {
1829254721Semaste            const DWARFDebugInfoEntry *sibling = GetSibling();
1830254721Semaste            assert (sibling); // TODO: take this out
1831254721Semaste            if (sibling)
1832254721Semaste                return die_offset < sibling->GetOffset();
1833254721Semaste        }
1834254721Semaste    }
1835254721Semaste    return false;
1836254721Semaste}
1837254721Semaste
1838254721Semaste//----------------------------------------------------------------------
1839254721Semaste// BuildAddressRangeTable
1840254721Semaste//----------------------------------------------------------------------
1841254721Semastevoid
1842254721SemasteDWARFDebugInfoEntry::BuildAddressRangeTable
1843254721Semaste(
1844254721Semaste    SymbolFileDWARF* dwarf2Data,
1845254721Semaste    const DWARFCompileUnit* cu,
1846254721Semaste    DWARFDebugAranges* debug_aranges
1847254721Semaste) const
1848254721Semaste{
1849254721Semaste    if (m_tag)
1850254721Semaste    {
1851254721Semaste        if (m_tag == DW_TAG_subprogram)
1852254721Semaste        {
1853254721Semaste            dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1854254721Semaste            dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1855254721Semaste            if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
1856254721Semaste            {
1857254721Semaste                /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
1858254721Semaste                debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc);
1859254721Semaste            }
1860254721Semaste        }
1861254721Semaste
1862254721Semaste
1863254721Semaste        const DWARFDebugInfoEntry* child = GetFirstChild();
1864254721Semaste        while (child)
1865254721Semaste        {
1866254721Semaste            child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
1867254721Semaste            child = child->GetSibling();
1868254721Semaste        }
1869254721Semaste    }
1870254721Semaste}
1871254721Semaste
1872254721Semaste//----------------------------------------------------------------------
1873254721Semaste// BuildFunctionAddressRangeTable
1874254721Semaste//
1875254721Semaste// This function is very similar to the BuildAddressRangeTable function
1876254721Semaste// except that the actual DIE offset for the function is placed in the
1877254721Semaste// table instead of the compile unit offset (which is the way the
1878254721Semaste// standard .debug_aranges section does it).
1879254721Semaste//----------------------------------------------------------------------
1880254721Semastevoid
1881254721SemasteDWARFDebugInfoEntry::BuildFunctionAddressRangeTable
1882254721Semaste(
1883254721Semaste    SymbolFileDWARF* dwarf2Data,
1884254721Semaste    const DWARFCompileUnit* cu,
1885254721Semaste    DWARFDebugAranges* debug_aranges
1886254721Semaste) const
1887254721Semaste{
1888254721Semaste    if (m_tag)
1889254721Semaste    {
1890254721Semaste        if (m_tag == DW_TAG_subprogram)
1891254721Semaste        {
1892254721Semaste            dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
1893254721Semaste            dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
1894254721Semaste            if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
1895254721Semaste            {
1896254721Semaste            //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
1897254721Semaste                debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc);
1898254721Semaste            }
1899254721Semaste        }
1900254721Semaste
1901254721Semaste        const DWARFDebugInfoEntry* child = GetFirstChild();
1902254721Semaste        while (child)
1903254721Semaste        {
1904254721Semaste            child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
1905254721Semaste            child = child->GetSibling();
1906254721Semaste        }
1907254721Semaste    }
1908254721Semaste}
1909254721Semaste
1910254721Semastevoid
1911254721SemasteDWARFDebugInfoEntry::GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data,
1912254721Semaste                                         DWARFCompileUnit* cu,
1913254721Semaste                                         DWARFDIECollection &decl_context_dies) const
1914254721Semaste{
1915254721Semaste    const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
1916254721Semaste    if (parent_decl_ctx_die && parent_decl_ctx_die != this)
1917254721Semaste    {
1918254721Semaste        decl_context_dies.Append(parent_decl_ctx_die);
1919254721Semaste        parent_decl_ctx_die->GetDeclContextDIEs (dwarf2Data, cu, decl_context_dies);
1920254721Semaste    }
1921254721Semaste}
1922254721Semaste
1923254721Semastevoid
1924254721SemasteDWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
1925254721Semaste                                          DWARFCompileUnit* cu,
1926254721Semaste                                          DWARFDeclContext &dwarf_decl_ctx) const
1927254721Semaste{
1928254721Semaste    const dw_tag_t tag = Tag();
1929254721Semaste    if (tag != DW_TAG_compile_unit)
1930254721Semaste    {
1931254721Semaste        dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
1932254721Semaste        const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
1933254721Semaste        if (parent_decl_ctx_die && parent_decl_ctx_die != this)
1934254721Semaste        {
1935254721Semaste            if (parent_decl_ctx_die->Tag() != DW_TAG_compile_unit)
1936254721Semaste                parent_decl_ctx_die->GetDWARFDeclContext (dwarf2Data, cu, dwarf_decl_ctx);
1937254721Semaste        }
1938254721Semaste    }
1939254721Semaste}
1940254721Semaste
1941254721Semaste
1942254721Semastebool
1943254721SemasteDWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
1944254721Semaste                                              DWARFCompileUnit* cu,
1945254721Semaste                                              const DWARFDeclContext &dwarf_decl_ctx) const
1946254721Semaste{
1947254721Semaste
1948254721Semaste    DWARFDeclContext this_dwarf_decl_ctx;
1949254721Semaste    GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx);
1950254721Semaste    return this_dwarf_decl_ctx == dwarf_decl_ctx;
1951254721Semaste}
1952254721Semaste
1953254721Semasteconst DWARFDebugInfoEntry *
1954254721SemasteDWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
1955254721Semaste											  DWARFCompileUnit* cu) const
1956254721Semaste{
1957254721Semaste	DWARFDebugInfoEntry::Attributes attributes;
1958254721Semaste	GetAttributes(dwarf2Data, cu, NULL, attributes);
1959254721Semaste	return GetParentDeclContextDIE (dwarf2Data, cu, attributes);
1960254721Semaste}
1961254721Semaste
1962254721Semasteconst DWARFDebugInfoEntry *
1963254721SemasteDWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
1964254721Semaste											  DWARFCompileUnit* cu,
1965254721Semaste											  const DWARFDebugInfoEntry::Attributes& attributes) const
1966254721Semaste{
1967254721Semaste	const DWARFDebugInfoEntry * die = this;
1968254721Semaste
1969254721Semaste	while (die != NULL)
1970254721Semaste	{
1971254721Semaste		// If this is the original DIE that we are searching for a declaration
1972254721Semaste		// for, then don't look in the cache as we don't want our own decl
1973254721Semaste		// context to be our decl context...
1974254721Semaste		if (die != this)
1975254721Semaste		{
1976254721Semaste			switch (die->Tag())
1977254721Semaste			{
1978254721Semaste				case DW_TAG_compile_unit:
1979254721Semaste				case DW_TAG_namespace:
1980254721Semaste				case DW_TAG_structure_type:
1981254721Semaste				case DW_TAG_union_type:
1982254721Semaste				case DW_TAG_class_type:
1983254721Semaste					return die;
1984254721Semaste
1985254721Semaste				default:
1986254721Semaste					break;
1987254721Semaste			}
1988254721Semaste		}
1989254721Semaste
1990254721Semaste		dw_offset_t die_offset;
1991254721Semaste
1992254721Semaste		die_offset = attributes.FormValueAsUnsigned(dwarf2Data, DW_AT_specification, DW_INVALID_OFFSET);
1993254721Semaste		if (die_offset != DW_INVALID_OFFSET)
1994254721Semaste		{
1995254721Semaste			const DWARFDebugInfoEntry *spec_die = cu->GetDIEPtr (die_offset);
1996254721Semaste			if (spec_die)
1997254721Semaste			{
1998254721Semaste				const DWARFDebugInfoEntry *spec_die_decl_ctx_die = spec_die->GetParentDeclContextDIE (dwarf2Data, cu);
1999254721Semaste				if (spec_die_decl_ctx_die)
2000254721Semaste					return spec_die_decl_ctx_die;
2001254721Semaste			}
2002254721Semaste		}
2003254721Semaste
2004254721Semaste        die_offset = attributes.FormValueAsUnsigned(dwarf2Data, DW_AT_abstract_origin, DW_INVALID_OFFSET);
2005254721Semaste		if (die_offset != DW_INVALID_OFFSET)
2006254721Semaste		{
2007254721Semaste			const DWARFDebugInfoEntry *abs_die = cu->GetDIEPtr (die_offset);
2008254721Semaste			if (abs_die)
2009254721Semaste			{
2010254721Semaste				const DWARFDebugInfoEntry *abs_die_decl_ctx_die = abs_die->GetParentDeclContextDIE (dwarf2Data, cu);
2011254721Semaste				if (abs_die_decl_ctx_die)
2012254721Semaste					return abs_die_decl_ctx_die;
2013254721Semaste			}
2014254721Semaste		}
2015254721Semaste
2016254721Semaste		die = die->GetParent();
2017254721Semaste	}
2018254721Semaste    return NULL;
2019254721Semaste}
2020254721Semaste
2021254721Semaste
2022254721Semasteconst char *
2023254721SemasteDWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
2024254721Semaste									   DWARFCompileUnit* cu,
2025254721Semaste									   std::string &storage) const
2026254721Semaste{
2027254721Semaste	DWARFDebugInfoEntry::Attributes attributes;
2028254721Semaste	GetAttributes(dwarf2Data, cu, NULL, attributes);
2029254721Semaste	return GetQualifiedName (dwarf2Data, cu, attributes, storage);
2030254721Semaste}
2031254721Semaste
2032254721Semasteconst char*
2033254721SemasteDWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
2034254721Semaste									   DWARFCompileUnit* cu,
2035254721Semaste									   const DWARFDebugInfoEntry::Attributes& attributes,
2036254721Semaste									   std::string &storage) const
2037254721Semaste{
2038254721Semaste
2039254721Semaste	const char *name = GetName (dwarf2Data, cu);
2040254721Semaste
2041254721Semaste	if (name)
2042254721Semaste	{
2043254721Semaste		const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
2044254721Semaste		storage.clear();
2045254721Semaste		// TODO: change this to get the correct decl context parent....
2046254721Semaste		while (parent_decl_ctx_die)
2047254721Semaste		{
2048254721Semaste			const dw_tag_t parent_tag = parent_decl_ctx_die->Tag();
2049254721Semaste			switch (parent_tag)
2050254721Semaste			{
2051254721Semaste                case DW_TAG_namespace:
2052254721Semaste				{
2053254721Semaste					const char *namespace_name = parent_decl_ctx_die->GetName (dwarf2Data, cu);
2054254721Semaste					if (namespace_name)
2055254721Semaste					{
2056254721Semaste						storage.insert (0, "::");
2057254721Semaste						storage.insert (0, namespace_name);
2058254721Semaste					}
2059254721Semaste					else
2060254721Semaste					{
2061254721Semaste						storage.insert (0, "(anonymous namespace)::");
2062254721Semaste					}
2063254721Semaste					parent_decl_ctx_die = parent_decl_ctx_die->GetParentDeclContextDIE(dwarf2Data, cu);
2064254721Semaste				}
2065254721Semaste                    break;
2066254721Semaste
2067254721Semaste                case DW_TAG_class_type:
2068254721Semaste                case DW_TAG_structure_type:
2069254721Semaste                case DW_TAG_union_type:
2070254721Semaste				{
2071254721Semaste					const char *class_union_struct_name = parent_decl_ctx_die->GetName (dwarf2Data, cu);
2072254721Semaste
2073254721Semaste					if (class_union_struct_name)
2074254721Semaste					{
2075254721Semaste						storage.insert (0, "::");
2076254721Semaste						storage.insert (0, class_union_struct_name);
2077254721Semaste					}
2078254721Semaste					parent_decl_ctx_die = parent_decl_ctx_die->GetParentDeclContextDIE(dwarf2Data, cu);
2079254721Semaste				}
2080254721Semaste                    break;
2081254721Semaste
2082254721Semaste                default:
2083254721Semaste                    parent_decl_ctx_die = NULL;
2084254721Semaste                    break;
2085254721Semaste			}
2086254721Semaste		}
2087254721Semaste
2088254721Semaste		if (storage.empty())
2089254721Semaste			storage.append ("::");
2090254721Semaste
2091254721Semaste		storage.append (name);
2092254721Semaste	}
2093254721Semaste	if (storage.empty())
2094254721Semaste		return NULL;
2095254721Semaste	return storage.c_str();
2096254721Semaste}
2097254721Semaste
2098254721Semaste
2099254721Semaste//----------------------------------------------------------------------
2100254721Semaste// LookupAddress
2101254721Semaste//----------------------------------------------------------------------
2102254721Semastebool
2103254721SemasteDWARFDebugInfoEntry::LookupAddress
2104254721Semaste(
2105254721Semaste    const dw_addr_t address,
2106254721Semaste    SymbolFileDWARF* dwarf2Data,
2107254721Semaste    const DWARFCompileUnit* cu,
2108254721Semaste    DWARFDebugInfoEntry** function_die,
2109254721Semaste    DWARFDebugInfoEntry** block_die
2110254721Semaste)
2111254721Semaste{
2112254721Semaste    bool found_address = false;
2113254721Semaste    if (m_tag)
2114254721Semaste    {
2115254721Semaste        bool check_children = false;
2116254721Semaste        bool match_addr_range = false;
2117254721Semaste    //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address);
2118254721Semaste        switch (m_tag)
2119254721Semaste        {
2120254721Semaste        case DW_TAG_array_type                 : break;
2121254721Semaste        case DW_TAG_class_type                 : check_children = true; break;
2122254721Semaste        case DW_TAG_entry_point                : break;
2123254721Semaste        case DW_TAG_enumeration_type           : break;
2124254721Semaste        case DW_TAG_formal_parameter           : break;
2125254721Semaste        case DW_TAG_imported_declaration       : break;
2126254721Semaste        case DW_TAG_label                      : break;
2127254721Semaste        case DW_TAG_lexical_block              : check_children = true; match_addr_range = true; break;
2128254721Semaste        case DW_TAG_member                     : break;
2129254721Semaste        case DW_TAG_pointer_type               : break;
2130254721Semaste        case DW_TAG_reference_type             : break;
2131254721Semaste        case DW_TAG_compile_unit               : match_addr_range = true; break;
2132254721Semaste        case DW_TAG_string_type                : break;
2133254721Semaste        case DW_TAG_structure_type             : check_children = true; break;
2134254721Semaste        case DW_TAG_subroutine_type            : break;
2135254721Semaste        case DW_TAG_typedef                    : break;
2136254721Semaste        case DW_TAG_union_type                 : break;
2137254721Semaste        case DW_TAG_unspecified_parameters     : break;
2138254721Semaste        case DW_TAG_variant                    : break;
2139254721Semaste        case DW_TAG_common_block               : check_children = true; break;
2140254721Semaste        case DW_TAG_common_inclusion           : break;
2141254721Semaste        case DW_TAG_inheritance                : break;
2142254721Semaste        case DW_TAG_inlined_subroutine         : check_children = true; match_addr_range = true; break;
2143254721Semaste        case DW_TAG_module                     : match_addr_range = true; break;
2144254721Semaste        case DW_TAG_ptr_to_member_type         : break;
2145254721Semaste        case DW_TAG_set_type                   : break;
2146254721Semaste        case DW_TAG_subrange_type              : break;
2147254721Semaste        case DW_TAG_with_stmt                  : break;
2148254721Semaste        case DW_TAG_access_declaration         : break;
2149254721Semaste        case DW_TAG_base_type                  : break;
2150254721Semaste        case DW_TAG_catch_block                : match_addr_range = true; break;
2151254721Semaste        case DW_TAG_const_type                 : break;
2152254721Semaste        case DW_TAG_constant                   : break;
2153254721Semaste        case DW_TAG_enumerator                 : break;
2154254721Semaste        case DW_TAG_file_type                  : break;
2155254721Semaste        case DW_TAG_friend                     : break;
2156254721Semaste        case DW_TAG_namelist                   : break;
2157254721Semaste        case DW_TAG_namelist_item              : break;
2158254721Semaste        case DW_TAG_packed_type                : break;
2159254721Semaste        case DW_TAG_subprogram                 : match_addr_range = true; break;
2160254721Semaste        case DW_TAG_template_type_parameter    : break;
2161254721Semaste        case DW_TAG_template_value_parameter   : break;
2162254721Semaste        case DW_TAG_thrown_type                : break;
2163254721Semaste        case DW_TAG_try_block                  : match_addr_range = true; break;
2164254721Semaste        case DW_TAG_variant_part               : break;
2165254721Semaste        case DW_TAG_variable                   : break;
2166254721Semaste        case DW_TAG_volatile_type              : break;
2167254721Semaste        case DW_TAG_dwarf_procedure            : break;
2168254721Semaste        case DW_TAG_restrict_type              : break;
2169254721Semaste        case DW_TAG_interface_type             : break;
2170254721Semaste        case DW_TAG_namespace                  : check_children = true; break;
2171254721Semaste        case DW_TAG_imported_module            : break;
2172254721Semaste        case DW_TAG_unspecified_type           : break;
2173254721Semaste        case DW_TAG_partial_unit               : break;
2174254721Semaste        case DW_TAG_imported_unit              : break;
2175254721Semaste        case DW_TAG_shared_type                : break;
2176254721Semaste        default: break;
2177254721Semaste        }
2178254721Semaste
2179254721Semaste        if (match_addr_range)
2180254721Semaste        {
2181254721Semaste            dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
2182254721Semaste            if (lo_pc != LLDB_INVALID_ADDRESS)
2183254721Semaste            {
2184254721Semaste                dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
2185254721Semaste                if (hi_pc != LLDB_INVALID_ADDRESS)
2186254721Semaste                {
2187254721Semaste                    //  printf("\n0x%8.8x: %30s: address = 0x%8.8x  [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
2188254721Semaste                    if ((lo_pc <= address) && (address < hi_pc))
2189254721Semaste                    {
2190254721Semaste                        found_address = true;
2191254721Semaste                    //  puts("***MATCH***");
2192254721Semaste                        switch (m_tag)
2193254721Semaste                        {
2194254721Semaste                        case DW_TAG_compile_unit:       // File
2195254721Semaste                            check_children = ((function_die != NULL) || (block_die != NULL));
2196254721Semaste                            break;
2197254721Semaste
2198254721Semaste                        case DW_TAG_subprogram:         // Function
2199254721Semaste                            if (function_die)
2200254721Semaste                                *function_die = this;
2201254721Semaste                            check_children = (block_die != NULL);
2202254721Semaste                            break;
2203254721Semaste
2204254721Semaste                        case DW_TAG_inlined_subroutine: // Inlined Function
2205254721Semaste                        case DW_TAG_lexical_block:      // Block { } in code
2206254721Semaste                            if (block_die)
2207254721Semaste                            {
2208254721Semaste                                *block_die = this;
2209254721Semaste                                check_children = true;
2210254721Semaste                            }
2211254721Semaste                            break;
2212254721Semaste
2213254721Semaste                        default:
2214254721Semaste                            check_children = true;
2215254721Semaste                            break;
2216254721Semaste                        }
2217254721Semaste                    }
2218254721Semaste                }
2219254721Semaste                else
2220254721Semaste                {   // compile units may not have a valid high/low pc when there
2221254721Semaste                    // are address gaps in subroutines so we must always search
2222254721Semaste                    // if there is no valid high and low PC
2223254721Semaste                    check_children = (m_tag == DW_TAG_compile_unit) && ((function_die != NULL) || (block_die != NULL));
2224254721Semaste                }
2225254721Semaste            }
2226254721Semaste            else
2227254721Semaste            {
2228254721Semaste                dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
2229254721Semaste                if (debug_ranges_offset != DW_INVALID_OFFSET)
2230254721Semaste                {
2231254721Semaste                    DWARFDebugRanges::RangeList ranges;
2232254721Semaste                    DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
2233254721Semaste                    debug_ranges->FindRanges(debug_ranges_offset, ranges);
2234254721Semaste                    // All DW_AT_ranges are relative to the base address of the
2235254721Semaste                    // compile unit. We add the compile unit base address to make
2236254721Semaste                    // sure all the addresses are properly fixed up.
2237254721Semaste                    ranges.Slide (cu->GetBaseAddress());
2238254721Semaste                    if (ranges.FindEntryThatContains(address))
2239254721Semaste                    {
2240254721Semaste                        found_address = true;
2241254721Semaste                    //  puts("***MATCH***");
2242254721Semaste                        switch (m_tag)
2243254721Semaste                        {
2244254721Semaste                        case DW_TAG_compile_unit:       // File
2245254721Semaste                            check_children = ((function_die != NULL) || (block_die != NULL));
2246254721Semaste                            break;
2247254721Semaste
2248254721Semaste                        case DW_TAG_subprogram:         // Function
2249254721Semaste                            if (function_die)
2250254721Semaste                                *function_die = this;
2251254721Semaste                            check_children = (block_die != NULL);
2252254721Semaste                            break;
2253254721Semaste
2254254721Semaste                        case DW_TAG_inlined_subroutine: // Inlined Function
2255254721Semaste                        case DW_TAG_lexical_block:      // Block { } in code
2256254721Semaste                            if (block_die)
2257254721Semaste                            {
2258254721Semaste                                *block_die = this;
2259254721Semaste                                check_children = true;
2260254721Semaste                            }
2261254721Semaste                            break;
2262254721Semaste
2263254721Semaste                        default:
2264254721Semaste                            check_children = true;
2265254721Semaste                            break;
2266254721Semaste                        }
2267254721Semaste                    }
2268254721Semaste                    else
2269254721Semaste                    {
2270254721Semaste                        check_children = false;
2271254721Semaste                    }
2272254721Semaste                }
2273254721Semaste            }
2274254721Semaste        }
2275254721Semaste
2276254721Semaste
2277254721Semaste        if (check_children)
2278254721Semaste        {
2279254721Semaste        //  printf("checking children\n");
2280254721Semaste            DWARFDebugInfoEntry* child = GetFirstChild();
2281254721Semaste            while (child)
2282254721Semaste            {
2283254721Semaste                if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die))
2284254721Semaste                    return true;
2285254721Semaste                child = child->GetSibling();
2286254721Semaste            }
2287254721Semaste        }
2288254721Semaste    }
2289254721Semaste    return found_address;
2290254721Semaste}
2291254721Semaste
2292254721Semasteconst DWARFAbbreviationDeclaration*
2293254721SemasteDWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
2294254721Semaste                                                    const DWARFCompileUnit *cu,
2295254721Semaste                                                    lldb::offset_t &offset) const
2296254721Semaste{
2297254721Semaste    if (dwarf2Data)
2298254721Semaste    {
2299254721Semaste        offset = GetOffset();
2300254721Semaste
2301254721Semaste        const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
2302254721Semaste        if (abbrev_decl)
2303254721Semaste        {
2304254721Semaste            // Make sure the abbreviation code still matches. If it doesn't and
2305254721Semaste            // the DWARF data was mmap'ed, the backing file might have been modified
2306254721Semaste            // which is bad news.
2307254721Semaste            const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
2308254721Semaste
2309254721Semaste            if (abbrev_decl->Code() == abbrev_code)
2310254721Semaste                return abbrev_decl;
2311254721Semaste
2312254721Semaste            dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
2313254721Semaste                                                                                   GetOffset(),
2314254721Semaste                                                                                   (uint32_t)abbrev_decl->Code(),
2315254721Semaste                                                                                   (uint32_t)abbrev_code);
2316254721Semaste        }
2317254721Semaste    }
2318254721Semaste    offset = DW_INVALID_OFFSET;
2319254721Semaste    return NULL;
2320254721Semaste}
2321254721Semaste
2322254721Semaste
2323254721Semastebool
2324254721SemasteDWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b)
2325254721Semaste{
2326254721Semaste    return a.GetOffset() < b.GetOffset();
2327254721Semaste}
2328254721Semaste
2329254721Semastevoid
2330254721SemasteDWARFDebugInfoEntry::DumpDIECollection (Stream &strm, DWARFDebugInfoEntry::collection &die_collection)
2331254721Semaste{
2332254721Semaste    DWARFDebugInfoEntry::const_iterator pos;
2333254721Semaste    DWARFDebugInfoEntry::const_iterator end = die_collection.end();
2334254721Semaste    strm.PutCString("\noffset    parent   sibling  child\n");
2335254721Semaste    strm.PutCString("--------  -------- -------- --------\n");
2336254721Semaste    for (pos = die_collection.begin(); pos != end; ++pos)
2337254721Semaste    {
2338254721Semaste        const DWARFDebugInfoEntry& die_ref = *pos;
2339254721Semaste        const DWARFDebugInfoEntry* p = die_ref.GetParent();
2340254721Semaste        const DWARFDebugInfoEntry* s = die_ref.GetSibling();
2341254721Semaste        const DWARFDebugInfoEntry* c = die_ref.GetFirstChild();
2342254721Semaste        strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n",
2343254721Semaste                    die_ref.GetOffset(),
2344254721Semaste                    p ? p->GetOffset() : 0,
2345254721Semaste                    s ? s->GetOffset() : 0,
2346254721Semaste                    c ? c->GetOffset() : 0,
2347254721Semaste                    die_ref.Tag(),
2348254721Semaste                    DW_TAG_value_to_name(die_ref.Tag()),
2349254721Semaste                    die_ref.HasChildren() ? " *" : "");
2350254721Semaste    }
2351254721Semaste}
2352254721Semaste
2353254721Semaste
2354