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 #include "SymbolFileDWARFDebugMap.h"
11 
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/ModuleList.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Core/RegularExpression.h"
16 #include "lldb/Core/Section.h"
17 #if defined(DEBUG_OSO_DMAP)
18 #include "lldb/Core/StreamFile.h"
19 #endif
20 #include "lldb/Core/Timer.h"
21 
22 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
23 #include "lldb/Symbol/CompileUnit.h"
24 #include "lldb/Symbol/ObjectFile.h"
25 #include "lldb/Symbol/SymbolVendor.h"
26 #include "lldb/Symbol/VariableList.h"
27 
28 #include "LogChannelDWARF.h"
29 #include "SymbolFileDWARF.h"
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 // Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
35 // (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
36 // (so we can fixup the symbol file id.
37 
38 class DebugMapModule : public Module
39 {
40 public:
41     DebugMapModule (const ModuleSP &exe_module_sp,
42                     uint32_t cu_idx,
43                     const FileSpec& file_spec,
44                     const ArchSpec& arch,
45                     const ConstString *object_name,
46                     off_t object_offset) :
47         Module (file_spec, arch, object_name, object_offset),
48         m_exe_module_wp (exe_module_sp),
49         m_cu_idx (cu_idx)
50     {
51     }
52 
53     virtual
54     ~DebugMapModule ()
55     {
56     }
57 
58     virtual ObjectFile *
59     GetObjectFile ()
60     {
61         Mutex::Locker locker (m_mutex);
62         if (m_did_load_objfile == false)
63         {
64             ModuleSP exe_module_sp (m_exe_module_wp.lock());
65             if (exe_module_sp)
66             {
67                 ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
68                 ObjectFile *oso_objfile = Module::GetObjectFile();
69                 SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
70 
71                 if (exe_objfile && oso_objfile && exe_sym_vendor)
72                 {
73                     SymbolFileDWARFDebugMap *exe_symfile = (SymbolFileDWARFDebugMap *)exe_sym_vendor->GetSymbolFile();
74                     if (exe_symfile)
75                     {
76                         SymbolFileDWARFDebugMap::CompileUnitInfo *comp_unit_info = exe_symfile->GetCompUnitInfo (this);
77                         if (comp_unit_info)
78                         {
79                             // Set the ID of the symbol file DWARF to the index of the OSO
80                             // shifted left by 32 bits to provide a unique prefix for any
81                             // UserID's that get created in the symbol file.
82                             //comp_unit_info->exe_sections_sp.reset(new SectionList);
83 
84                             Symtab *exe_symtab = exe_objfile->GetSymtab();
85                             ModuleSP oso_module_sp (oso_objfile->GetModule());
86                             Symtab *oso_symtab = oso_objfile->GetSymtab();
87                             //#define DEBUG_OSO_DMAP    // Do not check in with this defined...
88 #if defined(DEBUG_OSO_DMAP)
89                             StreamFile s(stdout);
90                             s << "OSO symtab:\n";
91                             oso_symtab->Dump(&s, NULL);
92                             s << "OSO sections before:\n";
93                             oso_objfile->GetSectionList()->Dump(&s, NULL, true);
94 #endif
95 
96                             ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
97                             //SectionList *oso_sections = oso_objfile->Sections();
98                             // Now we need to make sections that map from zero based object
99                             // file addresses to where things eneded up in the main executable.
100 
101                             assert (comp_unit_info->first_symbol_index != UINT32_MAX);
102                             // End index is one past the last valid symbol index
103                             const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
104                             uint32_t sect_id = 0x10000;
105                             for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
106                                  idx < oso_end_idx;
107                                  ++idx)
108                             {
109                                 Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
110                                 if (exe_symbol)
111                                 {
112                                     if (exe_symbol->IsDebug() == false)
113                                         continue;
114 
115                                     switch (exe_symbol->GetType())
116                                     {
117                                         default:
118                                             break;
119 
120                                         case eSymbolTypeCode:
121                                         {
122                                             // For each N_FUN, or function that we run into in the debug map
123                                             // we make a new section that we add to the sections found in the
124                                             // .o file. This new section has the file address set to what the
125                                             // addresses are in the .o file, and the load address is adjusted
126                                             // to match where it ended up in the final executable! We do this
127                                             // before we parse any dwarf info so that when it goes get parsed
128                                             // all section/offset addresses that get registered will resolve
129                                             // correctly to the new addresses in the main executable.
130 
131                                             // First we find the original symbol in the .o file's symbol table
132                                             Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
133                                             if (oso_fun_symbol)
134                                             {
135                                                 // If we found the symbol, then we
136                                                 SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection());
137                                                 SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection());
138                                                 if (oso_fun_section)
139                                                 {
140                                                     // Now we create a section that we will add as a child of the
141                                                     // section in which the .o symbol (the N_FUN) exists.
142 
143                                                     // We use the exe_symbol size because the one in the .o file
144                                                     // will just be a symbol with no size, and the exe_symbol
145                                                     // size will reflect any size changes (ppc has been known to
146                                                     // shrink function sizes when it gets rid of jump islands that
147                                                     // aren't needed anymore).
148                                                     SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(),
149                                                                                                oso_module_sp,                         // Module (the .o file)
150                                                                                                sect_id++,                          // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
151                                                                                                exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
152                                                                                                eSectionTypeDebug,
153                                                                                                oso_fun_symbol->GetAddress().GetOffset(),  // File VM address offset in the current section
154                                                                                                exe_symbol->GetByteSize(),          // File size (we need the size from the executable)
155                                                                                                0, 0, 0));
156 
157                                                     oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
158                                                                                            exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress());
159                                                     oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
160                                                 }
161                                             }
162                                         }
163                                             break;
164 
165                                         case eSymbolTypeData:
166                                         {
167                                             // For each N_GSYM we remap the address for the global by making
168                                             // a new section that we add to the sections found in the .o file.
169                                             // This new section has the file address set to what the
170                                             // addresses are in the .o file, and the load address is adjusted
171                                             // to match where it ended up in the final executable! We do this
172                                             // before we parse any dwarf info so that when it goes get parsed
173                                             // all section/offset addresses that get registered will resolve
174                                             // correctly to the new addresses in the main executable. We
175                                             // initially set the section size to be 1 byte, but will need to
176                                             // fix up these addresses further after all globals have been
177                                             // parsed to span the gaps, or we can find the global variable
178                                             // sizes from the DWARF info as we are parsing.
179 
180                                             // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
181                                             Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(),
182                                                                                                                   eSymbolTypeData,
183                                                                                                                   Symtab::eDebugNo,
184                                                                                                                   Symtab::eVisibilityAny);
185 
186                                             if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress())
187                                             {
188                                                 // If we found the symbol, then we
189                                                 SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection());
190                                                 SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection());
191                                                 if (oso_gsym_section)
192                                                 {
193                                                     SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(),
194                                                                                                 oso_module_sp,                         // Module (the .o file)
195                                                                                                 sect_id++,                          // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
196                                                                                                 exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
197                                                                                                 eSectionTypeDebug,
198                                                                                                 oso_gsym_symbol->GetAddress().GetOffset(),  // File VM address offset in the current section
199                                                                                                 1,                                   // We don't know the size of the global, just do the main address for now.
200                                                                                                 0, 0, 0));
201 
202                                                     oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
203                                                                                             exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress());
204                                                     oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
205                                                 }
206                                             }
207                                         }
208                                             break;
209                                     }
210                                 }
211                             }
212                             oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
213 #if defined(DEBUG_OSO_DMAP)
214                             s << "OSO sections after:\n";
215                             oso_objfile->GetSectionList()->Dump(&s, NULL, true);
216 #endif
217                         }
218                     }
219                 }
220             }
221         }
222         return m_objfile_sp.get();
223     }
224 
225     virtual SymbolVendor*
226     GetSymbolVendor(bool can_create = true)
227     {
228         // Scope for locker
229         if (m_symfile_ap.get() || can_create == false)
230             return m_symfile_ap.get();
231 
232         ModuleSP exe_module_sp (m_exe_module_wp.lock());
233         if (exe_module_sp)
234         {
235             // Now get the object file outside of a locking scope
236             ObjectFile *oso_objfile = GetObjectFile ();
237             if (oso_objfile)
238             {
239                 Mutex::Locker locker (m_mutex);
240                 SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create);
241                 if (symbol_vendor)
242                 {
243                     // Set a a pointer to this class to set our OSO DWARF file know
244                     // that the DWARF is being used along with a debug map and that
245                     // it will have the remapped sections that we do below.
246                     SymbolFileDWARF *oso_symfile = (SymbolFileDWARF *)symbol_vendor->GetSymbolFile();
247 
248                     if (!oso_symfile)
249                         return NULL;
250 
251                     ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
252                     SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
253 
254                     if (exe_objfile && exe_sym_vendor)
255                     {
256                         if (oso_symfile->GetNumCompileUnits() == 1)
257                         {
258                             oso_symfile->SetDebugMapModule(exe_module_sp);
259                             // Set the ID of the symbol file DWARF to the index of the OSO
260                             // shifted left by 32 bits to provide a unique prefix for any
261                             // UserID's that get created in the symbol file.
262                             oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
263                         }
264                         else
265                         {
266                             oso_symfile->SetID (UINT64_MAX);
267                         }
268                     }
269                     return symbol_vendor;
270                 }
271             }
272         }
273         return NULL;
274     }
275 
276 protected:
277     ModuleWP m_exe_module_wp;
278     const uint32_t m_cu_idx;
279 };
280 
281 void
282 SymbolFileDWARFDebugMap::Initialize()
283 {
284     PluginManager::RegisterPlugin (GetPluginNameStatic(),
285                                    GetPluginDescriptionStatic(),
286                                    CreateInstance);
287 }
288 
289 void
290 SymbolFileDWARFDebugMap::Terminate()
291 {
292     PluginManager::UnregisterPlugin (CreateInstance);
293 }
294 
295 
296 const char *
297 SymbolFileDWARFDebugMap::GetPluginNameStatic()
298 {
299     return "dwarf-debugmap";
300 }
301 
302 const char *
303 SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
304 {
305     return "DWARF and DWARF3 debug symbol file reader (debug map).";
306 }
307 
308 SymbolFile*
309 SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
310 {
311     return new SymbolFileDWARFDebugMap (obj_file);
312 }
313 
314 
315 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
316     SymbolFile(ofile),
317     m_flags(),
318     m_compile_unit_infos(),
319     m_func_indexes(),
320     m_glob_indexes(),
321     m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
322 {
323 }
324 
325 
326 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
327 {
328 }
329 
330 void
331 SymbolFileDWARFDebugMap::InitializeObject()
332 {
333     // Install our external AST source callbacks so we can complete Clang types.
334     llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
335         new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl,
336                                              SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl,
337                                              NULL,
338                                              SymbolFileDWARFDebugMap::LayoutRecordType,
339                                              this));
340 
341     GetClangASTContext().SetExternalSource (ast_source_ap);
342 }
343 
344 
345 
346 void
347 SymbolFileDWARFDebugMap::InitOSO()
348 {
349     if (m_flags.test(kHaveInitializedOSOs))
350         return;
351 
352     m_flags.set(kHaveInitializedOSOs);
353     // In order to get the abilities of this plug-in, we look at the list of
354     // N_OSO entries (object files) from the symbol table and make sure that
355     // these files exist and also contain valid DWARF. If we get any of that
356     // then we return the abilities of the first N_OSO's DWARF.
357 
358     Symtab* symtab = m_obj_file->GetSymtab();
359     if (symtab)
360     {
361         LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
362 
363         std::vector<uint32_t> oso_indexes;
364 #if defined(DEBUG_OSO_DMAP)
365 //      StreamFile s(stdout);
366 //      symtab->Dump(&s, NULL, eSortOrderNone);
367 #endif
368         // When a mach-o symbol is encoded, the n_type field is encoded in bits
369         // 23:16, and the n_desc field is encoded in bits 15:0.
370         //
371         // To find all N_OSO entries that are part of the DWARF + debug map
372         // we find only object file symbols with the flags value as follows:
373         // bits 23:16 == 0x66 (N_OSO)
374         // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
375         const uint32_t k_oso_symbol_flags_value = 0x660001u;
376 
377         const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
378 
379         if (oso_index_count > 0)
380         {
381             symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
382             symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
383 
384             symtab->SortSymbolIndexesByValue(m_func_indexes, true);
385             symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
386 
387             m_compile_unit_infos.resize(oso_index_count);
388 //          s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__);
389 //          symtab->Dump(&s, oso_indexes);
390 
391             for (uint32_t i=0; i<oso_index_count; ++i)
392             {
393                 const Symbol *so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1);
394                 const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]);
395                 assert (so_symbol);
396                 assert (oso_symbol);
397                 assert (so_symbol->GetType() == eSymbolTypeSourceFile);
398                 assert (oso_symbol->GetType() == eSymbolTypeObjectFile);
399                 m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), true);
400                 m_compile_unit_infos[i].oso_file.SetFile(oso_symbol->GetName().AsCString(), true);
401                 uint32_t sibling_idx = so_symbol->GetSiblingIndex();
402                 // The sibling index can't be less that or equal to the current index "i"
403                 if (sibling_idx <= i)
404                 {
405                     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());
406                 }
407                 else
408                 {
409                     const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
410                     m_compile_unit_infos[i].first_symbol_index = symtab->GetIndexForSymbol(so_symbol);
411                     m_compile_unit_infos[i].last_symbol_index = symtab->GetIndexForSymbol(last_symbol);
412                     m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
413                     m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
414 
415                     if (log)
416                         log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
417                 }
418             }
419         }
420     }
421 }
422 
423 Module *
424 SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
425 {
426     const uint32_t cu_count = GetNumCompileUnits();
427     if (oso_idx < cu_count)
428         return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
429     return NULL;
430 }
431 
432 Module *
433 SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
434 {
435     if (comp_unit_info->oso_module_sp.get() == NULL && comp_unit_info->symbol_file_supported)
436     {
437         if (!comp_unit_info->oso_file.Exists())
438         {
439             char path[PATH_MAX*2];
440             comp_unit_info->oso_file.GetPath(path, sizeof(path));
441             if (ObjectFile::SplitArchivePathWithObject (path,
442                                                         comp_unit_info->oso_file,
443                                                         comp_unit_info->oso_object))
444             {
445                 comp_unit_info->oso_file.GetPath(path, sizeof(path));
446                 //printf ("resolved archive '%s' and object '%s'\n", path, comp_unit_info->oso_object.GetCString());
447             }
448             else
449             {
450                 comp_unit_info->symbol_file_supported = false;
451                 return false;
452             }
453         }
454         // Always create a new module for .o files. Why? Because we
455         // use the debug map, to add new sections to each .o file and
456         // even though a .o file might not have changed, the sections
457         // that get added to the .o file can change.
458         comp_unit_info->oso_module_sp.reset (new DebugMapModule (GetObjectFile()->GetModule(),
459                                                                  GetCompUnitInfoIndex(comp_unit_info),
460                                                                  comp_unit_info->oso_file,
461                                                                  m_obj_file->GetModule()->GetArchitecture(),
462                                                                  comp_unit_info->oso_object ? &comp_unit_info->oso_object : NULL,
463                                                                  0));
464     }
465     return comp_unit_info->oso_module_sp.get();
466 }
467 
468 
469 bool
470 SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
471 {
472     if (oso_idx < m_compile_unit_infos.size())
473     {
474         if (m_compile_unit_infos[oso_idx].so_file)
475         {
476             file_spec = m_compile_unit_infos[oso_idx].so_file;
477             return true;
478         }
479     }
480     return false;
481 }
482 
483 
484 
485 ObjectFile *
486 SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
487 {
488     Module *oso_module = GetModuleByOSOIndex (oso_idx);
489     if (oso_module)
490         return oso_module->GetObjectFile();
491     return NULL;
492 }
493 
494 SymbolFileDWARF *
495 SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
496 {
497     CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
498     if (comp_unit_info)
499         return GetSymbolFileByCompUnitInfo (comp_unit_info);
500     return NULL;
501 }
502 
503 ObjectFile *
504 SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
505 {
506     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
507     if (oso_module)
508         return oso_module->GetObjectFile();
509     return NULL;
510 }
511 
512 
513 uint32_t
514 SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
515 {
516     if (!m_compile_unit_infos.empty())
517     {
518         const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
519         const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
520         if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
521             return comp_unit_info - first_comp_unit_info;
522     }
523     return UINT32_MAX;
524 }
525 
526 SymbolFileDWARF *
527 SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
528 {
529     if (oso_idx < m_compile_unit_infos.size())
530         return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
531     return NULL;
532 }
533 
534 SymbolFileDWARF *
535 SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
536 {
537     Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
538     if (oso_module)
539     {
540         SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
541         if (sym_vendor)
542             return (SymbolFileDWARF *)sym_vendor->GetSymbolFile();
543     }
544     return NULL;
545 }
546 
547 uint32_t
548 SymbolFileDWARFDebugMap::CalculateAbilities ()
549 {
550     // In order to get the abilities of this plug-in, we look at the list of
551     // N_OSO entries (object files) from the symbol table and make sure that
552     // these files exist and also contain valid DWARF. If we get any of that
553     // then we return the abilities of the first N_OSO's DWARF.
554 
555     const uint32_t oso_index_count = GetNumCompileUnits();
556     if (oso_index_count > 0)
557     {
558         const uint32_t dwarf_abilities = SymbolFile::CompileUnits |
559                                          SymbolFile::Functions |
560                                          SymbolFile::Blocks |
561                                          SymbolFile::GlobalVariables |
562                                          SymbolFile::LocalVariables |
563                                          SymbolFile::VariableTypes |
564                                          SymbolFile::LineTables;
565 
566         InitOSO();
567         if (!m_compile_unit_infos.empty())
568             return dwarf_abilities;
569 //        for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
570 //        {
571 //            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
572 //            if (oso_dwarf)
573 //            {
574 //                uint32_t oso_abilities = oso_dwarf->GetAbilities();
575 //                if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
576 //                    return oso_abilities;
577 //            }
578 //        }
579     }
580     return 0;
581 }
582 
583 uint32_t
584 SymbolFileDWARFDebugMap::GetNumCompileUnits()
585 {
586     InitOSO ();
587     return m_compile_unit_infos.size();
588 }
589 
590 
591 CompUnitSP
592 SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
593 {
594     CompUnitSP comp_unit_sp;
595     const uint32_t cu_count = GetNumCompileUnits();
596 
597     if (cu_idx < cu_count)
598     {
599         if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL &&
600             m_compile_unit_infos[cu_idx].symbol_file_supported)
601         {
602             FileSpec so_file_spec;
603             if (GetFileSpecForSO (cu_idx, so_file_spec))
604             {
605                 Module *oso_module = GetModuleByOSOIndex (cu_idx);
606                 if (oso_module)
607                 {
608                      // User zero as the ID to match the compile unit at offset
609                      // zero in each .o file since each .o file can only have
610                      // one compile unit for now.
611                     lldb::user_id_t cu_id = 0;
612                     m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset (new CompileUnit (oso_module->shared_from_this(),
613                                                                                              NULL,
614                                                                                              so_file_spec,
615                                                                                              cu_id,
616                                                                                              eLanguageTypeUnknown));
617                 }
618 
619                 if (!m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
620                 {
621                     m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
622                                                                                             NULL,
623                                                                                             so_file_spec,
624                                                                                             cu_idx,
625                                                                                             eLanguageTypeUnknown));
626                 }
627 
628                 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
629                 {
630                     // Let our symbol vendor know about this compile unit
631                     m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx,
632                                                                                        m_compile_unit_infos[cu_idx].oso_compile_unit_sp);
633                 }
634             }
635         }
636         comp_unit_sp = m_compile_unit_infos[cu_idx].oso_compile_unit_sp;
637     }
638 
639     return comp_unit_sp;
640 }
641 
642 SymbolFileDWARFDebugMap::CompileUnitInfo *
643 SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
644 {
645     const uint32_t cu_count = GetNumCompileUnits();
646     for (uint32_t i=0; i<cu_count; ++i)
647     {
648         if (sc.comp_unit == m_compile_unit_infos[i].oso_compile_unit_sp.get())
649             return &m_compile_unit_infos[i];
650     }
651     return NULL;
652 }
653 
654 
655 SymbolFileDWARFDebugMap::CompileUnitInfo *
656 SymbolFileDWARFDebugMap::GetCompUnitInfo (const lldb_private::Module *module)
657 {
658     const uint32_t cu_count = GetNumCompileUnits();
659     for (uint32_t i=0; i<cu_count; ++i)
660     {
661         if (module == m_compile_unit_infos[i].oso_module_sp.get())
662             return &m_compile_unit_infos[i];
663     }
664     return NULL;
665 }
666 
667 lldb::LanguageType
668 SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
669 {
670     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
671     if (oso_dwarf)
672         return oso_dwarf->ParseCompileUnitLanguage (sc);
673     return eLanguageTypeUnknown;
674 }
675 
676 size_t
677 SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
678 {
679     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
680     if (oso_dwarf)
681         return oso_dwarf->ParseCompileUnitFunctions (sc);
682     return 0;
683 }
684 
685 bool
686 SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
687 {
688     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
689     if (oso_dwarf)
690         return oso_dwarf->ParseCompileUnitLineTable (sc);
691     return false;
692 }
693 
694 bool
695 SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
696 {
697     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
698     if (oso_dwarf)
699         return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
700     return false;
701 }
702 
703 
704 size_t
705 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
706 {
707     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
708     if (oso_dwarf)
709         return oso_dwarf->ParseFunctionBlocks (sc);
710     return 0;
711 }
712 
713 
714 size_t
715 SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
716 {
717     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
718     if (oso_dwarf)
719         return oso_dwarf->ParseTypes (sc);
720     return 0;
721 }
722 
723 
724 size_t
725 SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
726 {
727     SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
728     if (oso_dwarf)
729         return oso_dwarf->ParseVariablesForContext (sc);
730     return 0;
731 }
732 
733 
734 
735 Type*
736 SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
737 {
738     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
739     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
740     if (oso_dwarf)
741         oso_dwarf->ResolveTypeUID (type_uid);
742     return NULL;
743 }
744 
745 lldb::clang_type_t
746 SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
747 {
748     // We have a struct/union/class/enum that needs to be fully resolved.
749     return NULL;
750 }
751 
752 uint32_t
753 SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
754 {
755     uint32_t resolved_flags = 0;
756     Symtab* symtab = m_obj_file->GetSymtab();
757     if (symtab)
758     {
759         const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
760         sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size());
761 
762         if (sc.symbol != NULL)
763         {
764             resolved_flags |= eSymbolContextSymbol;
765 
766             uint32_t oso_idx = 0;
767             CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
768             if (comp_unit_info)
769             {
770                 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
771                 ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx);
772                 if (oso_dwarf && oso_objfile)
773                 {
774                     SectionList *oso_section_list = oso_objfile->GetSectionList();
775 
776                     SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX));
777 
778                     if (oso_symbol_section_sp)
779                     {
780                         const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress();
781                         Address oso_so_addr (oso_symbol_section_sp, exe_file_addr - linked_file_addr);
782                         if (oso_so_addr.IsSectionOffset())
783                             resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
784                     }
785                 }
786             }
787         }
788     }
789     return resolved_flags;
790 }
791 
792 
793 uint32_t
794 SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
795 {
796     const uint32_t initial = sc_list.GetSize();
797     const uint32_t cu_count = GetNumCompileUnits();
798 
799     for (uint32_t i=0; i<cu_count; ++i)
800     {
801         // If we are checking for inlines, then we need to look through all
802         // compile units no matter if "file_spec" matches.
803         bool resolve = check_inlines;
804 
805         if (!resolve)
806         {
807             FileSpec so_file_spec;
808             if (GetFileSpecForSO (i, so_file_spec))
809             {
810                 // Match the full path if the incoming file_spec has a directory (not just a basename)
811                 const bool full_match = file_spec.GetDirectory();
812                 resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
813             }
814         }
815         if (resolve)
816         {
817             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
818             if (oso_dwarf)
819                 oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
820         }
821     }
822     return sc_list.GetSize() - initial;
823 }
824 
825 uint32_t
826 SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
827 (
828     const ConstString &name,
829     const ClangNamespaceDecl *namespace_decl,
830     const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
831     uint32_t max_matches,
832     VariableList& variables
833 )
834 {
835     const uint32_t original_size = variables.GetSize();
836     const size_t match_count = indexes.size();
837     for (size_t i=0; i<match_count; ++i)
838     {
839         uint32_t oso_idx;
840         CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
841         if (comp_unit_info)
842         {
843             SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
844             if (oso_dwarf)
845             {
846                 if (oso_dwarf->FindGlobalVariables(name, namespace_decl, true, max_matches, variables))
847                     if (variables.GetSize() > max_matches)
848                         break;
849             }
850         }
851     }
852     return variables.GetSize() - original_size;
853 }
854 
855 uint32_t
856 SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
857 {
858 
859     // If we aren't appending the results to this list, then clear the list
860     if (!append)
861         variables.Clear();
862 
863     // Remember how many variables are in the list before we search in case
864     // we are appending the results to a variable list.
865     const uint32_t original_size = variables.GetSize();
866 
867     uint32_t total_matches = 0;
868     SymbolFileDWARF *oso_dwarf;
869     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
870     {
871         const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
872                                                                      namespace_decl,
873                                                                      true,
874                                                                      max_matches,
875                                                                      variables);
876         if (oso_matches > 0)
877         {
878             total_matches += oso_matches;
879 
880             // Are we getting all matches?
881             if (max_matches == UINT32_MAX)
882                 continue;   // Yep, continue getting everything
883 
884             // If we have found enough matches, lets get out
885             if (max_matches >= total_matches)
886                 break;
887 
888             // Update the max matches for any subsequent calls to find globals
889             // in any other object files with DWARF
890             max_matches -= oso_matches;
891         }
892     }
893     // Return the number of variable that were appended to the list
894     return variables.GetSize() - original_size;
895 }
896 
897 
898 uint32_t
899 SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
900 {
901     // If we aren't appending the results to this list, then clear the list
902     if (!append)
903         variables.Clear();
904 
905     // Remember how many variables are in the list before we search in case
906     // we are appending the results to a variable list.
907     const uint32_t original_size = variables.GetSize();
908 
909     uint32_t total_matches = 0;
910     SymbolFileDWARF *oso_dwarf;
911     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
912     {
913         const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
914                                                                      true,
915                                                                      max_matches,
916                                                                      variables);
917         if (oso_matches > 0)
918         {
919             total_matches += oso_matches;
920 
921             // Are we getting all matches?
922             if (max_matches == UINT32_MAX)
923                 continue;   // Yep, continue getting everything
924 
925             // If we have found enough matches, lets get out
926             if (max_matches >= total_matches)
927                 break;
928 
929             // Update the max matches for any subsequent calls to find globals
930             // in any other object files with DWARF
931             max_matches -= oso_matches;
932         }
933     }
934     // Return the number of variable that were appended to the list
935     return variables.GetSize() - original_size;
936 }
937 
938 
939 int
940 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
941 {
942     const uint32_t symbol_idx = *symbol_idx_ptr;
943 
944     if (symbol_idx < comp_unit_info->first_symbol_index)
945         return -1;
946 
947     if (symbol_idx <= comp_unit_info->last_symbol_index)
948         return 0;
949 
950     return 1;
951 }
952 
953 
954 int
955 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
956 {
957     const user_id_t symbol_id = *symbol_idx_ptr;
958 
959     if (symbol_id < comp_unit_info->first_symbol_id)
960         return -1;
961 
962     if (symbol_id <= comp_unit_info->last_symbol_id)
963         return 0;
964 
965     return 1;
966 }
967 
968 
969 SymbolFileDWARFDebugMap::CompileUnitInfo*
970 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
971 {
972     const uint32_t oso_index_count = m_compile_unit_infos.size();
973     CompileUnitInfo *comp_unit_info = NULL;
974     if (oso_index_count)
975     {
976         comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
977                                                    &m_compile_unit_infos[0],
978                                                    m_compile_unit_infos.size(),
979                                                    sizeof(CompileUnitInfo),
980                                                    (ComparisonFunction)SymbolContainsSymbolWithIndex);
981     }
982 
983     if (oso_idx_ptr)
984     {
985         if (comp_unit_info != NULL)
986             *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
987         else
988             *oso_idx_ptr = UINT32_MAX;
989     }
990     return comp_unit_info;
991 }
992 
993 SymbolFileDWARFDebugMap::CompileUnitInfo*
994 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
995 {
996     const uint32_t oso_index_count = m_compile_unit_infos.size();
997     CompileUnitInfo *comp_unit_info = NULL;
998     if (oso_index_count)
999     {
1000         comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
1001                                                       &m_compile_unit_infos[0],
1002                                                       m_compile_unit_infos.size(),
1003                                                       sizeof(CompileUnitInfo),
1004                                                       (ComparisonFunction)SymbolContainsSymbolWithID);
1005     }
1006 
1007     if (oso_idx_ptr)
1008     {
1009         if (comp_unit_info != NULL)
1010             *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1011         else
1012             *oso_idx_ptr = UINT32_MAX;
1013     }
1014     return comp_unit_info;
1015 }
1016 
1017 
1018 static void
1019 RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
1020 {
1021     // We found functions in .o files. Not all functions in the .o files
1022     // will have made it into the final output file. The ones that did
1023     // make it into the final output file will have a section whose module
1024     // matches the module from the ObjectFile for this SymbolFile. When
1025     // the modules don't match, then we have something that was in a
1026     // .o file, but doesn't map to anything in the final executable.
1027     uint32_t i=start_idx;
1028     while (i < sc_list.GetSize())
1029     {
1030         SymbolContext sc;
1031         sc_list.GetContextAtIndex(i, sc);
1032         if (sc.function)
1033         {
1034             const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
1035             if (section_sp->GetModule() != module_sp)
1036             {
1037                 sc_list.RemoveContextAtIndex(i);
1038                 continue;
1039             }
1040         }
1041         ++i;
1042     }
1043 }
1044 
1045 uint32_t
1046 SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
1047 {
1048     Timer scoped_timer (__PRETTY_FUNCTION__,
1049                         "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1050                         name.GetCString());
1051 
1052     uint32_t initial_size = 0;
1053     if (append)
1054         initial_size = sc_list.GetSize();
1055     else
1056         sc_list.Clear();
1057 
1058     uint32_t oso_idx = 0;
1059     SymbolFileDWARF *oso_dwarf;
1060     while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
1061     {
1062         uint32_t sc_idx = sc_list.GetSize();
1063         if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list))
1064         {
1065             RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1066         }
1067     }
1068 
1069     return sc_list.GetSize() - initial_size;
1070 }
1071 
1072 
1073 uint32_t
1074 SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
1075 {
1076     Timer scoped_timer (__PRETTY_FUNCTION__,
1077                         "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1078                         regex.GetText());
1079 
1080     uint32_t initial_size = 0;
1081     if (append)
1082         initial_size = sc_list.GetSize();
1083     else
1084         sc_list.Clear();
1085 
1086     uint32_t oso_idx = 0;
1087     SymbolFileDWARF *oso_dwarf;
1088     while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
1089     {
1090         uint32_t sc_idx = sc_list.GetSize();
1091 
1092         if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
1093         {
1094             RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1095         }
1096     }
1097 
1098     return sc_list.GetSize() - initial_size;
1099 }
1100 
1101 TypeSP
1102 SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
1103 {
1104     TypeSP type_sp;
1105     SymbolFileDWARF *oso_dwarf;
1106     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1107     {
1108         type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
1109         if (type_sp)
1110             break;
1111     }
1112     return type_sp;
1113 }
1114 
1115 
1116 
1117 bool
1118 SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
1119 {
1120     if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
1121     {
1122         m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
1123         SymbolFileDWARF *oso_dwarf;
1124         for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1125         {
1126             if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
1127             {
1128                 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
1129                 break;
1130             }
1131         }
1132     }
1133     return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1134 }
1135 
1136 TypeSP
1137 SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
1138                                                                const ConstString &type_name,
1139                                                                bool must_be_implementation)
1140 {
1141     TypeSP type_sp;
1142     SymbolFileDWARF *oso_dwarf;
1143     for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1144     {
1145         type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
1146         if (type_sp)
1147             break;
1148     }
1149     return type_sp;
1150 }
1151 
1152 uint32_t
1153 SymbolFileDWARFDebugMap::FindTypes
1154 (
1155     const SymbolContext& sc,
1156     const ConstString &name,
1157     const ClangNamespaceDecl *namespace_decl,
1158     bool append,
1159     uint32_t max_matches,
1160     TypeList& types
1161 )
1162 {
1163     if (!append)
1164         types.Clear();
1165 
1166     const uint32_t initial_types_size = types.GetSize();
1167     SymbolFileDWARF *oso_dwarf;
1168 
1169     if (sc.comp_unit)
1170     {
1171         oso_dwarf = GetSymbolFile (sc);
1172         if (oso_dwarf)
1173             return oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
1174     }
1175     else
1176     {
1177         uint32_t oso_idx = 0;
1178         while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
1179             oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
1180     }
1181 
1182     return types.GetSize() - initial_types_size;
1183 }
1184 
1185 //
1186 //uint32_t
1187 //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)
1188 //{
1189 //  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1190 //  if (oso_dwarf)
1191 //      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
1192 //  return 0;
1193 //}
1194 
1195 
1196 ClangNamespaceDecl
1197 SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc,
1198                                         const lldb_private::ConstString &name,
1199                                         const ClangNamespaceDecl *parent_namespace_decl)
1200 {
1201     ClangNamespaceDecl matching_namespace;
1202     SymbolFileDWARF *oso_dwarf;
1203 
1204     if (sc.comp_unit)
1205     {
1206         oso_dwarf = GetSymbolFile (sc);
1207         if (oso_dwarf)
1208             matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
1209     }
1210     else
1211     {
1212         for (uint32_t oso_idx = 0;
1213              ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL);
1214              ++oso_idx)
1215         {
1216             matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
1217 
1218             if (matching_namespace)
1219                 break;
1220         }
1221     }
1222 
1223     return matching_namespace;
1224 }
1225 
1226 //------------------------------------------------------------------
1227 // PluginInterface protocol
1228 //------------------------------------------------------------------
1229 const char *
1230 SymbolFileDWARFDebugMap::GetPluginName()
1231 {
1232     return "SymbolFileDWARFDebugMap";
1233 }
1234 
1235 const char *
1236 SymbolFileDWARFDebugMap::GetShortPluginName()
1237 {
1238     return GetPluginNameStatic();
1239 }
1240 
1241 uint32_t
1242 SymbolFileDWARFDebugMap::GetPluginVersion()
1243 {
1244     return 1;
1245 }
1246 
1247 lldb::CompUnitSP
1248 SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
1249 {
1250     if (oso_dwarf)
1251     {
1252         const uint32_t cu_count = GetNumCompileUnits();
1253         for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1254         {
1255             SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1256             if (oso_symfile == oso_dwarf)
1257             {
1258                 if (!m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
1259                     m_compile_unit_infos[cu_idx].oso_compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
1260 
1261                 return m_compile_unit_infos[cu_idx].oso_compile_unit_sp;
1262             }
1263         }
1264     }
1265     assert(!"this shouldn't happen");
1266     return lldb::CompUnitSP();
1267 }
1268 
1269 
1270 void
1271 SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
1272 {
1273     if (oso_dwarf)
1274     {
1275         const uint32_t cu_count = GetNumCompileUnits();
1276         for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1277         {
1278             SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1279             if (oso_symfile == oso_dwarf)
1280             {
1281                 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
1282                 {
1283                     assert (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == cu_sp.get());
1284                 }
1285                 else
1286                 {
1287                     m_compile_unit_infos[cu_idx].oso_compile_unit_sp = cu_sp;
1288                     m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
1289                 }
1290             }
1291         }
1292     }
1293 }
1294 
1295 
1296 void
1297 SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl)
1298 {
1299     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1300     clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
1301     if (clang_type)
1302     {
1303         SymbolFileDWARF *oso_dwarf;
1304 
1305         for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1306         {
1307             if (oso_dwarf->HasForwardDeclForClangType (clang_type))
1308             {
1309                 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
1310                 return;
1311             }
1312         }
1313     }
1314 }
1315 
1316 void
1317 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
1318 {
1319     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1320     clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
1321     if (clang_type)
1322     {
1323         SymbolFileDWARF *oso_dwarf;
1324 
1325         for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1326         {
1327             if (oso_dwarf->HasForwardDeclForClangType (clang_type))
1328             {
1329                 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
1330                 return;
1331             }
1332         }
1333     }
1334 }
1335 
1336 bool
1337 SymbolFileDWARFDebugMap::LayoutRecordType (void *baton,
1338                                            const clang::RecordDecl *record_decl,
1339                                            uint64_t &size,
1340                                            uint64_t &alignment,
1341                                            llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
1342                                            llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
1343                                            llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
1344 {
1345     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1346     SymbolFileDWARF *oso_dwarf;
1347     for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1348     {
1349         if (oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets))
1350             return true;
1351     }
1352     return false;
1353 }
1354 
1355 
1356 
1357 clang::DeclContext*
1358 SymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
1359 {
1360     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1361     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1362     if (oso_dwarf)
1363         return oso_dwarf->GetClangDeclContextContainingTypeUID (type_uid);
1364     return NULL;
1365 }
1366 
1367 clang::DeclContext*
1368 SymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1369 {
1370     const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1371     SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1372     if (oso_dwarf)
1373         return oso_dwarf->GetClangDeclContextForTypeUID (sc, type_uid);
1374     return NULL;
1375 }
1376 
1377 
1378