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