1 //===-- SymbolFileDWARF.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 #include "SymbolFileDWARF.h"
11 
12 // Other libraries and framework includes
13 #include "clang/AST/ASTConsumer.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclGroup.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/Basic/Builtins.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "clang/Basic/LangOptions.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "clang/Basic/TargetInfo.h"
24 #include "clang/Basic/Specifiers.h"
25 #include "clang/Sema/DeclSpec.h"
26 
27 #include "llvm/Support/Casting.h"
28 
29 #include "lldb/Core/ArchSpec.h"
30 #include "lldb/Core/Module.h"
31 #include "lldb/Core/ModuleList.h"
32 #include "lldb/Core/ModuleSpec.h"
33 #include "lldb/Core/PluginManager.h"
34 #include "lldb/Core/RegularExpression.h"
35 #include "lldb/Core/Scalar.h"
36 #include "lldb/Core/Section.h"
37 #include "lldb/Core/StreamFile.h"
38 #include "lldb/Core/StreamString.h"
39 #include "lldb/Core/Timer.h"
40 #include "lldb/Core/Value.h"
41 
42 #include "lldb/Expression/ClangModulesDeclVendor.h"
43 
44 #include "lldb/Host/FileSystem.h"
45 #include "lldb/Host/Host.h"
46 
47 #include "lldb/Interpreter/OptionValueFileSpecList.h"
48 #include "lldb/Interpreter/OptionValueProperties.h"
49 
50 #include "lldb/Symbol/Block.h"
51 #include "lldb/Symbol/CompileUnit.h"
52 #include "lldb/Symbol/LineTable.h"
53 #include "lldb/Symbol/ObjectFile.h"
54 #include "lldb/Symbol/SymbolVendor.h"
55 #include "lldb/Symbol/VariableList.h"
56 
57 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
58 #include "Plugins/Language/ObjC/ObjCLanguage.h"
59 
60 #include "lldb/Target/Language.h"
61 
62 #include "DWARFASTParser.h"
63 #include "DWARFCompileUnit.h"
64 #include "DWARFDebugAbbrev.h"
65 #include "DWARFDebugAranges.h"
66 #include "DWARFDebugInfo.h"
67 #include "DWARFDebugLine.h"
68 #include "DWARFDebugPubnames.h"
69 #include "DWARFDebugRanges.h"
70 #include "DWARFDeclContext.h"
71 #include "DWARFDIECollection.h"
72 #include "DWARFFormValue.h"
73 #include "DWARFLocationList.h"
74 #include "LogChannelDWARF.h"
75 #include "SymbolFileDWARFDwo.h"
76 #include "SymbolFileDWARFDebugMap.h"
77 
78 #include <map>
79 
80 #include <ctype.h>
81 #include <string.h>
82 
83 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
84 
85 #ifdef ENABLE_DEBUG_PRINTF
86 #include <stdio.h>
87 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
88 #else
89 #define DEBUG_PRINTF(fmt, ...)
90 #endif
91 
92 using namespace lldb;
93 using namespace lldb_private;
94 
95 //static inline bool
96 //child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
97 //{
98 //    switch (tag)
99 //    {
100 //    default:
101 //        break;
102 //    case DW_TAG_subprogram:
103 //    case DW_TAG_inlined_subroutine:
104 //    case DW_TAG_class_type:
105 //    case DW_TAG_structure_type:
106 //    case DW_TAG_union_type:
107 //        return true;
108 //    }
109 //    return false;
110 //}
111 //
112 
113 namespace {
114 
115     PropertyDefinition
116     g_properties[] =
117     {
118         { "comp-dir-symlink-paths" , OptionValue::eTypeFileSpecList, true,  0 ,   nullptr, nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time." },
119         {  nullptr                 , OptionValue::eTypeInvalid     , false, 0,    nullptr, nullptr, nullptr }
120     };
121 
122     enum
123     {
124         ePropertySymLinkPaths
125     };
126 
127 
128     class PluginProperties : public Properties
129     {
130     public:
131         static ConstString
132         GetSettingName()
133         {
134             return SymbolFileDWARF::GetPluginNameStatic();
135         }
136 
137         PluginProperties()
138         {
139             m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
140             m_collection_sp->Initialize(g_properties);
141         }
142 
143         FileSpecList&
144         GetSymLinkPaths()
145         {
146             OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths);
147             assert(option_value);
148             return option_value->GetCurrentValue();
149         }
150 
151     };
152 
153     typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
154 
155     static const SymbolFileDWARFPropertiesSP&
156     GetGlobalPluginProperties()
157     {
158         static const auto g_settings_sp(std::make_shared<PluginProperties>());
159         return g_settings_sp;
160     }
161 
162 }  // anonymous namespace end
163 
164 
165 static const char*
166 removeHostnameFromPathname(const char* path_from_dwarf)
167 {
168     if (!path_from_dwarf || !path_from_dwarf[0])
169     {
170         return path_from_dwarf;
171     }
172 
173     const char *colon_pos = strchr(path_from_dwarf, ':');
174     if (nullptr == colon_pos)
175     {
176         return path_from_dwarf;
177     }
178 
179     const char *slash_pos = strchr(path_from_dwarf, '/');
180     if (slash_pos && (slash_pos < colon_pos))
181     {
182         return path_from_dwarf;
183     }
184 
185     // check whether we have a windows path, and so the first character
186     // is a drive-letter not a hostname.
187     if (
188         colon_pos == path_from_dwarf + 1 &&
189         isalpha(*path_from_dwarf) &&
190         strlen(path_from_dwarf) > 2 &&
191         '\\' == path_from_dwarf[2])
192     {
193         return path_from_dwarf;
194     }
195 
196     return colon_pos + 1;
197 }
198 
199 static const char*
200 resolveCompDir(const char* path_from_dwarf)
201 {
202     if (!path_from_dwarf)
203         return nullptr;
204 
205     // DWARF2/3 suggests the form hostname:pathname for compilation directory.
206     // Remove the host part if present.
207     const char* local_path = removeHostnameFromPathname(path_from_dwarf);
208     if (!local_path)
209         return nullptr;
210 
211     bool is_symlink = false;
212     FileSpec local_path_spec(local_path, false);
213     const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
214     for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
215         is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true);
216 
217     if (!is_symlink)
218         return local_path;
219 
220     if (!local_path_spec.IsSymbolicLink())
221         return local_path;
222 
223     FileSpec resolved_local_path_spec;
224     const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
225     if (error.Success())
226         return resolved_local_path_spec.GetCString();
227 
228     return nullptr;
229 }
230 
231 
232 void
233 SymbolFileDWARF::Initialize()
234 {
235     LogChannelDWARF::Initialize();
236     PluginManager::RegisterPlugin (GetPluginNameStatic(),
237                                    GetPluginDescriptionStatic(),
238                                    CreateInstance,
239                                    DebuggerInitialize);
240 }
241 
242 void
243 SymbolFileDWARF::DebuggerInitialize(Debugger &debugger)
244 {
245     if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName()))
246     {
247         const bool is_global_setting = true;
248         PluginManager::CreateSettingForSymbolFilePlugin(debugger,
249                                                         GetGlobalPluginProperties()->GetValueProperties(),
250                                                         ConstString ("Properties for the dwarf symbol-file plug-in."),
251                                                         is_global_setting);
252     }
253 }
254 
255 void
256 SymbolFileDWARF::Terminate()
257 {
258     PluginManager::UnregisterPlugin (CreateInstance);
259     LogChannelDWARF::Initialize();
260 }
261 
262 
263 lldb_private::ConstString
264 SymbolFileDWARF::GetPluginNameStatic()
265 {
266     static ConstString g_name("dwarf");
267     return g_name;
268 }
269 
270 const char *
271 SymbolFileDWARF::GetPluginDescriptionStatic()
272 {
273     return "DWARF and DWARF3 debug symbol file reader.";
274 }
275 
276 
277 SymbolFile*
278 SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
279 {
280     return new SymbolFileDWARF(obj_file);
281 }
282 
283 TypeList *
284 SymbolFileDWARF::GetTypeList ()
285 {
286     if (GetDebugMapSymfile ())
287         return m_debug_map_symfile->GetTypeList();
288     return m_obj_file->GetModule()->GetTypeList();
289 
290 }
291 void
292 SymbolFileDWARF::GetTypes (const DWARFDIE &die,
293                            dw_offset_t min_die_offset,
294                            dw_offset_t max_die_offset,
295                            uint32_t type_mask,
296                            TypeSet &type_set)
297 {
298     if (die)
299     {
300         const dw_offset_t die_offset = die.GetOffset();
301 
302         if (die_offset >= max_die_offset)
303             return;
304 
305         if (die_offset >= min_die_offset)
306         {
307             const dw_tag_t tag = die.Tag();
308 
309             bool add_type = false;
310 
311             switch (tag)
312             {
313                 case DW_TAG_array_type:         add_type = (type_mask & eTypeClassArray         ) != 0; break;
314                 case DW_TAG_unspecified_type:
315                 case DW_TAG_base_type:          add_type = (type_mask & eTypeClassBuiltin       ) != 0; break;
316                 case DW_TAG_class_type:         add_type = (type_mask & eTypeClassClass         ) != 0; break;
317                 case DW_TAG_structure_type:     add_type = (type_mask & eTypeClassStruct        ) != 0; break;
318                 case DW_TAG_union_type:         add_type = (type_mask & eTypeClassUnion         ) != 0; break;
319                 case DW_TAG_enumeration_type:   add_type = (type_mask & eTypeClassEnumeration   ) != 0; break;
320                 case DW_TAG_subroutine_type:
321                 case DW_TAG_subprogram:
322                 case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction      ) != 0; break;
323                 case DW_TAG_pointer_type:       add_type = (type_mask & eTypeClassPointer       ) != 0; break;
324                 case DW_TAG_rvalue_reference_type:
325                 case DW_TAG_reference_type:     add_type = (type_mask & eTypeClassReference     ) != 0; break;
326                 case DW_TAG_typedef:            add_type = (type_mask & eTypeClassTypedef       ) != 0; break;
327                 case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
328             }
329 
330             if (add_type)
331             {
332                 const bool assert_not_being_parsed = true;
333                 Type *type = ResolveTypeUID (die, assert_not_being_parsed);
334                 if (type)
335                 {
336                     if (type_set.find(type) == type_set.end())
337                         type_set.insert(type);
338                 }
339             }
340         }
341 
342         for (DWARFDIE child_die = die.GetFirstChild();
343              child_die.IsValid();
344              child_die = child_die.GetSibling())
345         {
346             GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set);
347         }
348     }
349 }
350 
351 size_t
352 SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
353                            uint32_t type_mask,
354                            TypeList &type_list)
355 
356 {
357     TypeSet type_set;
358 
359     CompileUnit *comp_unit = NULL;
360     DWARFCompileUnit* dwarf_cu = NULL;
361     if (sc_scope)
362         comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
363 
364     if (comp_unit)
365     {
366         dwarf_cu = GetDWARFCompileUnit(comp_unit);
367         if (dwarf_cu == 0)
368             return 0;
369         GetTypes (dwarf_cu->DIE(),
370                   dwarf_cu->GetOffset(),
371                   dwarf_cu->GetNextCompileUnitOffset(),
372                   type_mask,
373                   type_set);
374     }
375     else
376     {
377         DWARFDebugInfo* info = DebugInfo();
378         if (info)
379         {
380             const size_t num_cus = info->GetNumCompileUnits();
381             for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
382             {
383                 dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
384                 if (dwarf_cu)
385                 {
386                     GetTypes (dwarf_cu->DIE(),
387                               0,
388                               UINT32_MAX,
389                               type_mask,
390                               type_set);
391                 }
392             }
393         }
394     }
395 
396     std::set<CompilerType> clang_type_set;
397     size_t num_types_added = 0;
398     for (Type *type : type_set)
399     {
400         CompilerType clang_type = type->GetForwardCompilerType ();
401         if (clang_type_set.find(clang_type) == clang_type_set.end())
402         {
403             clang_type_set.insert(clang_type);
404             type_list.Insert (type->shared_from_this());
405             ++num_types_added;
406         }
407     }
408     return num_types_added;
409 }
410 
411 
412 //----------------------------------------------------------------------
413 // Gets the first parent that is a lexical block, function or inlined
414 // subroutine, or compile unit.
415 //----------------------------------------------------------------------
416 DWARFDIE
417 SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die)
418 {
419     DWARFDIE die;
420     for (die = child_die.GetParent(); die; die = die.GetParent())
421     {
422         dw_tag_t tag = die.Tag();
423 
424         switch (tag)
425         {
426         case DW_TAG_compile_unit:
427         case DW_TAG_subprogram:
428         case DW_TAG_inlined_subroutine:
429         case DW_TAG_lexical_block:
430             return die;
431         }
432     }
433     return DWARFDIE();
434 }
435 
436 
437 SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
438     SymbolFile (objfile),
439     UserID (0),  // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
440     m_debug_map_module_wp (),
441     m_debug_map_symfile (NULL),
442     m_flags(),
443     m_data_debug_abbrev (),
444     m_data_debug_aranges (),
445     m_data_debug_frame (),
446     m_data_debug_info (),
447     m_data_debug_line (),
448     m_data_debug_loc (),
449     m_data_debug_ranges (),
450     m_data_debug_str (),
451     m_data_apple_names (),
452     m_data_apple_types (),
453     m_data_apple_namespaces (),
454     m_abbr(),
455     m_info(),
456     m_line(),
457     m_apple_names_ap (),
458     m_apple_types_ap (),
459     m_apple_namespaces_ap (),
460     m_apple_objc_ap (),
461     m_function_basename_index(),
462     m_function_fullname_index(),
463     m_function_method_index(),
464     m_function_selector_index(),
465     m_objc_class_selectors_index(),
466     m_global_index(),
467     m_type_index(),
468     m_namespace_index(),
469     m_indexed (false),
470     m_using_apple_tables (false),
471     m_fetched_external_modules (false),
472     m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
473     m_ranges(),
474     m_unique_ast_type_map ()
475 {
476 }
477 
478 SymbolFileDWARF::~SymbolFileDWARF()
479 {
480 }
481 
482 static const ConstString &
483 GetDWARFMachOSegmentName ()
484 {
485     static ConstString g_dwarf_section_name ("__DWARF");
486     return g_dwarf_section_name;
487 }
488 
489 UniqueDWARFASTTypeMap &
490 SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
491 {
492     if (GetDebugMapSymfile ())
493         return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
494     return m_unique_ast_type_map;
495 }
496 
497 ClangASTContext &
498 SymbolFileDWARF::GetClangASTContext ()
499 {
500     if (GetDebugMapSymfile ())
501         return m_debug_map_symfile->GetClangASTContext ();
502     else
503         return m_obj_file->GetModule()->GetClangASTContext();
504 }
505 
506 TypeSystem *
507 SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
508 {
509     SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
510     TypeSystem *type_system;
511     if (debug_map_symfile)
512     {
513         type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
514     }
515     else
516     {
517         type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
518         if (type_system)
519             type_system->SetSymbolFile(this);
520     }
521     return type_system;
522 }
523 
524 void
525 SymbolFileDWARF::InitializeObject()
526 {
527     ModuleSP module_sp (m_obj_file->GetModule());
528     if (module_sp)
529     {
530         const SectionList *section_list = module_sp->GetSectionList();
531 
532         const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
533 
534         // Memory map the DWARF mach-o segment so we have everything mmap'ed
535         // to keep our heap memory usage down.
536         if (section)
537             m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
538     }
539     get_apple_names_data();
540     if (m_data_apple_names.GetByteSize() > 0)
541     {
542         m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
543         if (m_apple_names_ap->IsValid())
544             m_using_apple_tables = true;
545         else
546             m_apple_names_ap.reset();
547     }
548     get_apple_types_data();
549     if (m_data_apple_types.GetByteSize() > 0)
550     {
551         m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
552         if (m_apple_types_ap->IsValid())
553             m_using_apple_tables = true;
554         else
555             m_apple_types_ap.reset();
556     }
557 
558     get_apple_namespaces_data();
559     if (m_data_apple_namespaces.GetByteSize() > 0)
560     {
561         m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
562         if (m_apple_namespaces_ap->IsValid())
563             m_using_apple_tables = true;
564         else
565             m_apple_namespaces_ap.reset();
566     }
567 
568     get_apple_objc_data();
569     if (m_data_apple_objc.GetByteSize() > 0)
570     {
571         m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
572         if (m_apple_objc_ap->IsValid())
573             m_using_apple_tables = true;
574         else
575             m_apple_objc_ap.reset();
576     }
577 
578     // Set the symbol file to this file if we don't have a debug map symbol
579     // file as our main symbol file. This allows the clang ASTContext to complete
580     // types using this symbol file when it needs to complete classes and structures.
581     if (GetDebugMapSymfile () == nullptr)
582         GetClangASTContext().SetSymbolFile(this);
583 }
584 
585 bool
586 SymbolFileDWARF::SupportedVersion(uint16_t version)
587 {
588     return version == 2 || version == 3 || version == 4;
589 }
590 
591 uint32_t
592 SymbolFileDWARF::CalculateAbilities ()
593 {
594     uint32_t abilities = 0;
595     if (m_obj_file != NULL)
596     {
597         const Section* section = NULL;
598         const SectionList *section_list = m_obj_file->GetSectionList();
599         if (section_list == NULL)
600             return 0;
601 
602         uint64_t debug_abbrev_file_size = 0;
603         uint64_t debug_info_file_size = 0;
604         uint64_t debug_line_file_size = 0;
605 
606         section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
607 
608         if (section)
609             section_list = &section->GetChildren ();
610 
611         section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
612         if (section != NULL)
613         {
614             debug_info_file_size = section->GetFileSize();
615 
616             section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
617             if (section)
618                 debug_abbrev_file_size = section->GetFileSize();
619             else
620                 m_flags.Set (flagsGotDebugAbbrevData);
621 
622             section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
623             if (!section)
624                 m_flags.Set (flagsGotDebugArangesData);
625 
626             section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
627             if (!section)
628                 m_flags.Set (flagsGotDebugFrameData);
629 
630             section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
631             if (section)
632                 debug_line_file_size = section->GetFileSize();
633             else
634                 m_flags.Set (flagsGotDebugLineData);
635 
636             section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
637             if (!section)
638                 m_flags.Set (flagsGotDebugLocData);
639 
640             section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
641             if (!section)
642                 m_flags.Set (flagsGotDebugMacInfoData);
643 
644             section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
645             if (!section)
646                 m_flags.Set (flagsGotDebugPubNamesData);
647 
648             section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
649             if (!section)
650                 m_flags.Set (flagsGotDebugPubTypesData);
651 
652             section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
653             if (!section)
654                 m_flags.Set (flagsGotDebugRangesData);
655 
656             section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
657             if (!section)
658                 m_flags.Set (flagsGotDebugStrData);
659         }
660         else
661         {
662             const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
663             if (symfile_dir_cstr)
664             {
665                 if (strcasestr(symfile_dir_cstr, ".dsym"))
666                 {
667                     if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
668                     {
669                         // We have a dSYM file that didn't have a any debug info.
670                         // If the string table has a size of 1, then it was made from
671                         // an executable with no debug info, or from an executable that
672                         // was stripped.
673                         section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
674                         if (section && section->GetFileSize() == 1)
675                         {
676                             m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
677                         }
678                     }
679                 }
680             }
681         }
682 
683         if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
684             abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
685 
686         if (debug_line_file_size > 0)
687             abilities |= LineTables;
688     }
689     return abilities;
690 }
691 
692 const DWARFDataExtractor&
693 SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data)
694 {
695     if (m_flags.IsClear (got_flag))
696     {
697         ModuleSP module_sp (m_obj_file->GetModule());
698         m_flags.Set (got_flag);
699         const SectionList *section_list = module_sp->GetSectionList();
700         if (section_list)
701         {
702             SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
703             if (section_sp)
704             {
705                 // See if we memory mapped the DWARF segment?
706                 if (m_dwarf_data.GetByteSize())
707                 {
708                     data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize());
709                 }
710                 else
711                 {
712                     if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0)
713                         data.Clear();
714                 }
715             }
716         }
717     }
718     return data;
719 }
720 
721 const DWARFDataExtractor&
722 SymbolFileDWARF::get_debug_abbrev_data()
723 {
724     return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
725 }
726 
727 const DWARFDataExtractor&
728 SymbolFileDWARF::get_debug_addr_data()
729 {
730     return GetCachedSectionData (flagsGotDebugAddrData, eSectionTypeDWARFDebugAddr, m_data_debug_addr);
731 }
732 
733 const DWARFDataExtractor&
734 SymbolFileDWARF::get_debug_aranges_data()
735 {
736     return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
737 }
738 
739 const DWARFDataExtractor&
740 SymbolFileDWARF::get_debug_frame_data()
741 {
742     return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
743 }
744 
745 const DWARFDataExtractor&
746 SymbolFileDWARF::get_debug_info_data()
747 {
748     return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
749 }
750 
751 const DWARFDataExtractor&
752 SymbolFileDWARF::get_debug_line_data()
753 {
754     return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
755 }
756 
757 const DWARFDataExtractor&
758 SymbolFileDWARF::get_debug_loc_data()
759 {
760     return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
761 }
762 
763 const DWARFDataExtractor&
764 SymbolFileDWARF::get_debug_ranges_data()
765 {
766     return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
767 }
768 
769 const DWARFDataExtractor&
770 SymbolFileDWARF::get_debug_str_data()
771 {
772     return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
773 }
774 
775 const DWARFDataExtractor&
776 SymbolFileDWARF::get_debug_str_offsets_data()
777 {
778     return GetCachedSectionData (flagsGotDebugStrOffsetsData, eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets);
779 }
780 
781 const DWARFDataExtractor&
782 SymbolFileDWARF::get_apple_names_data()
783 {
784     return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
785 }
786 
787 const DWARFDataExtractor&
788 SymbolFileDWARF::get_apple_types_data()
789 {
790     return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
791 }
792 
793 const DWARFDataExtractor&
794 SymbolFileDWARF::get_apple_namespaces_data()
795 {
796     return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
797 }
798 
799 const DWARFDataExtractor&
800 SymbolFileDWARF::get_apple_objc_data()
801 {
802     return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
803 }
804 
805 
806 DWARFDebugAbbrev*
807 SymbolFileDWARF::DebugAbbrev()
808 {
809     if (m_abbr.get() == NULL)
810     {
811         const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
812         if (debug_abbrev_data.GetByteSize() > 0)
813         {
814             m_abbr.reset(new DWARFDebugAbbrev());
815             if (m_abbr.get())
816                 m_abbr->Parse(debug_abbrev_data);
817         }
818     }
819     return m_abbr.get();
820 }
821 
822 const DWARFDebugAbbrev*
823 SymbolFileDWARF::DebugAbbrev() const
824 {
825     return m_abbr.get();
826 }
827 
828 
829 DWARFDebugInfo*
830 SymbolFileDWARF::DebugInfo()
831 {
832     if (m_info.get() == NULL)
833     {
834         Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
835                            __PRETTY_FUNCTION__, static_cast<void*>(this));
836         if (get_debug_info_data().GetByteSize() > 0)
837         {
838             m_info.reset(new DWARFDebugInfo());
839             if (m_info.get())
840             {
841                 m_info->SetDwarfData(this);
842             }
843         }
844     }
845     return m_info.get();
846 }
847 
848 const DWARFDebugInfo*
849 SymbolFileDWARF::DebugInfo() const
850 {
851     return m_info.get();
852 }
853 
854 DWARFCompileUnit*
855 SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
856 {
857     if (!comp_unit)
858         return nullptr;
859 
860     DWARFDebugInfo* info = DebugInfo();
861     if (info)
862     {
863         if (GetDebugMapSymfile ())
864         {
865             // The debug map symbol file made the compile units for this DWARF
866             // file which is .o file with DWARF in it, and we should have
867             // only 1 compile unit which is at offset zero in the DWARF.
868             // TODO: modify to support LTO .o files where each .o file might
869             // have multiple DW_TAG_compile_unit tags.
870 
871             DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0);
872             if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
873                 dwarf_cu->SetUserData(comp_unit);
874             return dwarf_cu;
875         }
876         else
877         {
878             // Just a normal DWARF file whose user ID for the compile unit is
879             // the DWARF offset itself
880 
881             DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
882             if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
883                 dwarf_cu->SetUserData(comp_unit);
884             return dwarf_cu;
885 
886         }
887     }
888     return NULL;
889 }
890 
891 
892 DWARFDebugRanges*
893 SymbolFileDWARF::DebugRanges()
894 {
895     if (m_ranges.get() == NULL)
896     {
897         Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
898                            __PRETTY_FUNCTION__, static_cast<void*>(this));
899         if (get_debug_ranges_data().GetByteSize() > 0)
900         {
901             m_ranges.reset(new DWARFDebugRanges());
902             if (m_ranges.get())
903                 m_ranges->Extract(this);
904         }
905     }
906     return m_ranges.get();
907 }
908 
909 const DWARFDebugRanges*
910 SymbolFileDWARF::DebugRanges() const
911 {
912     return m_ranges.get();
913 }
914 
915 lldb::CompUnitSP
916 SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
917 {
918     CompUnitSP cu_sp;
919     if (dwarf_cu)
920     {
921         CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
922         if (comp_unit)
923         {
924             // We already parsed this compile unit, had out a shared pointer to it
925             cu_sp = comp_unit->shared_from_this();
926         }
927         else
928         {
929             if (dwarf_cu->GetSymbolFileDWARF() != this)
930             {
931                 return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
932             }
933             else if (GetDebugMapSymfile ())
934             {
935                 // Let the debug map create the compile unit
936                 cu_sp = m_debug_map_symfile->GetCompileUnit(this);
937                 dwarf_cu->SetUserData(cu_sp.get());
938             }
939             else
940             {
941                 ModuleSP module_sp (m_obj_file->GetModule());
942                 if (module_sp)
943                 {
944                     const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
945                     if (cu_die)
946                     {
947                         FileSpec cu_file_spec{cu_die.GetName(), false};
948                         if (cu_file_spec)
949                         {
950                             // If we have a full path to the compile unit, we don't need to resolve
951                             // the file.  This can be expensive e.g. when the source files are NFS mounted.
952                             if (cu_file_spec.IsRelative())
953                             {
954                                 const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
955                                 cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
956                             }
957 
958                             std::string remapped_file;
959                             if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
960                                 cu_file_spec.SetFile(remapped_file, false);
961                         }
962 
963                         LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
964 
965                         bool is_optimized = dwarf_cu->GetIsOptimized ();
966                         cu_sp.reset(new CompileUnit (module_sp,
967                                                      dwarf_cu,
968                                                      cu_file_spec,
969                                                      dwarf_cu->GetID(),
970                                                      cu_language,
971                                                      is_optimized));
972                         if (cu_sp)
973                         {
974                             // If we just created a compile unit with an invalid file spec, try and get the
975                             // first entry in the supports files from the line table as that should be the
976                             // compile unit.
977                             if (!cu_file_spec)
978                             {
979                                 cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
980                                 if (cu_file_spec)
981                                 {
982                                     (FileSpec &)(*cu_sp) = cu_file_spec;
983                                     // Also fix the invalid file spec which was copied from the compile unit.
984                                     cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
985                                 }
986                             }
987 
988                             dwarf_cu->SetUserData(cu_sp.get());
989 
990                             // Figure out the compile unit index if we weren't given one
991                             if (cu_idx == UINT32_MAX)
992                                 DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
993 
994                             m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
995                         }
996                     }
997                 }
998             }
999         }
1000     }
1001     return cu_sp;
1002 }
1003 
1004 uint32_t
1005 SymbolFileDWARF::GetNumCompileUnits()
1006 {
1007     DWARFDebugInfo* info = DebugInfo();
1008     if (info)
1009         return info->GetNumCompileUnits();
1010     return 0;
1011 }
1012 
1013 CompUnitSP
1014 SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
1015 {
1016     CompUnitSP cu_sp;
1017     DWARFDebugInfo* info = DebugInfo();
1018     if (info)
1019     {
1020         DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
1021         if (dwarf_cu)
1022             cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
1023     }
1024     return cu_sp;
1025 }
1026 
1027 Function *
1028 SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die)
1029 {
1030     if (die.IsValid())
1031     {
1032         TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
1033 
1034         if (type_system)
1035         {
1036             DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
1037             if (dwarf_ast)
1038                 return dwarf_ast->ParseFunctionFromDWARF(sc, die);
1039         }
1040     }
1041     return nullptr;
1042 }
1043 
1044 bool
1045 SymbolFileDWARF::FixupAddress (Address &addr)
1046 {
1047     SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
1048     if (debug_map_symfile)
1049     {
1050         return debug_map_symfile->LinkOSOAddress(addr);
1051     }
1052     // This is a normal DWARF file, no address fixups need to happen
1053     return true;
1054 }
1055 lldb::LanguageType
1056 SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
1057 {
1058     assert (sc.comp_unit);
1059     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1060     if (dwarf_cu)
1061         return dwarf_cu->GetLanguageType();
1062     else
1063         return eLanguageTypeUnknown;
1064 }
1065 
1066 size_t
1067 SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
1068 {
1069     assert (sc.comp_unit);
1070     size_t functions_added = 0;
1071     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1072     if (dwarf_cu)
1073     {
1074         DWARFDIECollection function_dies;
1075         const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
1076         size_t func_idx;
1077         for (func_idx = 0; func_idx < num_functions; ++func_idx)
1078         {
1079             DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
1080             if (sc.comp_unit->FindFunctionByUID (die.GetID()).get() == NULL)
1081             {
1082                 if (ParseCompileUnitFunction(sc, die))
1083                     ++functions_added;
1084             }
1085         }
1086         //FixupTypes();
1087     }
1088     return functions_added;
1089 }
1090 
1091 bool
1092 SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
1093 {
1094     assert (sc.comp_unit);
1095     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1096     if (dwarf_cu)
1097     {
1098         const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1099 
1100         if (cu_die)
1101         {
1102             const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
1103 
1104             const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
1105 
1106             // All file indexes in DWARF are one based and a file of index zero is
1107             // supposed to be the compile unit itself.
1108             support_files.Append (*sc.comp_unit);
1109 
1110             return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
1111         }
1112     }
1113     return false;
1114 }
1115 
1116 bool
1117 SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
1118 {
1119     assert (sc.comp_unit);
1120     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1121     if (dwarf_cu)
1122     {
1123         if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
1124         {
1125             UpdateExternalModuleListIfNeeded();
1126             for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
1127             {
1128                 imported_modules.push_back(external_type_module.second.m_name);
1129             }
1130         }
1131     }
1132     return false;
1133 }
1134 
1135 struct ParseDWARFLineTableCallbackInfo
1136 {
1137     LineTable* line_table;
1138     std::unique_ptr<LineSequence> sequence_ap;
1139 };
1140 
1141 //----------------------------------------------------------------------
1142 // ParseStatementTableCallback
1143 //----------------------------------------------------------------------
1144 static void
1145 ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1146 {
1147     if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1148     {
1149         // Just started parsing the line table
1150     }
1151     else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1152     {
1153         // Done parsing line table, nothing to do for the cleanup
1154     }
1155     else
1156     {
1157         ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
1158         LineTable* line_table = info->line_table;
1159 
1160         // If this is our first time here, we need to create a
1161         // sequence container.
1162         if (!info->sequence_ap.get())
1163         {
1164             info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
1165             assert(info->sequence_ap.get());
1166         }
1167         line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
1168                                                state.address,
1169                                                state.line,
1170                                                state.column,
1171                                                state.file,
1172                                                state.is_stmt,
1173                                                state.basic_block,
1174                                                state.prologue_end,
1175                                                state.epilogue_begin,
1176                                                state.end_sequence);
1177         if (state.end_sequence)
1178         {
1179             // First, put the current sequence into the line table.
1180             line_table->InsertSequence(info->sequence_ap.get());
1181             // Then, empty it to prepare for the next sequence.
1182             info->sequence_ap->Clear();
1183         }
1184     }
1185 }
1186 
1187 bool
1188 SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1189 {
1190     assert (sc.comp_unit);
1191     if (sc.comp_unit->GetLineTable() != NULL)
1192         return true;
1193 
1194     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1195     if (dwarf_cu)
1196     {
1197         const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1198         if (dwarf_cu_die)
1199         {
1200             const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
1201             if (cu_line_offset != DW_INVALID_OFFSET)
1202             {
1203                 std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
1204                 if (line_table_ap.get())
1205                 {
1206                     ParseDWARFLineTableCallbackInfo info;
1207                     info.line_table = line_table_ap.get();
1208                     lldb::offset_t offset = cu_line_offset;
1209                     DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1210                     if (m_debug_map_symfile)
1211                     {
1212                         // We have an object file that has a line table with addresses
1213                         // that are not linked. We need to link the line table and convert
1214                         // the addresses that are relative to the .o file into addresses
1215                         // for the main executable.
1216                         sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
1217                     }
1218                     else
1219                     {
1220                         sc.comp_unit->SetLineTable(line_table_ap.release());
1221                         return true;
1222                     }
1223                 }
1224             }
1225         }
1226     }
1227     return false;
1228 }
1229 
1230 size_t
1231 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc,
1232                                       Block *parent_block,
1233                                       const DWARFDIE &orig_die,
1234                                       addr_t subprogram_low_pc,
1235                                       uint32_t depth)
1236 {
1237     size_t blocks_added = 0;
1238     DWARFDIE die = orig_die;
1239     while (die)
1240     {
1241         dw_tag_t tag = die.Tag();
1242 
1243         switch (tag)
1244         {
1245         case DW_TAG_inlined_subroutine:
1246         case DW_TAG_subprogram:
1247         case DW_TAG_lexical_block:
1248             {
1249                 Block *block = NULL;
1250                 if (tag == DW_TAG_subprogram)
1251                 {
1252                     // Skip any DW_TAG_subprogram DIEs that are inside
1253                     // of a normal or inlined functions. These will be
1254                     // parsed on their own as separate entities.
1255 
1256                     if (depth > 0)
1257                         break;
1258 
1259                     block = parent_block;
1260                 }
1261                 else
1262                 {
1263                     BlockSP block_sp(new Block (die.GetID()));
1264                     parent_block->AddChild(block_sp);
1265                     block = block_sp.get();
1266                 }
1267                 DWARFRangeList ranges;
1268                 const char *name = NULL;
1269                 const char *mangled_name = NULL;
1270 
1271                 int decl_file = 0;
1272                 int decl_line = 0;
1273                 int decl_column = 0;
1274                 int call_file = 0;
1275                 int call_line = 0;
1276                 int call_column = 0;
1277                 if (die.GetDIENamesAndRanges (name,
1278                                               mangled_name,
1279                                               ranges,
1280                                               decl_file, decl_line, decl_column,
1281                                               call_file, call_line, call_column, nullptr))
1282                 {
1283                     if (tag == DW_TAG_subprogram)
1284                     {
1285                         assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1286                         subprogram_low_pc = ranges.GetMinRangeBase(0);
1287                     }
1288                     else if (tag == DW_TAG_inlined_subroutine)
1289                     {
1290                         // We get called here for inlined subroutines in two ways.
1291                         // The first time is when we are making the Function object
1292                         // for this inlined concrete instance.  Since we're creating a top level block at
1293                         // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS.  So we need to
1294                         // adjust the containing address.
1295                         // The second time is when we are parsing the blocks inside the function that contains
1296                         // the inlined concrete instance.  Since these will be blocks inside the containing "real"
1297                         // function the offset will be for that function.
1298                         if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1299                         {
1300                             subprogram_low_pc = ranges.GetMinRangeBase(0);
1301                         }
1302                     }
1303 
1304                     const size_t num_ranges = ranges.GetSize();
1305                     for (size_t i = 0; i<num_ranges; ++i)
1306                     {
1307                         const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
1308                         const addr_t range_base = range.GetRangeBase();
1309                         if (range_base >= subprogram_low_pc)
1310                             block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
1311                         else
1312                         {
1313                             GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
1314                                                                        block->GetID(),
1315                                                                        range_base,
1316                                                                        range.GetRangeEnd(),
1317                                                                        subprogram_low_pc);
1318                         }
1319                     }
1320                     block->FinalizeRanges ();
1321 
1322                     if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1323                     {
1324                         std::unique_ptr<Declaration> decl_ap;
1325                         if (decl_file != 0 || decl_line != 0 || decl_column != 0)
1326                             decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1327                                                           decl_line, decl_column));
1328 
1329                         std::unique_ptr<Declaration> call_ap;
1330                         if (call_file != 0 || call_line != 0 || call_column != 0)
1331                             call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1332                                                           call_line, call_column));
1333 
1334                         block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
1335                     }
1336 
1337                     ++blocks_added;
1338 
1339                     if (die.HasChildren())
1340                     {
1341                         blocks_added += ParseFunctionBlocks (sc,
1342                                                              block,
1343                                                              die.GetFirstChild(),
1344                                                              subprogram_low_pc,
1345                                                              depth + 1);
1346                     }
1347                 }
1348             }
1349             break;
1350         default:
1351             break;
1352         }
1353 
1354         // Only parse siblings of the block if we are not at depth zero. A depth
1355         // of zero indicates we are currently parsing the top level
1356         // DW_TAG_subprogram DIE
1357 
1358         if (depth == 0)
1359             die.Clear();
1360         else
1361             die = die.GetSibling();
1362     }
1363     return blocks_added;
1364 }
1365 
1366 bool
1367 SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
1368 {
1369     if (parent_die)
1370     {
1371         for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling())
1372         {
1373             dw_tag_t tag = die.Tag();
1374             bool check_virtuality = false;
1375             switch (tag)
1376             {
1377                 case DW_TAG_inheritance:
1378                 case DW_TAG_subprogram:
1379                     check_virtuality = true;
1380                     break;
1381                 default:
1382                     break;
1383             }
1384             if (check_virtuality)
1385             {
1386                 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
1387                     return true;
1388             }
1389         }
1390     }
1391     return false;
1392 }
1393 
1394 CompilerDeclContext
1395 SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
1396 {
1397     if (UserIDMatches(type_uid))
1398     {
1399         DWARFDebugInfo* debug_info = DebugInfo();
1400         if (debug_info)
1401         {
1402             DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
1403             if (die)
1404             {
1405                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1406                 if (dwarf_ast)
1407                     return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
1408             }
1409         }
1410     }
1411     return CompilerDeclContext();
1412 }
1413 
1414 CompilerDeclContext
1415 SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
1416 {
1417     if (UserIDMatches(type_uid))
1418     {
1419         DWARFDebugInfo* debug_info = DebugInfo();
1420         if (debug_info)
1421         {
1422             DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
1423             if (die)
1424             {
1425                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1426                 if (dwarf_ast)
1427                     return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
1428             }
1429         }
1430     }
1431     return CompilerDeclContext();
1432 }
1433 
1434 
1435 Type*
1436 SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
1437 {
1438     if (UserIDMatches(type_uid))
1439     {
1440         DWARFDebugInfo* debug_info = DebugInfo();
1441         if (debug_info)
1442         {
1443             DWARFDIE type_die = debug_info->GetDIE (DIERef(type_uid));
1444             if (type_die)
1445             {
1446                 const bool assert_not_being_parsed = true;
1447                 return ResolveTypeUID (type_die, assert_not_being_parsed);
1448             }
1449         }
1450     }
1451     return NULL;
1452 }
1453 
1454 Type*
1455 SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed)
1456 {
1457     if (die)
1458     {
1459         Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
1460         if (log)
1461             GetObjectFile()->GetModule()->LogMessage (log,
1462                                                       "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
1463                                                       die.GetOffset(),
1464                                                       die.GetTagAsCString(),
1465                                                       die.GetName());
1466 
1467         // We might be coming in in the middle of a type tree (a class
1468         // withing a class, an enum within a class), so parse any needed
1469         // parent DIEs before we get to this one...
1470         DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die);
1471         if (decl_ctx_die)
1472         {
1473             if (log)
1474             {
1475                 switch (decl_ctx_die.Tag())
1476                 {
1477                     case DW_TAG_structure_type:
1478                     case DW_TAG_union_type:
1479                     case DW_TAG_class_type:
1480                     {
1481                         // Get the type, which could be a forward declaration
1482                         if (log)
1483                             GetObjectFile()->GetModule()->LogMessage (log,
1484                                                                       "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
1485                                                                       die.GetOffset(),
1486                                                                       die.GetTagAsCString(),
1487                                                                       die.GetName(),
1488                                                                       decl_ctx_die.GetOffset());
1489                     }
1490                     break;
1491 
1492                     default:
1493                         break;
1494                 }
1495             }
1496         }
1497         return ResolveType (die);
1498     }
1499     return NULL;
1500 }
1501 
1502 // This function is used when SymbolFileDWARFDebugMap owns a bunch of
1503 // SymbolFileDWARF objects to detect if this DWARF file is the one that
1504 // can resolve a clang_type.
1505 bool
1506 SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &clang_type)
1507 {
1508     CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
1509     return GetForwardDeclClangTypeToDie().count (clang_type_no_qualifiers.GetOpaqueQualType());
1510 }
1511 
1512 
1513 bool
1514 SymbolFileDWARF::CompleteType (CompilerType &clang_type)
1515 {
1516     // We have a struct/union/class/enum that needs to be fully resolved.
1517     CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
1518     auto die_it = GetForwardDeclClangTypeToDie().find (clang_type_no_qualifiers.GetOpaqueQualType());
1519     if (die_it == GetForwardDeclClangTypeToDie().end())
1520     {
1521         // We have already resolved this type...
1522         return true;
1523     }
1524 
1525     DWARFDebugInfo* debug_info = DebugInfo();
1526     DWARFDIE dwarf_die = debug_info->GetDIE(die_it->getSecond());
1527 
1528     // Once we start resolving this type, remove it from the forward declaration
1529     // map in case anyone child members or other types require this type to get resolved.
1530     // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1531     // are done.
1532     GetForwardDeclClangTypeToDie().erase (die_it);
1533 
1534     Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
1535 
1536     Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
1537     if (log)
1538         GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
1539                                                                   "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
1540                                                                   dwarf_die.GetID(),
1541                                                                   dwarf_die.GetTagAsCString(),
1542                                                                   type->GetName().AsCString());
1543     assert (clang_type);
1544     DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
1545     if (dwarf_ast)
1546         return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, clang_type);
1547     return false;
1548 }
1549 
1550 Type*
1551 SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed)
1552 {
1553     if (die)
1554     {
1555         Type *type = GetDIEToType().lookup (die.GetDIE());
1556 
1557         if (type == NULL)
1558             type = GetTypeForDIE (die).get();
1559 
1560         if (assert_not_being_parsed)
1561         {
1562             if (type != DIE_IS_BEING_PARSED)
1563                 return type;
1564 
1565             GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
1566                                                        die.GetOffset(),
1567                                                        die.GetTagAsCString(),
1568                                                        die.GetName());
1569 
1570         }
1571         else
1572             return type;
1573     }
1574     return nullptr;
1575 }
1576 
1577 CompileUnit*
1578 SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
1579 {
1580     // Check if the symbol vendor already knows about this compile unit?
1581     if (dwarf_cu->GetUserData() == NULL)
1582     {
1583         // The symbol vendor doesn't know about this compile unit, we
1584         // need to parse and add it to the symbol vendor object.
1585         return ParseCompileUnit(dwarf_cu, cu_idx).get();
1586     }
1587     return (CompileUnit*)dwarf_cu->GetUserData();
1588 }
1589 
1590 size_t
1591 SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets)
1592 {
1593     method_die_offsets.clear();
1594     if (m_using_apple_tables)
1595     {
1596         if (m_apple_objc_ap.get())
1597             m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
1598     }
1599     else
1600     {
1601         if (!m_indexed)
1602             Index ();
1603 
1604         m_objc_class_selectors_index.Find (class_name, method_die_offsets);
1605     }
1606     return method_die_offsets.size();
1607 }
1608 
1609 bool
1610 SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
1611 {
1612     sc.Clear(false);
1613 
1614     if (die)
1615     {
1616         // Check if the symbol vendor already knows about this compile unit?
1617         sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
1618 
1619         sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get();
1620         if (sc.function == NULL)
1621             sc.function = ParseCompileUnitFunction(sc, die);
1622 
1623         if (sc.function)
1624         {
1625             sc.module_sp = sc.function->CalculateSymbolContextModule();
1626             return true;
1627         }
1628     }
1629 
1630     return false;
1631 }
1632 
1633 void
1634 SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
1635 {
1636     if (m_fetched_external_modules)
1637         return;
1638     m_fetched_external_modules = true;
1639 
1640     DWARFDebugInfo * debug_info = DebugInfo();
1641 
1642     const uint32_t num_compile_units = GetNumCompileUnits();
1643     for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1644     {
1645         DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1646 
1647         const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
1648         if (die && die.HasChildren() == false)
1649         {
1650             const uint64_t name_strp = die.GetAttributeValueAsUnsigned (DW_AT_name, UINT64_MAX);
1651             const uint64_t dwo_path_strp = die.GetAttributeValueAsUnsigned (DW_AT_GNU_dwo_name, UINT64_MAX);
1652 
1653             if (name_strp != UINT64_MAX)
1654             {
1655                 if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
1656                 {
1657                     const char *name = get_debug_str_data().PeekCStr(name_strp);
1658                     const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);
1659                     if (name || dwo_path)
1660                     {
1661                         ModuleSP module_sp;
1662                         if (dwo_path)
1663                         {
1664                             ModuleSpec dwo_module_spec;
1665                             dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
1666                             dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
1667                             //printf ("Loading dwo = '%s'\n", dwo_path);
1668                             Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
1669                         }
1670 
1671                         if (dwo_path_strp != LLDB_INVALID_UID)
1672                         {
1673                             m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };
1674                         }
1675                         else
1676                         {
1677                             // This hack should be removed promptly once clang emits both.
1678                             m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };
1679                         }
1680                     }
1681                 }
1682             }
1683         }
1684     }
1685 }
1686 
1687 SymbolFileDWARF::GlobalVariableMap &
1688 SymbolFileDWARF::GetGlobalAranges()
1689 {
1690     if (!m_global_aranges_ap)
1691     {
1692         m_global_aranges_ap.reset (new GlobalVariableMap());
1693 
1694         ModuleSP module_sp = GetObjectFile()->GetModule();
1695         if (module_sp)
1696         {
1697             const size_t num_cus = module_sp->GetNumCompileUnits();
1698             for (size_t i = 0; i < num_cus; ++i)
1699             {
1700                 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
1701                 if (cu_sp)
1702                 {
1703                     VariableListSP globals_sp = cu_sp->GetVariableList(true);
1704                     if (globals_sp)
1705                     {
1706                         const size_t num_globals = globals_sp->GetSize();
1707                         for (size_t g = 0; g < num_globals; ++g)
1708                         {
1709                             VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
1710                             if (var_sp && !var_sp->GetLocationIsConstantValueData())
1711                             {
1712                                 const DWARFExpression &location = var_sp->LocationExpression();
1713                                 Value location_result;
1714                                 Error error;
1715                                 if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
1716                                 {
1717                                     if (location_result.GetValueType() == Value::eValueTypeFileAddress)
1718                                     {
1719                                         lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
1720                                         lldb::addr_t byte_size = 1;
1721                                         if (var_sp->GetType())
1722                                             byte_size = var_sp->GetType()->GetByteSize();
1723                                         m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
1724                                     }
1725                                 }
1726                             }
1727                         }
1728                     }
1729                 }
1730             }
1731         }
1732         m_global_aranges_ap->Sort();
1733     }
1734     return *m_global_aranges_ap;
1735 }
1736 
1737 
1738 uint32_t
1739 SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1740 {
1741     Timer scoped_timer(__PRETTY_FUNCTION__,
1742                        "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
1743                        static_cast<void*>(so_addr.GetSection().get()),
1744                        so_addr.GetOffset(), resolve_scope);
1745     uint32_t resolved = 0;
1746     if (resolve_scope & (   eSymbolContextCompUnit  |
1747                             eSymbolContextFunction  |
1748                             eSymbolContextBlock     |
1749                             eSymbolContextLineEntry |
1750                             eSymbolContextVariable  ))
1751     {
1752         lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1753 
1754         DWARFDebugInfo* debug_info = DebugInfo();
1755         if (debug_info)
1756         {
1757             const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
1758             if (cu_offset == DW_INVALID_OFFSET)
1759             {
1760                 // Global variables are not in the compile unit address ranges. The only way to
1761                 // currently find global variables is to iterate over the .debug_pubnames or the
1762                 // __apple_names table and find all items in there that point to DW_TAG_variable
1763                 // DIEs and then find the address that matches.
1764                 if (resolve_scope & eSymbolContextVariable)
1765                 {
1766                     GlobalVariableMap &map = GetGlobalAranges();
1767                     const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
1768                     if (entry && entry->data)
1769                     {
1770                         Variable *variable = entry->data;
1771                         SymbolContextScope *scc = variable->GetSymbolContextScope();
1772                         if (scc)
1773                         {
1774                             scc->CalculateSymbolContext(&sc);
1775                             sc.variable = variable;
1776                         }
1777                         return sc.GetResolvedMask();
1778                     }
1779                 }
1780             }
1781             else
1782             {
1783                 uint32_t cu_idx = DW_INVALID_INDEX;
1784                 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx);
1785                 if (dwarf_cu)
1786                 {
1787                     sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
1788                     if (sc.comp_unit)
1789                     {
1790                         resolved |= eSymbolContextCompUnit;
1791 
1792                         bool force_check_line_table = false;
1793                         if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1794                         {
1795                             DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1796                             DWARFDIE block_die;
1797                             if (function_die)
1798                             {
1799                                 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
1800                                 if (sc.function == NULL)
1801                                     sc.function = ParseCompileUnitFunction(sc, function_die);
1802 
1803                                 if (sc.function && (resolve_scope & eSymbolContextBlock))
1804                                     block_die = function_die.LookupDeepestBlock(file_vm_addr);
1805                             }
1806                             else
1807                             {
1808                                 // We might have had a compile unit that had discontiguous
1809                                 // address ranges where the gaps are symbols that don't have
1810                                 // any debug info. Discontiguous compile unit address ranges
1811                                 // should only happen when there aren't other functions from
1812                                 // other compile units in these gaps. This helps keep the size
1813                                 // of the aranges down.
1814                                 force_check_line_table = true;
1815                             }
1816 
1817                             if (sc.function != NULL)
1818                             {
1819                                 resolved |= eSymbolContextFunction;
1820 
1821                                 if (resolve_scope & eSymbolContextBlock)
1822                                 {
1823                                     Block& block = sc.function->GetBlock (true);
1824 
1825                                     if (block_die)
1826                                         sc.block = block.FindBlockByID (block_die.GetID());
1827                                     else
1828                                         sc.block = block.FindBlockByID (function_die.GetID());
1829                                     if (sc.block)
1830                                         resolved |= eSymbolContextBlock;
1831                                 }
1832                             }
1833                         }
1834 
1835                         if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
1836                         {
1837                             LineTable *line_table = sc.comp_unit->GetLineTable();
1838                             if (line_table != NULL)
1839                             {
1840                                 // And address that makes it into this function should be in terms
1841                                 // of this debug file if there is no debug map, or it will be an
1842                                 // address in the .o file which needs to be fixed up to be in terms
1843                                 // of the debug map executable. Either way, calling FixupAddress()
1844                                 // will work for us.
1845                                 Address exe_so_addr (so_addr);
1846                                 if (FixupAddress(exe_so_addr))
1847                                 {
1848                                     if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
1849                                     {
1850                                         resolved |= eSymbolContextLineEntry;
1851                                     }
1852                                 }
1853                             }
1854                         }
1855 
1856                         if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
1857                         {
1858                             // We might have had a compile unit that had discontiguous
1859                             // address ranges where the gaps are symbols that don't have
1860                             // any debug info. Discontiguous compile unit address ranges
1861                             // should only happen when there aren't other functions from
1862                             // other compile units in these gaps. This helps keep the size
1863                             // of the aranges down.
1864                             sc.comp_unit = NULL;
1865                             resolved &= ~eSymbolContextCompUnit;
1866                         }
1867                     }
1868                     else
1869                     {
1870                         GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
1871                                                                      cu_offset,
1872                                                                      cu_idx);
1873                     }
1874                 }
1875             }
1876         }
1877     }
1878     return resolved;
1879 }
1880 
1881 
1882 
1883 uint32_t
1884 SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1885 {
1886     const uint32_t prev_size = sc_list.GetSize();
1887     if (resolve_scope & eSymbolContextCompUnit)
1888     {
1889         DWARFDebugInfo* debug_info = DebugInfo();
1890         if (debug_info)
1891         {
1892             uint32_t cu_idx;
1893             DWARFCompileUnit* dwarf_cu = NULL;
1894 
1895             for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1896             {
1897                 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
1898                 const bool full_match = (bool)file_spec.GetDirectory();
1899                 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
1900                 if (check_inlines || file_spec_matches_cu_file_spec)
1901                 {
1902                     SymbolContext sc (m_obj_file->GetModule());
1903                     sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
1904                     if (sc.comp_unit)
1905                     {
1906                         uint32_t file_idx = UINT32_MAX;
1907 
1908                         // If we are looking for inline functions only and we don't
1909                         // find it in the support files, we are done.
1910                         if (check_inlines)
1911                         {
1912                             file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
1913                             if (file_idx == UINT32_MAX)
1914                                 continue;
1915                         }
1916 
1917                         if (line != 0)
1918                         {
1919                             LineTable *line_table = sc.comp_unit->GetLineTable();
1920 
1921                             if (line_table != NULL && line != 0)
1922                             {
1923                                 // We will have already looked up the file index if
1924                                 // we are searching for inline entries.
1925                                 if (!check_inlines)
1926                                     file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
1927 
1928                                 if (file_idx != UINT32_MAX)
1929                                 {
1930                                     uint32_t found_line;
1931                                     uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1932                                     found_line = sc.line_entry.line;
1933 
1934                                     while (line_idx != UINT32_MAX)
1935                                     {
1936                                         sc.function = NULL;
1937                                         sc.block = NULL;
1938                                         if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1939                                         {
1940                                             const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1941                                             if (file_vm_addr != LLDB_INVALID_ADDRESS)
1942                                             {
1943                                                 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1944                                                 DWARFDIE block_die;
1945                                                 if (function_die)
1946                                                 {
1947                                                     sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
1948                                                     if (sc.function == NULL)
1949                                                         sc.function = ParseCompileUnitFunction(sc, function_die);
1950 
1951                                                     if (sc.function && (resolve_scope & eSymbolContextBlock))
1952                                                         block_die = function_die.LookupDeepestBlock(file_vm_addr);
1953                                                 }
1954 
1955                                                 if (sc.function != NULL)
1956                                                 {
1957                                                     Block& block = sc.function->GetBlock (true);
1958 
1959                                                     if (block_die)
1960                                                         sc.block = block.FindBlockByID (block_die.GetID());
1961                                                     else if (function_die)
1962                                                         sc.block = block.FindBlockByID (function_die.GetID());
1963                                                 }
1964                                             }
1965                                         }
1966 
1967                                         sc_list.Append(sc);
1968                                         line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1969                                     }
1970                                 }
1971                             }
1972                             else if (file_spec_matches_cu_file_spec && !check_inlines)
1973                             {
1974                                 // only append the context if we aren't looking for inline call sites
1975                                 // by file and line and if the file spec matches that of the compile unit
1976                                 sc_list.Append(sc);
1977                             }
1978                         }
1979                         else if (file_spec_matches_cu_file_spec && !check_inlines)
1980                         {
1981                             // only append the context if we aren't looking for inline call sites
1982                             // by file and line and if the file spec matches that of the compile unit
1983                             sc_list.Append(sc);
1984                         }
1985 
1986                         if (!check_inlines)
1987                             break;
1988                     }
1989                 }
1990             }
1991         }
1992     }
1993     return sc_list.GetSize() - prev_size;
1994 }
1995 
1996 void
1997 SymbolFileDWARF::Index ()
1998 {
1999     if (m_indexed)
2000         return;
2001     m_indexed = true;
2002     Timer scoped_timer (__PRETTY_FUNCTION__,
2003                         "SymbolFileDWARF::Index (%s)",
2004                         GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
2005 
2006     DWARFDebugInfo* debug_info = DebugInfo();
2007     if (debug_info)
2008     {
2009         uint32_t cu_idx = 0;
2010         const uint32_t num_compile_units = GetNumCompileUnits();
2011         for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2012         {
2013             DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
2014 
2015             bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
2016 
2017             dwarf_cu->Index (m_function_basename_index,
2018                              m_function_fullname_index,
2019                              m_function_method_index,
2020                              m_function_selector_index,
2021                              m_objc_class_selectors_index,
2022                              m_global_index,
2023                              m_type_index,
2024                              m_namespace_index);
2025 
2026             // Keep memory down by clearing DIEs if this generate function
2027             // caused them to be parsed
2028             if (clear_dies)
2029                 dwarf_cu->ClearDIEs (true);
2030         }
2031 
2032         m_function_basename_index.Finalize();
2033         m_function_fullname_index.Finalize();
2034         m_function_method_index.Finalize();
2035         m_function_selector_index.Finalize();
2036         m_objc_class_selectors_index.Finalize();
2037         m_global_index.Finalize();
2038         m_type_index.Finalize();
2039         m_namespace_index.Finalize();
2040 
2041 #if defined (ENABLE_DEBUG_PRINTF)
2042         StreamFile s(stdout, false);
2043         s.Printf ("DWARF index for '%s':",
2044                   GetObjectFile()->GetFileSpec().GetPath().c_str());
2045         s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
2046         s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
2047         s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
2048         s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
2049         s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
2050         s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
2051         s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
2052         s.Printf("\nNamespaces:\n")             m_namespace_index.Dump (&s);
2053 #endif
2054     }
2055 }
2056 
2057 bool
2058 SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx)
2059 {
2060     if (decl_ctx == nullptr || !decl_ctx->IsValid())
2061     {
2062         // Invalid namespace decl which means we aren't matching only things
2063         // in this symbol file, so return true to indicate it matches this
2064         // symbol file.
2065         return true;
2066     }
2067 
2068     if ((TypeSystem *)&GetClangASTContext() == decl_ctx->GetTypeSystem())
2069         return true;    // The type systems match, return true
2070 
2071     // The namespace AST was valid, and it does not match...
2072     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2073 
2074     if (log)
2075         GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
2076 
2077     return false;
2078 }
2079 
2080 uint32_t
2081 SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)
2082 {
2083     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2084 
2085     if (log)
2086         GetObjectFile()->GetModule()->LogMessage (log,
2087                                                   "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
2088                                                   name.GetCString(),
2089                                                   static_cast<const void*>(parent_decl_ctx),
2090                                                   append, max_matches);
2091 
2092     if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2093         return 0;
2094 
2095     DWARFDebugInfo* info = DebugInfo();
2096     if (info == NULL)
2097         return 0;
2098 
2099     // If we aren't appending the results to this list, then clear the list
2100     if (!append)
2101         variables.Clear();
2102 
2103     // Remember how many variables are in the list before we search in case
2104     // we are appending the results to a variable list.
2105     const uint32_t original_size = variables.GetSize();
2106 
2107     DIEArray die_offsets;
2108 
2109     if (m_using_apple_tables)
2110     {
2111         if (m_apple_names_ap.get())
2112         {
2113             const char *name_cstr = name.GetCString();
2114             llvm::StringRef basename;
2115             llvm::StringRef context;
2116 
2117             if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename))
2118                 basename = name_cstr;
2119 
2120             m_apple_names_ap->FindByName (basename.data(), die_offsets);
2121         }
2122     }
2123     else
2124     {
2125         // Index the DWARF if we haven't already
2126         if (!m_indexed)
2127             Index ();
2128 
2129         m_global_index.Find (name, die_offsets);
2130     }
2131 
2132     const size_t num_die_matches = die_offsets.size();
2133     if (num_die_matches)
2134     {
2135         SymbolContext sc;
2136         sc.module_sp = m_obj_file->GetModule();
2137         assert (sc.module_sp);
2138 
2139         DWARFDebugInfo* debug_info = DebugInfo();
2140         bool done = false;
2141         for (size_t i=0; i<num_die_matches && !done; ++i)
2142         {
2143             const DIERef& die_ref = die_offsets[i];
2144             DWARFDIE die = debug_info->GetDIE (die_ref);
2145 
2146             if (die)
2147             {
2148                 switch (die.Tag())
2149                 {
2150                     default:
2151                     case DW_TAG_subprogram:
2152                     case DW_TAG_inlined_subroutine:
2153                     case DW_TAG_try_block:
2154                     case DW_TAG_catch_block:
2155                         break;
2156 
2157                     case DW_TAG_variable:
2158                         {
2159                             sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
2160 
2161                             if (parent_decl_ctx)
2162                             {
2163                                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2164                                 if (dwarf_ast)
2165                                 {
2166                                     CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
2167                                     if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx)
2168                                         continue;
2169                                 }
2170                             }
2171 
2172                             ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
2173 
2174                             if (variables.GetSize() - original_size >= max_matches)
2175                                 done = true;
2176                         }
2177                         break;
2178                 }
2179             }
2180             else
2181             {
2182                 if (m_using_apple_tables)
2183                 {
2184                     GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
2185                                                                                die_ref.die_offset, name.GetCString());
2186                 }
2187             }
2188         }
2189     }
2190 
2191     // Return the number of variable that were appended to the list
2192     const uint32_t num_matches = variables.GetSize() - original_size;
2193     if (log && num_matches > 0)
2194     {
2195         GetObjectFile()->GetModule()->LogMessage (log,
2196                                                   "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
2197                                                   name.GetCString(),
2198                                                   static_cast<const void*>(parent_decl_ctx),
2199                                                   append, max_matches,
2200                                                   num_matches);
2201     }
2202     return num_matches;
2203 }
2204 
2205 uint32_t
2206 SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2207 {
2208     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2209 
2210     if (log)
2211     {
2212         GetObjectFile()->GetModule()->LogMessage (log,
2213                                                   "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
2214                                                   regex.GetText(), append,
2215                                                   max_matches);
2216     }
2217 
2218     DWARFDebugInfo* info = DebugInfo();
2219     if (info == NULL)
2220         return 0;
2221 
2222     // If we aren't appending the results to this list, then clear the list
2223     if (!append)
2224         variables.Clear();
2225 
2226     // Remember how many variables are in the list before we search in case
2227     // we are appending the results to a variable list.
2228     const uint32_t original_size = variables.GetSize();
2229 
2230     DIEArray die_offsets;
2231 
2232     if (m_using_apple_tables)
2233     {
2234         if (m_apple_names_ap.get())
2235         {
2236             DWARFMappedHash::DIEInfoArray hash_data_array;
2237             if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2238                 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2239         }
2240     }
2241     else
2242     {
2243         // Index the DWARF if we haven't already
2244         if (!m_indexed)
2245             Index ();
2246 
2247         m_global_index.Find (regex, die_offsets);
2248     }
2249 
2250     SymbolContext sc;
2251     sc.module_sp = m_obj_file->GetModule();
2252     assert (sc.module_sp);
2253 
2254     const size_t num_matches = die_offsets.size();
2255     if (num_matches)
2256     {
2257         DWARFDebugInfo* debug_info = DebugInfo();
2258         for (size_t i=0; i<num_matches; ++i)
2259         {
2260             const DIERef& die_ref = die_offsets[i];
2261             DWARFDIE die = debug_info->GetDIE (die_ref);
2262 
2263             if (die)
2264             {
2265                 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
2266 
2267                 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
2268 
2269                 if (variables.GetSize() - original_size >= max_matches)
2270                     break;
2271             }
2272             else
2273             {
2274                 if (m_using_apple_tables)
2275                 {
2276                     GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
2277                                                                                die_ref.die_offset, regex.GetText());
2278                 }
2279             }
2280         }
2281     }
2282 
2283     // Return the number of variable that were appended to the list
2284     return variables.GetSize() - original_size;
2285 }
2286 
2287 
2288 bool
2289 SymbolFileDWARF::ResolveFunction (const DIERef& die_ref,
2290                                   bool include_inlines,
2291                                   SymbolContextList& sc_list)
2292 {
2293     DWARFDIE die = DebugInfo()->GetDIE (die_ref);
2294     return ResolveFunction (die, include_inlines, sc_list);
2295 }
2296 
2297 
2298 bool
2299 SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die,
2300                                   bool include_inlines,
2301                                   SymbolContextList& sc_list)
2302 {
2303     SymbolContext sc;
2304 
2305     if (!orig_die)
2306         return false;
2307 
2308     // If we were passed a die that is not a function, just return false...
2309     if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
2310         return false;
2311 
2312     DWARFDIE die = orig_die;
2313     DWARFDIE inlined_die;
2314     if (die.Tag() == DW_TAG_inlined_subroutine)
2315     {
2316         inlined_die = die;
2317 
2318         while (1)
2319         {
2320             die = die.GetParent();
2321 
2322             if (die)
2323             {
2324                 if (die.Tag() == DW_TAG_subprogram)
2325                     break;
2326             }
2327             else
2328                 break;
2329         }
2330     }
2331     assert (die && die.Tag() == DW_TAG_subprogram);
2332     if (GetFunction (die, sc))
2333     {
2334         Address addr;
2335         // Parse all blocks if needed
2336         if (inlined_die)
2337         {
2338             Block &function_block = sc.function->GetBlock (true);
2339             sc.block = function_block.FindBlockByID (inlined_die.GetID());
2340             if (sc.block == NULL)
2341                 sc.block = function_block.FindBlockByID (inlined_die.GetOffset());
2342             if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
2343                 addr.Clear();
2344         }
2345         else
2346         {
2347             sc.block = NULL;
2348             addr = sc.function->GetAddressRange().GetBaseAddress();
2349         }
2350 
2351         if (addr.IsValid())
2352         {
2353             sc_list.Append(sc);
2354             return true;
2355         }
2356     }
2357 
2358     return false;
2359 }
2360 
2361 void
2362 SymbolFileDWARF::FindFunctions (const ConstString &name,
2363                                 const NameToDIE &name_to_die,
2364                                 bool include_inlines,
2365                                 SymbolContextList& sc_list)
2366 {
2367     DIEArray die_offsets;
2368     if (name_to_die.Find (name, die_offsets))
2369     {
2370         ParseFunctions (die_offsets, include_inlines, sc_list);
2371     }
2372 }
2373 
2374 
2375 void
2376 SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2377                                 const NameToDIE &name_to_die,
2378                                 bool include_inlines,
2379                                 SymbolContextList& sc_list)
2380 {
2381     DIEArray die_offsets;
2382     if (name_to_die.Find (regex, die_offsets))
2383     {
2384         ParseFunctions (die_offsets, include_inlines, sc_list);
2385     }
2386 }
2387 
2388 
2389 void
2390 SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2391                                 const DWARFMappedHash::MemoryTable &memory_table,
2392                                 bool include_inlines,
2393                                 SymbolContextList& sc_list)
2394 {
2395     DIEArray die_offsets;
2396     DWARFMappedHash::DIEInfoArray hash_data_array;
2397     if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2398     {
2399         DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2400         ParseFunctions (die_offsets, include_inlines, sc_list);
2401     }
2402 }
2403 
2404 void
2405 SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
2406                                  bool include_inlines,
2407                                  SymbolContextList& sc_list)
2408 {
2409     const size_t num_matches = die_offsets.size();
2410     if (num_matches)
2411     {
2412         for (size_t i=0; i<num_matches; ++i)
2413             ResolveFunction (die_offsets[i], include_inlines, sc_list);
2414     }
2415 }
2416 
2417 bool
2418 SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx,
2419                                    const DWARFDIE &die)
2420 {
2421     // If we have no parent decl context to match this DIE matches, and if the parent
2422     // decl context isn't valid, we aren't trying to look for any particular decl
2423     // context so any die matches.
2424     if (decl_ctx == nullptr || !decl_ctx->IsValid())
2425         return true;
2426 
2427     if (die)
2428     {
2429         DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2430         if (dwarf_ast)
2431         {
2432             CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
2433             if (actual_decl_ctx)
2434                 return actual_decl_ctx == *decl_ctx;
2435         }
2436     }
2437     return false;
2438 }
2439 
2440 uint32_t
2441 SymbolFileDWARF::FindFunctions (const ConstString &name,
2442                                 const CompilerDeclContext *parent_decl_ctx,
2443                                 uint32_t name_type_mask,
2444                                 bool include_inlines,
2445                                 bool append,
2446                                 SymbolContextList& sc_list)
2447 {
2448     Timer scoped_timer (__PRETTY_FUNCTION__,
2449                         "SymbolFileDWARF::FindFunctions (name = '%s')",
2450                         name.AsCString());
2451 
2452     // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
2453     assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
2454 
2455     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2456 
2457     if (log)
2458     {
2459         GetObjectFile()->GetModule()->LogMessage (log,
2460                                                   "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2461                                                   name.GetCString(),
2462                                                   name_type_mask,
2463                                                   append);
2464     }
2465 
2466     // If we aren't appending the results to this list, then clear the list
2467     if (!append)
2468         sc_list.Clear();
2469 
2470     if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2471         return 0;
2472 
2473     // If name is empty then we won't find anything.
2474     if (name.IsEmpty())
2475         return 0;
2476 
2477     // Remember how many sc_list are in the list before we search in case
2478     // we are appending the results to a variable list.
2479 
2480     const char *name_cstr = name.GetCString();
2481 
2482     const uint32_t original_size = sc_list.GetSize();
2483 
2484     DWARFDebugInfo* info = DebugInfo();
2485     if (info == NULL)
2486         return 0;
2487 
2488     std::set<const DWARFDebugInfoEntry *> resolved_dies;
2489     if (m_using_apple_tables)
2490     {
2491         if (m_apple_names_ap.get())
2492         {
2493 
2494             DIEArray die_offsets;
2495 
2496             uint32_t num_matches = 0;
2497 
2498             if (name_type_mask & eFunctionNameTypeFull)
2499             {
2500                 // If they asked for the full name, match what they typed.  At some point we may
2501                 // want to canonicalize this (strip double spaces, etc.  For now, we just add all the
2502                 // dies that we find by exact match.
2503                 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2504                 for (uint32_t i = 0; i < num_matches; i++)
2505                 {
2506                     const DIERef& die_ref = die_offsets[i];
2507                     DWARFDIE die = info->GetDIE (die_ref);
2508                     if (die)
2509                     {
2510                         if (!DIEInDeclContext(parent_decl_ctx, die))
2511                             continue; // The containing decl contexts don't match
2512 
2513                         if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
2514                         {
2515                             if (ResolveFunction (die, include_inlines, sc_list))
2516                                 resolved_dies.insert(die.GetDIE());
2517                         }
2518                     }
2519                     else
2520                     {
2521                         GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2522                                                                                    die_ref.die_offset, name_cstr);
2523                     }
2524                 }
2525             }
2526 
2527             if (name_type_mask & eFunctionNameTypeSelector)
2528             {
2529                 if (parent_decl_ctx && parent_decl_ctx->IsValid())
2530                     return 0; // no selectors in namespaces
2531 
2532                 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2533                 // Now make sure these are actually ObjC methods.  In this case we can simply look up the name,
2534                 // and if it is an ObjC method name, we're good.
2535 
2536                 for (uint32_t i = 0; i < num_matches; i++)
2537                 {
2538                     const DIERef& die_ref = die_offsets[i];
2539                     DWARFDIE die = info->GetDIE (die_ref);
2540                     if (die)
2541                     {
2542                         const char *die_name = die.GetName();
2543                         if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
2544                         {
2545                             if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
2546                             {
2547                                 if (ResolveFunction (die, include_inlines, sc_list))
2548                                     resolved_dies.insert(die.GetDIE());
2549                             }
2550                         }
2551                     }
2552                     else
2553                     {
2554                         GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2555                                                                    die_ref.die_offset, name_cstr);
2556                     }
2557                 }
2558                 die_offsets.clear();
2559             }
2560 
2561             if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase)
2562             {
2563                 // The apple_names table stores just the "base name" of C++ methods in the table.  So we have to
2564                 // extract the base name, look that up, and if there is any other information in the name we were
2565                 // passed in we have to post-filter based on that.
2566 
2567                 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
2568                 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2569 
2570                 for (uint32_t i = 0; i < num_matches; i++)
2571                 {
2572                     const DIERef& die_ref = die_offsets[i];
2573                     DWARFDIE die = info->GetDIE (die_ref);
2574                     if (die)
2575                     {
2576                         if (!DIEInDeclContext(parent_decl_ctx, die))
2577                             continue; // The containing decl contexts don't match
2578 
2579 
2580                         // If we get to here, the die is good, and we should add it:
2581                         if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list))
2582                         {
2583                             bool keep_die = true;
2584                             if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
2585                             {
2586                                 // We are looking for either basenames or methods, so we need to
2587                                 // trim out the ones we won't want by looking at the type
2588                                 SymbolContext sc;
2589                                 if (sc_list.GetLastContext(sc))
2590                                 {
2591                                     if (sc.block)
2592                                     {
2593                                         // We have an inlined function
2594                                     }
2595                                     else if (sc.function)
2596                                     {
2597                                         Type *type = sc.function->GetType();
2598 
2599                                         if (type)
2600                                         {
2601                                             CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID());
2602                                             if (decl_ctx.IsStructUnionOrClass())
2603                                             {
2604                                                 if (name_type_mask & eFunctionNameTypeBase)
2605                                                 {
2606                                                     sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2607                                                     keep_die = false;
2608                                                 }
2609                                             }
2610                                             else
2611                                             {
2612                                                 if (name_type_mask & eFunctionNameTypeMethod)
2613                                                 {
2614                                                     sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2615                                                     keep_die = false;
2616                                                 }
2617                                             }
2618                                         }
2619                                         else
2620                                         {
2621                                             GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
2622                                                                                          die_ref.die_offset);
2623                                         }
2624                                     }
2625                                 }
2626                             }
2627                             if (keep_die)
2628                                 resolved_dies.insert(die.GetDIE());
2629                         }
2630                     }
2631                     else
2632                     {
2633                         GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
2634                                                                                    die_ref.die_offset, name_cstr);
2635                     }
2636                 }
2637                 die_offsets.clear();
2638             }
2639         }
2640     }
2641     else
2642     {
2643 
2644         // Index the DWARF if we haven't already
2645         if (!m_indexed)
2646             Index ();
2647 
2648         if (name_type_mask & eFunctionNameTypeFull)
2649         {
2650             FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
2651 
2652             // FIXME Temporary workaround for global/anonymous namespace
2653             // functions debugging FreeBSD and Linux binaries.
2654             // If we didn't find any functions in the global namespace try
2655             // looking in the basename index but ignore any returned
2656             // functions that have a namespace but keep functions which
2657             // have an anonymous namespace
2658             // TODO: The arch in the object file isn't correct for MSVC
2659             // binaries on windows, we should find a way to make it
2660             // correct and handle those symbols as well.
2661             if (sc_list.GetSize() == 0)
2662             {
2663                 ArchSpec arch;
2664                 if (!parent_decl_ctx &&
2665                     GetObjectFile()->GetArchitecture(arch) &&
2666                     (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
2667                      arch.GetMachine() == llvm::Triple::hexagon))
2668                 {
2669                     SymbolContextList temp_sc_list;
2670                     FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
2671                     SymbolContext sc;
2672                     for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
2673                     {
2674                         if (temp_sc_list.GetContextAtIndex(i, sc))
2675                         {
2676                             ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
2677                             ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
2678                             // Mangled names on Linux and FreeBSD are of the form:
2679                             // _ZN18function_namespace13function_nameEv.
2680                             if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
2681                                 !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
2682                             {
2683                                 sc_list.Append(sc);
2684                             }
2685                         }
2686                     }
2687                 }
2688             }
2689         }
2690         DIEArray die_offsets;
2691         if (name_type_mask & eFunctionNameTypeBase)
2692         {
2693             uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
2694             for (uint32_t i = 0; i < num_base; i++)
2695             {
2696                 DWARFDIE die = info->GetDIE (die_offsets[i]);
2697                 if (die)
2698                 {
2699                     if (!DIEInDeclContext(parent_decl_ctx, die))
2700                         continue; // The containing decl contexts don't match
2701 
2702                     // If we get to here, the die is good, and we should add it:
2703                     if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
2704                     {
2705                         if (ResolveFunction (die, include_inlines, sc_list))
2706                             resolved_dies.insert(die.GetDIE());
2707                     }
2708                 }
2709             }
2710             die_offsets.clear();
2711         }
2712 
2713         if (name_type_mask & eFunctionNameTypeMethod)
2714         {
2715             if (parent_decl_ctx && parent_decl_ctx->IsValid())
2716                 return 0; // no methods in namespaces
2717 
2718             uint32_t num_base = m_function_method_index.Find(name, die_offsets);
2719             {
2720                 for (uint32_t i = 0; i < num_base; i++)
2721                 {
2722                     DWARFDIE die = info->GetDIE (die_offsets[i]);
2723                     if (die)
2724                     {
2725                         // If we get to here, the die is good, and we should add it:
2726                         if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
2727                         {
2728                             if (ResolveFunction (die, include_inlines, sc_list))
2729                                 resolved_dies.insert(die.GetDIE());
2730                         }
2731                     }
2732                 }
2733             }
2734             die_offsets.clear();
2735         }
2736 
2737         if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid()))
2738         {
2739             FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
2740         }
2741 
2742     }
2743 
2744     // Return the number of variable that were appended to the list
2745     const uint32_t num_matches = sc_list.GetSize() - original_size;
2746 
2747     if (log && num_matches > 0)
2748     {
2749         GetObjectFile()->GetModule()->LogMessage (log,
2750                                                   "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
2751                                                   name.GetCString(),
2752                                                   name_type_mask,
2753                                                   include_inlines,
2754                                                   append,
2755                                                   num_matches);
2756     }
2757     return num_matches;
2758 }
2759 
2760 uint32_t
2761 SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
2762 {
2763     Timer scoped_timer (__PRETTY_FUNCTION__,
2764                         "SymbolFileDWARF::FindFunctions (regex = '%s')",
2765                         regex.GetText());
2766 
2767     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2768 
2769     if (log)
2770     {
2771         GetObjectFile()->GetModule()->LogMessage (log,
2772                                                   "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
2773                                                   regex.GetText(),
2774                                                   append);
2775     }
2776 
2777 
2778     // If we aren't appending the results to this list, then clear the list
2779     if (!append)
2780         sc_list.Clear();
2781 
2782     // Remember how many sc_list are in the list before we search in case
2783     // we are appending the results to a variable list.
2784     uint32_t original_size = sc_list.GetSize();
2785 
2786     if (m_using_apple_tables)
2787     {
2788         if (m_apple_names_ap.get())
2789             FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
2790     }
2791     else
2792     {
2793         // Index the DWARF if we haven't already
2794         if (!m_indexed)
2795             Index ();
2796 
2797         FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
2798 
2799         FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
2800     }
2801 
2802     // Return the number of variable that were appended to the list
2803     return sc_list.GetSize() - original_size;
2804 }
2805 
2806 uint32_t
2807 SymbolFileDWARF::FindTypes (const SymbolContext& sc,
2808                             const ConstString &name,
2809                             const CompilerDeclContext *parent_decl_ctx,
2810                             bool append,
2811                             uint32_t max_matches,
2812                             TypeList& types)
2813 {
2814     DWARFDebugInfo* info = DebugInfo();
2815     if (info == NULL)
2816         return 0;
2817 
2818     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2819 
2820     if (log)
2821     {
2822         if (parent_decl_ctx)
2823             GetObjectFile()->GetModule()->LogMessage (log,
2824                                                       "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)",
2825                                                       name.GetCString(),
2826                                                       static_cast<const void*>(parent_decl_ctx),
2827                                                       parent_decl_ctx->GetName().AsCString("<NULL>"),
2828                                                       append, max_matches);
2829         else
2830             GetObjectFile()->GetModule()->LogMessage (log,
2831                                                       "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)",
2832                                                       name.GetCString(), append,
2833                                                       max_matches);
2834     }
2835 
2836     // If we aren't appending the results to this list, then clear the list
2837     if (!append)
2838         types.Clear();
2839 
2840     if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2841         return 0;
2842 
2843     DIEArray die_offsets;
2844 
2845     if (m_using_apple_tables)
2846     {
2847         if (m_apple_types_ap.get())
2848         {
2849             const char *name_cstr = name.GetCString();
2850             m_apple_types_ap->FindByName (name_cstr, die_offsets);
2851         }
2852     }
2853     else
2854     {
2855         if (!m_indexed)
2856             Index ();
2857 
2858         m_type_index.Find (name, die_offsets);
2859     }
2860 
2861     const size_t num_die_matches = die_offsets.size();
2862 
2863     if (num_die_matches)
2864     {
2865         const uint32_t initial_types_size = types.GetSize();
2866         DWARFDebugInfo* debug_info = DebugInfo();
2867         for (size_t i=0; i<num_die_matches; ++i)
2868         {
2869             const DIERef& die_ref = die_offsets[i];
2870             DWARFDIE die = debug_info->GetDIE (die_ref);
2871 
2872             if (die)
2873             {
2874                 if (!DIEInDeclContext(parent_decl_ctx, die))
2875                     continue; // The containing decl contexts don't match
2876 
2877                 Type *matching_type = ResolveType (die);
2878                 if (matching_type)
2879                 {
2880                     // We found a type pointer, now find the shared pointer form our type list
2881                     types.InsertUnique (matching_type->shared_from_this());
2882                     if (types.GetSize() >= max_matches)
2883                         break;
2884                 }
2885             }
2886             else
2887             {
2888                 if (m_using_apple_tables)
2889                 {
2890                     GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
2891                                                                                die_ref.die_offset, name.GetCString());
2892                 }
2893             }
2894 
2895         }
2896         const uint32_t num_matches = types.GetSize() - initial_types_size;
2897         if (log && num_matches)
2898         {
2899             if (parent_decl_ctx)
2900             {
2901                 GetObjectFile()->GetModule()->LogMessage (log,
2902                                                           "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
2903                                                           name.GetCString(),
2904                                                           static_cast<const void*>(parent_decl_ctx),
2905                                                           parent_decl_ctx->GetName().AsCString("<NULL>"),
2906                                                           append, max_matches,
2907                                                           num_matches);
2908             }
2909             else
2910             {
2911                 GetObjectFile()->GetModule()->LogMessage (log,
2912                                                           "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u",
2913                                                           name.GetCString(),
2914                                                           append, max_matches,
2915                                                           num_matches);
2916             }
2917         }
2918         return num_matches;
2919     }
2920     return 0;
2921 }
2922 
2923 
2924 CompilerDeclContext
2925 SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2926                                 const ConstString &name,
2927                                 const CompilerDeclContext *parent_decl_ctx)
2928 {
2929     Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2930 
2931     if (log)
2932     {
2933         GetObjectFile()->GetModule()->LogMessage (log,
2934                                                   "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
2935                                                   name.GetCString());
2936     }
2937 
2938     CompilerDeclContext namespace_decl_ctx;
2939 
2940     if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2941         return namespace_decl_ctx;
2942 
2943 
2944     DWARFDebugInfo* info = DebugInfo();
2945     if (info)
2946     {
2947         DIEArray die_offsets;
2948 
2949         // Index if we already haven't to make sure the compile units
2950         // get indexed and make their global DIE index list
2951         if (m_using_apple_tables)
2952         {
2953             if (m_apple_namespaces_ap.get())
2954             {
2955                 const char *name_cstr = name.GetCString();
2956                 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
2957             }
2958         }
2959         else
2960         {
2961             if (!m_indexed)
2962                 Index ();
2963 
2964             m_namespace_index.Find (name, die_offsets);
2965         }
2966 
2967         const size_t num_matches = die_offsets.size();
2968         if (num_matches)
2969         {
2970             DWARFDebugInfo* debug_info = DebugInfo();
2971             for (size_t i=0; i<num_matches; ++i)
2972             {
2973                 const DIERef& die_ref = die_offsets[i];
2974                 DWARFDIE die = debug_info->GetDIE (die_ref);
2975 
2976                 if (die)
2977                 {
2978                     if (!DIEInDeclContext (parent_decl_ctx, die))
2979                         continue; // The containing decl contexts don't match
2980 
2981                     DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2982                     if (dwarf_ast)
2983                     {
2984                         namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die);
2985                         if (namespace_decl_ctx)
2986                             break;
2987                     }
2988                 }
2989                 else
2990                 {
2991                     if (m_using_apple_tables)
2992                     {
2993                         GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
2994                                                                    die_ref.die_offset, name.GetCString());
2995                     }
2996                 }
2997 
2998             }
2999         }
3000     }
3001     if (log && namespace_decl_ctx)
3002     {
3003         GetObjectFile()->GetModule()->LogMessage (log,
3004                                                   "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"",
3005                                                   name.GetCString(),
3006                                                   static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()),
3007                                                   static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()),
3008                                                   namespace_decl_ctx.GetName().AsCString("<NULL>"));
3009     }
3010 
3011     return namespace_decl_ctx;
3012 }
3013 
3014 TypeSP
3015 SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die)
3016 {
3017     TypeSP type_sp;
3018     if (die)
3019     {
3020         Type *type_ptr = GetDIEToType().lookup (die.GetDIE());
3021         if (type_ptr == NULL)
3022         {
3023             CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
3024             assert (lldb_cu);
3025             SymbolContext sc(lldb_cu);
3026             type_sp = ParseType(sc, die, NULL);
3027         }
3028         else if (type_ptr != DIE_IS_BEING_PARSED)
3029         {
3030             // Grab the existing type from the master types lists
3031             type_sp = type_ptr->shared_from_this();
3032         }
3033 
3034     }
3035     return type_sp;
3036 }
3037 
3038 
3039 DWARFDIE
3040 SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die)
3041 {
3042     if (orig_die)
3043     {
3044         DWARFDIE die = orig_die;
3045 
3046         while (die)
3047         {
3048             // If this is the original DIE that we are searching for a declaration
3049             // for, then don't look in the cache as we don't want our own decl
3050             // context to be our decl context...
3051             if (orig_die != die)
3052             {
3053                 switch (die.Tag())
3054                 {
3055                     case DW_TAG_compile_unit:
3056                     case DW_TAG_namespace:
3057                     case DW_TAG_structure_type:
3058                     case DW_TAG_union_type:
3059                     case DW_TAG_class_type:
3060                         return die;
3061 
3062                     default:
3063                         break;
3064                 }
3065             }
3066 
3067             DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
3068             if (spec_die)
3069             {
3070                 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
3071                 if (decl_ctx_die)
3072                     return decl_ctx_die;
3073             }
3074 
3075             DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
3076             if (abs_die)
3077             {
3078                 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
3079                 if (decl_ctx_die)
3080                     return decl_ctx_die;
3081             }
3082 
3083             die = die.GetParent();
3084         }
3085     }
3086     return DWARFDIE();
3087 }
3088 
3089 
3090 Symbol *
3091 SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
3092 {
3093     Symbol *objc_class_symbol = NULL;
3094     if (m_obj_file)
3095     {
3096         Symtab *symtab = m_obj_file->GetSymtab ();
3097         if (symtab)
3098         {
3099             objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
3100                                                                         eSymbolTypeObjCClass,
3101                                                                         Symtab::eDebugNo,
3102                                                                         Symtab::eVisibilityAny);
3103         }
3104     }
3105     return objc_class_symbol;
3106 }
3107 
3108 // Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
3109 // then we can end up looking through all class types for a complete type and never find
3110 // the full definition. We need to know if this attribute is supported, so we determine
3111 // this here and cache th result. We also need to worry about the debug map DWARF file
3112 // if we are doing darwin DWARF in .o file debugging.
3113 bool
3114 SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
3115 {
3116     if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
3117     {
3118         m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
3119         if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
3120             m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3121         else
3122         {
3123             DWARFDebugInfo* debug_info = DebugInfo();
3124             const uint32_t num_compile_units = GetNumCompileUnits();
3125             for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
3126             {
3127                 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
3128                 if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
3129                 {
3130                     m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3131                     break;
3132                 }
3133             }
3134         }
3135         if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
3136             return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
3137     }
3138     return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
3139 }
3140 
3141 // This function can be used when a DIE is found that is a forward declaration
3142 // DIE and we want to try and find a type that has the complete definition.
3143 TypeSP
3144 SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
3145                                                        const ConstString &type_name,
3146                                                        bool must_be_implementation)
3147 {
3148 
3149     TypeSP type_sp;
3150 
3151     if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
3152         return type_sp;
3153 
3154     DIEArray die_offsets;
3155 
3156     if (m_using_apple_tables)
3157     {
3158         if (m_apple_types_ap.get())
3159         {
3160             const char *name_cstr = type_name.GetCString();
3161             m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
3162         }
3163     }
3164     else
3165     {
3166         if (!m_indexed)
3167             Index ();
3168 
3169         m_type_index.Find (type_name, die_offsets);
3170     }
3171 
3172     const size_t num_matches = die_offsets.size();
3173 
3174     if (num_matches)
3175     {
3176         DWARFDebugInfo* debug_info = DebugInfo();
3177         for (size_t i=0; i<num_matches; ++i)
3178         {
3179             const DIERef& die_ref = die_offsets[i];
3180             DWARFDIE type_die = debug_info->GetDIE (die_ref);
3181 
3182             if (type_die)
3183             {
3184                 bool try_resolving_type = false;
3185 
3186                 // Don't try and resolve the DIE we are looking for with the DIE itself!
3187                 if (type_die != die)
3188                 {
3189                     switch (type_die.Tag())
3190                     {
3191                         case DW_TAG_class_type:
3192                         case DW_TAG_structure_type:
3193                             try_resolving_type = true;
3194                             break;
3195                         default:
3196                             break;
3197                     }
3198                 }
3199 
3200                 if (try_resolving_type)
3201                 {
3202                     if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type())
3203                         try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0);
3204 
3205                     if (try_resolving_type)
3206                     {
3207                         Type *resolved_type = ResolveType (type_die, false);
3208                         if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3209                         {
3210                             DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
3211                                           die.GetID(),
3212                                           m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
3213                                           type_die.GetID(),
3214                                           type_cu->GetID());
3215 
3216                             if (die)
3217                                 GetDIEToType()[die.GetDIE()] = resolved_type;
3218                             type_sp = resolved_type->shared_from_this();
3219                             break;
3220                         }
3221                     }
3222                 }
3223             }
3224             else
3225             {
3226                 if (m_using_apple_tables)
3227                 {
3228                     GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3229                                                                die_ref.die_offset, type_name.GetCString());
3230                 }
3231             }
3232 
3233         }
3234     }
3235     return type_sp;
3236 }
3237 
3238 
3239 //----------------------------------------------------------------------
3240 // This function helps to ensure that the declaration contexts match for
3241 // two different DIEs. Often times debug information will refer to a
3242 // forward declaration of a type (the equivalent of "struct my_struct;".
3243 // There will often be a declaration of that type elsewhere that has the
3244 // full definition. When we go looking for the full type "my_struct", we
3245 // will find one or more matches in the accelerator tables and we will
3246 // then need to make sure the type was in the same declaration context
3247 // as the original DIE. This function can efficiently compare two DIEs
3248 // and will return true when the declaration context matches, and false
3249 // when they don't.
3250 //----------------------------------------------------------------------
3251 bool
3252 SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1,
3253                                        const DWARFDIE &die2)
3254 {
3255     if (die1 == die2)
3256         return true;
3257 
3258     DWARFDIECollection decl_ctx_1;
3259     DWARFDIECollection decl_ctx_2;
3260     //The declaration DIE stack is a stack of the declaration context
3261     // DIEs all the way back to the compile unit. If a type "T" is
3262     // declared inside a class "B", and class "B" is declared inside
3263     // a class "A" and class "A" is in a namespace "lldb", and the
3264     // namespace is in a compile unit, there will be a stack of DIEs:
3265     //
3266     //   [0] DW_TAG_class_type for "B"
3267     //   [1] DW_TAG_class_type for "A"
3268     //   [2] DW_TAG_namespace  for "lldb"
3269     //   [3] DW_TAG_compile_unit for the source file.
3270     //
3271     // We grab both contexts and make sure that everything matches
3272     // all the way back to the compiler unit.
3273 
3274     // First lets grab the decl contexts for both DIEs
3275     die1.GetDeclContextDIEs (decl_ctx_1);
3276     die2.GetDeclContextDIEs (decl_ctx_2);
3277     // Make sure the context arrays have the same size, otherwise
3278     // we are done
3279     const size_t count1 = decl_ctx_1.Size();
3280     const size_t count2 = decl_ctx_2.Size();
3281     if (count1 != count2)
3282         return false;
3283 
3284     // Make sure the DW_TAG values match all the way back up the
3285     // compile unit. If they don't, then we are done.
3286     DWARFDIE decl_ctx_die1;
3287     DWARFDIE decl_ctx_die2;
3288     size_t i;
3289     for (i=0; i<count1; i++)
3290     {
3291         decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3292         decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3293         if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
3294             return false;
3295     }
3296 #if defined LLDB_CONFIGURATION_DEBUG
3297 
3298     // Make sure the top item in the decl context die array is always
3299     // DW_TAG_compile_unit. If it isn't then something went wrong in
3300     // the DWARFDIE::GetDeclContextDIEs() function...
3301     assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit);
3302 
3303 #endif
3304     // Always skip the compile unit when comparing by only iterating up to
3305     // "count - 1". Here we compare the names as we go.
3306     for (i=0; i<count1 - 1; i++)
3307     {
3308         decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3309         decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3310         const char *name1 = decl_ctx_die1.GetName();
3311         const char *name2 = decl_ctx_die2.GetName();
3312         // If the string was from a DW_FORM_strp, then the pointer will often
3313         // be the same!
3314         if (name1 == name2)
3315             continue;
3316 
3317         // Name pointers are not equal, so only compare the strings
3318         // if both are not NULL.
3319         if (name1 && name2)
3320         {
3321             // If the strings don't compare, we are done...
3322             if (strcmp(name1, name2) != 0)
3323                 return false;
3324         }
3325         else
3326         {
3327             // One name was NULL while the other wasn't
3328             return false;
3329         }
3330     }
3331     // We made it through all of the checks and the declaration contexts
3332     // are equal.
3333     return true;
3334 }
3335 
3336 
3337 TypeSP
3338 SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
3339 {
3340     TypeSP type_sp;
3341 
3342     const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
3343     if (dwarf_decl_ctx_count > 0)
3344     {
3345         const ConstString type_name(dwarf_decl_ctx[0].name);
3346         const dw_tag_t tag = dwarf_decl_ctx[0].tag;
3347 
3348         if (type_name)
3349         {
3350             Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
3351             if (log)
3352             {
3353                 GetObjectFile()->GetModule()->LogMessage (log,
3354                                                           "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
3355                                                           DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3356                                                           dwarf_decl_ctx.GetQualifiedName());
3357             }
3358 
3359             DIEArray die_offsets;
3360 
3361             if (m_using_apple_tables)
3362             {
3363                 if (m_apple_types_ap.get())
3364                 {
3365                     const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
3366                     const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
3367                     if (has_tag && has_qualified_name_hash)
3368                     {
3369                         const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
3370                         const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
3371                         if (log)
3372                             GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
3373                         m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
3374                     }
3375                     else if (has_tag)
3376                     {
3377                         if (log)
3378                             GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
3379                         m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
3380                     }
3381                     else
3382                     {
3383                         m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
3384                     }
3385                 }
3386             }
3387             else
3388             {
3389                 if (!m_indexed)
3390                     Index ();
3391 
3392                 m_type_index.Find (type_name, die_offsets);
3393             }
3394 
3395             const size_t num_matches = die_offsets.size();
3396 
3397 
3398             if (num_matches)
3399             {
3400                 DWARFDebugInfo* debug_info = DebugInfo();
3401                 for (size_t i=0; i<num_matches; ++i)
3402                 {
3403                     const DIERef& die_ref = die_offsets[i];
3404                     DWARFDIE type_die = debug_info->GetDIE (die_ref);
3405 
3406                     if (type_die)
3407                     {
3408                         bool try_resolving_type = false;
3409 
3410                         // Don't try and resolve the DIE we are looking for with the DIE itself!
3411                         const dw_tag_t type_tag = type_die.Tag();
3412                         // Make sure the tags match
3413                         if (type_tag == tag)
3414                         {
3415                             // The tags match, lets try resolving this type
3416                             try_resolving_type = true;
3417                         }
3418                         else
3419                         {
3420                             // The tags don't match, but we need to watch our for a
3421                             // forward declaration for a struct and ("struct foo")
3422                             // ends up being a class ("class foo { ... };") or
3423                             // vice versa.
3424                             switch (type_tag)
3425                             {
3426                                 case DW_TAG_class_type:
3427                                     // We had a "class foo", see if we ended up with a "struct foo { ... };"
3428                                     try_resolving_type = (tag == DW_TAG_structure_type);
3429                                     break;
3430                                 case DW_TAG_structure_type:
3431                                     // We had a "struct foo", see if we ended up with a "class foo { ... };"
3432                                     try_resolving_type = (tag == DW_TAG_class_type);
3433                                     break;
3434                                 default:
3435                                     // Tags don't match, don't event try to resolve
3436                                     // using this type whose name matches....
3437                                     break;
3438                             }
3439                         }
3440 
3441                         if (try_resolving_type)
3442                         {
3443                             DWARFDeclContext type_dwarf_decl_ctx;
3444                             type_die.GetDWARFDeclContext (type_dwarf_decl_ctx);
3445 
3446                             if (log)
3447                             {
3448                                 GetObjectFile()->GetModule()->LogMessage (log,
3449                                                                           "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
3450                                                                           DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3451                                                                           dwarf_decl_ctx.GetQualifiedName(),
3452                                                                           type_die.GetOffset(),
3453                                                                           type_dwarf_decl_ctx.GetQualifiedName());
3454                             }
3455 
3456                             // Make sure the decl contexts match all the way up
3457                             if (dwarf_decl_ctx == type_dwarf_decl_ctx)
3458                             {
3459                                 Type *resolved_type = ResolveType (type_die, false);
3460                                 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3461                                 {
3462                                     type_sp = resolved_type->shared_from_this();
3463                                     break;
3464                                 }
3465                             }
3466                         }
3467                         else
3468                         {
3469                             if (log)
3470                             {
3471                                 std::string qualified_name;
3472                                 type_die.GetQualifiedName(qualified_name);
3473                                 GetObjectFile()->GetModule()->LogMessage (log,
3474                                                                           "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
3475                                                                           DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3476                                                                           dwarf_decl_ctx.GetQualifiedName(),
3477                                                                           type_die.GetOffset(),
3478                                                                           qualified_name.c_str());
3479                             }
3480                         }
3481                     }
3482                     else
3483                     {
3484                         if (m_using_apple_tables)
3485                         {
3486                             GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3487                                                                                        die_ref.die_offset, type_name.GetCString());
3488                         }
3489                     }
3490 
3491                 }
3492             }
3493         }
3494     }
3495     return type_sp;
3496 }
3497 
3498 TypeSP
3499 SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr)
3500 {
3501     TypeSP type_sp;
3502 
3503     if (die)
3504     {
3505         TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
3506 
3507         if (type_system)
3508         {
3509             DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
3510             if (dwarf_ast)
3511             {
3512                 Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
3513                 type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr);
3514                 if (type_sp)
3515                 {
3516                     TypeList* type_list = GetTypeList();
3517                     if (type_list)
3518                         type_list->Insert(type_sp);
3519                 }
3520             }
3521         }
3522     }
3523 
3524     return type_sp;
3525 }
3526 
3527 size_t
3528 SymbolFileDWARF::ParseTypes
3529 (
3530     const SymbolContext& sc,
3531     const DWARFDIE &orig_die,
3532     bool parse_siblings,
3533     bool parse_children
3534 )
3535 {
3536     size_t types_added = 0;
3537     DWARFDIE die = orig_die;
3538     while (die)
3539     {
3540         bool type_is_new = false;
3541         if (ParseType(sc, die, &type_is_new).get())
3542         {
3543             if (type_is_new)
3544                 ++types_added;
3545         }
3546 
3547         if (parse_children && die.HasChildren())
3548         {
3549             if (die.Tag() == DW_TAG_subprogram)
3550             {
3551                 SymbolContext child_sc(sc);
3552                 child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
3553                 types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
3554             }
3555             else
3556                 types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
3557         }
3558 
3559         if (parse_siblings)
3560             die = die.GetSibling();
3561         else
3562             die.Clear();
3563     }
3564     return types_added;
3565 }
3566 
3567 
3568 size_t
3569 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3570 {
3571     assert(sc.comp_unit && sc.function);
3572     size_t functions_added = 0;
3573     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
3574     if (dwarf_cu)
3575     {
3576         const dw_offset_t function_die_offset = sc.function->GetID();
3577         DWARFDIE function_die = dwarf_cu->GetDIE (function_die_offset);
3578         if (function_die)
3579         {
3580             ParseFunctionBlocks(sc, &sc.function->GetBlock (false), function_die, LLDB_INVALID_ADDRESS, 0);
3581         }
3582     }
3583 
3584     return functions_added;
3585 }
3586 
3587 
3588 size_t
3589 SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3590 {
3591     // At least a compile unit must be valid
3592     assert(sc.comp_unit);
3593     size_t types_added = 0;
3594     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
3595     if (dwarf_cu)
3596     {
3597         if (sc.function)
3598         {
3599             dw_offset_t function_die_offset = sc.function->GetID();
3600             DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
3601             if (func_die && func_die.HasChildren())
3602             {
3603                 types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
3604             }
3605         }
3606         else
3607         {
3608             DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
3609             if (dwarf_cu_die && dwarf_cu_die.HasChildren())
3610             {
3611                 types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
3612             }
3613         }
3614     }
3615 
3616     return types_added;
3617 }
3618 
3619 size_t
3620 SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3621 {
3622     if (sc.comp_unit != NULL)
3623     {
3624         DWARFDebugInfo* info = DebugInfo();
3625         if (info == NULL)
3626             return 0;
3627 
3628         if (sc.function)
3629         {
3630             DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID()));
3631 
3632             const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
3633             if (func_lo_pc != LLDB_INVALID_ADDRESS)
3634             {
3635                 const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
3636 
3637                 // Let all blocks know they have parse all their variables
3638                 sc.function->GetBlock (false).SetDidParseVariables (true, true);
3639                 return num_variables;
3640             }
3641         }
3642         else if (sc.comp_unit)
3643         {
3644             DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
3645 
3646             if (dwarf_cu == NULL)
3647                 return 0;
3648 
3649             uint32_t vars_added = 0;
3650             VariableListSP variables (sc.comp_unit->GetVariableList(false));
3651 
3652             if (variables.get() == NULL)
3653             {
3654                 variables.reset(new VariableList());
3655                 sc.comp_unit->SetVariableList(variables);
3656 
3657                 DIEArray die_offsets;
3658                 if (m_using_apple_tables)
3659                 {
3660                     if (m_apple_names_ap.get())
3661                     {
3662                         DWARFMappedHash::DIEInfoArray hash_data_array;
3663                         if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
3664                                                                     dwarf_cu->GetNextCompileUnitOffset(),
3665                                                                     hash_data_array))
3666                         {
3667                             DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
3668                         }
3669                     }
3670                 }
3671                 else
3672                 {
3673                     // Index if we already haven't to make sure the compile units
3674                     // get indexed and make their global DIE index list
3675                     if (!m_indexed)
3676                         Index ();
3677 
3678                     m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
3679                                                                  die_offsets);
3680                 }
3681 
3682                 const size_t num_matches = die_offsets.size();
3683                 if (num_matches)
3684                 {
3685                     DWARFDebugInfo* debug_info = DebugInfo();
3686                     for (size_t i=0; i<num_matches; ++i)
3687                     {
3688                         const DIERef& die_ref = die_offsets[i];
3689                         DWARFDIE die = debug_info->GetDIE (die_ref);
3690                         if (die)
3691                         {
3692                             VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
3693                             if (var_sp)
3694                             {
3695                                 variables->AddVariableIfUnique (var_sp);
3696                                 ++vars_added;
3697                             }
3698                         }
3699                         else
3700                         {
3701                             if (m_using_apple_tables)
3702                             {
3703                                 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_ref.die_offset);
3704                             }
3705                         }
3706 
3707                     }
3708                 }
3709             }
3710             return vars_added;
3711         }
3712     }
3713     return 0;
3714 }
3715 
3716 VariableSP
3717 SymbolFileDWARF::ParseVariableDIE
3718 (
3719     const SymbolContext& sc,
3720     const DWARFDIE &die,
3721     const lldb::addr_t func_low_pc
3722 )
3723 {
3724     if (die.GetDWARF() != this)
3725         return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
3726 
3727     VariableSP var_sp;
3728     if (!die)
3729         return var_sp;
3730 
3731     var_sp = GetDIEToVariable()[die.GetDIE()];
3732     if (var_sp)
3733         return var_sp;  // Already been parsed!
3734 
3735     const dw_tag_t tag = die.Tag();
3736     ModuleSP module = GetObjectFile()->GetModule();
3737 
3738     if ((tag == DW_TAG_variable) ||
3739         (tag == DW_TAG_constant) ||
3740         (tag == DW_TAG_formal_parameter && sc.function))
3741     {
3742         DWARFAttributes attributes;
3743         const size_t num_attributes = die.GetAttributes(attributes);
3744         if (num_attributes > 0)
3745         {
3746             const char *name = NULL;
3747             const char *mangled = NULL;
3748             Declaration decl;
3749             uint32_t i;
3750             DWARFFormValue type_die_form;
3751             DWARFExpression location(die.GetCU());
3752             bool is_external = false;
3753             bool is_artificial = false;
3754             bool location_is_const_value_data = false;
3755             bool has_explicit_location = false;
3756             DWARFFormValue const_value;
3757             //AccessType accessibility = eAccessNone;
3758 
3759             for (i=0; i<num_attributes; ++i)
3760             {
3761                 dw_attr_t attr = attributes.AttributeAtIndex(i);
3762                 DWARFFormValue form_value;
3763 
3764                 if (attributes.ExtractFormValueAtIndex(i, form_value))
3765                 {
3766                     switch (attr)
3767                     {
3768                     case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3769                     case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3770                     case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3771                     case DW_AT_name:        name = form_value.AsCString(); break;
3772                     case DW_AT_linkage_name:
3773                     case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
3774                     case DW_AT_type:        type_die_form = form_value; break;
3775                     case DW_AT_external:    is_external = form_value.Boolean(); break;
3776                     case DW_AT_const_value:
3777                         // If we have already found a DW_AT_location attribute, ignore this attribute.
3778                         if (!has_explicit_location)
3779                         {
3780                             location_is_const_value_data = true;
3781                             // The constant value will be either a block, a data value or a string.
3782                             const DWARFDataExtractor& debug_info_data = get_debug_info_data();
3783                             if (DWARFFormValue::IsBlockForm(form_value.Form()))
3784                             {
3785                                 // Retrieve the value as a block expression.
3786                                 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3787                                 uint32_t block_length = form_value.Unsigned();
3788                                 location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
3789                             }
3790                             else if (DWARFFormValue::IsDataForm(form_value.Form()))
3791                             {
3792                                 // Retrieve the value as a data expression.
3793                                 DWARFFormValue::FixedFormSizes fixed_form_sizes =
3794                                     DWARFFormValue::GetFixedFormSizesForAddressSize (
3795                                             attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
3796                                             attributes.CompileUnitAtIndex(i)->IsDWARF64());
3797                                 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
3798                                 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
3799                                 if (data_length == 0)
3800                                 {
3801                                     const uint8_t *data_pointer = form_value.BlockData();
3802                                     if (data_pointer)
3803                                     {
3804                                         form_value.Unsigned();
3805                                     }
3806                                     else if (DWARFFormValue::IsDataForm(form_value.Form()))
3807                                     {
3808                                         // we need to get the byte size of the type later after we create the variable
3809                                         const_value = form_value;
3810                                     }
3811                                 }
3812                                 else
3813                                     location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
3814                             }
3815                             else
3816                             {
3817                                 // Retrieve the value as a string expression.
3818                                 if (form_value.Form() == DW_FORM_strp)
3819                                 {
3820                                     DWARFFormValue::FixedFormSizes fixed_form_sizes =
3821                                         DWARFFormValue::GetFixedFormSizesForAddressSize (
3822                                                 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
3823                                                 attributes.CompileUnitAtIndex(i)->IsDWARF64());
3824                                     uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
3825                                     uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
3826                                     location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
3827                                 }
3828                                 else
3829                                 {
3830                                     const char *str = form_value.AsCString();
3831                                     uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
3832                                     uint32_t string_length = strlen(str) + 1;
3833                                     location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
3834                                 }
3835                             }
3836                         }
3837                         break;
3838                     case DW_AT_location:
3839                         {
3840                             location_is_const_value_data = false;
3841                             has_explicit_location = true;
3842                             if (form_value.BlockData())
3843                             {
3844                                 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
3845 
3846                                 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3847                                 uint32_t block_length = form_value.Unsigned();
3848                                 location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
3849                             }
3850                             else
3851                             {
3852                                 const DWARFDataExtractor&    debug_loc_data = get_debug_loc_data();
3853                                 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3854 
3855                                 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3856                                 if (loc_list_length > 0)
3857                                 {
3858                                     location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
3859                                     assert (func_low_pc != LLDB_INVALID_ADDRESS);
3860                                     location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
3861                                 }
3862                             }
3863                         }
3864                         break;
3865 
3866                     case DW_AT_artificial:      is_artificial = form_value.Boolean(); break;
3867                     case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3868                     case DW_AT_declaration:
3869                     case DW_AT_description:
3870                     case DW_AT_endianity:
3871                     case DW_AT_segment:
3872                     case DW_AT_start_scope:
3873                     case DW_AT_visibility:
3874                     default:
3875                     case DW_AT_abstract_origin:
3876                     case DW_AT_sibling:
3877                     case DW_AT_specification:
3878                         break;
3879                     }
3880                 }
3881             }
3882 
3883             const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
3884             const dw_tag_t parent_tag = die.GetParent().Tag();
3885             bool is_static_member = parent_tag == DW_TAG_compile_unit && (parent_context_die.Tag() == DW_TAG_class_type || parent_context_die.Tag() == DW_TAG_structure_type);
3886 
3887             ValueType scope = eValueTypeInvalid;
3888 
3889             const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
3890             SymbolContextScope * symbol_context_scope = NULL;
3891 
3892             if (!mangled)
3893             {
3894                 // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
3895                 // generate fully qualified names of global variables with commands like "frame var j".
3896                 // For example, if j were an int variable holding a value 4 and declared in a namespace
3897                 // B which in turn is contained in a namespace A, the command "frame var j" returns
3898                 // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
3899                 // to generate a fully qualified name from the declaration context.
3900                 if (parent_tag == DW_TAG_compile_unit &&
3901                     Language::LanguageIsCPlusPlus(die.GetLanguage()))
3902                 {
3903                     DWARFDeclContext decl_ctx;
3904 
3905                     die.GetDWARFDeclContext(decl_ctx);
3906                     mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
3907                 }
3908             }
3909 
3910             // DWARF doesn't specify if a DW_TAG_variable is a local, global
3911             // or static variable, so we have to do a little digging by
3912             // looking at the location of a variable to see if it contains
3913             // a DW_OP_addr opcode _somewhere_ in the definition. I say
3914             // somewhere because clang likes to combine small global variables
3915             // into the same symbol and have locations like:
3916             // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
3917             // So if we don't have a DW_TAG_formal_parameter, we can look at
3918             // the location to see if it contains a DW_OP_addr opcode, and
3919             // then we can correctly classify  our variables.
3920             if (tag == DW_TAG_formal_parameter)
3921                 scope = eValueTypeVariableArgument;
3922             else
3923             {
3924                 bool op_error = false;
3925                 // Check if the location has a DW_OP_addr with any address value...
3926                 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
3927                 if (!location_is_const_value_data)
3928                 {
3929                     location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
3930                     if (op_error)
3931                     {
3932                         StreamString strm;
3933                         location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
3934                         GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
3935                     }
3936                 }
3937 
3938                 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
3939                 {
3940                     if (is_external)
3941                         scope = eValueTypeVariableGlobal;
3942                     else
3943                         scope = eValueTypeVariableStatic;
3944 
3945 
3946                     SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
3947 
3948                     if (debug_map_symfile)
3949                     {
3950                         // When leaving the DWARF in the .o files on darwin,
3951                         // when we have a global variable that wasn't initialized,
3952                         // the .o file might not have allocated a virtual
3953                         // address for the global variable. In this case it will
3954                         // have created a symbol for the global variable
3955                         // that is undefined/data and external and the value will
3956                         // be the byte size of the variable. When we do the
3957                         // address map in SymbolFileDWARFDebugMap we rely on
3958                         // having an address, we need to do some magic here
3959                         // so we can get the correct address for our global
3960                         // variable. The address for all of these entries
3961                         // will be zero, and there will be an undefined symbol
3962                         // in this object file, and the executable will have
3963                         // a matching symbol with a good address. So here we
3964                         // dig up the correct address and replace it in the
3965                         // location for the variable, and set the variable's
3966                         // symbol context scope to be that of the main executable
3967                         // so the file address will resolve correctly.
3968                         bool linked_oso_file_addr = false;
3969                         if (is_external && location_DW_OP_addr == 0)
3970                         {
3971                             // we have a possible uninitialized extern global
3972                             ConstString const_name(mangled ? mangled : name);
3973                             ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
3974                             if (debug_map_objfile)
3975                             {
3976                                 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
3977                                 if (debug_map_symtab)
3978                                 {
3979                                     Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
3980                                                                                                            eSymbolTypeData,
3981                                                                                                            Symtab::eDebugYes,
3982                                                                                                            Symtab::eVisibilityExtern);
3983                                     if (exe_symbol)
3984                                     {
3985                                         if (exe_symbol->ValueIsAddress())
3986                                         {
3987                                             const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
3988                                             if (exe_file_addr != LLDB_INVALID_ADDRESS)
3989                                             {
3990                                                 if (location.Update_DW_OP_addr (exe_file_addr))
3991                                                 {
3992                                                     linked_oso_file_addr = true;
3993                                                     symbol_context_scope = exe_symbol;
3994                                                 }
3995                                             }
3996                                         }
3997                                     }
3998                                 }
3999                             }
4000                         }
4001 
4002                         if (!linked_oso_file_addr)
4003                         {
4004                             // The DW_OP_addr is not zero, but it contains a .o file address which
4005                             // needs to be linked up correctly.
4006                             const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
4007                             if (exe_file_addr != LLDB_INVALID_ADDRESS)
4008                             {
4009                                 // Update the file address for this variable
4010                                 location.Update_DW_OP_addr (exe_file_addr);
4011                             }
4012                             else
4013                             {
4014                                 // Variable didn't make it into the final executable
4015                                 return var_sp;
4016                             }
4017                         }
4018                     }
4019                 }
4020                 else
4021                 {
4022                     scope = eValueTypeVariableLocal;
4023                 }
4024             }
4025 
4026             if (symbol_context_scope == NULL)
4027             {
4028                 switch (parent_tag)
4029                 {
4030                 case DW_TAG_subprogram:
4031                 case DW_TAG_inlined_subroutine:
4032                 case DW_TAG_lexical_block:
4033                     if (sc.function)
4034                     {
4035                         symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
4036                         if (symbol_context_scope == NULL)
4037                             symbol_context_scope = sc.function;
4038                     }
4039                     break;
4040 
4041                 default:
4042                     symbol_context_scope = sc.comp_unit;
4043                     break;
4044                 }
4045             }
4046 
4047             if (symbol_context_scope)
4048             {
4049                 SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID()));
4050 
4051                 if (const_value.Form() && type_sp && type_sp->GetType())
4052                     location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
4053 
4054                 var_sp.reset (new Variable (die.GetID(),
4055                                             name,
4056                                             mangled,
4057                                             type_sp,
4058                                             scope,
4059                                             symbol_context_scope,
4060                                             &decl,
4061                                             location,
4062                                             is_external,
4063                                             is_artificial,
4064                                             is_static_member));
4065 
4066                 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
4067             }
4068             else
4069             {
4070                 // Not ready to parse this variable yet. It might be a global
4071                 // or static variable that is in a function scope and the function
4072                 // in the symbol context wasn't filled in yet
4073                 return var_sp;
4074             }
4075         }
4076         // Cache var_sp even if NULL (the variable was just a specification or
4077         // was missing vital information to be able to be displayed in the debugger
4078         // (missing location due to optimization, etc)) so we don't re-parse
4079         // this DIE over and over later...
4080         GetDIEToVariable()[die.GetDIE()] = var_sp;
4081     }
4082     return var_sp;
4083 }
4084 
4085 
4086 DWARFDIE
4087 SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref,
4088                                                    dw_offset_t spec_block_die_offset)
4089 {
4090     // Give the concrete function die specified by "func_die_offset", find the
4091     // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4092     // to "spec_block_die_offset"
4093     return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset);
4094 }
4095 
4096 
4097 DWARFDIE
4098 SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die,
4099                                                   dw_offset_t spec_block_die_offset)
4100 {
4101     if (die)
4102     {
4103         switch (die.Tag())
4104         {
4105         case DW_TAG_subprogram:
4106         case DW_TAG_inlined_subroutine:
4107         case DW_TAG_lexical_block:
4108             {
4109                 if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4110                     return die;
4111 
4112                 if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4113                     return die;
4114             }
4115             break;
4116         }
4117 
4118         // Give the concrete function die specified by "func_die_offset", find the
4119         // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4120         // to "spec_block_die_offset"
4121         for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling())
4122         {
4123             DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset);
4124             if (result_die)
4125                 return result_die;
4126         }
4127     }
4128 
4129     return DWARFDIE();
4130 }
4131 
4132 size_t
4133 SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
4134                                  const DWARFDIE &orig_die,
4135                                  const lldb::addr_t func_low_pc,
4136                                  bool parse_siblings,
4137                                  bool parse_children,
4138                                  VariableList* cc_variable_list)
4139 {
4140     if (!orig_die)
4141         return 0;
4142 
4143     VariableListSP variable_list_sp;
4144 
4145     size_t vars_added = 0;
4146     DWARFDIE die = orig_die;
4147     while (die)
4148     {
4149         dw_tag_t tag = die.Tag();
4150 
4151         // Check to see if we have already parsed this variable or constant?
4152         VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
4153         if (var_sp)
4154         {
4155             if (cc_variable_list)
4156                 cc_variable_list->AddVariableIfUnique (var_sp);
4157         }
4158         else
4159         {
4160             // We haven't already parsed it, lets do that now.
4161             if ((tag == DW_TAG_variable) ||
4162                 (tag == DW_TAG_constant) ||
4163                 (tag == DW_TAG_formal_parameter && sc.function))
4164             {
4165                 if (variable_list_sp.get() == NULL)
4166                 {
4167                     DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
4168                     dw_tag_t parent_tag = sc_parent_die.Tag();
4169                     switch (parent_tag)
4170                     {
4171                         case DW_TAG_compile_unit:
4172                             if (sc.comp_unit != NULL)
4173                             {
4174                                 variable_list_sp = sc.comp_unit->GetVariableList(false);
4175                                 if (variable_list_sp.get() == NULL)
4176                                 {
4177                                     variable_list_sp.reset(new VariableList());
4178                                     sc.comp_unit->SetVariableList(variable_list_sp);
4179                                 }
4180                             }
4181                             else
4182                             {
4183                                 GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
4184                                                                            sc_parent_die.GetID(),
4185                                                                            sc_parent_die.GetTagAsCString(),
4186                                                                            orig_die.GetID(),
4187                                                                            orig_die.GetTagAsCString());
4188                             }
4189                             break;
4190 
4191                         case DW_TAG_subprogram:
4192                         case DW_TAG_inlined_subroutine:
4193                         case DW_TAG_lexical_block:
4194                             if (sc.function != NULL)
4195                             {
4196                                 // Check to see if we already have parsed the variables for the given scope
4197 
4198                                 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
4199                                 if (block == NULL)
4200                                 {
4201                                     // This must be a specification or abstract origin with
4202                                     // a concrete block counterpart in the current function. We need
4203                                     // to find the concrete block so we can correctly add the
4204                                     // variable to it
4205                                     const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID()),
4206                                                                                                           sc_parent_die.GetOffset());
4207                                     if (concrete_block_die)
4208                                         block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
4209                                 }
4210 
4211                                 if (block != NULL)
4212                                 {
4213                                     const bool can_create = false;
4214                                     variable_list_sp = block->GetBlockVariableList (can_create);
4215                                     if (variable_list_sp.get() == NULL)
4216                                     {
4217                                         variable_list_sp.reset(new VariableList());
4218                                         block->SetVariableList(variable_list_sp);
4219                                     }
4220                                 }
4221                             }
4222                             break;
4223 
4224                         default:
4225                              GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
4226                                                                         orig_die.GetID(),
4227                                                                         orig_die.GetTagAsCString());
4228                             break;
4229                     }
4230                 }
4231 
4232                 if (variable_list_sp)
4233                 {
4234                     VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc));
4235                     if (var_sp)
4236                     {
4237                         variable_list_sp->AddVariableIfUnique (var_sp);
4238                         if (cc_variable_list)
4239                             cc_variable_list->AddVariableIfUnique (var_sp);
4240                         ++vars_added;
4241                     }
4242                 }
4243             }
4244         }
4245 
4246         bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4247 
4248         if (!skip_children && parse_children && die.HasChildren())
4249         {
4250             vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list);
4251         }
4252 
4253         if (parse_siblings)
4254             die = die.GetSibling();
4255         else
4256             die.Clear();
4257     }
4258     return vars_added;
4259 }
4260 
4261 //------------------------------------------------------------------
4262 // PluginInterface protocol
4263 //------------------------------------------------------------------
4264 ConstString
4265 SymbolFileDWARF::GetPluginName()
4266 {
4267     return GetPluginNameStatic();
4268 }
4269 
4270 uint32_t
4271 SymbolFileDWARF::GetPluginVersion()
4272 {
4273     return 1;
4274 }
4275 
4276 void
4277 SymbolFileDWARF::DumpIndexes ()
4278 {
4279     StreamFile s(stdout, false);
4280 
4281     s.Printf ("DWARF index for (%s) '%s':",
4282               GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4283               GetObjectFile()->GetFileSpec().GetPath().c_str());
4284     s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
4285     s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
4286     s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
4287     s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
4288     s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
4289     s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
4290     s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
4291     s.Printf("\nNamespaces:\n");            m_namespace_index.Dump (&s);
4292 }
4293 
4294 
4295 SymbolFileDWARFDebugMap *
4296 SymbolFileDWARF::GetDebugMapSymfile ()
4297 {
4298     if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
4299     {
4300         lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
4301         if (module_sp)
4302         {
4303             SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
4304             if (sym_vendor)
4305                 m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
4306         }
4307     }
4308     return m_debug_map_symfile;
4309 }
4310