1 //===-- DWARFCompileUnit.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_DWARFCompileUnit_h_
11 #define SymbolFileDWARF_DWARFCompileUnit_h_
12 
13 #include "DWARFDebugInfoEntry.h"
14 #include "SymbolFileDWARF.h"
15 
16 class NameToDIE;
17 
18 class DWARFCompileUnit
19 {
20 public:
21     DWARFCompileUnit(SymbolFileDWARF* dwarf2Data);
22 
23     bool        Extract(const lldb_private::DataExtractor &debug_info, uint32_t* offset_ptr);
24     dw_offset_t Extract(dw_offset_t offset, const lldb_private::DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs);
25     size_t      ExtractDIEsIfNeeded (bool cu_die_only);
26     bool        LookupAddress(
27                     const dw_addr_t address,
28                     DWARFDebugInfoEntry** function_die,
29                     DWARFDebugInfoEntry** block_die);
30 
31     size_t      AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& matching_dies, uint32_t depth = UINT32_MAX) const;
32     void        Clear();
33     bool        Verify(lldb_private::Stream *s) const;
34     void        Dump(lldb_private::Stream *s) const;
35     dw_offset_t GetOffset() const { return m_offset; }
36     uint32_t    Size() const { return 11; /* Size in bytes of the compile unit header */ }
37     bool        ContainsDIEOffset(dw_offset_t die_offset) const { return die_offset >= GetFirstDIEOffset() && die_offset < GetNextCompileUnitOffset(); }
38     dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
39     dw_offset_t GetNextCompileUnitOffset() const { return m_offset + m_length + 4; }
40     size_t      GetDebugInfoSize() const { return m_length + 4 - Size(); /* Size in bytes of the .debug_info data associated with this compile unit. */ }
41     uint32_t    GetLength() const { return m_length; }
42     uint16_t    GetVersion() const { return m_version; }
43     const DWARFAbbreviationDeclarationSet*  GetAbbreviations() const { return m_abbrevs; }
44     dw_offset_t GetAbbrevOffset() const;
45     uint8_t     GetAddressByteSize() const { return m_addr_size; }
46     dw_addr_t   GetBaseAddress() const { return m_base_addr; }
47     void        ClearDIEs(bool keep_compile_unit_die);
48     void        BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
49                                         DWARFDebugAranges* debug_aranges,
50                                         bool clear_dies_if_already_not_parsed);
51 
52     void
53     SetBaseAddress(dw_addr_t base_addr)
54     {
55         m_base_addr = base_addr;
56     }
57 
58     void
59     SetDIERelations();
60 
61     const DWARFDebugInfoEntry*
62     GetCompileUnitDIEOnly()
63     {
64         ExtractDIEsIfNeeded (true);
65         if (m_die_array.empty())
66             return NULL;
67         return &m_die_array[0];
68     }
69 
70     const DWARFDebugInfoEntry*
71     DIE()
72     {
73         ExtractDIEsIfNeeded (false);
74         if (m_die_array.empty())
75             return NULL;
76         return &m_die_array[0];
77     }
78 
79     void
80     AddDIE(DWARFDebugInfoEntry& die)
81     {
82         // The average bytes per DIE entry has been seen to be
83         // around 14-20 so lets pre-reserve the needed memory for
84         // our DIE entries accordingly. Search forward for "Compute
85         // average bytes per DIE" to see #if'ed out code that does
86         // that determination.
87 
88         // Only reserve the memory if we are adding children of
89         // the main compile unit DIE. The compile unit DIE is always
90         // the first entry, so if our size is 1, then we are adding
91         // the first compile unit child DIE and should reserve
92         // the memory.
93         if (m_die_array.empty())
94             m_die_array.reserve(GetDebugInfoSize() / 14);
95         m_die_array.push_back(die);
96     }
97 
98     DWARFDebugInfoEntry*
99     GetDIEAtIndexUnchecked (uint32_t idx)
100     {
101         return &m_die_array[idx];
102     }
103 
104     DWARFDebugInfoEntry*
105     GetDIEPtr (dw_offset_t die_offset);
106 
107     const DWARFDebugInfoEntry*
108     GetDIEPtrContainingOffset (dw_offset_t die_offset);
109 
110     static uint8_t
111     GetAddressByteSize(const DWARFCompileUnit* cu);
112 
113     static uint8_t
114     GetDefaultAddressSize();
115 
116     static void
117     SetDefaultAddressSize(uint8_t addr_size);
118 
119     void *
120     GetUserData() const
121     {
122         return m_user_data;
123     }
124 
125     void
126     SetUserData(void *d)
127     {
128         m_user_data = d;
129     }
130 
131 
132 //    void
133 //    AddGlobalDIEByIndex (uint32_t die_idx);
134 //
135 //    void
136 //    AddGlobal (const DWARFDebugInfoEntry* die);
137 //
138     void
139     Index (const uint32_t cu_idx,
140            NameToDIE& func_basenames,
141            NameToDIE& func_fullnames,
142            NameToDIE& func_methods,
143            NameToDIE& func_selectors,
144            NameToDIE& objc_class_selectors,
145            NameToDIE& globals,
146            NameToDIE& types,
147            NameToDIE& namespaces);
148 
149     const DWARFDebugAranges &
150     GetFunctionAranges ();
151 
152 protected:
153     SymbolFileDWARF*    m_dwarf2Data;
154     const DWARFAbbreviationDeclarationSet *m_abbrevs;
155     void *              m_user_data;
156     DWARFDebugInfoEntry::collection m_die_array;    // The compile unit debug information entry item
157     std::auto_ptr<DWARFDebugAranges> m_func_aranges_ap;   // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs
158     dw_addr_t           m_base_addr;
159     dw_offset_t         m_offset;
160     uint32_t            m_length;
161     uint16_t            m_version;
162     uint8_t             m_addr_size;
163 private:
164     DISALLOW_COPY_AND_ASSIGN (DWARFCompileUnit);
165 };
166 
167 #endif  // SymbolFileDWARF_DWARFCompileUnit_h_
168