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