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