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