1 //===-- DWARFDebugInfoEntry.h -----------------------------------*- 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 #ifndef SymbolFileDWARF_DWARFDebugInfoEntry_h_
11 #define SymbolFileDWARF_DWARFDebugInfoEntry_h_
12 
13 #include "SymbolFileDWARF.h"
14 
15 #include "llvm/ADT/SmallVector.h"
16 
17 #include "DWARFAbbreviationDeclaration.h"
18 #include "DWARFDebugRanges.h"
19 #include <vector>
20 #include <map>
21 #include <set>
22 
23 typedef std::map<const DWARFDebugInfoEntry*, dw_addr_t>     DIEToAddressMap;
24 typedef DIEToAddressMap::iterator                           DIEToAddressMapIter;
25 typedef DIEToAddressMap::const_iterator                     DIEToAddressMapConstIter;
26 
27 typedef std::map<dw_addr_t, const DWARFDebugInfoEntry*>     AddressToDIEMap;
28 typedef AddressToDIEMap::iterator                           AddressToDIEMapIter;
29 typedef AddressToDIEMap::const_iterator                     AddressToDIEMapConstIter;
30 
31 
32 typedef std::map<dw_offset_t, dw_offset_t>                  DIEToDIEMap;
33 typedef DIEToDIEMap::iterator                               DIEToDIEMapIter;
34 typedef DIEToDIEMap::const_iterator                         DIEToDIEMapConstIter;
35 
36 typedef std::map<uint32_t, const DWARFDebugInfoEntry*>      UInt32ToDIEMap;
37 typedef UInt32ToDIEMap::iterator                            UInt32ToDIEMapIter;
38 typedef UInt32ToDIEMap::const_iterator                      UInt32ToDIEMapConstIter;
39 
40 typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap;
41 typedef UInt32ToDIEMMap::iterator                           UInt32ToDIEMMapIter;
42 typedef UInt32ToDIEMMap::const_iterator                     UInt32ToDIEMMapConstIter;
43 
44 class DWARFDebugInfoEntry
45 {
46 public:
47     typedef std::vector<DWARFDebugInfoEntry>    collection;
48     typedef collection::iterator                iterator;
49     typedef collection::const_iterator          const_iterator;
50 
51     typedef std::vector<dw_offset_t>            offset_collection;
52     typedef offset_collection::iterator         offset_collection_iterator;
53     typedef offset_collection::const_iterator   offset_collection_const_iterator;
54 
55     class Attributes
56     {
57     public:
58         Attributes();
59         ~Attributes();
60 
61         void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form);
62         const DWARFCompileUnit * CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; }
63         dw_offset_t DIEOffsetAtIndex(uint32_t i) const { return m_infos[i].die_offset; }
64         dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr; }
65         dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].form; }
66         bool ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const;
67         uint64_t FormValueAsUnsignedAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const;
68         uint32_t FindAttributeIndex(dw_attr_t attr) const;
69         bool ContainsAttribute(dw_attr_t attr) const;
70         bool RemoveAttribute(dw_attr_t attr);
71         void Clear() { m_infos.clear(); }
72         uint32_t Size() const { return m_infos.size(); }
73 
74     protected:
75         struct Info
76         {
77             const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in case we have DW_FORM_ref_addr values
78             dw_offset_t die_offset;
79             dw_attr_t attr;
80             dw_form_t form;
81         };
82 
83         typedef llvm::SmallVector<Info, 32> collection;
84         collection m_infos;
85     };
86 
87     struct CompareState
88     {
89         CompareState() :
90             die_offset_pairs()
91         {
92             assert(sizeof(dw_offset_t)*2 == sizeof(uint64_t));
93         }
94 
95         bool AddTypePair(dw_offset_t a, dw_offset_t b)
96         {
97             uint64_t a_b_offsets = (uint64_t)a << 32 | (uint64_t)b;
98             // Return true if this type was inserted, false otherwise
99             return die_offset_pairs.insert(a_b_offsets).second;
100         }
101         std::set< uint64_t > die_offset_pairs;
102     };
103 
104                 DWARFDebugInfoEntry():
105                     m_offset        (DW_INVALID_OFFSET),
106                     m_parent_idx    (0),
107                     m_sibling_idx   (0),
108                     m_abbrevDecl    (NULL)
109                 {
110                 }
111 
112     bool        Contains (const DWARFDebugInfoEntry *die) const;
113 
114     void        BuildAddressRangeTable(
115                     SymbolFileDWARF* dwarf2Data,
116                     const DWARFCompileUnit* cu,
117                     DWARFDebugAranges* debug_aranges) const;
118 
119     void        BuildFunctionAddressRangeTable(
120                     SymbolFileDWARF* dwarf2Data,
121                     const DWARFCompileUnit* cu,
122                     DWARFDebugAranges* debug_aranges) const;
123 
124     bool        FastExtract(
125                     const lldb_private::DataExtractor& debug_info_data,
126                     const DWARFCompileUnit* cu,
127                     const uint8_t *fixed_form_sizes,
128                     dw_offset_t* offset_ptr);
129 
130     bool        Extract(
131                     SymbolFileDWARF* dwarf2Data,
132                     const DWARFCompileUnit* cu,
133                     dw_offset_t* offset_ptr);
134 
135     bool        LookupAddress(
136                     const dw_addr_t address,
137                     SymbolFileDWARF* dwarf2Data,
138                     const DWARFCompileUnit* cu,
139                     DWARFDebugInfoEntry** function_die,
140                     DWARFDebugInfoEntry** block_die);
141 
142     size_t      GetAttributes(
143                     SymbolFileDWARF* dwarf2Data,
144                     const DWARFCompileUnit* cu,
145                     const uint8_t *fixed_form_sizes,
146                     DWARFDebugInfoEntry::Attributes& attrs,
147                     uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!!
148 
149     dw_offset_t GetAttributeValue(
150                     SymbolFileDWARF* dwarf2Data,
151                     const DWARFCompileUnit* cu,
152                     const dw_attr_t attr,
153                     DWARFFormValue& formValue,
154                     dw_offset_t* end_attr_offset_ptr = NULL) const;
155 
156     const char* GetAttributeValueAsString(
157                     SymbolFileDWARF* dwarf2Data,
158                     const DWARFCompileUnit* cu,
159                     const dw_attr_t attr,
160                     const char* fail_value) const;
161 
162     uint64_t    GetAttributeValueAsUnsigned(
163                     SymbolFileDWARF* dwarf2Data,
164                     const DWARFCompileUnit* cu,
165                     const dw_attr_t attr,
166                     uint64_t fail_value) const;
167 
168     uint64_t    GetAttributeValueAsReference(
169                     SymbolFileDWARF* dwarf2Data,
170                     const DWARFCompileUnit* cu,
171                     const dw_attr_t attr,
172                     uint64_t fail_value) const;
173 
174     int64_t     GetAttributeValueAsSigned(
175                     SymbolFileDWARF* dwarf2Data,
176                     const DWARFCompileUnit* cu,
177                     const dw_attr_t attr,
178                     int64_t fail_value) const;
179 
180     dw_offset_t GetAttributeValueAsLocation(
181                     SymbolFileDWARF* dwarf2Data,
182                     const DWARFCompileUnit* cu,
183                     const dw_attr_t attr,
184                     lldb_private::DataExtractor& data,
185                     uint32_t &block_size) const;
186 
187     const char* GetName(
188                     SymbolFileDWARF* dwarf2Data,
189                     const DWARFCompileUnit* cu) const;
190 
191     const char* GetMangledName(
192                     SymbolFileDWARF* dwarf2Data,
193                     const DWARFCompileUnit* cu,
194                     bool substitute_name_allowed = true) const;
195 
196     const char* GetPubname(
197                     SymbolFileDWARF* dwarf2Data,
198                     const DWARFCompileUnit* cu) const;
199 
200     static bool GetName(
201                     SymbolFileDWARF* dwarf2Data,
202                     const DWARFCompileUnit* cu,
203                     const dw_offset_t die_offset,
204                     lldb_private::Stream &s);
205 
206     static bool AppendTypeName(
207                     SymbolFileDWARF* dwarf2Data,
208                     const DWARFCompileUnit* cu,
209                     const dw_offset_t die_offset,
210                     lldb_private::Stream &s);
211 
212 //    static int  Compare(
213 //                    SymbolFileDWARF* dwarf2Data,
214 //                    dw_offset_t a_die_offset,
215 //                    dw_offset_t b_die_offset,
216 //                    CompareState &compare_state,
217 //                    bool compare_siblings,
218 //                    bool compare_children);
219 //
220 //    static int Compare(
221 //                    SymbolFileDWARF* dwarf2Data,
222 //                    DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die,
223 //                    DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die,
224 //                    CompareState &compare_state,
225 //                    bool compare_siblings,
226 //                    bool compare_children);
227 
228     static bool OffsetLessThan (
229                     const DWARFDebugInfoEntry& a,
230                     const DWARFDebugInfoEntry& b);
231 
232     bool        AppendDependentDIES(
233                     SymbolFileDWARF* dwarf2Data,
234                     const DWARFCompileUnit* cu,
235                     const bool add_children,
236                     DWARFDIECollection& die_offsets) const;
237 
238     void        Dump(
239                     SymbolFileDWARF* dwarf2Data,
240                     const DWARFCompileUnit* cu,
241                     lldb_private::Stream &s,
242                     uint32_t recurse_depth) const;
243 
244     void        DumpAncestry(
245                     SymbolFileDWARF* dwarf2Data,
246                     const DWARFCompileUnit* cu,
247                     const DWARFDebugInfoEntry* oldest,
248                     lldb_private::Stream &s,
249                     uint32_t recurse_depth) const;
250 
251     static void DumpAttribute(
252                     SymbolFileDWARF* dwarf2Data,
253                     const DWARFCompileUnit* cu,
254                     const lldb_private::DataExtractor& debug_info_data,
255                     uint32_t* offset_ptr,
256                     lldb_private::Stream &s,
257                     dw_attr_t attr,
258                     dw_form_t form);
259     // This one dumps the comp unit name, objfile name and die offset for this die so the stream S.
260     void          DumpLocation(
261                     SymbolFileDWARF* dwarf2Data,
262                     DWARFCompileUnit* cu,
263                     lldb_private::Stream &s) const;
264 
265     bool        GetDIENamesAndRanges(
266                     SymbolFileDWARF* dwarf2Data,
267                     const DWARFCompileUnit* cu,
268                     const char * &name,
269                     const char * &mangled,
270                     DWARFDebugRanges::RangeList& rangeList,
271                     int& decl_file,
272                     int& decl_line,
273                     int& decl_column,
274                     int& call_file,
275                     int& call_line,
276                     int& call_column,
277                     lldb_private::DWARFExpression *frame_base = NULL) const;
278 
279 
280     dw_tag_t    Tag()           const { return m_abbrevDecl ? m_abbrevDecl->Tag() : 0; }
281     bool        IsNULL()        const { return m_abbrevDecl == NULL; }
282     dw_offset_t GetOffset()     const { return m_offset; }
283     void        SetOffset(dw_offset_t offset) { m_offset = offset; }
284     uint32_t    NumAttributes() const { return m_abbrevDecl ? m_abbrevDecl->NumAttributes() : 0; }
285     bool        HasChildren()   const { return m_abbrevDecl != NULL && m_abbrevDecl->HasChildren(); }
286 
287             // We know we are kept in a vector of contiguous entries, so we know
288             // our parent will be some index behind "this".
289             DWARFDebugInfoEntry*    GetParent()             { return m_parent_idx > 0 ? this - m_parent_idx : NULL;  }
290     const   DWARFDebugInfoEntry*    GetParent()     const   { return m_parent_idx > 0 ? this - m_parent_idx : NULL;  }
291             // We know we are kept in a vector of contiguous entries, so we know
292             // our sibling will be some index after "this".
293             DWARFDebugInfoEntry*    GetSibling()            { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;  }
294     const   DWARFDebugInfoEntry*    GetSibling()    const   { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;  }
295             // We know we are kept in a vector of contiguous entries, so we know
296             // we don't need to store our child pointer, if we have a child it will
297             // be the next entry in the list...
298             DWARFDebugInfoEntry*    GetFirstChild()         { return HasChildren() ? this + 1 : NULL; }
299     const   DWARFDebugInfoEntry*    GetFirstChild() const   { return HasChildren() ? this + 1 : NULL; }
300 
301     void
302     SetParent (DWARFDebugInfoEntry* parent)
303     {
304         if (parent)
305         {
306             // We know we are kept in a vector of contiguous entries, so we know
307             // our parent will be some index behind "this".
308             m_parent_idx = this - parent;
309         }
310         else
311             m_parent_idx = 0;
312     }
313     void
314     SetSibling (DWARFDebugInfoEntry* sibling)
315     {
316         if (sibling)
317         {
318             // We know we are kept in a vector of contiguous entries, so we know
319             // our sibling will be some index after "this".
320             m_sibling_idx = sibling - this;
321             sibling->SetParent(GetParent());
322         }
323         else
324             m_sibling_idx = 0;
325     }
326     const DWARFAbbreviationDeclaration* GetAbbreviationDeclarationPtr() const { return m_abbrevDecl; }
327 
328 protected:
329     dw_offset_t                         m_offset;       // Offset within the .debug_info of the start of this entry
330     uint32_t                            m_parent_idx;   // How many to subtract from "this" to get the parent. If zero this die has no parent
331     uint32_t                            m_sibling_idx;  // How many to add to "this" to get the sibling.
332     const DWARFAbbreviationDeclaration* m_abbrevDecl;
333 };
334 
335 #endif  // SymbolFileDWARF_DWARFDebugInfoEntry_h_
336