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