SymbolFileDWARFDebugMap.cpp revision 296417
1//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
14#include "SymbolFileDWARFDebugMap.h"
15
16#include "DWARFDebugAranges.h"
17
18#include "lldb/Core/RangeMap.h"
19#include "lldb/Core/Module.h"
20#include "lldb/Core/ModuleList.h"
21#include "lldb/Core/PluginManager.h"
22#include "lldb/Core/RegularExpression.h"
23#include "lldb/Core/Section.h"
24
25//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
26#if defined(DEBUG_OSO_DMAP)
27#include "lldb/Core/StreamFile.h"
28#endif
29#include "lldb/Core/Timer.h"
30
31#include "lldb/Symbol/CompileUnit.h"
32#include "lldb/Symbol/LineTable.h"
33#include "lldb/Symbol/ObjectFile.h"
34#include "lldb/Symbol/SymbolVendor.h"
35#include "lldb/Symbol/TypeMap.h"
36#include "lldb/Symbol/VariableList.h"
37
38#include "LogChannelDWARF.h"
39#include "SymbolFileDWARF.h"
40
41using namespace lldb;
42using namespace lldb_private;
43
44// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
45// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
46// (so we can fixup the symbol file id.
47
48const SymbolFileDWARFDebugMap::FileRangeMap &
49SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
50{
51    if (file_range_map_valid)
52        return file_range_map;
53
54    file_range_map_valid = true;
55
56    Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
57    if (!oso_module)
58        return file_range_map;
59
60    ObjectFile *oso_objfile = oso_module->GetObjectFile();
61    if (!oso_objfile)
62        return file_range_map;
63
64    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
65    if (log)
66    {
67        ConstString object_name (oso_module->GetObjectName());
68        log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
69                    static_cast<void*>(this),
70                    oso_module->GetSpecificationDescription().c_str());
71    }
72
73    std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
74    if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
75    {
76        for (auto comp_unit_info : cu_infos)
77        {
78            Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
79            ModuleSP oso_module_sp (oso_objfile->GetModule());
80            Symtab *oso_symtab = oso_objfile->GetSymtab();
81
82            ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
83            //SectionList *oso_sections = oso_objfile->Sections();
84            // Now we need to make sections that map from zero based object
85            // file addresses to where things ended up in the main executable.
86
87            assert (comp_unit_info->first_symbol_index != UINT32_MAX);
88            // End index is one past the last valid symbol index
89            const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
90            for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
91                 idx < oso_end_idx;
92                 ++idx)
93            {
94                Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
95                if (exe_symbol)
96                {
97                    if (exe_symbol->IsDebug() == false)
98                        continue;
99
100                    switch (exe_symbol->GetType())
101                    {
102                    default:
103                        break;
104
105                    case eSymbolTypeCode:
106                        {
107                            // For each N_FUN, or function that we run into in the debug map
108                            // we make a new section that we add to the sections found in the
109                            // .o file. This new section has the file address set to what the
110                            // addresses are in the .o file, and the load address is adjusted
111                            // to match where it ended up in the final executable! We do this
112                            // before we parse any dwarf info so that when it goes get parsed
113                            // all section/offset addresses that get registered will resolve
114                            // correctly to the new addresses in the main executable.
115
116                            // First we find the original symbol in the .o file's symbol table
117                            Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
118                                                                                                 eSymbolTypeCode,
119                                                                                                 Symtab::eDebugNo,
120                                                                                                 Symtab::eVisibilityAny);
121                            if (oso_fun_symbol)
122                            {
123                                // Add the inverse OSO file address to debug map entry mapping
124                                exe_symfile->AddOSOFileRange (this,
125                                                              exe_symbol->GetAddressRef().GetFileAddress(),
126                                                              oso_fun_symbol->GetAddressRef().GetFileAddress(),
127                                                              std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
128
129                            }
130                        }
131                        break;
132
133                    case eSymbolTypeData:
134                        {
135                            // For each N_GSYM we remap the address for the global by making
136                            // a new section that we add to the sections found in the .o file.
137                            // This new section has the file address set to what the
138                            // addresses are in the .o file, and the load address is adjusted
139                            // to match where it ended up in the final executable! We do this
140                            // before we parse any dwarf info so that when it goes get parsed
141                            // all section/offset addresses that get registered will resolve
142                            // correctly to the new addresses in the main executable. We
143                            // initially set the section size to be 1 byte, but will need to
144                            // fix up these addresses further after all globals have been
145                            // parsed to span the gaps, or we can find the global variable
146                            // sizes from the DWARF info as we are parsing.
147
148                            // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
149                            Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
150                                                                                                  eSymbolTypeData,
151                                                                                                  Symtab::eDebugNo,
152                                                                                                  Symtab::eVisibilityAny);
153                            if (exe_symbol && oso_gsym_symbol &&
154                                exe_symbol->ValueIsAddress() &&
155                                oso_gsym_symbol->ValueIsAddress())
156                            {
157                                // Add the inverse OSO file address to debug map entry mapping
158                                exe_symfile->AddOSOFileRange (this,
159                                                              exe_symbol->GetAddressRef().GetFileAddress(),
160                                                              oso_gsym_symbol->GetAddressRef().GetFileAddress(),
161                                                              std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
162                            }
163                        }
164                        break;
165                    }
166                }
167            }
168
169            exe_symfile->FinalizeOSOFileRanges (this);
170            // We don't need the symbols anymore for the .o files
171            oso_objfile->ClearSymtab();
172        }
173    }
174    return file_range_map;
175}
176
177class DebugMapModule : public Module
178{
179public:
180    DebugMapModule (const ModuleSP &exe_module_sp,
181                    uint32_t cu_idx,
182                    const FileSpec& file_spec,
183                    const ArchSpec& arch,
184                    const ConstString *object_name,
185                    off_t object_offset,
186                    const TimeValue *object_mod_time_ptr) :
187        Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
188        m_exe_module_wp (exe_module_sp),
189        m_cu_idx (cu_idx)
190    {
191    }
192
193    ~DebugMapModule() override = default;
194
195    SymbolVendor*
196    GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override
197    {
198        // Scope for locker
199        if (m_symfile_ap.get() || can_create == false)
200            return m_symfile_ap.get();
201
202        ModuleSP exe_module_sp (m_exe_module_wp.lock());
203        if (exe_module_sp)
204        {
205            // Now get the object file outside of a locking scope
206            ObjectFile *oso_objfile = GetObjectFile ();
207            if (oso_objfile)
208            {
209                Mutex::Locker locker (m_mutex);
210                SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
211                if (symbol_vendor)
212                {
213                    // Set a pointer to this class to set our OSO DWARF file know
214                    // that the DWARF is being used along with a debug map and that
215                    // it will have the remapped sections that we do below.
216                    SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
217
218                    if (!oso_symfile)
219                        return NULL;
220
221                    ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
222                    SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
223
224                    if (exe_objfile && exe_sym_vendor)
225                    {
226                        oso_symfile->SetDebugMapModule(exe_module_sp);
227                        // Set the ID of the symbol file DWARF to the index of the OSO
228                        // shifted left by 32 bits to provide a unique prefix for any
229                        // UserID's that get created in the symbol file.
230                        oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
231                    }
232                    return symbol_vendor;
233                }
234            }
235        }
236        return NULL;
237    }
238
239protected:
240    ModuleWP m_exe_module_wp;
241    const uint32_t m_cu_idx;
242};
243
244void
245SymbolFileDWARFDebugMap::Initialize()
246{
247    PluginManager::RegisterPlugin (GetPluginNameStatic(),
248                                   GetPluginDescriptionStatic(),
249                                   CreateInstance);
250}
251
252void
253SymbolFileDWARFDebugMap::Terminate()
254{
255    PluginManager::UnregisterPlugin (CreateInstance);
256}
257
258lldb_private::ConstString
259SymbolFileDWARFDebugMap::GetPluginNameStatic()
260{
261    static ConstString g_name("dwarf-debugmap");
262    return g_name;
263}
264
265const char *
266SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
267{
268    return "DWARF and DWARF3 debug symbol file reader (debug map).";
269}
270
271SymbolFile*
272SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
273{
274    return new SymbolFileDWARFDebugMap (obj_file);
275}
276
277SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
278    SymbolFile(ofile),
279    m_flags(),
280    m_compile_unit_infos(),
281    m_func_indexes(),
282    m_glob_indexes(),
283    m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
284{
285}
286
287SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
288{
289}
290
291void
292SymbolFileDWARFDebugMap::InitializeObject()
293{
294}
295
296void
297SymbolFileDWARFDebugMap::InitOSO()
298{
299    if (m_flags.test(kHaveInitializedOSOs))
300        return;
301
302    m_flags.set(kHaveInitializedOSOs);
303
304    // If the object file has been stripped, there is no sense in looking further
305    // as all of the debug symbols for the debug map will not be available
306    if (m_obj_file->IsStripped())
307        return;
308
309    // Also make sure the file type is some sort of executable. Core files, debug
310    // info files (dSYM), object files (.o files), and stub libraries all can
311    switch (m_obj_file->GetType())
312    {
313        case ObjectFile::eTypeInvalid:
314        case ObjectFile::eTypeCoreFile:
315        case ObjectFile::eTypeDebugInfo:
316        case ObjectFile::eTypeObjectFile:
317        case ObjectFile::eTypeStubLibrary:
318        case ObjectFile::eTypeUnknown:
319        case ObjectFile::eTypeJIT:
320            return;
321
322        case ObjectFile::eTypeExecutable:
323        case ObjectFile::eTypeDynamicLinker:
324        case ObjectFile::eTypeSharedLibrary:
325            break;
326    }
327
328    // In order to get the abilities of this plug-in, we look at the list of
329    // N_OSO entries (object files) from the symbol table and make sure that
330    // these files exist and also contain valid DWARF. If we get any of that
331    // then we return the abilities of the first N_OSO's DWARF.
332
333    Symtab* symtab = m_obj_file->GetSymtab();
334    if (symtab)
335    {
336        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
337
338        std::vector<uint32_t> oso_indexes;
339        // When a mach-o symbol is encoded, the n_type field is encoded in bits
340        // 23:16, and the n_desc field is encoded in bits 15:0.
341        //
342        // To find all N_OSO entries that are part of the DWARF + debug map
343        // we find only object file symbols with the flags value as follows:
344        // bits 23:16 == 0x66 (N_OSO)
345        // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
346        const uint32_t k_oso_symbol_flags_value = 0x660001u;
347
348        const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
349
350        if (oso_index_count > 0)
351        {
352            symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
353            symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
354
355            symtab->SortSymbolIndexesByValue(m_func_indexes, true);
356            symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
357
358            for (uint32_t sym_idx : m_func_indexes)
359            {
360                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
361                lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
362                lldb::addr_t byte_size = symbol->GetByteSize();
363                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
364                m_debug_map.Append(debug_map_entry);
365            }
366            for (uint32_t sym_idx : m_glob_indexes)
367            {
368                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
369                lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
370                lldb::addr_t byte_size = symbol->GetByteSize();
371                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
372                m_debug_map.Append(debug_map_entry);
373            }
374            m_debug_map.Sort();
375
376            m_compile_unit_infos.resize(oso_index_count);
377
378            for (uint32_t i=0; i<oso_index_count; ++i)
379            {
380                const uint32_t so_idx = oso_indexes[i] - 1;
381                const uint32_t oso_idx = oso_indexes[i];
382                const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
383                const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
384                if (so_symbol &&
385                    oso_symbol &&
386                    so_symbol->GetType() == eSymbolTypeSourceFile &&
387                    oso_symbol->GetType() == eSymbolTypeObjectFile)
388                {
389                    m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
390                    m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
391                    TimeValue oso_mod_time;
392                    oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0));
393                    m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
394                    uint32_t sibling_idx = so_symbol->GetSiblingIndex();
395                    // The sibling index can't be less that or equal to the current index "i"
396                    if (sibling_idx == UINT32_MAX)
397                    {
398                        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());
399                    }
400                    else
401                    {
402                        const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
403                        m_compile_unit_infos[i].first_symbol_index = so_idx;
404                        m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
405                        m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
406                        m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
407
408                        if (log)
409                            log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
410                    }
411                }
412                else
413                {
414                    if (oso_symbol == NULL)
415                        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);
416                    else if (so_symbol == NULL)
417                        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);
418                    else if (so_symbol->GetType() != eSymbolTypeSourceFile)
419                        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);
420                    else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
421                        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);
422                }
423            }
424        }
425    }
426}
427
428Module *
429SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
430{
431    const uint32_t cu_count = GetNumCompileUnits();
432    if (oso_idx < cu_count)
433        return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
434    return NULL;
435}
436
437Module *
438SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
439{
440    if (!comp_unit_info->oso_sp)
441    {
442        auto pos = m_oso_map.find (comp_unit_info->oso_path);
443        if (pos != m_oso_map.end())
444        {
445            comp_unit_info->oso_sp = pos->second;
446        }
447        else
448        {
449            ObjectFile *obj_file = GetObjectFile();
450            comp_unit_info->oso_sp.reset (new OSOInfo());
451            m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
452            const char *oso_path = comp_unit_info->oso_path.GetCString();
453            FileSpec oso_file (oso_path, false);
454            ConstString oso_object;
455            if (oso_file.Exists())
456            {
457                TimeValue oso_mod_time (oso_file.GetModificationTime());
458                if (oso_mod_time != comp_unit_info->oso_mod_time)
459                {
460                    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",
461                                                        oso_file.GetPath().c_str(),
462                                                        oso_mod_time.GetAsSecondsSinceJan1_1970(),
463                                                        comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
464                    return NULL;
465                }
466
467            }
468            else
469            {
470                const bool must_exist = true;
471
472                if (!ObjectFile::SplitArchivePathWithObject (oso_path,
473                                                             oso_file,
474                                                             oso_object,
475                                                             must_exist))
476                {
477                    return NULL;
478                }
479            }
480            // Always create a new module for .o files. Why? Because we
481            // use the debug map, to add new sections to each .o file and
482            // even though a .o file might not have changed, the sections
483            // that get added to the .o file can change.
484            ArchSpec oso_arch;
485            // Only adopt the architecture from the module (not the vendor or OS)
486            // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx"
487            // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
488            // load command...
489            oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str());
490            comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
491                                                                         GetCompUnitInfoIndex(comp_unit_info),
492                                                                         oso_file,
493                                                                         oso_arch,
494                                                                         oso_object ? &oso_object : NULL,
495                                                                         0,
496                                                                         oso_object ? &comp_unit_info->oso_mod_time : NULL));
497        }
498    }
499    if (comp_unit_info->oso_sp)
500        return comp_unit_info->oso_sp->module_sp.get();
501    return NULL;
502}
503
504bool
505SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
506{
507    if (oso_idx < m_compile_unit_infos.size())
508    {
509        if (m_compile_unit_infos[oso_idx].so_file)
510        {
511            file_spec = m_compile_unit_infos[oso_idx].so_file;
512            return true;
513        }
514    }
515    return false;
516}
517
518ObjectFile *
519SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
520{
521    Module *oso_module = GetModuleByOSOIndex (oso_idx);
522    if (oso_module)
523        return oso_module->GetObjectFile();
524    return NULL;
525}
526
527SymbolFileDWARF *
528SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
529{
530    CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
531    if (comp_unit_info)
532        return GetSymbolFileByCompUnitInfo (comp_unit_info);
533    return NULL;
534}
535
536ObjectFile *
537SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
538{
539    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
540    if (oso_module)
541        return oso_module->GetObjectFile();
542    return NULL;
543}
544
545uint32_t
546SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
547{
548    if (!m_compile_unit_infos.empty())
549    {
550        const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
551        const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
552        if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
553            return comp_unit_info - first_comp_unit_info;
554    }
555    return UINT32_MAX;
556}
557
558SymbolFileDWARF *
559SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
560{
561    if (oso_idx < m_compile_unit_infos.size())
562        return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
563    return NULL;
564}
565
566SymbolFileDWARF *
567SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
568{
569    if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
570        return (SymbolFileDWARF *)sym_file;
571    return NULL;
572}
573
574SymbolFileDWARF *
575SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
576{
577    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
578    if (oso_module)
579    {
580        SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
581        if (sym_vendor)
582            return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
583    }
584    return NULL;
585}
586
587uint32_t
588SymbolFileDWARFDebugMap::CalculateAbilities ()
589{
590    // In order to get the abilities of this plug-in, we look at the list of
591    // N_OSO entries (object files) from the symbol table and make sure that
592    // these files exist and also contain valid DWARF. If we get any of that
593    // then we return the abilities of the first N_OSO's DWARF.
594
595    const uint32_t oso_index_count = GetNumCompileUnits();
596    if (oso_index_count > 0)
597    {
598        InitOSO();
599        if (!m_compile_unit_infos.empty())
600        {
601            return SymbolFile::CompileUnits    |
602                   SymbolFile::Functions       |
603                   SymbolFile::Blocks          |
604                   SymbolFile::GlobalVariables |
605                   SymbolFile::LocalVariables  |
606                   SymbolFile::VariableTypes   |
607                   SymbolFile::LineTables      ;
608        }
609    }
610    return 0;
611}
612
613uint32_t
614SymbolFileDWARFDebugMap::GetNumCompileUnits()
615{
616    InitOSO ();
617    return m_compile_unit_infos.size();
618}
619
620CompUnitSP
621SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
622{
623    CompUnitSP comp_unit_sp;
624    const uint32_t cu_count = GetNumCompileUnits();
625
626    if (cu_idx < cu_count)
627    {
628        Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
629        if (oso_module)
630        {
631            FileSpec so_file_spec;
632            if (GetFileSpecForSO (cu_idx, so_file_spec))
633            {
634                // User zero as the ID to match the compile unit at offset
635                // zero in each .o file since each .o file can only have
636                // one compile unit for now.
637                lldb::user_id_t cu_id = 0;
638                m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
639                                                                                    NULL,
640                                                                                    so_file_spec,
641                                                                                    cu_id,
642                                                                                    eLanguageTypeUnknown,
643                                                                                    false));
644
645                if (m_compile_unit_infos[cu_idx].compile_unit_sp)
646                {
647                    // Let our symbol vendor know about this compile unit
648                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
649                }
650            }
651        }
652        comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
653    }
654
655    return comp_unit_sp;
656}
657
658SymbolFileDWARFDebugMap::CompileUnitInfo *
659SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
660{
661    const uint32_t cu_count = GetNumCompileUnits();
662    for (uint32_t i=0; i<cu_count; ++i)
663    {
664        if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
665            return &m_compile_unit_infos[i];
666    }
667    return NULL;
668}
669
670size_t
671SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
672{
673    const uint32_t cu_count = GetNumCompileUnits();
674    for (uint32_t i=0; i<cu_count; ++i)
675    {
676        if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
677            cu_infos.push_back (&m_compile_unit_infos[i]);
678    }
679    return cu_infos.size();
680}
681
682lldb::LanguageType
683SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
684{
685    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
686    if (oso_dwarf)
687        return oso_dwarf->ParseCompileUnitLanguage (sc);
688    return eLanguageTypeUnknown;
689}
690
691size_t
692SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
693{
694    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
695    if (oso_dwarf)
696        return oso_dwarf->ParseCompileUnitFunctions (sc);
697    return 0;
698}
699
700bool
701SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
702{
703    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
704    if (oso_dwarf)
705        return oso_dwarf->ParseCompileUnitLineTable (sc);
706    return false;
707}
708
709bool
710SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros (const SymbolContext& sc)
711{
712    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
713    if (oso_dwarf)
714        return oso_dwarf->ParseCompileUnitDebugMacros (sc);
715    return false;
716}
717
718bool
719SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
720{
721    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
722    if (oso_dwarf)
723        return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
724    return false;
725}
726
727bool
728SymbolFileDWARFDebugMap::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules)
729{
730    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
731    if (oso_dwarf)
732        return oso_dwarf->ParseImportedModules(sc, imported_modules);
733    return false;
734}
735
736size_t
737SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
738{
739    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
740    if (oso_dwarf)
741        return oso_dwarf->ParseFunctionBlocks (sc);
742    return 0;
743}
744
745size_t
746SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
747{
748    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
749    if (oso_dwarf)
750        return oso_dwarf->ParseTypes (sc);
751    return 0;
752}
753
754size_t
755SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
756{
757    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
758    if (oso_dwarf)
759        return oso_dwarf->ParseVariablesForContext (sc);
760    return 0;
761}
762
763Type*
764SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
765{
766    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
767    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
768    if (oso_dwarf)
769        return oso_dwarf->ResolveTypeUID (type_uid);
770    return NULL;
771}
772
773bool
774SymbolFileDWARFDebugMap::CompleteType (CompilerType& compiler_type)
775{
776    bool success = false;
777    if (compiler_type)
778    {
779        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
780            if (oso_dwarf->HasForwardDeclForClangType (compiler_type))
781            {
782                oso_dwarf->CompleteType (compiler_type);
783                success = true;
784                return true;
785            }
786            return false;
787        });
788    }
789    return success;
790}
791
792uint32_t
793SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
794{
795    uint32_t resolved_flags = 0;
796    Symtab* symtab = m_obj_file->GetSymtab();
797    if (symtab)
798    {
799        const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
800
801        const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
802        if (debug_map_entry)
803        {
804
805            sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
806
807            if (sc.symbol != NULL)
808            {
809                resolved_flags |= eSymbolContextSymbol;
810
811                uint32_t oso_idx = 0;
812                CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
813                if (comp_unit_info)
814                {
815                    comp_unit_info->GetFileRangeMap(this);
816                    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
817                    if (oso_module)
818                    {
819                        lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
820                        Address oso_so_addr;
821                        if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
822                        {
823                            resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
824                        }
825                    }
826                }
827            }
828        }
829    }
830    return resolved_flags;
831}
832
833uint32_t
834SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
835{
836    const uint32_t initial = sc_list.GetSize();
837    const uint32_t cu_count = GetNumCompileUnits();
838
839    for (uint32_t i=0; i<cu_count; ++i)
840    {
841        // If we are checking for inlines, then we need to look through all
842        // compile units no matter if "file_spec" matches.
843        bool resolve = check_inlines;
844
845        if (!resolve)
846        {
847            FileSpec so_file_spec;
848            if (GetFileSpecForSO (i, so_file_spec))
849            {
850                // Match the full path if the incoming file_spec has a directory (not just a basename)
851                const bool full_match = (bool)file_spec.GetDirectory();
852                resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
853            }
854        }
855        if (resolve)
856        {
857            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
858            if (oso_dwarf)
859                oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
860        }
861    }
862    return sc_list.GetSize() - initial;
863}
864
865uint32_t
866SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
867(
868    const ConstString &name,
869    const CompilerDeclContext *parent_decl_ctx,
870    const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
871    uint32_t max_matches,
872    VariableList& variables
873)
874{
875    const uint32_t original_size = variables.GetSize();
876    const size_t match_count = indexes.size();
877    for (size_t i=0; i<match_count; ++i)
878    {
879        uint32_t oso_idx;
880        CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
881        if (comp_unit_info)
882        {
883            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
884            if (oso_dwarf)
885            {
886                if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, max_matches, variables))
887                    if (variables.GetSize() > max_matches)
888                        break;
889            }
890        }
891    }
892    return variables.GetSize() - original_size;
893}
894
895uint32_t
896SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name,
897                                              const CompilerDeclContext *parent_decl_ctx,
898                                              bool append,
899                                              uint32_t max_matches,
900                                              VariableList& variables)
901{
902
903    // If we aren't appending the results to this list, then clear the list
904    if (!append)
905        variables.Clear();
906
907    // Remember how many variables are in the list before we search in case
908    // we are appending the results to a variable list.
909    const uint32_t original_size = variables.GetSize();
910
911    uint32_t total_matches = 0;
912
913    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
914        const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
915                                                                     parent_decl_ctx,
916                                                                     true,
917                                                                     max_matches,
918                                                                     variables);
919        if (oso_matches > 0)
920        {
921            total_matches += oso_matches;
922
923            // Are we getting all matches?
924            if (max_matches == UINT32_MAX)
925                return false;   // Yep, continue getting everything
926
927            // If we have found enough matches, lets get out
928            if (max_matches >= total_matches)
929                return true;
930
931            // Update the max matches for any subsequent calls to find globals
932            // in any other object files with DWARF
933            max_matches -= oso_matches;
934        }
935
936        return false;
937    });
938
939    // Return the number of variable that were appended to the list
940    return variables.GetSize() - original_size;
941}
942
943uint32_t
944SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
945{
946    // If we aren't appending the results to this list, then clear the list
947    if (!append)
948        variables.Clear();
949
950    // Remember how many variables are in the list before we search in case
951    // we are appending the results to a variable list.
952    const uint32_t original_size = variables.GetSize();
953
954    uint32_t total_matches = 0;
955    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
956        const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
957                                                                     true,
958                                                                     max_matches,
959                                                                     variables);
960        if (oso_matches > 0)
961        {
962            total_matches += oso_matches;
963
964            // Are we getting all matches?
965            if (max_matches == UINT32_MAX)
966                return false;   // Yep, continue getting everything
967
968            // If we have found enough matches, lets get out
969            if (max_matches >= total_matches)
970                return true;
971
972            // Update the max matches for any subsequent calls to find globals
973            // in any other object files with DWARF
974            max_matches -= oso_matches;
975        }
976
977        return false;
978    });
979
980    // Return the number of variable that were appended to the list
981    return variables.GetSize() - original_size;
982}
983
984int
985SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
986{
987    const uint32_t symbol_idx = *symbol_idx_ptr;
988
989    if (symbol_idx < comp_unit_info->first_symbol_index)
990        return -1;
991
992    if (symbol_idx <= comp_unit_info->last_symbol_index)
993        return 0;
994
995    return 1;
996}
997
998int
999SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
1000{
1001    const user_id_t symbol_id = *symbol_idx_ptr;
1002
1003    if (symbol_id < comp_unit_info->first_symbol_id)
1004        return -1;
1005
1006    if (symbol_id <= comp_unit_info->last_symbol_id)
1007        return 0;
1008
1009    return 1;
1010}
1011
1012SymbolFileDWARFDebugMap::CompileUnitInfo*
1013SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
1014{
1015    const uint32_t oso_index_count = m_compile_unit_infos.size();
1016    CompileUnitInfo *comp_unit_info = NULL;
1017    if (oso_index_count)
1018    {
1019        comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
1020                                                   &m_compile_unit_infos[0],
1021                                                   m_compile_unit_infos.size(),
1022                                                   sizeof(CompileUnitInfo),
1023                                                   (ComparisonFunction)SymbolContainsSymbolWithIndex);
1024    }
1025
1026    if (oso_idx_ptr)
1027    {
1028        if (comp_unit_info != NULL)
1029            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1030        else
1031            *oso_idx_ptr = UINT32_MAX;
1032    }
1033    return comp_unit_info;
1034}
1035
1036SymbolFileDWARFDebugMap::CompileUnitInfo*
1037SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
1038{
1039    const uint32_t oso_index_count = m_compile_unit_infos.size();
1040    CompileUnitInfo *comp_unit_info = NULL;
1041    if (oso_index_count)
1042    {
1043        comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
1044                                                      &m_compile_unit_infos[0],
1045                                                      m_compile_unit_infos.size(),
1046                                                      sizeof(CompileUnitInfo),
1047                                                      (ComparisonFunction)SymbolContainsSymbolWithID);
1048    }
1049
1050    if (oso_idx_ptr)
1051    {
1052        if (comp_unit_info != NULL)
1053            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
1054        else
1055            *oso_idx_ptr = UINT32_MAX;
1056    }
1057    return comp_unit_info;
1058}
1059
1060static void
1061RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
1062{
1063    // We found functions in .o files. Not all functions in the .o files
1064    // will have made it into the final output file. The ones that did
1065    // make it into the final output file will have a section whose module
1066    // matches the module from the ObjectFile for this SymbolFile. When
1067    // the modules don't match, then we have something that was in a
1068    // .o file, but doesn't map to anything in the final executable.
1069    uint32_t i=start_idx;
1070    while (i < sc_list.GetSize())
1071    {
1072        SymbolContext sc;
1073        sc_list.GetContextAtIndex(i, sc);
1074        if (sc.function)
1075        {
1076            const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
1077            if (section_sp->GetModule() != module_sp)
1078            {
1079                sc_list.RemoveContextAtIndex(i);
1080                continue;
1081            }
1082        }
1083        ++i;
1084    }
1085}
1086
1087uint32_t
1088SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name,
1089                                       const CompilerDeclContext *parent_decl_ctx,
1090                                       uint32_t name_type_mask,
1091                                       bool include_inlines,
1092                                       bool append,
1093                                       SymbolContextList& sc_list)
1094{
1095    Timer scoped_timer (__PRETTY_FUNCTION__,
1096                        "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1097                        name.GetCString());
1098
1099    uint32_t initial_size = 0;
1100    if (append)
1101        initial_size = sc_list.GetSize();
1102    else
1103        sc_list.Clear();
1104
1105    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1106        uint32_t sc_idx = sc_list.GetSize();
1107        if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, true, sc_list))
1108        {
1109            RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1110        }
1111        return false;
1112    });
1113
1114    return sc_list.GetSize() - initial_size;
1115}
1116
1117uint32_t
1118SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
1119{
1120    Timer scoped_timer (__PRETTY_FUNCTION__,
1121                        "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1122                        regex.GetText());
1123
1124    uint32_t initial_size = 0;
1125    if (append)
1126        initial_size = sc_list.GetSize();
1127    else
1128        sc_list.Clear();
1129
1130    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1131        uint32_t sc_idx = sc_list.GetSize();
1132
1133        if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
1134        {
1135            RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
1136        }
1137        return false;
1138    });
1139
1140    return sc_list.GetSize() - initial_size;
1141}
1142
1143size_t
1144SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
1145                                   uint32_t type_mask,
1146                                   TypeList &type_list)
1147{
1148    Timer scoped_timer (__PRETTY_FUNCTION__,
1149                        "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1150                        type_mask);
1151
1152    uint32_t initial_size = type_list.GetSize();
1153    SymbolFileDWARF *oso_dwarf = NULL;
1154    if (sc_scope)
1155    {
1156        SymbolContext sc;
1157        sc_scope->CalculateSymbolContext(&sc);
1158
1159        CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
1160        if (cu_info)
1161        {
1162            oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
1163            if (oso_dwarf)
1164                oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1165        }
1166    }
1167    else
1168    {
1169        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1170            oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
1171            return false;
1172        });
1173    }
1174    return type_list.GetSize() - initial_size;
1175}
1176
1177TypeSP
1178SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
1179{
1180    TypeSP type_sp;
1181    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1182        type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
1183        return ((bool)type_sp);
1184    });
1185    return type_sp;
1186}
1187
1188bool
1189SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
1190{
1191    if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
1192    {
1193        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
1194        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1195            if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
1196            {
1197                m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
1198                return true;
1199            }
1200            return false;
1201        });
1202    }
1203    return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1204}
1205
1206TypeSP
1207SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
1208                                                               const ConstString &type_name,
1209                                                               bool must_be_implementation)
1210{
1211    // If we have a debug map, we will have an Objective C symbol whose name is
1212    // the type name and whose type is eSymbolTypeObjCClass. If we can find that
1213    // symbol and find its containing parent, we can locate the .o file that will
1214    // contain the implementation definition since it will be scoped inside the N_SO
1215    // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
1216    SymbolFileDWARF *oso_dwarf = NULL;
1217    TypeSP type_sp;
1218    ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
1219    if (module_objfile)
1220    {
1221        Symtab *symtab = module_objfile->GetSymtab();
1222        if (symtab)
1223        {
1224            Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny);
1225            if (objc_class_symbol)
1226            {
1227                // Get the N_SO symbol that contains the objective C class symbol as this
1228                // should be the .o file that contains the real definition...
1229                const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
1230
1231                if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile)
1232                {
1233                    const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol);
1234                    if (source_file_symbol_idx != UINT32_MAX)
1235                    {
1236                        CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL);
1237                        if (compile_unit_info)
1238                        {
1239                            oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info);
1240                            if (oso_dwarf)
1241                            {
1242                                TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
1243                                if (type_sp)
1244                                {
1245                                    return type_sp;
1246                                }
1247                            }
1248                        }
1249                    }
1250                }
1251            }
1252        }
1253    }
1254
1255    // Only search all .o files for the definition if we don't need the implementation
1256    // because otherwise, with a valid debug map we should have the ObjC class symbol and
1257    // the code above should have found it.
1258    if (must_be_implementation == false)
1259    {
1260        TypeSP type_sp;
1261
1262        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1263            type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
1264            return (bool)type_sp;
1265        });
1266
1267        return type_sp;
1268    }
1269    return TypeSP();
1270}
1271
1272uint32_t
1273SymbolFileDWARFDebugMap::FindTypes
1274(
1275    const SymbolContext& sc,
1276    const ConstString &name,
1277    const CompilerDeclContext *parent_decl_ctx,
1278    bool append,
1279    uint32_t max_matches,
1280    TypeMap& types
1281)
1282{
1283    if (!append)
1284        types.Clear();
1285
1286    const uint32_t initial_types_size = types.GetSize();
1287    SymbolFileDWARF *oso_dwarf;
1288
1289    if (sc.comp_unit)
1290    {
1291        oso_dwarf = GetSymbolFile (sc);
1292        if (oso_dwarf)
1293            return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, types);
1294    }
1295    else
1296    {
1297        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1298            oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, types);
1299            return false;
1300        });
1301    }
1302
1303    return types.GetSize() - initial_types_size;
1304}
1305
1306//
1307//uint32_t
1308//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)
1309//{
1310//  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1311//  if (oso_dwarf)
1312//      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
1313//  return 0;
1314//}
1315
1316
1317CompilerDeclContext
1318SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc,
1319                                        const lldb_private::ConstString &name,
1320                                        const CompilerDeclContext *parent_decl_ctx)
1321{
1322    CompilerDeclContext matching_namespace;
1323    SymbolFileDWARF *oso_dwarf;
1324
1325    if (sc.comp_unit)
1326    {
1327        oso_dwarf = GetSymbolFile (sc);
1328        if (oso_dwarf)
1329            matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
1330    }
1331    else
1332    {
1333        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1334            matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
1335
1336            return (bool)matching_namespace;
1337        });
1338    }
1339
1340    return matching_namespace;
1341}
1342
1343//------------------------------------------------------------------
1344// PluginInterface protocol
1345//------------------------------------------------------------------
1346lldb_private::ConstString
1347SymbolFileDWARFDebugMap::GetPluginName()
1348{
1349    return GetPluginNameStatic();
1350}
1351
1352uint32_t
1353SymbolFileDWARFDebugMap::GetPluginVersion()
1354{
1355    return 1;
1356}
1357
1358lldb::CompUnitSP
1359SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
1360{
1361    if (oso_dwarf)
1362    {
1363        const uint32_t cu_count = GetNumCompileUnits();
1364        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1365        {
1366            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1367            if (oso_symfile == oso_dwarf)
1368            {
1369                if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
1370                    m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
1371
1372                return m_compile_unit_infos[cu_idx].compile_unit_sp;
1373            }
1374        }
1375    }
1376    assert(!"this shouldn't happen");
1377    return lldb::CompUnitSP();
1378}
1379
1380SymbolFileDWARFDebugMap::CompileUnitInfo *
1381SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
1382{
1383    if (oso_dwarf)
1384    {
1385        const uint32_t cu_count = GetNumCompileUnits();
1386        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1387        {
1388            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1389            if (oso_symfile == oso_dwarf)
1390            {
1391                return &m_compile_unit_infos[cu_idx];
1392            }
1393        }
1394    }
1395    return NULL;
1396}
1397
1398void
1399SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
1400{
1401    if (oso_dwarf)
1402    {
1403        const uint32_t cu_count = GetNumCompileUnits();
1404        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
1405        {
1406            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
1407            if (oso_symfile == oso_dwarf)
1408            {
1409                if (m_compile_unit_infos[cu_idx].compile_unit_sp)
1410                {
1411                    assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
1412                }
1413                else
1414                {
1415                    m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
1416                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
1417                }
1418            }
1419        }
1420    }
1421}
1422
1423CompilerDeclContext
1424SymbolFileDWARFDebugMap::GetDeclContextForUID (lldb::user_id_t type_uid)
1425{
1426    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1427    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1428    if (oso_dwarf)
1429        return oso_dwarf->GetDeclContextForUID (type_uid);
1430    return CompilerDeclContext();
1431}
1432
1433CompilerDeclContext
1434SymbolFileDWARFDebugMap::GetDeclContextContainingUID (lldb::user_id_t type_uid)
1435{
1436    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
1437    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
1438    if (oso_dwarf)
1439        return oso_dwarf->GetDeclContextContainingUID (type_uid);
1440    return CompilerDeclContext();
1441}
1442
1443void
1444SymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx)
1445{
1446    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1447        oso_dwarf->ParseDeclsForContext (decl_ctx);
1448        return true; // Keep iterating
1449    });
1450}
1451
1452bool
1453SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
1454                                          lldb::addr_t exe_file_addr,
1455                                          lldb::addr_t oso_file_addr,
1456                                          lldb::addr_t oso_byte_size)
1457{
1458    const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
1459    if (debug_map_idx != UINT32_MAX)
1460    {
1461        DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
1462        debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
1463        cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
1464        return true;
1465    }
1466    return false;
1467}
1468
1469void
1470SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
1471{
1472    cu_info->file_range_map.Sort();
1473#if defined(DEBUG_OSO_DMAP)
1474    const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1475    const size_t n = oso_file_range_map.GetSize();
1476    printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
1477            cu_info,
1478            cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
1479    for (size_t i=0; i<n; ++i)
1480    {
1481        const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
1482        printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
1483                entry.GetRangeBase(), entry.GetRangeEnd(),
1484                entry.data, entry.data + entry.GetByteSize());
1485    }
1486#endif
1487}
1488
1489lldb::addr_t
1490SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
1491{
1492    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
1493    if (cu_info)
1494    {
1495        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1496        if (oso_range_entry)
1497        {
1498            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1499            if (debug_map_entry)
1500            {
1501                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1502                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1503                return exe_file_addr;
1504            }
1505        }
1506    }
1507    return LLDB_INVALID_ADDRESS;
1508}
1509
1510bool
1511SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
1512{
1513    // Make sure this address hasn't been fixed already
1514    Module *exe_module = GetObjectFile()->GetModule().get();
1515    Module *addr_module = addr.GetModule().get();
1516    if (addr_module == exe_module)
1517        return true; // Address is already in terms of the main executable module
1518
1519    CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
1520    if (cu_info)
1521    {
1522        const lldb::addr_t oso_file_addr = addr.GetFileAddress();
1523        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1524        if (oso_range_entry)
1525        {
1526            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
1527            if (debug_map_entry)
1528            {
1529                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
1530                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
1531                return exe_module->ResolveFileAddress(exe_file_addr, addr);
1532            }
1533        }
1534    }
1535    return true;
1536}
1537
1538LineTable *
1539SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
1540{
1541    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
1542    if (cu_info)
1543        return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
1544    return NULL;
1545}
1546
1547size_t
1548SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
1549{
1550    size_t num_line_entries_added = 0;
1551    if (debug_aranges && dwarf2Data)
1552    {
1553        CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
1554        if (compile_unit_info)
1555        {
1556            const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
1557            for (size_t idx = 0;
1558                 idx < file_range_map.GetSize();
1559                 idx++)
1560            {
1561                const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
1562                if (entry)
1563                {
1564                    debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
1565                    num_line_entries_added++;
1566                }
1567            }
1568        }
1569    }
1570    return num_line_entries_added;
1571}
1572