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