1254721Semaste//===-- 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
10254721Semaste#include "SymbolFileDWARFDebugMap.h"
11254721Semaste
12254721Semaste#include "DWARFDebugAranges.h"
13254721Semaste
14254721Semaste#include "lldb/Core/RangeMap.h"
15254721Semaste#include "lldb/Core/Module.h"
16254721Semaste#include "lldb/Core/ModuleList.h"
17254721Semaste#include "lldb/Core/PluginManager.h"
18254721Semaste#include "lldb/Core/RegularExpression.h"
19254721Semaste#include "lldb/Core/Section.h"
20254721Semaste
21254721Semaste//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
22254721Semaste#if defined(DEBUG_OSO_DMAP)
23254721Semaste#include "lldb/Core/StreamFile.h"
24254721Semaste#endif
25254721Semaste#include "lldb/Core/Timer.h"
26254721Semaste
27254721Semaste#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
28254721Semaste#include "lldb/Symbol/CompileUnit.h"
29254721Semaste#include "lldb/Symbol/LineTable.h"
30254721Semaste#include "lldb/Symbol/ObjectFile.h"
31254721Semaste#include "lldb/Symbol/SymbolVendor.h"
32254721Semaste#include "lldb/Symbol/VariableList.h"
33254721Semaste
34254721Semaste#include "LogChannelDWARF.h"
35254721Semaste#include "SymbolFileDWARF.h"
36254721Semaste
37254721Semasteusing namespace lldb;
38254721Semasteusing namespace lldb_private;
39254721Semaste
40254721Semaste// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
41254721Semaste// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
42254721Semaste// (so we can fixup the symbol file id.
43254721Semaste
44254721Semaste
45254721Semaste
46254721Semaste
47254721Semasteconst SymbolFileDWARFDebugMap::FileRangeMap &
48254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
49254721Semaste{
50254721Semaste    if (file_range_map_valid)
51254721Semaste        return file_range_map;
52254721Semaste
53254721Semaste    file_range_map_valid = true;
54254721Semaste
55254721Semaste    Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
56254721Semaste    if (!oso_module)
57254721Semaste        return file_range_map;
58254721Semaste
59254721Semaste    ObjectFile *oso_objfile = oso_module->GetObjectFile();
60254721Semaste    if (!oso_objfile)
61254721Semaste        return file_range_map;
62254721Semaste
63254721Semaste    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
64254721Semaste    if (log)
65254721Semaste    {
66254721Semaste        ConstString object_name (oso_module->GetObjectName());
67254721Semaste        log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
68254721Semaste                    this,
69254721Semaste                    oso_module->GetSpecificationDescription().c_str());
70254721Semaste    }
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();
81254721Semaste
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
85254721Semaste            // file addresses to where things eneded up in the main executable.
86254721Semaste
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;
99254721Semaste
100254721Semaste                    switch (exe_symbol->GetType())
101254721Semaste                    {
102254721Semaste                    default:
103254721Semaste                        break;
104254721Semaste
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.
115254721Semaste
116254721Semaste                            // First we find the original symbol in the .o file's symbol table
117254721Semaste                            Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(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,
125254721Semaste                                                              exe_symbol->GetAddress().GetFileAddress(),
126254721Semaste                                                              oso_fun_symbol->GetAddress().GetFileAddress(),
127254721Semaste                                                              std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
128254721Semaste
129254721Semaste                            }
130254721Semaste                        }
131254721Semaste                        break;
132254721Semaste
133254721Semaste                    case eSymbolTypeData:
134254721Semaste                        {
135254721Semaste                            // For each N_GSYM we remap the address for the global by making
136254721Semaste                            // a new section that we add to the sections found in the .o file.
137254721Semaste                            // This new section has the file address set to what the
138254721Semaste                            // addresses are in the .o file, and the load address is adjusted
139254721Semaste                            // to match where it ended up in the final executable! We do this
140254721Semaste                            // before we parse any dwarf info so that when it goes get parsed
141254721Semaste                            // all section/offset addresses that get registered will resolve
142254721Semaste                            // correctly to the new addresses in the main executable. We
143254721Semaste                            // initially set the section size to be 1 byte, but will need to
144254721Semaste                            // fix up these addresses further after all globals have been
145254721Semaste                            // parsed to span the gaps, or we can find the global variable
146254721Semaste                            // sizes from the DWARF info as we are parsing.
147254721Semaste
148254721Semaste                            // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
149254721Semaste                            Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
150254721Semaste                                                                                                  eSymbolTypeData,
151254721Semaste                                                                                                  Symtab::eDebugNo,
152254721Semaste                                                                                                  Symtab::eVisibilityAny);
153254721Semaste
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,
160254721Semaste                                                              exe_symbol->GetAddress().GetFileAddress(),
161254721Semaste                                                              oso_gsym_symbol->GetAddress().GetFileAddress(),
162254721Semaste                                                              std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
163254721Semaste                            }
164254721Semaste                        }
165254721Semaste                        break;
166254721Semaste                    }
167254721Semaste                }
168254721Semaste            }
169254721Semaste
170254721Semaste            exe_symfile->FinalizeOSOFileRanges (this);
171254721Semaste            // We don't need the symbols anymore for the .o files
172254721Semaste            oso_objfile->ClearSymtab();
173254721Semaste        }
174254721Semaste    }
175254721Semaste    return file_range_map;
176254721Semaste}
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
195254721Semaste    virtual
196254721Semaste    ~DebugMapModule ()
197254721Semaste    {
198254721Semaste    }
199254721Semaste
200254721Semaste
201254721Semaste    virtual SymbolVendor*
202254721Semaste    GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
203254721Semaste    {
204254721Semaste        // Scope for locker
205254721Semaste        if (m_symfile_ap.get() || can_create == false)
206254721Semaste            return m_symfile_ap.get();
207254721Semaste
208254721Semaste        ModuleSP exe_module_sp (m_exe_module_wp.lock());
209254721Semaste        if (exe_module_sp)
210254721Semaste        {
211254721Semaste            // Now get the object file outside of a locking scope
212254721Semaste            ObjectFile *oso_objfile = GetObjectFile ();
213254721Semaste            if (oso_objfile)
214254721Semaste            {
215254721Semaste                Mutex::Locker locker (m_mutex);
216254721Semaste                SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
217254721Semaste                if (symbol_vendor)
218254721Semaste                {
219254721Semaste                    // Set a a pointer to this class to set our OSO DWARF file know
220254721Semaste                    // that the DWARF is being used along with a debug map and that
221254721Semaste                    // it will have the remapped sections that we do below.
222254721Semaste                    SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
223254721Semaste
224254721Semaste                    if (!oso_symfile)
225254721Semaste                        return NULL;
226254721Semaste
227254721Semaste                    ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
228254721Semaste                    SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
229254721Semaste
230254721Semaste                    if (exe_objfile && exe_sym_vendor)
231254721Semaste                    {
232254721Semaste                        if (oso_symfile->GetNumCompileUnits() == 1)
233254721Semaste                        {
234254721Semaste                            oso_symfile->SetDebugMapModule(exe_module_sp);
235254721Semaste                            // Set the ID of the symbol file DWARF to the index of the OSO
236254721Semaste                            // shifted left by 32 bits to provide a unique prefix for any
237254721Semaste                            // UserID's that get created in the symbol file.
238254721Semaste                            oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
239254721Semaste                        }
240254721Semaste                        else
241254721Semaste                        {
242254721Semaste                            oso_symfile->SetID (UINT64_MAX);
243254721Semaste                        }
244254721Semaste                    }
245254721Semaste                    return symbol_vendor;
246254721Semaste                }
247254721Semaste            }
248254721Semaste        }
249254721Semaste        return NULL;
250254721Semaste    }
251254721Semaste
252254721Semasteprotected:
253254721Semaste    ModuleWP m_exe_module_wp;
254254721Semaste    const uint32_t m_cu_idx;
255254721Semaste};
256254721Semaste
257254721Semastevoid
258254721SemasteSymbolFileDWARFDebugMap::Initialize()
259254721Semaste{
260254721Semaste    PluginManager::RegisterPlugin (GetPluginNameStatic(),
261254721Semaste                                   GetPluginDescriptionStatic(),
262254721Semaste                                   CreateInstance);
263254721Semaste}
264254721Semaste
265254721Semastevoid
266254721SemasteSymbolFileDWARFDebugMap::Terminate()
267254721Semaste{
268254721Semaste    PluginManager::UnregisterPlugin (CreateInstance);
269254721Semaste}
270254721Semaste
271254721Semaste
272254721Semastelldb_private::ConstString
273254721SemasteSymbolFileDWARFDebugMap::GetPluginNameStatic()
274254721Semaste{
275254721Semaste    static ConstString g_name("dwarf-debugmap");
276254721Semaste    return g_name;
277254721Semaste}
278254721Semaste
279254721Semasteconst char *
280254721SemasteSymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
281254721Semaste{
282254721Semaste    return "DWARF and DWARF3 debug symbol file reader (debug map).";
283254721Semaste}
284254721Semaste
285254721SemasteSymbolFile*
286254721SemasteSymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
287254721Semaste{
288254721Semaste    return new SymbolFileDWARFDebugMap (obj_file);
289254721Semaste}
290254721Semaste
291254721Semaste
292254721SemasteSymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
293254721Semaste    SymbolFile(ofile),
294254721Semaste    m_flags(),
295254721Semaste    m_compile_unit_infos(),
296254721Semaste    m_func_indexes(),
297254721Semaste    m_glob_indexes(),
298254721Semaste    m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
299254721Semaste{
300254721Semaste}
301254721Semaste
302254721Semaste
303254721SemasteSymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
304254721Semaste{
305254721Semaste}
306254721Semaste
307254721Semastevoid
308254721SemasteSymbolFileDWARFDebugMap::InitializeObject()
309254721Semaste{
310254721Semaste    // Install our external AST source callbacks so we can complete Clang types.
311254721Semaste    llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
312254721Semaste        new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl,
313254721Semaste                                             SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl,
314254721Semaste                                             NULL,
315254721Semaste                                             SymbolFileDWARFDebugMap::LayoutRecordType,
316254721Semaste                                             this));
317254721Semaste
318254721Semaste    GetClangASTContext().SetExternalSource (ast_source_ap);
319254721Semaste}
320254721Semaste
321254721Semastevoid
322254721SemasteSymbolFileDWARFDebugMap::InitOSO()
323254721Semaste{
324254721Semaste    if (m_flags.test(kHaveInitializedOSOs))
325254721Semaste        return;
326254721Semaste
327254721Semaste    m_flags.set(kHaveInitializedOSOs);
328254721Semaste
329254721Semaste    // If the object file has been stripped, there is no sense in looking further
330254721Semaste    // as all of the debug symbols for the debug map will not be available
331254721Semaste    if (m_obj_file->IsStripped())
332254721Semaste        return;
333254721Semaste
334254721Semaste    // Also make sure the file type is some sort of executable. Core files, debug
335254721Semaste    // info files (dSYM), object files (.o files), and stub libraries all can
336254721Semaste    switch (m_obj_file->GetType())
337254721Semaste    {
338254721Semaste        case ObjectFile::eTypeInvalid:
339254721Semaste        case ObjectFile::eTypeCoreFile:
340254721Semaste        case ObjectFile::eTypeDebugInfo:
341254721Semaste        case ObjectFile::eTypeObjectFile:
342254721Semaste        case ObjectFile::eTypeStubLibrary:
343254721Semaste        case ObjectFile::eTypeUnknown:
344254721Semaste            return;
345254721Semaste
346254721Semaste        case ObjectFile::eTypeExecutable:
347254721Semaste        case ObjectFile::eTypeDynamicLinker:
348254721Semaste        case ObjectFile::eTypeSharedLibrary:
349254721Semaste            break;
350254721Semaste    }
351254721Semaste
352254721Semaste    // In order to get the abilities of this plug-in, we look at the list of
353254721Semaste    // N_OSO entries (object files) from the symbol table and make sure that
354254721Semaste    // these files exist and also contain valid DWARF. If we get any of that
355254721Semaste    // then we return the abilities of the first N_OSO's DWARF.
356254721Semaste
357254721Semaste    Symtab* symtab = m_obj_file->GetSymtab();
358254721Semaste    if (symtab)
359254721Semaste    {
360254721Semaste        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
361254721Semaste
362254721Semaste        std::vector<uint32_t> oso_indexes;
363254721Semaste        // When a mach-o symbol is encoded, the n_type field is encoded in bits
364254721Semaste        // 23:16, and the n_desc field is encoded in bits 15:0.
365254721Semaste        //
366254721Semaste        // To find all N_OSO entries that are part of the DWARF + debug map
367254721Semaste        // we find only object file symbols with the flags value as follows:
368254721Semaste        // bits 23:16 == 0x66 (N_OSO)
369254721Semaste        // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
370254721Semaste        const uint32_t k_oso_symbol_flags_value = 0x660001u;
371254721Semaste
372254721Semaste        const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
373254721Semaste
374254721Semaste        if (oso_index_count > 0)
375254721Semaste        {
376254721Semaste            symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
377254721Semaste            symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
378254721Semaste
379254721Semaste            symtab->SortSymbolIndexesByValue(m_func_indexes, true);
380254721Semaste            symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
381254721Semaste
382254721Semaste            for (uint32_t sym_idx : m_func_indexes)
383254721Semaste            {
384254721Semaste                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
385254721Semaste                lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
386254721Semaste                lldb::addr_t byte_size = symbol->GetByteSize();
387254721Semaste                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
388254721Semaste                m_debug_map.Append(debug_map_entry);
389254721Semaste            }
390254721Semaste            for (uint32_t sym_idx : m_glob_indexes)
391254721Semaste            {
392254721Semaste                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
393254721Semaste                lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
394254721Semaste                lldb::addr_t byte_size = symbol->GetByteSize();
395254721Semaste                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
396254721Semaste                m_debug_map.Append(debug_map_entry);
397254721Semaste            }
398254721Semaste            m_debug_map.Sort();
399254721Semaste
400254721Semaste            m_compile_unit_infos.resize(oso_index_count);
401254721Semaste
402254721Semaste            for (uint32_t i=0; i<oso_index_count; ++i)
403254721Semaste            {
404254721Semaste                const uint32_t so_idx = oso_indexes[i] - 1;
405254721Semaste                const uint32_t oso_idx = oso_indexes[i];
406254721Semaste                const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
407254721Semaste                const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
408254721Semaste                if (so_symbol &&
409254721Semaste                    oso_symbol &&
410254721Semaste                    so_symbol->GetType() == eSymbolTypeSourceFile &&
411254721Semaste                    oso_symbol->GetType() == eSymbolTypeObjectFile)
412254721Semaste                {
413254721Semaste                    m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
414254721Semaste                    m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
415254721Semaste                    TimeValue oso_mod_time;
416254721Semaste                    oso_mod_time.OffsetWithSeconds(oso_symbol->GetAddress().GetOffset());
417254721Semaste                    m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
418254721Semaste                    uint32_t sibling_idx = so_symbol->GetSiblingIndex();
419254721Semaste                    // The sibling index can't be less that or equal to the current index "i"
420254721Semaste                    if (sibling_idx <= i)
421254721Semaste                    {
422254721Semaste                        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());
423254721Semaste                    }
424254721Semaste                    else
425254721Semaste                    {
426254721Semaste                        const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
427254721Semaste                        m_compile_unit_infos[i].first_symbol_index = so_idx;
428254721Semaste                        m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
429254721Semaste                        m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
430254721Semaste                        m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
431254721Semaste
432254721Semaste                        if (log)
433254721Semaste                            log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
434254721Semaste                    }
435254721Semaste                }
436254721Semaste                else
437254721Semaste                {
438254721Semaste                    if (oso_symbol == NULL)
439254721Semaste                        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);
440254721Semaste                    else if (so_symbol == NULL)
441254721Semaste                        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);
442254721Semaste                    else if (so_symbol->GetType() != eSymbolTypeSourceFile)
443254721Semaste                        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);
444254721Semaste                    else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
445254721Semaste                        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);
446254721Semaste                }
447254721Semaste            }
448254721Semaste        }
449254721Semaste    }
450254721Semaste}
451254721Semaste
452254721SemasteModule *
453254721SemasteSymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
454254721Semaste{
455254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
456254721Semaste    if (oso_idx < cu_count)
457254721Semaste        return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
458254721Semaste    return NULL;
459254721Semaste}
460254721Semaste
461254721SemasteModule *
462254721SemasteSymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
463254721Semaste{
464254721Semaste    if (!comp_unit_info->oso_sp)
465254721Semaste    {
466254721Semaste        auto pos = m_oso_map.find (comp_unit_info->oso_path);
467254721Semaste        if (pos != m_oso_map.end())
468254721Semaste        {
469254721Semaste            comp_unit_info->oso_sp = pos->second;
470254721Semaste        }
471254721Semaste        else
472254721Semaste        {
473254721Semaste            ObjectFile *obj_file = GetObjectFile();
474254721Semaste            comp_unit_info->oso_sp.reset (new OSOInfo());
475254721Semaste            m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
476254721Semaste            const char *oso_path = comp_unit_info->oso_path.GetCString();
477254721Semaste            FileSpec oso_file (oso_path, false);
478254721Semaste            ConstString oso_object;
479254721Semaste            if (oso_file.Exists())
480254721Semaste            {
481254721Semaste                TimeValue oso_mod_time (oso_file.GetModificationTime());
482254721Semaste                if (oso_mod_time != comp_unit_info->oso_mod_time)
483254721Semaste                {
484254721Semaste                    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",
485254721Semaste                                                        oso_file.GetPath().c_str(),
486254721Semaste                                                        oso_mod_time.GetAsSecondsSinceJan1_1970(),
487254721Semaste                                                        comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
488254721Semaste                    return NULL;
489254721Semaste                }
490254721Semaste
491254721Semaste            }
492254721Semaste            else
493254721Semaste            {
494254721Semaste                const bool must_exist = true;
495254721Semaste
496254721Semaste                if (!ObjectFile::SplitArchivePathWithObject (oso_path,
497254721Semaste                                                             oso_file,
498254721Semaste                                                             oso_object,
499254721Semaste                                                             must_exist))
500254721Semaste                {
501254721Semaste                    return NULL;
502254721Semaste                }
503254721Semaste            }
504254721Semaste            // Always create a new module for .o files. Why? Because we
505254721Semaste            // use the debug map, to add new sections to each .o file and
506254721Semaste            // even though a .o file might not have changed, the sections
507254721Semaste            // that get added to the .o file can change.
508254721Semaste            comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
509254721Semaste                                                                         GetCompUnitInfoIndex(comp_unit_info),
510254721Semaste                                                                         oso_file,
511254721Semaste                                                                         m_obj_file->GetModule()->GetArchitecture(),
512254721Semaste                                                                         oso_object ? &oso_object : NULL,
513254721Semaste                                                                         0,
514254721Semaste                                                                         oso_object ? &comp_unit_info->oso_mod_time : NULL));
515254721Semaste        }
516254721Semaste    }
517254721Semaste    if (comp_unit_info->oso_sp)
518254721Semaste        return comp_unit_info->oso_sp->module_sp.get();
519254721Semaste    return NULL;
520254721Semaste}
521254721Semaste
522254721Semaste
523254721Semastebool
524254721SemasteSymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
525254721Semaste{
526254721Semaste    if (oso_idx < m_compile_unit_infos.size())
527254721Semaste    {
528254721Semaste        if (m_compile_unit_infos[oso_idx].so_file)
529254721Semaste        {
530254721Semaste            file_spec = m_compile_unit_infos[oso_idx].so_file;
531254721Semaste            return true;
532254721Semaste        }
533254721Semaste    }
534254721Semaste    return false;
535254721Semaste}
536254721Semaste
537254721Semaste
538254721Semaste
539254721SemasteObjectFile *
540254721SemasteSymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
541254721Semaste{
542254721Semaste    Module *oso_module = GetModuleByOSOIndex (oso_idx);
543254721Semaste    if (oso_module)
544254721Semaste        return oso_module->GetObjectFile();
545254721Semaste    return NULL;
546254721Semaste}
547254721Semaste
548254721SemasteSymbolFileDWARF *
549254721SemasteSymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
550254721Semaste{
551254721Semaste    CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
552254721Semaste    if (comp_unit_info)
553254721Semaste        return GetSymbolFileByCompUnitInfo (comp_unit_info);
554254721Semaste    return NULL;
555254721Semaste}
556254721Semaste
557254721SemasteObjectFile *
558254721SemasteSymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
559254721Semaste{
560254721Semaste    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
561254721Semaste    if (oso_module)
562254721Semaste        return oso_module->GetObjectFile();
563254721Semaste    return NULL;
564254721Semaste}
565254721Semaste
566254721Semaste
567254721Semasteuint32_t
568254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
569254721Semaste{
570254721Semaste    if (!m_compile_unit_infos.empty())
571254721Semaste    {
572254721Semaste        const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
573254721Semaste        const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
574254721Semaste        if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
575254721Semaste            return comp_unit_info - first_comp_unit_info;
576254721Semaste    }
577254721Semaste    return UINT32_MAX;
578254721Semaste}
579254721Semaste
580254721SemasteSymbolFileDWARF *
581254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
582254721Semaste{
583254721Semaste    if (oso_idx < m_compile_unit_infos.size())
584254721Semaste        return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
585254721Semaste    return NULL;
586254721Semaste}
587254721Semaste
588254721SemasteSymbolFileDWARF *
589254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
590254721Semaste{
591254721Semaste    if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
592254721Semaste        return (SymbolFileDWARF *)sym_file;
593254721Semaste    return NULL;
594254721Semaste}
595254721Semaste
596254721SemasteSymbolFileDWARF *
597254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
598254721Semaste{
599254721Semaste    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
600254721Semaste    if (oso_module)
601254721Semaste    {
602254721Semaste        SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
603254721Semaste        if (sym_vendor)
604254721Semaste            return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
605254721Semaste    }
606254721Semaste    return NULL;
607254721Semaste}
608254721Semaste
609254721Semasteuint32_t
610254721SemasteSymbolFileDWARFDebugMap::CalculateAbilities ()
611254721Semaste{
612254721Semaste    // In order to get the abilities of this plug-in, we look at the list of
613254721Semaste    // N_OSO entries (object files) from the symbol table and make sure that
614254721Semaste    // these files exist and also contain valid DWARF. If we get any of that
615254721Semaste    // then we return the abilities of the first N_OSO's DWARF.
616254721Semaste
617254721Semaste    const uint32_t oso_index_count = GetNumCompileUnits();
618254721Semaste    if (oso_index_count > 0)
619254721Semaste    {
620254721Semaste        InitOSO();
621254721Semaste        if (!m_compile_unit_infos.empty())
622254721Semaste        {
623254721Semaste            return SymbolFile::CompileUnits    |
624254721Semaste                   SymbolFile::Functions       |
625254721Semaste                   SymbolFile::Blocks          |
626254721Semaste                   SymbolFile::GlobalVariables |
627254721Semaste                   SymbolFile::LocalVariables  |
628254721Semaste                   SymbolFile::VariableTypes   |
629254721Semaste                   SymbolFile::LineTables      ;
630254721Semaste        }
631254721Semaste    }
632254721Semaste    return 0;
633254721Semaste}
634254721Semaste
635254721Semasteuint32_t
636254721SemasteSymbolFileDWARFDebugMap::GetNumCompileUnits()
637254721Semaste{
638254721Semaste    InitOSO ();
639254721Semaste    return m_compile_unit_infos.size();
640254721Semaste}
641254721Semaste
642254721Semaste
643254721SemasteCompUnitSP
644254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
645254721Semaste{
646254721Semaste    CompUnitSP comp_unit_sp;
647254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
648254721Semaste
649254721Semaste    if (cu_idx < cu_count)
650254721Semaste    {
651254721Semaste        Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
652254721Semaste        if (oso_module)
653254721Semaste        {
654254721Semaste            FileSpec so_file_spec;
655254721Semaste            if (GetFileSpecForSO (cu_idx, so_file_spec))
656254721Semaste            {
657254721Semaste                // User zero as the ID to match the compile unit at offset
658254721Semaste                // zero in each .o file since each .o file can only have
659254721Semaste                // one compile unit for now.
660254721Semaste                lldb::user_id_t cu_id = 0;
661254721Semaste                m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
662254721Semaste                                                                                    NULL,
663254721Semaste                                                                                    so_file_spec,
664254721Semaste                                                                                    cu_id,
665254721Semaste                                                                                    eLanguageTypeUnknown));
666254721Semaste
667254721Semaste                if (m_compile_unit_infos[cu_idx].compile_unit_sp)
668254721Semaste                {
669254721Semaste                    // Let our symbol vendor know about this compile unit
670254721Semaste                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
671254721Semaste                }
672254721Semaste            }
673254721Semaste        }
674254721Semaste        comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
675254721Semaste    }
676254721Semaste
677254721Semaste    return comp_unit_sp;
678254721Semaste}
679254721Semaste
680254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo *
681254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
682254721Semaste{
683254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
684254721Semaste    for (uint32_t i=0; i<cu_count; ++i)
685254721Semaste    {
686254721Semaste        if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
687254721Semaste            return &m_compile_unit_infos[i];
688254721Semaste    }
689254721Semaste    return NULL;
690254721Semaste}
691254721Semaste
692254721Semaste
693254721Semastesize_t
694254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
695254721Semaste{
696254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
697254721Semaste    for (uint32_t i=0; i<cu_count; ++i)
698254721Semaste    {
699254721Semaste        if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
700254721Semaste            cu_infos.push_back (&m_compile_unit_infos[i]);
701254721Semaste    }
702254721Semaste    return cu_infos.size();
703254721Semaste}
704254721Semaste
705254721Semastelldb::LanguageType
706254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
707254721Semaste{
708254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
709254721Semaste    if (oso_dwarf)
710254721Semaste        return oso_dwarf->ParseCompileUnitLanguage (sc);
711254721Semaste    return eLanguageTypeUnknown;
712254721Semaste}
713254721Semaste
714254721Semastesize_t
715254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
716254721Semaste{
717254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
718254721Semaste    if (oso_dwarf)
719254721Semaste        return oso_dwarf->ParseCompileUnitFunctions (sc);
720254721Semaste    return 0;
721254721Semaste}
722254721Semaste
723254721Semastebool
724254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
725254721Semaste{
726254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
727254721Semaste    if (oso_dwarf)
728254721Semaste        return oso_dwarf->ParseCompileUnitLineTable (sc);
729254721Semaste    return false;
730254721Semaste}
731254721Semaste
732254721Semastebool
733254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
734254721Semaste{
735254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
736254721Semaste    if (oso_dwarf)
737254721Semaste        return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
738254721Semaste    return false;
739254721Semaste}
740254721Semaste
741254721Semaste
742254721Semastesize_t
743254721SemasteSymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
744254721Semaste{
745254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
746254721Semaste    if (oso_dwarf)
747254721Semaste        return oso_dwarf->ParseFunctionBlocks (sc);
748254721Semaste    return 0;
749254721Semaste}
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
761254721Semaste
762254721Semastesize_t
763254721SemasteSymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
764254721Semaste{
765254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
766254721Semaste    if (oso_dwarf)
767254721Semaste        return oso_dwarf->ParseVariablesForContext (sc);
768254721Semaste    return 0;
769254721Semaste}
770254721Semaste
771254721Semaste
772254721Semaste
773254721SemasteType*
774254721SemasteSymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
775254721Semaste{
776254721Semaste    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
777254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
778254721Semaste    if (oso_dwarf)
779254721Semaste        return oso_dwarf->ResolveTypeUID (type_uid);
780254721Semaste    return NULL;
781254721Semaste}
782254721Semaste
783254721Semastebool
784254721SemasteSymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (ClangASTType& clang_type)
785254721Semaste{
786254721Semaste    // We have a struct/union/class/enum that needs to be fully resolved.
787254721Semaste    return false;
788254721Semaste}
789254721Semaste
790254721Semasteuint32_t
791254721SemasteSymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
792254721Semaste{
793254721Semaste    uint32_t resolved_flags = 0;
794254721Semaste    Symtab* symtab = m_obj_file->GetSymtab();
795254721Semaste    if (symtab)
796254721Semaste    {
797254721Semaste        const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
798254721Semaste
799254721Semaste        const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
800254721Semaste        if (debug_map_entry)
801254721Semaste        {
802254721Semaste
803254721Semaste            sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
804254721Semaste
805254721Semaste            if (sc.symbol != NULL)
806254721Semaste            {
807254721Semaste                resolved_flags |= eSymbolContextSymbol;
808254721Semaste
809254721Semaste                uint32_t oso_idx = 0;
810254721Semaste                CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
811254721Semaste                if (comp_unit_info)
812254721Semaste                {
813254721Semaste                    comp_unit_info->GetFileRangeMap(this);
814254721Semaste                    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
815254721Semaste                    if (oso_module)
816254721Semaste                    {
817254721Semaste                        lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
818254721Semaste                        Address oso_so_addr;
819254721Semaste                        if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
820254721Semaste                        {
821254721Semaste                            resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
822254721Semaste                        }
823254721Semaste                    }
824254721Semaste                }
825254721Semaste            }
826254721Semaste        }
827254721Semaste    }
828254721Semaste    return resolved_flags;
829254721Semaste}
830254721Semaste
831254721Semaste
832254721Semasteuint32_t
833254721SemasteSymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
834254721Semaste{
835254721Semaste    const uint32_t initial = sc_list.GetSize();
836254721Semaste    const uint32_t cu_count = GetNumCompileUnits();
837254721Semaste
838254721Semaste    for (uint32_t i=0; i<cu_count; ++i)
839254721Semaste    {
840254721Semaste        // If we are checking for inlines, then we need to look through all
841254721Semaste        // compile units no matter if "file_spec" matches.
842254721Semaste        bool resolve = check_inlines;
843254721Semaste
844254721Semaste        if (!resolve)
845254721Semaste        {
846254721Semaste            FileSpec so_file_spec;
847254721Semaste            if (GetFileSpecForSO (i, so_file_spec))
848254721Semaste            {
849254721Semaste                // Match the full path if the incoming file_spec has a directory (not just a basename)
850263363Semaste                const bool full_match = (bool)file_spec.GetDirectory();
851254721Semaste                resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
852254721Semaste            }
853254721Semaste        }
854254721Semaste        if (resolve)
855254721Semaste        {
856254721Semaste            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
857254721Semaste            if (oso_dwarf)
858254721Semaste                oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
859254721Semaste        }
860254721Semaste    }
861254721Semaste    return sc_list.GetSize() - initial;
862254721Semaste}
863254721Semaste
864254721Semasteuint32_t
865254721SemasteSymbolFileDWARFDebugMap::PrivateFindGlobalVariables
866254721Semaste(
867254721Semaste    const ConstString &name,
868254721Semaste    const ClangNamespaceDecl *namespace_decl,
869254721Semaste    const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
870254721Semaste    uint32_t max_matches,
871254721Semaste    VariableList& variables
872254721Semaste)
873254721Semaste{
874254721Semaste    const uint32_t original_size = variables.GetSize();
875254721Semaste    const size_t match_count = indexes.size();
876254721Semaste    for (size_t i=0; i<match_count; ++i)
877254721Semaste    {
878254721Semaste        uint32_t oso_idx;
879254721Semaste        CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
880254721Semaste        if (comp_unit_info)
881254721Semaste        {
882254721Semaste            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
883254721Semaste            if (oso_dwarf)
884254721Semaste            {
885254721Semaste                if (oso_dwarf->FindGlobalVariables(name, namespace_decl, true, max_matches, variables))
886254721Semaste                    if (variables.GetSize() > max_matches)
887254721Semaste                        break;
888254721Semaste            }
889254721Semaste        }
890254721Semaste    }
891254721Semaste    return variables.GetSize() - original_size;
892254721Semaste}
893254721Semaste
894254721Semasteuint32_t
895254721SemasteSymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
896254721Semaste{
897254721Semaste
898254721Semaste    // If we aren't appending the results to this list, then clear the list
899254721Semaste    if (!append)
900254721Semaste        variables.Clear();
901254721Semaste
902254721Semaste    // Remember how many variables are in the list before we search in case
903254721Semaste    // we are appending the results to a variable list.
904254721Semaste    const uint32_t original_size = variables.GetSize();
905254721Semaste
906254721Semaste    uint32_t total_matches = 0;
907254721Semaste    SymbolFileDWARF *oso_dwarf;
908254721Semaste    for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
909254721Semaste    {
910254721Semaste        const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
911254721Semaste                                                                     namespace_decl,
912254721Semaste                                                                     true,
913254721Semaste                                                                     max_matches,
914254721Semaste                                                                     variables);
915254721Semaste        if (oso_matches > 0)
916254721Semaste        {
917254721Semaste            total_matches += oso_matches;
918254721Semaste
919254721Semaste            // Are we getting all matches?
920254721Semaste            if (max_matches == UINT32_MAX)
921254721Semaste                continue;   // Yep, continue getting everything
922254721Semaste
923254721Semaste            // If we have found enough matches, lets get out
924254721Semaste            if (max_matches >= total_matches)
925254721Semaste                break;
926254721Semaste
927254721Semaste            // Update the max matches for any subsequent calls to find globals
928254721Semaste            // in any other object files with DWARF
929254721Semaste            max_matches -= oso_matches;
930254721Semaste        }
931254721Semaste    }
932254721Semaste    // Return the number of variable that were appended to the list
933254721Semaste    return variables.GetSize() - original_size;
934254721Semaste}
935254721Semaste
936254721Semaste
937254721Semasteuint32_t
938254721SemasteSymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
939254721Semaste{
940254721Semaste    // If we aren't appending the results to this list, then clear the list
941254721Semaste    if (!append)
942254721Semaste        variables.Clear();
943254721Semaste
944254721Semaste    // Remember how many variables are in the list before we search in case
945254721Semaste    // we are appending the results to a variable list.
946254721Semaste    const uint32_t original_size = variables.GetSize();
947254721Semaste
948254721Semaste    uint32_t total_matches = 0;
949254721Semaste    SymbolFileDWARF *oso_dwarf;
950254721Semaste    for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
951254721Semaste    {
952254721Semaste        const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
953254721Semaste                                                                     true,
954254721Semaste                                                                     max_matches,
955254721Semaste                                                                     variables);
956254721Semaste        if (oso_matches > 0)
957254721Semaste        {
958254721Semaste            total_matches += oso_matches;
959254721Semaste
960254721Semaste            // Are we getting all matches?
961254721Semaste            if (max_matches == UINT32_MAX)
962254721Semaste                continue;   // Yep, continue getting everything
963254721Semaste
964254721Semaste            // If we have found enough matches, lets get out
965254721Semaste            if (max_matches >= total_matches)
966254721Semaste                break;
967254721Semaste
968254721Semaste            // Update the max matches for any subsequent calls to find globals
969254721Semaste            // in any other object files with DWARF
970254721Semaste            max_matches -= oso_matches;
971254721Semaste        }
972254721Semaste    }
973254721Semaste    // Return the number of variable that were appended to the list
974254721Semaste    return variables.GetSize() - original_size;
975254721Semaste}
976254721Semaste
977254721Semaste
978254721Semasteint
979254721SemasteSymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
980254721Semaste{
981254721Semaste    const uint32_t symbol_idx = *symbol_idx_ptr;
982254721Semaste
983254721Semaste    if (symbol_idx < comp_unit_info->first_symbol_index)
984254721Semaste        return -1;
985254721Semaste
986254721Semaste    if (symbol_idx <= comp_unit_info->last_symbol_index)
987254721Semaste        return 0;
988254721Semaste
989254721Semaste    return 1;
990254721Semaste}
991254721Semaste
992254721Semaste
993254721Semasteint
994254721SemasteSymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
995254721Semaste{
996254721Semaste    const user_id_t symbol_id = *symbol_idx_ptr;
997254721Semaste
998254721Semaste    if (symbol_id < comp_unit_info->first_symbol_id)
999254721Semaste        return -1;
1000254721Semaste
1001254721Semaste    if (symbol_id <= comp_unit_info->last_symbol_id)
1002254721Semaste        return 0;
1003254721Semaste
1004254721Semaste    return 1;
1005254721Semaste}
1006254721Semaste
1007254721Semaste
1008254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo*
1009254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
1010254721Semaste{
1011254721Semaste    const uint32_t oso_index_count = m_compile_unit_infos.size();
1012254721Semaste    CompileUnitInfo *comp_unit_info = NULL;
1013254721Semaste    if (oso_index_count)
1014254721Semaste    {
1015254721Semaste        comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
1016254721Semaste                                                   &m_compile_unit_infos[0],
1017254721Semaste                                                   m_compile_unit_infos.size(),
1018254721Semaste                                                   sizeof(CompileUnitInfo),
1019254721Semaste                                                   (ComparisonFunction)SymbolContainsSymbolWithIndex);
1020254721Semaste    }
1021254721Semaste
1022254721Semaste    if (oso_idx_ptr)
1023254721Semaste    {
1024254721Semaste        if (comp_unit_info != NULL)
1025254721Semaste            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1026254721Semaste        else
1027254721Semaste            *oso_idx_ptr = UINT32_MAX;
1028254721Semaste    }
1029254721Semaste    return comp_unit_info;
1030254721Semaste}
1031254721Semaste
1032254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo*
1033254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
1034254721Semaste{
1035254721Semaste    const uint32_t oso_index_count = m_compile_unit_infos.size();
1036254721Semaste    CompileUnitInfo *comp_unit_info = NULL;
1037254721Semaste    if (oso_index_count)
1038254721Semaste    {
1039254721Semaste        comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
1040254721Semaste                                                      &m_compile_unit_infos[0],
1041254721Semaste                                                      m_compile_unit_infos.size(),
1042254721Semaste                                                      sizeof(CompileUnitInfo),
1043254721Semaste                                                      (ComparisonFunction)SymbolContainsSymbolWithID);
1044254721Semaste    }
1045254721Semaste
1046254721Semaste    if (oso_idx_ptr)
1047254721Semaste    {
1048254721Semaste        if (comp_unit_info != NULL)
1049254721Semaste            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1050254721Semaste        else
1051254721Semaste            *oso_idx_ptr = UINT32_MAX;
1052254721Semaste    }
1053254721Semaste    return comp_unit_info;
1054254721Semaste}
1055254721Semaste
1056254721Semaste
1057254721Semastestatic void
1058254721SemasteRemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
1059254721Semaste{
1060254721Semaste    // We found functions in .o files. Not all functions in the .o files
1061254721Semaste    // will have made it into the final output file. The ones that did
1062254721Semaste    // make it into the final output file will have a section whose module
1063254721Semaste    // matches the module from the ObjectFile for this SymbolFile. When
1064254721Semaste    // the modules don't match, then we have something that was in a
1065254721Semaste    // .o file, but doesn't map to anything in the final executable.
1066254721Semaste    uint32_t i=start_idx;
1067254721Semaste    while (i < sc_list.GetSize())
1068254721Semaste    {
1069254721Semaste        SymbolContext sc;
1070254721Semaste        sc_list.GetContextAtIndex(i, sc);
1071254721Semaste        if (sc.function)
1072254721Semaste        {
1073254721Semaste            const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
1074254721Semaste            if (section_sp->GetModule() != module_sp)
1075254721Semaste            {
1076254721Semaste                sc_list.RemoveContextAtIndex(i);
1077254721Semaste                continue;
1078254721Semaste            }
1079254721Semaste        }
1080254721Semaste        ++i;
1081254721Semaste    }
1082254721Semaste}
1083254721Semaste
1084254721Semasteuint32_t
1085254721SemasteSymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
1086254721Semaste{
1087254721Semaste    Timer scoped_timer (__PRETTY_FUNCTION__,
1088254721Semaste                        "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1089254721Semaste                        name.GetCString());
1090254721Semaste
1091254721Semaste    uint32_t initial_size = 0;
1092254721Semaste    if (append)
1093254721Semaste        initial_size = sc_list.GetSize();
1094254721Semaste    else
1095254721Semaste        sc_list.Clear();
1096254721Semaste
1097254721Semaste    uint32_t oso_idx = 0;
1098254721Semaste    SymbolFileDWARF *oso_dwarf;
1099254721Semaste    while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
1100254721Semaste    {
1101254721Semaste        uint32_t sc_idx = sc_list.GetSize();
1102254721Semaste        if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list))
1103254721Semaste        {
1104254721Semaste            RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1105254721Semaste        }
1106254721Semaste    }
1107254721Semaste
1108254721Semaste    return sc_list.GetSize() - initial_size;
1109254721Semaste}
1110254721Semaste
1111254721Semaste
1112254721Semasteuint32_t
1113254721SemasteSymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
1114254721Semaste{
1115254721Semaste    Timer scoped_timer (__PRETTY_FUNCTION__,
1116254721Semaste                        "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1117254721Semaste                        regex.GetText());
1118254721Semaste
1119254721Semaste    uint32_t initial_size = 0;
1120254721Semaste    if (append)
1121254721Semaste        initial_size = sc_list.GetSize();
1122254721Semaste    else
1123254721Semaste        sc_list.Clear();
1124254721Semaste
1125254721Semaste    uint32_t oso_idx = 0;
1126254721Semaste    SymbolFileDWARF *oso_dwarf;
1127254721Semaste    while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
1128254721Semaste    {
1129254721Semaste        uint32_t sc_idx = sc_list.GetSize();
1130254721Semaste
1131254721Semaste        if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
1132254721Semaste        {
1133254721Semaste            RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1134254721Semaste        }
1135254721Semaste    }
1136254721Semaste
1137254721Semaste    return sc_list.GetSize() - initial_size;
1138254721Semaste}
1139254721Semaste
1140254721Semastesize_t
1141254721SemasteSymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
1142254721Semaste                                   uint32_t type_mask,
1143254721Semaste                                   TypeList &type_list)
1144254721Semaste{
1145254721Semaste    Timer scoped_timer (__PRETTY_FUNCTION__,
1146254721Semaste                        "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1147254721Semaste                        type_mask);
1148254721Semaste
1149254721Semaste
1150254721Semaste    uint32_t initial_size = type_list.GetSize();
1151254721Semaste    SymbolFileDWARF *oso_dwarf = NULL;
1152254721Semaste    if (sc_scope)
1153254721Semaste    {
1154254721Semaste        SymbolContext sc;
1155254721Semaste        sc_scope->CalculateSymbolContext(&sc);
1156254721Semaste
1157254721Semaste        CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
1158254721Semaste        if (cu_info)
1159254721Semaste        {
1160254721Semaste            oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
1161254721Semaste            if (oso_dwarf)
1162254721Semaste                oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1163254721Semaste        }
1164254721Semaste    }
1165254721Semaste    else
1166254721Semaste    {
1167254721Semaste        uint32_t oso_idx = 0;
1168254721Semaste        while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
1169254721Semaste        {
1170254721Semaste            oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1171254721Semaste        }
1172254721Semaste    }
1173254721Semaste    return type_list.GetSize() - initial_size;
1174254721Semaste}
1175254721Semaste
1176254721Semaste
1177254721SemasteTypeSP
1178254721SemasteSymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
1179254721Semaste{
1180254721Semaste    TypeSP type_sp;
1181254721Semaste    SymbolFileDWARF *oso_dwarf;
1182254721Semaste    for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1183254721Semaste    {
1184254721Semaste        type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
1185254721Semaste        if (type_sp)
1186254721Semaste            break;
1187254721Semaste    }
1188254721Semaste    return type_sp;
1189254721Semaste}
1190254721Semaste
1191254721Semaste
1192254721Semaste
1193254721Semastebool
1194254721SemasteSymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
1195254721Semaste{
1196254721Semaste    if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
1197254721Semaste    {
1198254721Semaste        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
1199254721Semaste        SymbolFileDWARF *oso_dwarf;
1200254721Semaste        for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1201254721Semaste        {
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;
1205254721Semaste                break;
1206254721Semaste            }
1207254721Semaste        }
1208254721Semaste    }
1209254721Semaste    return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1210254721Semaste}
1211254721Semaste
1212254721SemasteTypeSP
1213254721SemasteSymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
1214254721Semaste                                                               const ConstString &type_name,
1215254721Semaste                                                               bool must_be_implementation)
1216254721Semaste{
1217254721Semaste    TypeSP type_sp;
1218254721Semaste    SymbolFileDWARF *oso_dwarf;
1219254721Semaste    for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1220254721Semaste    {
1221254721Semaste        type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
1222254721Semaste        if (type_sp)
1223254721Semaste            break;
1224254721Semaste    }
1225254721Semaste    return type_sp;
1226254721Semaste}
1227254721Semaste
1228254721Semasteuint32_t
1229254721SemasteSymbolFileDWARFDebugMap::FindTypes
1230254721Semaste(
1231254721Semaste    const SymbolContext& sc,
1232254721Semaste    const ConstString &name,
1233254721Semaste    const ClangNamespaceDecl *namespace_decl,
1234254721Semaste    bool append,
1235254721Semaste    uint32_t max_matches,
1236254721Semaste    TypeList& types
1237254721Semaste)
1238254721Semaste{
1239254721Semaste    if (!append)
1240254721Semaste        types.Clear();
1241254721Semaste
1242254721Semaste    const uint32_t initial_types_size = types.GetSize();
1243254721Semaste    SymbolFileDWARF *oso_dwarf;
1244254721Semaste
1245254721Semaste    if (sc.comp_unit)
1246254721Semaste    {
1247254721Semaste        oso_dwarf = GetSymbolFile (sc);
1248254721Semaste        if (oso_dwarf)
1249254721Semaste            return oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
1250254721Semaste    }
1251254721Semaste    else
1252254721Semaste    {
1253254721Semaste        uint32_t oso_idx = 0;
1254254721Semaste        while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL)
1255254721Semaste            oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
1256254721Semaste    }
1257254721Semaste
1258254721Semaste    return types.GetSize() - initial_types_size;
1259254721Semaste}
1260254721Semaste
1261254721Semaste//
1262254721Semaste//uint32_t
1263254721Semaste//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)
1264254721Semaste//{
1265254721Semaste//  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1266254721Semaste//  if (oso_dwarf)
1267254721Semaste//      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
1268254721Semaste//  return 0;
1269254721Semaste//}
1270254721Semaste
1271254721Semaste
1272254721SemasteClangNamespaceDecl
1273254721SemasteSymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc,
1274254721Semaste                                        const lldb_private::ConstString &name,
1275254721Semaste                                        const ClangNamespaceDecl *parent_namespace_decl)
1276254721Semaste{
1277254721Semaste    ClangNamespaceDecl matching_namespace;
1278254721Semaste    SymbolFileDWARF *oso_dwarf;
1279254721Semaste
1280254721Semaste    if (sc.comp_unit)
1281254721Semaste    {
1282254721Semaste        oso_dwarf = GetSymbolFile (sc);
1283254721Semaste        if (oso_dwarf)
1284254721Semaste            matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
1285254721Semaste    }
1286254721Semaste    else
1287254721Semaste    {
1288254721Semaste        for (uint32_t oso_idx = 0;
1289254721Semaste             ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL);
1290254721Semaste             ++oso_idx)
1291254721Semaste        {
1292254721Semaste            matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl);
1293254721Semaste
1294254721Semaste            if (matching_namespace)
1295254721Semaste                break;
1296254721Semaste        }
1297254721Semaste    }
1298254721Semaste
1299254721Semaste    return matching_namespace;
1300254721Semaste}
1301254721Semaste
1302254721Semaste//------------------------------------------------------------------
1303254721Semaste// PluginInterface protocol
1304254721Semaste//------------------------------------------------------------------
1305254721Semastelldb_private::ConstString
1306254721SemasteSymbolFileDWARFDebugMap::GetPluginName()
1307254721Semaste{
1308254721Semaste    return GetPluginNameStatic();
1309254721Semaste}
1310254721Semaste
1311254721Semasteuint32_t
1312254721SemasteSymbolFileDWARFDebugMap::GetPluginVersion()
1313254721Semaste{
1314254721Semaste    return 1;
1315254721Semaste}
1316254721Semaste
1317254721Semastelldb::CompUnitSP
1318254721SemasteSymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
1319254721Semaste{
1320254721Semaste    if (oso_dwarf)
1321254721Semaste    {
1322254721Semaste        const uint32_t cu_count = GetNumCompileUnits();
1323254721Semaste        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1324254721Semaste        {
1325254721Semaste            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1326254721Semaste            if (oso_symfile == oso_dwarf)
1327254721Semaste            {
1328254721Semaste                if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
1329254721Semaste                    m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
1330254721Semaste
1331254721Semaste                return m_compile_unit_infos[cu_idx].compile_unit_sp;
1332254721Semaste            }
1333254721Semaste        }
1334254721Semaste    }
1335254721Semaste    assert(!"this shouldn't happen");
1336254721Semaste    return lldb::CompUnitSP();
1337254721Semaste}
1338254721Semaste
1339254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo *
1340254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
1341254721Semaste{
1342254721Semaste    if (oso_dwarf)
1343254721Semaste    {
1344254721Semaste        const uint32_t cu_count = GetNumCompileUnits();
1345254721Semaste        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1346254721Semaste        {
1347254721Semaste            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1348254721Semaste            if (oso_symfile == oso_dwarf)
1349254721Semaste            {
1350254721Semaste                return &m_compile_unit_infos[cu_idx];
1351254721Semaste            }
1352254721Semaste        }
1353254721Semaste    }
1354254721Semaste    return NULL;
1355254721Semaste}
1356254721Semaste
1357254721Semaste
1358254721Semastevoid
1359254721SemasteSymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
1360254721Semaste{
1361254721Semaste    if (oso_dwarf)
1362254721Semaste    {
1363254721Semaste        const uint32_t cu_count = GetNumCompileUnits();
1364254721Semaste        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1365254721Semaste        {
1366254721Semaste            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1367254721Semaste            if (oso_symfile == oso_dwarf)
1368254721Semaste            {
1369254721Semaste                if (m_compile_unit_infos[cu_idx].compile_unit_sp)
1370254721Semaste                {
1371254721Semaste                    assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
1372254721Semaste                }
1373254721Semaste                else
1374254721Semaste                {
1375254721Semaste                    m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
1376254721Semaste                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
1377254721Semaste                }
1378254721Semaste            }
1379254721Semaste        }
1380254721Semaste    }
1381254721Semaste}
1382254721Semaste
1383254721Semaste
1384254721Semastevoid
1385254721SemasteSymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl)
1386254721Semaste{
1387254721Semaste    SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1388254721Semaste    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
1389254721Semaste    if (clang_type)
1390254721Semaste    {
1391254721Semaste        SymbolFileDWARF *oso_dwarf;
1392254721Semaste
1393254721Semaste        for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1394254721Semaste        {
1395254721Semaste            if (oso_dwarf->HasForwardDeclForClangType (clang_type))
1396254721Semaste            {
1397254721Semaste                oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
1398254721Semaste                return;
1399254721Semaste            }
1400254721Semaste        }
1401254721Semaste    }
1402254721Semaste}
1403254721Semaste
1404254721Semastevoid
1405254721SemasteSymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
1406254721Semaste{
1407254721Semaste    SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1408254721Semaste    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
1409254721Semaste    if (clang_type)
1410254721Semaste    {
1411254721Semaste        SymbolFileDWARF *oso_dwarf;
1412254721Semaste
1413254721Semaste        for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1414254721Semaste        {
1415254721Semaste            if (oso_dwarf->HasForwardDeclForClangType (clang_type))
1416254721Semaste            {
1417254721Semaste                oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
1418254721Semaste                return;
1419254721Semaste            }
1420254721Semaste        }
1421254721Semaste    }
1422254721Semaste}
1423254721Semaste
1424254721Semastebool
1425254721SemasteSymbolFileDWARFDebugMap::LayoutRecordType (void *baton,
1426254721Semaste                                           const clang::RecordDecl *record_decl,
1427254721Semaste                                           uint64_t &size,
1428254721Semaste                                           uint64_t &alignment,
1429254721Semaste                                           llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
1430254721Semaste                                           llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
1431254721Semaste                                           llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
1432254721Semaste{
1433254721Semaste    SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
1434254721Semaste    SymbolFileDWARF *oso_dwarf;
1435254721Semaste    for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
1436254721Semaste    {
1437254721Semaste        if (oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets))
1438254721Semaste            return true;
1439254721Semaste    }
1440254721Semaste    return false;
1441254721Semaste}
1442254721Semaste
1443254721Semaste
1444254721Semaste
1445254721Semasteclang::DeclContext*
1446254721SemasteSymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
1447254721Semaste{
1448254721Semaste    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1449254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1450254721Semaste    if (oso_dwarf)
1451254721Semaste        return oso_dwarf->GetClangDeclContextContainingTypeUID (type_uid);
1452254721Semaste    return NULL;
1453254721Semaste}
1454254721Semaste
1455254721Semasteclang::DeclContext*
1456254721SemasteSymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1457254721Semaste{
1458254721Semaste    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1459254721Semaste    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1460254721Semaste    if (oso_dwarf)
1461254721Semaste        return oso_dwarf->GetClangDeclContextForTypeUID (sc, type_uid);
1462254721Semaste    return NULL;
1463254721Semaste}
1464254721Semaste
1465254721Semastebool
1466254721SemasteSymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
1467254721Semaste                                          lldb::addr_t exe_file_addr,
1468254721Semaste                                          lldb::addr_t oso_file_addr,
1469254721Semaste                                          lldb::addr_t oso_byte_size)
1470254721Semaste{
1471254721Semaste    const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
1472254721Semaste    if (debug_map_idx != UINT32_MAX)
1473254721Semaste    {
1474254721Semaste        DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
1475254721Semaste        debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
1476254721Semaste        cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
1477254721Semaste        return true;
1478254721Semaste    }
1479254721Semaste    return false;
1480254721Semaste}
1481254721Semaste
1482254721Semastevoid
1483254721SemasteSymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
1484254721Semaste{
1485254721Semaste    cu_info->file_range_map.Sort();
1486254721Semaste#if defined(DEBUG_OSO_DMAP)
1487254721Semaste    const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1488254721Semaste    const size_t n = oso_file_range_map.GetSize();
1489254721Semaste    printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
1490254721Semaste            cu_info,
1491254721Semaste            cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
1492254721Semaste    for (size_t i=0; i<n; ++i)
1493254721Semaste    {
1494254721Semaste        const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
1495254721Semaste        printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
1496254721Semaste                entry.GetRangeBase(), entry.GetRangeEnd(),
1497254721Semaste                entry.data, entry.data + entry.GetByteSize());
1498254721Semaste    }
1499254721Semaste#endif
1500254721Semaste}
1501254721Semaste
1502254721Semastelldb::addr_t
1503254721SemasteSymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
1504254721Semaste{
1505254721Semaste    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
1506254721Semaste    if (cu_info)
1507254721Semaste    {
1508254721Semaste        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1509254721Semaste        if (oso_range_entry)
1510254721Semaste        {
1511254721Semaste            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1512254721Semaste            if (debug_map_entry)
1513254721Semaste            {
1514254721Semaste                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1515254721Semaste                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1516254721Semaste                return exe_file_addr;
1517254721Semaste            }
1518254721Semaste        }
1519254721Semaste    }
1520254721Semaste    return LLDB_INVALID_ADDRESS;
1521254721Semaste}
1522254721Semaste
1523254721Semastebool
1524254721SemasteSymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
1525254721Semaste{
1526254721Semaste    // Make sure this address hasn't been fixed already
1527254721Semaste    Module *exe_module = GetObjectFile()->GetModule().get();
1528254721Semaste    Module *addr_module = addr.GetModule().get();
1529254721Semaste    if (addr_module == exe_module)
1530254721Semaste        return true; // Address is already in terms of the main executable module
1531254721Semaste
1532254721Semaste    CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
1533254721Semaste    if (cu_info)
1534254721Semaste    {
1535254721Semaste        const lldb::addr_t oso_file_addr = addr.GetFileAddress();
1536254721Semaste        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1537254721Semaste        if (oso_range_entry)
1538254721Semaste        {
1539254721Semaste            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1540254721Semaste            if (debug_map_entry)
1541254721Semaste            {
1542254721Semaste                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1543254721Semaste                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1544254721Semaste                return exe_module->ResolveFileAddress(exe_file_addr, addr);
1545254721Semaste            }
1546254721Semaste        }
1547254721Semaste    }
1548254721Semaste    return true;
1549254721Semaste}
1550254721Semaste
1551254721SemasteLineTable *
1552254721SemasteSymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
1553254721Semaste{
1554254721Semaste    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
1555254721Semaste    if (cu_info)
1556254721Semaste        return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
1557254721Semaste    return NULL;
1558254721Semaste}
1559254721Semaste
1560254721Semastesize_t
1561254721SemasteSymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
1562254721Semaste{
1563254721Semaste    size_t num_line_entries_added = 0;
1564254721Semaste    if (debug_aranges && dwarf2Data)
1565254721Semaste    {
1566254721Semaste        CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
1567254721Semaste        if (compile_unit_info)
1568254721Semaste        {
1569254721Semaste            const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
1570254721Semaste            for (size_t idx = 0;
1571254721Semaste                 idx < file_range_map.GetSize();
1572254721Semaste                 idx++)
1573254721Semaste            {
1574254721Semaste                const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
1575254721Semaste                if (entry)
1576254721Semaste                {
1577254721Semaste                    printf ("[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", entry->GetRangeBase(), entry->GetRangeEnd());
1578254721Semaste                    debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
1579254721Semaste                    num_line_entries_added++;
1580254721Semaste                }
1581254721Semaste            }
1582254721Semaste        }
1583254721Semaste    }
1584254721Semaste    return num_line_entries_added;
1585254721Semaste}
1586254721Semaste
1587