19f2f44ceSEd Maste //===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "SymbolFileDWARFDebugMap.h"
11ac7ddfbfSEd Maste 
12ac7ddfbfSEd Maste #include "DWARFDebugAranges.h"
13ac7ddfbfSEd Maste 
14ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
15ac7ddfbfSEd Maste #include "lldb/Core/ModuleList.h"
16ac7ddfbfSEd Maste #include "lldb/Core/PluginManager.h"
17435933ddSDimitry Andric #include "lldb/Core/RangeMap.h"
18ac7ddfbfSEd Maste #include "lldb/Core/Section.h"
19435933ddSDimitry Andric #include "lldb/Host/FileSystem.h"
20f678e45dSDimitry Andric #include "lldb/Utility/RegularExpression.h"
21a580b014SDimitry Andric #include "lldb/Utility/Timer.h"
22ac7ddfbfSEd Maste 
23ac7ddfbfSEd Maste //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
24ac7ddfbfSEd Maste #if defined(DEBUG_OSO_DMAP)
25ac7ddfbfSEd Maste #include "lldb/Core/StreamFile.h"
26ac7ddfbfSEd Maste #endif
27ac7ddfbfSEd Maste 
28ac7ddfbfSEd Maste #include "lldb/Symbol/CompileUnit.h"
29ac7ddfbfSEd Maste #include "lldb/Symbol/LineTable.h"
30ac7ddfbfSEd Maste #include "lldb/Symbol/ObjectFile.h"
31ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolVendor.h"
329f2f44ceSEd Maste #include "lldb/Symbol/TypeMap.h"
33ac7ddfbfSEd Maste #include "lldb/Symbol/VariableList.h"
34435933ddSDimitry Andric #include "llvm/Support/ScopedPrinter.h"
35ac7ddfbfSEd Maste 
36ac7ddfbfSEd Maste #include "LogChannelDWARF.h"
37ac7ddfbfSEd Maste #include "SymbolFileDWARF.h"
38ac7ddfbfSEd Maste 
39ac7ddfbfSEd Maste using namespace lldb;
40ac7ddfbfSEd Maste using namespace lldb_private;
41ac7ddfbfSEd Maste 
42435933ddSDimitry Andric // Subclass lldb_private::Module so we can intercept the
434ba319b5SDimitry Andric // "Module::GetObjectFile()" (so we can fixup the object file sections) and
444ba319b5SDimitry Andric // also for "Module::GetSymbolVendor()" (so we can fixup the symbol file id.
45ac7ddfbfSEd Maste 
46ac7ddfbfSEd Maste const SymbolFileDWARFDebugMap::FileRangeMap &
GetFileRangeMap(SymbolFileDWARFDebugMap * exe_symfile)47435933ddSDimitry Andric SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
48435933ddSDimitry Andric     SymbolFileDWARFDebugMap *exe_symfile) {
49ac7ddfbfSEd Maste   if (file_range_map_valid)
50ac7ddfbfSEd Maste     return file_range_map;
51ac7ddfbfSEd Maste 
52ac7ddfbfSEd Maste   file_range_map_valid = true;
53ac7ddfbfSEd Maste 
54ac7ddfbfSEd Maste   Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this);
55ac7ddfbfSEd Maste   if (!oso_module)
56ac7ddfbfSEd Maste     return file_range_map;
57ac7ddfbfSEd Maste 
58ac7ddfbfSEd Maste   ObjectFile *oso_objfile = oso_module->GetObjectFile();
59ac7ddfbfSEd Maste   if (!oso_objfile)
60ac7ddfbfSEd Maste     return file_range_map;
61ac7ddfbfSEd Maste 
62ac7ddfbfSEd Maste   Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
63435933ddSDimitry Andric   if (log) {
64ac7ddfbfSEd Maste     ConstString object_name(oso_module->GetObjectName());
65435933ddSDimitry Andric     log->Printf(
66435933ddSDimitry Andric         "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
670127ef0fSEd Maste         static_cast<void *>(this),
68ac7ddfbfSEd Maste         oso_module->GetSpecificationDescription().c_str());
69ac7ddfbfSEd Maste   }
70ac7ddfbfSEd Maste 
71ac7ddfbfSEd Maste   std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
72435933ddSDimitry Andric   if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
73435933ddSDimitry Andric     for (auto comp_unit_info : cu_infos) {
74ac7ddfbfSEd Maste       Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
75ac7ddfbfSEd Maste       ModuleSP oso_module_sp(oso_objfile->GetModule());
76ac7ddfbfSEd Maste       Symtab *oso_symtab = oso_objfile->GetSymtab();
77ac7ddfbfSEd Maste 
78435933ddSDimitry Andric       /// const uint32_t fun_resolve_flags = SymbolContext::Module |
79435933ddSDimitry Andric       /// eSymbolContextCompUnit | eSymbolContextFunction;
80ac7ddfbfSEd Maste       // SectionList *oso_sections = oso_objfile->Sections();
814ba319b5SDimitry Andric       // Now we need to make sections that map from zero based object file
824ba319b5SDimitry Andric       // addresses to where things ended up in the main executable.
83ac7ddfbfSEd Maste 
84ac7ddfbfSEd Maste       assert(comp_unit_info->first_symbol_index != UINT32_MAX);
85ac7ddfbfSEd Maste       // End index is one past the last valid symbol index
86ac7ddfbfSEd Maste       const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
87435933ddSDimitry Andric       for (uint32_t idx = comp_unit_info->first_symbol_index +
88435933ddSDimitry Andric                           2; // Skip the N_SO and N_OSO
89*b5893f02SDimitry Andric            idx < oso_end_idx; ++idx) {
90ac7ddfbfSEd Maste         Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
91435933ddSDimitry Andric         if (exe_symbol) {
92*b5893f02SDimitry Andric           if (!exe_symbol->IsDebug())
93ac7ddfbfSEd Maste             continue;
94ac7ddfbfSEd Maste 
95435933ddSDimitry Andric           switch (exe_symbol->GetType()) {
96ac7ddfbfSEd Maste           default:
97ac7ddfbfSEd Maste             break;
98ac7ddfbfSEd Maste 
99435933ddSDimitry Andric           case eSymbolTypeCode: {
1004ba319b5SDimitry Andric             // For each N_FUN, or function that we run into in the debug map we
1014ba319b5SDimitry Andric             // make a new section that we add to the sections found in the .o
1024ba319b5SDimitry Andric             // file. This new section has the file address set to what the
103ac7ddfbfSEd Maste             // addresses are in the .o file, and the load address is adjusted
104ac7ddfbfSEd Maste             // to match where it ended up in the final executable! We do this
105ac7ddfbfSEd Maste             // before we parse any dwarf info so that when it goes get parsed
106ac7ddfbfSEd Maste             // all section/offset addresses that get registered will resolve
107ac7ddfbfSEd Maste             // correctly to the new addresses in the main executable.
108ac7ddfbfSEd Maste 
109ac7ddfbfSEd Maste             // First we find the original symbol in the .o file's symbol table
110435933ddSDimitry Andric             Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(
111435933ddSDimitry Andric                 exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
112435933ddSDimitry Andric                                                  Mangled::ePreferMangled),
113435933ddSDimitry Andric                 eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
114435933ddSDimitry Andric             if (oso_fun_symbol) {
115ac7ddfbfSEd Maste               // Add the inverse OSO file address to debug map entry mapping
116435933ddSDimitry Andric               exe_symfile->AddOSOFileRange(
117435933ddSDimitry Andric                   this, exe_symbol->GetAddressRef().GetFileAddress(),
1184bb0738eSEd Maste                   exe_symbol->GetByteSize(),
1191c3bbb01SEd Maste                   oso_fun_symbol->GetAddressRef().GetFileAddress(),
1204bb0738eSEd Maste                   oso_fun_symbol->GetByteSize());
121ac7ddfbfSEd Maste             }
122435933ddSDimitry Andric           } break;
123ac7ddfbfSEd Maste 
124435933ddSDimitry Andric           case eSymbolTypeData: {
1254ba319b5SDimitry Andric             // For each N_GSYM we remap the address for the global by making a
1264ba319b5SDimitry Andric             // new section that we add to the sections found in the .o file.
1274ba319b5SDimitry Andric             // This new section has the file address set to what the addresses
1284ba319b5SDimitry Andric             // are in the .o file, and the load address is adjusted to match
1294ba319b5SDimitry Andric             // where it ended up in the final executable! We do this before we
1304ba319b5SDimitry Andric             // parse any dwarf info so that when it goes get parsed all
1314ba319b5SDimitry Andric             // section/offset addresses that get registered will resolve
132ac7ddfbfSEd Maste             // correctly to the new addresses in the main executable. We
133ac7ddfbfSEd Maste             // initially set the section size to be 1 byte, but will need to
134ac7ddfbfSEd Maste             // fix up these addresses further after all globals have been
135ac7ddfbfSEd Maste             // parsed to span the gaps, or we can find the global variable
136ac7ddfbfSEd Maste             // sizes from the DWARF info as we are parsing.
137ac7ddfbfSEd Maste 
1384ba319b5SDimitry Andric             // Next we find the non-stab entry that corresponds to the N_GSYM
1394ba319b5SDimitry Andric             // in the .o file
140435933ddSDimitry Andric             Symbol *oso_gsym_symbol =
141435933ddSDimitry Andric                 oso_symtab->FindFirstSymbolWithNameAndType(
142435933ddSDimitry Andric                     exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
143435933ddSDimitry Andric                                                      Mangled::ePreferMangled),
144435933ddSDimitry Andric                     eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny);
145435933ddSDimitry Andric             if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() &&
146435933ddSDimitry Andric                 oso_gsym_symbol->ValueIsAddress()) {
147ac7ddfbfSEd Maste               // Add the inverse OSO file address to debug map entry mapping
148435933ddSDimitry Andric               exe_symfile->AddOSOFileRange(
149435933ddSDimitry Andric                   this, exe_symbol->GetAddressRef().GetFileAddress(),
1504bb0738eSEd Maste                   exe_symbol->GetByteSize(),
1511c3bbb01SEd Maste                   oso_gsym_symbol->GetAddressRef().GetFileAddress(),
1524bb0738eSEd Maste                   oso_gsym_symbol->GetByteSize());
153ac7ddfbfSEd Maste             }
154435933ddSDimitry Andric           } break;
155ac7ddfbfSEd Maste           }
156ac7ddfbfSEd Maste         }
157ac7ddfbfSEd Maste       }
158ac7ddfbfSEd Maste 
159ac7ddfbfSEd Maste       exe_symfile->FinalizeOSOFileRanges(this);
160ac7ddfbfSEd Maste       // We don't need the symbols anymore for the .o files
161ac7ddfbfSEd Maste       oso_objfile->ClearSymtab();
162ac7ddfbfSEd Maste     }
163ac7ddfbfSEd Maste   }
164ac7ddfbfSEd Maste   return file_range_map;
165ac7ddfbfSEd Maste }
166ac7ddfbfSEd Maste 
167435933ddSDimitry Andric class DebugMapModule : public Module {
168ac7ddfbfSEd Maste public:
DebugMapModule(const ModuleSP & exe_module_sp,uint32_t cu_idx,const FileSpec & file_spec,const ArchSpec & arch,const ConstString * object_name,off_t object_offset,const llvm::sys::TimePoint<> object_mod_time)169435933ddSDimitry Andric   DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx,
170435933ddSDimitry Andric                  const FileSpec &file_spec, const ArchSpec &arch,
171435933ddSDimitry Andric                  const ConstString *object_name, off_t object_offset,
172435933ddSDimitry Andric                  const llvm::sys::TimePoint<> object_mod_time)
173435933ddSDimitry Andric       : Module(file_spec, arch, object_name, object_offset, object_mod_time),
174435933ddSDimitry Andric         m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {}
175ac7ddfbfSEd Maste 
1769f2f44ceSEd Maste   ~DebugMapModule() override = default;
177ac7ddfbfSEd Maste 
1789f2f44ceSEd Maste   SymbolVendor *
GetSymbolVendor(bool can_create=true,lldb_private::Stream * feedback_strm=NULL)179435933ddSDimitry Andric   GetSymbolVendor(bool can_create = true,
180435933ddSDimitry Andric                   lldb_private::Stream *feedback_strm = NULL) override {
181ac7ddfbfSEd Maste     // Scope for locker
182*b5893f02SDimitry Andric     if (m_symfile_ap.get() || !can_create)
183ac7ddfbfSEd Maste       return m_symfile_ap.get();
184ac7ddfbfSEd Maste 
185ac7ddfbfSEd Maste     ModuleSP exe_module_sp(m_exe_module_wp.lock());
186435933ddSDimitry Andric     if (exe_module_sp) {
187ac7ddfbfSEd Maste       // Now get the object file outside of a locking scope
188ac7ddfbfSEd Maste       ObjectFile *oso_objfile = GetObjectFile();
189435933ddSDimitry Andric       if (oso_objfile) {
1904bb0738eSEd Maste         std::lock_guard<std::recursive_mutex> guard(m_mutex);
191435933ddSDimitry Andric         SymbolVendor *symbol_vendor =
192435933ddSDimitry Andric             Module::GetSymbolVendor(can_create, feedback_strm);
193435933ddSDimitry Andric         if (symbol_vendor) {
1944ba319b5SDimitry Andric           // Set a pointer to this class to set our OSO DWARF file know that
1954ba319b5SDimitry Andric           // the DWARF is being used along with a debug map and that it will
1964ba319b5SDimitry Andric           // have the remapped sections that we do below.
197435933ddSDimitry Andric           SymbolFileDWARF *oso_symfile =
198435933ddSDimitry Andric               SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(
199435933ddSDimitry Andric                   symbol_vendor->GetSymbolFile());
200ac7ddfbfSEd Maste 
201ac7ddfbfSEd Maste           if (!oso_symfile)
202ac7ddfbfSEd Maste             return NULL;
203ac7ddfbfSEd Maste 
204ac7ddfbfSEd Maste           ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
205ac7ddfbfSEd Maste           SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
206ac7ddfbfSEd Maste 
207435933ddSDimitry Andric           if (exe_objfile && exe_sym_vendor) {
208ac7ddfbfSEd Maste             oso_symfile->SetDebugMapModule(exe_module_sp);
209ac7ddfbfSEd Maste             // Set the ID of the symbol file DWARF to the index of the OSO
210ac7ddfbfSEd Maste             // shifted left by 32 bits to provide a unique prefix for any
211ac7ddfbfSEd Maste             // UserID's that get created in the symbol file.
212ac7ddfbfSEd Maste             oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull);
213ac7ddfbfSEd Maste           }
214ac7ddfbfSEd Maste           return symbol_vendor;
215ac7ddfbfSEd Maste         }
216ac7ddfbfSEd Maste       }
217ac7ddfbfSEd Maste     }
218ac7ddfbfSEd Maste     return NULL;
219ac7ddfbfSEd Maste   }
220ac7ddfbfSEd Maste 
221ac7ddfbfSEd Maste protected:
222ac7ddfbfSEd Maste   ModuleWP m_exe_module_wp;
223ac7ddfbfSEd Maste   const uint32_t m_cu_idx;
224ac7ddfbfSEd Maste };
225ac7ddfbfSEd Maste 
Initialize()226435933ddSDimitry Andric void SymbolFileDWARFDebugMap::Initialize() {
227ac7ddfbfSEd Maste   PluginManager::RegisterPlugin(GetPluginNameStatic(),
228435933ddSDimitry Andric                                 GetPluginDescriptionStatic(), CreateInstance);
229ac7ddfbfSEd Maste }
230ac7ddfbfSEd Maste 
Terminate()231435933ddSDimitry Andric void SymbolFileDWARFDebugMap::Terminate() {
232ac7ddfbfSEd Maste   PluginManager::UnregisterPlugin(CreateInstance);
233ac7ddfbfSEd Maste }
234ac7ddfbfSEd Maste 
GetPluginNameStatic()235435933ddSDimitry Andric lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() {
236ac7ddfbfSEd Maste   static ConstString g_name("dwarf-debugmap");
237ac7ddfbfSEd Maste   return g_name;
238ac7ddfbfSEd Maste }
239ac7ddfbfSEd Maste 
GetPluginDescriptionStatic()240435933ddSDimitry Andric const char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
241ac7ddfbfSEd Maste   return "DWARF and DWARF3 debug symbol file reader (debug map).";
242ac7ddfbfSEd Maste }
243ac7ddfbfSEd Maste 
CreateInstance(ObjectFile * obj_file)244435933ddSDimitry Andric SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) {
245ac7ddfbfSEd Maste   return new SymbolFileDWARFDebugMap(obj_file);
246ac7ddfbfSEd Maste }
247ac7ddfbfSEd Maste 
SymbolFileDWARFDebugMap(ObjectFile * ofile)248435933ddSDimitry Andric SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
249435933ddSDimitry Andric     : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
250ac7ddfbfSEd Maste       m_glob_indexes(),
251435933ddSDimitry Andric       m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
252ac7ddfbfSEd Maste 
~SymbolFileDWARFDebugMap()253435933ddSDimitry Andric SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
254ac7ddfbfSEd Maste 
InitializeObject()255435933ddSDimitry Andric void SymbolFileDWARFDebugMap::InitializeObject() {}
256ac7ddfbfSEd Maste 
InitOSO()257435933ddSDimitry Andric void SymbolFileDWARFDebugMap::InitOSO() {
258ac7ddfbfSEd Maste   if (m_flags.test(kHaveInitializedOSOs))
259ac7ddfbfSEd Maste     return;
260ac7ddfbfSEd Maste 
261ac7ddfbfSEd Maste   m_flags.set(kHaveInitializedOSOs);
262ac7ddfbfSEd Maste 
263ac7ddfbfSEd Maste   // If the object file has been stripped, there is no sense in looking further
264ac7ddfbfSEd Maste   // as all of the debug symbols for the debug map will not be available
265ac7ddfbfSEd Maste   if (m_obj_file->IsStripped())
266ac7ddfbfSEd Maste     return;
267ac7ddfbfSEd Maste 
268ac7ddfbfSEd Maste   // Also make sure the file type is some sort of executable. Core files, debug
269ac7ddfbfSEd Maste   // info files (dSYM), object files (.o files), and stub libraries all can
270435933ddSDimitry Andric   switch (m_obj_file->GetType()) {
271ac7ddfbfSEd Maste   case ObjectFile::eTypeInvalid:
272ac7ddfbfSEd Maste   case ObjectFile::eTypeCoreFile:
273ac7ddfbfSEd Maste   case ObjectFile::eTypeDebugInfo:
274ac7ddfbfSEd Maste   case ObjectFile::eTypeObjectFile:
275ac7ddfbfSEd Maste   case ObjectFile::eTypeStubLibrary:
276ac7ddfbfSEd Maste   case ObjectFile::eTypeUnknown:
2770127ef0fSEd Maste   case ObjectFile::eTypeJIT:
278ac7ddfbfSEd Maste     return;
279ac7ddfbfSEd Maste 
280ac7ddfbfSEd Maste   case ObjectFile::eTypeExecutable:
281ac7ddfbfSEd Maste   case ObjectFile::eTypeDynamicLinker:
282ac7ddfbfSEd Maste   case ObjectFile::eTypeSharedLibrary:
283ac7ddfbfSEd Maste     break;
284ac7ddfbfSEd Maste   }
285ac7ddfbfSEd Maste 
286ac7ddfbfSEd Maste   // In order to get the abilities of this plug-in, we look at the list of
287ac7ddfbfSEd Maste   // N_OSO entries (object files) from the symbol table and make sure that
2884ba319b5SDimitry Andric   // these files exist and also contain valid DWARF. If we get any of that then
2894ba319b5SDimitry Andric   // we return the abilities of the first N_OSO's DWARF.
290ac7ddfbfSEd Maste 
291ac7ddfbfSEd Maste   Symtab *symtab = m_obj_file->GetSymtab();
292435933ddSDimitry Andric   if (symtab) {
293ac7ddfbfSEd Maste     Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
294ac7ddfbfSEd Maste 
295ac7ddfbfSEd Maste     std::vector<uint32_t> oso_indexes;
296ac7ddfbfSEd Maste     // When a mach-o symbol is encoded, the n_type field is encoded in bits
297ac7ddfbfSEd Maste     // 23:16, and the n_desc field is encoded in bits 15:0.
298ac7ddfbfSEd Maste     //
2994ba319b5SDimitry Andric     // To find all N_OSO entries that are part of the DWARF + debug map we find
3004ba319b5SDimitry Andric     // only object file symbols with the flags value as follows: bits 23:16 ==
3014ba319b5SDimitry Andric     // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object
3024ba319b5SDimitry Andric     // file)
303ac7ddfbfSEd Maste     const uint32_t k_oso_symbol_flags_value = 0x660001u;
304ac7ddfbfSEd Maste 
305435933ddSDimitry Andric     const uint32_t oso_index_count =
306435933ddSDimitry Andric         symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
307435933ddSDimitry Andric             eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
308ac7ddfbfSEd Maste 
309435933ddSDimitry Andric     if (oso_index_count > 0) {
310435933ddSDimitry Andric       symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes,
311435933ddSDimitry Andric                                           Symtab::eVisibilityAny,
312435933ddSDimitry Andric                                           m_func_indexes);
313435933ddSDimitry Andric       symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes,
314435933ddSDimitry Andric                                           Symtab::eVisibilityAny,
315435933ddSDimitry Andric                                           m_glob_indexes);
316ac7ddfbfSEd Maste 
317ac7ddfbfSEd Maste       symtab->SortSymbolIndexesByValue(m_func_indexes, true);
318ac7ddfbfSEd Maste       symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
319ac7ddfbfSEd Maste 
320435933ddSDimitry Andric       for (uint32_t sym_idx : m_func_indexes) {
321ac7ddfbfSEd Maste         const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
3221c3bbb01SEd Maste         lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
323ac7ddfbfSEd Maste         lldb::addr_t byte_size = symbol->GetByteSize();
324435933ddSDimitry Andric         DebugMap::Entry debug_map_entry(
325435933ddSDimitry Andric             file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
326ac7ddfbfSEd Maste         m_debug_map.Append(debug_map_entry);
327ac7ddfbfSEd Maste       }
328435933ddSDimitry Andric       for (uint32_t sym_idx : m_glob_indexes) {
329ac7ddfbfSEd Maste         const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
3301c3bbb01SEd Maste         lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
331ac7ddfbfSEd Maste         lldb::addr_t byte_size = symbol->GetByteSize();
332435933ddSDimitry Andric         DebugMap::Entry debug_map_entry(
333435933ddSDimitry Andric             file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
334ac7ddfbfSEd Maste         m_debug_map.Append(debug_map_entry);
335ac7ddfbfSEd Maste       }
336ac7ddfbfSEd Maste       m_debug_map.Sort();
337ac7ddfbfSEd Maste 
338ac7ddfbfSEd Maste       m_compile_unit_infos.resize(oso_index_count);
339ac7ddfbfSEd Maste 
340435933ddSDimitry Andric       for (uint32_t i = 0; i < oso_index_count; ++i) {
341ac7ddfbfSEd Maste         const uint32_t so_idx = oso_indexes[i] - 1;
342ac7ddfbfSEd Maste         const uint32_t oso_idx = oso_indexes[i];
343ac7ddfbfSEd Maste         const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
344ac7ddfbfSEd Maste         const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
345435933ddSDimitry Andric         if (so_symbol && oso_symbol &&
346ac7ddfbfSEd Maste             so_symbol->GetType() == eSymbolTypeSourceFile &&
347435933ddSDimitry Andric             oso_symbol->GetType() == eSymbolTypeObjectFile) {
348435933ddSDimitry Andric           m_compile_unit_infos[i].so_file.SetFile(
349*b5893f02SDimitry Andric               so_symbol->GetName().AsCString(), FileSpec::Style::native);
350ac7ddfbfSEd Maste           m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
351435933ddSDimitry Andric           m_compile_unit_infos[i].oso_mod_time =
352435933ddSDimitry Andric               llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0));
353ac7ddfbfSEd Maste           uint32_t sibling_idx = so_symbol->GetSiblingIndex();
354435933ddSDimitry Andric           // The sibling index can't be less that or equal to the current index
355435933ddSDimitry Andric           // "i"
356435933ddSDimitry Andric           if (sibling_idx == UINT32_MAX) {
357435933ddSDimitry Andric             m_obj_file->GetModule()->ReportError(
358435933ddSDimitry Andric                 "N_SO in symbol with UID %u has invalid sibling in debug map, "
359435933ddSDimitry Andric                 "please file a bug and attach the binary listed in this error",
360435933ddSDimitry Andric                 so_symbol->GetID());
361435933ddSDimitry Andric           } else {
362ac7ddfbfSEd Maste             const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
363ac7ddfbfSEd Maste             m_compile_unit_infos[i].first_symbol_index = so_idx;
364ac7ddfbfSEd Maste             m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
365ac7ddfbfSEd Maste             m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
366ac7ddfbfSEd Maste             m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
367ac7ddfbfSEd Maste 
368ac7ddfbfSEd Maste             if (log)
369435933ddSDimitry Andric               log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
370435933ddSDimitry Andric                           oso_symbol->GetName().GetCString());
371ac7ddfbfSEd Maste           }
372435933ddSDimitry Andric         } else {
373ac7ddfbfSEd Maste           if (oso_symbol == NULL)
374435933ddSDimitry Andric             m_obj_file->GetModule()->ReportError(
375435933ddSDimitry Andric                 "N_OSO symbol[%u] can't be found, please file a bug and attach "
376435933ddSDimitry Andric                 "the binary listed in this error",
377435933ddSDimitry Andric                 oso_idx);
378ac7ddfbfSEd Maste           else if (so_symbol == NULL)
379435933ddSDimitry Andric             m_obj_file->GetModule()->ReportError(
380435933ddSDimitry Andric                 "N_SO not found for N_OSO symbol[%u], please file a bug and "
381435933ddSDimitry Andric                 "attach the binary listed in this error",
382435933ddSDimitry Andric                 oso_idx);
383ac7ddfbfSEd Maste           else if (so_symbol->GetType() != eSymbolTypeSourceFile)
384435933ddSDimitry Andric             m_obj_file->GetModule()->ReportError(
385435933ddSDimitry Andric                 "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
386435933ddSDimitry Andric                 "please file a bug and attach the binary listed in this error",
387435933ddSDimitry Andric                 so_symbol->GetType(), oso_idx);
388ac7ddfbfSEd Maste           else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
389435933ddSDimitry Andric             m_obj_file->GetModule()->ReportError(
390435933ddSDimitry Andric                 "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
391435933ddSDimitry Andric                 "please file a bug and attach the binary listed in this error",
392435933ddSDimitry Andric                 oso_symbol->GetType(), oso_idx);
393ac7ddfbfSEd Maste         }
394ac7ddfbfSEd Maste       }
395ac7ddfbfSEd Maste     }
396ac7ddfbfSEd Maste   }
397ac7ddfbfSEd Maste }
398ac7ddfbfSEd Maste 
GetModuleByOSOIndex(uint32_t oso_idx)399435933ddSDimitry Andric Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
400ac7ddfbfSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
401ac7ddfbfSEd Maste   if (oso_idx < cu_count)
402ac7ddfbfSEd Maste     return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
403ac7ddfbfSEd Maste   return NULL;
404ac7ddfbfSEd Maste }
405ac7ddfbfSEd Maste 
GetModuleByCompUnitInfo(CompileUnitInfo * comp_unit_info)406435933ddSDimitry Andric Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
407435933ddSDimitry Andric     CompileUnitInfo *comp_unit_info) {
408435933ddSDimitry Andric   if (!comp_unit_info->oso_sp) {
4094ba319b5SDimitry Andric     auto pos = m_oso_map.find(
4104ba319b5SDimitry Andric         {comp_unit_info->oso_path, comp_unit_info->oso_mod_time});
411435933ddSDimitry Andric     if (pos != m_oso_map.end()) {
412ac7ddfbfSEd Maste       comp_unit_info->oso_sp = pos->second;
413435933ddSDimitry Andric     } else {
414ac7ddfbfSEd Maste       ObjectFile *obj_file = GetObjectFile();
415ac7ddfbfSEd Maste       comp_unit_info->oso_sp.reset(new OSOInfo());
4164ba319b5SDimitry Andric       m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] =
4174ba319b5SDimitry Andric           comp_unit_info->oso_sp;
418ac7ddfbfSEd Maste       const char *oso_path = comp_unit_info->oso_path.GetCString();
419*b5893f02SDimitry Andric       FileSpec oso_file(oso_path);
420ac7ddfbfSEd Maste       ConstString oso_object;
421*b5893f02SDimitry Andric       if (FileSystem::Instance().Exists(oso_file)) {
422*b5893f02SDimitry Andric         // The modification time returned by the FS can have a higher precision
423*b5893f02SDimitry Andric         // than the one from the CU.
424*b5893f02SDimitry Andric         auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
425*b5893f02SDimitry Andric             FileSystem::Instance().GetModificationTime(oso_file));
426435933ddSDimitry Andric         if (oso_mod_time != comp_unit_info->oso_mod_time) {
427435933ddSDimitry Andric           obj_file->GetModule()->ReportError(
428435933ddSDimitry Andric               "debug map object file '%s' has changed (actual time is "
429435933ddSDimitry Andric               "%s, debug map time is %s"
430435933ddSDimitry Andric               ") since this executable was linked, file will be ignored",
431435933ddSDimitry Andric               oso_file.GetPath().c_str(), llvm::to_string(oso_mod_time).c_str(),
432435933ddSDimitry Andric               llvm::to_string(comp_unit_info->oso_mod_time).c_str());
433ac7ddfbfSEd Maste           return NULL;
434ac7ddfbfSEd Maste         }
435ac7ddfbfSEd Maste 
436435933ddSDimitry Andric       } else {
437ac7ddfbfSEd Maste         const bool must_exist = true;
438ac7ddfbfSEd Maste 
439435933ddSDimitry Andric         if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file,
440435933ddSDimitry Andric                                                     oso_object, must_exist)) {
441ac7ddfbfSEd Maste           return NULL;
442ac7ddfbfSEd Maste         }
443ac7ddfbfSEd Maste       }
4444ba319b5SDimitry Andric       // Always create a new module for .o files. Why? Because we use the debug
4454ba319b5SDimitry Andric       // map, to add new sections to each .o file and even though a .o file
4464ba319b5SDimitry Andric       // might not have changed, the sections that get added to the .o file can
4474ba319b5SDimitry Andric       // change.
4480127ef0fSEd Maste       ArchSpec oso_arch;
4490127ef0fSEd Maste       // Only adopt the architecture from the module (not the vendor or OS)
4504ba319b5SDimitry Andric       // since .o files for "i386-apple-ios" will historically show up as "i386
4514ba319b5SDimitry Andric       // -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or
4524ba319b5SDimitry Andric       // LC_VERSION_MIN_IPHONEOS load command...
453435933ddSDimitry Andric       oso_arch.SetTriple(m_obj_file->GetModule()
454435933ddSDimitry Andric                              ->GetArchitecture()
455435933ddSDimitry Andric                              .GetTriple()
456435933ddSDimitry Andric                              .getArchName()
457435933ddSDimitry Andric                              .str()
458435933ddSDimitry Andric                              .c_str());
459435933ddSDimitry Andric       comp_unit_info->oso_sp->module_sp.reset(new DebugMapModule(
460435933ddSDimitry Andric           obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file,
461435933ddSDimitry Andric           oso_arch, oso_object ? &oso_object : NULL, 0,
462435933ddSDimitry Andric           oso_object ? comp_unit_info->oso_mod_time
463435933ddSDimitry Andric                      : llvm::sys::TimePoint<>()));
464ac7ddfbfSEd Maste     }
465ac7ddfbfSEd Maste   }
466ac7ddfbfSEd Maste   if (comp_unit_info->oso_sp)
467ac7ddfbfSEd Maste     return comp_unit_info->oso_sp->module_sp.get();
468ac7ddfbfSEd Maste   return NULL;
469ac7ddfbfSEd Maste }
470ac7ddfbfSEd Maste 
GetFileSpecForSO(uint32_t oso_idx,FileSpec & file_spec)471435933ddSDimitry Andric bool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx,
472435933ddSDimitry Andric                                                FileSpec &file_spec) {
473435933ddSDimitry Andric   if (oso_idx < m_compile_unit_infos.size()) {
474435933ddSDimitry Andric     if (m_compile_unit_infos[oso_idx].so_file) {
475ac7ddfbfSEd Maste       file_spec = m_compile_unit_infos[oso_idx].so_file;
476ac7ddfbfSEd Maste       return true;
477ac7ddfbfSEd Maste     }
478ac7ddfbfSEd Maste   }
479ac7ddfbfSEd Maste   return false;
480ac7ddfbfSEd Maste }
481ac7ddfbfSEd Maste 
GetObjectFileByOSOIndex(uint32_t oso_idx)482435933ddSDimitry Andric ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) {
483ac7ddfbfSEd Maste   Module *oso_module = GetModuleByOSOIndex(oso_idx);
484ac7ddfbfSEd Maste   if (oso_module)
485ac7ddfbfSEd Maste     return oso_module->GetObjectFile();
486ac7ddfbfSEd Maste   return NULL;
487ac7ddfbfSEd Maste }
488ac7ddfbfSEd Maste 
489ac7ddfbfSEd Maste SymbolFileDWARF *
GetSymbolFile(const SymbolContext & sc)490435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) {
491*b5893f02SDimitry Andric   return GetSymbolFile(*sc.comp_unit);
492*b5893f02SDimitry Andric }
493*b5893f02SDimitry Andric 
494*b5893f02SDimitry Andric SymbolFileDWARF *
GetSymbolFile(const CompileUnit & comp_unit)495*b5893f02SDimitry Andric SymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) {
496*b5893f02SDimitry Andric   CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit);
497ac7ddfbfSEd Maste   if (comp_unit_info)
498ac7ddfbfSEd Maste     return GetSymbolFileByCompUnitInfo(comp_unit_info);
499ac7ddfbfSEd Maste   return NULL;
500ac7ddfbfSEd Maste }
501ac7ddfbfSEd Maste 
GetObjectFileByCompUnitInfo(CompileUnitInfo * comp_unit_info)502435933ddSDimitry Andric ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo(
503435933ddSDimitry Andric     CompileUnitInfo *comp_unit_info) {
504ac7ddfbfSEd Maste   Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
505ac7ddfbfSEd Maste   if (oso_module)
506ac7ddfbfSEd Maste     return oso_module->GetObjectFile();
507ac7ddfbfSEd Maste   return NULL;
508ac7ddfbfSEd Maste }
509ac7ddfbfSEd Maste 
GetCompUnitInfoIndex(const CompileUnitInfo * comp_unit_info)510435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex(
511435933ddSDimitry Andric     const CompileUnitInfo *comp_unit_info) {
512435933ddSDimitry Andric   if (!m_compile_unit_infos.empty()) {
513ac7ddfbfSEd Maste     const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
514ac7ddfbfSEd Maste     const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
515435933ddSDimitry Andric     if (first_comp_unit_info <= comp_unit_info &&
516435933ddSDimitry Andric         comp_unit_info <= last_comp_unit_info)
517ac7ddfbfSEd Maste       return comp_unit_info - first_comp_unit_info;
518ac7ddfbfSEd Maste   }
519ac7ddfbfSEd Maste   return UINT32_MAX;
520ac7ddfbfSEd Maste }
521ac7ddfbfSEd Maste 
522ac7ddfbfSEd Maste SymbolFileDWARF *
GetSymbolFileByOSOIndex(uint32_t oso_idx)523435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) {
524*b5893f02SDimitry Andric   unsigned size = m_compile_unit_infos.size();
525*b5893f02SDimitry Andric   if (oso_idx < size)
526ac7ddfbfSEd Maste     return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
527ac7ddfbfSEd Maste   return NULL;
528ac7ddfbfSEd Maste }
529ac7ddfbfSEd Maste 
530ac7ddfbfSEd Maste SymbolFileDWARF *
GetSymbolFileAsSymbolFileDWARF(SymbolFile * sym_file)531435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
532435933ddSDimitry Andric   if (sym_file &&
533435933ddSDimitry Andric       sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
534ac7ddfbfSEd Maste     return (SymbolFileDWARF *)sym_file;
535ac7ddfbfSEd Maste   return NULL;
536ac7ddfbfSEd Maste }
537ac7ddfbfSEd Maste 
GetSymbolFileByCompUnitInfo(CompileUnitInfo * comp_unit_info)538435933ddSDimitry Andric SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
539435933ddSDimitry Andric     CompileUnitInfo *comp_unit_info) {
540ac7ddfbfSEd Maste   Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
541435933ddSDimitry Andric   if (oso_module) {
542ac7ddfbfSEd Maste     SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
543ac7ddfbfSEd Maste     if (sym_vendor)
544ac7ddfbfSEd Maste       return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile());
545ac7ddfbfSEd Maste   }
546ac7ddfbfSEd Maste   return NULL;
547ac7ddfbfSEd Maste }
548ac7ddfbfSEd Maste 
CalculateAbilities()549435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
550ac7ddfbfSEd Maste   // In order to get the abilities of this plug-in, we look at the list of
551ac7ddfbfSEd Maste   // N_OSO entries (object files) from the symbol table and make sure that
5524ba319b5SDimitry Andric   // these files exist and also contain valid DWARF. If we get any of that then
5534ba319b5SDimitry Andric   // we return the abilities of the first N_OSO's DWARF.
554ac7ddfbfSEd Maste 
555ac7ddfbfSEd Maste   const uint32_t oso_index_count = GetNumCompileUnits();
556435933ddSDimitry Andric   if (oso_index_count > 0) {
557ac7ddfbfSEd Maste     InitOSO();
558435933ddSDimitry Andric     if (!m_compile_unit_infos.empty()) {
559435933ddSDimitry Andric       return SymbolFile::CompileUnits | SymbolFile::Functions |
560435933ddSDimitry Andric              SymbolFile::Blocks | SymbolFile::GlobalVariables |
561435933ddSDimitry Andric              SymbolFile::LocalVariables | SymbolFile::VariableTypes |
562ac7ddfbfSEd Maste              SymbolFile::LineTables;
563ac7ddfbfSEd Maste     }
564ac7ddfbfSEd Maste   }
565ac7ddfbfSEd Maste   return 0;
566ac7ddfbfSEd Maste }
567ac7ddfbfSEd Maste 
GetNumCompileUnits()568435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
569ac7ddfbfSEd Maste   InitOSO();
570ac7ddfbfSEd Maste   return m_compile_unit_infos.size();
571ac7ddfbfSEd Maste }
572ac7ddfbfSEd Maste 
ParseCompileUnitAtIndex(uint32_t cu_idx)573435933ddSDimitry Andric CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
574ac7ddfbfSEd Maste   CompUnitSP comp_unit_sp;
575ac7ddfbfSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
576ac7ddfbfSEd Maste 
577435933ddSDimitry Andric   if (cu_idx < cu_count) {
578ac7ddfbfSEd Maste     Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
579435933ddSDimitry Andric     if (oso_module) {
580ac7ddfbfSEd Maste       FileSpec so_file_spec;
581435933ddSDimitry Andric       if (GetFileSpecForSO(cu_idx, so_file_spec)) {
5824ba319b5SDimitry Andric         // User zero as the ID to match the compile unit at offset zero in each
5834ba319b5SDimitry Andric         // .o file since each .o file can only have one compile unit for now.
584ac7ddfbfSEd Maste         lldb::user_id_t cu_id = 0;
585435933ddSDimitry Andric         m_compile_unit_infos[cu_idx].compile_unit_sp.reset(
586435933ddSDimitry Andric             new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id,
587435933ddSDimitry Andric                             eLanguageTypeUnknown, eLazyBoolCalculate));
588ac7ddfbfSEd Maste 
589435933ddSDimitry Andric         if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
590ac7ddfbfSEd Maste           // Let our symbol vendor know about this compile unit
591435933ddSDimitry Andric           m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
592435933ddSDimitry Andric               cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
593ac7ddfbfSEd Maste         }
594ac7ddfbfSEd Maste       }
595ac7ddfbfSEd Maste     }
596ac7ddfbfSEd Maste     comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
597ac7ddfbfSEd Maste   }
598ac7ddfbfSEd Maste 
599ac7ddfbfSEd Maste   return comp_unit_sp;
600ac7ddfbfSEd Maste }
601ac7ddfbfSEd Maste 
602ac7ddfbfSEd Maste SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompUnitInfo(const SymbolContext & sc)603435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) {
604*b5893f02SDimitry Andric   return GetCompUnitInfo(*sc.comp_unit);
605*b5893f02SDimitry Andric }
606*b5893f02SDimitry Andric 
607*b5893f02SDimitry Andric SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompUnitInfo(const CompileUnit & comp_unit)608*b5893f02SDimitry Andric SymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) {
609ac7ddfbfSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
610435933ddSDimitry Andric   for (uint32_t i = 0; i < cu_count; ++i) {
611*b5893f02SDimitry Andric     if (comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
612ac7ddfbfSEd Maste       return &m_compile_unit_infos[i];
613ac7ddfbfSEd Maste   }
614ac7ddfbfSEd Maste   return NULL;
615ac7ddfbfSEd Maste }
616ac7ddfbfSEd Maste 
GetCompUnitInfosForModule(const lldb_private::Module * module,std::vector<CompileUnitInfo * > & cu_infos)617435933ddSDimitry Andric size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
618435933ddSDimitry Andric     const lldb_private::Module *module,
619435933ddSDimitry Andric     std::vector<CompileUnitInfo *> &cu_infos) {
620ac7ddfbfSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
621435933ddSDimitry Andric   for (uint32_t i = 0; i < cu_count; ++i) {
622ac7ddfbfSEd Maste     if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i]))
623ac7ddfbfSEd Maste       cu_infos.push_back(&m_compile_unit_infos[i]);
624ac7ddfbfSEd Maste   }
625ac7ddfbfSEd Maste   return cu_infos.size();
626ac7ddfbfSEd Maste }
627ac7ddfbfSEd Maste 
628ac7ddfbfSEd Maste lldb::LanguageType
ParseLanguage(CompileUnit & comp_unit)629*b5893f02SDimitry Andric SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
630*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
631ac7ddfbfSEd Maste   if (oso_dwarf)
632*b5893f02SDimitry Andric     return oso_dwarf->ParseLanguage(comp_unit);
633ac7ddfbfSEd Maste   return eLanguageTypeUnknown;
634ac7ddfbfSEd Maste }
635ac7ddfbfSEd Maste 
ParseFunctions(CompileUnit & comp_unit)636*b5893f02SDimitry Andric size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
637*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
638ac7ddfbfSEd Maste   if (oso_dwarf)
639*b5893f02SDimitry Andric     return oso_dwarf->ParseFunctions(comp_unit);
640ac7ddfbfSEd Maste   return 0;
641ac7ddfbfSEd Maste }
642ac7ddfbfSEd Maste 
ParseLineTable(CompileUnit & comp_unit)643*b5893f02SDimitry Andric bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
644*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
645ac7ddfbfSEd Maste   if (oso_dwarf)
646*b5893f02SDimitry Andric     return oso_dwarf->ParseLineTable(comp_unit);
647ac7ddfbfSEd Maste   return false;
648ac7ddfbfSEd Maste }
649ac7ddfbfSEd Maste 
ParseDebugMacros(CompileUnit & comp_unit)650*b5893f02SDimitry Andric bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) {
651*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
6529f2f44ceSEd Maste   if (oso_dwarf)
653*b5893f02SDimitry Andric     return oso_dwarf->ParseDebugMacros(comp_unit);
6549f2f44ceSEd Maste   return false;
6559f2f44ceSEd Maste }
6569f2f44ceSEd Maste 
ParseSupportFiles(CompileUnit & comp_unit,FileSpecList & support_files)657*b5893f02SDimitry Andric bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
658*b5893f02SDimitry Andric                                                 FileSpecList &support_files) {
659*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
660ac7ddfbfSEd Maste   if (oso_dwarf)
661*b5893f02SDimitry Andric     return oso_dwarf->ParseSupportFiles(comp_unit, support_files);
662ac7ddfbfSEd Maste   return false;
663ac7ddfbfSEd Maste }
664ac7ddfbfSEd Maste 
ParseIsOptimized(CompileUnit & comp_unit)665*b5893f02SDimitry Andric bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
666*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
6674bb0738eSEd Maste   if (oso_dwarf)
668*b5893f02SDimitry Andric     return oso_dwarf->ParseIsOptimized(comp_unit);
6694bb0738eSEd Maste   return false;
6704bb0738eSEd Maste }
6714bb0738eSEd Maste 
ParseImportedModules(const SymbolContext & sc,std::vector<ConstString> & imported_modules)672435933ddSDimitry Andric bool SymbolFileDWARFDebugMap::ParseImportedModules(
673435933ddSDimitry Andric     const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
6741c3bbb01SEd Maste   SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
6751c3bbb01SEd Maste   if (oso_dwarf)
6761c3bbb01SEd Maste     return oso_dwarf->ParseImportedModules(sc, imported_modules);
6771c3bbb01SEd Maste   return false;
6781c3bbb01SEd Maste }
679ac7ddfbfSEd Maste 
ParseBlocksRecursive(Function & func)680*b5893f02SDimitry Andric size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
681*b5893f02SDimitry Andric   CompileUnit *comp_unit = func.GetCompileUnit();
682*b5893f02SDimitry Andric   if (!comp_unit)
683*b5893f02SDimitry Andric     return 0;
684*b5893f02SDimitry Andric 
685*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(*comp_unit);
686ac7ddfbfSEd Maste   if (oso_dwarf)
687*b5893f02SDimitry Andric     return oso_dwarf->ParseBlocksRecursive(func);
688ac7ddfbfSEd Maste   return 0;
689ac7ddfbfSEd Maste }
690ac7ddfbfSEd Maste 
ParseTypes(CompileUnit & comp_unit)691*b5893f02SDimitry Andric size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
692*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
693ac7ddfbfSEd Maste   if (oso_dwarf)
694*b5893f02SDimitry Andric     return oso_dwarf->ParseTypes(comp_unit);
695ac7ddfbfSEd Maste   return 0;
696ac7ddfbfSEd Maste }
697ac7ddfbfSEd Maste 
698ac7ddfbfSEd Maste size_t
ParseVariablesForContext(const SymbolContext & sc)699435933ddSDimitry Andric SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
700ac7ddfbfSEd Maste   SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
701ac7ddfbfSEd Maste   if (oso_dwarf)
702ac7ddfbfSEd Maste     return oso_dwarf->ParseVariablesForContext(sc);
703ac7ddfbfSEd Maste   return 0;
704ac7ddfbfSEd Maste }
705ac7ddfbfSEd Maste 
ResolveTypeUID(lldb::user_id_t type_uid)706435933ddSDimitry Andric Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
707ac7ddfbfSEd Maste   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
708ac7ddfbfSEd Maste   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
709ac7ddfbfSEd Maste   if (oso_dwarf)
710ac7ddfbfSEd Maste     return oso_dwarf->ResolveTypeUID(type_uid);
711ac7ddfbfSEd Maste   return NULL;
712ac7ddfbfSEd Maste }
713ac7ddfbfSEd Maste 
714*b5893f02SDimitry Andric llvm::Optional<SymbolFile::ArrayInfo>
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)715*b5893f02SDimitry Andric SymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID(
716*b5893f02SDimitry Andric     lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
717*b5893f02SDimitry Andric   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
718*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
719*b5893f02SDimitry Andric   if (oso_dwarf)
720*b5893f02SDimitry Andric     return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx);
721*b5893f02SDimitry Andric   return llvm::None;
722*b5893f02SDimitry Andric }
723*b5893f02SDimitry Andric 
CompleteType(CompilerType & compiler_type)724435933ddSDimitry Andric bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
7259f2f44ceSEd Maste   bool success = false;
726435933ddSDimitry Andric   if (compiler_type) {
7279f2f44ceSEd Maste     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
728435933ddSDimitry Andric       if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) {
7299f2f44ceSEd Maste         oso_dwarf->CompleteType(compiler_type);
7309f2f44ceSEd Maste         success = true;
7319f2f44ceSEd Maste         return true;
7329f2f44ceSEd Maste       }
733ac7ddfbfSEd Maste       return false;
7349f2f44ceSEd Maste     });
7359f2f44ceSEd Maste   }
7369f2f44ceSEd Maste   return success;
737ac7ddfbfSEd Maste }
738ac7ddfbfSEd Maste 
739*b5893f02SDimitry Andric uint32_t
ResolveSymbolContext(const Address & exe_so_addr,SymbolContextItem resolve_scope,SymbolContext & sc)740*b5893f02SDimitry Andric SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
741*b5893f02SDimitry Andric                                               SymbolContextItem resolve_scope,
742*b5893f02SDimitry Andric                                               SymbolContext &sc) {
743ac7ddfbfSEd Maste   uint32_t resolved_flags = 0;
744ac7ddfbfSEd Maste   Symtab *symtab = m_obj_file->GetSymtab();
745435933ddSDimitry Andric   if (symtab) {
746ac7ddfbfSEd Maste     const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
747ac7ddfbfSEd Maste 
748435933ddSDimitry Andric     const DebugMap::Entry *debug_map_entry =
749435933ddSDimitry Andric         m_debug_map.FindEntryThatContains(exe_file_addr);
750435933ddSDimitry Andric     if (debug_map_entry) {
751ac7ddfbfSEd Maste 
752435933ddSDimitry Andric       sc.symbol =
753435933ddSDimitry Andric           symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
754ac7ddfbfSEd Maste 
755435933ddSDimitry Andric       if (sc.symbol != NULL) {
756ac7ddfbfSEd Maste         resolved_flags |= eSymbolContextSymbol;
757ac7ddfbfSEd Maste 
758ac7ddfbfSEd Maste         uint32_t oso_idx = 0;
759435933ddSDimitry Andric         CompileUnitInfo *comp_unit_info =
760435933ddSDimitry Andric             GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx);
761435933ddSDimitry Andric         if (comp_unit_info) {
762ac7ddfbfSEd Maste           comp_unit_info->GetFileRangeMap(this);
763ac7ddfbfSEd Maste           Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
764435933ddSDimitry Andric           if (oso_module) {
765435933ddSDimitry Andric             lldb::addr_t oso_file_addr =
766435933ddSDimitry Andric                 exe_file_addr - debug_map_entry->GetRangeBase() +
767435933ddSDimitry Andric                 debug_map_entry->data.GetOSOFileAddress();
768ac7ddfbfSEd Maste             Address oso_so_addr;
769435933ddSDimitry Andric             if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) {
770435933ddSDimitry Andric               resolved_flags |=
771435933ddSDimitry Andric                   oso_module->GetSymbolVendor()->ResolveSymbolContext(
772435933ddSDimitry Andric                       oso_so_addr, resolve_scope, sc);
773ac7ddfbfSEd Maste             }
774ac7ddfbfSEd Maste           }
775ac7ddfbfSEd Maste         }
776ac7ddfbfSEd Maste       }
777ac7ddfbfSEd Maste     }
778ac7ddfbfSEd Maste   }
779ac7ddfbfSEd Maste   return resolved_flags;
780ac7ddfbfSEd Maste }
781ac7ddfbfSEd Maste 
ResolveSymbolContext(const FileSpec & file_spec,uint32_t line,bool check_inlines,SymbolContextItem resolve_scope,SymbolContextList & sc_list)782435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
783435933ddSDimitry Andric     const FileSpec &file_spec, uint32_t line, bool check_inlines,
784*b5893f02SDimitry Andric     SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
785ac7ddfbfSEd Maste   const uint32_t initial = sc_list.GetSize();
786ac7ddfbfSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
787ac7ddfbfSEd Maste 
788435933ddSDimitry Andric   for (uint32_t i = 0; i < cu_count; ++i) {
7894ba319b5SDimitry Andric     // If we are checking for inlines, then we need to look through all compile
7904ba319b5SDimitry Andric     // units no matter if "file_spec" matches.
791ac7ddfbfSEd Maste     bool resolve = check_inlines;
792ac7ddfbfSEd Maste 
793435933ddSDimitry Andric     if (!resolve) {
794ac7ddfbfSEd Maste       FileSpec so_file_spec;
795435933ddSDimitry Andric       if (GetFileSpecForSO(i, so_file_spec)) {
796435933ddSDimitry Andric         // Match the full path if the incoming file_spec has a directory (not
797435933ddSDimitry Andric         // just a basename)
79835617911SEd Maste         const bool full_match = (bool)file_spec.GetDirectory();
799ac7ddfbfSEd Maste         resolve = FileSpec::Equal(file_spec, so_file_spec, full_match);
800ac7ddfbfSEd Maste       }
801ac7ddfbfSEd Maste     }
802435933ddSDimitry Andric     if (resolve) {
803ac7ddfbfSEd Maste       SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i);
804ac7ddfbfSEd Maste       if (oso_dwarf)
805435933ddSDimitry Andric         oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines,
806435933ddSDimitry Andric                                         resolve_scope, sc_list);
807ac7ddfbfSEd Maste     }
808ac7ddfbfSEd Maste   }
809ac7ddfbfSEd Maste   return sc_list.GetSize() - initial;
810ac7ddfbfSEd Maste }
811ac7ddfbfSEd Maste 
PrivateFindGlobalVariables(const ConstString & name,const CompilerDeclContext * parent_decl_ctx,const std::vector<uint32_t> & indexes,uint32_t max_matches,VariableList & variables)812435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
813435933ddSDimitry Andric     const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
814435933ddSDimitry Andric     const std::vector<uint32_t>
815435933ddSDimitry Andric         &indexes, // Indexes into the symbol table that match "name"
816*b5893f02SDimitry Andric     uint32_t max_matches, VariableList &variables) {
817ac7ddfbfSEd Maste   const uint32_t original_size = variables.GetSize();
818ac7ddfbfSEd Maste   const size_t match_count = indexes.size();
819435933ddSDimitry Andric   for (size_t i = 0; i < match_count; ++i) {
820ac7ddfbfSEd Maste     uint32_t oso_idx;
821435933ddSDimitry Andric     CompileUnitInfo *comp_unit_info =
822435933ddSDimitry Andric         GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx);
823435933ddSDimitry Andric     if (comp_unit_info) {
824ac7ddfbfSEd Maste       SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
825435933ddSDimitry Andric       if (oso_dwarf) {
8264ba319b5SDimitry Andric         if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
8274ba319b5SDimitry Andric                                            variables))
828ac7ddfbfSEd Maste           if (variables.GetSize() > max_matches)
829ac7ddfbfSEd Maste             break;
830ac7ddfbfSEd Maste       }
831ac7ddfbfSEd Maste     }
832ac7ddfbfSEd Maste   }
833ac7ddfbfSEd Maste   return variables.GetSize() - original_size;
834ac7ddfbfSEd Maste }
835ac7ddfbfSEd Maste 
FindGlobalVariables(const ConstString & name,const CompilerDeclContext * parent_decl_ctx,uint32_t max_matches,VariableList & variables)836435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
837435933ddSDimitry Andric     const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
8384ba319b5SDimitry Andric     uint32_t max_matches, VariableList &variables) {
839ac7ddfbfSEd Maste 
8404ba319b5SDimitry Andric   // Remember how many variables are in the list before we search.
841ac7ddfbfSEd Maste   const uint32_t original_size = variables.GetSize();
842ac7ddfbfSEd Maste 
843ac7ddfbfSEd Maste   uint32_t total_matches = 0;
8441c3bbb01SEd Maste 
8451c3bbb01SEd Maste   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
846435933ddSDimitry Andric     const uint32_t oso_matches = oso_dwarf->FindGlobalVariables(
8474ba319b5SDimitry Andric         name, parent_decl_ctx, max_matches, variables);
848435933ddSDimitry Andric     if (oso_matches > 0) {
849ac7ddfbfSEd Maste       total_matches += oso_matches;
850ac7ddfbfSEd Maste 
851ac7ddfbfSEd Maste       // Are we getting all matches?
852ac7ddfbfSEd Maste       if (max_matches == UINT32_MAX)
8531c3bbb01SEd Maste         return false; // Yep, continue getting everything
854ac7ddfbfSEd Maste 
855ac7ddfbfSEd Maste       // If we have found enough matches, lets get out
856ac7ddfbfSEd Maste       if (max_matches >= total_matches)
8571c3bbb01SEd Maste         return true;
858ac7ddfbfSEd Maste 
8594ba319b5SDimitry Andric       // Update the max matches for any subsequent calls to find globals in any
8604ba319b5SDimitry Andric       // other object files with DWARF
861ac7ddfbfSEd Maste       max_matches -= oso_matches;
862ac7ddfbfSEd Maste     }
8631c3bbb01SEd Maste 
8641c3bbb01SEd Maste     return false;
8651c3bbb01SEd Maste   });
8661c3bbb01SEd Maste 
867ac7ddfbfSEd Maste   // Return the number of variable that were appended to the list
868ac7ddfbfSEd Maste   return variables.GetSize() - original_size;
869ac7ddfbfSEd Maste }
870ac7ddfbfSEd Maste 
871ac7ddfbfSEd Maste uint32_t
FindGlobalVariables(const RegularExpression & regex,uint32_t max_matches,VariableList & variables)872435933ddSDimitry Andric SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
8734ba319b5SDimitry Andric                                              uint32_t max_matches,
874435933ddSDimitry Andric                                              VariableList &variables) {
8754ba319b5SDimitry Andric   // Remember how many variables are in the list before we search.
876ac7ddfbfSEd Maste   const uint32_t original_size = variables.GetSize();
877ac7ddfbfSEd Maste 
878ac7ddfbfSEd Maste   uint32_t total_matches = 0;
8791c3bbb01SEd Maste   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
880435933ddSDimitry Andric     const uint32_t oso_matches =
8814ba319b5SDimitry Andric         oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
882435933ddSDimitry Andric     if (oso_matches > 0) {
883ac7ddfbfSEd Maste       total_matches += oso_matches;
884ac7ddfbfSEd Maste 
885ac7ddfbfSEd Maste       // Are we getting all matches?
886ac7ddfbfSEd Maste       if (max_matches == UINT32_MAX)
8871c3bbb01SEd Maste         return false; // Yep, continue getting everything
888ac7ddfbfSEd Maste 
889ac7ddfbfSEd Maste       // If we have found enough matches, lets get out
890ac7ddfbfSEd Maste       if (max_matches >= total_matches)
8911c3bbb01SEd Maste         return true;
892ac7ddfbfSEd Maste 
8934ba319b5SDimitry Andric       // Update the max matches for any subsequent calls to find globals in any
8944ba319b5SDimitry Andric       // other object files with DWARF
895ac7ddfbfSEd Maste       max_matches -= oso_matches;
896ac7ddfbfSEd Maste     }
8971c3bbb01SEd Maste 
8981c3bbb01SEd Maste     return false;
8991c3bbb01SEd Maste   });
9001c3bbb01SEd Maste 
901ac7ddfbfSEd Maste   // Return the number of variable that were appended to the list
902ac7ddfbfSEd Maste   return variables.GetSize() - original_size;
903ac7ddfbfSEd Maste }
904ac7ddfbfSEd Maste 
SymbolContainsSymbolWithIndex(uint32_t * symbol_idx_ptr,const CompileUnitInfo * comp_unit_info)905435933ddSDimitry Andric int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
906435933ddSDimitry Andric     uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
907ac7ddfbfSEd Maste   const uint32_t symbol_idx = *symbol_idx_ptr;
908ac7ddfbfSEd Maste 
909ac7ddfbfSEd Maste   if (symbol_idx < comp_unit_info->first_symbol_index)
910ac7ddfbfSEd Maste     return -1;
911ac7ddfbfSEd Maste 
912ac7ddfbfSEd Maste   if (symbol_idx <= comp_unit_info->last_symbol_index)
913ac7ddfbfSEd Maste     return 0;
914ac7ddfbfSEd Maste 
915ac7ddfbfSEd Maste   return 1;
916ac7ddfbfSEd Maste }
917ac7ddfbfSEd Maste 
SymbolContainsSymbolWithID(user_id_t * symbol_idx_ptr,const CompileUnitInfo * comp_unit_info)918435933ddSDimitry Andric int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID(
919435933ddSDimitry Andric     user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
920ac7ddfbfSEd Maste   const user_id_t symbol_id = *symbol_idx_ptr;
921ac7ddfbfSEd Maste 
922ac7ddfbfSEd Maste   if (symbol_id < comp_unit_info->first_symbol_id)
923ac7ddfbfSEd Maste     return -1;
924ac7ddfbfSEd Maste 
925ac7ddfbfSEd Maste   if (symbol_id <= comp_unit_info->last_symbol_id)
926ac7ddfbfSEd Maste     return 0;
927ac7ddfbfSEd Maste 
928ac7ddfbfSEd Maste   return 1;
929ac7ddfbfSEd Maste }
930ac7ddfbfSEd Maste 
931ac7ddfbfSEd Maste SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompileUnitInfoForSymbolWithIndex(uint32_t symbol_idx,uint32_t * oso_idx_ptr)932435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex(
933435933ddSDimitry Andric     uint32_t symbol_idx, uint32_t *oso_idx_ptr) {
934ac7ddfbfSEd Maste   const uint32_t oso_index_count = m_compile_unit_infos.size();
935ac7ddfbfSEd Maste   CompileUnitInfo *comp_unit_info = NULL;
936435933ddSDimitry Andric   if (oso_index_count) {
937435933ddSDimitry Andric     comp_unit_info = (CompileUnitInfo *)bsearch(
938435933ddSDimitry Andric         &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
939ac7ddfbfSEd Maste         sizeof(CompileUnitInfo),
940ac7ddfbfSEd Maste         (ComparisonFunction)SymbolContainsSymbolWithIndex);
941ac7ddfbfSEd Maste   }
942ac7ddfbfSEd Maste 
943435933ddSDimitry Andric   if (oso_idx_ptr) {
944ac7ddfbfSEd Maste     if (comp_unit_info != NULL)
945ac7ddfbfSEd Maste       *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
946ac7ddfbfSEd Maste     else
947ac7ddfbfSEd Maste       *oso_idx_ptr = UINT32_MAX;
948ac7ddfbfSEd Maste   }
949ac7ddfbfSEd Maste   return comp_unit_info;
950ac7ddfbfSEd Maste }
951ac7ddfbfSEd Maste 
952ac7ddfbfSEd Maste SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompileUnitInfoForSymbolWithID(user_id_t symbol_id,uint32_t * oso_idx_ptr)953435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
954435933ddSDimitry Andric     user_id_t symbol_id, uint32_t *oso_idx_ptr) {
955ac7ddfbfSEd Maste   const uint32_t oso_index_count = m_compile_unit_infos.size();
956ac7ddfbfSEd Maste   CompileUnitInfo *comp_unit_info = NULL;
957435933ddSDimitry Andric   if (oso_index_count) {
958435933ddSDimitry Andric     comp_unit_info = (CompileUnitInfo *)::bsearch(
959435933ddSDimitry Andric         &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
960ac7ddfbfSEd Maste         sizeof(CompileUnitInfo),
961ac7ddfbfSEd Maste         (ComparisonFunction)SymbolContainsSymbolWithID);
962ac7ddfbfSEd Maste   }
963ac7ddfbfSEd Maste 
964435933ddSDimitry Andric   if (oso_idx_ptr) {
965ac7ddfbfSEd Maste     if (comp_unit_info != NULL)
966ac7ddfbfSEd Maste       *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
967ac7ddfbfSEd Maste     else
968ac7ddfbfSEd Maste       *oso_idx_ptr = UINT32_MAX;
969ac7ddfbfSEd Maste   }
970ac7ddfbfSEd Maste   return comp_unit_info;
971ac7ddfbfSEd Maste }
972ac7ddfbfSEd Maste 
RemoveFunctionsWithModuleNotEqualTo(const ModuleSP & module_sp,SymbolContextList & sc_list,uint32_t start_idx)973435933ddSDimitry Andric static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
974435933ddSDimitry Andric                                                 SymbolContextList &sc_list,
975435933ddSDimitry Andric                                                 uint32_t start_idx) {
9764ba319b5SDimitry Andric   // We found functions in .o files. Not all functions in the .o files will
9774ba319b5SDimitry Andric   // have made it into the final output file. The ones that did make it into
9784ba319b5SDimitry Andric   // the final output file will have a section whose module matches the module
9794ba319b5SDimitry Andric   // from the ObjectFile for this SymbolFile. When the modules don't match,
9804ba319b5SDimitry Andric   // then we have something that was in a .o file, but doesn't map to anything
9814ba319b5SDimitry Andric   // in the final executable.
982ac7ddfbfSEd Maste   uint32_t i = start_idx;
983435933ddSDimitry Andric   while (i < sc_list.GetSize()) {
984ac7ddfbfSEd Maste     SymbolContext sc;
985ac7ddfbfSEd Maste     sc_list.GetContextAtIndex(i, sc);
986435933ddSDimitry Andric     if (sc.function) {
987435933ddSDimitry Andric       const SectionSP section_sp(
988435933ddSDimitry Andric           sc.function->GetAddressRange().GetBaseAddress().GetSection());
989435933ddSDimitry Andric       if (section_sp->GetModule() != module_sp) {
990ac7ddfbfSEd Maste         sc_list.RemoveContextAtIndex(i);
991ac7ddfbfSEd Maste         continue;
992ac7ddfbfSEd Maste       }
993ac7ddfbfSEd Maste     }
994ac7ddfbfSEd Maste     ++i;
995ac7ddfbfSEd Maste   }
996ac7ddfbfSEd Maste }
997ac7ddfbfSEd Maste 
FindFunctions(const ConstString & name,const CompilerDeclContext * parent_decl_ctx,FunctionNameType name_type_mask,bool include_inlines,bool append,SymbolContextList & sc_list)998435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::FindFunctions(
999435933ddSDimitry Andric     const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
1000*b5893f02SDimitry Andric     FunctionNameType name_type_mask, bool include_inlines, bool append,
1001435933ddSDimitry Andric     SymbolContextList &sc_list) {
10025517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
10035517e702SDimitry Andric   Timer scoped_timer(func_cat,
1004ac7ddfbfSEd Maste                      "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1005ac7ddfbfSEd Maste                      name.GetCString());
1006ac7ddfbfSEd Maste 
1007ac7ddfbfSEd Maste   uint32_t initial_size = 0;
1008ac7ddfbfSEd Maste   if (append)
1009ac7ddfbfSEd Maste     initial_size = sc_list.GetSize();
1010ac7ddfbfSEd Maste   else
1011ac7ddfbfSEd Maste     sc_list.Clear();
1012ac7ddfbfSEd Maste 
10131c3bbb01SEd Maste   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1014ac7ddfbfSEd Maste     uint32_t sc_idx = sc_list.GetSize();
1015435933ddSDimitry Andric     if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
1016435933ddSDimitry Andric                                  include_inlines, true, sc_list)) {
1017435933ddSDimitry Andric       RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
1018435933ddSDimitry Andric                                           sc_idx);
1019ac7ddfbfSEd Maste     }
10201c3bbb01SEd Maste     return false;
10211c3bbb01SEd Maste   });
1022ac7ddfbfSEd Maste 
1023ac7ddfbfSEd Maste   return sc_list.GetSize() - initial_size;
1024ac7ddfbfSEd Maste }
1025ac7ddfbfSEd Maste 
FindFunctions(const RegularExpression & regex,bool include_inlines,bool append,SymbolContextList & sc_list)1026435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
1027435933ddSDimitry Andric                                                 bool include_inlines,
1028435933ddSDimitry Andric                                                 bool append,
1029435933ddSDimitry Andric                                                 SymbolContextList &sc_list) {
10305517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
10315517e702SDimitry Andric   Timer scoped_timer(func_cat,
1032ac7ddfbfSEd Maste                      "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1033435933ddSDimitry Andric                      regex.GetText().str().c_str());
1034ac7ddfbfSEd Maste 
1035ac7ddfbfSEd Maste   uint32_t initial_size = 0;
1036ac7ddfbfSEd Maste   if (append)
1037ac7ddfbfSEd Maste     initial_size = sc_list.GetSize();
1038ac7ddfbfSEd Maste   else
1039ac7ddfbfSEd Maste     sc_list.Clear();
1040ac7ddfbfSEd Maste 
10411c3bbb01SEd Maste   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1042ac7ddfbfSEd Maste     uint32_t sc_idx = sc_list.GetSize();
1043ac7ddfbfSEd Maste 
1044435933ddSDimitry Andric     if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) {
1045435933ddSDimitry Andric       RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
1046435933ddSDimitry Andric                                           sc_idx);
1047ac7ddfbfSEd Maste     }
10481c3bbb01SEd Maste     return false;
10491c3bbb01SEd Maste   });
1050ac7ddfbfSEd Maste 
1051ac7ddfbfSEd Maste   return sc_list.GetSize() - initial_size;
1052ac7ddfbfSEd Maste }
1053ac7ddfbfSEd Maste 
GetTypes(SymbolContextScope * sc_scope,lldb::TypeClass type_mask,TypeList & type_list)1054435933ddSDimitry Andric size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
1055*b5893f02SDimitry Andric                                          lldb::TypeClass type_mask,
1056435933ddSDimitry Andric                                          TypeList &type_list) {
10575517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
10585517e702SDimitry Andric   Timer scoped_timer(func_cat,
1059ac7ddfbfSEd Maste                      "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1060ac7ddfbfSEd Maste                      type_mask);
1061ac7ddfbfSEd Maste 
1062ac7ddfbfSEd Maste   uint32_t initial_size = type_list.GetSize();
1063ac7ddfbfSEd Maste   SymbolFileDWARF *oso_dwarf = NULL;
1064435933ddSDimitry Andric   if (sc_scope) {
1065ac7ddfbfSEd Maste     SymbolContext sc;
1066ac7ddfbfSEd Maste     sc_scope->CalculateSymbolContext(&sc);
1067ac7ddfbfSEd Maste 
1068ac7ddfbfSEd Maste     CompileUnitInfo *cu_info = GetCompUnitInfo(sc);
1069435933ddSDimitry Andric     if (cu_info) {
1070ac7ddfbfSEd Maste       oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info);
1071ac7ddfbfSEd Maste       if (oso_dwarf)
1072ac7ddfbfSEd Maste         oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
1073ac7ddfbfSEd Maste     }
1074435933ddSDimitry Andric   } else {
10751c3bbb01SEd Maste     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1076ac7ddfbfSEd Maste       oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
10771c3bbb01SEd Maste       return false;
10781c3bbb01SEd Maste     });
1079ac7ddfbfSEd Maste   }
1080ac7ddfbfSEd Maste   return type_list.GetSize() - initial_size;
1081ac7ddfbfSEd Maste }
1082ac7ddfbfSEd Maste 
1083*b5893f02SDimitry Andric std::vector<lldb_private::CallEdge>
ParseCallEdgesInFunction(UserID func_id)1084*b5893f02SDimitry Andric SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) {
1085*b5893f02SDimitry Andric   uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID());
1086*b5893f02SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1087*b5893f02SDimitry Andric   if (oso_dwarf)
1088*b5893f02SDimitry Andric     return oso_dwarf->ParseCallEdgesInFunction(func_id);
1089*b5893f02SDimitry Andric   return {};
1090*b5893f02SDimitry Andric }
1091*b5893f02SDimitry Andric 
FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext & die_decl_ctx)1092435933ddSDimitry Andric TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext(
1093435933ddSDimitry Andric     const DWARFDeclContext &die_decl_ctx) {
1094ac7ddfbfSEd Maste   TypeSP type_sp;
10951c3bbb01SEd Maste   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1096ac7ddfbfSEd Maste     type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
10971c3bbb01SEd Maste     return ((bool)type_sp);
10981c3bbb01SEd Maste   });
1099ac7ddfbfSEd Maste   return type_sp;
1100ac7ddfbfSEd Maste }
1101ac7ddfbfSEd Maste 
Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF * skip_dwarf_oso)1102435933ddSDimitry Andric bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
1103435933ddSDimitry Andric     SymbolFileDWARF *skip_dwarf_oso) {
1104435933ddSDimitry Andric   if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
1105ac7ddfbfSEd Maste     m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
11061c3bbb01SEd Maste     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1107435933ddSDimitry Andric       if (skip_dwarf_oso != oso_dwarf &&
1108435933ddSDimitry Andric           oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) {
1109ac7ddfbfSEd Maste         m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
11101c3bbb01SEd Maste         return true;
1111ac7ddfbfSEd Maste       }
11121c3bbb01SEd Maste       return false;
11131c3bbb01SEd Maste     });
1114ac7ddfbfSEd Maste   }
1115ac7ddfbfSEd Maste   return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1116ac7ddfbfSEd Maste }
1117ac7ddfbfSEd Maste 
FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE & die,const ConstString & type_name,bool must_be_implementation)1118435933ddSDimitry Andric TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
1119435933ddSDimitry Andric     const DWARFDIE &die, const ConstString &type_name,
1120435933ddSDimitry Andric     bool must_be_implementation) {
11214ba319b5SDimitry Andric   // If we have a debug map, we will have an Objective-C symbol whose name is
11221c3bbb01SEd Maste   // the type name and whose type is eSymbolTypeObjCClass. If we can find that
11231c3bbb01SEd Maste   // symbol and find its containing parent, we can locate the .o file that will
1124435933ddSDimitry Andric   // contain the implementation definition since it will be scoped inside the
11254ba319b5SDimitry Andric   // N_SO and we can then locate the SymbolFileDWARF that corresponds to that
11264ba319b5SDimitry Andric   // N_SO.
11271c3bbb01SEd Maste   SymbolFileDWARF *oso_dwarf = NULL;
1128ac7ddfbfSEd Maste   TypeSP type_sp;
11291c3bbb01SEd Maste   ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
1130435933ddSDimitry Andric   if (module_objfile) {
11311c3bbb01SEd Maste     Symtab *symtab = module_objfile->GetSymtab();
1132435933ddSDimitry Andric     if (symtab) {
1133435933ddSDimitry Andric       Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
1134435933ddSDimitry Andric           type_name, eSymbolTypeObjCClass, Symtab::eDebugAny,
1135435933ddSDimitry Andric           Symtab::eVisibilityAny);
1136435933ddSDimitry Andric       if (objc_class_symbol) {
1137435933ddSDimitry Andric         // Get the N_SO symbol that contains the objective C class symbol as
11384ba319b5SDimitry Andric         // this should be the .o file that contains the real definition...
11391c3bbb01SEd Maste         const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
11401c3bbb01SEd Maste 
1141435933ddSDimitry Andric         if (source_file_symbol &&
1142435933ddSDimitry Andric             source_file_symbol->GetType() == eSymbolTypeSourceFile) {
1143435933ddSDimitry Andric           const uint32_t source_file_symbol_idx =
1144435933ddSDimitry Andric               symtab->GetIndexForSymbol(source_file_symbol);
1145435933ddSDimitry Andric           if (source_file_symbol_idx != UINT32_MAX) {
1146435933ddSDimitry Andric             CompileUnitInfo *compile_unit_info =
1147435933ddSDimitry Andric                 GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx,
1148435933ddSDimitry Andric                                                      NULL);
1149435933ddSDimitry Andric             if (compile_unit_info) {
11501c3bbb01SEd Maste               oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info);
1151435933ddSDimitry Andric               if (oso_dwarf) {
1152435933ddSDimitry Andric                 TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
1153435933ddSDimitry Andric                     die, type_name, must_be_implementation));
1154435933ddSDimitry Andric                 if (type_sp) {
1155ac7ddfbfSEd Maste                   return type_sp;
1156ac7ddfbfSEd Maste                 }
11571c3bbb01SEd Maste               }
11581c3bbb01SEd Maste             }
11591c3bbb01SEd Maste           }
11601c3bbb01SEd Maste         }
11611c3bbb01SEd Maste       }
11621c3bbb01SEd Maste     }
11631c3bbb01SEd Maste   }
11641c3bbb01SEd Maste 
1165435933ddSDimitry Andric   // Only search all .o files for the definition if we don't need the
11664ba319b5SDimitry Andric   // implementation because otherwise, with a valid debug map we should have
11674ba319b5SDimitry Andric   // the ObjC class symbol and the code above should have found it.
1168*b5893f02SDimitry Andric   if (!must_be_implementation) {
11691c3bbb01SEd Maste     TypeSP type_sp;
11701c3bbb01SEd Maste 
11711c3bbb01SEd Maste     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1172435933ddSDimitry Andric       type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
1173435933ddSDimitry Andric           die, type_name, must_be_implementation);
11741c3bbb01SEd Maste       return (bool)type_sp;
11751c3bbb01SEd Maste     });
11761c3bbb01SEd Maste 
11771c3bbb01SEd Maste     return type_sp;
11781c3bbb01SEd Maste   }
11791c3bbb01SEd Maste   return TypeSP();
11801c3bbb01SEd Maste }
1181ac7ddfbfSEd Maste 
FindTypes(const ConstString & name,const CompilerDeclContext * parent_decl_ctx,bool append,uint32_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)1182435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::FindTypes(
1183*b5893f02SDimitry Andric     const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
1184*b5893f02SDimitry Andric     bool append, uint32_t max_matches,
11854bb0738eSEd Maste     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1186435933ddSDimitry Andric     TypeMap &types) {
1187ac7ddfbfSEd Maste   if (!append)
1188ac7ddfbfSEd Maste     types.Clear();
1189ac7ddfbfSEd Maste 
1190ac7ddfbfSEd Maste   const uint32_t initial_types_size = types.GetSize();
1191ac7ddfbfSEd Maste 
11921c3bbb01SEd Maste   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1193*b5893f02SDimitry Andric     oso_dwarf->FindTypes(name, parent_decl_ctx, append, max_matches,
1194435933ddSDimitry Andric                          searched_symbol_files, types);
1195*b5893f02SDimitry Andric     return types.GetSize() >= max_matches;
11961c3bbb01SEd Maste   });
1197ac7ddfbfSEd Maste 
1198ac7ddfbfSEd Maste   return types.GetSize() - initial_types_size;
1199ac7ddfbfSEd Maste }
1200ac7ddfbfSEd Maste 
1201ac7ddfbfSEd Maste //
1202ac7ddfbfSEd Maste // uint32_t
1203435933ddSDimitry Andric // SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const
1204435933ddSDimitry Andric // RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding
1205435933ddSDimitry Andric // encoding, lldb::user_id_t udt_uid, TypeList& types)
1206ac7ddfbfSEd Maste //{
1207ac7ddfbfSEd Maste //  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1208ac7ddfbfSEd Maste //  if (oso_dwarf)
1209435933ddSDimitry Andric //      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding,
1210435933ddSDimitry Andric //      udt_uid, types);
1211ac7ddfbfSEd Maste //  return 0;
1212ac7ddfbfSEd Maste //}
1213ac7ddfbfSEd Maste 
FindNamespace(const lldb_private::ConstString & name,const CompilerDeclContext * parent_decl_ctx)1214435933ddSDimitry Andric CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
1215ac7ddfbfSEd Maste     const lldb_private::ConstString &name,
1216435933ddSDimitry Andric     const CompilerDeclContext *parent_decl_ctx) {
12179f2f44ceSEd Maste   CompilerDeclContext matching_namespace;
1218ac7ddfbfSEd Maste 
12191c3bbb01SEd Maste   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1220*b5893f02SDimitry Andric     matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx);
1221ac7ddfbfSEd Maste 
12221c3bbb01SEd Maste     return (bool)matching_namespace;
12231c3bbb01SEd Maste   });
1224ac7ddfbfSEd Maste 
1225ac7ddfbfSEd Maste   return matching_namespace;
1226ac7ddfbfSEd Maste }
1227ac7ddfbfSEd Maste 
DumpClangAST(Stream & s)1228*b5893f02SDimitry Andric void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
1229*b5893f02SDimitry Andric   ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool {
1230*b5893f02SDimitry Andric     oso_dwarf->DumpClangAST(s);
1231*b5893f02SDimitry Andric     return true;
1232*b5893f02SDimitry Andric   });
1233*b5893f02SDimitry Andric }
1234*b5893f02SDimitry Andric 
1235ac7ddfbfSEd Maste //------------------------------------------------------------------
1236ac7ddfbfSEd Maste // PluginInterface protocol
1237ac7ddfbfSEd Maste //------------------------------------------------------------------
GetPluginName()1238435933ddSDimitry Andric lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() {
1239ac7ddfbfSEd Maste   return GetPluginNameStatic();
1240ac7ddfbfSEd Maste }
1241ac7ddfbfSEd Maste 
GetPluginVersion()1242435933ddSDimitry Andric uint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; }
1243ac7ddfbfSEd Maste 
1244ac7ddfbfSEd Maste lldb::CompUnitSP
GetCompileUnit(SymbolFileDWARF * oso_dwarf)1245435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) {
1246435933ddSDimitry Andric   if (oso_dwarf) {
1247ac7ddfbfSEd Maste     const uint32_t cu_count = GetNumCompileUnits();
1248435933ddSDimitry Andric     for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
1249435933ddSDimitry Andric       SymbolFileDWARF *oso_symfile =
1250435933ddSDimitry Andric           GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1251435933ddSDimitry Andric       if (oso_symfile == oso_dwarf) {
1252ac7ddfbfSEd Maste         if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
1253435933ddSDimitry Andric           m_compile_unit_infos[cu_idx].compile_unit_sp =
1254435933ddSDimitry Andric               ParseCompileUnitAtIndex(cu_idx);
1255ac7ddfbfSEd Maste 
1256ac7ddfbfSEd Maste         return m_compile_unit_infos[cu_idx].compile_unit_sp;
1257ac7ddfbfSEd Maste       }
1258ac7ddfbfSEd Maste     }
1259ac7ddfbfSEd Maste   }
126095ec533aSDimitry Andric   llvm_unreachable("this shouldn't happen");
1261ac7ddfbfSEd Maste }
1262ac7ddfbfSEd Maste 
1263ac7ddfbfSEd Maste SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompileUnitInfo(SymbolFileDWARF * oso_dwarf)1264435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) {
1265435933ddSDimitry Andric   if (oso_dwarf) {
1266ac7ddfbfSEd Maste     const uint32_t cu_count = GetNumCompileUnits();
1267435933ddSDimitry Andric     for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
1268435933ddSDimitry Andric       SymbolFileDWARF *oso_symfile =
1269435933ddSDimitry Andric           GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1270435933ddSDimitry Andric       if (oso_symfile == oso_dwarf) {
1271ac7ddfbfSEd Maste         return &m_compile_unit_infos[cu_idx];
1272ac7ddfbfSEd Maste       }
1273ac7ddfbfSEd Maste     }
1274ac7ddfbfSEd Maste   }
1275ac7ddfbfSEd Maste   return NULL;
1276ac7ddfbfSEd Maste }
1277ac7ddfbfSEd Maste 
SetCompileUnit(SymbolFileDWARF * oso_dwarf,const CompUnitSP & cu_sp)1278435933ddSDimitry Andric void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
1279435933ddSDimitry Andric                                              const CompUnitSP &cu_sp) {
1280435933ddSDimitry Andric   if (oso_dwarf) {
1281ac7ddfbfSEd Maste     const uint32_t cu_count = GetNumCompileUnits();
1282435933ddSDimitry Andric     for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
1283435933ddSDimitry Andric       SymbolFileDWARF *oso_symfile =
1284435933ddSDimitry Andric           GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1285435933ddSDimitry Andric       if (oso_symfile == oso_dwarf) {
1286435933ddSDimitry Andric         if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
1287435933ddSDimitry Andric           assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() ==
1288435933ddSDimitry Andric                  cu_sp.get());
1289435933ddSDimitry Andric         } else {
1290ac7ddfbfSEd Maste           m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
1291435933ddSDimitry Andric           m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
1292435933ddSDimitry Andric               cu_idx, cu_sp);
1293ac7ddfbfSEd Maste         }
1294ac7ddfbfSEd Maste       }
1295ac7ddfbfSEd Maste     }
1296ac7ddfbfSEd Maste   }
1297ac7ddfbfSEd Maste }
1298ac7ddfbfSEd Maste 
12999f2f44ceSEd Maste CompilerDeclContext
GetDeclContextForUID(lldb::user_id_t type_uid)1300435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) {
1301ac7ddfbfSEd Maste   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1302ac7ddfbfSEd Maste   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1303ac7ddfbfSEd Maste   if (oso_dwarf)
13049f2f44ceSEd Maste     return oso_dwarf->GetDeclContextForUID(type_uid);
13059f2f44ceSEd Maste   return CompilerDeclContext();
1306ac7ddfbfSEd Maste }
1307ac7ddfbfSEd Maste 
13089f2f44ceSEd Maste CompilerDeclContext
GetDeclContextContainingUID(lldb::user_id_t type_uid)1309435933ddSDimitry Andric SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
1310ac7ddfbfSEd Maste   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1311ac7ddfbfSEd Maste   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1312ac7ddfbfSEd Maste   if (oso_dwarf)
13139f2f44ceSEd Maste     return oso_dwarf->GetDeclContextContainingUID(type_uid);
13149f2f44ceSEd Maste   return CompilerDeclContext();
13159f2f44ceSEd Maste }
13169f2f44ceSEd Maste 
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)1317435933ddSDimitry Andric void SymbolFileDWARFDebugMap::ParseDeclsForContext(
1318435933ddSDimitry Andric     lldb_private::CompilerDeclContext decl_ctx) {
13199f2f44ceSEd Maste   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
13209f2f44ceSEd Maste     oso_dwarf->ParseDeclsForContext(decl_ctx);
13219f2f44ceSEd Maste     return true; // Keep iterating
13229f2f44ceSEd Maste   });
1323ac7ddfbfSEd Maste }
1324ac7ddfbfSEd Maste 
AddOSOFileRange(CompileUnitInfo * cu_info,lldb::addr_t exe_file_addr,lldb::addr_t exe_byte_size,lldb::addr_t oso_file_addr,lldb::addr_t oso_byte_size)1325435933ddSDimitry Andric bool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info,
1326ac7ddfbfSEd Maste                                               lldb::addr_t exe_file_addr,
13274bb0738eSEd Maste                                               lldb::addr_t exe_byte_size,
1328ac7ddfbfSEd Maste                                               lldb::addr_t oso_file_addr,
1329435933ddSDimitry Andric                                               lldb::addr_t oso_byte_size) {
1330435933ddSDimitry Andric   const uint32_t debug_map_idx =
1331435933ddSDimitry Andric       m_debug_map.FindEntryIndexThatContains(exe_file_addr);
1332435933ddSDimitry Andric   if (debug_map_idx != UINT32_MAX) {
1333435933ddSDimitry Andric     DebugMap::Entry *debug_map_entry =
1334435933ddSDimitry Andric         m_debug_map.FindEntryThatContains(exe_file_addr);
1335ac7ddfbfSEd Maste     debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
13364bb0738eSEd Maste     addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
1337435933ddSDimitry Andric     if (range_size == 0) {
13384bb0738eSEd Maste       range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
13394bb0738eSEd Maste       if (range_size == 0)
13404bb0738eSEd Maste         range_size = 1;
13414bb0738eSEd Maste     }
1342435933ddSDimitry Andric     cu_info->file_range_map.Append(
1343435933ddSDimitry Andric         FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
1344ac7ddfbfSEd Maste     return true;
1345ac7ddfbfSEd Maste   }
1346ac7ddfbfSEd Maste   return false;
1347ac7ddfbfSEd Maste }
1348ac7ddfbfSEd Maste 
FinalizeOSOFileRanges(CompileUnitInfo * cu_info)1349435933ddSDimitry Andric void SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) {
1350ac7ddfbfSEd Maste   cu_info->file_range_map.Sort();
1351ac7ddfbfSEd Maste #if defined(DEBUG_OSO_DMAP)
1352ac7ddfbfSEd Maste   const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1353ac7ddfbfSEd Maste   const size_t n = oso_file_range_map.GetSize();
1354ac7ddfbfSEd Maste   printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
1355435933ddSDimitry Andric          cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
1356435933ddSDimitry Andric   for (size_t i = 0; i < n; ++i) {
1357ac7ddfbfSEd Maste     const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
1358435933ddSDimitry Andric     printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
1359435933ddSDimitry Andric            ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
1360435933ddSDimitry Andric            entry.GetRangeBase(), entry.GetRangeEnd(), entry.data,
1361435933ddSDimitry Andric            entry.data + entry.GetByteSize());
1362ac7ddfbfSEd Maste   }
1363ac7ddfbfSEd Maste #endif
1364ac7ddfbfSEd Maste }
1365ac7ddfbfSEd Maste 
1366ac7ddfbfSEd Maste lldb::addr_t
LinkOSOFileAddress(SymbolFileDWARF * oso_symfile,lldb::addr_t oso_file_addr)1367435933ddSDimitry Andric SymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
1368435933ddSDimitry Andric                                             lldb::addr_t oso_file_addr) {
1369ac7ddfbfSEd Maste   CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile);
1370435933ddSDimitry Andric   if (cu_info) {
1371435933ddSDimitry Andric     const FileRangeMap::Entry *oso_range_entry =
1372435933ddSDimitry Andric         cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1373435933ddSDimitry Andric     if (oso_range_entry) {
1374435933ddSDimitry Andric       const DebugMap::Entry *debug_map_entry =
1375435933ddSDimitry Andric           m_debug_map.FindEntryThatContains(oso_range_entry->data);
1376435933ddSDimitry Andric       if (debug_map_entry) {
1377435933ddSDimitry Andric         const lldb::addr_t offset =
1378435933ddSDimitry Andric             oso_file_addr - oso_range_entry->GetRangeBase();
1379435933ddSDimitry Andric         const lldb::addr_t exe_file_addr =
1380435933ddSDimitry Andric             debug_map_entry->GetRangeBase() + offset;
1381ac7ddfbfSEd Maste         return exe_file_addr;
1382ac7ddfbfSEd Maste       }
1383ac7ddfbfSEd Maste     }
1384ac7ddfbfSEd Maste   }
1385ac7ddfbfSEd Maste   return LLDB_INVALID_ADDRESS;
1386ac7ddfbfSEd Maste }
1387ac7ddfbfSEd Maste 
LinkOSOAddress(Address & addr)1388435933ddSDimitry Andric bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) {
1389ac7ddfbfSEd Maste   // Make sure this address hasn't been fixed already
1390ac7ddfbfSEd Maste   Module *exe_module = GetObjectFile()->GetModule().get();
1391ac7ddfbfSEd Maste   Module *addr_module = addr.GetModule().get();
1392ac7ddfbfSEd Maste   if (addr_module == exe_module)
1393ac7ddfbfSEd Maste     return true; // Address is already in terms of the main executable module
1394ac7ddfbfSEd Maste 
1395435933ddSDimitry Andric   CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF(
1396435933ddSDimitry Andric       addr_module->GetSymbolVendor()->GetSymbolFile()));
1397435933ddSDimitry Andric   if (cu_info) {
1398ac7ddfbfSEd Maste     const lldb::addr_t oso_file_addr = addr.GetFileAddress();
1399435933ddSDimitry Andric     const FileRangeMap::Entry *oso_range_entry =
1400435933ddSDimitry Andric         cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1401435933ddSDimitry Andric     if (oso_range_entry) {
1402435933ddSDimitry Andric       const DebugMap::Entry *debug_map_entry =
1403435933ddSDimitry Andric           m_debug_map.FindEntryThatContains(oso_range_entry->data);
1404435933ddSDimitry Andric       if (debug_map_entry) {
1405435933ddSDimitry Andric         const lldb::addr_t offset =
1406435933ddSDimitry Andric             oso_file_addr - oso_range_entry->GetRangeBase();
1407435933ddSDimitry Andric         const lldb::addr_t exe_file_addr =
1408435933ddSDimitry Andric             debug_map_entry->GetRangeBase() + offset;
1409ac7ddfbfSEd Maste         return exe_module->ResolveFileAddress(exe_file_addr, addr);
1410ac7ddfbfSEd Maste       }
1411ac7ddfbfSEd Maste     }
1412ac7ddfbfSEd Maste   }
1413ac7ddfbfSEd Maste   return true;
1414ac7ddfbfSEd Maste }
1415ac7ddfbfSEd Maste 
LinkOSOLineTable(SymbolFileDWARF * oso_dwarf,LineTable * line_table)1416435933ddSDimitry Andric LineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf,
1417435933ddSDimitry Andric                                                      LineTable *line_table) {
1418ac7ddfbfSEd Maste   CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf);
1419ac7ddfbfSEd Maste   if (cu_info)
1420ac7ddfbfSEd Maste     return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
1421ac7ddfbfSEd Maste   return NULL;
1422ac7ddfbfSEd Maste }
1423ac7ddfbfSEd Maste 
1424ac7ddfbfSEd Maste size_t
AddOSOARanges(SymbolFileDWARF * dwarf2Data,DWARFDebugAranges * debug_aranges)1425435933ddSDimitry Andric SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,
1426435933ddSDimitry Andric                                        DWARFDebugAranges *debug_aranges) {
1427ac7ddfbfSEd Maste   size_t num_line_entries_added = 0;
1428435933ddSDimitry Andric   if (debug_aranges && dwarf2Data) {
1429ac7ddfbfSEd Maste     CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
1430435933ddSDimitry Andric     if (compile_unit_info) {
1431435933ddSDimitry Andric       const FileRangeMap &file_range_map =
1432435933ddSDimitry Andric           compile_unit_info->GetFileRangeMap(this);
1433435933ddSDimitry Andric       for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) {
1434ac7ddfbfSEd Maste         const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx);
1435435933ddSDimitry Andric         if (entry) {
1436435933ddSDimitry Andric           debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(),
1437435933ddSDimitry Andric                                      entry->GetRangeEnd());
1438ac7ddfbfSEd Maste           num_line_entries_added++;
1439ac7ddfbfSEd Maste         }
1440ac7ddfbfSEd Maste       }
1441ac7ddfbfSEd Maste     }
1442ac7ddfbfSEd Maste   }
1443ac7ddfbfSEd Maste   return num_line_entries_added;
1444ac7ddfbfSEd Maste }
1445