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 DWARFDebugAranges;
27 class DWARFDebugInfoEntry;
28 class DWARFDeclContext;
29 class DebugMapModule;
30 
31 class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile
32 {
33 public:
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 
125 protected:
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 
OSOInfoOSOInfo139         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 
CompileUnitInfoCompileUnitInfo167         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
GetOSOIndexFromUserID(lldb::user_id_t uid)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 &
GetUniqueDWARFASTTypeMap()277     GetUniqueDWARFASTTypeMap ()
278     {
279         return m_unique_ast_type_map;
280     }
281 
282 
283     //------------------------------------------------------------------
284     // OSOEntry
285     //------------------------------------------------------------------
286     class OSOEntry
287     {
288     public:
289 
OSOEntry()290         OSOEntry () :
291         m_exe_sym_idx (UINT32_MAX),
292         m_oso_file_addr (LLDB_INVALID_ADDRESS)
293         {
294         }
295 
OSOEntry(uint32_t exe_sym_idx,lldb::addr_t oso_file_addr)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
GetExeSymbolIndex()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
GetOSOFileAddress()316         GetOSOFileAddress () const
317         {
318             return m_oso_file_addr;
319         }
320 
321         void
SetOSOFileAddress(lldb::addr_t oso_file_addr)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