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 "lldb/Core/RangeMap.h"
18 #include "lldb/Symbol/SymbolFile.h"
19 
20 #include "UniqueDWARFASTType.h"
21 
22 class SymbolFileDWARF;
23 class DWARFDebugAranges;
24 class DWARFDeclContext;
25 
26 class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile
27 {
28 public:
29 
30     //------------------------------------------------------------------
31     // Static Functions
32     //------------------------------------------------------------------
33     static void
34     Initialize();
35 
36     static void
37     Terminate();
38 
39     static lldb_private::ConstString
40     GetPluginNameStatic();
41 
42     static const char *
43     GetPluginDescriptionStatic();
44 
45     static lldb_private::SymbolFile *
46     CreateInstance (lldb_private::ObjectFile* obj_file);
47 
48     //------------------------------------------------------------------
49     // Constructors and Destructors
50     //------------------------------------------------------------------
51     SymbolFileDWARFDebugMap (lldb_private::ObjectFile* ofile);
52     ~SymbolFileDWARFDebugMap () override;
53 
54     uint32_t        CalculateAbilities () override;
55     void            InitializeObject() override;
56 
57     //------------------------------------------------------------------
58     // Compile Unit function calls
59     //------------------------------------------------------------------
60     uint32_t        GetNumCompileUnits () override;
61     lldb::CompUnitSP ParseCompileUnitAtIndex (uint32_t index) override;
62 
63     lldb::LanguageType ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc) override;
64     size_t          ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc) override;
65     bool            ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc) override;
66     bool            ParseCompileUnitDebugMacros (const lldb_private::SymbolContext& sc) override;
67     bool            ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files) override;
68     bool            ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) override;
69     size_t          ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override;
70     size_t          ParseTypes (const lldb_private::SymbolContext& sc) override;
71     size_t          ParseVariablesForContext (const lldb_private::SymbolContext& sc) override;
72 
73     lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid) override;
74     lldb_private::CompilerDeclContext GetDeclContextForUID (lldb::user_id_t uid) override;
75     lldb_private::CompilerDeclContext GetDeclContextContainingUID (lldb::user_id_t uid) override;
76     void ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override;
77 
78     bool            CompleteType (lldb_private::CompilerType& compiler_type) override;
79     uint32_t        ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc) override;
80     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;
81     uint32_t        FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override;
82     uint32_t        FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override;
83     uint32_t        FindFunctions (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override;
84     uint32_t        FindFunctions (const lldb_private::RegularExpression& regex, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override;
85     uint32_t        FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap& types) override;
86     lldb_private::CompilerDeclContext
87                     FindNamespace (const lldb_private::SymbolContext& sc,
88                                    const lldb_private::ConstString &name,
89                                    const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
90     size_t          GetTypes (lldb_private::SymbolContextScope *sc_scope,
91                               uint32_t type_mask,
92                               lldb_private::TypeList &type_list) override;
93 
94     //------------------------------------------------------------------
95     // PluginInterface protocol
96     //------------------------------------------------------------------
97     lldb_private::ConstString
98     GetPluginName() override;
99 
100     uint32_t
101     GetPluginVersion() override;
102 
103 protected:
104     enum
105     {
106         kHaveInitializedOSOs = (1 << 0),
107         kNumFlags
108     };
109 
110     friend class DebugMapModule;
111     friend struct DIERef;
112     friend class DWARFASTParserClang;
113     friend class DWARFCompileUnit;
114     friend class SymbolFileDWARF;
115     struct OSOInfo
116     {
117         lldb::ModuleSP module_sp;
118 
119         OSOInfo() :
120             module_sp ()
121         {
122         }
123     };
124 
125     typedef std::shared_ptr<OSOInfo> OSOInfoSP;
126 
127     typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
128 
129     //------------------------------------------------------------------
130     // Class specific types
131     //------------------------------------------------------------------
132     struct CompileUnitInfo
133     {
134         lldb_private::FileSpec so_file;
135         lldb_private::ConstString oso_path;
136         lldb_private::TimeValue oso_mod_time;
137         OSOInfoSP oso_sp;
138         lldb::CompUnitSP compile_unit_sp;
139         uint32_t first_symbol_index;
140         uint32_t last_symbol_index;
141         uint32_t first_symbol_id;
142         uint32_t last_symbol_id;
143         FileRangeMap file_range_map;
144         bool file_range_map_valid;
145 
146 
147         CompileUnitInfo() :
148             so_file (),
149             oso_path (),
150             oso_mod_time (),
151             oso_sp (),
152             compile_unit_sp (),
153             first_symbol_index (UINT32_MAX),
154             last_symbol_index (UINT32_MAX),
155             first_symbol_id (UINT32_MAX),
156             last_symbol_id (UINT32_MAX),
157             file_range_map (),
158             file_range_map_valid (false)
159         {
160         }
161 
162         const FileRangeMap &
163         GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
164     };
165 
166     //------------------------------------------------------------------
167     // Protected Member Functions
168     //------------------------------------------------------------------
169     void
170     InitOSO ();
171 
172     static uint32_t
173     GetOSOIndexFromUserID (lldb::user_id_t uid)
174     {
175         return (uint32_t)((uid >> 32ull) - 1ull);
176     }
177 
178     static SymbolFileDWARF *
179     GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file);
180 
181     bool
182     GetFileSpecForSO (uint32_t oso_idx, lldb_private::FileSpec &file_spec);
183 
184     CompileUnitInfo *
185     GetCompUnitInfo (const lldb_private::SymbolContext& sc);
186 
187     size_t
188     GetCompUnitInfosForModule (const lldb_private::Module *oso_module,
189                                std::vector<CompileUnitInfo *>& cu_infos);
190 
191     lldb_private::Module *
192     GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info);
193 
194     lldb_private::Module *
195     GetModuleByOSOIndex (uint32_t oso_idx);
196 
197     lldb_private::ObjectFile *
198     GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
199 
200     lldb_private::ObjectFile *
201     GetObjectFileByOSOIndex (uint32_t oso_idx);
202 
203     uint32_t
204     GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info);
205 
206     SymbolFileDWARF *
207     GetSymbolFile (const lldb_private::SymbolContext& sc);
208 
209     SymbolFileDWARF *
210     GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
211 
212     SymbolFileDWARF *
213     GetSymbolFileByOSOIndex (uint32_t oso_idx);
214 
215     // If closure returns "false", iteration continues.  If it returns
216     // "true", iteration terminates.
217     void
218     ForEachSymbolFile (std::function<bool (SymbolFileDWARF *)> closure)
219     {
220         for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size();
221              oso_idx < num_oso_idxs;
222              ++oso_idx)
223         {
224             if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx))
225             {
226                 if (closure(oso_dwarf))
227                     return;
228             }
229         }
230     }
231 
232     CompileUnitInfo *
233     GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr);
234 
235     CompileUnitInfo *
236     GetCompileUnitInfoForSymbolWithID (lldb::user_id_t symbol_id, uint32_t *oso_idx_ptr);
237 
238     static int
239     SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
240 
241     static int
242     SymbolContainsSymbolWithID (lldb::user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
243 
244     uint32_t
245     PrivateFindGlobalVariables (const lldb_private::ConstString &name,
246                                 const lldb_private::CompilerDeclContext *parent_decl_ctx,
247                                 const std::vector<uint32_t> &name_symbol_indexes,
248                                 uint32_t max_matches,
249                                 lldb_private::VariableList& variables);
250 
251 
252     void
253     SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp);
254 
255     lldb::CompUnitSP
256     GetCompileUnit (SymbolFileDWARF *oso_dwarf);
257 
258     CompileUnitInfo *
259     GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
260 
261     lldb::TypeSP
262     FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
263 
264     bool
265     Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso);
266 
267     lldb::TypeSP
268     FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
269                                           const lldb_private::ConstString &type_name,
270                                           bool must_be_implementation);
271 
272 
273     UniqueDWARFASTTypeMap &
274     GetUniqueDWARFASTTypeMap ()
275     {
276         return m_unique_ast_type_map;
277     }
278 
279 
280     //------------------------------------------------------------------
281     // OSOEntry
282     //------------------------------------------------------------------
283     class OSOEntry
284     {
285     public:
286 
287         OSOEntry () :
288         m_exe_sym_idx (UINT32_MAX),
289         m_oso_file_addr (LLDB_INVALID_ADDRESS)
290         {
291         }
292 
293         OSOEntry (uint32_t exe_sym_idx,
294                   lldb::addr_t oso_file_addr) :
295         m_exe_sym_idx (exe_sym_idx),
296         m_oso_file_addr (oso_file_addr)
297         {
298         }
299 
300         uint32_t
301         GetExeSymbolIndex () const
302         {
303             return m_exe_sym_idx;
304         }
305 
306         bool
307         operator < (const OSOEntry &rhs) const
308         {
309             return m_exe_sym_idx < rhs.m_exe_sym_idx;
310         }
311 
312         lldb::addr_t
313         GetOSOFileAddress () const
314         {
315             return m_oso_file_addr;
316         }
317 
318         void
319         SetOSOFileAddress (lldb::addr_t oso_file_addr)
320         {
321             m_oso_file_addr = oso_file_addr;
322         }
323     protected:
324         uint32_t m_exe_sym_idx;
325         lldb::addr_t m_oso_file_addr;
326     };
327 
328     typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
329 
330     //------------------------------------------------------------------
331     // Member Variables
332     //------------------------------------------------------------------
333     std::bitset<kNumFlags> m_flags;
334     std::vector<CompileUnitInfo> m_compile_unit_infos;
335     std::vector<uint32_t> m_func_indexes;   // Sorted by address
336     std::vector<uint32_t> m_glob_indexes;
337     std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
338     UniqueDWARFASTTypeMap m_unique_ast_type_map;
339     lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
340     DebugMap m_debug_map;
341 
342     //------------------------------------------------------------------
343     // When an object file from the debug map gets parsed in
344     // SymbolFileDWARF, it needs to tell the debug map about the object
345     // files addresses by calling this function once for each N_FUN,
346     // N_GSYM and N_STSYM and after all entries in the debug map have
347     // been matched up, FinalizeOSOFileRanges() should be called.
348     //------------------------------------------------------------------
349     bool
350     AddOSOFileRange (CompileUnitInfo *cu_info,
351                      lldb::addr_t exe_file_addr,
352                      lldb::addr_t exe_byte_size,
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