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 lldb_private::ConstString
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 lldb_private::ConstString
116     GetPluginName();
117 
118     virtual uint32_t
119     GetPluginVersion();
120 
121 protected:
122     enum
123     {
124         kHaveInitializedOSOs = (1 << 0),
125         kNumFlags
126     };
127 
128     friend class SymbolFileDWARF;
129     friend class DebugMapModule;
130     struct OSOInfo
131     {
132         lldb::ModuleSP module_sp;
133 
134         OSOInfo() :
135             module_sp ()
136         {
137         }
138     };
139 
140     typedef std::shared_ptr<OSOInfo> OSOInfoSP;
141 
142     typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
143 
144     //------------------------------------------------------------------
145     // Class specific types
146     //------------------------------------------------------------------
147     struct CompileUnitInfo
148     {
149         lldb_private::FileSpec so_file;
150         lldb_private::ConstString oso_path;
151         lldb_private::TimeValue oso_mod_time;
152         OSOInfoSP oso_sp;
153         lldb::CompUnitSP compile_unit_sp;
154         uint32_t first_symbol_index;
155         uint32_t last_symbol_index;
156         uint32_t first_symbol_id;
157         uint32_t last_symbol_id;
158         FileRangeMap file_range_map;
159         bool file_range_map_valid;
160 
161 
162         CompileUnitInfo() :
163             so_file (),
164             oso_path (),
165             oso_mod_time (),
166             oso_sp (),
167             compile_unit_sp (),
168             first_symbol_index (UINT32_MAX),
169             last_symbol_index (UINT32_MAX),
170             first_symbol_id (UINT32_MAX),
171             last_symbol_id (UINT32_MAX),
172             file_range_map (),
173             file_range_map_valid (false)
174         {
175         }
176 
177         const FileRangeMap &
178         GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
179     };
180 
181     //------------------------------------------------------------------
182     // Protected Member Functions
183     //------------------------------------------------------------------
184     void
185     InitOSO ();
186 
187     static uint32_t
188     GetOSOIndexFromUserID (lldb::user_id_t uid)
189     {
190         return (uint32_t)((uid >> 32ull) - 1ull);
191     }
192 
193     static SymbolFileDWARF *
194     GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file);
195 
196     bool
197     GetFileSpecForSO (uint32_t oso_idx, lldb_private::FileSpec &file_spec);
198 
199     CompileUnitInfo *
200     GetCompUnitInfo (const lldb_private::SymbolContext& sc);
201 
202     size_t
203     GetCompUnitInfosForModule (const lldb_private::Module *oso_module,
204                                std::vector<CompileUnitInfo *>& cu_infos);
205 
206     lldb_private::Module *
207     GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info);
208 
209     lldb_private::Module *
210     GetModuleByOSOIndex (uint32_t oso_idx);
211 
212     lldb_private::ObjectFile *
213     GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
214 
215     lldb_private::ObjectFile *
216     GetObjectFileByOSOIndex (uint32_t oso_idx);
217 
218     uint32_t
219     GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info);
220 
221     SymbolFileDWARF *
222     GetSymbolFile (const lldb_private::SymbolContext& sc);
223 
224     SymbolFileDWARF *
225     GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
226 
227     SymbolFileDWARF *
228     GetSymbolFileByOSOIndex (uint32_t oso_idx);
229 
230     CompileUnitInfo *
231     GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr);
232 
233     CompileUnitInfo *
234     GetCompileUnitInfoForSymbolWithID (lldb::user_id_t symbol_id, uint32_t *oso_idx_ptr);
235 
236     static int
237     SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
238 
239     static int
240     SymbolContainsSymbolWithID (lldb::user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
241 
242     uint32_t
243     PrivateFindGlobalVariables (const lldb_private::ConstString &name,
244                                 const lldb_private::ClangNamespaceDecl *namespace_decl,
245                                 const std::vector<uint32_t> &name_symbol_indexes,
246                                 uint32_t max_matches,
247                                 lldb_private::VariableList& variables);
248 
249 
250     void
251     SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp);
252 
253     lldb::CompUnitSP
254     GetCompileUnit (SymbolFileDWARF *oso_dwarf);
255 
256     CompileUnitInfo *
257     GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
258 
259     lldb::TypeSP
260     FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
261 
262     bool
263     Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso);
264 
265     lldb::TypeSP
266     FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
267                                           const lldb_private::ConstString &type_name,
268                                           bool must_be_implementation);
269 
270 
271     UniqueDWARFASTTypeMap &
272     GetUniqueDWARFASTTypeMap ()
273     {
274         return m_unique_ast_type_map;
275     }
276 
277 
278     //------------------------------------------------------------------
279     // OSOEntry
280     //------------------------------------------------------------------
281     class OSOEntry
282     {
283     public:
284 
285         OSOEntry () :
286         m_exe_sym_idx (UINT32_MAX),
287         m_oso_file_addr (LLDB_INVALID_ADDRESS)
288         {
289         }
290 
291         OSOEntry (uint32_t exe_sym_idx,
292                   lldb::addr_t oso_file_addr) :
293         m_exe_sym_idx (exe_sym_idx),
294         m_oso_file_addr (oso_file_addr)
295         {
296         }
297 
298         uint32_t
299         GetExeSymbolIndex () const
300         {
301             return m_exe_sym_idx;
302         }
303 
304         bool
305         operator < (const OSOEntry &rhs) const
306         {
307             return m_exe_sym_idx < rhs.m_exe_sym_idx;
308         }
309 
310         lldb::addr_t
311         GetOSOFileAddress () const
312         {
313             return m_oso_file_addr;
314         }
315 
316         void
317         SetOSOFileAddress (lldb::addr_t oso_file_addr)
318         {
319             m_oso_file_addr = oso_file_addr;
320         }
321     protected:
322         uint32_t m_exe_sym_idx;
323         lldb::addr_t m_oso_file_addr;
324     };
325 
326     typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
327 
328     //------------------------------------------------------------------
329     // Member Variables
330     //------------------------------------------------------------------
331     std::bitset<kNumFlags> m_flags;
332     std::vector<CompileUnitInfo> m_compile_unit_infos;
333     std::vector<uint32_t> m_func_indexes;   // Sorted by address
334     std::vector<uint32_t> m_glob_indexes;
335     std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
336     UniqueDWARFASTTypeMap m_unique_ast_type_map;
337     lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
338     DebugMap m_debug_map;
339 
340     //------------------------------------------------------------------
341     // When an object file from the debug map gets parsed in
342     // SymbolFileDWARF, it needs to tell the debug map about the object
343     // files addresses by calling this function once for each N_FUN,
344     // N_GSYM and N_STSYM and after all entries in the debug map have
345     // been matched up, FinalizeOSOFileRanges() should be called.
346     //------------------------------------------------------------------
347     bool
348     AddOSOFileRange (CompileUnitInfo *cu_info,
349                      lldb::addr_t exe_file_addr,
350                      lldb::addr_t oso_file_addr,
351                      lldb::addr_t oso_byte_size);
352 
353     //------------------------------------------------------------------
354     // Called after calling AddOSOFileRange() for each object file debug
355     // map entry to finalize the info for the unlinked compile unit.
356     //------------------------------------------------------------------
357     void
358     FinalizeOSOFileRanges (CompileUnitInfo *cu_info);
359 
360     //------------------------------------------------------------------
361     /// Convert \a addr from a .o file address, to an executable address.
362     ///
363     /// @param[in] addr
364     ///     A section offset address from a .o file
365     ///
366     /// @return
367     ///     Returns true if \a addr was converted to be an executable
368     ///     section/offset address, false otherwise.
369     //------------------------------------------------------------------
370     bool
371     LinkOSOAddress (lldb_private::Address &addr);
372 
373     //------------------------------------------------------------------
374     /// Convert a .o file "file address" to an executable "file address".
375     ///
376     /// @param[in] oso_symfile
377     ///     The DWARF symbol file that contains \a oso_file_addr
378     ///
379     /// @param[in] oso_file_addr
380     ///     A .o file "file address" to convert.
381     ///
382     /// @return
383     ///     LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
384     ///     linked executable, otherwise a valid "file address" from the
385     ///     linked executable that contains the debug map.
386     //------------------------------------------------------------------
387     lldb::addr_t
388     LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr);
389 
390     //------------------------------------------------------------------
391     /// Given a line table full of lines with "file adresses" that are
392     /// for a .o file represented by \a oso_symfile, link a new line table
393     /// and return it.
394     ///
395     /// @param[in] oso_symfile
396     ///     The DWARF symbol file that produced the \a line_table
397     ///
398     /// @param[in] addr
399     ///     A section offset address from a .o file
400     ///
401     /// @return
402     ///     Returns a valid line table full of linked addresses, or NULL
403     ///     if none of the line table adresses exist in the main
404     ///     executable.
405     //------------------------------------------------------------------
406     lldb_private::LineTable *
407     LinkOSOLineTable (SymbolFileDWARF *oso_symfile,
408                       lldb_private::LineTable *line_table);
409 };
410 
411 #endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
412