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