]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
MFC r309362:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / SymbolFileDWARFDebugMap.cpp
1 //===-- 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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "SymbolFileDWARFDebugMap.h"
15
16 #include "DWARFDebugAranges.h"
17
18 #include "lldb/Core/RangeMap.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/ModuleList.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Core/RegularExpression.h"
23 #include "lldb/Core/Section.h"
24
25 //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
26 #if defined(DEBUG_OSO_DMAP)
27 #include "lldb/Core/StreamFile.h"
28 #endif
29 #include "lldb/Core/Timer.h"
30
31 #include "lldb/Symbol/CompileUnit.h"
32 #include "lldb/Symbol/LineTable.h"
33 #include "lldb/Symbol/ObjectFile.h"
34 #include "lldb/Symbol/SymbolVendor.h"
35 #include "lldb/Symbol/TypeMap.h"
36 #include "lldb/Symbol/VariableList.h"
37
38 #include "LogChannelDWARF.h"
39 #include "SymbolFileDWARF.h"
40
41 using namespace lldb;
42 using namespace lldb_private;
43
44 // Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()" 
45 // (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
46 // (so we can fixup the symbol file id.
47
48 const SymbolFileDWARFDebugMap::FileRangeMap &
49 SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
50 {
51     if (file_range_map_valid)
52         return file_range_map;
53
54     file_range_map_valid = true;
55
56     Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
57     if (!oso_module)
58         return file_range_map;
59
60     ObjectFile *oso_objfile = oso_module->GetObjectFile();
61     if (!oso_objfile)
62         return file_range_map;
63
64     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
65     if (log)
66     {
67         ConstString object_name (oso_module->GetObjectName());
68         log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
69                     static_cast<void*>(this),
70                     oso_module->GetSpecificationDescription().c_str());
71     }
72
73     std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
74     if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
75     {
76         for (auto comp_unit_info : cu_infos)
77         {
78             Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
79             ModuleSP oso_module_sp (oso_objfile->GetModule());
80             Symtab *oso_symtab = oso_objfile->GetSymtab();
81
82             ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
83             //SectionList *oso_sections = oso_objfile->Sections();
84             // Now we need to make sections that map from zero based object
85             // file addresses to where things ended up in the main executable.
86
87             assert (comp_unit_info->first_symbol_index != UINT32_MAX);
88             // End index is one past the last valid symbol index
89             const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
90             for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
91                  idx < oso_end_idx;
92                  ++idx)
93             {
94                 Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
95                 if (exe_symbol)
96                 {
97                     if (exe_symbol->IsDebug() == false)
98                         continue;
99
100                     switch (exe_symbol->GetType())
101                     {
102                     default:
103                         break;
104
105                     case eSymbolTypeCode:
106                         {
107                             // For each N_FUN, or function that we run into in the debug map
108                             // we make a new section that we add to the sections found in the
109                             // .o file. This new section has the file address set to what the
110                             // addresses are in the .o file, and the load address is adjusted
111                             // to match where it ended up in the final executable! We do this
112                             // before we parse any dwarf info so that when it goes get parsed
113                             // all section/offset addresses that get registered will resolve
114                             // correctly to the new addresses in the main executable.
115
116                             // First we find the original symbol in the .o file's symbol table
117                             Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
118                                                                                                  eSymbolTypeCode,
119                                                                                                  Symtab::eDebugNo,
120                                                                                                  Symtab::eVisibilityAny);
121                             if (oso_fun_symbol)
122                             {
123                                 // Add the inverse OSO file address to debug map entry mapping
124                                 exe_symfile->AddOSOFileRange (this,
125                                                               exe_symbol->GetAddressRef().GetFileAddress(),
126                                                               exe_symbol->GetByteSize(),
127                                                               oso_fun_symbol->GetAddressRef().GetFileAddress(),
128                                                               oso_fun_symbol->GetByteSize());
129
130                             }
131                         }
132                         break;
133
134                     case eSymbolTypeData:
135                         {
136                             // For each N_GSYM we remap the address for the global by making
137                             // a new section that we add to the sections found in the .o file.
138                             // This new section has the file address set to what the
139                             // addresses are in the .o file, and the load address is adjusted
140                             // to match where it ended up in the final executable! We do this
141                             // before we parse any dwarf info so that when it goes get parsed
142                             // all section/offset addresses that get registered will resolve
143                             // correctly to the new addresses in the main executable. We
144                             // initially set the section size to be 1 byte, but will need to
145                             // fix up these addresses further after all globals have been
146                             // parsed to span the gaps, or we can find the global variable
147                             // sizes from the DWARF info as we are parsing.
148
149                             // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
150                             Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
151                                                                                                   eSymbolTypeData,
152                                                                                                   Symtab::eDebugNo,
153                                                                                                   Symtab::eVisibilityAny);
154                             if (exe_symbol && oso_gsym_symbol &&
155                                 exe_symbol->ValueIsAddress() &&
156                                 oso_gsym_symbol->ValueIsAddress())
157                             {
158                                 // Add the inverse OSO file address to debug map entry mapping
159                                 exe_symfile->AddOSOFileRange (this,
160                                                               exe_symbol->GetAddressRef().GetFileAddress(),
161                                                               exe_symbol->GetByteSize(),
162                                                               oso_gsym_symbol->GetAddressRef().GetFileAddress(),
163                                                               oso_gsym_symbol->GetByteSize());
164                             }
165                         }
166                         break;
167                     }
168                 }
169             }
170
171             exe_symfile->FinalizeOSOFileRanges (this);
172             // We don't need the symbols anymore for the .o files
173             oso_objfile->ClearSymtab();
174         }
175     }
176     return file_range_map;
177 }
178
179 class DebugMapModule : public Module
180 {
181 public:
182     DebugMapModule (const ModuleSP &exe_module_sp,
183                     uint32_t cu_idx,
184                     const FileSpec& file_spec,
185                     const ArchSpec& arch,
186                     const ConstString *object_name,
187                     off_t object_offset,
188                     const TimeValue *object_mod_time_ptr) :
189         Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
190         m_exe_module_wp (exe_module_sp),
191         m_cu_idx (cu_idx)
192     {
193     }
194
195     ~DebugMapModule() override = default;
196
197     SymbolVendor*
198     GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override
199     {
200         // Scope for locker
201         if (m_symfile_ap.get() || can_create == false)
202             return m_symfile_ap.get();
203
204         ModuleSP exe_module_sp (m_exe_module_wp.lock());
205         if (exe_module_sp)
206         {
207             // Now get the object file outside of a locking scope
208             ObjectFile *oso_objfile = GetObjectFile ();
209             if (oso_objfile)
210             {
211                 std::lock_guard<std::recursive_mutex> guard(m_mutex);
212                 SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
213                 if (symbol_vendor)
214                 {
215                     // Set a pointer to this class to set our OSO DWARF file know
216                     // that the DWARF is being used along with a debug map and that
217                     // it will have the remapped sections that we do below.
218                     SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
219                     
220                     if (!oso_symfile)
221                         return NULL;
222
223                     ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
224                     SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
225                     
226                     if (exe_objfile && exe_sym_vendor)
227                     {
228                         oso_symfile->SetDebugMapModule(exe_module_sp);
229                         // Set the ID of the symbol file DWARF to the index of the OSO
230                         // shifted left by 32 bits to provide a unique prefix for any
231                         // UserID's that get created in the symbol file.
232                         oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
233                     }
234                     return symbol_vendor;
235                 }
236             }
237         }
238         return NULL;
239     }
240
241 protected:
242     ModuleWP m_exe_module_wp;
243     const uint32_t m_cu_idx;
244 };
245
246 void
247 SymbolFileDWARFDebugMap::Initialize()
248 {
249     PluginManager::RegisterPlugin (GetPluginNameStatic(),
250                                    GetPluginDescriptionStatic(),
251                                    CreateInstance);
252 }
253
254 void
255 SymbolFileDWARFDebugMap::Terminate()
256 {
257     PluginManager::UnregisterPlugin (CreateInstance);
258 }
259
260 lldb_private::ConstString
261 SymbolFileDWARFDebugMap::GetPluginNameStatic()
262 {
263     static ConstString g_name("dwarf-debugmap");
264     return g_name;
265 }
266
267 const char *
268 SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
269 {
270     return "DWARF and DWARF3 debug symbol file reader (debug map).";
271 }
272
273 SymbolFile*
274 SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
275 {
276     return new SymbolFileDWARFDebugMap (obj_file);
277 }
278
279 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
280     SymbolFile(ofile),
281     m_flags(),
282     m_compile_unit_infos(),
283     m_func_indexes(),
284     m_glob_indexes(),
285     m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
286 {
287 }
288
289 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
290 {
291 }
292
293 void
294 SymbolFileDWARFDebugMap::InitializeObject()
295 {
296 }
297
298 void
299 SymbolFileDWARFDebugMap::InitOSO()
300 {
301     if (m_flags.test(kHaveInitializedOSOs))
302         return;
303     
304     m_flags.set(kHaveInitializedOSOs);
305     
306     // If the object file has been stripped, there is no sense in looking further
307     // as all of the debug symbols for the debug map will not be available
308     if (m_obj_file->IsStripped())
309         return;
310     
311     // Also make sure the file type is some sort of executable. Core files, debug
312     // info files (dSYM), object files (.o files), and stub libraries all can
313     switch (m_obj_file->GetType())
314     {
315         case ObjectFile::eTypeInvalid:
316         case ObjectFile::eTypeCoreFile:
317         case ObjectFile::eTypeDebugInfo:
318         case ObjectFile::eTypeObjectFile:
319         case ObjectFile::eTypeStubLibrary:
320         case ObjectFile::eTypeUnknown:
321         case ObjectFile::eTypeJIT:
322             return;
323             
324         case ObjectFile::eTypeExecutable:
325         case ObjectFile::eTypeDynamicLinker:
326         case ObjectFile::eTypeSharedLibrary:
327             break;
328     }
329
330     // In order to get the abilities of this plug-in, we look at the list of
331     // N_OSO entries (object files) from the symbol table and make sure that
332     // these files exist and also contain valid DWARF. If we get any of that
333     // then we return the abilities of the first N_OSO's DWARF.
334
335     Symtab* symtab = m_obj_file->GetSymtab();
336     if (symtab)
337     {
338         Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
339
340         std::vector<uint32_t> oso_indexes;
341         // When a mach-o symbol is encoded, the n_type field is encoded in bits
342         // 23:16, and the n_desc field is encoded in bits 15:0.
343         // 
344         // To find all N_OSO entries that are part of the DWARF + debug map
345         // we find only object file symbols with the flags value as follows:
346         // bits 23:16 == 0x66 (N_OSO)
347         // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
348         const uint32_t k_oso_symbol_flags_value = 0x660001u;
349
350         const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
351
352         if (oso_index_count > 0)
353         {
354             symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
355             symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
356
357             symtab->SortSymbolIndexesByValue(m_func_indexes, true);
358             symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
359
360             for (uint32_t sym_idx : m_func_indexes)
361             {
362                 const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
363                 lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
364                 lldb::addr_t byte_size = symbol->GetByteSize();
365                 DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
366                 m_debug_map.Append(debug_map_entry);
367             }
368             for (uint32_t sym_idx : m_glob_indexes)
369             {
370                 const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
371                 lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
372                 lldb::addr_t byte_size = symbol->GetByteSize();
373                 DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
374                 m_debug_map.Append(debug_map_entry);
375             }
376             m_debug_map.Sort();
377
378             m_compile_unit_infos.resize(oso_index_count);
379
380             for (uint32_t i=0; i<oso_index_count; ++i)
381             {
382                 const uint32_t so_idx = oso_indexes[i] - 1;
383                 const uint32_t oso_idx = oso_indexes[i];
384                 const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
385                 const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
386                 if (so_symbol &&
387                     oso_symbol &&
388                     so_symbol->GetType() == eSymbolTypeSourceFile &&
389                     oso_symbol->GetType() == eSymbolTypeObjectFile)
390                 {
391                     m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
392                     m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
393                     TimeValue oso_mod_time;
394                     oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0));
395                     m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
396                     uint32_t sibling_idx = so_symbol->GetSiblingIndex();
397                     // The sibling index can't be less that or equal to the current index "i"
398                     if (sibling_idx == UINT32_MAX)
399                     {
400                         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());
401                     }
402                     else
403                     {
404                         const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
405                         m_compile_unit_infos[i].first_symbol_index = so_idx;
406                         m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
407                         m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
408                         m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
409                         
410                         if (log)
411                             log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
412                     }
413                 }
414                 else
415                 {
416                     if (oso_symbol == NULL)
417                         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);
418                     else if (so_symbol == NULL)
419                         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);
420                     else if (so_symbol->GetType() != eSymbolTypeSourceFile)
421                         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);
422                     else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
423                         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);
424                 }
425             }
426         }
427     }
428 }
429
430 Module *
431 SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
432 {
433     const uint32_t cu_count = GetNumCompileUnits();
434     if (oso_idx < cu_count)
435         return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
436     return NULL;
437 }
438
439 Module *
440 SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
441 {
442     if (!comp_unit_info->oso_sp)
443     {
444         auto pos = m_oso_map.find (comp_unit_info->oso_path);
445         if (pos != m_oso_map.end())
446         {
447             comp_unit_info->oso_sp = pos->second;
448         }
449         else
450         {
451             ObjectFile *obj_file = GetObjectFile();
452             comp_unit_info->oso_sp.reset (new OSOInfo());
453             m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
454             const char *oso_path = comp_unit_info->oso_path.GetCString();
455             FileSpec oso_file (oso_path, false);
456             ConstString oso_object;
457             if (oso_file.Exists())
458             {
459                 TimeValue oso_mod_time (oso_file.GetModificationTime());
460                 if (oso_mod_time != comp_unit_info->oso_mod_time)
461                 {
462                     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",
463                                                         oso_file.GetPath().c_str(),
464                                                         oso_mod_time.GetAsSecondsSinceJan1_1970(),
465                                                         comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
466                     return NULL;
467                 }
468
469             }
470             else
471             {
472                 const bool must_exist = true;
473
474                 if (!ObjectFile::SplitArchivePathWithObject (oso_path,
475                                                              oso_file,
476                                                              oso_object,
477                                                              must_exist))
478                 {
479                     return NULL;
480                 }
481             }
482             // Always create a new module for .o files. Why? Because we
483             // use the debug map, to add new sections to each .o file and
484             // even though a .o file might not have changed, the sections
485             // that get added to the .o file can change.
486             ArchSpec oso_arch;
487             // Only adopt the architecture from the module (not the vendor or OS)
488             // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx"
489             // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
490             // load command...
491             oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str());
492             comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
493                                                                          GetCompUnitInfoIndex(comp_unit_info),
494                                                                          oso_file,
495                                                                          oso_arch,
496                                                                          oso_object ? &oso_object : NULL,
497                                                                          0,
498                                                                          oso_object ? &comp_unit_info->oso_mod_time : NULL));
499         }
500     }
501     if (comp_unit_info->oso_sp)
502         return comp_unit_info->oso_sp->module_sp.get();
503     return NULL;
504 }
505
506 bool
507 SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
508 {
509     if (oso_idx < m_compile_unit_infos.size())
510     {
511         if (m_compile_unit_infos[oso_idx].so_file)
512         {
513             file_spec = m_compile_unit_infos[oso_idx].so_file;
514             return true;
515         }
516     }
517     return false;
518 }
519
520 ObjectFile *
521 SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
522 {
523     Module *oso_module = GetModuleByOSOIndex (oso_idx);
524     if (oso_module)
525         return oso_module->GetObjectFile();
526     return NULL;
527 }
528
529 SymbolFileDWARF *
530 SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
531 {
532     CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
533     if (comp_unit_info)
534         return GetSymbolFileByCompUnitInfo (comp_unit_info);
535     return NULL;
536 }
537
538 ObjectFile *
539 SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
540 {
541     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
542     if (oso_module)
543         return oso_module->GetObjectFile();
544     return NULL;
545 }
546
547 uint32_t
548 SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
549 {
550     if (!m_compile_unit_infos.empty())
551     {
552         const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
553         const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
554         if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
555             return comp_unit_info - first_comp_unit_info;
556     }
557     return UINT32_MAX;
558 }
559
560 SymbolFileDWARF *
561 SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
562 {
563     if (oso_idx < m_compile_unit_infos.size())
564         return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
565     return NULL;
566 }
567
568 SymbolFileDWARF *
569 SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
570 {
571     if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
572         return (SymbolFileDWARF *)sym_file;
573     return NULL;
574 }
575
576 SymbolFileDWARF *
577 SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
578 {
579     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
580     if (oso_module)
581     {
582         SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
583         if (sym_vendor)
584             return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
585     }
586     return NULL;
587 }
588
589 uint32_t
590 SymbolFileDWARFDebugMap::CalculateAbilities ()
591 {
592     // In order to get the abilities of this plug-in, we look at the list of
593     // N_OSO entries (object files) from the symbol table and make sure that
594     // these files exist and also contain valid DWARF. If we get any of that
595     // then we return the abilities of the first N_OSO's DWARF.
596
597     const uint32_t oso_index_count = GetNumCompileUnits();
598     if (oso_index_count > 0)
599     {
600         InitOSO();
601         if (!m_compile_unit_infos.empty())
602         {
603             return SymbolFile::CompileUnits    |
604                    SymbolFile::Functions       |
605                    SymbolFile::Blocks          |
606                    SymbolFile::GlobalVariables |
607                    SymbolFile::LocalVariables  |
608                    SymbolFile::VariableTypes   |
609                    SymbolFile::LineTables      ;
610         }
611     }
612     return 0;
613 }
614
615 uint32_t
616 SymbolFileDWARFDebugMap::GetNumCompileUnits()
617 {
618     InitOSO ();
619     return m_compile_unit_infos.size();
620 }
621
622 CompUnitSP
623 SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
624 {
625     CompUnitSP comp_unit_sp;
626     const uint32_t cu_count = GetNumCompileUnits();
627
628     if (cu_idx < cu_count)
629     {
630         Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
631         if (oso_module)
632         {
633             FileSpec so_file_spec;
634             if (GetFileSpecForSO (cu_idx, so_file_spec))
635             {
636                 // User zero as the ID to match the compile unit at offset
637                 // zero in each .o file since each .o file can only have
638                 // one compile unit for now.
639                 lldb::user_id_t cu_id = 0;
640                 m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit(
641                     m_obj_file->GetModule(), NULL, so_file_spec, cu_id, eLanguageTypeUnknown, eLazyBoolCalculate));
642
643                 if (m_compile_unit_infos[cu_idx].compile_unit_sp)
644                 {
645                     // Let our symbol vendor know about this compile unit
646                     m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
647                 }
648             }
649         }
650         comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
651     }
652
653     return comp_unit_sp;
654 }
655
656 SymbolFileDWARFDebugMap::CompileUnitInfo *
657 SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
658 {
659     const uint32_t cu_count = GetNumCompileUnits();
660     for (uint32_t i=0; i<cu_count; ++i)
661     {
662         if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
663             return &m_compile_unit_infos[i];
664     }
665     return NULL;
666 }
667
668 size_t
669 SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
670 {
671     const uint32_t cu_count = GetNumCompileUnits();
672     for (uint32_t i=0; i<cu_count; ++i)
673     {
674         if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
675             cu_infos.push_back (&m_compile_unit_infos[i]);
676     }
677     return cu_infos.size();
678 }
679
680 lldb::LanguageType
681 SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
682 {
683     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
684     if (oso_dwarf)
685         return oso_dwarf->ParseCompileUnitLanguage (sc);
686     return eLanguageTypeUnknown;
687 }
688
689 size_t
690 SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
691 {
692     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
693     if (oso_dwarf)
694         return oso_dwarf->ParseCompileUnitFunctions (sc);
695     return 0;
696 }
697
698 bool
699 SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
700 {
701     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
702     if (oso_dwarf)
703         return oso_dwarf->ParseCompileUnitLineTable (sc);
704     return false;
705 }
706
707 bool
708 SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros (const SymbolContext& sc)
709 {
710     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
711     if (oso_dwarf)
712         return oso_dwarf->ParseCompileUnitDebugMacros (sc);
713     return false;
714 }
715
716 bool
717 SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
718 {
719     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
720     if (oso_dwarf)
721         return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
722     return false;
723 }
724
725 bool
726 SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
727 {
728     SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
729     if (oso_dwarf)
730         return oso_dwarf->ParseCompileUnitIsOptimized(sc);
731     return false;
732 }
733
734 bool
735 SymbolFileDWARFDebugMap::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
736 {
737     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
738     if (oso_dwarf)
739         return oso_dwarf->ParseImportedModules(sc, imported_modules);
740     return false;
741 }
742
743 size_t
744 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
745 {
746     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
747     if (oso_dwarf)
748         return oso_dwarf->ParseFunctionBlocks (sc);
749     return 0;
750 }
751
752 size_t
753 SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
754 {
755     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
756     if (oso_dwarf)
757         return oso_dwarf->ParseTypes (sc);
758     return 0;
759 }
760
761 size_t
762 SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
763 {
764     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
765     if (oso_dwarf)
766         return oso_dwarf->ParseVariablesForContext (sc);
767     return 0;
768 }
769
770 Type*
771 SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
772 {
773     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
774     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
775     if (oso_dwarf)
776         return oso_dwarf->ResolveTypeUID (type_uid);
777     return NULL;
778 }
779
780 bool
781 SymbolFileDWARFDebugMap::CompleteType (CompilerType& compiler_type)
782 {
783     bool success = false;
784     if (compiler_type)
785     {
786         ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
787             if (oso_dwarf->HasForwardDeclForClangType (compiler_type))
788             {
789                 oso_dwarf->CompleteType (compiler_type);
790                 success = true;
791                 return true;
792             }
793             return false;
794         });
795     }
796     return success;
797 }
798
799 uint32_t
800 SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
801 {
802     uint32_t resolved_flags = 0;
803     Symtab* symtab = m_obj_file->GetSymtab();
804     if (symtab)
805     {
806         const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
807
808         const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
809         if (debug_map_entry)
810         {
811
812             sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
813
814             if (sc.symbol != NULL)
815             {
816                 resolved_flags |= eSymbolContextSymbol;
817
818                 uint32_t oso_idx = 0;
819                 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
820                 if (comp_unit_info)
821                 {
822                     comp_unit_info->GetFileRangeMap(this);
823                     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
824                     if (oso_module)
825                     {
826                         lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
827                         Address oso_so_addr;
828                         if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
829                         {
830                             resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
831                         }
832                     }
833                 }
834             }
835         }
836     }
837     return resolved_flags;
838 }
839
840 uint32_t
841 SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
842 {
843     const uint32_t initial = sc_list.GetSize();
844     const uint32_t cu_count = GetNumCompileUnits();
845
846     for (uint32_t i=0; i<cu_count; ++i)
847     {
848         // If we are checking for inlines, then we need to look through all
849         // compile units no matter if "file_spec" matches.
850         bool resolve = check_inlines;
851         
852         if (!resolve)
853         {
854             FileSpec so_file_spec;
855             if (GetFileSpecForSO (i, so_file_spec))
856             {
857                 // Match the full path if the incoming file_spec has a directory (not just a basename)
858                 const bool full_match = (bool)file_spec.GetDirectory();
859                 resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
860             }
861         }
862         if (resolve)
863         {
864             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
865             if (oso_dwarf)
866                 oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
867         }
868     }
869     return sc_list.GetSize() - initial;
870 }
871
872 uint32_t
873 SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
874 (
875     const ConstString &name,
876     const CompilerDeclContext *parent_decl_ctx,
877     const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
878     uint32_t max_matches,
879     VariableList& variables
880 )
881 {
882     const uint32_t original_size = variables.GetSize();
883     const size_t match_count = indexes.size();
884     for (size_t i=0; i<match_count; ++i)
885     {
886         uint32_t oso_idx;
887         CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
888         if (comp_unit_info)
889         {
890             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
891             if (oso_dwarf)
892             {
893                 if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, max_matches, variables))
894                     if (variables.GetSize() > max_matches)
895                         break;
896             }
897         }
898     }
899     return variables.GetSize() - original_size;
900 }
901
902 uint32_t
903 SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name,
904                                               const CompilerDeclContext *parent_decl_ctx,
905                                               bool append,
906                                               uint32_t max_matches,
907                                               VariableList& variables)
908 {
909
910     // If we aren't appending the results to this list, then clear the list
911     if (!append)
912         variables.Clear();
913
914     // Remember how many variables are in the list before we search in case
915     // we are appending the results to a variable list.
916     const uint32_t original_size = variables.GetSize();
917
918     uint32_t total_matches = 0;
919     
920     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
921         const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
922                                                                      parent_decl_ctx,
923                                                                      true,
924                                                                      max_matches,
925                                                                      variables);
926         if (oso_matches > 0)
927         {
928             total_matches += oso_matches;
929             
930             // Are we getting all matches?
931             if (max_matches == UINT32_MAX)
932                 return false;   // Yep, continue getting everything
933             
934             // If we have found enough matches, lets get out
935             if (max_matches >= total_matches)
936                 return true;
937             
938             // Update the max matches for any subsequent calls to find globals
939             // in any other object files with DWARF
940             max_matches -= oso_matches;
941         }
942         
943         return false;
944     });
945
946     // Return the number of variable that were appended to the list
947     return variables.GetSize() - original_size;
948 }
949
950 uint32_t
951 SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
952 {
953     // If we aren't appending the results to this list, then clear the list
954     if (!append)
955         variables.Clear();
956
957     // Remember how many variables are in the list before we search in case
958     // we are appending the results to a variable list.
959     const uint32_t original_size = variables.GetSize();
960
961     uint32_t total_matches = 0;
962     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
963         const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
964                                                                      true, 
965                                                                      max_matches, 
966                                                                      variables);
967         if (oso_matches > 0)
968         {
969             total_matches += oso_matches;
970
971             // Are we getting all matches?
972             if (max_matches == UINT32_MAX)
973                 return false;   // Yep, continue getting everything
974
975             // If we have found enough matches, lets get out
976             if (max_matches >= total_matches)
977                 return true;
978
979             // Update the max matches for any subsequent calls to find globals
980             // in any other object files with DWARF
981             max_matches -= oso_matches;
982         }
983         
984         return false;
985     });
986         
987     // Return the number of variable that were appended to the list
988     return variables.GetSize() - original_size;
989 }
990
991 int
992 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
993 {
994     const uint32_t symbol_idx = *symbol_idx_ptr;
995
996     if (symbol_idx < comp_unit_info->first_symbol_index)
997         return -1;
998
999     if (symbol_idx <= comp_unit_info->last_symbol_index)
1000         return 0;
1001
1002     return 1;
1003 }
1004
1005 int
1006 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
1007 {
1008     const user_id_t symbol_id = *symbol_idx_ptr;
1009
1010     if (symbol_id < comp_unit_info->first_symbol_id)
1011         return -1;
1012
1013     if (symbol_id <= comp_unit_info->last_symbol_id)
1014         return 0;
1015
1016     return 1;
1017 }
1018
1019 SymbolFileDWARFDebugMap::CompileUnitInfo*
1020 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
1021 {
1022     const uint32_t oso_index_count = m_compile_unit_infos.size();
1023     CompileUnitInfo *comp_unit_info = NULL;
1024     if (oso_index_count)
1025     {
1026         comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, 
1027                                                    &m_compile_unit_infos[0], 
1028                                                    m_compile_unit_infos.size(), 
1029                                                    sizeof(CompileUnitInfo), 
1030                                                    (ComparisonFunction)SymbolContainsSymbolWithIndex);
1031     }
1032
1033     if (oso_idx_ptr)
1034     {
1035         if (comp_unit_info != NULL)
1036             *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1037         else
1038             *oso_idx_ptr = UINT32_MAX;
1039     }
1040     return comp_unit_info;
1041 }
1042
1043 SymbolFileDWARFDebugMap::CompileUnitInfo*
1044 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
1045 {
1046     const uint32_t oso_index_count = m_compile_unit_infos.size();
1047     CompileUnitInfo *comp_unit_info = NULL;
1048     if (oso_index_count)
1049     {
1050         comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id, 
1051                                                       &m_compile_unit_infos[0], 
1052                                                       m_compile_unit_infos.size(), 
1053                                                       sizeof(CompileUnitInfo), 
1054                                                       (ComparisonFunction)SymbolContainsSymbolWithID);
1055     }
1056
1057     if (oso_idx_ptr)
1058     {
1059         if (comp_unit_info != NULL)
1060             *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1061         else
1062             *oso_idx_ptr = UINT32_MAX;
1063     }
1064     return comp_unit_info;
1065 }
1066
1067 static void
1068 RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
1069 {
1070     // We found functions in .o files. Not all functions in the .o files
1071     // will have made it into the final output file. The ones that did
1072     // make it into the final output file will have a section whose module
1073     // matches the module from the ObjectFile for this SymbolFile. When
1074     // the modules don't match, then we have something that was in a
1075     // .o file, but doesn't map to anything in the final executable.
1076     uint32_t i=start_idx;
1077     while (i < sc_list.GetSize())
1078     {
1079         SymbolContext sc;
1080         sc_list.GetContextAtIndex(i, sc);
1081         if (sc.function)
1082         {
1083             const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
1084             if (section_sp->GetModule() != module_sp)
1085             {
1086                 sc_list.RemoveContextAtIndex(i);
1087                 continue;
1088             }
1089         }
1090         ++i;
1091     }
1092 }
1093
1094 uint32_t
1095 SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name,
1096                                        const CompilerDeclContext *parent_decl_ctx,
1097                                        uint32_t name_type_mask,
1098                                        bool include_inlines,
1099                                        bool append,
1100                                        SymbolContextList& sc_list)
1101 {
1102     Timer scoped_timer (__PRETTY_FUNCTION__,
1103                         "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1104                         name.GetCString());
1105
1106     uint32_t initial_size = 0;
1107     if (append)
1108         initial_size = sc_list.GetSize();
1109     else
1110         sc_list.Clear();
1111
1112     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1113         uint32_t sc_idx = sc_list.GetSize();
1114         if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, true, sc_list))
1115         {
1116             RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1117         }
1118         return false;
1119     });
1120
1121     return sc_list.GetSize() - initial_size;
1122 }
1123
1124 uint32_t
1125 SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
1126 {
1127     Timer scoped_timer (__PRETTY_FUNCTION__,
1128                         "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1129                         regex.GetText());
1130
1131     uint32_t initial_size = 0;
1132     if (append)
1133         initial_size = sc_list.GetSize();
1134     else
1135         sc_list.Clear();
1136
1137     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1138         uint32_t sc_idx = sc_list.GetSize();
1139         
1140         if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
1141         {
1142             RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1143         }
1144         return false;
1145     });
1146
1147     return sc_list.GetSize() - initial_size;
1148 }
1149
1150 size_t
1151 SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
1152                                    uint32_t type_mask,
1153                                    TypeList &type_list)
1154 {
1155     Timer scoped_timer (__PRETTY_FUNCTION__,
1156                         "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1157                         type_mask);
1158
1159     uint32_t initial_size = type_list.GetSize();
1160     SymbolFileDWARF *oso_dwarf = NULL;
1161     if (sc_scope)
1162     {
1163         SymbolContext sc;
1164         sc_scope->CalculateSymbolContext(&sc);
1165         
1166         CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
1167         if (cu_info)
1168         {
1169             oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
1170             if (oso_dwarf)
1171                 oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1172         }
1173     }
1174     else
1175     {
1176         ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1177             oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1178             return false;
1179         });
1180     }
1181     return type_list.GetSize() - initial_size;
1182 }
1183
1184 TypeSP
1185 SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
1186 {
1187     TypeSP type_sp;
1188     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1189         type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
1190         return ((bool)type_sp);
1191     });
1192     return type_sp;
1193 }
1194
1195 bool
1196 SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
1197 {
1198     if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
1199     {
1200         m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
1201         ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1202             if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
1203             {
1204                 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
1205                 return true;
1206             }
1207             return false;
1208         });
1209     }
1210     return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1211 }
1212
1213 TypeSP
1214 SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
1215                                                                const ConstString &type_name,
1216                                                                bool must_be_implementation)
1217 {
1218     // If we have a debug map, we will have an Objective C symbol whose name is
1219     // the type name and whose type is eSymbolTypeObjCClass. If we can find that
1220     // symbol and find its containing parent, we can locate the .o file that will
1221     // contain the implementation definition since it will be scoped inside the N_SO
1222     // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
1223     SymbolFileDWARF *oso_dwarf = NULL;
1224     TypeSP type_sp;
1225     ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
1226     if (module_objfile)
1227     {
1228         Symtab *symtab = module_objfile->GetSymtab();
1229         if (symtab)
1230         {
1231             Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny);
1232             if (objc_class_symbol)
1233             {
1234                 // Get the N_SO symbol that contains the objective C class symbol as this
1235                 // should be the .o file that contains the real definition...
1236                 const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
1237
1238                 if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile)
1239                 {
1240                     const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol);
1241                     if (source_file_symbol_idx != UINT32_MAX)
1242                     {
1243                         CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL);
1244                         if (compile_unit_info)
1245                         {
1246                             oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info);
1247                             if (oso_dwarf)
1248                             {
1249                                 TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
1250                                 if (type_sp)
1251                                 {
1252                                     return type_sp;
1253                                 }
1254                             }
1255                         }
1256                     }
1257                 }
1258             }
1259         }
1260     }
1261
1262     // Only search all .o files for the definition if we don't need the implementation
1263     // because otherwise, with a valid debug map we should have the ObjC class symbol and
1264     // the code above should have found it.
1265     if (must_be_implementation == false)
1266     {
1267         TypeSP type_sp;
1268         
1269         ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1270             type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
1271             return (bool)type_sp;
1272         });
1273         
1274         return type_sp;
1275     }
1276     return TypeSP();
1277 }
1278
1279 uint32_t
1280 SymbolFileDWARFDebugMap::FindTypes 
1281 (
1282     const SymbolContext& sc, 
1283     const ConstString &name,
1284     const CompilerDeclContext *parent_decl_ctx,
1285     bool append,
1286     uint32_t max_matches,
1287     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1288     TypeMap& types
1289 )
1290 {
1291     if (!append)
1292         types.Clear();
1293
1294     const uint32_t initial_types_size = types.GetSize();
1295     SymbolFileDWARF *oso_dwarf;
1296
1297     if (sc.comp_unit)
1298     {
1299         oso_dwarf = GetSymbolFile (sc);
1300         if (oso_dwarf)
1301             return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
1302     }
1303     else
1304     {
1305         ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1306             oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
1307             if (types.GetSize() >= max_matches)
1308                 return true;
1309             else
1310                 return false;
1311         });
1312     }
1313
1314     return types.GetSize() - initial_types_size;
1315 }
1316
1317 //
1318 //uint32_t
1319 //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)
1320 //{
1321 //  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1322 //  if (oso_dwarf)
1323 //      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
1324 //  return 0;
1325 //}
1326
1327
1328 CompilerDeclContext
1329 SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc, 
1330                                         const lldb_private::ConstString &name,
1331                                         const CompilerDeclContext *parent_decl_ctx)
1332 {
1333     CompilerDeclContext matching_namespace;
1334     SymbolFileDWARF *oso_dwarf;
1335
1336     if (sc.comp_unit)
1337     {
1338         oso_dwarf = GetSymbolFile (sc);
1339         if (oso_dwarf)
1340             matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
1341     }
1342     else
1343     {
1344         ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1345             matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
1346
1347             return (bool)matching_namespace;
1348         });
1349     }
1350
1351     return matching_namespace;
1352 }
1353
1354 //------------------------------------------------------------------
1355 // PluginInterface protocol
1356 //------------------------------------------------------------------
1357 lldb_private::ConstString
1358 SymbolFileDWARFDebugMap::GetPluginName()
1359 {
1360     return GetPluginNameStatic();
1361 }
1362
1363 uint32_t
1364 SymbolFileDWARFDebugMap::GetPluginVersion()
1365 {
1366     return 1;
1367 }
1368
1369 lldb::CompUnitSP
1370 SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
1371 {
1372     if (oso_dwarf)
1373     {
1374         const uint32_t cu_count = GetNumCompileUnits();
1375         for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1376         {
1377             SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1378             if (oso_symfile == oso_dwarf)
1379             {
1380                 if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
1381                     m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
1382
1383                 return m_compile_unit_infos[cu_idx].compile_unit_sp;
1384             }
1385         }
1386     }
1387     assert(!"this shouldn't happen");
1388     return lldb::CompUnitSP();
1389 }
1390
1391 SymbolFileDWARFDebugMap::CompileUnitInfo *
1392 SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
1393 {
1394     if (oso_dwarf)
1395     {
1396         const uint32_t cu_count = GetNumCompileUnits();
1397         for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1398         {
1399             SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1400             if (oso_symfile == oso_dwarf)
1401             {
1402                 return &m_compile_unit_infos[cu_idx];
1403             }
1404         }
1405     }
1406     return NULL;
1407 }
1408
1409 void
1410 SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
1411 {
1412     if (oso_dwarf)
1413     {
1414         const uint32_t cu_count = GetNumCompileUnits();
1415         for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1416         {
1417             SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1418             if (oso_symfile == oso_dwarf)
1419             {
1420                 if (m_compile_unit_infos[cu_idx].compile_unit_sp)
1421                 {
1422                     assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
1423                 }
1424                 else
1425                 {
1426                     m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
1427                     m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
1428                 }
1429             }
1430         }
1431     }
1432 }
1433
1434 CompilerDeclContext
1435 SymbolFileDWARFDebugMap::GetDeclContextForUID (lldb::user_id_t type_uid)
1436 {
1437     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1438     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1439     if (oso_dwarf)
1440         return oso_dwarf->GetDeclContextForUID (type_uid);
1441     return CompilerDeclContext();
1442 }
1443
1444 CompilerDeclContext
1445 SymbolFileDWARFDebugMap::GetDeclContextContainingUID (lldb::user_id_t type_uid)
1446 {
1447     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1448     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1449     if (oso_dwarf)
1450         return oso_dwarf->GetDeclContextContainingUID (type_uid);
1451     return CompilerDeclContext();
1452 }
1453
1454 void
1455 SymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx)
1456 {
1457     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1458         oso_dwarf->ParseDeclsForContext (decl_ctx);
1459         return true; // Keep iterating
1460     });
1461 }
1462
1463 bool
1464 SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
1465                                           lldb::addr_t exe_file_addr,
1466                                           lldb::addr_t exe_byte_size,
1467                                           lldb::addr_t oso_file_addr,
1468                                           lldb::addr_t oso_byte_size)
1469 {
1470     const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
1471     if (debug_map_idx != UINT32_MAX)
1472     {
1473         DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
1474         debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
1475         addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
1476         if (range_size == 0)
1477         {
1478             range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
1479             if (range_size == 0)
1480                 range_size = 1;
1481         }
1482         cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
1483         return true;
1484     }
1485     return false;
1486 }
1487
1488 void
1489 SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
1490 {
1491     cu_info->file_range_map.Sort();
1492 #if defined(DEBUG_OSO_DMAP)
1493     const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1494     const size_t n = oso_file_range_map.GetSize();
1495     printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
1496             cu_info,
1497             cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
1498     for (size_t i=0; i<n; ++i)
1499     {
1500         const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
1501         printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
1502                 entry.GetRangeBase(), entry.GetRangeEnd(),
1503                 entry.data, entry.data + entry.GetByteSize());
1504     }
1505 #endif
1506 }
1507
1508 lldb::addr_t
1509 SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
1510 {
1511     CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
1512     if (cu_info)
1513     {
1514         const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1515         if (oso_range_entry)
1516         {
1517             const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1518             if (debug_map_entry)
1519             {
1520                 const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1521                 const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1522                 return exe_file_addr;
1523             }
1524         }
1525     }
1526     return LLDB_INVALID_ADDRESS;
1527 }
1528
1529 bool
1530 SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
1531 {
1532     // Make sure this address hasn't been fixed already
1533     Module *exe_module = GetObjectFile()->GetModule().get();
1534     Module *addr_module = addr.GetModule().get();
1535     if (addr_module == exe_module)
1536         return true; // Address is already in terms of the main executable module
1537
1538     CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
1539     if (cu_info)
1540     {
1541         const lldb::addr_t oso_file_addr = addr.GetFileAddress();
1542         const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1543         if (oso_range_entry)
1544         {
1545             const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1546             if (debug_map_entry)
1547             {
1548                 const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1549                 const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1550                 return exe_module->ResolveFileAddress(exe_file_addr, addr);
1551             }
1552         }
1553     }
1554     return true;
1555 }
1556
1557 LineTable *
1558 SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
1559 {
1560     CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
1561     if (cu_info)
1562         return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
1563     return NULL;
1564 }
1565
1566 size_t
1567 SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
1568 {
1569     size_t num_line_entries_added = 0;
1570     if (debug_aranges && dwarf2Data)
1571     {
1572         CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
1573         if (compile_unit_info)
1574         {
1575             const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
1576             for (size_t idx = 0;
1577                  idx < file_range_map.GetSize();
1578                  idx++)
1579             {
1580                 const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
1581                 if (entry)
1582                 {
1583                     debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
1584                     num_line_entries_added++;
1585                 }
1586             }
1587         }
1588     }
1589     return num_line_entries_added;
1590 }