1254721Semaste//===-- DWARFAbbreviationDeclaration.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 "DWARFAbbreviationDeclaration.h"
11254721Semaste
12254721Semaste#include "lldb/Core/dwarf.h"
13254721Semaste
14254721Semaste#include "DWARFFormValue.h"
15254721Semaste
16254721Semasteusing namespace lldb_private;
17254721Semaste
18254721SemasteDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() :
19254721Semaste    m_code  (InvalidCode),
20254721Semaste    m_tag   (0),
21254721Semaste    m_has_children (0),
22254721Semaste    m_attributes()
23254721Semaste{
24254721Semaste}
25254721Semaste
26254721SemasteDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) :
27254721Semaste    m_code  (InvalidCode),
28254721Semaste    m_tag   (tag),
29254721Semaste    m_has_children (has_children),
30254721Semaste    m_attributes()
31254721Semaste{
32254721Semaste}
33254721Semaste
34254721Semastebool
35263363SemasteDWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr)
36254721Semaste{
37254721Semaste    return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
38254721Semaste}
39254721Semaste
40254721Semastebool
41263363SemasteDWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code)
42254721Semaste{
43254721Semaste    m_code = code;
44254721Semaste    m_attributes.clear();
45254721Semaste    if (m_code)
46254721Semaste    {
47254721Semaste        m_tag = data.GetULEB128(offset_ptr);
48254721Semaste        m_has_children = data.GetU8(offset_ptr);
49254721Semaste
50254721Semaste        while (data.ValidOffset(*offset_ptr))
51254721Semaste        {
52254721Semaste            dw_attr_t attr = data.GetULEB128(offset_ptr);
53254721Semaste            dw_form_t form = data.GetULEB128(offset_ptr);
54254721Semaste
55254721Semaste            if (attr && form)
56254721Semaste                m_attributes.push_back(DWARFAttribute(attr, form));
57254721Semaste            else
58254721Semaste                break;
59254721Semaste        }
60254721Semaste
61254721Semaste        return m_tag != 0;
62254721Semaste    }
63254721Semaste    else
64254721Semaste    {
65254721Semaste        m_tag = 0;
66254721Semaste        m_has_children = 0;
67254721Semaste    }
68254721Semaste
69254721Semaste    return false;
70254721Semaste}
71254721Semaste
72254721Semaste
73254721Semastevoid
74254721SemasteDWARFAbbreviationDeclaration::Dump(Stream *s)  const
75254721Semaste{
76254721Semaste//  *ostrm_ptr << std::setfill(' ') << std::dec << '[' << std::setw(3) << std::right << m_code << ']' << ' ' << std::setw(30) << std::left << DW_TAG_value_to_name(m_tag) << DW_CHILDREN_value_to_name(m_has_children) << std::endl;
77254721Semaste//
78254721Semaste//  DWARFAttribute::const_iterator pos;
79254721Semaste//
80254721Semaste//  for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
81254721Semaste//      *ostrm_ptr << "      " << std::setw(29) << std::left << DW_AT_value_to_name(pos->attr()) << ' ' << DW_FORM_value_to_name(pos->form()) << std::endl;
82254721Semaste//
83254721Semaste//  *ostrm_ptr << std::endl;
84254721Semaste}
85254721Semaste
86254721Semaste
87254721Semaste
88254721Semastebool
89254721SemasteDWARFAbbreviationDeclaration::IsValid()
90254721Semaste{
91254721Semaste    return m_code != 0 && m_tag != 0;
92254721Semaste}
93254721Semaste
94254721Semaste
95254721Semastevoid
96254721SemasteDWARFAbbreviationDeclaration::CopyExcludingAddressAttributes(const DWARFAbbreviationDeclaration& abbr_decl, const uint32_t idx)
97254721Semaste{
98254721Semaste    m_code = abbr_decl.Code();  // Invalidate the code since that can't be copied safely.
99254721Semaste    m_tag = abbr_decl.Tag();
100254721Semaste    m_has_children = abbr_decl.HasChildren();
101254721Semaste
102254721Semaste    const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
103254721Semaste    const uint32_t num_abbr_decl_attributes = attributes.size();
104254721Semaste
105254721Semaste    dw_attr_t attr;
106254721Semaste    dw_form_t form;
107254721Semaste    uint32_t i;
108254721Semaste
109254721Semaste    for (i = 0; i < num_abbr_decl_attributes; ++i)
110254721Semaste    {
111254721Semaste        attributes[i].get(attr, form);
112254721Semaste        switch (attr)
113254721Semaste        {
114254721Semaste        case DW_AT_location:
115254721Semaste        case DW_AT_frame_base:
116254721Semaste            // Only add these if they are location expressions (have a single
117254721Semaste            // value) and not location lists (have a lists of location
118254721Semaste            // expressions which are only valid over specific address ranges)
119254721Semaste            if (DWARFFormValue::IsBlockForm(form))
120254721Semaste                m_attributes.push_back(DWARFAttribute(attr, form));
121254721Semaste            break;
122254721Semaste
123254721Semaste        case DW_AT_low_pc:
124254721Semaste        case DW_AT_high_pc:
125254721Semaste        case DW_AT_ranges:
126254721Semaste        case DW_AT_entry_pc:
127254721Semaste            // Don't add these attributes
128254721Semaste            if (i >= idx)
129254721Semaste                break;
130254721Semaste            // Fall through and add attribute
131254721Semaste        default:
132254721Semaste            // Add anything that isn't address related
133254721Semaste            m_attributes.push_back(DWARFAttribute(attr, form));
134254721Semaste            break;
135254721Semaste        }
136254721Semaste    }
137254721Semaste}
138254721Semaste
139254721Semastevoid
140254721SemasteDWARFAbbreviationDeclaration::CopyChangingStringToStrp(
141254721Semaste    const DWARFAbbreviationDeclaration& abbr_decl,
142263363Semaste    const DWARFDataExtractor& debug_info_data,
143254721Semaste    dw_offset_t debug_info_offset,
144254721Semaste    const DWARFCompileUnit* cu,
145254721Semaste    const uint32_t strp_min_len
146254721Semaste)
147254721Semaste{
148254721Semaste    m_code = InvalidCode;
149254721Semaste    m_tag = abbr_decl.Tag();
150254721Semaste    m_has_children = abbr_decl.HasChildren();
151254721Semaste
152254721Semaste    const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
153254721Semaste    const uint32_t num_abbr_decl_attributes = attributes.size();
154254721Semaste
155254721Semaste    dw_attr_t attr;
156254721Semaste    dw_form_t form;
157254721Semaste    uint32_t i;
158254721Semaste    lldb::offset_t offset = debug_info_offset;
159254721Semaste
160254721Semaste    for (i = 0; i < num_abbr_decl_attributes; ++i)
161254721Semaste    {
162254721Semaste        attributes[i].get(attr, form);
163254721Semaste        dw_offset_t attr_offset = offset;
164254721Semaste        DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
165254721Semaste
166254721Semaste        if (form == DW_FORM_string && ((offset - attr_offset) >= strp_min_len))
167254721Semaste            m_attributes.push_back(DWARFAttribute(attr, DW_FORM_strp));
168254721Semaste        else
169254721Semaste            m_attributes.push_back(DWARFAttribute(attr, form));
170254721Semaste    }
171254721Semaste}
172254721Semaste
173254721Semaste
174254721Semasteuint32_t
175254721SemasteDWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const
176254721Semaste{
177254721Semaste    uint32_t i;
178254721Semaste    const uint32_t kNumAttributes = m_attributes.size();
179254721Semaste    for (i = 0; i < kNumAttributes; ++i)
180254721Semaste    {
181254721Semaste        if (m_attributes[i].get_attr() == attr)
182254721Semaste            return i;
183254721Semaste    }
184254721Semaste    return DW_INVALID_INDEX;
185254721Semaste}
186254721Semaste
187254721Semaste
188254721Semastebool
189254721SemasteDWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const
190254721Semaste{
191254721Semaste    return Tag()            == rhs.Tag()
192254721Semaste        && HasChildren()    == rhs.HasChildren()
193254721Semaste        && Attributes()     == rhs.Attributes();
194254721Semaste}
195254721Semaste
196254721Semaste#if 0
197254721SemasteDWARFAbbreviationDeclaration::Append(BinaryStreamBuf& out_buff) const
198254721Semaste{
199254721Semaste    out_buff.Append32_as_ULEB128(Code());
200254721Semaste    out_buff.Append32_as_ULEB128(Tag());
201254721Semaste    out_buff.Append8(HasChildren());
202254721Semaste    const uint32_t kNumAttributes = m_attributes.size();
203254721Semaste    for (uint32_t i = 0; i < kNumAttributes; ++i)
204254721Semaste    {
205254721Semaste        out_buff.Append32_as_ULEB128(m_attributes[i].attr());
206254721Semaste        out_buff.Append32_as_ULEB128(m_attributes[i].form());
207254721Semaste    }
208254721Semaste    out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
209254721Semaste    out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
210254721Semaste}
211254721Semaste#endif  // 0
212