SymbolFileDWARFDebugMap.cpp revision 309124
1296417Sdim//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10296417Sdim// C Includes
11296417Sdim// C++ Includes
12296417Sdim// Other libraries and framework includes
13296417Sdim// Project includes
14254721Semaste#include "SymbolFileDWARFDebugMap.h"
15254721Semaste
16254721Semaste#include "DWARFDebugAranges.h"
17254721Semaste
18254721Semaste#include "lldb/Core/RangeMap.h"
19254721Semaste#include "lldb/Core/Module.h"
20254721Semaste#include "lldb/Core/ModuleList.h"
21254721Semaste#include "lldb/Core/PluginManager.h"
22254721Semaste#include "lldb/Core/RegularExpression.h"
23254721Semaste#include "lldb/Core/Section.h"
24254721Semaste
25254721Semaste//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
26254721Semaste#if defined(DEBUG_OSO_DMAP)
27254721Semaste#include "lldb/Core/StreamFile.h"
28254721Semaste#endif
29254721Semaste#include "lldb/Core/Timer.h"
30254721Semaste
31254721Semaste#include "lldb/Symbol/CompileUnit.h"
32254721Semaste#include "lldb/Symbol/LineTable.h"
33254721Semaste#include "lldb/Symbol/ObjectFile.h"
34254721Semaste#include "lldb/Symbol/SymbolVendor.h"
35296417Sdim#include "lldb/Symbol/TypeMap.h"
36254721Semaste#include "lldb/Symbol/VariableList.h"
37254721Semaste
38254721Semaste#include "LogChannelDWARF.h"
39254721Semaste#include "SymbolFileDWARF.h"
40254721Semaste
41254721Semasteusing namespace lldb;
42254721Semasteusing namespace lldb_private;
43254721Semaste
44254721Semaste// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
45254721Semaste// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
46254721Semaste// (so we can fixup the symbol file id.
47254721Semaste
48254721Semasteconst SymbolFileDWARFDebugMap::FileRangeMap &
49254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
50254721Semaste{
51254721Semaste    if (file_range_map_valid)
52254721Semaste        return file_range_map;
53254721Semaste
54254721Semaste    file_range_map_valid = true;
55254721Semaste
56254721Semaste    Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
57254721Semaste    if (!oso_module)
58254721Semaste        return file_range_map;
59276479Sdim
60254721Semaste    ObjectFile *oso_objfile = oso_module->GetObjectFile();
61254721Semaste    if (!oso_objfile)
62254721Semaste        return file_range_map;
63276479Sdim
64254721Semaste    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
65254721Semaste    if (log)
66254721Semaste    {
67254721Semaste        ConstString object_name (oso_module->GetObjectName());
68254721Semaste        log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
69276479Sdim                    static_cast<void*>(this),
70254721Semaste                    oso_module->GetSpecificationDescription().c_str());
71254721Semaste    }
72254721Semaste
73254721Semaste    std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
74254721Semaste    if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
75254721Semaste    {
76254721Semaste        for (auto comp_unit_info : cu_infos)
77254721Semaste        {
78254721Semaste            Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
79254721Semaste            ModuleSP oso_module_sp (oso_objfile->GetModule());
80254721Semaste            Symtab *oso_symtab = oso_objfile->GetSymtab();
81276479Sdim
82254721Semaste            ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
83254721Semaste            //SectionList *oso_sections = oso_objfile->Sections();
84254721Semaste            // Now we need to make sections that map from zero based object
85276479Sdim            // file addresses to where things ended up in the main executable.
86276479Sdim
87254721Semaste            assert (comp_unit_info->first_symbol_index != UINT32_MAX);
88254721Semaste            // End index is one past the last valid symbol index
89254721Semaste            const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
90254721Semaste            for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
91254721Semaste                 idx < oso_end_idx;
92254721Semaste                 ++idx)
93254721Semaste            {
94254721Semaste                Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
95254721Semaste                if (exe_symbol)
96254721Semaste                {
97254721Semaste                    if (exe_symbol->IsDebug() == false)
98254721Semaste                        continue;
99276479Sdim
100254721Semaste                    switch (exe_symbol->GetType())
101254721Semaste                    {
102254721Semaste                    default:
103254721Semaste                        break;
104276479Sdim
105254721Semaste                    case eSymbolTypeCode:
106254721Semaste                        {
107254721Semaste                            // For each N_FUN, or function that we run into in the debug map
108254721Semaste                            // we make a new section that we add to the sections found in the
109254721Semaste                            // .o file. This new section has the file address set to what the
110254721Semaste                            // addresses are in the .o file, and the load address is adjusted
111254721Semaste                            // to match where it ended up in the final executable! We do this
112254721Semaste                            // before we parse any dwarf info so that when it goes get parsed
113254721Semaste                            // all section/offset addresses that get registered will resolve
114254721Semaste                            // correctly to the new addresses in the main executable.
115276479Sdim
116254721Semaste                            // First we find the original symbol in the .o file's symbol table
117288943Sdim                            Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
118254721Semaste                                                                                                 eSymbolTypeCode,
119254721Semaste                                                                                                 Symtab::eDebugNo,
120254721Semaste                                                                                                 Symtab::eVisibilityAny);
121254721Semaste                            if (oso_fun_symbol)
122254721Semaste                            {
123254721Semaste                                // Add the inverse OSO file address to debug map entry mapping
124254721Semaste                                exe_symfile->AddOSOFileRange (this,
125288943Sdim                                                              exe_symbol->GetAddressRef().GetFileAddress(),
126309124Sdim                                                              exe_symbol->GetByteSize(),
127288943Sdim                                                              oso_fun_symbol->GetAddressRef().GetFileAddress(),
128309124Sdim                                                              oso_fun_symbol->GetByteSize());
129276479Sdim
130254721Semaste                            }
131254721Semaste                        }
132254721Semaste                        break;
133276479Sdim
134254721Semaste                    case eSymbolTypeData:
135254721Semaste                        {
136254721Semaste                            // For each N_GSYM we remap the address for the global by making
137254721Semaste                            // a new section that we add to the sections found in the .o file.
138254721Semaste                            // This new section has the file address set to what the
139254721Semaste                            // addresses are in the .o file, and the load address is adjusted
140254721Semaste                            // to match where it ended up in the final executable! We do this
141254721Semaste                            // before we parse any dwarf info so that when it goes get parsed
142254721Semaste                            // all section/offset addresses that get registered will resolve
143254721Semaste                            // correctly to the new addresses in the main executable. We
144254721Semaste                            // initially set the section size to be 1 byte, but will need to
145254721Semaste                            // fix up these addresses further after all globals have been
146254721Semaste                            // parsed to span the gaps, or we can find the global variable
147254721Semaste                            // sizes from the DWARF info as we are parsing.
148276479Sdim
149254721Semaste                            // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
150288943Sdim                            Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
151254721Semaste                                                                                                  eSymbolTypeData,
152254721Semaste                                                                                                  Symtab::eDebugNo,
153254721Semaste                                                                                                  Symtab::eVisibilityAny);
154254721Semaste                            if (exe_symbol && oso_gsym_symbol &&
155254721Semaste                                exe_symbol->ValueIsAddress() &&
156254721Semaste                                oso_gsym_symbol->ValueIsAddress())
157254721Semaste                            {
158254721Semaste                                // Add the inverse OSO file address to debug map entry mapping
159254721Semaste                                exe_symfile->AddOSOFileRange (this,
160288943Sdim                                                              exe_symbol->GetAddressRef().GetFileAddress(),
161309124Sdim                                                              exe_symbol->GetByteSize(),
162288943Sdim                                                              oso_gsym_symbol->GetAddressRef().GetFileAddress(),
163309124Sdim                                                              oso_gsym_symbol->GetByteSize());
164254721Semaste                            }
165254721Semaste                        }
166254721Semaste                        break;
167254721Semaste                    }
168254721Semaste                }
169254721Semaste            }
170276479Sdim
171254721Semaste            exe_symfile->FinalizeOSOFileRanges (this);
172254721Semaste            // We don't need the symbols anymore for the .o files
173254721Semaste            oso_objfile->ClearSymtab();
174254721Semaste        }
175254721Semaste    }
176254721Semaste    return file_range_map;
177254721Semaste}
178254721Semaste
179254721Semasteclass DebugMapModule : public Module
180254721Semaste{
181254721Semastepublic:
182254721Semaste    DebugMapModule (const ModuleSP &exe_module_sp,
183254721Semaste                    uint32_t cu_idx,
184254721Semaste                    const FileSpec& file_spec,
185254721Semaste                    const ArchSpec& arch,
186254721Semaste                    const ConstString *object_name,
187254721Semaste                    off_t object_offset,
188254721Semaste                    const TimeValue *object_mod_time_ptr) :
189254721Semaste        Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
190254721Semaste        m_exe_module_wp (exe_module_sp),
191254721Semaste        m_cu_idx (cu_idx)
192254721Semaste    {
193254721Semaste    }
194254721Semaste
195296417Sdim    ~DebugMapModule() override = default;
196254721Semaste
197296417Sdim    SymbolVendor*
198296417Sdim    GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override
199254721Semaste    {
200254721Semaste        // Scope for locker
201254721Semaste        if (m_symfile_ap.get() || can_create == false)
202254721Semaste            return m_symfile_ap.get();
203254721Semaste
204254721Semaste        ModuleSP exe_module_sp (m_exe_module_wp.lock());
205254721Semaste        if (exe_module_sp)
206254721Semaste        {
207254721Semaste            // Now get the object file outside of a locking scope
208254721Semaste            ObjectFile *oso_objfile = GetObjectFile ();
209254721Semaste            if (oso_objfile)
210254721Semaste            {
211309124Sdim                std::lock_guard<std::recursive_mutex> guard(m_mutex);
212254721Semaste                SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
213254721Semaste                if (symbol_vendor)
214254721Semaste                {
215276479Sdim                    // Set a pointer to this class to set our OSO DWARF file know
216254721Semaste                    // that the DWARF is being used along with a debug map and that
217254721Semaste                    // it will have the remapped sections that we do below.
218254721Semaste                    SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
219254721Semaste
220254721Semaste                    if (!oso_symfile)
221254721Semaste                        return NULL;
222254721Semaste
223254721Semaste                    ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
224254721Semaste                    SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
225254721Semaste
226254721Semaste                    if (exe_objfile && exe_sym_vendor)
227254721Semaste                    {
228288943Sdim                        oso_symfile->SetDebugMapModule(exe_module_sp);
229288943Sdim                        // Set the ID of the symbol file DWARF to the index of the OSO
230288943Sdim                        // shifted left by 32 bits to provide a unique prefix for any
231288943Sdim                        // UserID's that get created in the symbol file.
232288943Sdim                        oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
233254721Semaste                    }
234254721Semaste                    return symbol_vendor;
235254721Semaste                }
236254721Semaste            }
237254721Semaste        }
238254721Semaste        return NULL;
239254721Semaste    }
240254721Semaste
241254721Semasteprotected:
242254721Semaste    ModuleWP m_exe_module_wp;
243254721Semaste    const uint32_t m_cu_idx;
244254721Semaste};
245254721Semaste
246254721Semastevoid
247254721SemasteSymbolFileDWARFDebugMap::Initialize()
248254721Semaste{
249254721Semaste    PluginManager::RegisterPlugin (GetPluginNameStatic(),
250254721Semaste                                   GetPluginDescriptionStatic(),
251254721Semaste                                   CreateInstance);
252254721Semaste}
253254721Semaste
254254721Semastevoid
255254721SemasteSymbolFileDWARFDebugMap::Terminate()
256254721Semaste{
257254721Semaste    PluginManager::UnregisterPlugin (CreateInstance);
258254721Semaste}
259254721Semaste
260254721Semastelldb_private::ConstString
261254721SemasteSymbolFileDWARFDebugMap::GetPluginNameStatic()
262254721Semaste{
263254721Semaste    static ConstString g_name("dwarf-debugmap");
264254721Semaste    return g_name;
265254721Semaste}
266254721Semaste
267254721Semasteconst char *
268254721SemasteSymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
269254721Semaste{
270254721Semaste    return "DWARF and DWARF3 debug symbol file reader (debug map).";
271254721Semaste}
272254721Semaste
273254721SemasteSymbolFile*
274254721SemasteSymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
275254721Semaste{
276254721Semaste    return new SymbolFileDWARFDebugMap (obj_file);
277254721Semaste}
278254721Semaste
279254721SemasteSymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
280254721Semaste    SymbolFile(ofile),
281254721Semaste    m_flags(),
282254721Semaste    m_compile_unit_infos(),
283254721Semaste    m_func_indexes(),
284254721Semaste    m_glob_indexes(),
285254721Semaste    m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
286254721Semaste{
287254721Semaste}
288254721Semaste
289254721SemasteSymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
290254721Semaste{
291254721Semaste}
292254721Semaste
293254721Semastevoid
294254721SemasteSymbolFileDWARFDebugMap::InitializeObject()
295254721Semaste{
296254721Semaste}
297254721Semaste
298254721Semastevoid
299254721SemasteSymbolFileDWARFDebugMap::InitOSO()
300254721Semaste{
301254721Semaste    if (m_flags.test(kHaveInitializedOSOs))
302254721Semaste        return;
303254721Semaste
304254721Semaste    m_flags.set(kHaveInitializedOSOs);
305254721Semaste
306254721Semaste    // If the object file has been stripped, there is no sense in looking further
307254721Semaste    // as all of the debug symbols for the debug map will not be available
308254721Semaste    if (m_obj_file->IsStripped())
309254721Semaste        return;
310254721Semaste
311254721Semaste    // Also make sure the file type is some sort of executable. Core files, debug
312254721Semaste    // info files (dSYM), object files (.o files), and stub libraries all can
313254721Semaste    switch (m_obj_file->GetType())
314254721Semaste    {
315254721Semaste        case ObjectFile::eTypeInvalid:
316254721Semaste        case ObjectFile::eTypeCoreFile:
317254721Semaste        case ObjectFile::eTypeDebugInfo:
318254721Semaste        case ObjectFile::eTypeObjectFile:
319254721Semaste        case ObjectFile::eTypeStubLibrary:
320254721Semaste        case ObjectFile::eTypeUnknown:
321276479Sdim        case ObjectFile::eTypeJIT:
322254721Semaste            return;
323254721Semaste
324254721Semaste        case ObjectFile::eTypeExecutable:
325254721Semaste        case ObjectFile::eTypeDynamicLinker:
326254721Semaste        case ObjectFile::eTypeSharedLibrary:
327254721Semaste            break;
328254721Semaste    }
329254721Semaste
330254721Semaste    // In order to get the abilities of this plug-in, we look at the list of
331254721Semaste    // N_OSO entries (object files) from the symbol table and make sure that
332254721Semaste    // these files exist and also contain valid DWARF. If we get any of that
333254721Semaste    // then we return the abilities of the first N_OSO's DWARF.
334254721Semaste
335254721Semaste    Symtab* symtab = m_obj_file->GetSymtab();
336254721Semaste    if (symtab)
337254721Semaste    {
338254721Semaste        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
339254721Semaste
340254721Semaste        std::vector<uint32_t> oso_indexes;
341254721Semaste        // When a mach-o symbol is encoded, the n_type field is encoded in bits
342254721Semaste        // 23:16, and the n_desc field is encoded in bits 15:0.
343254721Semaste        //
344254721Semaste        // To find all N_OSO entries that are part of the DWARF + debug map
345254721Semaste        // we find only object file symbols with the flags value as follows:
346254721Semaste        // bits 23:16 == 0x66 (N_OSO)
347254721Semaste        // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
348254721Semaste        const uint32_t k_oso_symbol_flags_value = 0x660001u;
349254721Semaste
350254721Semaste        const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
351254721Semaste
352254721Semaste        if (oso_index_count > 0)
353254721Semaste        {
354254721Semaste            symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
355254721Semaste            symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
356254721Semaste
357254721Semaste            symtab->SortSymbolIndexesByValue(m_func_indexes, true);
358254721Semaste            symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
359254721Semaste
360254721Semaste            for (uint32_t sym_idx : m_func_indexes)
361254721Semaste            {
362254721Semaste                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
363288943Sdim                lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
364254721Semaste                lldb::addr_t byte_size = symbol->GetByteSize();
365254721Semaste                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
366254721Semaste                m_debug_map.Append(debug_map_entry);
367254721Semaste            }
368254721Semaste            for (uint32_t sym_idx : m_glob_indexes)
369254721Semaste            {
370254721Semaste                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
371288943Sdim                lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
372254721Semaste                lldb::addr_t byte_size = symbol->GetByteSize();
373254721Semaste                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
374254721Semaste                m_debug_map.Append(debug_map_entry);
375254721Semaste            }
376254721Semaste            m_debug_map.Sort();
377254721Semaste
378254721Semaste            m_compile_unit_infos.resize(oso_index_count);
379254721Semaste
380254721Semaste            for (uint32_t i=0; i<oso_index_count; ++i)
381254721Semaste            {
382254721Semaste                const uint32_t so_idx = oso_indexes[i] - 1;
383254721Semaste                const uint32_t oso_idx = oso_indexes[i];
384254721Semaste                const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
385254721Semaste                const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
386254721Semaste                if (so_symbol &&
387254721Semaste                    oso_symbol &&
388254721Semaste                    so_symbol->GetType() == eSymbolTypeSourceFile &&
389254721Semaste                    oso_symbol->GetType() == eSymbolTypeObjectFile)
390254721Semaste                {
391254721Semaste                    m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
392254721Semaste                    m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
393254721Semaste                    TimeValue oso_mod_time;
394288943Sdim                    oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0));
395254721Semaste                    m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
396254721Semaste                    uint32_t sibling_idx = so_symbol->GetSiblingIndex();
397254721Semaste                    // The sibling index can't be less that or equal to the current index "i"
398288943Sdim                    if (sibling_idx == UINT32_MAX)
399254721Semaste                    {
400254721Semaste                        m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
401254721Semaste                    }
402254721Semaste                    else
403254721Semaste                    {
404254721Semaste                        const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
405254721Semaste                        m_compile_unit_infos[i].first_symbol_index = so_idx;
406254721Semaste                        m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
407254721Semaste                        m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
408254721Semaste                        m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
409254721Semaste
410254721Semaste                        if (log)
411254721Semaste                            log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
412254721Semaste                    }
413254721Semaste                }
414254721Semaste                else
415254721Semaste                {
416254721Semaste                    if (oso_symbol == NULL)
417254721Semaste                        m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx);
418254721Semaste                    else if (so_symbol == NULL)
419254721Semaste                        m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx);
420254721Semaste                    else if (so_symbol->GetType() != eSymbolTypeSourceFile)
421254721Semaste                        m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx);
422254721Semaste                    else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
423254721Semaste                        m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx);
424254721Semaste                }
425254721Semaste            }
426254721Semaste        }
427254721Semaste    }
428254721Semaste}
429254721Semaste
430254721SemasteModule *
431254721SemasteSymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
432254721Semaste{
433254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
434254721Semaste    if (oso_idx < cu_count)
435254721Semaste        return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
436254721Semaste    return NULL;
437254721Semaste}
438254721Semaste
439254721SemasteModule *
440254721SemasteSymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
441254721Semaste{
442254721Semaste    if (!comp_unit_info->oso_sp)
443254721Semaste    {
444254721Semaste        auto pos = m_oso_map.find (comp_unit_info->oso_path);
445254721Semaste        if (pos != m_oso_map.end())
446254721Semaste        {
447254721Semaste            comp_unit_info->oso_sp = pos->second;
448254721Semaste        }
449254721Semaste        else
450254721Semaste        {
451254721Semaste            ObjectFile *obj_file = GetObjectFile();
452254721Semaste            comp_unit_info->oso_sp.reset (new OSOInfo());
453254721Semaste            m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
454254721Semaste            const char *oso_path = comp_unit_info->oso_path.GetCString();
455254721Semaste            FileSpec oso_file (oso_path, false);
456254721Semaste            ConstString oso_object;
457254721Semaste            if (oso_file.Exists())
458254721Semaste            {
459254721Semaste                TimeValue oso_mod_time (oso_file.GetModificationTime());
460254721Semaste                if (oso_mod_time != comp_unit_info->oso_mod_time)
461254721Semaste                {
462254721Semaste                    obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored",
463254721Semaste                                                        oso_file.GetPath().c_str(),
464254721Semaste                                                        oso_mod_time.GetAsSecondsSinceJan1_1970(),
465254721Semaste                                                        comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
466254721Semaste                    return NULL;
467254721Semaste                }
468254721Semaste
469254721Semaste            }
470254721Semaste            else
471254721Semaste            {
472254721Semaste                const bool must_exist = true;
473254721Semaste
474254721Semaste                if (!ObjectFile::SplitArchivePathWithObject (oso_path,
475254721Semaste                                                             oso_file,
476254721Semaste                                                             oso_object,
477254721Semaste                                                             must_exist))
478254721Semaste                {
479254721Semaste                    return NULL;
480254721Semaste                }
481254721Semaste            }
482254721Semaste            // Always create a new module for .o files. Why? Because we
483254721Semaste            // use the debug map, to add new sections to each .o file and
484254721Semaste            // even though a .o file might not have changed, the sections
485254721Semaste            // that get added to the .o file can change.
486276479Sdim            ArchSpec oso_arch;
487276479Sdim            // Only adopt the architecture from the module (not the vendor or OS)
488276479Sdim            // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx"
489276479Sdim            // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
490276479Sdim            // load command...
491276479Sdim            oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str());
492254721Semaste            comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
493254721Semaste                                                                         GetCompUnitInfoIndex(comp_unit_info),
494254721Semaste                                                                         oso_file,
495276479Sdim                                                                         oso_arch,
496254721Semaste                                                                         oso_object ? &oso_object : NULL,
497254721Semaste                                                                         0,
498254721Semaste                                                                         oso_object ? &comp_unit_info->oso_mod_time : NULL));
499254721Semaste        }
500254721Semaste    }
501254721Semaste    if (comp_unit_info->oso_sp)
502254721Semaste        return comp_unit_info->oso_sp->module_sp.get();
503254721Semaste    return NULL;
504254721Semaste}
505254721Semaste
506254721Semastebool
507254721SemasteSymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
508254721Semaste{
509254721Semaste    if (oso_idx < m_compile_unit_infos.size())
510254721Semaste    {
511254721Semaste        if (m_compile_unit_infos[oso_idx].so_file)
512254721Semaste        {
513254721Semaste            file_spec = m_compile_unit_infos[oso_idx].so_file;
514254721Semaste            return true;
515254721Semaste        }
516254721Semaste    }
517254721Semaste    return false;
518254721Semaste}
519254721Semaste
520254721SemasteObjectFile *
521254721SemasteSymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
522254721Semaste{
523254721Semaste    Module *oso_module = GetModuleByOSOIndex (oso_idx);
524254721Semaste    if (oso_module)
525254721Semaste        return oso_module->GetObjectFile();
526254721Semaste    return NULL;
527254721Semaste}
528254721Semaste
529254721SemasteSymbolFileDWARF *
530254721SemasteSymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
531254721Semaste{
532254721Semaste    CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
533254721Semaste    if (comp_unit_info)
534254721Semaste        return GetSymbolFileByCompUnitInfo (comp_unit_info);
535254721Semaste    return NULL;
536254721Semaste}
537254721Semaste
538254721SemasteObjectFile *
539254721SemasteSymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
540254721Semaste{
541254721Semaste    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
542254721Semaste    if (oso_module)
543254721Semaste        return oso_module->GetObjectFile();
544254721Semaste    return NULL;
545254721Semaste}
546254721Semaste
547254721Semasteuint32_t
548254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
549254721Semaste{
550254721Semaste    if (!m_compile_unit_infos.empty())
551254721Semaste    {
552254721Semaste        const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
553254721Semaste        const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
554254721Semaste        if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
555254721Semaste            return comp_unit_info - first_comp_unit_info;
556254721Semaste    }
557254721Semaste    return UINT32_MAX;
558254721Semaste}
559254721Semaste
560254721SemasteSymbolFileDWARF *
561254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
562254721Semaste{
563254721Semaste    if (oso_idx < m_compile_unit_infos.size())
564254721Semaste        return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
565254721Semaste    return NULL;
566254721Semaste}
567254721Semaste
568254721SemasteSymbolFileDWARF *
569254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
570254721Semaste{
571254721Semaste    if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
572254721Semaste        return (SymbolFileDWARF *)sym_file;
573254721Semaste    return NULL;
574254721Semaste}
575254721Semaste
576254721SemasteSymbolFileDWARF *
577254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
578254721Semaste{
579254721Semaste    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
580254721Semaste    if (oso_module)
581254721Semaste    {
582254721Semaste        SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
583254721Semaste        if (sym_vendor)
584254721Semaste            return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
585254721Semaste    }
586254721Semaste    return NULL;
587254721Semaste}
588254721Semaste
589254721Semasteuint32_t
590254721SemasteSymbolFileDWARFDebugMap::CalculateAbilities ()
591254721Semaste{
592254721Semaste    // In order to get the abilities of this plug-in, we look at the list of
593254721Semaste    // N_OSO entries (object files) from the symbol table and make sure that
594254721Semaste    // these files exist and also contain valid DWARF. If we get any of that
595254721Semaste    // then we return the abilities of the first N_OSO's DWARF.
596254721Semaste
597254721Semaste    const uint32_t oso_index_count = GetNumCompileUnits();
598254721Semaste    if (oso_index_count > 0)
599254721Semaste    {
600254721Semaste        InitOSO();
601254721Semaste        if (!m_compile_unit_infos.empty())
602254721Semaste        {
603254721Semaste            return SymbolFile::CompileUnits    |
604254721Semaste                   SymbolFile::Functions       |
605254721Semaste                   SymbolFile::Blocks          |
606254721Semaste                   SymbolFile::GlobalVariables |
607254721Semaste                   SymbolFile::LocalVariables  |
608254721Semaste                   SymbolFile::VariableTypes   |
609254721Semaste                   SymbolFile::LineTables      ;
610254721Semaste        }
611254721Semaste    }
612254721Semaste    return 0;
613254721Semaste}
614254721Semaste
615254721Semasteuint32_t
616254721SemasteSymbolFileDWARFDebugMap::GetNumCompileUnits()
617254721Semaste{
618254721Semaste    InitOSO ();
619254721Semaste    return m_compile_unit_infos.size();
620254721Semaste}
621254721Semaste
622254721SemasteCompUnitSP
623254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
624254721Semaste{
625254721Semaste    CompUnitSP comp_unit_sp;
626254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
627254721Semaste
628254721Semaste    if (cu_idx < cu_count)
629254721Semaste    {
630254721Semaste        Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
631254721Semaste        if (oso_module)
632254721Semaste        {
633254721Semaste            FileSpec so_file_spec;
634254721Semaste            if (GetFileSpecForSO (cu_idx, so_file_spec))
635254721Semaste            {
636254721Semaste                // User zero as the ID to match the compile unit at offset
637254721Semaste                // zero in each .o file since each .o file can only have
638254721Semaste                // one compile unit for now.
639254721Semaste                lldb::user_id_t cu_id = 0;
640309124Sdim                m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit(
641309124Sdim                    m_obj_file->GetModule(), NULL, so_file_spec, cu_id, eLanguageTypeUnknown, eLazyBoolCalculate));
642309124Sdim
643254721Semaste                if (m_compile_unit_infos[cu_idx].compile_unit_sp)
644254721Semaste                {
645254721Semaste                    // Let our symbol vendor know about this compile unit
646254721Semaste                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
647254721Semaste                }
648254721Semaste            }
649254721Semaste        }
650254721Semaste        comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
651254721Semaste    }
652254721Semaste
653254721Semaste    return comp_unit_sp;
654254721Semaste}
655254721Semaste
656254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo *
657254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
658254721Semaste{
659254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
660254721Semaste    for (uint32_t i=0; i<cu_count; ++i)
661254721Semaste    {
662254721Semaste        if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
663254721Semaste            return &m_compile_unit_infos[i];
664254721Semaste    }
665254721Semaste    return NULL;
666254721Semaste}
667254721Semaste
668254721Semastesize_t
669254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
670254721Semaste{
671254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
672254721Semaste    for (uint32_t i=0; i<cu_count; ++i)
673254721Semaste    {
674254721Semaste        if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
675254721Semaste            cu_infos.push_back (&m_compile_unit_infos[i]);
676254721Semaste    }
677254721Semaste    return cu_infos.size();
678254721Semaste}
679254721Semaste
680254721Semastelldb::LanguageType
681254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
682254721Semaste{
683254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
684254721Semaste    if (oso_dwarf)
685254721Semaste        return oso_dwarf->ParseCompileUnitLanguage (sc);
686254721Semaste    return eLanguageTypeUnknown;
687254721Semaste}
688254721Semaste
689254721Semastesize_t
690254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
691254721Semaste{
692254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
693254721Semaste    if (oso_dwarf)
694254721Semaste        return oso_dwarf->ParseCompileUnitFunctions (sc);
695254721Semaste    return 0;
696254721Semaste}
697254721Semaste
698254721Semastebool
699254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
700254721Semaste{
701254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
702254721Semaste    if (oso_dwarf)
703254721Semaste        return oso_dwarf->ParseCompileUnitLineTable (sc);
704254721Semaste    return false;
705254721Semaste}
706254721Semaste
707254721Semastebool
708296417SdimSymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros (const SymbolContext& sc)
709296417Sdim{
710296417Sdim    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
711296417Sdim    if (oso_dwarf)
712296417Sdim        return oso_dwarf->ParseCompileUnitDebugMacros (sc);
713296417Sdim    return false;
714296417Sdim}
715296417Sdim
716296417Sdimbool
717254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
718254721Semaste{
719254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
720254721Semaste    if (oso_dwarf)
721254721Semaste        return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
722254721Semaste    return false;
723254721Semaste}
724254721Semaste
725288943Sdimbool
726309124SdimSymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
727288943Sdim{
728309124Sdim    SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
729309124Sdim    if (oso_dwarf)
730309124Sdim        return oso_dwarf->ParseCompileUnitIsOptimized(sc);
731309124Sdim    return false;
732309124Sdim}
733309124Sdim
734309124Sdimbool
735309124SdimSymbolFileDWARFDebugMap::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
736309124Sdim{
737288943Sdim    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
738288943Sdim    if (oso_dwarf)
739288943Sdim        return oso_dwarf->ParseImportedModules(sc, imported_modules);
740288943Sdim    return false;
741288943Sdim}
742254721Semaste
743254721Semastesize_t
744254721SemasteSymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
745254721Semaste{
746254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
747254721Semaste    if (oso_dwarf)
748254721Semaste        return oso_dwarf->ParseFunctionBlocks (sc);
749254721Semaste    return 0;
750254721Semaste}
751254721Semaste
752254721Semastesize_t
753254721SemasteSymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
754254721Semaste{
755254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
756254721Semaste    if (oso_dwarf)
757254721Semaste        return oso_dwarf->ParseTypes (sc);
758254721Semaste    return 0;
759254721Semaste}
760254721Semaste
761254721Semastesize_t
762254721SemasteSymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
763254721Semaste{
764254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
765254721Semaste    if (oso_dwarf)
766254721Semaste        return oso_dwarf->ParseVariablesForContext (sc);
767254721Semaste    return 0;
768254721Semaste}
769254721Semaste
770254721SemasteType*
771254721SemasteSymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
772254721Semaste{
773254721Semaste    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
774254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
775254721Semaste    if (oso_dwarf)
776254721Semaste        return oso_dwarf->ResolveTypeUID (type_uid);
777254721Semaste    return NULL;
778254721Semaste}
779254721Semaste
780254721Semastebool
781296417SdimSymbolFileDWARFDebugMap::CompleteType (CompilerType& compiler_type)
782254721Semaste{
783296417Sdim    bool success = false;
784296417Sdim    if (compiler_type)
785296417Sdim    {
786296417Sdim        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
787296417Sdim            if (oso_dwarf->HasForwardDeclForClangType (compiler_type))
788296417Sdim            {
789296417Sdim                oso_dwarf->CompleteType (compiler_type);
790296417Sdim                success = true;
791296417Sdim                return true;
792296417Sdim            }
793296417Sdim            return false;
794296417Sdim        });
795296417Sdim    }
796296417Sdim    return success;
797254721Semaste}
798254721Semaste
799254721Semasteuint32_t
800254721SemasteSymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
801254721Semaste{
802254721Semaste    uint32_t resolved_flags = 0;
803254721Semaste    Symtab* symtab = m_obj_file->GetSymtab();
804254721Semaste    if (symtab)
805254721Semaste    {
806254721Semaste        const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
807254721Semaste
808254721Semaste        const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
809254721Semaste        if (debug_map_entry)
810254721Semaste        {
811254721Semaste
812254721Semaste            sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
813254721Semaste
814254721Semaste            if (sc.symbol != NULL)
815254721Semaste            {
816254721Semaste                resolved_flags |= eSymbolContextSymbol;
817254721Semaste
818254721Semaste                uint32_t oso_idx = 0;
819254721Semaste                CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
820254721Semaste                if (comp_unit_info)
821254721Semaste                {
822254721Semaste                    comp_unit_info->GetFileRangeMap(this);
823254721Semaste                    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
824254721Semaste                    if (oso_module)
825254721Semaste                    {
826254721Semaste                        lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
827254721Semaste                        Address oso_so_addr;
828254721Semaste                        if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
829254721Semaste                        {
830254721Semaste                            resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
831254721Semaste                        }
832254721Semaste                    }
833254721Semaste                }
834254721Semaste            }
835254721Semaste        }
836254721Semaste    }
837254721Semaste    return resolved_flags;
838254721Semaste}
839254721Semaste
840254721Semasteuint32_t
841254721SemasteSymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
842254721Semaste{
843254721Semaste    const uint32_t initial = sc_list.GetSize();
844254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
845254721Semaste
846254721Semaste    for (uint32_t i=0; i<cu_count; ++i)
847254721Semaste    {
848254721Semaste        // If we are checking for inlines, then we need to look through all
849254721Semaste        // compile units no matter if "file_spec" matches.
850254721Semaste        bool resolve = check_inlines;
851254721Semaste
852254721Semaste        if (!resolve)
853254721Semaste        {
854254721Semaste            FileSpec so_file_spec;
855254721Semaste            if (GetFileSpecForSO (i, so_file_spec))
856254721Semaste            {
857254721Semaste                // Match the full path if the incoming file_spec has a directory (not just a basename)
858258054Semaste                const bool full_match = (bool)file_spec.GetDirectory();
859254721Semaste                resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
860254721Semaste            }
861254721Semaste        }
862254721Semaste        if (resolve)
863254721Semaste        {
864254721Semaste            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
865254721Semaste            if (oso_dwarf)
866254721Semaste                oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
867254721Semaste        }
868254721Semaste    }
869254721Semaste    return sc_list.GetSize() - initial;
870254721Semaste}
871254721Semaste
872254721Semasteuint32_t
873254721SemasteSymbolFileDWARFDebugMap::PrivateFindGlobalVariables
874254721Semaste(
875254721Semaste    const ConstString &name,
876296417Sdim    const CompilerDeclContext *parent_decl_ctx,
877254721Semaste    const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
878254721Semaste    uint32_t max_matches,
879254721Semaste    VariableList& variables
880254721Semaste)
881254721Semaste{
882254721Semaste    const uint32_t original_size = variables.GetSize();
883254721Semaste    const size_t match_count = indexes.size();
884254721Semaste    for (size_t i=0; i<match_count; ++i)
885254721Semaste    {
886254721Semaste        uint32_t oso_idx;
887254721Semaste        CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
888254721Semaste        if (comp_unit_info)
889254721Semaste        {
890254721Semaste            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
891254721Semaste            if (oso_dwarf)
892254721Semaste            {
893296417Sdim                if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, max_matches, variables))
894254721Semaste                    if (variables.GetSize() > max_matches)
895254721Semaste                        break;
896254721Semaste            }
897254721Semaste        }
898254721Semaste    }
899254721Semaste    return variables.GetSize() - original_size;
900254721Semaste}
901254721Semaste
902254721Semasteuint32_t
903296417SdimSymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name,
904296417Sdim                                              const CompilerDeclContext *parent_decl_ctx,
905296417Sdim                                              bool append,
906296417Sdim                                              uint32_t max_matches,
907296417Sdim                                              VariableList& variables)
908254721Semaste{
909254721Semaste
910254721Semaste    // If we aren't appending the results to this list, then clear the list
911254721Semaste    if (!append)
912254721Semaste        variables.Clear();
913254721Semaste
914254721Semaste    // Remember how many variables are in the list before we search in case
915254721Semaste    // we are appending the results to a variable list.
916254721Semaste    const uint32_t original_size = variables.GetSize();
917254721Semaste
918254721Semaste    uint32_t total_matches = 0;
919288943Sdim
920288943Sdim    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
921254721Semaste        const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
922296417Sdim                                                                     parent_decl_ctx,
923288943Sdim                                                                     true,
924288943Sdim                                                                     max_matches,
925254721Semaste                                                                     variables);
926254721Semaste        if (oso_matches > 0)
927254721Semaste        {
928254721Semaste            total_matches += oso_matches;
929288943Sdim
930254721Semaste            // Are we getting all matches?
931254721Semaste            if (max_matches == UINT32_MAX)
932288943Sdim                return false;   // Yep, continue getting everything
933288943Sdim
934254721Semaste            // If we have found enough matches, lets get out
935254721Semaste            if (max_matches >= total_matches)
936288943Sdim                return true;
937288943Sdim
938254721Semaste            // Update the max matches for any subsequent calls to find globals
939254721Semaste            // in any other object files with DWARF
940254721Semaste            max_matches -= oso_matches;
941254721Semaste        }
942288943Sdim
943288943Sdim        return false;
944288943Sdim    });
945288943Sdim
946254721Semaste    // Return the number of variable that were appended to the list
947254721Semaste    return variables.GetSize() - original_size;
948254721Semaste}
949254721Semaste
950254721Semasteuint32_t
951254721SemasteSymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
952254721Semaste{
953254721Semaste    // If we aren't appending the results to this list, then clear the list
954254721Semaste    if (!append)
955254721Semaste        variables.Clear();
956254721Semaste
957254721Semaste    // Remember how many variables are in the list before we search in case
958254721Semaste    // we are appending the results to a variable list.
959254721Semaste    const uint32_t original_size = variables.GetSize();
960254721Semaste
961254721Semaste    uint32_t total_matches = 0;
962288943Sdim    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
963288943Sdim        const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
964254721Semaste                                                                     true,
965254721Semaste                                                                     max_matches,
966254721Semaste                                                                     variables);
967254721Semaste        if (oso_matches > 0)
968254721Semaste        {
969254721Semaste            total_matches += oso_matches;
970254721Semaste
971254721Semaste            // Are we getting all matches?
972254721Semaste            if (max_matches == UINT32_MAX)
973288943Sdim                return false;   // Yep, continue getting everything
974254721Semaste
975254721Semaste            // If we have found enough matches, lets get out
976254721Semaste            if (max_matches >= total_matches)
977288943Sdim                return true;
978254721Semaste
979254721Semaste            // Update the max matches for any subsequent calls to find globals
980254721Semaste            // in any other object files with DWARF
981254721Semaste            max_matches -= oso_matches;
982254721Semaste        }
983288943Sdim
984288943Sdim        return false;
985288943Sdim    });
986288943Sdim
987254721Semaste    // Return the number of variable that were appended to the list
988254721Semaste    return variables.GetSize() - original_size;
989254721Semaste}
990254721Semaste
991254721Semasteint
992254721SemasteSymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
993254721Semaste{
994254721Semaste    const uint32_t symbol_idx = *symbol_idx_ptr;
995254721Semaste
996254721Semaste    if (symbol_idx < comp_unit_info->first_symbol_index)
997254721Semaste        return -1;
998254721Semaste
999254721Semaste    if (symbol_idx <= comp_unit_info->last_symbol_index)
1000254721Semaste        return 0;
1001254721Semaste
1002254721Semaste    return 1;
1003254721Semaste}
1004254721Semaste
1005254721Semasteint
1006254721SemasteSymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
1007254721Semaste{
1008254721Semaste    const user_id_t symbol_id = *symbol_idx_ptr;
1009254721Semaste
1010254721Semaste    if (symbol_id < comp_unit_info->first_symbol_id)
1011254721Semaste        return -1;
1012254721Semaste
1013254721Semaste    if (symbol_id <= comp_unit_info->last_symbol_id)
1014254721Semaste        return 0;
1015254721Semaste
1016254721Semaste    return 1;
1017254721Semaste}
1018254721Semaste
1019254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo*
1020254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
1021254721Semaste{
1022254721Semaste    const uint32_t oso_index_count = m_compile_unit_infos.size();
1023254721Semaste    CompileUnitInfo *comp_unit_info = NULL;
1024254721Semaste    if (oso_index_count)
1025254721Semaste    {
1026254721Semaste        comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
1027254721Semaste                                                   &m_compile_unit_infos[0],
1028254721Semaste                                                   m_compile_unit_infos.size(),
1029254721Semaste                                                   sizeof(CompileUnitInfo),
1030254721Semaste                                                   (ComparisonFunction)SymbolContainsSymbolWithIndex);
1031254721Semaste    }
1032254721Semaste
1033254721Semaste    if (oso_idx_ptr)
1034254721Semaste    {
1035254721Semaste        if (comp_unit_info != NULL)
1036254721Semaste            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1037254721Semaste        else
1038254721Semaste            *oso_idx_ptr = UINT32_MAX;
1039254721Semaste    }
1040254721Semaste    return comp_unit_info;
1041254721Semaste}
1042254721Semaste
1043254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo*
1044254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
1045254721Semaste{
1046254721Semaste    const uint32_t oso_index_count = m_compile_unit_infos.size();
1047254721Semaste    CompileUnitInfo *comp_unit_info = NULL;
1048254721Semaste    if (oso_index_count)
1049254721Semaste    {
1050254721Semaste        comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
1051254721Semaste                                                      &m_compile_unit_infos[0],
1052254721Semaste                                                      m_compile_unit_infos.size(),
1053254721Semaste                                                      sizeof(CompileUnitInfo),
1054254721Semaste                                                      (ComparisonFunction)SymbolContainsSymbolWithID);
1055254721Semaste    }
1056254721Semaste
1057254721Semaste    if (oso_idx_ptr)
1058254721Semaste    {
1059254721Semaste        if (comp_unit_info != NULL)
1060254721Semaste            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1061254721Semaste        else
1062254721Semaste            *oso_idx_ptr = UINT32_MAX;
1063254721Semaste    }
1064254721Semaste    return comp_unit_info;
1065254721Semaste}
1066254721Semaste
1067254721Semastestatic void
1068254721SemasteRemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
1069254721Semaste{
1070254721Semaste    // We found functions in .o files. Not all functions in the .o files
1071254721Semaste    // will have made it into the final output file. The ones that did
1072254721Semaste    // make it into the final output file will have a section whose module
1073254721Semaste    // matches the module from the ObjectFile for this SymbolFile. When
1074254721Semaste    // the modules don't match, then we have something that was in a
1075254721Semaste    // .o file, but doesn't map to anything in the final executable.
1076254721Semaste    uint32_t i=start_idx;
1077254721Semaste    while (i < sc_list.GetSize())
1078254721Semaste    {
1079254721Semaste        SymbolContext sc;
1080254721Semaste        sc_list.GetContextAtIndex(i, sc);
1081254721Semaste        if (sc.function)
1082254721Semaste        {
1083254721Semaste            const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
1084254721Semaste            if (section_sp->GetModule() != module_sp)
1085254721Semaste            {
1086254721Semaste                sc_list.RemoveContextAtIndex(i);
1087254721Semaste                continue;
1088254721Semaste            }
1089254721Semaste        }
1090254721Semaste        ++i;
1091254721Semaste    }
1092254721Semaste}
1093254721Semaste
1094254721Semasteuint32_t
1095296417SdimSymbolFileDWARFDebugMap::FindFunctions(const ConstString &name,
1096296417Sdim                                       const CompilerDeclContext *parent_decl_ctx,
1097296417Sdim                                       uint32_t name_type_mask,
1098296417Sdim                                       bool include_inlines,
1099296417Sdim                                       bool append,
1100296417Sdim                                       SymbolContextList& sc_list)
1101254721Semaste{
1102254721Semaste    Timer scoped_timer (__PRETTY_FUNCTION__,
1103254721Semaste                        "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1104254721Semaste                        name.GetCString());
1105254721Semaste
1106254721Semaste    uint32_t initial_size = 0;
1107254721Semaste    if (append)
1108254721Semaste        initial_size = sc_list.GetSize();
1109254721Semaste    else
1110254721Semaste        sc_list.Clear();
1111254721Semaste
1112288943Sdim    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1113254721Semaste        uint32_t sc_idx = sc_list.GetSize();
1114296417Sdim        if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, true, sc_list))
1115254721Semaste        {
1116254721Semaste            RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1117254721Semaste        }
1118288943Sdim        return false;
1119288943Sdim    });
1120254721Semaste
1121254721Semaste    return sc_list.GetSize() - initial_size;
1122254721Semaste}
1123254721Semaste
1124254721Semasteuint32_t
1125254721SemasteSymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
1126254721Semaste{
1127254721Semaste    Timer scoped_timer (__PRETTY_FUNCTION__,
1128254721Semaste                        "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1129254721Semaste                        regex.GetText());
1130254721Semaste
1131254721Semaste    uint32_t initial_size = 0;
1132254721Semaste    if (append)
1133254721Semaste        initial_size = sc_list.GetSize();
1134254721Semaste    else
1135254721Semaste        sc_list.Clear();
1136254721Semaste
1137288943Sdim    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1138254721Semaste        uint32_t sc_idx = sc_list.GetSize();
1139254721Semaste
1140254721Semaste        if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
1141254721Semaste        {
1142254721Semaste            RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1143254721Semaste        }
1144288943Sdim        return false;
1145288943Sdim    });
1146254721Semaste
1147254721Semaste    return sc_list.GetSize() - initial_size;
1148254721Semaste}
1149254721Semaste
1150254721Semastesize_t
1151254721SemasteSymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
1152254721Semaste                                   uint32_t type_mask,
1153254721Semaste                                   TypeList &type_list)
1154254721Semaste{
1155254721Semaste    Timer scoped_timer (__PRETTY_FUNCTION__,
1156254721Semaste                        "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1157254721Semaste                        type_mask);
1158296417Sdim
1159254721Semaste    uint32_t initial_size = type_list.GetSize();
1160254721Semaste    SymbolFileDWARF *oso_dwarf = NULL;
1161254721Semaste    if (sc_scope)
1162254721Semaste    {
1163254721Semaste        SymbolContext sc;
1164254721Semaste        sc_scope->CalculateSymbolContext(&sc);
1165254721Semaste
1166254721Semaste        CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
1167254721Semaste        if (cu_info)
1168254721Semaste        {
1169254721Semaste            oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
1170254721Semaste            if (oso_dwarf)
1171254721Semaste                oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1172254721Semaste        }
1173254721Semaste    }
1174254721Semaste    else
1175254721Semaste    {
1176288943Sdim        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1177254721Semaste            oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1178288943Sdim            return false;
1179288943Sdim        });
1180254721Semaste    }
1181254721Semaste    return type_list.GetSize() - initial_size;
1182254721Semaste}
1183254721Semaste
1184254721SemasteTypeSP
1185254721SemasteSymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
1186254721Semaste{
1187254721Semaste    TypeSP type_sp;
1188288943Sdim    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1189254721Semaste        type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
1190288943Sdim        return ((bool)type_sp);
1191288943Sdim    });
1192254721Semaste    return type_sp;
1193254721Semaste}
1194254721Semaste
1195254721Semastebool
1196254721SemasteSymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
1197254721Semaste{
1198254721Semaste    if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
1199254721Semaste    {
1200254721Semaste        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
1201288943Sdim        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1202254721Semaste            if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
1203254721Semaste            {
1204254721Semaste                m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
1205288943Sdim                return true;
1206254721Semaste            }
1207288943Sdim            return false;
1208288943Sdim        });
1209254721Semaste    }
1210254721Semaste    return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1211254721Semaste}
1212254721Semaste
1213254721SemasteTypeSP
1214296417SdimSymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
1215254721Semaste                                                               const ConstString &type_name,
1216254721Semaste                                                               bool must_be_implementation)
1217254721Semaste{
1218288943Sdim    // If we have a debug map, we will have an Objective C symbol whose name is
1219288943Sdim    // the type name and whose type is eSymbolTypeObjCClass. If we can find that
1220288943Sdim    // symbol and find its containing parent, we can locate the .o file that will
1221288943Sdim    // contain the implementation definition since it will be scoped inside the N_SO
1222288943Sdim    // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
1223288943Sdim    SymbolFileDWARF *oso_dwarf = NULL;
1224254721Semaste    TypeSP type_sp;
1225288943Sdim    ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
1226288943Sdim    if (module_objfile)
1227254721Semaste    {
1228288943Sdim        Symtab *symtab = module_objfile->GetSymtab();
1229288943Sdim        if (symtab)
1230288943Sdim        {
1231288943Sdim            Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny);
1232288943Sdim            if (objc_class_symbol)
1233288943Sdim            {
1234288943Sdim                // Get the N_SO symbol that contains the objective C class symbol as this
1235288943Sdim                // should be the .o file that contains the real definition...
1236288943Sdim                const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
1237288943Sdim
1238288943Sdim                if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile)
1239288943Sdim                {
1240288943Sdim                    const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol);
1241288943Sdim                    if (source_file_symbol_idx != UINT32_MAX)
1242288943Sdim                    {
1243288943Sdim                        CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL);
1244288943Sdim                        if (compile_unit_info)
1245288943Sdim                        {
1246288943Sdim                            oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info);
1247288943Sdim                            if (oso_dwarf)
1248288943Sdim                            {
1249288943Sdim                                TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
1250288943Sdim                                if (type_sp)
1251288943Sdim                                {
1252288943Sdim                                    return type_sp;
1253288943Sdim                                }
1254288943Sdim                            }
1255288943Sdim                        }
1256288943Sdim                    }
1257288943Sdim                }
1258288943Sdim            }
1259288943Sdim        }
1260254721Semaste    }
1261288943Sdim
1262288943Sdim    // Only search all .o files for the definition if we don't need the implementation
1263288943Sdim    // because otherwise, with a valid debug map we should have the ObjC class symbol and
1264288943Sdim    // the code above should have found it.
1265288943Sdim    if (must_be_implementation == false)
1266288943Sdim    {
1267288943Sdim        TypeSP type_sp;
1268288943Sdim
1269288943Sdim        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1270288943Sdim            type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
1271288943Sdim            return (bool)type_sp;
1272288943Sdim        });
1273288943Sdim
1274288943Sdim        return type_sp;
1275288943Sdim    }
1276288943Sdim    return TypeSP();
1277254721Semaste}
1278254721Semaste
1279254721Semasteuint32_t
1280254721SemasteSymbolFileDWARFDebugMap::FindTypes
1281254721Semaste(
1282254721Semaste    const SymbolContext& sc,
1283254721Semaste    const ConstString &name,
1284296417Sdim    const CompilerDeclContext *parent_decl_ctx,
1285296417Sdim    bool append,
1286309124Sdim    uint32_t max_matches,
1287309124Sdim    llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1288296417Sdim    TypeMap& types
1289254721Semaste)
1290254721Semaste{
1291254721Semaste    if (!append)
1292254721Semaste        types.Clear();
1293254721Semaste
1294254721Semaste    const uint32_t initial_types_size = types.GetSize();
1295254721Semaste    SymbolFileDWARF *oso_dwarf;
1296254721Semaste
1297254721Semaste    if (sc.comp_unit)
1298254721Semaste    {
1299254721Semaste        oso_dwarf = GetSymbolFile (sc);
1300254721Semaste        if (oso_dwarf)
1301309124Sdim            return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
1302254721Semaste    }
1303254721Semaste    else
1304254721Semaste    {
1305288943Sdim        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1306309124Sdim            oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
1307309124Sdim            if (types.GetSize() >= max_matches)
1308309124Sdim                return true;
1309309124Sdim            else
1310309124Sdim                return false;
1311288943Sdim        });
1312254721Semaste    }
1313254721Semaste
1314254721Semaste    return types.GetSize() - initial_types_size;
1315254721Semaste}
1316254721Semaste
1317254721Semaste//
1318254721Semaste//uint32_t
1319254721Semaste//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
1320254721Semaste//{
1321254721Semaste//  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1322254721Semaste//  if (oso_dwarf)
1323254721Semaste//      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
1324254721Semaste//  return 0;
1325254721Semaste//}
1326254721Semaste
1327254721Semaste
1328296417SdimCompilerDeclContext
1329254721SemasteSymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc,
1330254721Semaste                                        const lldb_private::ConstString &name,
1331296417Sdim                                        const CompilerDeclContext *parent_decl_ctx)
1332254721Semaste{
1333296417Sdim    CompilerDeclContext matching_namespace;
1334254721Semaste    SymbolFileDWARF *oso_dwarf;
1335254721Semaste
1336254721Semaste    if (sc.comp_unit)
1337254721Semaste    {
1338254721Semaste        oso_dwarf = GetSymbolFile (sc);
1339254721Semaste        if (oso_dwarf)
1340296417Sdim            matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
1341254721Semaste    }
1342254721Semaste    else
1343254721Semaste    {
1344288943Sdim        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1345296417Sdim            matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
1346254721Semaste
1347288943Sdim            return (bool)matching_namespace;
1348288943Sdim        });
1349254721Semaste    }
1350254721Semaste
1351254721Semaste    return matching_namespace;
1352254721Semaste}
1353254721Semaste
1354254721Semaste//------------------------------------------------------------------
1355254721Semaste// PluginInterface protocol
1356254721Semaste//------------------------------------------------------------------
1357254721Semastelldb_private::ConstString
1358254721SemasteSymbolFileDWARFDebugMap::GetPluginName()
1359254721Semaste{
1360254721Semaste    return GetPluginNameStatic();
1361254721Semaste}
1362254721Semaste
1363254721Semasteuint32_t
1364254721SemasteSymbolFileDWARFDebugMap::GetPluginVersion()
1365254721Semaste{
1366254721Semaste    return 1;
1367254721Semaste}
1368254721Semaste
1369254721Semastelldb::CompUnitSP
1370254721SemasteSymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
1371254721Semaste{
1372254721Semaste    if (oso_dwarf)
1373254721Semaste    {
1374254721Semaste        const uint32_t cu_count = GetNumCompileUnits();
1375254721Semaste        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1376254721Semaste        {
1377254721Semaste            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1378254721Semaste            if (oso_symfile == oso_dwarf)
1379254721Semaste            {
1380254721Semaste                if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
1381254721Semaste                    m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
1382254721Semaste
1383254721Semaste                return m_compile_unit_infos[cu_idx].compile_unit_sp;
1384254721Semaste            }
1385254721Semaste        }
1386254721Semaste    }
1387254721Semaste    assert(!"this shouldn't happen");
1388254721Semaste    return lldb::CompUnitSP();
1389254721Semaste}
1390254721Semaste
1391254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo *
1392254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
1393254721Semaste{
1394254721Semaste    if (oso_dwarf)
1395254721Semaste    {
1396254721Semaste        const uint32_t cu_count = GetNumCompileUnits();
1397254721Semaste        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1398254721Semaste        {
1399254721Semaste            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1400254721Semaste            if (oso_symfile == oso_dwarf)
1401254721Semaste            {
1402254721Semaste                return &m_compile_unit_infos[cu_idx];
1403254721Semaste            }
1404254721Semaste        }
1405254721Semaste    }
1406254721Semaste    return NULL;
1407254721Semaste}
1408254721Semaste
1409254721Semastevoid
1410254721SemasteSymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
1411254721Semaste{
1412254721Semaste    if (oso_dwarf)
1413254721Semaste    {
1414254721Semaste        const uint32_t cu_count = GetNumCompileUnits();
1415254721Semaste        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1416254721Semaste        {
1417254721Semaste            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1418254721Semaste            if (oso_symfile == oso_dwarf)
1419254721Semaste            {
1420254721Semaste                if (m_compile_unit_infos[cu_idx].compile_unit_sp)
1421254721Semaste                {
1422254721Semaste                    assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
1423254721Semaste                }
1424254721Semaste                else
1425254721Semaste                {
1426254721Semaste                    m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
1427254721Semaste                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
1428254721Semaste                }
1429254721Semaste            }
1430254721Semaste        }
1431254721Semaste    }
1432254721Semaste}
1433254721Semaste
1434296417SdimCompilerDeclContext
1435296417SdimSymbolFileDWARFDebugMap::GetDeclContextForUID (lldb::user_id_t type_uid)
1436254721Semaste{
1437254721Semaste    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1438254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1439254721Semaste    if (oso_dwarf)
1440296417Sdim        return oso_dwarf->GetDeclContextForUID (type_uid);
1441296417Sdim    return CompilerDeclContext();
1442254721Semaste}
1443254721Semaste
1444296417SdimCompilerDeclContext
1445296417SdimSymbolFileDWARFDebugMap::GetDeclContextContainingUID (lldb::user_id_t type_uid)
1446254721Semaste{
1447254721Semaste    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1448254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1449254721Semaste    if (oso_dwarf)
1450296417Sdim        return oso_dwarf->GetDeclContextContainingUID (type_uid);
1451296417Sdim    return CompilerDeclContext();
1452254721Semaste}
1453254721Semaste
1454296417Sdimvoid
1455296417SdimSymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx)
1456296417Sdim{
1457296417Sdim    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1458296417Sdim        oso_dwarf->ParseDeclsForContext (decl_ctx);
1459296417Sdim        return true; // Keep iterating
1460296417Sdim    });
1461296417Sdim}
1462296417Sdim
1463254721Semastebool
1464254721SemasteSymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
1465254721Semaste                                          lldb::addr_t exe_file_addr,
1466309124Sdim                                          lldb::addr_t exe_byte_size,
1467254721Semaste                                          lldb::addr_t oso_file_addr,
1468254721Semaste                                          lldb::addr_t oso_byte_size)
1469254721Semaste{
1470254721Semaste    const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
1471254721Semaste    if (debug_map_idx != UINT32_MAX)
1472254721Semaste    {
1473254721Semaste        DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
1474254721Semaste        debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
1475309124Sdim        addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
1476309124Sdim        if (range_size == 0)
1477309124Sdim        {
1478309124Sdim            range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
1479309124Sdim            if (range_size == 0)
1480309124Sdim                range_size = 1;
1481309124Sdim        }
1482309124Sdim        cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
1483254721Semaste        return true;
1484254721Semaste    }
1485254721Semaste    return false;
1486254721Semaste}
1487254721Semaste
1488254721Semastevoid
1489254721SemasteSymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
1490254721Semaste{
1491254721Semaste    cu_info->file_range_map.Sort();
1492254721Semaste#if defined(DEBUG_OSO_DMAP)
1493254721Semaste    const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1494254721Semaste    const size_t n = oso_file_range_map.GetSize();
1495254721Semaste    printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
1496254721Semaste            cu_info,
1497254721Semaste            cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
1498254721Semaste    for (size_t i=0; i<n; ++i)
1499254721Semaste    {
1500254721Semaste        const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
1501254721Semaste        printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
1502254721Semaste                entry.GetRangeBase(), entry.GetRangeEnd(),
1503254721Semaste                entry.data, entry.data + entry.GetByteSize());
1504254721Semaste    }
1505254721Semaste#endif
1506254721Semaste}
1507254721Semaste
1508254721Semastelldb::addr_t
1509254721SemasteSymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
1510254721Semaste{
1511254721Semaste    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
1512254721Semaste    if (cu_info)
1513254721Semaste    {
1514254721Semaste        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1515254721Semaste        if (oso_range_entry)
1516254721Semaste        {
1517254721Semaste            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1518254721Semaste            if (debug_map_entry)
1519254721Semaste            {
1520254721Semaste                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1521254721Semaste                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1522254721Semaste                return exe_file_addr;
1523254721Semaste            }
1524254721Semaste        }
1525254721Semaste    }
1526254721Semaste    return LLDB_INVALID_ADDRESS;
1527254721Semaste}
1528254721Semaste
1529254721Semastebool
1530254721SemasteSymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
1531254721Semaste{
1532254721Semaste    // Make sure this address hasn't been fixed already
1533254721Semaste    Module *exe_module = GetObjectFile()->GetModule().get();
1534254721Semaste    Module *addr_module = addr.GetModule().get();
1535254721Semaste    if (addr_module == exe_module)
1536254721Semaste        return true; // Address is already in terms of the main executable module
1537254721Semaste
1538254721Semaste    CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
1539254721Semaste    if (cu_info)
1540254721Semaste    {
1541254721Semaste        const lldb::addr_t oso_file_addr = addr.GetFileAddress();
1542254721Semaste        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1543254721Semaste        if (oso_range_entry)
1544254721Semaste        {
1545254721Semaste            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1546254721Semaste            if (debug_map_entry)
1547254721Semaste            {
1548254721Semaste                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1549254721Semaste                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1550254721Semaste                return exe_module->ResolveFileAddress(exe_file_addr, addr);
1551254721Semaste            }
1552254721Semaste        }
1553254721Semaste    }
1554254721Semaste    return true;
1555254721Semaste}
1556254721Semaste
1557254721SemasteLineTable *
1558254721SemasteSymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
1559254721Semaste{
1560254721Semaste    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
1561254721Semaste    if (cu_info)
1562254721Semaste        return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
1563254721Semaste    return NULL;
1564254721Semaste}
1565254721Semaste
1566254721Semastesize_t
1567254721SemasteSymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
1568254721Semaste{
1569254721Semaste    size_t num_line_entries_added = 0;
1570254721Semaste    if (debug_aranges && dwarf2Data)
1571254721Semaste    {
1572254721Semaste        CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
1573254721Semaste        if (compile_unit_info)
1574254721Semaste        {
1575254721Semaste            const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
1576254721Semaste            for (size_t idx = 0;
1577254721Semaste                 idx < file_range_map.GetSize();
1578254721Semaste                 idx++)
1579254721Semaste            {
1580254721Semaste                const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
1581254721Semaste                if (entry)
1582254721Semaste                {
1583254721Semaste                    debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
1584254721Semaste                    num_line_entries_added++;
1585254721Semaste                }
1586254721Semaste            }
1587254721Semaste        }
1588254721Semaste    }
1589254721Semaste    return num_line_entries_added;
1590254721Semaste}
1591