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