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