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