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