• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "DWARFAbbreviationDeclaration.h"
11 
12 #include "lldb/Core/dwarf.h"
13 
14 #include "DWARFFormValue.h"
15 
16 using namespace lldb_private;
17 
DWARFAbbreviationDeclaration()18 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() :
19     m_code  (InvalidCode),
20     m_tag   (0),
21     m_has_children (0),
22     m_attributes()
23 {
24 }
25 
DWARFAbbreviationDeclaration(dw_tag_t tag,uint8_t has_children)26 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) :
27     m_code  (InvalidCode),
28     m_tag   (tag),
29     m_has_children (has_children),
30     m_attributes()
31 {
32 }
33 
34 bool
Extract(const DataExtractor & data,lldb::offset_t * offset_ptr)35 DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t* offset_ptr)
36 {
37     return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
38 }
39 
40 bool
Extract(const DataExtractor & data,lldb::offset_t * offset_ptr,dw_uleb128_t code)41 DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code)
42 {
43     m_code = code;
44     m_attributes.clear();
45     if (m_code)
46     {
47         m_tag = data.GetULEB128(offset_ptr);
48         m_has_children = data.GetU8(offset_ptr);
49 
50         while (data.ValidOffset(*offset_ptr))
51         {
52             dw_attr_t attr = data.GetULEB128(offset_ptr);
53             dw_form_t form = data.GetULEB128(offset_ptr);
54 
55             if (attr && form)
56                 m_attributes.push_back(DWARFAttribute(attr, form));
57             else
58                 break;
59         }
60 
61         return m_tag != 0;
62     }
63     else
64     {
65         m_tag = 0;
66         m_has_children = 0;
67     }
68 
69     return false;
70 }
71 
72 
73 void
Dump(Stream * s) const74 DWARFAbbreviationDeclaration::Dump(Stream *s)  const
75 {
76 //  *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;
77 //
78 //  DWARFAttribute::const_iterator pos;
79 //
80 //  for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
81 //      *ostrm_ptr << "      " << std::setw(29) << std::left << DW_AT_value_to_name(pos->attr()) << ' ' << DW_FORM_value_to_name(pos->form()) << std::endl;
82 //
83 //  *ostrm_ptr << std::endl;
84 }
85 
86 
87 
88 bool
IsValid()89 DWARFAbbreviationDeclaration::IsValid()
90 {
91     return m_code != 0 && m_tag != 0;
92 }
93 
94 
95 void
CopyExcludingAddressAttributes(const DWARFAbbreviationDeclaration & abbr_decl,const uint32_t idx)96 DWARFAbbreviationDeclaration::CopyExcludingAddressAttributes(const DWARFAbbreviationDeclaration& abbr_decl, const uint32_t idx)
97 {
98     m_code = abbr_decl.Code();  // Invalidate the code since that can't be copied safely.
99     m_tag = abbr_decl.Tag();
100     m_has_children = abbr_decl.HasChildren();
101 
102     const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
103     const uint32_t num_abbr_decl_attributes = attributes.size();
104 
105     dw_attr_t attr;
106     dw_form_t form;
107     uint32_t i;
108 
109     for (i = 0; i < num_abbr_decl_attributes; ++i)
110     {
111         attributes[i].get(attr, form);
112         switch (attr)
113         {
114         case DW_AT_location:
115         case DW_AT_frame_base:
116             // Only add these if they are location expressions (have a single
117             // value) and not location lists (have a lists of location
118             // expressions which are only valid over specific address ranges)
119             if (DWARFFormValue::IsBlockForm(form))
120                 m_attributes.push_back(DWARFAttribute(attr, form));
121             break;
122 
123         case DW_AT_low_pc:
124         case DW_AT_high_pc:
125         case DW_AT_ranges:
126         case DW_AT_entry_pc:
127             // Don't add these attributes
128             if (i >= idx)
129                 break;
130             // Fall through and add attribute
131         default:
132             // Add anything that isn't address related
133             m_attributes.push_back(DWARFAttribute(attr, form));
134             break;
135         }
136     }
137 }
138 
139 void
CopyChangingStringToStrp(const DWARFAbbreviationDeclaration & abbr_decl,const DataExtractor & debug_info_data,dw_offset_t debug_info_offset,const DWARFCompileUnit * cu,const uint32_t strp_min_len)140 DWARFAbbreviationDeclaration::CopyChangingStringToStrp(
141     const DWARFAbbreviationDeclaration& abbr_decl,
142     const DataExtractor& debug_info_data,
143     dw_offset_t debug_info_offset,
144     const DWARFCompileUnit* cu,
145     const uint32_t strp_min_len
146 )
147 {
148     m_code = InvalidCode;
149     m_tag = abbr_decl.Tag();
150     m_has_children = abbr_decl.HasChildren();
151 
152     const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
153     const uint32_t num_abbr_decl_attributes = attributes.size();
154 
155     dw_attr_t attr;
156     dw_form_t form;
157     uint32_t i;
158     lldb::offset_t offset = debug_info_offset;
159 
160     for (i = 0; i < num_abbr_decl_attributes; ++i)
161     {
162         attributes[i].get(attr, form);
163         dw_offset_t attr_offset = offset;
164         DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
165 
166         if (form == DW_FORM_string && ((offset - attr_offset) >= strp_min_len))
167             m_attributes.push_back(DWARFAttribute(attr, DW_FORM_strp));
168         else
169             m_attributes.push_back(DWARFAttribute(attr, form));
170     }
171 }
172 
173 
174 uint32_t
FindAttributeIndex(dw_attr_t attr) const175 DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const
176 {
177     uint32_t i;
178     const uint32_t kNumAttributes = m_attributes.size();
179     for (i = 0; i < kNumAttributes; ++i)
180     {
181         if (m_attributes[i].get_attr() == attr)
182             return i;
183     }
184     return DW_INVALID_INDEX;
185 }
186 
187 
188 bool
operator ==(const DWARFAbbreviationDeclaration & rhs) const189 DWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const
190 {
191     return Tag()            == rhs.Tag()
192         && HasChildren()    == rhs.HasChildren()
193         && Attributes()     == rhs.Attributes();
194 }
195 
196 #if 0
197 DWARFAbbreviationDeclaration::Append(BinaryStreamBuf& out_buff) const
198 {
199     out_buff.Append32_as_ULEB128(Code());
200     out_buff.Append32_as_ULEB128(Tag());
201     out_buff.Append8(HasChildren());
202     const uint32_t kNumAttributes = m_attributes.size();
203     for (uint32_t i = 0; i < kNumAttributes; ++i)
204     {
205         out_buff.Append32_as_ULEB128(m_attributes[i].attr());
206         out_buff.Append32_as_ULEB128(m_attributes[i].form());
207     }
208     out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
209     out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
210 }
211 #endif  // 0
212