blob: 3087bde65d5d852b86188a94ca8bfd3505807d8b [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolFileDWARFDebugMap.cpp ----------------------------*- 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#include "SymbolFileDWARFDebugMap.h"
11
Enrico Granatac76e60b2013-06-27 01:43:09 +000012#include "DWARFDebugAranges.h"
13
14#include "lldb/Core/RangeMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Core/Module.h"
16#include "lldb/Core/ModuleList.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Core/RegularExpression.h"
Greg Clayton1f746072012-08-29 21:13:06 +000019#include "lldb/Core/Section.h"
Greg Clayton9422dd62013-03-04 21:46:16 +000020
21//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
Greg Clayton1f746072012-08-29 21:13:06 +000022#if defined(DEBUG_OSO_DMAP)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/StreamFile.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/Timer.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000026
27#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Greg Clayton1f746072012-08-29 21:13:06 +000028#include "lldb/Symbol/CompileUnit.h"
Greg Clayton9422dd62013-03-04 21:46:16 +000029#include "lldb/Symbol/LineTable.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Symbol/ObjectFile.h"
31#include "lldb/Symbol/SymbolVendor.h"
32#include "lldb/Symbol/VariableList.h"
33
Sean Callanan60217122012-04-13 00:10:03 +000034#include "LogChannelDWARF.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "SymbolFileDWARF.h"
36
37using namespace lldb;
38using namespace lldb_private;
39
Greg Clayton1f746072012-08-29 21:13:06 +000040// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
41// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
42// (so we can fixup the symbol file id.
43
Greg Clayton9422dd62013-03-04 21:46:16 +000044
45
46
47const SymbolFileDWARFDebugMap::FileRangeMap &
48SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
49{
50 if (file_range_map_valid)
51 return file_range_map;
52
53 file_range_map_valid = true;
54
55 Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
Jim Ingham199e4f72013-03-13 01:34:14 +000056 if (!oso_module)
57 return file_range_map;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000058
Greg Clayton9422dd62013-03-04 21:46:16 +000059 ObjectFile *oso_objfile = oso_module->GetObjectFile();
Greg Clayton8caea6d2013-05-22 00:10:28 +000060 if (!oso_objfile)
61 return file_range_map;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000062
Greg Clayton5160ce52013-03-27 23:08:40 +000063 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
Greg Clayton9422dd62013-03-04 21:46:16 +000064 if (log)
65 {
66 ConstString object_name (oso_module->GetObjectName());
Greg Claytonb5ad4ec2013-04-29 17:25:54 +000067 log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000068 static_cast<void*>(this),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +000069 oso_module->GetSpecificationDescription().c_str());
Greg Clayton9422dd62013-03-04 21:46:16 +000070 }
Greg Clayton9422dd62013-03-04 21:46:16 +000071
72 std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
73 if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
74 {
75 for (auto comp_unit_info : cu_infos)
76 {
Greg Clayton3046e662013-07-10 01:23:25 +000077 Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
Greg Clayton9422dd62013-03-04 21:46:16 +000078 ModuleSP oso_module_sp (oso_objfile->GetModule());
Greg Clayton3046e662013-07-10 01:23:25 +000079 Symtab *oso_symtab = oso_objfile->GetSymtab();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000080
Greg Clayton9422dd62013-03-04 21:46:16 +000081 ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
82 //SectionList *oso_sections = oso_objfile->Sections();
83 // Now we need to make sections that map from zero based object
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +000084 // file addresses to where things ended up in the main executable.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000085
Greg Clayton9422dd62013-03-04 21:46:16 +000086 assert (comp_unit_info->first_symbol_index != UINT32_MAX);
87 // End index is one past the last valid symbol index
88 const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
89 for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
90 idx < oso_end_idx;
91 ++idx)
92 {
93 Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
94 if (exe_symbol)
95 {
96 if (exe_symbol->IsDebug() == false)
97 continue;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000098
Greg Clayton9422dd62013-03-04 21:46:16 +000099 switch (exe_symbol->GetType())
100 {
101 default:
102 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000103
Greg Clayton9422dd62013-03-04 21:46:16 +0000104 case eSymbolTypeCode:
105 {
106 // For each N_FUN, or function that we run into in the debug map
107 // we make a new section that we add to the sections found in the
108 // .o file. This new section has the file address set to what the
109 // addresses are in the .o file, and the load address is adjusted
110 // to match where it ended up in the final executable! We do this
111 // before we parse any dwarf info so that when it goes get parsed
112 // all section/offset addresses that get registered will resolve
113 // correctly to the new addresses in the main executable.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000114
Greg Clayton9422dd62013-03-04 21:46:16 +0000115 // First we find the original symbol in the .o file's symbol table
116 Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
117 eSymbolTypeCode,
118 Symtab::eDebugNo,
119 Symtab::eVisibilityAny);
120 if (oso_fun_symbol)
121 {
122 // Add the inverse OSO file address to debug map entry mapping
123 exe_symfile->AddOSOFileRange (this,
124 exe_symbol->GetAddress().GetFileAddress(),
125 oso_fun_symbol->GetAddress().GetFileAddress(),
126 std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000127
Greg Clayton9422dd62013-03-04 21:46:16 +0000128 }
129 }
130 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000131
Greg Clayton9422dd62013-03-04 21:46:16 +0000132 case eSymbolTypeData:
133 {
134 // For each N_GSYM we remap the address for the global by making
135 // a new section that we add to the sections found in the .o file.
136 // This new section has the file address set to what the
137 // addresses are in the .o file, and the load address is adjusted
138 // to match where it ended up in the final executable! We do this
139 // before we parse any dwarf info so that when it goes get parsed
140 // all section/offset addresses that get registered will resolve
141 // correctly to the new addresses in the main executable. We
142 // initially set the section size to be 1 byte, but will need to
143 // fix up these addresses further after all globals have been
144 // parsed to span the gaps, or we can find the global variable
145 // sizes from the DWARF info as we are parsing.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000146
Greg Clayton9422dd62013-03-04 21:46:16 +0000147 // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
148 Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
149 eSymbolTypeData,
150 Symtab::eDebugNo,
151 Symtab::eVisibilityAny);
Greg Clayton9422dd62013-03-04 21:46:16 +0000152 if (exe_symbol && oso_gsym_symbol &&
153 exe_symbol->ValueIsAddress() &&
154 oso_gsym_symbol->ValueIsAddress())
155 {
156 // Add the inverse OSO file address to debug map entry mapping
157 exe_symfile->AddOSOFileRange (this,
158 exe_symbol->GetAddress().GetFileAddress(),
159 oso_gsym_symbol->GetAddress().GetFileAddress(),
160 std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
161 }
162 }
163 break;
164 }
165 }
166 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000167
Greg Clayton9422dd62013-03-04 21:46:16 +0000168 exe_symfile->FinalizeOSOFileRanges (this);
Greg Clayton9422dd62013-03-04 21:46:16 +0000169 // We don't need the symbols anymore for the .o files
Greg Clayton3046e662013-07-10 01:23:25 +0000170 oso_objfile->ClearSymtab();
Greg Clayton9422dd62013-03-04 21:46:16 +0000171 }
172 }
173 return file_range_map;
174}
175
176
Greg Clayton1f746072012-08-29 21:13:06 +0000177class DebugMapModule : public Module
178{
179public:
180 DebugMapModule (const ModuleSP &exe_module_sp,
181 uint32_t cu_idx,
182 const FileSpec& file_spec,
183 const ArchSpec& arch,
184 const ConstString *object_name,
Greg Clayton57abc5d2013-05-10 21:47:16 +0000185 off_t object_offset,
186 const TimeValue *object_mod_time_ptr) :
187 Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
Greg Clayton1f746072012-08-29 21:13:06 +0000188 m_exe_module_wp (exe_module_sp),
189 m_cu_idx (cu_idx)
190 {
191 }
192
Greg Clayton9ba42d12012-10-08 22:48:57 +0000193 virtual
194 ~DebugMapModule ()
195 {
196 }
197
Greg Clayton1f746072012-08-29 21:13:06 +0000198
199 virtual SymbolVendor*
Greg Clayton136dff82012-12-14 02:15:00 +0000200 GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
Greg Clayton1f746072012-08-29 21:13:06 +0000201 {
202 // Scope for locker
203 if (m_symfile_ap.get() || can_create == false)
204 return m_symfile_ap.get();
205
206 ModuleSP exe_module_sp (m_exe_module_wp.lock());
207 if (exe_module_sp)
208 {
209 // Now get the object file outside of a locking scope
210 ObjectFile *oso_objfile = GetObjectFile ();
211 if (oso_objfile)
212 {
213 Mutex::Locker locker (m_mutex);
Greg Clayton136dff82012-12-14 02:15:00 +0000214 SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
Greg Clayton1f746072012-08-29 21:13:06 +0000215 if (symbol_vendor)
216 {
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +0000217 // Set a pointer to this class to set our OSO DWARF file know
Greg Clayton1f746072012-08-29 21:13:06 +0000218 // that the DWARF is being used along with a debug map and that
219 // it will have the remapped sections that we do below.
Greg Clayton57abc5d2013-05-10 21:47:16 +0000220 SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
Greg Clayton1f746072012-08-29 21:13:06 +0000221
222 if (!oso_symfile)
223 return NULL;
224
225 ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
226 SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
227
228 if (exe_objfile && exe_sym_vendor)
229 {
230 if (oso_symfile->GetNumCompileUnits() == 1)
231 {
232 oso_symfile->SetDebugMapModule(exe_module_sp);
233 // Set the ID of the symbol file DWARF to the index of the OSO
234 // shifted left by 32 bits to provide a unique prefix for any
235 // UserID's that get created in the symbol file.
236 oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
237 }
238 else
239 {
240 oso_symfile->SetID (UINT64_MAX);
241 }
242 }
243 return symbol_vendor;
244 }
245 }
246 }
247 return NULL;
248 }
249
250protected:
251 ModuleWP m_exe_module_wp;
252 const uint32_t m_cu_idx;
253};
254
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255void
256SymbolFileDWARFDebugMap::Initialize()
257{
258 PluginManager::RegisterPlugin (GetPluginNameStatic(),
259 GetPluginDescriptionStatic(),
260 CreateInstance);
261}
262
263void
264SymbolFileDWARFDebugMap::Terminate()
265{
266 PluginManager::UnregisterPlugin (CreateInstance);
267}
268
269
Greg Clayton57abc5d2013-05-10 21:47:16 +0000270lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271SymbolFileDWARFDebugMap::GetPluginNameStatic()
272{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000273 static ConstString g_name("dwarf-debugmap");
274 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275}
276
277const char *
278SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
279{
280 return "DWARF and DWARF3 debug symbol file reader (debug map).";
281}
282
283SymbolFile*
284SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
285{
286 return new SymbolFileDWARFDebugMap (obj_file);
287}
288
289
290SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
291 SymbolFile(ofile),
292 m_flags(),
293 m_compile_unit_infos(),
294 m_func_indexes(),
Greg Claytonc7f03b62012-01-12 04:33:28 +0000295 m_glob_indexes(),
296 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297{
298}
299
300
301SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
302{
303}
304
Greg Clayton6beaaa62011-01-17 03:46:26 +0000305void
306SymbolFileDWARFDebugMap::InitializeObject()
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000307{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000308 // Install our external AST source callbacks so we can complete Clang types.
Todd Fiala955fe6f2014-02-27 17:18:23 +0000309 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap (
Greg Clayton6beaaa62011-01-17 03:46:26 +0000310 new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl,
311 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000312 NULL,
Greg Claytoncaab74e2012-01-28 00:48:57 +0000313 SymbolFileDWARFDebugMap::LayoutRecordType,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000314 this));
315
316 GetClangASTContext().SetExternalSource (ast_source_ap);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000317}
318
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319void
Greg Clayton1f746072012-08-29 21:13:06 +0000320SymbolFileDWARFDebugMap::InitOSO()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321{
322 if (m_flags.test(kHaveInitializedOSOs))
323 return;
Greg Clayton9422dd62013-03-04 21:46:16 +0000324
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 m_flags.set(kHaveInitializedOSOs);
Greg Clayton3046e662013-07-10 01:23:25 +0000326
327 // If the object file has been stripped, there is no sense in looking further
328 // as all of the debug symbols for the debug map will not be available
329 if (m_obj_file->IsStripped())
330 return;
331
332 // Also make sure the file type is some sort of executable. Core files, debug
333 // info files (dSYM), object files (.o files), and stub libraries all can
334 switch (m_obj_file->GetType())
335 {
336 case ObjectFile::eTypeInvalid:
337 case ObjectFile::eTypeCoreFile:
338 case ObjectFile::eTypeDebugInfo:
339 case ObjectFile::eTypeObjectFile:
340 case ObjectFile::eTypeStubLibrary:
341 case ObjectFile::eTypeUnknown:
Greg Clayton23f8c952014-03-24 23:10:19 +0000342 case ObjectFile::eTypeJIT:
Greg Clayton3046e662013-07-10 01:23:25 +0000343 return;
344
345 case ObjectFile::eTypeExecutable:
346 case ObjectFile::eTypeDynamicLinker:
347 case ObjectFile::eTypeSharedLibrary:
348 break;
349 }
350
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351 // In order to get the abilities of this plug-in, we look at the list of
352 // N_OSO entries (object files) from the symbol table and make sure that
353 // these files exist and also contain valid DWARF. If we get any of that
354 // then we return the abilities of the first N_OSO's DWARF.
355
Greg Clayton3046e662013-07-10 01:23:25 +0000356 Symtab* symtab = m_obj_file->GetSymtab();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357 if (symtab)
358 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000359 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
Sean Callanan60217122012-04-13 00:10:03 +0000360
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 std::vector<uint32_t> oso_indexes;
Greg Clayton16b2d2b2011-01-20 06:08:59 +0000362 // When a mach-o symbol is encoded, the n_type field is encoded in bits
363 // 23:16, and the n_desc field is encoded in bits 15:0.
364 //
365 // To find all N_OSO entries that are part of the DWARF + debug map
366 // we find only object file symbols with the flags value as follows:
367 // bits 23:16 == 0x66 (N_OSO)
368 // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
369 const uint32_t k_oso_symbol_flags_value = 0x660001u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370
Greg Clayton16b2d2b2011-01-20 06:08:59 +0000371 const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372
373 if (oso_index_count > 0)
374 {
Greg Clayton16b2d2b2011-01-20 06:08:59 +0000375 symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
376 symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
377
378 symtab->SortSymbolIndexesByValue(m_func_indexes, true);
379 symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
380
Greg Clayton9422dd62013-03-04 21:46:16 +0000381 for (uint32_t sym_idx : m_func_indexes)
382 {
383 const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
384 lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
385 lldb::addr_t byte_size = symbol->GetByteSize();
386 DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
387 m_debug_map.Append(debug_map_entry);
388 }
389 for (uint32_t sym_idx : m_glob_indexes)
390 {
391 const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
392 lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
Greg Clayton3046e662013-07-10 01:23:25 +0000393 lldb::addr_t byte_size = symbol->GetByteSize();
Greg Clayton9422dd62013-03-04 21:46:16 +0000394 DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
395 m_debug_map.Append(debug_map_entry);
396 }
397 m_debug_map.Sort();
398
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399 m_compile_unit_infos.resize(oso_index_count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400
401 for (uint32_t i=0; i<oso_index_count; ++i)
402 {
Greg Clayton906ba472013-02-06 00:38:25 +0000403 const uint32_t so_idx = oso_indexes[i] - 1;
Greg Clayton61f39ce2013-02-05 18:40:36 +0000404 const uint32_t oso_idx = oso_indexes[i];
Greg Clayton906ba472013-02-06 00:38:25 +0000405 const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
Greg Clayton61f39ce2013-02-05 18:40:36 +0000406 const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
407 if (so_symbol &&
408 oso_symbol &&
409 so_symbol->GetType() == eSymbolTypeSourceFile &&
410 oso_symbol->GetType() == eSymbolTypeObjectFile)
Greg Claytonb9cafbb2012-07-17 20:18:12 +0000411 {
Greg Clayton613641d2013-03-08 21:46:30 +0000412 m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
Greg Clayton906ba472013-02-06 00:38:25 +0000413 m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
Greg Clayton57abc5d2013-05-10 21:47:16 +0000414 TimeValue oso_mod_time;
415 oso_mod_time.OffsetWithSeconds(oso_symbol->GetAddress().GetOffset());
416 m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
Greg Clayton61f39ce2013-02-05 18:40:36 +0000417 uint32_t sibling_idx = so_symbol->GetSiblingIndex();
418 // The sibling index can't be less that or equal to the current index "i"
Greg Claytonbc63aac2015-02-25 22:41:34 +0000419 if (sibling_idx == UINT32_MAX)
Greg Clayton61f39ce2013-02-05 18:40:36 +0000420 {
421 m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
422 }
423 else
424 {
425 const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
Greg Clayton906ba472013-02-06 00:38:25 +0000426 m_compile_unit_infos[i].first_symbol_index = so_idx;
427 m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
Greg Clayton61f39ce2013-02-05 18:40:36 +0000428 m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
429 m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
430
431 if (log)
432 log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
433 }
Greg Claytonb9cafbb2012-07-17 20:18:12 +0000434 }
435 else
436 {
Greg Clayton61f39ce2013-02-05 18:40:36 +0000437 if (oso_symbol == NULL)
438 m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx);
439 else if (so_symbol == NULL)
440 m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx);
441 else if (so_symbol->GetType() != eSymbolTypeSourceFile)
442 m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx);
443 else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
444 m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx);
Greg Claytonb9cafbb2012-07-17 20:18:12 +0000445 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446 }
447 }
448 }
449}
450
451Module *
452SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
453{
454 const uint32_t cu_count = GetNumCompileUnits();
455 if (oso_idx < cu_count)
456 return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
457 return NULL;
458}
459
460Module *
461SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
462{
Greg Clayton906ba472013-02-06 00:38:25 +0000463 if (!comp_unit_info->oso_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464 {
Greg Clayton906ba472013-02-06 00:38:25 +0000465 auto pos = m_oso_map.find (comp_unit_info->oso_path);
466 if (pos != m_oso_map.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467 {
Greg Clayton906ba472013-02-06 00:38:25 +0000468 comp_unit_info->oso_sp = pos->second;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469 }
Greg Clayton906ba472013-02-06 00:38:25 +0000470 else
471 {
Greg Clayton57abc5d2013-05-10 21:47:16 +0000472 ObjectFile *obj_file = GetObjectFile();
Greg Clayton906ba472013-02-06 00:38:25 +0000473 comp_unit_info->oso_sp.reset (new OSOInfo());
474 m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
475 const char *oso_path = comp_unit_info->oso_path.GetCString();
Greg Clayton96b68662013-03-23 00:50:06 +0000476 FileSpec oso_file (oso_path, false);
Greg Clayton906ba472013-02-06 00:38:25 +0000477 ConstString oso_object;
Greg Clayton57abc5d2013-05-10 21:47:16 +0000478 if (oso_file.Exists())
479 {
480 TimeValue oso_mod_time (oso_file.GetModificationTime());
481 if (oso_mod_time != comp_unit_info->oso_mod_time)
482 {
483 obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored",
484 oso_file.GetPath().c_str(),
485 oso_mod_time.GetAsSecondsSinceJan1_1970(),
486 comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
487 return NULL;
488 }
489
490 }
491 else
Greg Clayton906ba472013-02-06 00:38:25 +0000492 {
493 const bool must_exist = true;
494
495 if (!ObjectFile::SplitArchivePathWithObject (oso_path,
496 oso_file,
497 oso_object,
498 must_exist))
499 {
Greg Clayton906ba472013-02-06 00:38:25 +0000500 return NULL;
501 }
502 }
503 // Always create a new module for .o files. Why? Because we
504 // use the debug map, to add new sections to each .o file and
505 // even though a .o file might not have changed, the sections
506 // that get added to the .o file can change.
Greg Clayton3f19ada2014-07-10 23:33:37 +0000507 ArchSpec oso_arch;
508 // Only adopt the architecture from the module (not the vendor or OS)
509 // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx"
510 // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
511 // load command...
512 oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str());
Greg Clayton57abc5d2013-05-10 21:47:16 +0000513 comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
Greg Clayton906ba472013-02-06 00:38:25 +0000514 GetCompUnitInfoIndex(comp_unit_info),
515 oso_file,
Greg Clayton3f19ada2014-07-10 23:33:37 +0000516 oso_arch,
Greg Clayton906ba472013-02-06 00:38:25 +0000517 oso_object ? &oso_object : NULL,
Greg Clayton57abc5d2013-05-10 21:47:16 +0000518 0,
519 oso_object ? &comp_unit_info->oso_mod_time : NULL));
Greg Clayton906ba472013-02-06 00:38:25 +0000520 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521 }
Greg Clayton906ba472013-02-06 00:38:25 +0000522 if (comp_unit_info->oso_sp)
523 return comp_unit_info->oso_sp->module_sp.get();
524 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525}
526
527
528bool
529SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
530{
531 if (oso_idx < m_compile_unit_infos.size())
532 {
Greg Clayton1f746072012-08-29 21:13:06 +0000533 if (m_compile_unit_infos[oso_idx].so_file)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534 {
Greg Clayton1f746072012-08-29 21:13:06 +0000535 file_spec = m_compile_unit_infos[oso_idx].so_file;
536 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000537 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538 }
539 return false;
540}
541
542
543
544ObjectFile *
545SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
546{
547 Module *oso_module = GetModuleByOSOIndex (oso_idx);
548 if (oso_module)
549 return oso_module->GetObjectFile();
550 return NULL;
551}
552
553SymbolFileDWARF *
554SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
555{
556 CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
557 if (comp_unit_info)
558 return GetSymbolFileByCompUnitInfo (comp_unit_info);
559 return NULL;
560}
561
562ObjectFile *
563SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
564{
565 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
566 if (oso_module)
567 return oso_module->GetObjectFile();
568 return NULL;
569}
570
Greg Clayton81c22f62011-10-19 18:09:39 +0000571
572uint32_t
573SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
574{
575 if (!m_compile_unit_infos.empty())
576 {
577 const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
578 const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
579 if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
580 return comp_unit_info - first_comp_unit_info;
581 }
582 return UINT32_MAX;
583}
584
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000585SymbolFileDWARF *
586SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
587{
588 if (oso_idx < m_compile_unit_infos.size())
589 return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
590 return NULL;
591}
592
593SymbolFileDWARF *
Greg Clayton57abc5d2013-05-10 21:47:16 +0000594SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
595{
596 if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
597 return (SymbolFileDWARF *)sym_file;
598 return NULL;
599}
600
601SymbolFileDWARF *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
603{
Greg Clayton1f746072012-08-29 21:13:06 +0000604 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
605 if (oso_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606 {
Greg Clayton1f746072012-08-29 21:13:06 +0000607 SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
608 if (sym_vendor)
Greg Clayton57abc5d2013-05-10 21:47:16 +0000609 return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000611 return NULL;
612}
613
614uint32_t
Sean Callananbfaf54d2011-12-03 04:38:43 +0000615SymbolFileDWARFDebugMap::CalculateAbilities ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000616{
617 // In order to get the abilities of this plug-in, we look at the list of
618 // N_OSO entries (object files) from the symbol table and make sure that
619 // these files exist and also contain valid DWARF. If we get any of that
620 // then we return the abilities of the first N_OSO's DWARF.
621
622 const uint32_t oso_index_count = GetNumCompileUnits();
623 if (oso_index_count > 0)
624 {
Greg Clayton1f746072012-08-29 21:13:06 +0000625 InitOSO();
626 if (!m_compile_unit_infos.empty())
Greg Clayton3046e662013-07-10 01:23:25 +0000627 {
628 return SymbolFile::CompileUnits |
629 SymbolFile::Functions |
630 SymbolFile::Blocks |
631 SymbolFile::GlobalVariables |
632 SymbolFile::LocalVariables |
633 SymbolFile::VariableTypes |
634 SymbolFile::LineTables ;
635 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636 }
637 return 0;
638}
639
640uint32_t
641SymbolFileDWARFDebugMap::GetNumCompileUnits()
642{
643 InitOSO ();
644 return m_compile_unit_infos.size();
645}
646
647
648CompUnitSP
649SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
650{
651 CompUnitSP comp_unit_sp;
652 const uint32_t cu_count = GetNumCompileUnits();
653
654 if (cu_idx < cu_count)
655 {
Greg Clayton906ba472013-02-06 00:38:25 +0000656 Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
657 if (oso_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000658 {
Greg Clayton1f746072012-08-29 21:13:06 +0000659 FileSpec so_file_spec;
660 if (GetFileSpecForSO (cu_idx, so_file_spec))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661 {
Greg Clayton9422dd62013-03-04 21:46:16 +0000662 // User zero as the ID to match the compile unit at offset
663 // zero in each .o file since each .o file can only have
664 // one compile unit for now.
665 lldb::user_id_t cu_id = 0;
666 m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
667 NULL,
668 so_file_spec,
669 cu_id,
670 eLanguageTypeUnknown));
Greg Clayton1f746072012-08-29 21:13:06 +0000671
Greg Clayton906ba472013-02-06 00:38:25 +0000672 if (m_compile_unit_infos[cu_idx].compile_unit_sp)
Greg Clayton1f746072012-08-29 21:13:06 +0000673 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000674 // Let our symbol vendor know about this compile unit
Greg Clayton9422dd62013-03-04 21:46:16 +0000675 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000676 }
677 }
678 }
Greg Clayton906ba472013-02-06 00:38:25 +0000679 comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000680 }
681
682 return comp_unit_sp;
683}
684
685SymbolFileDWARFDebugMap::CompileUnitInfo *
686SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
687{
688 const uint32_t cu_count = GetNumCompileUnits();
689 for (uint32_t i=0; i<cu_count; ++i)
690 {
Greg Clayton906ba472013-02-06 00:38:25 +0000691 if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000692 return &m_compile_unit_infos[i];
693 }
694 return NULL;
695}
696
Greg Clayton1f746072012-08-29 21:13:06 +0000697
Greg Clayton906ba472013-02-06 00:38:25 +0000698size_t
699SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
Greg Clayton1f746072012-08-29 21:13:06 +0000700{
701 const uint32_t cu_count = GetNumCompileUnits();
702 for (uint32_t i=0; i<cu_count; ++i)
703 {
Greg Clayton906ba472013-02-06 00:38:25 +0000704 if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
705 cu_infos.push_back (&m_compile_unit_infos[i]);
Greg Clayton1f746072012-08-29 21:13:06 +0000706 }
Greg Clayton906ba472013-02-06 00:38:25 +0000707 return cu_infos.size();
Greg Clayton1f746072012-08-29 21:13:06 +0000708}
709
710lldb::LanguageType
711SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
712{
713 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
714 if (oso_dwarf)
715 return oso_dwarf->ParseCompileUnitLanguage (sc);
716 return eLanguageTypeUnknown;
717}
718
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000719size_t
720SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
721{
722 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
723 if (oso_dwarf)
724 return oso_dwarf->ParseCompileUnitFunctions (sc);
725 return 0;
726}
727
728bool
729SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
730{
731 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
732 if (oso_dwarf)
733 return oso_dwarf->ParseCompileUnitLineTable (sc);
734 return false;
735}
736
737bool
738SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
739{
740 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
741 if (oso_dwarf)
742 return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
743 return false;
744}
745
746
747size_t
748SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
749{
750 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
751 if (oso_dwarf)
752 return oso_dwarf->ParseFunctionBlocks (sc);
753 return 0;
754}
755
756
757size_t
758SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
759{
760 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
761 if (oso_dwarf)
762 return oso_dwarf->ParseTypes (sc);
763 return 0;
764}
765
766
767size_t
768SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
769{
770 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
771 if (oso_dwarf)
Greg Clayton1f746072012-08-29 21:13:06 +0000772 return oso_dwarf->ParseVariablesForContext (sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000773 return 0;
774}
775
776
777
778Type*
779SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
780{
Greg Clayton81c22f62011-10-19 18:09:39 +0000781 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
782 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
783 if (oso_dwarf)
Greg Clayton9422dd62013-03-04 21:46:16 +0000784 return oso_dwarf->ResolveTypeUID (type_uid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785 return NULL;
786}
787
Greg Clayton57ee3062013-07-11 22:46:58 +0000788bool
789SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (ClangASTType& clang_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +0000790{
791 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton57ee3062013-07-11 22:46:58 +0000792 return false;
Greg Clayton1be10fc2010-09-29 01:12:09 +0000793}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000794
795uint32_t
796SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
797{
798 uint32_t resolved_flags = 0;
Greg Clayton3046e662013-07-10 01:23:25 +0000799 Symtab* symtab = m_obj_file->GetSymtab();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 if (symtab)
801 {
802 const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000803
Greg Clayton9422dd62013-03-04 21:46:16 +0000804 const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
805 if (debug_map_entry)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000806 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000807
Greg Clayton9422dd62013-03-04 21:46:16 +0000808 sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
809
810 if (sc.symbol != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000811 {
Greg Clayton9422dd62013-03-04 21:46:16 +0000812 resolved_flags |= eSymbolContextSymbol;
813
814 uint32_t oso_idx = 0;
815 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
816 if (comp_unit_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000817 {
Jim Ingham1b57d172013-03-13 00:07:18 +0000818 comp_unit_info->GetFileRangeMap(this);
Greg Clayton9422dd62013-03-04 21:46:16 +0000819 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
820 if (oso_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000821 {
Greg Clayton9422dd62013-03-04 21:46:16 +0000822 lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
823 Address oso_so_addr;
824 if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
825 {
826 resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
827 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000828 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 }
830 }
831 }
832 }
833 return resolved_flags;
834}
835
836
837uint32_t
838SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
839{
Greg Clayton1f746072012-08-29 21:13:06 +0000840 const uint32_t initial = sc_list.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841 const uint32_t cu_count = GetNumCompileUnits();
842
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000843 for (uint32_t i=0; i<cu_count; ++i)
844 {
Greg Clayton1f746072012-08-29 21:13:06 +0000845 // If we are checking for inlines, then we need to look through all
846 // compile units no matter if "file_spec" matches.
847 bool resolve = check_inlines;
848
849 if (!resolve)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000850 {
Greg Clayton1f746072012-08-29 21:13:06 +0000851 FileSpec so_file_spec;
852 if (GetFileSpecForSO (i, so_file_spec))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853 {
Greg Clayton1f746072012-08-29 21:13:06 +0000854 // Match the full path if the incoming file_spec has a directory (not just a basename)
Sean Callananddd7a2a2013-10-03 22:27:29 +0000855 const bool full_match = (bool)file_spec.GetDirectory();
Greg Clayton1f746072012-08-29 21:13:06 +0000856 resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857 }
858 }
Greg Clayton1f746072012-08-29 21:13:06 +0000859 if (resolve)
860 {
861 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
862 if (oso_dwarf)
863 oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
864 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865 }
866 return sc_list.GetSize() - initial;
867}
868
869uint32_t
870SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
871(
872 const ConstString &name,
Sean Callanan213fdb82011-10-13 01:49:10 +0000873 const ClangNamespaceDecl *namespace_decl,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874 const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name"
875 uint32_t max_matches,
876 VariableList& variables
877)
878{
879 const uint32_t original_size = variables.GetSize();
880 const size_t match_count = indexes.size();
881 for (size_t i=0; i<match_count; ++i)
882 {
883 uint32_t oso_idx;
884 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
885 if (comp_unit_info)
886 {
887 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
888 if (oso_dwarf)
889 {
Sean Callanan213fdb82011-10-13 01:49:10 +0000890 if (oso_dwarf->FindGlobalVariables(name, namespace_decl, true, max_matches, variables))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000891 if (variables.GetSize() > max_matches)
892 break;
893 }
894 }
895 }
896 return variables.GetSize() - original_size;
897}
898
899uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000900SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000901{
902
903 // If we aren't appending the results to this list, then clear the list
904 if (!append)
905 variables.Clear();
906
907 // Remember how many variables are in the list before we search in case
908 // we are appending the results to a variable list.
909 const uint32_t original_size = variables.GetSize();
910
Greg Claytonba2d22d2010-11-13 22:57:37 +0000911 uint32_t total_matches = 0;
Sean Callanan0dc848c2015-04-01 20:43:23 +0000912
913 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Sean Callanan213fdb82011-10-13 01:49:10 +0000914 const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
915 namespace_decl,
Sean Callanan0dc848c2015-04-01 20:43:23 +0000916 true,
917 max_matches,
Greg Claytonba2d22d2010-11-13 22:57:37 +0000918 variables);
919 if (oso_matches > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000920 {
Greg Claytonba2d22d2010-11-13 22:57:37 +0000921 total_matches += oso_matches;
Sean Callanan0dc848c2015-04-01 20:43:23 +0000922
Greg Claytonba2d22d2010-11-13 22:57:37 +0000923 // Are we getting all matches?
924 if (max_matches == UINT32_MAX)
Sean Callanan0dc848c2015-04-01 20:43:23 +0000925 return false; // Yep, continue getting everything
926
Greg Claytonba2d22d2010-11-13 22:57:37 +0000927 // If we have found enough matches, lets get out
928 if (max_matches >= total_matches)
Sean Callanan0dc848c2015-04-01 20:43:23 +0000929 return true;
930
Greg Claytonba2d22d2010-11-13 22:57:37 +0000931 // Update the max matches for any subsequent calls to find globals
932 // in any other object files with DWARF
933 max_matches -= oso_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934 }
Sean Callanan0dc848c2015-04-01 20:43:23 +0000935
936 return false;
937 });
938
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939 // Return the number of variable that were appended to the list
940 return variables.GetSize() - original_size;
941}
942
943
944uint32_t
945SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
946{
Greg Claytonba2d22d2010-11-13 22:57:37 +0000947 // If we aren't appending the results to this list, then clear the list
948 if (!append)
949 variables.Clear();
950
951 // Remember how many variables are in the list before we search in case
952 // we are appending the results to a variable list.
953 const uint32_t original_size = variables.GetSize();
954
955 uint32_t total_matches = 0;
Sean Callanan0dc848c2015-04-01 20:43:23 +0000956 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
957 const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
Greg Claytonba2d22d2010-11-13 22:57:37 +0000958 true,
959 max_matches,
960 variables);
961 if (oso_matches > 0)
962 {
963 total_matches += oso_matches;
964
965 // Are we getting all matches?
966 if (max_matches == UINT32_MAX)
Sean Callanan0dc848c2015-04-01 20:43:23 +0000967 return false; // Yep, continue getting everything
Greg Claytonba2d22d2010-11-13 22:57:37 +0000968
969 // If we have found enough matches, lets get out
970 if (max_matches >= total_matches)
Sean Callanan0dc848c2015-04-01 20:43:23 +0000971 return true;
Greg Claytonba2d22d2010-11-13 22:57:37 +0000972
973 // Update the max matches for any subsequent calls to find globals
974 // in any other object files with DWARF
975 max_matches -= oso_matches;
976 }
Sean Callanan0dc848c2015-04-01 20:43:23 +0000977
978 return false;
979 });
980
Greg Claytonba2d22d2010-11-13 22:57:37 +0000981 // Return the number of variable that were appended to the list
982 return variables.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000983}
984
985
986int
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000987SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000988{
989 const uint32_t symbol_idx = *symbol_idx_ptr;
990
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000991 if (symbol_idx < comp_unit_info->first_symbol_index)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000992 return -1;
993
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000994 if (symbol_idx <= comp_unit_info->last_symbol_index)
995 return 0;
996
997 return 1;
998}
999
1000
1001int
1002SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
1003{
1004 const user_id_t symbol_id = *symbol_idx_ptr;
1005
Greg Clayton1f746072012-08-29 21:13:06 +00001006 if (symbol_id < comp_unit_info->first_symbol_id)
Greg Claytonbcf2cfb2010-09-11 03:13:28 +00001007 return -1;
1008
Greg Clayton1f746072012-08-29 21:13:06 +00001009 if (symbol_id <= comp_unit_info->last_symbol_id)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010 return 0;
1011
1012 return 1;
1013}
1014
1015
1016SymbolFileDWARFDebugMap::CompileUnitInfo*
1017SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
1018{
1019 const uint32_t oso_index_count = m_compile_unit_infos.size();
1020 CompileUnitInfo *comp_unit_info = NULL;
1021 if (oso_index_count)
1022 {
Greg Claytone0d378b2011-03-24 21:19:54 +00001023 comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
1024 &m_compile_unit_infos[0],
1025 m_compile_unit_infos.size(),
1026 sizeof(CompileUnitInfo),
1027 (ComparisonFunction)SymbolContainsSymbolWithIndex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001028 }
1029
1030 if (oso_idx_ptr)
1031 {
1032 if (comp_unit_info != NULL)
1033 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1034 else
1035 *oso_idx_ptr = UINT32_MAX;
1036 }
1037 return comp_unit_info;
1038}
1039
Greg Claytonbcf2cfb2010-09-11 03:13:28 +00001040SymbolFileDWARFDebugMap::CompileUnitInfo*
1041SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
1042{
1043 const uint32_t oso_index_count = m_compile_unit_infos.size();
1044 CompileUnitInfo *comp_unit_info = NULL;
1045 if (oso_index_count)
1046 {
Greg Claytone0d378b2011-03-24 21:19:54 +00001047 comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
1048 &m_compile_unit_infos[0],
1049 m_compile_unit_infos.size(),
1050 sizeof(CompileUnitInfo),
1051 (ComparisonFunction)SymbolContainsSymbolWithID);
Greg Claytonbcf2cfb2010-09-11 03:13:28 +00001052 }
1053
1054 if (oso_idx_ptr)
1055 {
1056 if (comp_unit_info != NULL)
1057 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1058 else
1059 *oso_idx_ptr = UINT32_MAX;
1060 }
1061 return comp_unit_info;
1062}
1063
1064
Greg Clayton3ef3fc62010-08-17 23:16:15 +00001065static void
Greg Claytone72dfb32012-02-24 01:59:29 +00001066RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
Greg Clayton3ef3fc62010-08-17 23:16:15 +00001067{
1068 // We found functions in .o files. Not all functions in the .o files
1069 // will have made it into the final output file. The ones that did
1070 // make it into the final output file will have a section whose module
1071 // matches the module from the ObjectFile for this SymbolFile. When
1072 // the modules don't match, then we have something that was in a
1073 // .o file, but doesn't map to anything in the final executable.
1074 uint32_t i=start_idx;
1075 while (i < sc_list.GetSize())
1076 {
1077 SymbolContext sc;
1078 sc_list.GetContextAtIndex(i, sc);
1079 if (sc.function)
1080 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001081 const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
1082 if (section_sp->GetModule() != module_sp)
Greg Clayton3ef3fc62010-08-17 23:16:15 +00001083 {
1084 sc_list.RemoveContextAtIndex(i);
1085 continue;
1086 }
1087 }
1088 ++i;
1089 }
1090}
1091
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001092uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +00001093SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094{
1095 Timer scoped_timer (__PRETTY_FUNCTION__,
1096 "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1097 name.GetCString());
1098
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 uint32_t initial_size = 0;
1100 if (append)
1101 initial_size = sc_list.GetSize();
1102 else
1103 sc_list.Clear();
1104
Sean Callanan0dc848c2015-04-01 20:43:23 +00001105 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Greg Clayton3ef3fc62010-08-17 23:16:15 +00001106 uint32_t sc_idx = sc_list.GetSize();
Sean Callanan9df05fb2012-02-10 22:52:19 +00001107 if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list))
Greg Clayton3ef3fc62010-08-17 23:16:15 +00001108 {
1109 RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1110 }
Sean Callanan0dc848c2015-04-01 20:43:23 +00001111 return false;
1112 });
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001113
1114 return sc_list.GetSize() - initial_size;
1115}
1116
1117
1118uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +00001119SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001120{
1121 Timer scoped_timer (__PRETTY_FUNCTION__,
1122 "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1123 regex.GetText());
1124
Greg Clayton57a6b992010-08-17 00:35:34 +00001125 uint32_t initial_size = 0;
1126 if (append)
1127 initial_size = sc_list.GetSize();
1128 else
1129 sc_list.Clear();
1130
Sean Callanan0dc848c2015-04-01 20:43:23 +00001131 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Greg Clayton3ef3fc62010-08-17 23:16:15 +00001132 uint32_t sc_idx = sc_list.GetSize();
1133
Sean Callanan9df05fb2012-02-10 22:52:19 +00001134 if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
Greg Clayton3ef3fc62010-08-17 23:16:15 +00001135 {
1136 RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1137 }
Sean Callanan0dc848c2015-04-01 20:43:23 +00001138 return false;
1139 });
Greg Clayton57a6b992010-08-17 00:35:34 +00001140
1141 return sc_list.GetSize() - initial_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001142}
1143
Greg Claytonf02500c2013-06-18 22:51:05 +00001144size_t
1145SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
1146 uint32_t type_mask,
1147 TypeList &type_list)
1148{
1149 Timer scoped_timer (__PRETTY_FUNCTION__,
1150 "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1151 type_mask);
1152
1153
1154 uint32_t initial_size = type_list.GetSize();
1155 SymbolFileDWARF *oso_dwarf = NULL;
1156 if (sc_scope)
1157 {
1158 SymbolContext sc;
1159 sc_scope->CalculateSymbolContext(&sc);
1160
1161 CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
1162 if (cu_info)
1163 {
1164 oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
1165 if (oso_dwarf)
1166 oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1167 }
1168 }
1169 else
1170 {
Sean Callanan0dc848c2015-04-01 20:43:23 +00001171 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Greg Claytonf02500c2013-06-18 22:51:05 +00001172 oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
Sean Callanan0dc848c2015-04-01 20:43:23 +00001173 return false;
1174 });
Greg Claytonf02500c2013-06-18 22:51:05 +00001175 }
1176 return type_list.GetSize() - initial_size;
1177}
1178
1179
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00001180TypeSP
Greg Claytona8022fa2012-04-24 21:22:41 +00001181SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00001182{
1183 TypeSP type_sp;
Sean Callanan0dc848c2015-04-01 20:43:23 +00001184 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Greg Claytona8022fa2012-04-24 21:22:41 +00001185 type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
Sean Callanan0dc848c2015-04-01 20:43:23 +00001186 return ((bool)type_sp);
1187 });
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00001188 return type_sp;
1189}
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001190
Greg Clayton901c5ca2011-12-03 04:40:03 +00001191
Greg Claytonc7f03b62012-01-12 04:33:28 +00001192
1193bool
1194SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
1195{
1196 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
1197 {
1198 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
Sean Callanan0dc848c2015-04-01 20:43:23 +00001199 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Greg Claytonc7f03b62012-01-12 04:33:28 +00001200 if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
1201 {
1202 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
Sean Callanan0dc848c2015-04-01 20:43:23 +00001203 return true;
Greg Claytonc7f03b62012-01-12 04:33:28 +00001204 }
Sean Callanan0dc848c2015-04-01 20:43:23 +00001205 return false;
1206 });
Greg Claytonc7f03b62012-01-12 04:33:28 +00001207 }
1208 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1209}
1210
Greg Clayton901c5ca2011-12-03 04:40:03 +00001211TypeSP
Greg Claytonc7f03b62012-01-12 04:33:28 +00001212SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
1213 const ConstString &type_name,
1214 bool must_be_implementation)
Greg Clayton901c5ca2011-12-03 04:40:03 +00001215{
Greg Claytonbc63aac2015-02-25 22:41:34 +00001216 // If we have a debug map, we will have an Objective C symbol whose name is
1217 // the type name and whose type is eSymbolTypeObjCClass. If we can find that
1218 // symbol and find its containing parent, we can locate the .o file that will
1219 // contain the implementation definition since it will be scoped inside the N_SO
1220 // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
1221 SymbolFileDWARF *oso_dwarf = NULL;
Greg Clayton901c5ca2011-12-03 04:40:03 +00001222 TypeSP type_sp;
Greg Claytonbc63aac2015-02-25 22:41:34 +00001223 ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
1224 if (module_objfile)
Greg Clayton901c5ca2011-12-03 04:40:03 +00001225 {
Greg Claytonbc63aac2015-02-25 22:41:34 +00001226 Symtab *symtab = module_objfile->GetSymtab();
1227 if (symtab)
1228 {
1229 Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny);
1230 if (objc_class_symbol)
1231 {
1232 // Get the N_SO symbol that contains the objective C class symbol as this
1233 // should be the .o file that contains the real definition...
1234 const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
1235
1236 if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile)
1237 {
1238 const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol);
1239 if (source_file_symbol_idx != UINT32_MAX)
1240 {
1241 CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL);
1242 if (compile_unit_info)
1243 {
1244 oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info);
1245 if (oso_dwarf)
1246 {
1247 TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
1248 if (type_sp)
1249 {
1250 return type_sp;
1251 }
1252 }
1253 }
1254 }
1255 }
1256 }
1257 }
Greg Clayton901c5ca2011-12-03 04:40:03 +00001258 }
Greg Claytonbc63aac2015-02-25 22:41:34 +00001259
1260 // Only search all .o files for the definition if we don't need the implementation
1261 // because otherwise, with a valid debug map we should have the ObjC class symbol and
1262 // the code above should have found it.
1263 if (must_be_implementation == false)
1264 {
Sean Callanan0dc848c2015-04-01 20:43:23 +00001265 TypeSP type_sp;
1266
1267 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1268 type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
1269 return (bool)type_sp;
1270 });
1271
1272 return type_sp;
Greg Claytonbc63aac2015-02-25 22:41:34 +00001273 }
1274 return TypeSP();
Greg Clayton901c5ca2011-12-03 04:40:03 +00001275}
1276
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001277uint32_t
Greg Clayton6dbd3982010-09-15 05:51:24 +00001278SymbolFileDWARFDebugMap::FindTypes
1279(
1280 const SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00001281 const ConstString &name,
1282 const ClangNamespaceDecl *namespace_decl,
Greg Clayton6dbd3982010-09-15 05:51:24 +00001283 bool append,
1284 uint32_t max_matches,
1285 TypeList& types
1286)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001287{
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001288 if (!append)
1289 types.Clear();
Greg Clayton6dbd3982010-09-15 05:51:24 +00001290
1291 const uint32_t initial_types_size = types.GetSize();
1292 SymbolFileDWARF *oso_dwarf;
1293
1294 if (sc.comp_unit)
1295 {
1296 oso_dwarf = GetSymbolFile (sc);
1297 if (oso_dwarf)
Sean Callanan213fdb82011-10-13 01:49:10 +00001298 return oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
Greg Clayton6dbd3982010-09-15 05:51:24 +00001299 }
1300 else
1301 {
Sean Callanan0dc848c2015-04-01 20:43:23 +00001302 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Sean Callanan213fdb82011-10-13 01:49:10 +00001303 oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
Sean Callananbc021732015-04-01 22:12:57 +00001304 return false;
Sean Callanan0dc848c2015-04-01 20:43:23 +00001305 });
Greg Clayton6dbd3982010-09-15 05:51:24 +00001306 }
1307
1308 return types.GetSize() - initial_types_size;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001309}
1310
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001311//
1312//uint32_t
1313//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
1314//{
1315// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1316// if (oso_dwarf)
1317// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
1318// return 0;
1319//}
1320
Greg Clayton96d7d742010-11-10 23:42:09 +00001321
Greg Clayton526e5af2010-11-13 03:52:47 +00001322ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00001323SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00001324 const lldb_private::ConstString &name,
1325 const ClangNamespaceDecl *parent_namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00001326{
Greg Clayton526e5af2010-11-13 03:52:47 +00001327 ClangNamespaceDecl matching_namespace;
Greg Clayton96d7d742010-11-10 23:42:09 +00001328 SymbolFileDWARF *oso_dwarf;
1329
1330 if (sc.comp_unit)
1331 {
1332 oso_dwarf = GetSymbolFile (sc);
1333 if (oso_dwarf)
Sean Callanan213fdb82011-10-13 01:49:10 +00001334 matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
Greg Clayton96d7d742010-11-10 23:42:09 +00001335 }
1336 else
1337 {
Sean Callanan0dc848c2015-04-01 20:43:23 +00001338 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Sean Callanan213fdb82011-10-13 01:49:10 +00001339 matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
Greg Clayton96d7d742010-11-10 23:42:09 +00001340
Sean Callanan0dc848c2015-04-01 20:43:23 +00001341 return (bool)matching_namespace;
1342 });
Greg Clayton96d7d742010-11-10 23:42:09 +00001343 }
1344
1345 return matching_namespace;
1346}
1347
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001348//------------------------------------------------------------------
1349// PluginInterface protocol
1350//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00001351lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001352SymbolFileDWARFDebugMap::GetPluginName()
1353{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001354 return GetPluginNameStatic();
1355}
1356
1357uint32_t
1358SymbolFileDWARFDebugMap::GetPluginVersion()
1359{
1360 return 1;
1361}
1362
Greg Clayton1f746072012-08-29 21:13:06 +00001363lldb::CompUnitSP
1364SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
1365{
1366 if (oso_dwarf)
1367 {
1368 const uint32_t cu_count = GetNumCompileUnits();
1369 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1370 {
1371 SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1372 if (oso_symfile == oso_dwarf)
1373 {
Greg Clayton906ba472013-02-06 00:38:25 +00001374 if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
1375 m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
Greg Clayton1f746072012-08-29 21:13:06 +00001376
Greg Clayton906ba472013-02-06 00:38:25 +00001377 return m_compile_unit_infos[cu_idx].compile_unit_sp;
Greg Clayton1f746072012-08-29 21:13:06 +00001378 }
1379 }
1380 }
1381 assert(!"this shouldn't happen");
1382 return lldb::CompUnitSP();
1383}
1384
Greg Clayton9422dd62013-03-04 21:46:16 +00001385SymbolFileDWARFDebugMap::CompileUnitInfo *
1386SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
1387{
1388 if (oso_dwarf)
1389 {
1390 const uint32_t cu_count = GetNumCompileUnits();
1391 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1392 {
1393 SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1394 if (oso_symfile == oso_dwarf)
1395 {
1396 return &m_compile_unit_infos[cu_idx];
1397 }
1398 }
1399 }
1400 return NULL;
1401}
1402
Greg Clayton1f746072012-08-29 21:13:06 +00001403
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404void
Greg Clayton450e3f32010-10-12 02:24:53 +00001405SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
1406{
Greg Clayton1f746072012-08-29 21:13:06 +00001407 if (oso_dwarf)
Greg Clayton450e3f32010-10-12 02:24:53 +00001408 {
Greg Clayton1f746072012-08-29 21:13:06 +00001409 const uint32_t cu_count = GetNumCompileUnits();
1410 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
Greg Clayton450e3f32010-10-12 02:24:53 +00001411 {
Greg Clayton1f746072012-08-29 21:13:06 +00001412 SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1413 if (oso_symfile == oso_dwarf)
Greg Clayton450e3f32010-10-12 02:24:53 +00001414 {
Greg Clayton906ba472013-02-06 00:38:25 +00001415 if (m_compile_unit_infos[cu_idx].compile_unit_sp)
Greg Clayton1f746072012-08-29 21:13:06 +00001416 {
Greg Clayton906ba472013-02-06 00:38:25 +00001417 assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
Greg Clayton1f746072012-08-29 21:13:06 +00001418 }
1419 else
1420 {
Greg Clayton906ba472013-02-06 00:38:25 +00001421 m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
Greg Clayton1f746072012-08-29 21:13:06 +00001422 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
1423 }
Greg Clayton450e3f32010-10-12 02:24:53 +00001424 }
1425 }
1426 }
1427}
1428
Greg Clayton6beaaa62011-01-17 03:46:26 +00001429
1430void
1431SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl)
1432{
1433 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
Greg Clayton57ee3062013-07-11 22:46:58 +00001434 ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001435 if (clang_type)
1436 {
Sean Callanan0dc848c2015-04-01 20:43:23 +00001437 symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001438 if (oso_dwarf->HasForwardDeclForClangType (clang_type))
1439 {
1440 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
Sean Callanan0dc848c2015-04-01 20:43:23 +00001441 return true;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001442 }
Sean Callanan0dc848c2015-04-01 20:43:23 +00001443 return false;
1444 });
Greg Clayton6beaaa62011-01-17 03:46:26 +00001445 }
1446}
1447
1448void
1449SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
1450{
1451 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
Greg Clayton57ee3062013-07-11 22:46:58 +00001452 ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001453 if (clang_type)
1454 {
Sean Callanan0dc848c2015-04-01 20:43:23 +00001455 symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001456 if (oso_dwarf->HasForwardDeclForClangType (clang_type))
1457 {
1458 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
Sean Callanan0dc848c2015-04-01 20:43:23 +00001459 return true;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001460 }
Sean Callanan0dc848c2015-04-01 20:43:23 +00001461 return false;
1462 });
Greg Clayton6beaaa62011-01-17 03:46:26 +00001463 }
1464}
1465
Zachary Turner504f38d2015-03-24 16:24:50 +00001466bool
Zachary Turnera98fac22015-03-24 18:56:08 +00001467SymbolFileDWARFDebugMap::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size,
1468 uint64_t &alignment,
1469 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
1470 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
1471 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
Greg Claytoncaab74e2012-01-28 00:48:57 +00001472{
1473 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
Sean Callanan0dc848c2015-04-01 20:43:23 +00001474 bool laid_out = false;
1475 symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1476 return (laid_out = oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets));
1477 });
1478 return laid_out;
Greg Claytoncaab74e2012-01-28 00:48:57 +00001479}
1480
1481
1482
Greg Clayton81c22f62011-10-19 18:09:39 +00001483clang::DeclContext*
1484SymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
1485{
1486 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1487 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1488 if (oso_dwarf)
1489 return oso_dwarf->GetClangDeclContextContainingTypeUID (type_uid);
1490 return NULL;
1491}
1492
1493clang::DeclContext*
1494SymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1495{
1496 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1497 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1498 if (oso_dwarf)
1499 return oso_dwarf->GetClangDeclContextForTypeUID (sc, type_uid);
1500 return NULL;
1501}
1502
Greg Clayton9422dd62013-03-04 21:46:16 +00001503bool
1504SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
1505 lldb::addr_t exe_file_addr,
1506 lldb::addr_t oso_file_addr,
1507 lldb::addr_t oso_byte_size)
1508{
Greg Clayton9422dd62013-03-04 21:46:16 +00001509 const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
1510 if (debug_map_idx != UINT32_MAX)
1511 {
1512 DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
Greg Clayton9422dd62013-03-04 21:46:16 +00001513 debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
1514 cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
1515 return true;
1516 }
1517 return false;
1518}
1519
1520void
1521SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
1522{
1523 cu_info->file_range_map.Sort();
1524#if defined(DEBUG_OSO_DMAP)
1525 const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1526 const size_t n = oso_file_range_map.GetSize();
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00001527 printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
Greg Clayton084fad62013-03-06 23:23:27 +00001528 cu_info,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00001529 cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
Greg Clayton9422dd62013-03-04 21:46:16 +00001530 for (size_t i=0; i<n; ++i)
1531 {
1532 const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
1533 printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
1534 entry.GetRangeBase(), entry.GetRangeEnd(),
1535 entry.data, entry.data + entry.GetByteSize());
1536 }
1537#endif
1538}
1539
1540lldb::addr_t
1541SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
1542{
1543 CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
1544 if (cu_info)
1545 {
1546 const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1547 if (oso_range_entry)
1548 {
1549 const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1550 if (debug_map_entry)
1551 {
1552 const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1553 const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1554 return exe_file_addr;
1555 }
1556 }
1557 }
1558 return LLDB_INVALID_ADDRESS;
1559}
1560
1561bool
1562SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
1563{
1564 // Make sure this address hasn't been fixed already
1565 Module *exe_module = GetObjectFile()->GetModule().get();
1566 Module *addr_module = addr.GetModule().get();
1567 if (addr_module == exe_module)
1568 return true; // Address is already in terms of the main executable module
1569
Greg Clayton57abc5d2013-05-10 21:47:16 +00001570 CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
Greg Clayton9422dd62013-03-04 21:46:16 +00001571 if (cu_info)
1572 {
1573 const lldb::addr_t oso_file_addr = addr.GetFileAddress();
1574 const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1575 if (oso_range_entry)
1576 {
1577 const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1578 if (debug_map_entry)
1579 {
1580 const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1581 const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1582 return exe_module->ResolveFileAddress(exe_file_addr, addr);
1583 }
1584 }
1585 }
1586 return true;
1587}
1588
1589LineTable *
1590SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
1591{
1592 CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
1593 if (cu_info)
1594 return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
1595 return NULL;
1596}
1597
Enrico Granatac76e60b2013-06-27 01:43:09 +00001598size_t
1599SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
1600{
1601 size_t num_line_entries_added = 0;
1602 if (debug_aranges && dwarf2Data)
1603 {
1604 CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
1605 if (compile_unit_info)
1606 {
1607 const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
1608 for (size_t idx = 0;
1609 idx < file_range_map.GetSize();
1610 idx++)
1611 {
1612 const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
1613 if (entry)
1614 {
1615 printf ("[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", entry->GetRangeBase(), entry->GetRangeEnd());
1616 debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
1617 num_line_entries_added++;
1618 }
1619 }
1620 }
1621 }
1622 return num_line_entries_added;
1623}
Greg Clayton81c22f62011-10-19 18:09:39 +00001624