1//===-- SymbolFileDWARFDebugMap.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_SymbolFileDWARFDebugMap_h_
11#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
12
13
14#include <vector>
15#include <bitset>
16
17#include "clang/AST/CharUnits.h"
18
19#include "lldb/Core/RangeMap.h"
20#include "lldb/Symbol/SymbolFile.h"
21
22#include "UniqueDWARFASTType.h"
23
24class SymbolFileDWARF;
25class DWARFCompileUnit;
26class DWARFDebugAranges;
27class DWARFDebugInfoEntry;
28class DWARFDeclContext;
29class DebugMapModule;
30
31class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile
32{
33public:
34
35    //------------------------------------------------------------------
36    // Static Functions
37    //------------------------------------------------------------------
38    static void
39    Initialize();
40
41    static void
42    Terminate();
43
44    static lldb_private::ConstString
45    GetPluginNameStatic();
46
47    static const char *
48    GetPluginDescriptionStatic();
49
50    static lldb_private::SymbolFile *
51    CreateInstance (lldb_private::ObjectFile* obj_file);
52
53    //------------------------------------------------------------------
54    // Constructors and Destructors
55    //------------------------------------------------------------------
56                            SymbolFileDWARFDebugMap (lldb_private::ObjectFile* ofile);
57    virtual               ~ SymbolFileDWARFDebugMap ();
58
59    virtual uint32_t        CalculateAbilities ();
60
61    virtual void            InitializeObject();
62
63    //------------------------------------------------------------------
64    // Compile Unit function calls
65    //------------------------------------------------------------------
66    virtual uint32_t        GetNumCompileUnits ();
67    virtual lldb::CompUnitSP ParseCompileUnitAtIndex (uint32_t index);
68
69    virtual lldb::LanguageType ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc);
70    virtual size_t          ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
71    virtual bool            ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
72    virtual bool            ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files);
73    virtual size_t          ParseFunctionBlocks (const lldb_private::SymbolContext& sc);
74    virtual size_t          ParseTypes (const lldb_private::SymbolContext& sc);
75    virtual size_t          ParseVariablesForContext (const lldb_private::SymbolContext& sc);
76
77    virtual lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid);
78    virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid);
79    virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid);
80    virtual bool            ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type);
81    virtual uint32_t        ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
82    virtual uint32_t        ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list);
83    virtual uint32_t        FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
84    virtual uint32_t        FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
85    virtual uint32_t        FindFunctions (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list);
86    virtual uint32_t        FindFunctions (const lldb_private::RegularExpression& regex, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list);
87    virtual uint32_t        FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::TypeList& types);
88    virtual lldb_private::ClangNamespaceDecl
89                            FindNamespace (const lldb_private::SymbolContext& sc,
90                                           const lldb_private::ConstString &name,
91                                           const lldb_private::ClangNamespaceDecl *parent_namespace_decl);
92    virtual size_t          GetTypes (lldb_private::SymbolContextScope *sc_scope,
93                                      uint32_t type_mask,
94                                      lldb_private::TypeList &type_list);
95
96
97    //------------------------------------------------------------------
98    // ClangASTContext callbacks for external source lookups.
99    //------------------------------------------------------------------
100    static void
101    CompleteTagDecl (void *baton, clang::TagDecl *);
102
103    static void
104    CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *);
105
106    static bool
107    LayoutRecordType (void *baton,
108                      const clang::RecordDecl *record_decl,
109                      uint64_t &size,
110                      uint64_t &alignment,
111                      llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
112                      llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
113                      llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets);
114
115
116    //------------------------------------------------------------------
117    // PluginInterface protocol
118    //------------------------------------------------------------------
119    virtual lldb_private::ConstString
120    GetPluginName();
121
122    virtual uint32_t
123    GetPluginVersion();
124
125protected:
126    enum
127    {
128        kHaveInitializedOSOs = (1 << 0),
129        kNumFlags
130    };
131
132    friend class DWARFCompileUnit;
133    friend class SymbolFileDWARF;
134    friend class DebugMapModule;
135    struct OSOInfo
136    {
137        lldb::ModuleSP module_sp;
138
139        OSOInfo() :
140            module_sp ()
141        {
142        }
143    };
144
145    typedef std::shared_ptr<OSOInfo> OSOInfoSP;
146
147    typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
148
149    //------------------------------------------------------------------
150    // Class specific types
151    //------------------------------------------------------------------
152    struct CompileUnitInfo
153    {
154        lldb_private::FileSpec so_file;
155        lldb_private::ConstString oso_path;
156        lldb_private::TimeValue oso_mod_time;
157        OSOInfoSP oso_sp;
158        lldb::CompUnitSP compile_unit_sp;
159        uint32_t first_symbol_index;
160        uint32_t last_symbol_index;
161        uint32_t first_symbol_id;
162        uint32_t last_symbol_id;
163        FileRangeMap file_range_map;
164        bool file_range_map_valid;
165
166
167        CompileUnitInfo() :
168            so_file (),
169            oso_path (),
170            oso_mod_time (),
171            oso_sp (),
172            compile_unit_sp (),
173            first_symbol_index (UINT32_MAX),
174            last_symbol_index (UINT32_MAX),
175            first_symbol_id (UINT32_MAX),
176            last_symbol_id (UINT32_MAX),
177            file_range_map (),
178            file_range_map_valid (false)
179        {
180        }
181
182        const FileRangeMap &
183        GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
184    };
185
186    //------------------------------------------------------------------
187    // Protected Member Functions
188    //------------------------------------------------------------------
189    void
190    InitOSO ();
191
192    static uint32_t
193    GetOSOIndexFromUserID (lldb::user_id_t uid)
194    {
195        return (uint32_t)((uid >> 32ull) - 1ull);
196    }
197
198    static SymbolFileDWARF *
199    GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file);
200
201    bool
202    GetFileSpecForSO (uint32_t oso_idx, lldb_private::FileSpec &file_spec);
203
204    CompileUnitInfo *
205    GetCompUnitInfo (const lldb_private::SymbolContext& sc);
206
207    size_t
208    GetCompUnitInfosForModule (const lldb_private::Module *oso_module,
209                               std::vector<CompileUnitInfo *>& cu_infos);
210
211    lldb_private::Module *
212    GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info);
213
214    lldb_private::Module *
215    GetModuleByOSOIndex (uint32_t oso_idx);
216
217    lldb_private::ObjectFile *
218    GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
219
220    lldb_private::ObjectFile *
221    GetObjectFileByOSOIndex (uint32_t oso_idx);
222
223    uint32_t
224    GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info);
225
226    SymbolFileDWARF *
227    GetSymbolFile (const lldb_private::SymbolContext& sc);
228
229    SymbolFileDWARF *
230    GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
231
232    SymbolFileDWARF *
233    GetSymbolFileByOSOIndex (uint32_t oso_idx);
234
235    CompileUnitInfo *
236    GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr);
237
238    CompileUnitInfo *
239    GetCompileUnitInfoForSymbolWithID (lldb::user_id_t symbol_id, uint32_t *oso_idx_ptr);
240
241    static int
242    SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
243
244    static int
245    SymbolContainsSymbolWithID (lldb::user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
246
247    uint32_t
248    PrivateFindGlobalVariables (const lldb_private::ConstString &name,
249                                const lldb_private::ClangNamespaceDecl *namespace_decl,
250                                const std::vector<uint32_t> &name_symbol_indexes,
251                                uint32_t max_matches,
252                                lldb_private::VariableList& variables);
253
254
255    void
256    SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp);
257
258    lldb::CompUnitSP
259    GetCompileUnit (SymbolFileDWARF *oso_dwarf);
260
261    CompileUnitInfo *
262    GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
263
264    lldb::TypeSP
265    FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
266
267    bool
268    Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso);
269
270    lldb::TypeSP
271    FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
272                                          const lldb_private::ConstString &type_name,
273                                          bool must_be_implementation);
274
275
276    UniqueDWARFASTTypeMap &
277    GetUniqueDWARFASTTypeMap ()
278    {
279        return m_unique_ast_type_map;
280    }
281
282
283    //------------------------------------------------------------------
284    // OSOEntry
285    //------------------------------------------------------------------
286    class OSOEntry
287    {
288    public:
289
290        OSOEntry () :
291        m_exe_sym_idx (UINT32_MAX),
292        m_oso_file_addr (LLDB_INVALID_ADDRESS)
293        {
294        }
295
296        OSOEntry (uint32_t exe_sym_idx,
297                  lldb::addr_t oso_file_addr) :
298        m_exe_sym_idx (exe_sym_idx),
299        m_oso_file_addr (oso_file_addr)
300        {
301        }
302
303        uint32_t
304        GetExeSymbolIndex () const
305        {
306            return m_exe_sym_idx;
307        }
308
309        bool
310        operator < (const OSOEntry &rhs) const
311        {
312            return m_exe_sym_idx < rhs.m_exe_sym_idx;
313        }
314
315        lldb::addr_t
316        GetOSOFileAddress () const
317        {
318            return m_oso_file_addr;
319        }
320
321        void
322        SetOSOFileAddress (lldb::addr_t oso_file_addr)
323        {
324            m_oso_file_addr = oso_file_addr;
325        }
326    protected:
327        uint32_t m_exe_sym_idx;
328        lldb::addr_t m_oso_file_addr;
329    };
330
331    typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
332
333    //------------------------------------------------------------------
334    // Member Variables
335    //------------------------------------------------------------------
336    std::bitset<kNumFlags> m_flags;
337    std::vector<CompileUnitInfo> m_compile_unit_infos;
338    std::vector<uint32_t> m_func_indexes;   // Sorted by address
339    std::vector<uint32_t> m_glob_indexes;
340    std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
341    UniqueDWARFASTTypeMap m_unique_ast_type_map;
342    lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
343    DebugMap m_debug_map;
344
345    //------------------------------------------------------------------
346    // When an object file from the debug map gets parsed in
347    // SymbolFileDWARF, it needs to tell the debug map about the object
348    // files addresses by calling this function once for each N_FUN,
349    // N_GSYM and N_STSYM and after all entries in the debug map have
350    // been matched up, FinalizeOSOFileRanges() should be called.
351    //------------------------------------------------------------------
352    bool
353    AddOSOFileRange (CompileUnitInfo *cu_info,
354                     lldb::addr_t exe_file_addr,
355                     lldb::addr_t oso_file_addr,
356                     lldb::addr_t oso_byte_size);
357
358    //------------------------------------------------------------------
359    // Called after calling AddOSOFileRange() for each object file debug
360    // map entry to finalize the info for the unlinked compile unit.
361    //------------------------------------------------------------------
362    void
363    FinalizeOSOFileRanges (CompileUnitInfo *cu_info);
364
365    //------------------------------------------------------------------
366    /// Convert \a addr from a .o file address, to an executable address.
367    ///
368    /// @param[in] addr
369    ///     A section offset address from a .o file
370    ///
371    /// @return
372    ///     Returns true if \a addr was converted to be an executable
373    ///     section/offset address, false otherwise.
374    //------------------------------------------------------------------
375    bool
376    LinkOSOAddress (lldb_private::Address &addr);
377
378    //------------------------------------------------------------------
379    /// Convert a .o file "file address" to an executable "file address".
380    ///
381    /// @param[in] oso_symfile
382    ///     The DWARF symbol file that contains \a oso_file_addr
383    ///
384    /// @param[in] oso_file_addr
385    ///     A .o file "file address" to convert.
386    ///
387    /// @return
388    ///     LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
389    ///     linked executable, otherwise a valid "file address" from the
390    ///     linked executable that contains the debug map.
391    //------------------------------------------------------------------
392    lldb::addr_t
393    LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr);
394
395    //------------------------------------------------------------------
396    /// Given a line table full of lines with "file adresses" that are
397    /// for a .o file represented by \a oso_symfile, link a new line table
398    /// and return it.
399    ///
400    /// @param[in] oso_symfile
401    ///     The DWARF symbol file that produced the \a line_table
402    ///
403    /// @param[in] addr
404    ///     A section offset address from a .o file
405    ///
406    /// @return
407    ///     Returns a valid line table full of linked addresses, or NULL
408    ///     if none of the line table adresses exist in the main
409    ///     executable.
410    //------------------------------------------------------------------
411    lldb_private::LineTable *
412    LinkOSOLineTable (SymbolFileDWARF *oso_symfile,
413                      lldb_private::LineTable *line_table);
414
415    size_t
416    AddOSOARanges (SymbolFileDWARF* dwarf2Data,
417                   DWARFDebugAranges* debug_aranges);
418};
419
420#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
421