xref: /src/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1cfca06d7SDimitry Andric //===-- SymbolFileDWARFDebugMap.cpp ---------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste 
9f034231aSEd Maste #include "SymbolFileDWARFDebugMap.h"
10e3b55780SDimitry Andric #include "DWARFCompileUnit.h"
11f034231aSEd Maste #include "DWARFDebugAranges.h"
12e3b55780SDimitry Andric #include "DWARFDebugInfo.h"
13f034231aSEd Maste 
14f034231aSEd Maste #include "lldb/Core/Module.h"
15f034231aSEd Maste #include "lldb/Core/ModuleList.h"
16f034231aSEd Maste #include "lldb/Core/PluginManager.h"
17f034231aSEd Maste #include "lldb/Core/Section.h"
1814f1b3e8SDimitry Andric #include "lldb/Host/FileSystem.h"
195f29bb8aSDimitry Andric #include "lldb/Utility/RangeMap.h"
2074a628f7SDimitry Andric #include "lldb/Utility/RegularExpression.h"
21e3b55780SDimitry Andric #include "lldb/Utility/StreamString.h"
22b1c73532SDimitry Andric #include "lldb/Utility/StructuredData.h"
23b1c73532SDimitry Andric #include "lldb/Utility/Timer.h"
24f034231aSEd Maste 
25f034231aSEd Maste //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
26f034231aSEd Maste 
27f034231aSEd Maste #include "lldb/Symbol/CompileUnit.h"
28f034231aSEd Maste #include "lldb/Symbol/LineTable.h"
29f034231aSEd Maste #include "lldb/Symbol/ObjectFile.h"
30f034231aSEd Maste #include "lldb/Symbol/SymbolVendor.h"
31e81d9d49SDimitry Andric #include "lldb/Symbol/TypeMap.h"
32f034231aSEd Maste #include "lldb/Symbol/VariableList.h"
337fa27ce4SDimitry Andric #include "llvm/ADT/STLExtras.h"
3414f1b3e8SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
35f034231aSEd Maste 
36e3b55780SDimitry Andric #include "lldb/Target/StackFrame.h"
37e3b55780SDimitry Andric 
38f034231aSEd Maste #include "LogChannelDWARF.h"
39f034231aSEd Maste #include "SymbolFileDWARF.h"
40ac9a064cSDimitry Andric #include "lldb/lldb-private-enumerations.h"
41f034231aSEd Maste 
425f29bb8aSDimitry Andric #include <memory>
43e3b55780SDimitry Andric #include <optional>
445f29bb8aSDimitry Andric 
45f034231aSEd Maste using namespace lldb;
46f034231aSEd Maste using namespace lldb_private;
47b1c73532SDimitry Andric using namespace lldb_private::plugin::dwarf;
48f034231aSEd Maste 
49706b4fc4SDimitry Andric char SymbolFileDWARFDebugMap::ID;
50706b4fc4SDimitry Andric 
5114f1b3e8SDimitry Andric // Subclass lldb_private::Module so we can intercept the
52f73363f1SDimitry Andric // "Module::GetObjectFile()" (so we can fixup the object file sections) and
53ead24645SDimitry Andric // also for "Module::GetSymbolFile()" (so we can fixup the symbol file id.
54f034231aSEd Maste 
55f034231aSEd Maste const SymbolFileDWARFDebugMap::FileRangeMap &
GetFileRangeMap(SymbolFileDWARFDebugMap * exe_symfile)5614f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
5714f1b3e8SDimitry Andric     SymbolFileDWARFDebugMap *exe_symfile) {
58f034231aSEd Maste   if (file_range_map_valid)
59f034231aSEd Maste     return file_range_map;
60f034231aSEd Maste 
61f034231aSEd Maste   file_range_map_valid = true;
62f034231aSEd Maste 
63f034231aSEd Maste   Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this);
64f034231aSEd Maste   if (!oso_module)
65f034231aSEd Maste     return file_range_map;
66f034231aSEd Maste 
67f034231aSEd Maste   ObjectFile *oso_objfile = oso_module->GetObjectFile();
68f034231aSEd Maste   if (!oso_objfile)
69f034231aSEd Maste     return file_range_map;
70f034231aSEd Maste 
71ecbca9f5SDimitry Andric   Log *log = GetLog(DWARFLog::DebugMap);
72ead24645SDimitry Andric   LLDB_LOGF(
73ead24645SDimitry Andric       log,
7414f1b3e8SDimitry Andric       "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
750cac4ca3SEd Maste       static_cast<void *>(this),
76f034231aSEd Maste       oso_module->GetSpecificationDescription().c_str());
77f034231aSEd Maste 
78f034231aSEd Maste   std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
7914f1b3e8SDimitry Andric   if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
8014f1b3e8SDimitry Andric     for (auto comp_unit_info : cu_infos) {
81f034231aSEd Maste       Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
82f034231aSEd Maste       ModuleSP oso_module_sp(oso_objfile->GetModule());
83f034231aSEd Maste       Symtab *oso_symtab = oso_objfile->GetSymtab();
84f034231aSEd Maste 
8514f1b3e8SDimitry Andric       /// const uint32_t fun_resolve_flags = SymbolContext::Module |
8614f1b3e8SDimitry Andric       /// eSymbolContextCompUnit | eSymbolContextFunction;
87f034231aSEd Maste       // SectionList *oso_sections = oso_objfile->Sections();
88f73363f1SDimitry Andric       // Now we need to make sections that map from zero based object file
89f73363f1SDimitry Andric       // addresses to where things ended up in the main executable.
90f034231aSEd Maste 
91f034231aSEd Maste       assert(comp_unit_info->first_symbol_index != UINT32_MAX);
92f034231aSEd Maste       // End index is one past the last valid symbol index
93f034231aSEd Maste       const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
9414f1b3e8SDimitry Andric       for (uint32_t idx = comp_unit_info->first_symbol_index +
9514f1b3e8SDimitry Andric                           2; // Skip the N_SO and N_OSO
9694994d37SDimitry Andric            idx < oso_end_idx; ++idx) {
97f034231aSEd Maste         Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
9814f1b3e8SDimitry Andric         if (exe_symbol) {
9994994d37SDimitry Andric           if (!exe_symbol->IsDebug())
100f034231aSEd Maste             continue;
101f034231aSEd Maste 
10214f1b3e8SDimitry Andric           switch (exe_symbol->GetType()) {
103f034231aSEd Maste           default:
104f034231aSEd Maste             break;
105f034231aSEd Maste 
10614f1b3e8SDimitry Andric           case eSymbolTypeCode: {
107f73363f1SDimitry Andric             // For each N_FUN, or function that we run into in the debug map we
108f73363f1SDimitry Andric             // make a new section that we add to the sections found in the .o
109f73363f1SDimitry Andric             // file. This new section has the file address set to what the
110f034231aSEd Maste             // addresses are in the .o file, and the load address is adjusted
111f034231aSEd Maste             // to match where it ended up in the final executable! We do this
112f034231aSEd Maste             // before we parse any dwarf info so that when it goes get parsed
113f034231aSEd Maste             // all section/offset addresses that get registered will resolve
114f034231aSEd Maste             // correctly to the new addresses in the main executable.
115f034231aSEd Maste 
116f034231aSEd Maste             // First we find the original symbol in the .o file's symbol table
11714f1b3e8SDimitry Andric             Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(
118cfca06d7SDimitry Andric                 exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
11914f1b3e8SDimitry Andric                 eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
12014f1b3e8SDimitry Andric             if (oso_fun_symbol) {
121f034231aSEd Maste               // Add the inverse OSO file address to debug map entry mapping
12214f1b3e8SDimitry Andric               exe_symfile->AddOSOFileRange(
12314f1b3e8SDimitry Andric                   this, exe_symbol->GetAddressRef().GetFileAddress(),
124f3fbd1c0SDimitry Andric                   exe_symbol->GetByteSize(),
1255e95aa85SEd Maste                   oso_fun_symbol->GetAddressRef().GetFileAddress(),
126f3fbd1c0SDimitry Andric                   oso_fun_symbol->GetByteSize());
127f034231aSEd Maste             }
12814f1b3e8SDimitry Andric           } break;
129f034231aSEd Maste 
13014f1b3e8SDimitry Andric           case eSymbolTypeData: {
131f73363f1SDimitry Andric             // For each N_GSYM we remap the address for the global by making a
132f73363f1SDimitry Andric             // new section that we add to the sections found in the .o file.
133f73363f1SDimitry Andric             // This new section has the file address set to what the addresses
134f73363f1SDimitry Andric             // are in the .o file, and the load address is adjusted to match
135f73363f1SDimitry Andric             // where it ended up in the final executable! We do this before we
136f73363f1SDimitry Andric             // parse any dwarf info so that when it goes get parsed all
137f73363f1SDimitry Andric             // section/offset addresses that get registered will resolve
138f034231aSEd Maste             // correctly to the new addresses in the main executable. We
139f034231aSEd Maste             // initially set the section size to be 1 byte, but will need to
140f034231aSEd Maste             // fix up these addresses further after all globals have been
141f034231aSEd Maste             // parsed to span the gaps, or we can find the global variable
142f034231aSEd Maste             // sizes from the DWARF info as we are parsing.
143f034231aSEd Maste 
144f73363f1SDimitry Andric             // Next we find the non-stab entry that corresponds to the N_GSYM
145f73363f1SDimitry Andric             // in the .o file
14614f1b3e8SDimitry Andric             Symbol *oso_gsym_symbol =
14714f1b3e8SDimitry Andric                 oso_symtab->FindFirstSymbolWithNameAndType(
148cfca06d7SDimitry Andric                     exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
14914f1b3e8SDimitry Andric                     eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny);
15014f1b3e8SDimitry Andric             if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() &&
15114f1b3e8SDimitry Andric                 oso_gsym_symbol->ValueIsAddress()) {
152f034231aSEd Maste               // Add the inverse OSO file address to debug map entry mapping
15314f1b3e8SDimitry Andric               exe_symfile->AddOSOFileRange(
15414f1b3e8SDimitry Andric                   this, exe_symbol->GetAddressRef().GetFileAddress(),
155f3fbd1c0SDimitry Andric                   exe_symbol->GetByteSize(),
1565e95aa85SEd Maste                   oso_gsym_symbol->GetAddressRef().GetFileAddress(),
157f3fbd1c0SDimitry Andric                   oso_gsym_symbol->GetByteSize());
158f034231aSEd Maste             }
15914f1b3e8SDimitry Andric           } break;
160f034231aSEd Maste           }
161f034231aSEd Maste         }
162f034231aSEd Maste       }
163f034231aSEd Maste 
164f034231aSEd Maste       exe_symfile->FinalizeOSOFileRanges(this);
165f034231aSEd Maste       // We don't need the symbols anymore for the .o files
166f034231aSEd Maste       oso_objfile->ClearSymtab();
167f034231aSEd Maste     }
168f034231aSEd Maste   }
169f034231aSEd Maste   return file_range_map;
170f034231aSEd Maste }
171f034231aSEd Maste 
172b1c73532SDimitry Andric namespace lldb_private::plugin {
173b1c73532SDimitry Andric namespace dwarf {
17414f1b3e8SDimitry Andric class DebugMapModule : public Module {
175f034231aSEd Maste public:
DebugMapModule(const ModuleSP & exe_module_sp,uint32_t cu_idx,const FileSpec & file_spec,const ArchSpec & arch,ConstString object_name,off_t object_offset,const llvm::sys::TimePoint<> object_mod_time)17614f1b3e8SDimitry Andric   DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx,
17714f1b3e8SDimitry Andric                  const FileSpec &file_spec, const ArchSpec &arch,
178b1c73532SDimitry Andric                  ConstString object_name, off_t object_offset,
17914f1b3e8SDimitry Andric                  const llvm::sys::TimePoint<> object_mod_time)
18014f1b3e8SDimitry Andric       : Module(file_spec, arch, object_name, object_offset, object_mod_time),
18114f1b3e8SDimitry Andric         m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {}
182f034231aSEd Maste 
183e81d9d49SDimitry Andric   ~DebugMapModule() override = default;
184f034231aSEd Maste 
185ead24645SDimitry Andric   SymbolFile *
GetSymbolFile(bool can_create=true,lldb_private::Stream * feedback_strm=nullptr)186ead24645SDimitry Andric   GetSymbolFile(bool can_create = true,
1875f29bb8aSDimitry Andric                 lldb_private::Stream *feedback_strm = nullptr) override {
188f034231aSEd Maste     // Scope for locker
1895f29bb8aSDimitry Andric     if (m_symfile_up.get() || !can_create)
190ead24645SDimitry Andric       return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
191f034231aSEd Maste 
192f034231aSEd Maste     ModuleSP exe_module_sp(m_exe_module_wp.lock());
19314f1b3e8SDimitry Andric     if (exe_module_sp) {
194f034231aSEd Maste       // Now get the object file outside of a locking scope
195f034231aSEd Maste       ObjectFile *oso_objfile = GetObjectFile();
19614f1b3e8SDimitry Andric       if (oso_objfile) {
197f3fbd1c0SDimitry Andric         std::lock_guard<std::recursive_mutex> guard(m_mutex);
198ead24645SDimitry Andric         if (SymbolFile *symfile =
199ead24645SDimitry Andric                 Module::GetSymbolFile(can_create, feedback_strm)) {
200f73363f1SDimitry Andric           // Set a pointer to this class to set our OSO DWARF file know that
201f73363f1SDimitry Andric           // the DWARF is being used along with a debug map and that it will
202f73363f1SDimitry Andric           // have the remapped sections that we do below.
20314f1b3e8SDimitry Andric           SymbolFileDWARF *oso_symfile =
204ead24645SDimitry Andric               SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symfile);
205f034231aSEd Maste 
206f034231aSEd Maste           if (!oso_symfile)
2075f29bb8aSDimitry Andric             return nullptr;
208f034231aSEd Maste 
209f034231aSEd Maste           ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
210ead24645SDimitry Andric           SymbolFile *exe_symfile = exe_module_sp->GetSymbolFile();
211f034231aSEd Maste 
212ead24645SDimitry Andric           if (exe_objfile && exe_symfile) {
213f034231aSEd Maste             oso_symfile->SetDebugMapModule(exe_module_sp);
214f034231aSEd Maste             // Set the ID of the symbol file DWARF to the index of the OSO
215f034231aSEd Maste             // shifted left by 32 bits to provide a unique prefix for any
216f034231aSEd Maste             // UserID's that get created in the symbol file.
2177fa27ce4SDimitry Andric             oso_symfile->SetFileIndex((uint64_t)m_cu_idx);
218f034231aSEd Maste           }
219ead24645SDimitry Andric           return symfile;
220f034231aSEd Maste         }
221f034231aSEd Maste       }
222f034231aSEd Maste     }
2235f29bb8aSDimitry Andric     return nullptr;
224f034231aSEd Maste   }
225f034231aSEd Maste 
226f034231aSEd Maste protected:
227f034231aSEd Maste   ModuleWP m_exe_module_wp;
228f034231aSEd Maste   const uint32_t m_cu_idx;
229f034231aSEd Maste };
230b1c73532SDimitry Andric } // namespace dwarf
231b1c73532SDimitry Andric } // namespace lldb_private::plugin
232f034231aSEd Maste 
Initialize()23314f1b3e8SDimitry Andric void SymbolFileDWARFDebugMap::Initialize() {
234f034231aSEd Maste   PluginManager::RegisterPlugin(GetPluginNameStatic(),
23514f1b3e8SDimitry Andric                                 GetPluginDescriptionStatic(), CreateInstance);
236f034231aSEd Maste }
237f034231aSEd Maste 
Terminate()23814f1b3e8SDimitry Andric void SymbolFileDWARFDebugMap::Terminate() {
239f034231aSEd Maste   PluginManager::UnregisterPlugin(CreateInstance);
240f034231aSEd Maste }
241f034231aSEd Maste 
GetPluginDescriptionStatic()242c0981da4SDimitry Andric llvm::StringRef SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
243f034231aSEd Maste   return "DWARF and DWARF3 debug symbol file reader (debug map).";
244f034231aSEd Maste }
245f034231aSEd Maste 
CreateInstance(ObjectFileSP objfile_sp)246ead24645SDimitry Andric SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) {
247ead24645SDimitry Andric   return new SymbolFileDWARFDebugMap(std::move(objfile_sp));
248f034231aSEd Maste }
249f034231aSEd Maste 
SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp)250ead24645SDimitry Andric SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp)
251145449b1SDimitry Andric     : SymbolFileCommon(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(),
252ead24645SDimitry Andric       m_func_indexes(), m_glob_indexes(),
25314f1b3e8SDimitry Andric       m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
254f034231aSEd Maste 
255344a3780SDimitry Andric SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() = default;
256f034231aSEd Maste 
InitializeObject()25714f1b3e8SDimitry Andric void SymbolFileDWARFDebugMap::InitializeObject() {}
258f034231aSEd Maste 
InitOSO()25914f1b3e8SDimitry Andric void SymbolFileDWARFDebugMap::InitOSO() {
260f034231aSEd Maste   if (m_flags.test(kHaveInitializedOSOs))
261f034231aSEd Maste     return;
262f034231aSEd Maste 
263f034231aSEd Maste   m_flags.set(kHaveInitializedOSOs);
264f034231aSEd Maste 
265f034231aSEd Maste   // If the object file has been stripped, there is no sense in looking further
266f034231aSEd Maste   // as all of the debug symbols for the debug map will not be available
267ead24645SDimitry Andric   if (m_objfile_sp->IsStripped())
268f034231aSEd Maste     return;
269f034231aSEd Maste 
270f034231aSEd Maste   // Also make sure the file type is some sort of executable. Core files, debug
271f034231aSEd Maste   // info files (dSYM), object files (.o files), and stub libraries all can
272ead24645SDimitry Andric   switch (m_objfile_sp->GetType()) {
273f034231aSEd Maste   case ObjectFile::eTypeInvalid:
274f034231aSEd Maste   case ObjectFile::eTypeCoreFile:
275f034231aSEd Maste   case ObjectFile::eTypeDebugInfo:
276f034231aSEd Maste   case ObjectFile::eTypeObjectFile:
277f034231aSEd Maste   case ObjectFile::eTypeStubLibrary:
278f034231aSEd Maste   case ObjectFile::eTypeUnknown:
2790cac4ca3SEd Maste   case ObjectFile::eTypeJIT:
280f034231aSEd Maste     return;
281f034231aSEd Maste 
282f034231aSEd Maste   case ObjectFile::eTypeExecutable:
283f034231aSEd Maste   case ObjectFile::eTypeDynamicLinker:
284f034231aSEd Maste   case ObjectFile::eTypeSharedLibrary:
285f034231aSEd Maste     break;
286f034231aSEd Maste   }
287f034231aSEd Maste 
288f034231aSEd Maste   // In order to get the abilities of this plug-in, we look at the list of
289f034231aSEd Maste   // N_OSO entries (object files) from the symbol table and make sure that
290f73363f1SDimitry Andric   // these files exist and also contain valid DWARF. If we get any of that then
291f73363f1SDimitry Andric   // we return the abilities of the first N_OSO's DWARF.
292f034231aSEd Maste 
293ead24645SDimitry Andric   Symtab *symtab = m_objfile_sp->GetSymtab();
2947fa27ce4SDimitry Andric   if (!symtab)
2957fa27ce4SDimitry Andric     return;
2967fa27ce4SDimitry Andric 
297ecbca9f5SDimitry Andric   Log *log = GetLog(DWARFLog::DebugMap);
298f034231aSEd Maste 
299f034231aSEd Maste   std::vector<uint32_t> oso_indexes;
300f034231aSEd Maste   // When a mach-o symbol is encoded, the n_type field is encoded in bits
301f034231aSEd Maste   // 23:16, and the n_desc field is encoded in bits 15:0.
302f034231aSEd Maste   //
303f73363f1SDimitry Andric   // To find all N_OSO entries that are part of the DWARF + debug map we find
304f73363f1SDimitry Andric   // only object file symbols with the flags value as follows: bits 23:16 ==
305f73363f1SDimitry Andric   // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object
306f73363f1SDimitry Andric   // file)
307f034231aSEd Maste   const uint32_t k_oso_symbol_flags_value = 0x660001u;
308f034231aSEd Maste 
30914f1b3e8SDimitry Andric   const uint32_t oso_index_count =
31014f1b3e8SDimitry Andric       symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
31114f1b3e8SDimitry Andric           eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
312f034231aSEd Maste 
3137fa27ce4SDimitry Andric   if (oso_index_count == 0)
3147fa27ce4SDimitry Andric     return;
3157fa27ce4SDimitry Andric 
31614f1b3e8SDimitry Andric   symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes,
3177fa27ce4SDimitry Andric                                       Symtab::eVisibilityAny, m_func_indexes);
31814f1b3e8SDimitry Andric   symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes,
3197fa27ce4SDimitry Andric                                       Symtab::eVisibilityAny, m_glob_indexes);
320f034231aSEd Maste 
321f034231aSEd Maste   symtab->SortSymbolIndexesByValue(m_func_indexes, true);
322f034231aSEd Maste   symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
323f034231aSEd Maste 
3247fa27ce4SDimitry Andric   for (uint32_t sym_idx :
3257fa27ce4SDimitry Andric        llvm::concat<uint32_t>(m_func_indexes, m_glob_indexes)) {
326f034231aSEd Maste     const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
3275e95aa85SEd Maste     lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
328f034231aSEd Maste     lldb::addr_t byte_size = symbol->GetByteSize();
3297fa27ce4SDimitry Andric     DebugMap::Entry debug_map_entry(file_addr, byte_size,
3307fa27ce4SDimitry Andric                                     OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
331f034231aSEd Maste     m_debug_map.Append(debug_map_entry);
332f034231aSEd Maste   }
333f034231aSEd Maste   m_debug_map.Sort();
334f034231aSEd Maste 
335f034231aSEd Maste   m_compile_unit_infos.resize(oso_index_count);
336f034231aSEd Maste 
33714f1b3e8SDimitry Andric   for (uint32_t i = 0; i < oso_index_count; ++i) {
338f034231aSEd Maste     const uint32_t so_idx = oso_indexes[i] - 1;
339f034231aSEd Maste     const uint32_t oso_idx = oso_indexes[i];
340f034231aSEd Maste     const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
341f034231aSEd Maste     const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
34214f1b3e8SDimitry Andric     if (so_symbol && oso_symbol &&
343f034231aSEd Maste         so_symbol->GetType() == eSymbolTypeSourceFile &&
34414f1b3e8SDimitry Andric         oso_symbol->GetType() == eSymbolTypeObjectFile) {
3457fa27ce4SDimitry Andric       m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(),
3467fa27ce4SDimitry Andric                                               FileSpec::Style::native);
347f034231aSEd Maste       m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
34814f1b3e8SDimitry Andric       m_compile_unit_infos[i].oso_mod_time =
34914f1b3e8SDimitry Andric           llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0));
350f034231aSEd Maste       uint32_t sibling_idx = so_symbol->GetSiblingIndex();
35114f1b3e8SDimitry Andric       // The sibling index can't be less that or equal to the current index
35214f1b3e8SDimitry Andric       // "i"
3537fa27ce4SDimitry Andric       if (sibling_idx <= i || sibling_idx == UINT32_MAX) {
354ead24645SDimitry Andric         m_objfile_sp->GetModule()->ReportError(
355e3b55780SDimitry Andric             "N_SO in symbol with UID {0} has invalid sibling in debug "
356e3b55780SDimitry Andric             "map, "
35714f1b3e8SDimitry Andric             "please file a bug and attach the binary listed in this error",
35814f1b3e8SDimitry Andric             so_symbol->GetID());
35914f1b3e8SDimitry Andric       } else {
360f034231aSEd Maste         const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
361f034231aSEd Maste         m_compile_unit_infos[i].first_symbol_index = so_idx;
362f034231aSEd Maste         m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
363f034231aSEd Maste         m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
364f034231aSEd Maste         m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
365f034231aSEd Maste 
366ead24645SDimitry Andric         LLDB_LOGF(log, "Initialized OSO 0x%8.8x: file=%s", i,
36714f1b3e8SDimitry Andric                   oso_symbol->GetName().GetCString());
368f034231aSEd Maste       }
36914f1b3e8SDimitry Andric     } else {
3705f29bb8aSDimitry Andric       if (oso_symbol == nullptr)
371ead24645SDimitry Andric         m_objfile_sp->GetModule()->ReportError(
372e3b55780SDimitry Andric             "N_OSO symbol[{0}] can't be found, please file a bug and "
373e3b55780SDimitry Andric             "attach "
37414f1b3e8SDimitry Andric             "the binary listed in this error",
37514f1b3e8SDimitry Andric             oso_idx);
3765f29bb8aSDimitry Andric       else if (so_symbol == nullptr)
377ead24645SDimitry Andric         m_objfile_sp->GetModule()->ReportError(
378e3b55780SDimitry Andric             "N_SO not found for N_OSO symbol[{0}], please file a bug and "
37914f1b3e8SDimitry Andric             "attach the binary listed in this error",
38014f1b3e8SDimitry Andric             oso_idx);
381f034231aSEd Maste       else if (so_symbol->GetType() != eSymbolTypeSourceFile)
382ead24645SDimitry Andric         m_objfile_sp->GetModule()->ReportError(
383e3b55780SDimitry Andric             "N_SO has incorrect symbol type ({0}) for N_OSO "
384e3b55780SDimitry Andric             "symbol[{1}], "
38514f1b3e8SDimitry Andric             "please file a bug and attach the binary listed in this error",
38614f1b3e8SDimitry Andric             so_symbol->GetType(), oso_idx);
387f034231aSEd Maste       else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
388ead24645SDimitry Andric         m_objfile_sp->GetModule()->ReportError(
389e3b55780SDimitry Andric             "N_OSO has incorrect symbol type ({0}) for N_OSO "
390e3b55780SDimitry Andric             "symbol[{1}], "
39114f1b3e8SDimitry Andric             "please file a bug and attach the binary listed in this error",
39214f1b3e8SDimitry Andric             oso_symbol->GetType(), oso_idx);
393f034231aSEd Maste     }
394f034231aSEd Maste   }
395f034231aSEd Maste }
396f034231aSEd Maste 
GetModuleByOSOIndex(uint32_t oso_idx)39714f1b3e8SDimitry Andric Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
398f034231aSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
399f034231aSEd Maste   if (oso_idx < cu_count)
400f034231aSEd Maste     return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
4015f29bb8aSDimitry Andric   return nullptr;
402f034231aSEd Maste }
403f034231aSEd Maste 
GetModuleByCompUnitInfo(CompileUnitInfo * comp_unit_info)40414f1b3e8SDimitry Andric Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
40514f1b3e8SDimitry Andric     CompileUnitInfo *comp_unit_info) {
40614f1b3e8SDimitry Andric   if (!comp_unit_info->oso_sp) {
407f73363f1SDimitry Andric     auto pos = m_oso_map.find(
408f73363f1SDimitry Andric         {comp_unit_info->oso_path, comp_unit_info->oso_mod_time});
40914f1b3e8SDimitry Andric     if (pos != m_oso_map.end()) {
410f034231aSEd Maste       comp_unit_info->oso_sp = pos->second;
41114f1b3e8SDimitry Andric     } else {
412f034231aSEd Maste       ObjectFile *obj_file = GetObjectFile();
4135f29bb8aSDimitry Andric       comp_unit_info->oso_sp = std::make_shared<OSOInfo>();
414f73363f1SDimitry Andric       m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] =
415f73363f1SDimitry Andric           comp_unit_info->oso_sp;
416f034231aSEd Maste       const char *oso_path = comp_unit_info->oso_path.GetCString();
41794994d37SDimitry Andric       FileSpec oso_file(oso_path);
418f034231aSEd Maste       ConstString oso_object;
41994994d37SDimitry Andric       if (FileSystem::Instance().Exists(oso_file)) {
42094994d37SDimitry Andric         // The modification time returned by the FS can have a higher precision
42194994d37SDimitry Andric         // than the one from the CU.
42294994d37SDimitry Andric         auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
42394994d37SDimitry Andric             FileSystem::Instance().GetModificationTime(oso_file));
424ead24645SDimitry Andric         // A timestamp of 0 means that the linker was in deterministic mode. In
425ead24645SDimitry Andric         // that case, we should skip the check against the filesystem last
426ead24645SDimitry Andric         // modification timestamp, since it will never match.
427ead24645SDimitry Andric         if (comp_unit_info->oso_mod_time != llvm::sys::TimePoint<>() &&
428ead24645SDimitry Andric             oso_mod_time != comp_unit_info->oso_mod_time) {
429e3b55780SDimitry Andric           comp_unit_info->oso_load_error.SetErrorStringWithFormat(
430e3b55780SDimitry Andric               "debug map object file \"%s\" changed (actual: 0x%8.8x, debug "
431e3b55780SDimitry Andric               "map: 0x%8.8x) since this executable was linked, debug info "
432e3b55780SDimitry Andric               "will not be loaded", oso_file.GetPath().c_str(),
433e3b55780SDimitry Andric               (uint32_t)llvm::sys::toTimeT(oso_mod_time),
434e3b55780SDimitry Andric               (uint32_t)llvm::sys::toTimeT(comp_unit_info->oso_mod_time));
43514f1b3e8SDimitry Andric           obj_file->GetModule()->ReportError(
436e3b55780SDimitry Andric               "{0}", comp_unit_info->oso_load_error.AsCString());
4375f29bb8aSDimitry Andric           return nullptr;
438f034231aSEd Maste         }
439f034231aSEd Maste 
44014f1b3e8SDimitry Andric       } else {
441f034231aSEd Maste         const bool must_exist = true;
442f034231aSEd Maste 
44314f1b3e8SDimitry Andric         if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file,
44414f1b3e8SDimitry Andric                                                     oso_object, must_exist)) {
445e3b55780SDimitry Andric           comp_unit_info->oso_load_error.SetErrorStringWithFormat(
446e3b55780SDimitry Andric               "debug map object file \"%s\" containing debug info does not "
447e3b55780SDimitry Andric               "exist, debug info will not be loaded",
448e3b55780SDimitry Andric               comp_unit_info->oso_path.GetCString());
4495f29bb8aSDimitry Andric           return nullptr;
450f034231aSEd Maste         }
451f034231aSEd Maste       }
452f73363f1SDimitry Andric       // Always create a new module for .o files. Why? Because we use the debug
453f73363f1SDimitry Andric       // map, to add new sections to each .o file and even though a .o file
454f73363f1SDimitry Andric       // might not have changed, the sections that get added to the .o file can
455f73363f1SDimitry Andric       // change.
4560cac4ca3SEd Maste       ArchSpec oso_arch;
4570cac4ca3SEd Maste       // Only adopt the architecture from the module (not the vendor or OS)
458f73363f1SDimitry Andric       // since .o files for "i386-apple-ios" will historically show up as "i386
459f73363f1SDimitry Andric       // -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or
460f73363f1SDimitry Andric       // LC_VERSION_MIN_IPHONEOS load command...
461ead24645SDimitry Andric       oso_arch.SetTriple(m_objfile_sp->GetModule()
46214f1b3e8SDimitry Andric                              ->GetArchitecture()
46314f1b3e8SDimitry Andric                              .GetTriple()
46414f1b3e8SDimitry Andric                              .getArchName()
46514f1b3e8SDimitry Andric                              .str()
46614f1b3e8SDimitry Andric                              .c_str());
4675f29bb8aSDimitry Andric       comp_unit_info->oso_sp->module_sp = std::make_shared<DebugMapModule>(
46814f1b3e8SDimitry Andric           obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file,
469b1c73532SDimitry Andric           oso_arch, oso_object, 0,
4705f29bb8aSDimitry Andric           oso_object ? comp_unit_info->oso_mod_time : llvm::sys::TimePoint<>());
471e3b55780SDimitry Andric 
4727fa27ce4SDimitry Andric       if (oso_object && !comp_unit_info->oso_sp->module_sp->GetObjectFile() &&
4737fa27ce4SDimitry Andric           FileSystem::Instance().Exists(oso_file)) {
474e3b55780SDimitry Andric         // If we are loading a .o file from a .a file the "oso_object" will
475e3b55780SDimitry Andric         // have a valid value name and if the .a file exists, either the .o
476e3b55780SDimitry Andric         // file didn't exist in the .a file or the mod time didn't match.
477e3b55780SDimitry Andric         comp_unit_info->oso_load_error.SetErrorStringWithFormat(
478e3b55780SDimitry Andric             "\"%s\" object from the \"%s\" archive: "
479e3b55780SDimitry Andric             "either the .o file doesn't exist in the archive or the "
480e3b55780SDimitry Andric             "modification time (0x%8.8x) of the .o file doesn't match",
481e3b55780SDimitry Andric             oso_object.AsCString(), oso_file.GetPath().c_str(),
482e3b55780SDimitry Andric             (uint32_t)llvm::sys::toTimeT(comp_unit_info->oso_mod_time));
483e3b55780SDimitry Andric       }
484e3b55780SDimitry Andric     }
485f034231aSEd Maste   }
486f034231aSEd Maste   if (comp_unit_info->oso_sp)
487f034231aSEd Maste     return comp_unit_info->oso_sp->module_sp.get();
4885f29bb8aSDimitry Andric   return nullptr;
489f034231aSEd Maste }
490f034231aSEd Maste 
GetFileSpecForSO(uint32_t oso_idx,FileSpec & file_spec)49114f1b3e8SDimitry Andric bool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx,
49214f1b3e8SDimitry Andric                                                FileSpec &file_spec) {
49314f1b3e8SDimitry Andric   if (oso_idx < m_compile_unit_infos.size()) {
49414f1b3e8SDimitry Andric     if (m_compile_unit_infos[oso_idx].so_file) {
495f034231aSEd Maste       file_spec = m_compile_unit_infos[oso_idx].so_file;
496f034231aSEd Maste       return true;
497f034231aSEd Maste     }
498f034231aSEd Maste   }
499f034231aSEd Maste   return false;
500f034231aSEd Maste }
501f034231aSEd Maste 
GetObjectFileByOSOIndex(uint32_t oso_idx)50214f1b3e8SDimitry Andric ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) {
503f034231aSEd Maste   Module *oso_module = GetModuleByOSOIndex(oso_idx);
504f034231aSEd Maste   if (oso_module)
505f034231aSEd Maste     return oso_module->GetObjectFile();
5065f29bb8aSDimitry Andric   return nullptr;
507f034231aSEd Maste }
508f034231aSEd Maste 
509f034231aSEd Maste SymbolFileDWARF *
GetSymbolFile(const SymbolContext & sc)51014f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) {
51194994d37SDimitry Andric   return GetSymbolFile(*sc.comp_unit);
51294994d37SDimitry Andric }
51394994d37SDimitry Andric 
51494994d37SDimitry Andric SymbolFileDWARF *
GetSymbolFile(const CompileUnit & comp_unit)51594994d37SDimitry Andric SymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) {
51694994d37SDimitry Andric   CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit);
517f034231aSEd Maste   if (comp_unit_info)
518f034231aSEd Maste     return GetSymbolFileByCompUnitInfo(comp_unit_info);
5195f29bb8aSDimitry Andric   return nullptr;
520f034231aSEd Maste }
521f034231aSEd Maste 
GetObjectFileByCompUnitInfo(CompileUnitInfo * comp_unit_info)52214f1b3e8SDimitry Andric ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo(
52314f1b3e8SDimitry Andric     CompileUnitInfo *comp_unit_info) {
524f034231aSEd Maste   Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
525f034231aSEd Maste   if (oso_module)
526f034231aSEd Maste     return oso_module->GetObjectFile();
5275f29bb8aSDimitry Andric   return nullptr;
528f034231aSEd Maste }
529f034231aSEd Maste 
GetCompUnitInfoIndex(const CompileUnitInfo * comp_unit_info)53014f1b3e8SDimitry Andric uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex(
53114f1b3e8SDimitry Andric     const CompileUnitInfo *comp_unit_info) {
53214f1b3e8SDimitry Andric   if (!m_compile_unit_infos.empty()) {
533f034231aSEd Maste     const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
534f034231aSEd Maste     const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
53514f1b3e8SDimitry Andric     if (first_comp_unit_info <= comp_unit_info &&
53614f1b3e8SDimitry Andric         comp_unit_info <= last_comp_unit_info)
537f034231aSEd Maste       return comp_unit_info - first_comp_unit_info;
538f034231aSEd Maste   }
539f034231aSEd Maste   return UINT32_MAX;
540f034231aSEd Maste }
541f034231aSEd Maste 
542f034231aSEd Maste SymbolFileDWARF *
GetSymbolFileByOSOIndex(uint32_t oso_idx)54314f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) {
54494994d37SDimitry Andric   unsigned size = m_compile_unit_infos.size();
54594994d37SDimitry Andric   if (oso_idx < size)
546f034231aSEd Maste     return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
5475f29bb8aSDimitry Andric   return nullptr;
548f034231aSEd Maste }
549f034231aSEd Maste 
550f034231aSEd Maste SymbolFileDWARF *
GetSymbolFileAsSymbolFileDWARF(SymbolFile * sym_file)55114f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
55214f1b3e8SDimitry Andric   if (sym_file &&
55314f1b3e8SDimitry Andric       sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
554cfca06d7SDimitry Andric     return static_cast<SymbolFileDWARF *>(sym_file);
5555f29bb8aSDimitry Andric   return nullptr;
556f034231aSEd Maste }
557f034231aSEd Maste 
GetSymbolFileByCompUnitInfo(CompileUnitInfo * comp_unit_info)55814f1b3e8SDimitry Andric SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
55914f1b3e8SDimitry Andric     CompileUnitInfo *comp_unit_info) {
560ead24645SDimitry Andric   if (Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info))
561ead24645SDimitry Andric     return GetSymbolFileAsSymbolFileDWARF(oso_module->GetSymbolFile());
5625f29bb8aSDimitry Andric   return nullptr;
563f034231aSEd Maste }
564f034231aSEd Maste 
CalculateAbilities()56514f1b3e8SDimitry Andric uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
566f034231aSEd Maste   // In order to get the abilities of this plug-in, we look at the list of
567f034231aSEd Maste   // N_OSO entries (object files) from the symbol table and make sure that
568f73363f1SDimitry Andric   // these files exist and also contain valid DWARF. If we get any of that then
569f73363f1SDimitry Andric   // we return the abilities of the first N_OSO's DWARF.
570f034231aSEd Maste 
571f034231aSEd Maste   const uint32_t oso_index_count = GetNumCompileUnits();
57214f1b3e8SDimitry Andric   if (oso_index_count > 0) {
573f034231aSEd Maste     InitOSO();
57414f1b3e8SDimitry Andric     if (!m_compile_unit_infos.empty()) {
57514f1b3e8SDimitry Andric       return SymbolFile::CompileUnits | SymbolFile::Functions |
57614f1b3e8SDimitry Andric              SymbolFile::Blocks | SymbolFile::GlobalVariables |
57714f1b3e8SDimitry Andric              SymbolFile::LocalVariables | SymbolFile::VariableTypes |
578f034231aSEd Maste              SymbolFile::LineTables;
579f034231aSEd Maste     }
580f034231aSEd Maste   }
581f034231aSEd Maste   return 0;
582f034231aSEd Maste }
583f034231aSEd Maste 
CalculateNumCompileUnits()584ead24645SDimitry Andric uint32_t SymbolFileDWARFDebugMap::CalculateNumCompileUnits() {
585f034231aSEd Maste   InitOSO();
586f034231aSEd Maste   return m_compile_unit_infos.size();
587f034231aSEd Maste }
588f034231aSEd Maste 
ParseCompileUnitAtIndex(uint32_t cu_idx)58914f1b3e8SDimitry Andric CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
590f034231aSEd Maste   CompUnitSP comp_unit_sp;
591f034231aSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
592f034231aSEd Maste 
59314f1b3e8SDimitry Andric   if (cu_idx < cu_count) {
594e3b55780SDimitry Andric     auto &cu_info = m_compile_unit_infos[cu_idx];
595e3b55780SDimitry Andric     Module *oso_module = GetModuleByCompUnitInfo(&cu_info);
59614f1b3e8SDimitry Andric     if (oso_module) {
597f034231aSEd Maste       FileSpec so_file_spec;
59814f1b3e8SDimitry Andric       if (GetFileSpecForSO(cu_idx, so_file_spec)) {
599f73363f1SDimitry Andric         // User zero as the ID to match the compile unit at offset zero in each
600e3b55780SDimitry Andric         // .o file.
601f034231aSEd Maste         lldb::user_id_t cu_id = 0;
6024df029ccSDimitry Andric         cu_info.compile_units_sps.push_back(std::make_shared<CompileUnit>(
6034df029ccSDimitry Andric             m_objfile_sp->GetModule(), nullptr,
6044df029ccSDimitry Andric             std::make_shared<SupportFile>(so_file_spec), cu_id,
605e3b55780SDimitry Andric             eLanguageTypeUnknown, eLazyBoolCalculate));
606e3b55780SDimitry Andric         cu_info.id_to_index_map.insert({0, 0});
607e3b55780SDimitry Andric         SetCompileUnitAtIndex(cu_idx, cu_info.compile_units_sps[0]);
608e3b55780SDimitry Andric         // If there's a symbol file also register all the extra compile units.
609e3b55780SDimitry Andric         if (SymbolFileDWARF *oso_symfile =
610e3b55780SDimitry Andric                 GetSymbolFileByCompUnitInfo(&cu_info)) {
611e3b55780SDimitry Andric           auto num_dwarf_units = oso_symfile->DebugInfo().GetNumUnits();
612e3b55780SDimitry Andric           for (size_t i = 0; i < num_dwarf_units; ++i) {
613e3b55780SDimitry Andric             auto *dwarf_unit = oso_symfile->DebugInfo().GetUnitAtIndex(i);
614e3b55780SDimitry Andric             if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(dwarf_unit)) {
615e3b55780SDimitry Andric               // The "main" one was already registered.
616e3b55780SDimitry Andric               if (dwarf_cu->GetID() == 0)
617e3b55780SDimitry Andric                 continue;
618e3b55780SDimitry Andric               cu_info.compile_units_sps.push_back(std::make_shared<CompileUnit>(
6194df029ccSDimitry Andric                   m_objfile_sp->GetModule(), nullptr,
6204df029ccSDimitry Andric                   std::make_shared<SupportFile>(so_file_spec),
621e3b55780SDimitry Andric                   dwarf_cu->GetID(), eLanguageTypeUnknown, eLazyBoolCalculate));
622e3b55780SDimitry Andric               cu_info.id_to_index_map.insert(
623e3b55780SDimitry Andric                   {dwarf_cu->GetID(), cu_info.compile_units_sps.size() - 1});
624f034231aSEd Maste             }
625f034231aSEd Maste           }
626f034231aSEd Maste         }
627e3b55780SDimitry Andric       }
628e3b55780SDimitry Andric     }
629e3b55780SDimitry Andric     if (!cu_info.compile_units_sps.empty())
630e3b55780SDimitry Andric       comp_unit_sp = cu_info.compile_units_sps[0];
631f034231aSEd Maste   }
632f034231aSEd Maste 
633f034231aSEd Maste   return comp_unit_sp;
634f034231aSEd Maste }
635f034231aSEd Maste 
636f034231aSEd Maste SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompUnitInfo(const SymbolContext & sc)63714f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) {
63894994d37SDimitry Andric   return GetCompUnitInfo(*sc.comp_unit);
63994994d37SDimitry Andric }
64094994d37SDimitry Andric 
64194994d37SDimitry Andric SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompUnitInfo(const CompileUnit & comp_unit)64294994d37SDimitry Andric SymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) {
643f034231aSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
64414f1b3e8SDimitry Andric   for (uint32_t i = 0; i < cu_count; ++i) {
645e3b55780SDimitry Andric     auto &id_to_index_map = m_compile_unit_infos[i].id_to_index_map;
646e3b55780SDimitry Andric 
647e3b55780SDimitry Andric     auto it = id_to_index_map.find(comp_unit.GetID());
648e3b55780SDimitry Andric     if (it != id_to_index_map.end() &&
649e3b55780SDimitry Andric         &comp_unit ==
650e3b55780SDimitry Andric             m_compile_unit_infos[i].compile_units_sps[it->getSecond()].get())
651f034231aSEd Maste       return &m_compile_unit_infos[i];
652f034231aSEd Maste   }
6535f29bb8aSDimitry Andric   return nullptr;
654f034231aSEd Maste }
655f034231aSEd Maste 
GetCompUnitInfosForModule(const lldb_private::Module * module,std::vector<CompileUnitInfo * > & cu_infos)65614f1b3e8SDimitry Andric size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
65714f1b3e8SDimitry Andric     const lldb_private::Module *module,
65814f1b3e8SDimitry Andric     std::vector<CompileUnitInfo *> &cu_infos) {
659f034231aSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
66014f1b3e8SDimitry Andric   for (uint32_t i = 0; i < cu_count; ++i) {
661f034231aSEd Maste     if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i]))
662f034231aSEd Maste       cu_infos.push_back(&m_compile_unit_infos[i]);
663f034231aSEd Maste   }
664f034231aSEd Maste   return cu_infos.size();
665f034231aSEd Maste }
666f034231aSEd Maste 
667f034231aSEd Maste lldb::LanguageType
ParseLanguage(CompileUnit & comp_unit)66894994d37SDimitry Andric SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
669ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
67094994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
671f034231aSEd Maste   if (oso_dwarf)
67294994d37SDimitry Andric     return oso_dwarf->ParseLanguage(comp_unit);
673f034231aSEd Maste   return eLanguageTypeUnknown;
674f034231aSEd Maste }
675f034231aSEd Maste 
ParseXcodeSDK(CompileUnit & comp_unit)676cfca06d7SDimitry Andric XcodeSDK SymbolFileDWARFDebugMap::ParseXcodeSDK(CompileUnit &comp_unit) {
677cfca06d7SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
678cfca06d7SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
679cfca06d7SDimitry Andric   if (oso_dwarf)
680cfca06d7SDimitry Andric     return oso_dwarf->ParseXcodeSDK(comp_unit);
681cfca06d7SDimitry Andric   return {};
682cfca06d7SDimitry Andric }
683cfca06d7SDimitry Andric 
6847fa27ce4SDimitry Andric llvm::SmallSet<lldb::LanguageType, 4>
ParseAllLanguages(lldb_private::CompileUnit & comp_unit)6857fa27ce4SDimitry Andric SymbolFileDWARFDebugMap::ParseAllLanguages(
6867fa27ce4SDimitry Andric     lldb_private::CompileUnit &comp_unit) {
6877fa27ce4SDimitry Andric   llvm::SmallSet<lldb::LanguageType, 4> langs;
6887fa27ce4SDimitry Andric   auto *info = GetCompUnitInfo(comp_unit);
6897fa27ce4SDimitry Andric   for (auto &comp_unit : info->compile_units_sps) {
6907fa27ce4SDimitry Andric     langs.insert(comp_unit->GetLanguage());
6917fa27ce4SDimitry Andric   }
6927fa27ce4SDimitry Andric   return langs;
6937fa27ce4SDimitry Andric }
6947fa27ce4SDimitry Andric 
ParseFunctions(CompileUnit & comp_unit)69594994d37SDimitry Andric size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
696ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
69794994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
698f034231aSEd Maste   if (oso_dwarf)
69994994d37SDimitry Andric     return oso_dwarf->ParseFunctions(comp_unit);
700f034231aSEd Maste   return 0;
701f034231aSEd Maste }
702f034231aSEd Maste 
ParseLineTable(CompileUnit & comp_unit)70394994d37SDimitry Andric bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
704ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
70594994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
706f034231aSEd Maste   if (oso_dwarf)
70794994d37SDimitry Andric     return oso_dwarf->ParseLineTable(comp_unit);
708f034231aSEd Maste   return false;
709f034231aSEd Maste }
710f034231aSEd Maste 
ParseDebugMacros(CompileUnit & comp_unit)71194994d37SDimitry Andric bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) {
712ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
71394994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
714e81d9d49SDimitry Andric   if (oso_dwarf)
71594994d37SDimitry Andric     return oso_dwarf->ParseDebugMacros(comp_unit);
716e81d9d49SDimitry Andric   return false;
717e81d9d49SDimitry Andric }
718e81d9d49SDimitry Andric 
ForEachExternalModule(CompileUnit & comp_unit,llvm::DenseSet<lldb_private::SymbolFile * > & visited_symbol_files,llvm::function_ref<bool (Module &)> f)719706b4fc4SDimitry Andric bool SymbolFileDWARFDebugMap::ForEachExternalModule(
720706b4fc4SDimitry Andric     CompileUnit &comp_unit,
721706b4fc4SDimitry Andric     llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
722706b4fc4SDimitry Andric     llvm::function_ref<bool(Module &)> f) {
723ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
724ead24645SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
725ead24645SDimitry Andric   if (oso_dwarf)
726706b4fc4SDimitry Andric     return oso_dwarf->ForEachExternalModule(comp_unit, visited_symbol_files, f);
727706b4fc4SDimitry Andric   return false;
728ead24645SDimitry Andric }
729ead24645SDimitry Andric 
ParseSupportFiles(CompileUnit & comp_unit,SupportFileList & support_files)730aca2e42cSDimitry Andric bool SymbolFileDWARFDebugMap::ParseSupportFiles(
731aca2e42cSDimitry Andric     CompileUnit &comp_unit, SupportFileList &support_files) {
732ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
73394994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
734f034231aSEd Maste   if (oso_dwarf)
73594994d37SDimitry Andric     return oso_dwarf->ParseSupportFiles(comp_unit, support_files);
736f034231aSEd Maste   return false;
737f034231aSEd Maste }
738f034231aSEd Maste 
ParseIsOptimized(CompileUnit & comp_unit)73994994d37SDimitry Andric bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
740ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
74194994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
742f3fbd1c0SDimitry Andric   if (oso_dwarf)
74394994d37SDimitry Andric     return oso_dwarf->ParseIsOptimized(comp_unit);
744f3fbd1c0SDimitry Andric   return false;
745f3fbd1c0SDimitry Andric }
746f3fbd1c0SDimitry Andric 
ParseImportedModules(const SymbolContext & sc,std::vector<SourceModule> & imported_modules)74714f1b3e8SDimitry Andric bool SymbolFileDWARFDebugMap::ParseImportedModules(
7485f29bb8aSDimitry Andric     const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
749ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
7505e95aa85SEd Maste   SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
7515e95aa85SEd Maste   if (oso_dwarf)
7525e95aa85SEd Maste     return oso_dwarf->ParseImportedModules(sc, imported_modules);
7535e95aa85SEd Maste   return false;
7545e95aa85SEd Maste }
755f034231aSEd Maste 
ParseBlocksRecursive(Function & func)75694994d37SDimitry Andric size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
757ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
75894994d37SDimitry Andric   CompileUnit *comp_unit = func.GetCompileUnit();
75994994d37SDimitry Andric   if (!comp_unit)
76094994d37SDimitry Andric     return 0;
76194994d37SDimitry Andric 
76294994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(*comp_unit);
763f034231aSEd Maste   if (oso_dwarf)
76494994d37SDimitry Andric     return oso_dwarf->ParseBlocksRecursive(func);
765f034231aSEd Maste   return 0;
766f034231aSEd Maste }
767f034231aSEd Maste 
ParseTypes(CompileUnit & comp_unit)76894994d37SDimitry Andric size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
769ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
77094994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
771f034231aSEd Maste   if (oso_dwarf)
77294994d37SDimitry Andric     return oso_dwarf->ParseTypes(comp_unit);
773f034231aSEd Maste   return 0;
774f034231aSEd Maste }
775f034231aSEd Maste 
776f034231aSEd Maste size_t
ParseVariablesForContext(const SymbolContext & sc)77714f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
778ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
779f034231aSEd Maste   SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
780f034231aSEd Maste   if (oso_dwarf)
781f034231aSEd Maste     return oso_dwarf->ParseVariablesForContext(sc);
782f034231aSEd Maste   return 0;
783f034231aSEd Maste }
784f034231aSEd Maste 
ResolveTypeUID(lldb::user_id_t type_uid)78514f1b3e8SDimitry Andric Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
786ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
787f034231aSEd Maste   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
788f034231aSEd Maste   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
789f034231aSEd Maste   if (oso_dwarf)
790f034231aSEd Maste     return oso_dwarf->ResolveTypeUID(type_uid);
7915f29bb8aSDimitry Andric   return nullptr;
792f034231aSEd Maste }
793f034231aSEd Maste 
794e3b55780SDimitry Andric std::optional<SymbolFile::ArrayInfo>
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)79594994d37SDimitry Andric SymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID(
79694994d37SDimitry Andric     lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
79794994d37SDimitry Andric   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
79894994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
79994994d37SDimitry Andric   if (oso_dwarf)
80094994d37SDimitry Andric     return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx);
801e3b55780SDimitry Andric   return std::nullopt;
80294994d37SDimitry Andric }
80394994d37SDimitry Andric 
CompleteType(CompilerType & compiler_type)80414f1b3e8SDimitry Andric bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
805e81d9d49SDimitry Andric   bool success = false;
80614f1b3e8SDimitry Andric   if (compiler_type) {
807ac9a064cSDimitry Andric     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
808b1c73532SDimitry Andric       if (oso_dwarf->HasForwardDeclForCompilerType(compiler_type)) {
809e81d9d49SDimitry Andric         oso_dwarf->CompleteType(compiler_type);
810e81d9d49SDimitry Andric         success = true;
811ac9a064cSDimitry Andric         return IterationAction::Stop;
812e81d9d49SDimitry Andric       }
813ac9a064cSDimitry Andric       return IterationAction::Continue;
814e81d9d49SDimitry Andric     });
815e81d9d49SDimitry Andric   }
816e81d9d49SDimitry Andric   return success;
817f034231aSEd Maste }
818f034231aSEd Maste 
81994994d37SDimitry Andric uint32_t
ResolveSymbolContext(const Address & exe_so_addr,SymbolContextItem resolve_scope,SymbolContext & sc)82094994d37SDimitry Andric SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
82194994d37SDimitry Andric                                               SymbolContextItem resolve_scope,
82294994d37SDimitry Andric                                               SymbolContext &sc) {
823ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
824f034231aSEd Maste   uint32_t resolved_flags = 0;
825ead24645SDimitry Andric   Symtab *symtab = m_objfile_sp->GetSymtab();
82614f1b3e8SDimitry Andric   if (symtab) {
827f034231aSEd Maste     const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
828f034231aSEd Maste 
82914f1b3e8SDimitry Andric     const DebugMap::Entry *debug_map_entry =
83014f1b3e8SDimitry Andric         m_debug_map.FindEntryThatContains(exe_file_addr);
83114f1b3e8SDimitry Andric     if (debug_map_entry) {
832f034231aSEd Maste 
83314f1b3e8SDimitry Andric       sc.symbol =
83414f1b3e8SDimitry Andric           symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
835f034231aSEd Maste 
8365f29bb8aSDimitry Andric       if (sc.symbol != nullptr) {
837f034231aSEd Maste         resolved_flags |= eSymbolContextSymbol;
838f034231aSEd Maste 
839f034231aSEd Maste         uint32_t oso_idx = 0;
84014f1b3e8SDimitry Andric         CompileUnitInfo *comp_unit_info =
84114f1b3e8SDimitry Andric             GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx);
84214f1b3e8SDimitry Andric         if (comp_unit_info) {
843f034231aSEd Maste           comp_unit_info->GetFileRangeMap(this);
844f034231aSEd Maste           Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
84514f1b3e8SDimitry Andric           if (oso_module) {
84614f1b3e8SDimitry Andric             lldb::addr_t oso_file_addr =
84714f1b3e8SDimitry Andric                 exe_file_addr - debug_map_entry->GetRangeBase() +
84814f1b3e8SDimitry Andric                 debug_map_entry->data.GetOSOFileAddress();
849f034231aSEd Maste             Address oso_so_addr;
85014f1b3e8SDimitry Andric             if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) {
851ac9a064cSDimitry Andric               if (SymbolFile *sym_file = oso_module->GetSymbolFile()) {
852ac9a064cSDimitry Andric                 resolved_flags |= sym_file->ResolveSymbolContext(
85314f1b3e8SDimitry Andric                     oso_so_addr, resolve_scope, sc);
854ac9a064cSDimitry Andric               } else {
855ac9a064cSDimitry Andric                 ObjectFile *obj_file = GetObjectFile();
856ac9a064cSDimitry Andric                 LLDB_LOG(GetLog(DWARFLog::DebugMap),
857ac9a064cSDimitry Andric                          "Failed to get symfile for OSO: {0} in module: {1}",
858ac9a064cSDimitry Andric                          oso_module->GetFileSpec(),
859ac9a064cSDimitry Andric                          obj_file ? obj_file->GetFileSpec()
860ac9a064cSDimitry Andric                                   : FileSpec("unknown"));
861ac9a064cSDimitry Andric               }
862f034231aSEd Maste             }
863f034231aSEd Maste           }
864f034231aSEd Maste         }
865f034231aSEd Maste       }
866f034231aSEd Maste     }
867f034231aSEd Maste   }
868f034231aSEd Maste   return resolved_flags;
869f034231aSEd Maste }
870f034231aSEd Maste 
ResolveSymbolContext(const SourceLocationSpec & src_location_spec,SymbolContextItem resolve_scope,SymbolContextList & sc_list)87114f1b3e8SDimitry Andric uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
872344a3780SDimitry Andric     const SourceLocationSpec &src_location_spec,
87394994d37SDimitry Andric     SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
874ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
875f034231aSEd Maste   const uint32_t initial = sc_list.GetSize();
876f034231aSEd Maste   const uint32_t cu_count = GetNumCompileUnits();
877f034231aSEd Maste 
87814f1b3e8SDimitry Andric   for (uint32_t i = 0; i < cu_count; ++i) {
879f73363f1SDimitry Andric     // If we are checking for inlines, then we need to look through all compile
880f73363f1SDimitry Andric     // units no matter if "file_spec" matches.
881344a3780SDimitry Andric     bool resolve = src_location_spec.GetCheckInlines();
882f034231aSEd Maste 
88314f1b3e8SDimitry Andric     if (!resolve) {
884f034231aSEd Maste       FileSpec so_file_spec;
885706b4fc4SDimitry Andric       if (GetFileSpecForSO(i, so_file_spec))
886344a3780SDimitry Andric         resolve =
887344a3780SDimitry Andric             FileSpec::Match(src_location_spec.GetFileSpec(), so_file_spec);
888f034231aSEd Maste     }
88914f1b3e8SDimitry Andric     if (resolve) {
890f034231aSEd Maste       SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i);
891f034231aSEd Maste       if (oso_dwarf)
892344a3780SDimitry Andric         oso_dwarf->ResolveSymbolContext(src_location_spec, resolve_scope,
893344a3780SDimitry Andric                                         sc_list);
894f034231aSEd Maste     }
895f034231aSEd Maste   }
896f034231aSEd Maste   return sc_list.GetSize() - initial;
897f034231aSEd Maste }
898f034231aSEd Maste 
PrivateFindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,const std::vector<uint32_t> & indexes,uint32_t max_matches,VariableList & variables)899ead24645SDimitry Andric void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
900cfca06d7SDimitry Andric     ConstString name, const CompilerDeclContext &parent_decl_ctx,
90114f1b3e8SDimitry Andric     const std::vector<uint32_t>
90214f1b3e8SDimitry Andric         &indexes, // Indexes into the symbol table that match "name"
90394994d37SDimitry Andric     uint32_t max_matches, VariableList &variables) {
904f034231aSEd Maste   const size_t match_count = indexes.size();
90514f1b3e8SDimitry Andric   for (size_t i = 0; i < match_count; ++i) {
906f034231aSEd Maste     uint32_t oso_idx;
90714f1b3e8SDimitry Andric     CompileUnitInfo *comp_unit_info =
90814f1b3e8SDimitry Andric         GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx);
90914f1b3e8SDimitry Andric     if (comp_unit_info) {
910f034231aSEd Maste       SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
91114f1b3e8SDimitry Andric       if (oso_dwarf) {
912ead24645SDimitry Andric         oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
913ead24645SDimitry Andric                                        variables);
914f034231aSEd Maste         if (variables.GetSize() > max_matches)
915f034231aSEd Maste           break;
916f034231aSEd Maste       }
917f034231aSEd Maste     }
918f034231aSEd Maste   }
919f034231aSEd Maste }
920f034231aSEd Maste 
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,uint32_t max_matches,VariableList & variables)921ead24645SDimitry Andric void SymbolFileDWARFDebugMap::FindGlobalVariables(
922cfca06d7SDimitry Andric     ConstString name, const CompilerDeclContext &parent_decl_ctx,
923f73363f1SDimitry Andric     uint32_t max_matches, VariableList &variables) {
924ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
925f034231aSEd Maste   uint32_t total_matches = 0;
9265e95aa85SEd Maste 
927ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
928ead24645SDimitry Andric     const uint32_t old_size = variables.GetSize();
929ead24645SDimitry Andric     oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
930ead24645SDimitry Andric                                    variables);
931ead24645SDimitry Andric     const uint32_t oso_matches = variables.GetSize() - old_size;
93214f1b3e8SDimitry Andric     if (oso_matches > 0) {
933f034231aSEd Maste       total_matches += oso_matches;
934f034231aSEd Maste 
935f034231aSEd Maste       // Are we getting all matches?
936f034231aSEd Maste       if (max_matches == UINT32_MAX)
937ac9a064cSDimitry Andric         return IterationAction::Continue; // Yep, continue getting everything
938f034231aSEd Maste 
939f034231aSEd Maste       // If we have found enough matches, lets get out
940f034231aSEd Maste       if (max_matches >= total_matches)
941ac9a064cSDimitry Andric         return IterationAction::Stop;
942f034231aSEd Maste 
943f73363f1SDimitry Andric       // Update the max matches for any subsequent calls to find globals in any
944f73363f1SDimitry Andric       // other object files with DWARF
945f034231aSEd Maste       max_matches -= oso_matches;
946f034231aSEd Maste     }
9475e95aa85SEd Maste 
948ac9a064cSDimitry Andric     return IterationAction::Continue;
9495e95aa85SEd Maste   });
950f034231aSEd Maste }
951f034231aSEd Maste 
FindGlobalVariables(const RegularExpression & regex,uint32_t max_matches,VariableList & variables)952ead24645SDimitry Andric void SymbolFileDWARFDebugMap::FindGlobalVariables(
953ead24645SDimitry Andric     const RegularExpression &regex, uint32_t max_matches,
95414f1b3e8SDimitry Andric     VariableList &variables) {
955ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
956f034231aSEd Maste   uint32_t total_matches = 0;
957ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
958ead24645SDimitry Andric     const uint32_t old_size = variables.GetSize();
959f73363f1SDimitry Andric     oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
960ead24645SDimitry Andric 
961ead24645SDimitry Andric     const uint32_t oso_matches = variables.GetSize() - old_size;
96214f1b3e8SDimitry Andric     if (oso_matches > 0) {
963f034231aSEd Maste       total_matches += oso_matches;
964f034231aSEd Maste 
965f034231aSEd Maste       // Are we getting all matches?
966f034231aSEd Maste       if (max_matches == UINT32_MAX)
967ac9a064cSDimitry Andric         return IterationAction::Continue; // Yep, continue getting everything
968f034231aSEd Maste 
969f034231aSEd Maste       // If we have found enough matches, lets get out
970f034231aSEd Maste       if (max_matches >= total_matches)
971ac9a064cSDimitry Andric         return IterationAction::Stop;
972f034231aSEd Maste 
973f73363f1SDimitry Andric       // Update the max matches for any subsequent calls to find globals in any
974f73363f1SDimitry Andric       // other object files with DWARF
975f034231aSEd Maste       max_matches -= oso_matches;
976f034231aSEd Maste     }
9775e95aa85SEd Maste 
978ac9a064cSDimitry Andric     return IterationAction::Continue;
9795e95aa85SEd Maste   });
980f034231aSEd Maste }
981f034231aSEd Maste 
SymbolContainsSymbolWithIndex(uint32_t * symbol_idx_ptr,const CompileUnitInfo * comp_unit_info)98214f1b3e8SDimitry Andric int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
98314f1b3e8SDimitry Andric     uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
984f034231aSEd Maste   const uint32_t symbol_idx = *symbol_idx_ptr;
985f034231aSEd Maste 
986f034231aSEd Maste   if (symbol_idx < comp_unit_info->first_symbol_index)
987f034231aSEd Maste     return -1;
988f034231aSEd Maste 
989f034231aSEd Maste   if (symbol_idx <= comp_unit_info->last_symbol_index)
990f034231aSEd Maste     return 0;
991f034231aSEd Maste 
992f034231aSEd Maste   return 1;
993f034231aSEd Maste }
994f034231aSEd Maste 
SymbolContainsSymbolWithID(user_id_t * symbol_idx_ptr,const CompileUnitInfo * comp_unit_info)99514f1b3e8SDimitry Andric int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID(
99614f1b3e8SDimitry Andric     user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
997f034231aSEd Maste   const user_id_t symbol_id = *symbol_idx_ptr;
998f034231aSEd Maste 
999f034231aSEd Maste   if (symbol_id < comp_unit_info->first_symbol_id)
1000f034231aSEd Maste     return -1;
1001f034231aSEd Maste 
1002f034231aSEd Maste   if (symbol_id <= comp_unit_info->last_symbol_id)
1003f034231aSEd Maste     return 0;
1004f034231aSEd Maste 
1005f034231aSEd Maste   return 1;
1006f034231aSEd Maste }
1007f034231aSEd Maste 
1008f034231aSEd Maste SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompileUnitInfoForSymbolWithIndex(uint32_t symbol_idx,uint32_t * oso_idx_ptr)100914f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex(
101014f1b3e8SDimitry Andric     uint32_t symbol_idx, uint32_t *oso_idx_ptr) {
1011f034231aSEd Maste   const uint32_t oso_index_count = m_compile_unit_infos.size();
10125f29bb8aSDimitry Andric   CompileUnitInfo *comp_unit_info = nullptr;
101314f1b3e8SDimitry Andric   if (oso_index_count) {
101414f1b3e8SDimitry Andric     comp_unit_info = (CompileUnitInfo *)bsearch(
101514f1b3e8SDimitry Andric         &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
1016f034231aSEd Maste         sizeof(CompileUnitInfo),
1017f034231aSEd Maste         (ComparisonFunction)SymbolContainsSymbolWithIndex);
1018f034231aSEd Maste   }
1019f034231aSEd Maste 
102014f1b3e8SDimitry Andric   if (oso_idx_ptr) {
10215f29bb8aSDimitry Andric     if (comp_unit_info != nullptr)
1022f034231aSEd Maste       *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1023f034231aSEd Maste     else
1024f034231aSEd Maste       *oso_idx_ptr = UINT32_MAX;
1025f034231aSEd Maste   }
1026f034231aSEd Maste   return comp_unit_info;
1027f034231aSEd Maste }
1028f034231aSEd Maste 
1029f034231aSEd Maste SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompileUnitInfoForSymbolWithID(user_id_t symbol_id,uint32_t * oso_idx_ptr)103014f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
103114f1b3e8SDimitry Andric     user_id_t symbol_id, uint32_t *oso_idx_ptr) {
1032f034231aSEd Maste   const uint32_t oso_index_count = m_compile_unit_infos.size();
10335f29bb8aSDimitry Andric   CompileUnitInfo *comp_unit_info = nullptr;
103414f1b3e8SDimitry Andric   if (oso_index_count) {
103514f1b3e8SDimitry Andric     comp_unit_info = (CompileUnitInfo *)::bsearch(
103614f1b3e8SDimitry Andric         &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
1037f034231aSEd Maste         sizeof(CompileUnitInfo),
1038f034231aSEd Maste         (ComparisonFunction)SymbolContainsSymbolWithID);
1039f034231aSEd Maste   }
1040f034231aSEd Maste 
104114f1b3e8SDimitry Andric   if (oso_idx_ptr) {
10425f29bb8aSDimitry Andric     if (comp_unit_info != nullptr)
1043f034231aSEd Maste       *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1044f034231aSEd Maste     else
1045f034231aSEd Maste       *oso_idx_ptr = UINT32_MAX;
1046f034231aSEd Maste   }
1047f034231aSEd Maste   return comp_unit_info;
1048f034231aSEd Maste }
1049f034231aSEd Maste 
RemoveFunctionsWithModuleNotEqualTo(const ModuleSP & module_sp,SymbolContextList & sc_list,uint32_t start_idx)105014f1b3e8SDimitry Andric static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
105114f1b3e8SDimitry Andric                                                 SymbolContextList &sc_list,
105214f1b3e8SDimitry Andric                                                 uint32_t start_idx) {
1053f73363f1SDimitry Andric   // We found functions in .o files. Not all functions in the .o files will
1054f73363f1SDimitry Andric   // have made it into the final output file. The ones that did make it into
1055f73363f1SDimitry Andric   // the final output file will have a section whose module matches the module
1056f73363f1SDimitry Andric   // from the ObjectFile for this SymbolFile. When the modules don't match,
1057f73363f1SDimitry Andric   // then we have something that was in a .o file, but doesn't map to anything
1058f73363f1SDimitry Andric   // in the final executable.
1059f034231aSEd Maste   uint32_t i = start_idx;
106014f1b3e8SDimitry Andric   while (i < sc_list.GetSize()) {
1061f034231aSEd Maste     SymbolContext sc;
1062f034231aSEd Maste     sc_list.GetContextAtIndex(i, sc);
106314f1b3e8SDimitry Andric     if (sc.function) {
106414f1b3e8SDimitry Andric       const SectionSP section_sp(
106514f1b3e8SDimitry Andric           sc.function->GetAddressRange().GetBaseAddress().GetSection());
106614f1b3e8SDimitry Andric       if (section_sp->GetModule() != module_sp) {
1067f034231aSEd Maste         sc_list.RemoveContextAtIndex(i);
1068f034231aSEd Maste         continue;
1069f034231aSEd Maste       }
1070f034231aSEd Maste     }
1071f034231aSEd Maste     ++i;
1072f034231aSEd Maste   }
1073f034231aSEd Maste }
1074f034231aSEd Maste 
FindFunctions(const Module::LookupInfo & lookup_info,const CompilerDeclContext & parent_decl_ctx,bool include_inlines,SymbolContextList & sc_list)1075ead24645SDimitry Andric void SymbolFileDWARFDebugMap::FindFunctions(
1076e3b55780SDimitry Andric     const Module::LookupInfo &lookup_info,
1077e3b55780SDimitry Andric     const CompilerDeclContext &parent_decl_ctx, bool include_inlines,
107814f1b3e8SDimitry Andric     SymbolContextList &sc_list) {
1079ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1080b60736ecSDimitry Andric   LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1081e3b55780SDimitry Andric                      lookup_info.GetLookupName().GetCString());
1082f034231aSEd Maste 
1083ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
1084f034231aSEd Maste     uint32_t sc_idx = sc_list.GetSize();
1085e3b55780SDimitry Andric     oso_dwarf->FindFunctions(lookup_info, parent_decl_ctx, include_inlines,
1086e3b55780SDimitry Andric                              sc_list);
1087ead24645SDimitry Andric     if (!sc_list.IsEmpty()) {
1088ead24645SDimitry Andric       RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
108914f1b3e8SDimitry Andric                                           sc_idx);
1090f034231aSEd Maste     }
1091ac9a064cSDimitry Andric     return IterationAction::Continue;
10925e95aa85SEd Maste   });
1093f034231aSEd Maste }
1094f034231aSEd Maste 
FindFunctions(const RegularExpression & regex,bool include_inlines,SymbolContextList & sc_list)1095ead24645SDimitry Andric void SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
109614f1b3e8SDimitry Andric                                             bool include_inlines,
109714f1b3e8SDimitry Andric                                             SymbolContextList &sc_list) {
1098ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1099b60736ecSDimitry Andric   LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
110014f1b3e8SDimitry Andric                      regex.GetText().str().c_str());
1101f034231aSEd Maste 
1102ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
1103f034231aSEd Maste     uint32_t sc_idx = sc_list.GetSize();
1104f034231aSEd Maste 
1105ead24645SDimitry Andric     oso_dwarf->FindFunctions(regex, include_inlines, sc_list);
1106ead24645SDimitry Andric     if (!sc_list.IsEmpty()) {
1107ead24645SDimitry Andric       RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
110814f1b3e8SDimitry Andric                                           sc_idx);
1109f034231aSEd Maste     }
1110ac9a064cSDimitry Andric     return IterationAction::Continue;
11115e95aa85SEd Maste   });
1112f034231aSEd Maste }
1113f034231aSEd Maste 
GetTypes(SymbolContextScope * sc_scope,lldb::TypeClass type_mask,TypeList & type_list)1114ead24645SDimitry Andric void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
111594994d37SDimitry Andric                                        lldb::TypeClass type_mask,
111614f1b3e8SDimitry Andric                                        TypeList &type_list) {
1117ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1118b60736ecSDimitry Andric   LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1119f034231aSEd Maste                      type_mask);
1120f034231aSEd Maste 
11215f29bb8aSDimitry Andric   SymbolFileDWARF *oso_dwarf = nullptr;
112214f1b3e8SDimitry Andric   if (sc_scope) {
1123f034231aSEd Maste     SymbolContext sc;
1124f034231aSEd Maste     sc_scope->CalculateSymbolContext(&sc);
1125f034231aSEd Maste 
1126f034231aSEd Maste     CompileUnitInfo *cu_info = GetCompUnitInfo(sc);
112714f1b3e8SDimitry Andric     if (cu_info) {
1128f034231aSEd Maste       oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info);
1129f034231aSEd Maste       if (oso_dwarf)
1130f034231aSEd Maste         oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
1131f034231aSEd Maste     }
113214f1b3e8SDimitry Andric   } else {
1133ac9a064cSDimitry Andric     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
1134f034231aSEd Maste       oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
1135ac9a064cSDimitry Andric       return IterationAction::Continue;
11365e95aa85SEd Maste     });
1137f034231aSEd Maste   }
1138f034231aSEd Maste }
1139f034231aSEd Maste 
1140706b4fc4SDimitry Andric std::vector<std::unique_ptr<lldb_private::CallEdge>>
ParseCallEdgesInFunction(lldb_private::UserID func_id)11417fa27ce4SDimitry Andric SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(
11427fa27ce4SDimitry Andric     lldb_private::UserID func_id) {
114394994d37SDimitry Andric   uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID());
114494994d37SDimitry Andric   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
114594994d37SDimitry Andric   if (oso_dwarf)
114694994d37SDimitry Andric     return oso_dwarf->ParseCallEdgesInFunction(func_id);
114794994d37SDimitry Andric   return {};
114894994d37SDimitry Andric }
114994994d37SDimitry Andric 
FindDefinitionDIE(const DWARFDIE & die)1150ac9a064cSDimitry Andric DWARFDIE SymbolFileDWARFDebugMap::FindDefinitionDIE(const DWARFDIE &die) {
1151ac9a064cSDimitry Andric   DWARFDIE result;
1152ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
1153ac9a064cSDimitry Andric     result = oso_dwarf->FindDefinitionDIE(die);
1154ac9a064cSDimitry Andric     return result ? IterationAction::Stop : IterationAction::Continue;
11555e95aa85SEd Maste   });
1156ac9a064cSDimitry Andric   return result;
1157f034231aSEd Maste }
1158f034231aSEd Maste 
Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF * skip_dwarf_oso)115914f1b3e8SDimitry Andric bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
116014f1b3e8SDimitry Andric     SymbolFileDWARF *skip_dwarf_oso) {
116114f1b3e8SDimitry Andric   if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
1162f034231aSEd Maste     m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
1163ac9a064cSDimitry Andric     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
116414f1b3e8SDimitry Andric       if (skip_dwarf_oso != oso_dwarf &&
11655f29bb8aSDimitry Andric           oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(nullptr)) {
1166f034231aSEd Maste         m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
1167ac9a064cSDimitry Andric         return IterationAction::Stop;
1168f034231aSEd Maste       }
1169ac9a064cSDimitry Andric       return IterationAction::Continue;
11705e95aa85SEd Maste     });
1171f034231aSEd Maste   }
1172f034231aSEd Maste   return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1173f034231aSEd Maste }
1174f034231aSEd Maste 
FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE & die,ConstString type_name,bool must_be_implementation)117514f1b3e8SDimitry Andric TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
11765f29bb8aSDimitry Andric     const DWARFDIE &die, ConstString type_name,
117714f1b3e8SDimitry Andric     bool must_be_implementation) {
1178f73363f1SDimitry Andric   // If we have a debug map, we will have an Objective-C symbol whose name is
11795e95aa85SEd Maste   // the type name and whose type is eSymbolTypeObjCClass. If we can find that
11805e95aa85SEd Maste   // symbol and find its containing parent, we can locate the .o file that will
118114f1b3e8SDimitry Andric   // contain the implementation definition since it will be scoped inside the
1182f73363f1SDimitry Andric   // N_SO and we can then locate the SymbolFileDWARF that corresponds to that
1183f73363f1SDimitry Andric   // N_SO.
11845f29bb8aSDimitry Andric   SymbolFileDWARF *oso_dwarf = nullptr;
1185f034231aSEd Maste   TypeSP type_sp;
1186ead24645SDimitry Andric   ObjectFile *module_objfile = m_objfile_sp->GetModule()->GetObjectFile();
118714f1b3e8SDimitry Andric   if (module_objfile) {
11885e95aa85SEd Maste     Symtab *symtab = module_objfile->GetSymtab();
118914f1b3e8SDimitry Andric     if (symtab) {
119014f1b3e8SDimitry Andric       Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
119114f1b3e8SDimitry Andric           type_name, eSymbolTypeObjCClass, Symtab::eDebugAny,
119214f1b3e8SDimitry Andric           Symtab::eVisibilityAny);
119314f1b3e8SDimitry Andric       if (objc_class_symbol) {
119414f1b3e8SDimitry Andric         // Get the N_SO symbol that contains the objective C class symbol as
1195f73363f1SDimitry Andric         // this should be the .o file that contains the real definition...
11965e95aa85SEd Maste         const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
11975e95aa85SEd Maste 
119814f1b3e8SDimitry Andric         if (source_file_symbol &&
119914f1b3e8SDimitry Andric             source_file_symbol->GetType() == eSymbolTypeSourceFile) {
120014f1b3e8SDimitry Andric           const uint32_t source_file_symbol_idx =
120114f1b3e8SDimitry Andric               symtab->GetIndexForSymbol(source_file_symbol);
120214f1b3e8SDimitry Andric           if (source_file_symbol_idx != UINT32_MAX) {
120314f1b3e8SDimitry Andric             CompileUnitInfo *compile_unit_info =
120414f1b3e8SDimitry Andric                 GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx,
12055f29bb8aSDimitry Andric                                                      nullptr);
120614f1b3e8SDimitry Andric             if (compile_unit_info) {
12075e95aa85SEd Maste               oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info);
120814f1b3e8SDimitry Andric               if (oso_dwarf) {
120914f1b3e8SDimitry Andric                 TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
121014f1b3e8SDimitry Andric                     die, type_name, must_be_implementation));
121114f1b3e8SDimitry Andric                 if (type_sp) {
1212f034231aSEd Maste                   return type_sp;
1213f034231aSEd Maste                 }
12145e95aa85SEd Maste               }
12155e95aa85SEd Maste             }
12165e95aa85SEd Maste           }
12175e95aa85SEd Maste         }
12185e95aa85SEd Maste       }
12195e95aa85SEd Maste     }
12205e95aa85SEd Maste   }
12215e95aa85SEd Maste 
122214f1b3e8SDimitry Andric   // Only search all .o files for the definition if we don't need the
1223f73363f1SDimitry Andric   // implementation because otherwise, with a valid debug map we should have
1224f73363f1SDimitry Andric   // the ObjC class symbol and the code above should have found it.
122594994d37SDimitry Andric   if (!must_be_implementation) {
12265e95aa85SEd Maste     TypeSP type_sp;
12275e95aa85SEd Maste 
1228ac9a064cSDimitry Andric     ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
122914f1b3e8SDimitry Andric       type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
123014f1b3e8SDimitry Andric           die, type_name, must_be_implementation);
1231ac9a064cSDimitry Andric       return type_sp ? IterationAction::Stop : IterationAction::Continue;
12325e95aa85SEd Maste     });
12335e95aa85SEd Maste 
12345e95aa85SEd Maste     return type_sp;
12355e95aa85SEd Maste   }
12365e95aa85SEd Maste   return TypeSP();
12375e95aa85SEd Maste }
1238f034231aSEd Maste 
FindTypes(const TypeQuery & query,TypeResults & results)1239312c0ed1SDimitry Andric void SymbolFileDWARFDebugMap::FindTypes(const TypeQuery &query,
1240312c0ed1SDimitry Andric                                         TypeResults &results) {
1241ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1242ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
1243312c0ed1SDimitry Andric     oso_dwarf->FindTypes(query, results);
1244ac9a064cSDimitry Andric     return results.Done(query) ? IterationAction::Stop
1245ac9a064cSDimitry Andric                                : IterationAction::Continue;
1246706b4fc4SDimitry Andric   });
1247706b4fc4SDimitry Andric }
1248706b4fc4SDimitry Andric 
FindNamespace(lldb_private::ConstString name,const CompilerDeclContext & parent_decl_ctx,bool only_root_namespaces)124914f1b3e8SDimitry Andric CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
12507fa27ce4SDimitry Andric     lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx,
12517fa27ce4SDimitry Andric     bool only_root_namespaces) {
1252ead24645SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1253e81d9d49SDimitry Andric   CompilerDeclContext matching_namespace;
1254f034231aSEd Maste 
1255ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
12567fa27ce4SDimitry Andric     matching_namespace =
12577fa27ce4SDimitry Andric         oso_dwarf->FindNamespace(name, parent_decl_ctx, only_root_namespaces);
1258f034231aSEd Maste 
1259ac9a064cSDimitry Andric     return matching_namespace ? IterationAction::Stop
1260ac9a064cSDimitry Andric                               : IterationAction::Continue;
12615e95aa85SEd Maste   });
1262f034231aSEd Maste 
1263f034231aSEd Maste   return matching_namespace;
1264f034231aSEd Maste }
1265f034231aSEd Maste 
DumpClangAST(Stream & s)126694994d37SDimitry Andric void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
1267ac9a064cSDimitry Andric   ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) {
126894994d37SDimitry Andric     oso_dwarf->DumpClangAST(s);
1269cfca06d7SDimitry Andric     // The underlying assumption is that DumpClangAST(...) will obtain the
1270cfca06d7SDimitry Andric     // AST from the underlying TypeSystem and therefore we only need to do
1271cfca06d7SDimitry Andric     // this once and can stop after the first iteration hence we return true.
1272ac9a064cSDimitry Andric     return IterationAction::Stop;
127394994d37SDimitry Andric   });
127494994d37SDimitry Andric }
127594994d37SDimitry Andric 
GetSeparateDebugInfo(lldb_private::StructuredData::Dictionary & d,bool errors_only)1276b1c73532SDimitry Andric bool SymbolFileDWARFDebugMap::GetSeparateDebugInfo(
1277b1c73532SDimitry Andric     lldb_private::StructuredData::Dictionary &d, bool errors_only) {
1278b1c73532SDimitry Andric   StructuredData::Array separate_debug_info_files;
1279b1c73532SDimitry Andric   const uint32_t cu_count = GetNumCompileUnits();
1280b1c73532SDimitry Andric   for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
1281b1c73532SDimitry Andric     const auto &info = m_compile_unit_infos[cu_idx];
1282b1c73532SDimitry Andric     StructuredData::DictionarySP oso_data =
1283b1c73532SDimitry Andric         std::make_shared<StructuredData::Dictionary>();
1284b1c73532SDimitry Andric     oso_data->AddStringItem("so_file", info.so_file.GetPath());
1285b1c73532SDimitry Andric     oso_data->AddStringItem("oso_path", info.oso_path);
1286b1c73532SDimitry Andric     oso_data->AddIntegerItem("oso_mod_time",
1287b1c73532SDimitry Andric                              (uint32_t)llvm::sys::toTimeT(info.oso_mod_time));
1288b1c73532SDimitry Andric 
1289b1c73532SDimitry Andric     bool loaded_successfully = false;
1290b1c73532SDimitry Andric     if (GetModuleByOSOIndex(cu_idx)) {
1291b1c73532SDimitry Andric       // If we have a valid pointer to the module, we successfully
1292b1c73532SDimitry Andric       // loaded the oso if there are no load errors.
1293b1c73532SDimitry Andric       if (!info.oso_load_error.Fail()) {
1294b1c73532SDimitry Andric         loaded_successfully = true;
1295b1c73532SDimitry Andric       }
1296b1c73532SDimitry Andric     }
1297b1c73532SDimitry Andric     if (!loaded_successfully) {
1298b1c73532SDimitry Andric       oso_data->AddStringItem("error", info.oso_load_error.AsCString());
1299b1c73532SDimitry Andric     }
1300b1c73532SDimitry Andric     oso_data->AddBooleanItem("loaded", loaded_successfully);
1301b1c73532SDimitry Andric     if (!errors_only || oso_data->HasKey("error"))
1302b1c73532SDimitry Andric       separate_debug_info_files.AddItem(oso_data);
1303b1c73532SDimitry Andric   }
1304b1c73532SDimitry Andric 
1305b1c73532SDimitry Andric   d.AddStringItem("type", "oso");
1306b1c73532SDimitry Andric   d.AddStringItem("symfile", GetMainObjectFile()->GetFileSpec().GetPath());
1307b1c73532SDimitry Andric   d.AddItem("separate-debug-info-files",
1308b1c73532SDimitry Andric             std::make_shared<StructuredData::Array>(
1309b1c73532SDimitry Andric                 std::move(separate_debug_info_files)));
1310b1c73532SDimitry Andric   return true;
1311b1c73532SDimitry Andric }
1312b1c73532SDimitry Andric 
1313f034231aSEd Maste lldb::CompUnitSP
GetCompileUnit(SymbolFileDWARF * oso_dwarf,DWARFCompileUnit & dwarf_cu)1314e3b55780SDimitry Andric SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf, DWARFCompileUnit &dwarf_cu) {
131514f1b3e8SDimitry Andric   if (oso_dwarf) {
1316f034231aSEd Maste     const uint32_t cu_count = GetNumCompileUnits();
131714f1b3e8SDimitry Andric     for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
131814f1b3e8SDimitry Andric       SymbolFileDWARF *oso_symfile =
131914f1b3e8SDimitry Andric           GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
132014f1b3e8SDimitry Andric       if (oso_symfile == oso_dwarf) {
1321e3b55780SDimitry Andric         if (m_compile_unit_infos[cu_idx].compile_units_sps.empty())
132214f1b3e8SDimitry Andric           ParseCompileUnitAtIndex(cu_idx);
1323f034231aSEd Maste 
1324e3b55780SDimitry Andric         auto &id_to_index_map = m_compile_unit_infos[cu_idx].id_to_index_map;
1325e3b55780SDimitry Andric         auto it = id_to_index_map.find(dwarf_cu.GetID());
1326e3b55780SDimitry Andric         if (it != id_to_index_map.end())
1327e3b55780SDimitry Andric           return m_compile_unit_infos[cu_idx]
1328e3b55780SDimitry Andric               .compile_units_sps[it->getSecond()];
1329f034231aSEd Maste       }
1330f034231aSEd Maste     }
1331f034231aSEd Maste   }
1332a4092fcbSDimitry Andric   llvm_unreachable("this shouldn't happen");
1333f034231aSEd Maste }
1334f034231aSEd Maste 
1335f034231aSEd Maste SymbolFileDWARFDebugMap::CompileUnitInfo *
GetCompileUnitInfo(SymbolFileDWARF * oso_dwarf)133614f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) {
133714f1b3e8SDimitry Andric   if (oso_dwarf) {
1338f034231aSEd Maste     const uint32_t cu_count = GetNumCompileUnits();
133914f1b3e8SDimitry Andric     for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
134014f1b3e8SDimitry Andric       SymbolFileDWARF *oso_symfile =
134114f1b3e8SDimitry Andric           GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
134214f1b3e8SDimitry Andric       if (oso_symfile == oso_dwarf) {
1343f034231aSEd Maste         return &m_compile_unit_infos[cu_idx];
1344f034231aSEd Maste       }
1345f034231aSEd Maste     }
1346f034231aSEd Maste   }
13475f29bb8aSDimitry Andric   return nullptr;
1348f034231aSEd Maste }
1349f034231aSEd Maste 
SetCompileUnit(SymbolFileDWARF * oso_dwarf,const CompUnitSP & cu_sp)135014f1b3e8SDimitry Andric void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
135114f1b3e8SDimitry Andric                                              const CompUnitSP &cu_sp) {
135214f1b3e8SDimitry Andric   if (oso_dwarf) {
1353f034231aSEd Maste     const uint32_t cu_count = GetNumCompileUnits();
135414f1b3e8SDimitry Andric     for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
135514f1b3e8SDimitry Andric       SymbolFileDWARF *oso_symfile =
135614f1b3e8SDimitry Andric           GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
135714f1b3e8SDimitry Andric       if (oso_symfile == oso_dwarf) {
1358e3b55780SDimitry Andric         if (!m_compile_unit_infos[cu_idx].compile_units_sps.empty()) {
1359e3b55780SDimitry Andric           assert(m_compile_unit_infos[cu_idx].compile_units_sps[0].get() ==
136014f1b3e8SDimitry Andric                  cu_sp.get());
136114f1b3e8SDimitry Andric         } else {
1362e3b55780SDimitry Andric           assert(cu_sp->GetID() == 0 &&
1363e3b55780SDimitry Andric                  "Setting first compile unit but with id different than 0!");
1364e3b55780SDimitry Andric           auto &compile_units_sps = m_compile_unit_infos[cu_idx].compile_units_sps;
1365e3b55780SDimitry Andric           compile_units_sps.push_back(cu_sp);
1366e3b55780SDimitry Andric           m_compile_unit_infos[cu_idx].id_to_index_map.insert(
1367e3b55780SDimitry Andric               {cu_sp->GetID(), compile_units_sps.size() - 1});
1368e3b55780SDimitry Andric 
1369ead24645SDimitry Andric           SetCompileUnitAtIndex(cu_idx, cu_sp);
1370f034231aSEd Maste         }
1371f034231aSEd Maste       }
1372f034231aSEd Maste     }
1373f034231aSEd Maste   }
1374f034231aSEd Maste }
1375f034231aSEd Maste 
1376e81d9d49SDimitry Andric CompilerDeclContext
GetDeclContextForUID(lldb::user_id_t type_uid)137714f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) {
1378f034231aSEd Maste   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1379b1c73532SDimitry Andric   if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx))
1380e81d9d49SDimitry Andric     return oso_dwarf->GetDeclContextForUID(type_uid);
1381b1c73532SDimitry Andric   return {};
1382f034231aSEd Maste }
1383f034231aSEd Maste 
1384e81d9d49SDimitry Andric CompilerDeclContext
GetDeclContextContainingUID(lldb::user_id_t type_uid)138514f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
1386f034231aSEd Maste   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1387b1c73532SDimitry Andric   if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx))
1388e81d9d49SDimitry Andric     return oso_dwarf->GetDeclContextContainingUID(type_uid);
1389b1c73532SDimitry Andric   return {};
1390b1c73532SDimitry Andric }
1391b1c73532SDimitry Andric 
1392b1c73532SDimitry Andric std::vector<CompilerContext>
GetCompilerContextForUID(lldb::user_id_t type_uid)1393b1c73532SDimitry Andric SymbolFileDWARFDebugMap::GetCompilerContextForUID(lldb::user_id_t type_uid) {
1394b1c73532SDimitry Andric   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1395b1c73532SDimitry Andric   if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx))
1396b1c73532SDimitry Andric     return oso_dwarf->GetCompilerContextForUID(type_uid);
1397b1c73532SDimitry Andric   return {};
1398e81d9d49SDimitry Andric }
1399e81d9d49SDimitry Andric 
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)140014f1b3e8SDimitry Andric void SymbolFileDWARFDebugMap::ParseDeclsForContext(
140114f1b3e8SDimitry Andric     lldb_private::CompilerDeclContext decl_ctx) {
1402ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
1403e81d9d49SDimitry Andric     oso_dwarf->ParseDeclsForContext(decl_ctx);
1404ac9a064cSDimitry Andric     return IterationAction::Continue;
1405e81d9d49SDimitry Andric   });
1406f034231aSEd Maste }
1407f034231aSEd 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)140814f1b3e8SDimitry Andric bool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info,
1409f034231aSEd Maste                                               lldb::addr_t exe_file_addr,
1410f3fbd1c0SDimitry Andric                                               lldb::addr_t exe_byte_size,
1411f034231aSEd Maste                                               lldb::addr_t oso_file_addr,
141214f1b3e8SDimitry Andric                                               lldb::addr_t oso_byte_size) {
141314f1b3e8SDimitry Andric   const uint32_t debug_map_idx =
141414f1b3e8SDimitry Andric       m_debug_map.FindEntryIndexThatContains(exe_file_addr);
141514f1b3e8SDimitry Andric   if (debug_map_idx != UINT32_MAX) {
141614f1b3e8SDimitry Andric     DebugMap::Entry *debug_map_entry =
141714f1b3e8SDimitry Andric         m_debug_map.FindEntryThatContains(exe_file_addr);
1418f034231aSEd Maste     debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
1419f3fbd1c0SDimitry Andric     addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
142014f1b3e8SDimitry Andric     if (range_size == 0) {
1421f3fbd1c0SDimitry Andric       range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
1422f3fbd1c0SDimitry Andric       if (range_size == 0)
1423f3fbd1c0SDimitry Andric         range_size = 1;
1424f3fbd1c0SDimitry Andric     }
142514f1b3e8SDimitry Andric     cu_info->file_range_map.Append(
142614f1b3e8SDimitry Andric         FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
1427f034231aSEd Maste     return true;
1428f034231aSEd Maste   }
1429f034231aSEd Maste   return false;
1430f034231aSEd Maste }
1431f034231aSEd Maste 
FinalizeOSOFileRanges(CompileUnitInfo * cu_info)143214f1b3e8SDimitry Andric void SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) {
1433f034231aSEd Maste   cu_info->file_range_map.Sort();
1434f034231aSEd Maste #if defined(DEBUG_OSO_DMAP)
1435f034231aSEd Maste   const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1436f034231aSEd Maste   const size_t n = oso_file_range_map.GetSize();
1437f034231aSEd Maste   printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
143814f1b3e8SDimitry Andric          cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
143914f1b3e8SDimitry Andric   for (size_t i = 0; i < n; ++i) {
1440f034231aSEd Maste     const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
144114f1b3e8SDimitry Andric     printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
144214f1b3e8SDimitry Andric            ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
144314f1b3e8SDimitry Andric            entry.GetRangeBase(), entry.GetRangeEnd(), entry.data,
144414f1b3e8SDimitry Andric            entry.data + entry.GetByteSize());
1445f034231aSEd Maste   }
1446f034231aSEd Maste #endif
1447f034231aSEd Maste }
1448f034231aSEd Maste 
1449f034231aSEd Maste lldb::addr_t
LinkOSOFileAddress(SymbolFileDWARF * oso_symfile,lldb::addr_t oso_file_addr)145014f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
145114f1b3e8SDimitry Andric                                             lldb::addr_t oso_file_addr) {
1452f034231aSEd Maste   CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile);
145314f1b3e8SDimitry Andric   if (cu_info) {
145414f1b3e8SDimitry Andric     const FileRangeMap::Entry *oso_range_entry =
145514f1b3e8SDimitry Andric         cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
145614f1b3e8SDimitry Andric     if (oso_range_entry) {
145714f1b3e8SDimitry Andric       const DebugMap::Entry *debug_map_entry =
145814f1b3e8SDimitry Andric           m_debug_map.FindEntryThatContains(oso_range_entry->data);
145914f1b3e8SDimitry Andric       if (debug_map_entry) {
146014f1b3e8SDimitry Andric         const lldb::addr_t offset =
146114f1b3e8SDimitry Andric             oso_file_addr - oso_range_entry->GetRangeBase();
146214f1b3e8SDimitry Andric         const lldb::addr_t exe_file_addr =
146314f1b3e8SDimitry Andric             debug_map_entry->GetRangeBase() + offset;
1464f034231aSEd Maste         return exe_file_addr;
1465f034231aSEd Maste       }
1466f034231aSEd Maste     }
1467f034231aSEd Maste   }
1468f034231aSEd Maste   return LLDB_INVALID_ADDRESS;
1469f034231aSEd Maste }
1470f034231aSEd Maste 
LinkOSOAddress(Address & addr)147114f1b3e8SDimitry Andric bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) {
1472f034231aSEd Maste   // Make sure this address hasn't been fixed already
1473f034231aSEd Maste   Module *exe_module = GetObjectFile()->GetModule().get();
1474f034231aSEd Maste   Module *addr_module = addr.GetModule().get();
1475f034231aSEd Maste   if (addr_module == exe_module)
1476f034231aSEd Maste     return true; // Address is already in terms of the main executable module
1477f034231aSEd Maste 
1478ead24645SDimitry Andric   CompileUnitInfo *cu_info = GetCompileUnitInfo(
1479ead24645SDimitry Andric       GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolFile()));
148014f1b3e8SDimitry Andric   if (cu_info) {
1481f034231aSEd Maste     const lldb::addr_t oso_file_addr = addr.GetFileAddress();
148214f1b3e8SDimitry Andric     const FileRangeMap::Entry *oso_range_entry =
148314f1b3e8SDimitry Andric         cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
148414f1b3e8SDimitry Andric     if (oso_range_entry) {
148514f1b3e8SDimitry Andric       const DebugMap::Entry *debug_map_entry =
148614f1b3e8SDimitry Andric           m_debug_map.FindEntryThatContains(oso_range_entry->data);
148714f1b3e8SDimitry Andric       if (debug_map_entry) {
148814f1b3e8SDimitry Andric         const lldb::addr_t offset =
148914f1b3e8SDimitry Andric             oso_file_addr - oso_range_entry->GetRangeBase();
149014f1b3e8SDimitry Andric         const lldb::addr_t exe_file_addr =
149114f1b3e8SDimitry Andric             debug_map_entry->GetRangeBase() + offset;
1492f034231aSEd Maste         return exe_module->ResolveFileAddress(exe_file_addr, addr);
1493f034231aSEd Maste       }
1494f034231aSEd Maste     }
1495f034231aSEd Maste   }
1496f034231aSEd Maste   return true;
1497f034231aSEd Maste }
1498f034231aSEd Maste 
LinkOSOLineTable(SymbolFileDWARF * oso_dwarf,LineTable * line_table)149914f1b3e8SDimitry Andric LineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf,
150014f1b3e8SDimitry Andric                                                      LineTable *line_table) {
1501f034231aSEd Maste   CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf);
1502f034231aSEd Maste   if (cu_info)
1503f034231aSEd Maste     return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
15045f29bb8aSDimitry Andric   return nullptr;
1505f034231aSEd Maste }
1506f034231aSEd Maste 
1507f034231aSEd Maste size_t
AddOSOARanges(SymbolFileDWARF * dwarf2Data,DWARFDebugAranges * debug_aranges)150814f1b3e8SDimitry Andric SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,
150914f1b3e8SDimitry Andric                                        DWARFDebugAranges *debug_aranges) {
1510f034231aSEd Maste   size_t num_line_entries_added = 0;
151114f1b3e8SDimitry Andric   if (debug_aranges && dwarf2Data) {
1512f034231aSEd Maste     CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
151314f1b3e8SDimitry Andric     if (compile_unit_info) {
151414f1b3e8SDimitry Andric       const FileRangeMap &file_range_map =
151514f1b3e8SDimitry Andric           compile_unit_info->GetFileRangeMap(this);
151614f1b3e8SDimitry Andric       for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) {
1517f034231aSEd Maste         const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx);
151814f1b3e8SDimitry Andric         if (entry) {
15197fa27ce4SDimitry Andric           debug_aranges->AppendRange(*dwarf2Data->GetFileIndex(),
15207fa27ce4SDimitry Andric                                      entry->GetRangeBase(),
152114f1b3e8SDimitry Andric                                      entry->GetRangeEnd());
1522f034231aSEd Maste           num_line_entries_added++;
1523f034231aSEd Maste         }
1524f034231aSEd Maste       }
1525f034231aSEd Maste     }
1526f034231aSEd Maste   }
1527f034231aSEd Maste   return num_line_entries_added;
1528f034231aSEd Maste }
1529c0981da4SDimitry Andric 
GetDebugInfoModules()1530145449b1SDimitry Andric ModuleList SymbolFileDWARFDebugMap::GetDebugInfoModules() {
1531145449b1SDimitry Andric   ModuleList oso_modules;
1532ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
1533c0981da4SDimitry Andric     ObjectFile *oso_objfile = oso_dwarf->GetObjectFile();
1534c0981da4SDimitry Andric     if (oso_objfile) {
1535c0981da4SDimitry Andric       ModuleSP module_sp = oso_objfile->GetModule();
1536145449b1SDimitry Andric       if (module_sp)
1537145449b1SDimitry Andric         oso_modules.Append(module_sp);
1538c0981da4SDimitry Andric     }
1539ac9a064cSDimitry Andric     return IterationAction::Continue;
1540c0981da4SDimitry Andric   });
1541145449b1SDimitry Andric   return oso_modules;
1542c0981da4SDimitry Andric }
1543e3b55780SDimitry Andric 
CalculateFrameVariableError(StackFrame & frame)1544e3b55780SDimitry Andric Status SymbolFileDWARFDebugMap::CalculateFrameVariableError(StackFrame &frame) {
1545e3b55780SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1546e3b55780SDimitry Andric 
1547e3b55780SDimitry Andric   // We need to make sure that our PC value from the frame matches the module
1548e3b55780SDimitry Andric   // for this object file since we will lookup the PC file address in the debug
1549e3b55780SDimitry Andric   // map below.
1550e3b55780SDimitry Andric   Address pc_addr = frame.GetFrameCodeAddress();
1551e3b55780SDimitry Andric   if (pc_addr.GetModule() == m_objfile_sp->GetModule()) {
1552e3b55780SDimitry Andric     Symtab *symtab = m_objfile_sp->GetSymtab();
1553e3b55780SDimitry Andric     if (symtab) {
1554e3b55780SDimitry Andric       const DebugMap::Entry *debug_map_entry =
1555e3b55780SDimitry Andric           m_debug_map.FindEntryThatContains(pc_addr.GetFileAddress());
1556e3b55780SDimitry Andric       if (debug_map_entry) {
1557e3b55780SDimitry Andric         Symbol *symbol =
1558e3b55780SDimitry Andric             symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
1559e3b55780SDimitry Andric         if (symbol) {
1560e3b55780SDimitry Andric           uint32_t oso_idx = 0;
1561e3b55780SDimitry Andric           CompileUnitInfo *comp_unit_info =
1562e3b55780SDimitry Andric               GetCompileUnitInfoForSymbolWithID(symbol->GetID(), &oso_idx);
1563e3b55780SDimitry Andric           if (comp_unit_info) {
1564e3b55780SDimitry Andric             Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
1565e3b55780SDimitry Andric             if (oso_module) {
1566e3b55780SDimitry Andric               // Check the .o file's DWARF in case it has an error to display.
1567e3b55780SDimitry Andric               SymbolFile *oso_sym_file = oso_module->GetSymbolFile();
1568e3b55780SDimitry Andric               if (oso_sym_file)
1569e3b55780SDimitry Andric                 return oso_sym_file->GetFrameVariableError(frame);
1570e3b55780SDimitry Andric             }
1571e3b55780SDimitry Andric             // If we don't have a valid OSO module here, then something went
1572e3b55780SDimitry Andric             // wrong as we have a symbol for the address in the debug map, but
1573e3b55780SDimitry Andric             // we weren't able to open the .o file. Display an appropriate
1574e3b55780SDimitry Andric             // error
1575e3b55780SDimitry Andric             if (comp_unit_info->oso_load_error.Fail())
1576e3b55780SDimitry Andric               return comp_unit_info->oso_load_error;
1577e3b55780SDimitry Andric             else
1578e3b55780SDimitry Andric               return Status("unable to load debug map object file \"%s\" "
1579e3b55780SDimitry Andric                             "exist, debug info will not be loaded",
1580e3b55780SDimitry Andric                             comp_unit_info->oso_path.GetCString());
1581e3b55780SDimitry Andric           }
1582e3b55780SDimitry Andric         }
1583e3b55780SDimitry Andric       }
1584e3b55780SDimitry Andric     }
1585e3b55780SDimitry Andric   }
1586e3b55780SDimitry Andric   return Status();
1587e3b55780SDimitry Andric }
15887fa27ce4SDimitry Andric 
GetCompileOptions(std::unordered_map<lldb::CompUnitSP,lldb_private::Args> & args)15897fa27ce4SDimitry Andric void SymbolFileDWARFDebugMap::GetCompileOptions(
15907fa27ce4SDimitry Andric     std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {
15917fa27ce4SDimitry Andric 
1592ac9a064cSDimitry Andric   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
15937fa27ce4SDimitry Andric     oso_dwarf->GetCompileOptions(args);
1594ac9a064cSDimitry Andric     return IterationAction::Continue;
15957fa27ce4SDimitry Andric   });
15967fa27ce4SDimitry Andric }
1597