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