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