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