blob: fd254ad9c29a3b0be7091d3c8eea0ded12837a74 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Sean Callanancc427fa2011-07-30 02:42:06 +000013#include "llvm/Support/Casting.h"
14
Robert Flackeb83fab2015-05-15 18:59:59 +000015#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/Module.h"
Sean Callananf0c5aeb2015-04-20 16:31:29 +000017#include "lldb/Core/ModuleList.h"
18#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/RegularExpression.h"
21#include "lldb/Core/Scalar.h"
22#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000023#include "lldb/Core/StreamFile.h"
Jim Ingham318c9f22011-08-26 19:44:13 +000024#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/Timer.h"
26#include "lldb/Core/Value.h"
27
Sean Callanan4dbb2712015-09-25 20:35:58 +000028#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
Sean Callananf0c5aeb2015-04-20 16:31:29 +000029
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +000030#include "lldb/Host/FileSystem.h"
Greg Clayton20568dd2011-10-13 23:13:20 +000031#include "lldb/Host/Host.h"
32
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +000033#include "lldb/Interpreter/OptionValueFileSpecList.h"
34#include "lldb/Interpreter/OptionValueProperties.h"
35
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036#include "lldb/Symbol/Block.h"
Bruce Mitchener937e3962015-09-21 16:56:08 +000037#include "lldb/Symbol/ClangASTContext.h"
Paul Hermand628cbb2015-09-15 23:44:17 +000038#include "lldb/Symbol/CompilerDecl.h"
39#include "lldb/Symbol/CompilerDeclContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040#include "lldb/Symbol/CompileUnit.h"
41#include "lldb/Symbol/LineTable.h"
42#include "lldb/Symbol/ObjectFile.h"
43#include "lldb/Symbol/SymbolVendor.h"
Bruce Mitchener937e3962015-09-21 16:56:08 +000044#include "lldb/Symbol/TypeSystem.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045#include "lldb/Symbol/VariableList.h"
Ravitheja Addepally40697302015-10-08 09:45:41 +000046#include "lldb/Symbol/TypeMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
Jim Inghamaa816b82015-09-02 01:59:14 +000048#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
49#include "Plugins/Language/ObjC/ObjCLanguage.h"
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000050
Jim Ingham0e0984e2015-09-02 01:06:46 +000051#include "lldb/Target/Language.h"
52
Tamas Berghammer2ff88702015-10-23 10:34:49 +000053#include "lldb/Utility/TaskPool.h"
54
Greg Clayton261ac3f2015-08-28 01:01:03 +000055#include "DWARFASTParser.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056#include "DWARFCompileUnit.h"
57#include "DWARFDebugAbbrev.h"
58#include "DWARFDebugAranges.h"
59#include "DWARFDebugInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060#include "DWARFDebugLine.h"
61#include "DWARFDebugPubnames.h"
62#include "DWARFDebugRanges.h"
Greg Claytona8022fa2012-04-24 21:22:41 +000063#include "DWARFDeclContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064#include "DWARFDIECollection.h"
65#include "DWARFFormValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066#include "LogChannelDWARF.h"
Tamas Berghammereb882fc2015-09-09 10:20:48 +000067#include "SymbolFileDWARFDwo.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000068#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069
70#include <map>
71
Matthew Gardinere81df3b2014-08-26 06:57:23 +000072#include <ctype.h>
73#include <string.h>
74
Greg Clayton62742b12010-11-11 01:09:45 +000075//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000076
77#ifdef ENABLE_DEBUG_PRINTF
78#include <stdio.h>
Ed Mastea0191d12013-10-17 20:42:56 +000079#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
Greg Claytonc93237c2010-10-01 20:48:32 +000080#else
81#define DEBUG_PRINTF(fmt, ...)
82#endif
83
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084using namespace lldb;
85using namespace lldb_private;
86
Greg Clayton219cf312012-03-30 00:51:13 +000087//static inline bool
88//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
89//{
90// switch (tag)
91// {
92// default:
93// break;
94// case DW_TAG_subprogram:
95// case DW_TAG_inlined_subroutine:
96// case DW_TAG_class_type:
97// case DW_TAG_structure_type:
98// case DW_TAG_union_type:
99// return true;
100// }
101// return false;
102//}
103//
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000104
105namespace {
106
107 PropertyDefinition
108 g_properties[] =
109 {
110 { "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." },
111 { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr }
112 };
113
114 enum
115 {
116 ePropertySymLinkPaths
117 };
118
119
120 class PluginProperties : public Properties
121 {
122 public:
123 static ConstString
124 GetSettingName()
125 {
126 return SymbolFileDWARF::GetPluginNameStatic();
127 }
128
129 PluginProperties()
130 {
131 m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
132 m_collection_sp->Initialize(g_properties);
133 }
134
135 FileSpecList&
136 GetSymLinkPaths()
137 {
138 OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths);
139 assert(option_value);
140 return option_value->GetCurrentValue();
141 }
142
143 };
144
145 typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
146
147 static const SymbolFileDWARFPropertiesSP&
148 GetGlobalPluginProperties()
149 {
150 static const auto g_settings_sp(std::make_shared<PluginProperties>());
151 return g_settings_sp;
152 }
153
154} // anonymous namespace end
155
156
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000157static const char*
158removeHostnameFromPathname(const char* path_from_dwarf)
159{
160 if (!path_from_dwarf || !path_from_dwarf[0])
161 {
162 return path_from_dwarf;
163 }
Enrico Granata99e5e222015-07-27 21:27:02 +0000164
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000165 const char *colon_pos = strchr(path_from_dwarf, ':');
Enrico Granata99e5e222015-07-27 21:27:02 +0000166 if (nullptr == colon_pos)
167 {
168 return path_from_dwarf;
169 }
170
171 const char *slash_pos = strchr(path_from_dwarf, '/');
172 if (slash_pos && (slash_pos < colon_pos))
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000173 {
174 return path_from_dwarf;
175 }
176
177 // check whether we have a windows path, and so the first character
178 // is a drive-letter not a hostname.
179 if (
180 colon_pos == path_from_dwarf + 1 &&
181 isalpha(*path_from_dwarf) &&
182 strlen(path_from_dwarf) > 2 &&
183 '\\' == path_from_dwarf[2])
184 {
185 return path_from_dwarf;
186 }
Enrico Granata99e5e222015-07-27 21:27:02 +0000187
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000188 return colon_pos + 1;
189}
190
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000191static const char*
192resolveCompDir(const char* path_from_dwarf)
193{
194 if (!path_from_dwarf)
195 return nullptr;
196
197 // DWARF2/3 suggests the form hostname:pathname for compilation directory.
198 // Remove the host part if present.
199 const char* local_path = removeHostnameFromPathname(path_from_dwarf);
200 if (!local_path)
201 return nullptr;
202
203 bool is_symlink = false;
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000204 FileSpec local_path_spec(local_path, false);
205 const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
206 for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
207 is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true);
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000208
209 if (!is_symlink)
210 return local_path;
211
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000212 if (!local_path_spec.IsSymbolicLink())
213 return local_path;
214
215 FileSpec resolved_local_path_spec;
216 const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
217 if (error.Success())
218 return resolved_local_path_spec.GetCString();
219
220 return nullptr;
221}
222
223
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224void
225SymbolFileDWARF::Initialize()
226{
227 LogChannelDWARF::Initialize();
228 PluginManager::RegisterPlugin (GetPluginNameStatic(),
229 GetPluginDescriptionStatic(),
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000230 CreateInstance,
231 DebuggerInitialize);
232}
233
234void
235SymbolFileDWARF::DebuggerInitialize(Debugger &debugger)
236{
237 if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName()))
238 {
239 const bool is_global_setting = true;
240 PluginManager::CreateSettingForSymbolFilePlugin(debugger,
241 GetGlobalPluginProperties()->GetValueProperties(),
242 ConstString ("Properties for the dwarf symbol-file plug-in."),
243 is_global_setting);
244 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245}
246
247void
248SymbolFileDWARF::Terminate()
249{
250 PluginManager::UnregisterPlugin (CreateInstance);
251 LogChannelDWARF::Initialize();
252}
253
254
Greg Clayton57abc5d2013-05-10 21:47:16 +0000255lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256SymbolFileDWARF::GetPluginNameStatic()
257{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000258 static ConstString g_name("dwarf");
259 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260}
261
262const char *
263SymbolFileDWARF::GetPluginDescriptionStatic()
264{
265 return "DWARF and DWARF3 debug symbol file reader.";
266}
267
268
269SymbolFile*
270SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
271{
272 return new SymbolFileDWARF(obj_file);
273}
274
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000275TypeList *
276SymbolFileDWARF::GetTypeList ()
277{
Greg Clayton1f746072012-08-29 21:13:06 +0000278 if (GetDebugMapSymfile ())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000279 return m_debug_map_symfile->GetTypeList();
280 return m_obj_file->GetModule()->GetTypeList();
281
282}
Greg Claytonf02500c2013-06-18 22:51:05 +0000283void
Greg Clayton6071e6f2015-08-26 22:57:51 +0000284SymbolFileDWARF::GetTypes (const DWARFDIE &die,
Greg Claytonf02500c2013-06-18 22:51:05 +0000285 dw_offset_t min_die_offset,
286 dw_offset_t max_die_offset,
287 uint32_t type_mask,
288 TypeSet &type_set)
289{
Greg Clayton6071e6f2015-08-26 22:57:51 +0000290 if (die)
Greg Claytonf02500c2013-06-18 22:51:05 +0000291 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000292 const dw_offset_t die_offset = die.GetOffset();
293
294 if (die_offset >= max_die_offset)
295 return;
296
297 if (die_offset >= min_die_offset)
Greg Claytonf02500c2013-06-18 22:51:05 +0000298 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000299 const dw_tag_t tag = die.Tag();
Greg Claytonf02500c2013-06-18 22:51:05 +0000300
Greg Clayton6071e6f2015-08-26 22:57:51 +0000301 bool add_type = false;
302
303 switch (tag)
Greg Claytonf02500c2013-06-18 22:51:05 +0000304 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000305 case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
306 case DW_TAG_unspecified_type:
307 case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
308 case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
309 case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
310 case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
311 case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
312 case DW_TAG_subroutine_type:
313 case DW_TAG_subprogram:
314 case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
315 case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
316 case DW_TAG_rvalue_reference_type:
317 case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
318 case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
319 case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
320 }
Greg Claytonf02500c2013-06-18 22:51:05 +0000321
Greg Clayton6071e6f2015-08-26 22:57:51 +0000322 if (add_type)
323 {
324 const bool assert_not_being_parsed = true;
325 Type *type = ResolveTypeUID (die, assert_not_being_parsed);
326 if (type)
Greg Claytonf02500c2013-06-18 22:51:05 +0000327 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000328 if (type_set.find(type) == type_set.end())
329 type_set.insert(type);
Greg Claytonf02500c2013-06-18 22:51:05 +0000330 }
331 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000332 }
333
334 for (DWARFDIE child_die = die.GetFirstChild();
335 child_die.IsValid();
336 child_die = child_die.GetSibling())
337 {
338 GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set);
Greg Claytonf02500c2013-06-18 22:51:05 +0000339 }
340 }
341}
342
343size_t
344SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
345 uint32_t type_mask,
346 TypeList &type_list)
347
348{
349 TypeSet type_set;
350
351 CompileUnit *comp_unit = NULL;
352 DWARFCompileUnit* dwarf_cu = NULL;
353 if (sc_scope)
354 comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
355
356 if (comp_unit)
357 {
358 dwarf_cu = GetDWARFCompileUnit(comp_unit);
359 if (dwarf_cu == 0)
360 return 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +0000361 GetTypes (dwarf_cu->DIE(),
Greg Claytonf02500c2013-06-18 22:51:05 +0000362 dwarf_cu->GetOffset(),
363 dwarf_cu->GetNextCompileUnitOffset(),
364 type_mask,
365 type_set);
366 }
367 else
368 {
369 DWARFDebugInfo* info = DebugInfo();
370 if (info)
371 {
372 const size_t num_cus = info->GetNumCompileUnits();
373 for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
374 {
375 dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
376 if (dwarf_cu)
377 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000378 GetTypes (dwarf_cu->DIE(),
Greg Claytonf02500c2013-06-18 22:51:05 +0000379 0,
380 UINT32_MAX,
381 type_mask,
382 type_set);
383 }
384 }
385 }
386 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000387
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000388 std::set<CompilerType> compiler_type_set;
Greg Claytonf02500c2013-06-18 22:51:05 +0000389 size_t num_types_added = 0;
390 for (Type *type : type_set)
391 {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000392 CompilerType compiler_type = type->GetForwardCompilerType ();
393 if (compiler_type_set.find(compiler_type) == compiler_type_set.end())
Greg Clayton0fc4f312013-06-20 01:23:18 +0000394 {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000395 compiler_type_set.insert(compiler_type);
Greg Clayton0fc4f312013-06-20 01:23:18 +0000396 type_list.Insert (type->shared_from_this());
397 ++num_types_added;
398 }
Greg Claytonf02500c2013-06-18 22:51:05 +0000399 }
400 return num_types_added;
401}
402
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000403
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404//----------------------------------------------------------------------
405// Gets the first parent that is a lexical block, function or inlined
406// subroutine, or compile unit.
407//----------------------------------------------------------------------
Greg Clayton6071e6f2015-08-26 22:57:51 +0000408DWARFDIE
409SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410{
Greg Clayton6071e6f2015-08-26 22:57:51 +0000411 DWARFDIE die;
412 for (die = child_die.GetParent(); die; die = die.GetParent())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000413 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000414 dw_tag_t tag = die.Tag();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000415
416 switch (tag)
417 {
418 case DW_TAG_compile_unit:
419 case DW_TAG_subprogram:
420 case DW_TAG_inlined_subroutine:
421 case DW_TAG_lexical_block:
422 return die;
423 }
424 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000425 return DWARFDIE();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426}
427
428
Greg Clayton450e3f32010-10-12 02:24:53 +0000429SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
430 SymbolFile (objfile),
Greg Clayton81c22f62011-10-19 18:09:39 +0000431 UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
Greg Clayton1f746072012-08-29 21:13:06 +0000432 m_debug_map_module_wp (),
Greg Clayton450e3f32010-10-12 02:24:53 +0000433 m_debug_map_symfile (NULL),
Greg Claytond4a2b372011-09-12 23:21:58 +0000434 m_data_debug_abbrev (),
435 m_data_debug_aranges (),
436 m_data_debug_frame (),
437 m_data_debug_info (),
438 m_data_debug_line (),
439 m_data_debug_loc (),
440 m_data_debug_ranges (),
441 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000442 m_data_apple_names (),
443 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000444 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446 m_info(),
447 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000448 m_apple_names_ap (),
449 m_apple_types_ap (),
450 m_apple_namespaces_ap (),
Greg Clayton5009f9d2011-10-27 17:55:14 +0000451 m_apple_objc_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000452 m_function_basename_index(),
453 m_function_fullname_index(),
454 m_function_method_index(),
455 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000456 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000457 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000458 m_type_index(),
459 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000460 m_indexed (false),
Greg Clayton97fbc342011-10-20 22:30:33 +0000461 m_using_apple_tables (false),
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000462 m_fetched_external_modules (false),
Greg Claytonc7f03b62012-01-12 04:33:28 +0000463 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000464 m_ranges(),
465 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466{
467}
468
469SymbolFileDWARF::~SymbolFileDWARF()
470{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000471}
472
473static const ConstString &
474GetDWARFMachOSegmentName ()
475{
476 static ConstString g_dwarf_section_name ("__DWARF");
477 return g_dwarf_section_name;
478}
479
Greg Claytone576ab22011-02-15 00:19:15 +0000480UniqueDWARFASTTypeMap &
481SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
482{
Greg Clayton1f746072012-08-29 21:13:06 +0000483 if (GetDebugMapSymfile ())
Greg Claytone576ab22011-02-15 00:19:15 +0000484 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
485 return m_unique_ast_type_map;
486}
487
Greg Clayton8b4edba2015-08-14 20:02:05 +0000488TypeSystem *
489SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
490{
491 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000492 TypeSystem *type_system;
Greg Clayton8b4edba2015-08-14 20:02:05 +0000493 if (debug_map_symfile)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000494 {
495 type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
496 }
Greg Clayton8b4edba2015-08-14 20:02:05 +0000497 else
Ryan Brown57bee1e2015-09-14 22:45:11 +0000498 {
499 type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
500 if (type_system)
501 type_system->SetSymbolFile(this);
502 }
503 return type_system;
Greg Clayton8b4edba2015-08-14 20:02:05 +0000504}
505
Greg Clayton6beaaa62011-01-17 03:46:26 +0000506void
507SymbolFileDWARF::InitializeObject()
508{
Greg Claytone72dfb32012-02-24 01:59:29 +0000509 ModuleSP module_sp (m_obj_file->GetModule());
510 if (module_sp)
Greg Clayton6beaaa62011-01-17 03:46:26 +0000511 {
Greg Clayton3046e662013-07-10 01:23:25 +0000512 const SectionList *section_list = module_sp->GetSectionList();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000513 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
514
515 // Memory map the DWARF mach-o segment so we have everything mmap'ed
516 // to keep our heap memory usage down.
517 if (section)
Greg Claytonc9660542012-02-05 02:38:54 +0000518 m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000519 }
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000520
Greg Clayton4d01ace2011-09-29 16:58:15 +0000521 get_apple_names_data();
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000522 if (m_data_apple_names.m_data.GetByteSize() > 0)
Greg Clayton7f995132011-10-04 22:41:51 +0000523 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000524 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names.m_data,
525 get_debug_str_data(),
526 ".apple_names"));
Greg Clayton97fbc342011-10-20 22:30:33 +0000527 if (m_apple_names_ap->IsValid())
528 m_using_apple_tables = true;
529 else
Greg Clayton7f995132011-10-04 22:41:51 +0000530 m_apple_names_ap.reset();
531 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000532 get_apple_types_data();
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000533 if (m_data_apple_types.m_data.GetByteSize() > 0)
Greg Clayton7f995132011-10-04 22:41:51 +0000534 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000535 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types.m_data,
536 get_debug_str_data(),
537 ".apple_types"));
Greg Clayton97fbc342011-10-20 22:30:33 +0000538 if (m_apple_types_ap->IsValid())
539 m_using_apple_tables = true;
540 else
Greg Clayton7f995132011-10-04 22:41:51 +0000541 m_apple_types_ap.reset();
542 }
543
544 get_apple_namespaces_data();
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000545 if (m_data_apple_namespaces.m_data.GetByteSize() > 0)
Greg Clayton7f995132011-10-04 22:41:51 +0000546 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000547 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces.m_data,
548 get_debug_str_data(),
549 ".apple_namespaces"));
Greg Clayton97fbc342011-10-20 22:30:33 +0000550 if (m_apple_namespaces_ap->IsValid())
551 m_using_apple_tables = true;
552 else
Greg Clayton7f995132011-10-04 22:41:51 +0000553 m_apple_namespaces_ap.reset();
554 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000555
Greg Clayton5009f9d2011-10-27 17:55:14 +0000556 get_apple_objc_data();
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000557 if (m_data_apple_objc.m_data.GetByteSize() > 0)
Greg Clayton5009f9d2011-10-27 17:55:14 +0000558 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000559 m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc.m_data,
560 get_debug_str_data(),
561 ".apple_objc"));
Greg Clayton5009f9d2011-10-27 17:55:14 +0000562 if (m_apple_objc_ap->IsValid())
563 m_using_apple_tables = true;
564 else
565 m_apple_objc_ap.reset();
566 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567}
568
569bool
570SymbolFileDWARF::SupportedVersion(uint16_t version)
571{
Greg Claytonabcbfe52013-04-04 00:00:36 +0000572 return version == 2 || version == 3 || version == 4;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000573}
574
575uint32_t
Sean Callananbfaf54d2011-12-03 04:38:43 +0000576SymbolFileDWARF::CalculateAbilities ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000577{
578 uint32_t abilities = 0;
579 if (m_obj_file != NULL)
580 {
581 const Section* section = NULL;
582 const SectionList *section_list = m_obj_file->GetSectionList();
583 if (section_list == NULL)
584 return 0;
585
586 uint64_t debug_abbrev_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000587 uint64_t debug_info_file_size = 0;
588 uint64_t debug_line_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000589
Greg Clayton6beaaa62011-01-17 03:46:26 +0000590 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000591
592 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000593 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594
Greg Clayton4ceb9982010-07-21 22:54:26 +0000595 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 if (section != NULL)
597 {
Greg Clayton47037bc2012-03-27 02:40:46 +0000598 debug_info_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000599
Greg Clayton4ceb9982010-07-21 22:54:26 +0000600 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000601 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000602 debug_abbrev_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603
Greg Clayton4ceb9982010-07-21 22:54:26 +0000604 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000606 debug_line_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 }
Greg Clayton6c596612012-05-18 21:47:20 +0000608 else
609 {
610 const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
611 if (symfile_dir_cstr)
612 {
613 if (strcasestr(symfile_dir_cstr, ".dsym"))
614 {
615 if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
616 {
617 // We have a dSYM file that didn't have a any debug info.
618 // If the string table has a size of 1, then it was made from
619 // an executable with no debug info, or from an executable that
620 // was stripped.
621 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
622 if (section && section->GetFileSize() == 1)
623 {
624 m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
625 }
626 }
627 }
628 }
629 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630
631 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
632 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
633
634 if (debug_line_file_size > 0)
635 abilities |= LineTables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636 }
637 return abilities;
638}
639
Ed Masteeeae7212013-10-24 20:43:47 +0000640const DWARFDataExtractor&
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000641SymbolFileDWARF::GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000643 std::call_once(data_segment.m_flag,
644 &SymbolFileDWARF::LoadSectionData,
645 this,
646 sect_type,
647 std::ref(data_segment.m_data));
648 return data_segment.m_data;
649}
650
651void
652SymbolFileDWARF::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data)
653{
654 ModuleSP module_sp (m_obj_file->GetModule());
655 const SectionList *section_list = module_sp->GetSectionList();
656 if (section_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000658 SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
659 if (section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000660 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000661 // See if we memory mapped the DWARF segment?
662 if (m_dwarf_data.GetByteSize())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000664 data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize());
665 }
666 else
667 {
668 if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
669 data.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000670 }
671 }
672 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000673}
674
Ed Masteeeae7212013-10-24 20:43:47 +0000675const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000676SymbolFileDWARF::get_debug_abbrev_data()
677{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000678 return GetCachedSectionData (eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679}
680
Ed Masteeeae7212013-10-24 20:43:47 +0000681const DWARFDataExtractor&
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000682SymbolFileDWARF::get_debug_addr_data()
683{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000684 return GetCachedSectionData (eSectionTypeDWARFDebugAddr, m_data_debug_addr);
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000685}
686
687const DWARFDataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000688SymbolFileDWARF::get_debug_aranges_data()
689{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000690 return GetCachedSectionData (eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
Greg Claytond4a2b372011-09-12 23:21:58 +0000691}
692
Ed Masteeeae7212013-10-24 20:43:47 +0000693const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694SymbolFileDWARF::get_debug_frame_data()
695{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000696 return GetCachedSectionData (eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697}
698
Ed Masteeeae7212013-10-24 20:43:47 +0000699const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700SymbolFileDWARF::get_debug_info_data()
701{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000702 return GetCachedSectionData (eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703}
704
Ed Masteeeae7212013-10-24 20:43:47 +0000705const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000706SymbolFileDWARF::get_debug_line_data()
707{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000708 return GetCachedSectionData (eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000709}
710
Ed Masteeeae7212013-10-24 20:43:47 +0000711const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000712SymbolFileDWARF::get_debug_loc_data()
713{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000714 return GetCachedSectionData (eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000715}
716
Ed Masteeeae7212013-10-24 20:43:47 +0000717const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718SymbolFileDWARF::get_debug_ranges_data()
719{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000720 return GetCachedSectionData (eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000721}
722
Ed Masteeeae7212013-10-24 20:43:47 +0000723const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724SymbolFileDWARF::get_debug_str_data()
725{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000726 return GetCachedSectionData (eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727}
728
Ed Masteeeae7212013-10-24 20:43:47 +0000729const DWARFDataExtractor&
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000730SymbolFileDWARF::get_debug_str_offsets_data()
731{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000732 return GetCachedSectionData (eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets);
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000733}
734
735const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000736SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000737{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000738 return GetCachedSectionData (eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000739}
740
Ed Masteeeae7212013-10-24 20:43:47 +0000741const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000742SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000743{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000744 return GetCachedSectionData (eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000745}
746
Ed Masteeeae7212013-10-24 20:43:47 +0000747const DWARFDataExtractor&
Greg Clayton7f995132011-10-04 22:41:51 +0000748SymbolFileDWARF::get_apple_namespaces_data()
749{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000750 return GetCachedSectionData (eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000751}
752
Ed Masteeeae7212013-10-24 20:43:47 +0000753const DWARFDataExtractor&
Greg Clayton5009f9d2011-10-27 17:55:14 +0000754SymbolFileDWARF::get_apple_objc_data()
755{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000756 return GetCachedSectionData (eSectionTypeDWARFAppleObjC, m_data_apple_objc);
Greg Clayton7f995132011-10-04 22:41:51 +0000757}
758
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000759
760DWARFDebugAbbrev*
761SymbolFileDWARF::DebugAbbrev()
762{
763 if (m_abbr.get() == NULL)
764 {
Ed Masteeeae7212013-10-24 20:43:47 +0000765 const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000766 if (debug_abbrev_data.GetByteSize() > 0)
767 {
768 m_abbr.reset(new DWARFDebugAbbrev());
769 if (m_abbr.get())
770 m_abbr->Parse(debug_abbrev_data);
771 }
772 }
773 return m_abbr.get();
774}
775
776const DWARFDebugAbbrev*
777SymbolFileDWARF::DebugAbbrev() const
778{
779 return m_abbr.get();
780}
781
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782
783DWARFDebugInfo*
784SymbolFileDWARF::DebugInfo()
785{
786 if (m_info.get() == NULL)
787 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000788 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
789 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000790 if (get_debug_info_data().GetByteSize() > 0)
791 {
792 m_info.reset(new DWARFDebugInfo());
793 if (m_info.get())
794 {
795 m_info->SetDwarfData(this);
796 }
797 }
798 }
799 return m_info.get();
800}
801
802const DWARFDebugInfo*
803SymbolFileDWARF::DebugInfo() const
804{
805 return m_info.get();
806}
807
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000808DWARFCompileUnit*
Greg Clayton1f746072012-08-29 21:13:06 +0000809SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000810{
Greg Claytonea4a5bb2015-09-04 22:29:46 +0000811 if (!comp_unit)
812 return nullptr;
813
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000814 DWARFDebugInfo* info = DebugInfo();
Greg Clayton1f746072012-08-29 21:13:06 +0000815 if (info)
816 {
817 if (GetDebugMapSymfile ())
818 {
819 // The debug map symbol file made the compile units for this DWARF
820 // file which is .o file with DWARF in it, and we should have
821 // only 1 compile unit which is at offset zero in the DWARF.
822 // TODO: modify to support LTO .o files where each .o file might
823 // have multiple DW_TAG_compile_unit tags.
Greg Clayton68c00bd2015-02-05 02:10:29 +0000824
Greg Clayton6071e6f2015-08-26 22:57:51 +0000825 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0);
Greg Clayton68c00bd2015-02-05 02:10:29 +0000826 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
827 dwarf_cu->SetUserData(comp_unit);
828 return dwarf_cu;
Greg Clayton1f746072012-08-29 21:13:06 +0000829 }
830 else
831 {
832 // Just a normal DWARF file whose user ID for the compile unit is
833 // the DWARF offset itself
Greg Clayton68c00bd2015-02-05 02:10:29 +0000834
Greg Clayton6071e6f2015-08-26 22:57:51 +0000835 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
Greg Clayton68c00bd2015-02-05 02:10:29 +0000836 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
837 dwarf_cu->SetUserData(comp_unit);
838 return dwarf_cu;
839
Greg Clayton1f746072012-08-29 21:13:06 +0000840 }
841 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842 return NULL;
843}
844
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000845
846DWARFDebugRanges*
847SymbolFileDWARF::DebugRanges()
848{
849 if (m_ranges.get() == NULL)
850 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000851 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
852 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853 if (get_debug_ranges_data().GetByteSize() > 0)
854 {
855 m_ranges.reset(new DWARFDebugRanges());
856 if (m_ranges.get())
857 m_ranges->Extract(this);
858 }
859 }
860 return m_ranges.get();
861}
862
863const DWARFDebugRanges*
864SymbolFileDWARF::DebugRanges() const
865{
866 return m_ranges.get();
867}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868
Greg Clayton53eb1c22012-04-02 22:59:12 +0000869lldb::CompUnitSP
870SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871{
Greg Clayton53eb1c22012-04-02 22:59:12 +0000872 CompUnitSP cu_sp;
873 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000875 CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
876 if (comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000877 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000878 // We already parsed this compile unit, had out a shared pointer to it
879 cu_sp = comp_unit->shared_from_this();
880 }
881 else
882 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000883 if (dwarf_cu->GetSymbolFileDWARF() != this)
884 {
885 return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
886 }
887 else if (GetDebugMapSymfile ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000888 {
Greg Clayton1f746072012-08-29 21:13:06 +0000889 // Let the debug map create the compile unit
890 cu_sp = m_debug_map_symfile->GetCompileUnit(this);
891 dwarf_cu->SetUserData(cu_sp.get());
892 }
893 else
894 {
895 ModuleSP module_sp (m_obj_file->GetModule());
896 if (module_sp)
Greg Clayton53eb1c22012-04-02 22:59:12 +0000897 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000898 const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
Greg Clayton1f746072012-08-29 21:13:06 +0000899 if (cu_die)
Greg Clayton53eb1c22012-04-02 22:59:12 +0000900 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000901 FileSpec cu_file_spec{cu_die.GetName(), false};
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000902 if (cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +0000903 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000904 // If we have a full path to the compile unit, we don't need to resolve
905 // the file. This can be expensive e.g. when the source files are NFS mounted.
Chaoren Lin372e9062015-06-09 17:54:27 +0000906 if (cu_file_spec.IsRelative())
Greg Clayton53eb1c22012-04-02 22:59:12 +0000907 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000908 const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000909 cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
Greg Clayton1f746072012-08-29 21:13:06 +0000910 }
911
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000912 std::string remapped_file;
913 if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
914 cu_file_spec.SetFile(remapped_file, false);
David Srbeckyd515e942015-07-08 14:00:04 +0000915 }
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000916
Greg Clayton5ce1a842015-08-27 18:09:44 +0000917 LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000918
Jason Molendac7099582015-07-31 05:47:00 +0000919 bool is_optimized = dwarf_cu->GetIsOptimized ();
David Srbeckyd515e942015-07-08 14:00:04 +0000920 cu_sp.reset(new CompileUnit (module_sp,
921 dwarf_cu,
922 cu_file_spec,
Greg Clayton6071e6f2015-08-26 22:57:51 +0000923 dwarf_cu->GetID(),
Jason Molenda6ab659a2015-07-29 00:42:47 +0000924 cu_language,
925 is_optimized));
David Srbeckyd515e942015-07-08 14:00:04 +0000926 if (cu_sp)
927 {
928 // If we just created a compile unit with an invalid file spec, try and get the
929 // first entry in the supports files from the line table as that should be the
930 // compile unit.
931 if (!cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +0000932 {
David Srbeckyd515e942015-07-08 14:00:04 +0000933 cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
934 if (cu_file_spec)
935 {
936 (FileSpec &)(*cu_sp) = cu_file_spec;
937 // Also fix the invalid file spec which was copied from the compile unit.
938 cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
939 }
Greg Clayton53eb1c22012-04-02 22:59:12 +0000940 }
David Srbeckyd515e942015-07-08 14:00:04 +0000941
942 dwarf_cu->SetUserData(cu_sp.get());
943
944 // Figure out the compile unit index if we weren't given one
945 if (cu_idx == UINT32_MAX)
946 DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
947
948 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
Greg Clayton53eb1c22012-04-02 22:59:12 +0000949 }
950 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000951 }
952 }
953 }
954 }
Greg Clayton53eb1c22012-04-02 22:59:12 +0000955 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956}
957
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000958uint32_t
959SymbolFileDWARF::GetNumCompileUnits()
960{
961 DWARFDebugInfo* info = DebugInfo();
962 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000963 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000964 return 0;
965}
966
967CompUnitSP
968SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
969{
Greg Clayton53eb1c22012-04-02 22:59:12 +0000970 CompUnitSP cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000971 DWARFDebugInfo* info = DebugInfo();
972 if (info)
973 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000974 DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
975 if (dwarf_cu)
976 cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977 }
Greg Clayton53eb1c22012-04-02 22:59:12 +0000978 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000979}
980
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981Function *
Greg Clayton6071e6f2015-08-26 22:57:51 +0000982SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000983{
Greg Clayton6071e6f2015-08-26 22:57:51 +0000984 if (die.IsValid())
985 {
986 TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987
Greg Clayton6071e6f2015-08-26 22:57:51 +0000988 if (type_system)
989 {
Greg Clayton261ac3f2015-08-28 01:01:03 +0000990 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
991 if (dwarf_ast)
992 return dwarf_ast->ParseFunctionFromDWARF(sc, die);
Greg Clayton6071e6f2015-08-26 22:57:51 +0000993 }
994 }
995 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000996}
997
Greg Clayton9422dd62013-03-04 21:46:16 +0000998bool
999SymbolFileDWARF::FixupAddress (Address &addr)
1000{
1001 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
1002 if (debug_map_symfile)
1003 {
1004 return debug_map_symfile->LinkOSOAddress(addr);
1005 }
1006 // This is a normal DWARF file, no address fixups need to happen
1007 return true;
1008}
Greg Clayton1f746072012-08-29 21:13:06 +00001009lldb::LanguageType
1010SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
1011{
1012 assert (sc.comp_unit);
1013 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1014 if (dwarf_cu)
Greg Clayton5ce1a842015-08-27 18:09:44 +00001015 return dwarf_cu->GetLanguageType();
1016 else
1017 return eLanguageTypeUnknown;
Greg Clayton1f746072012-08-29 21:13:06 +00001018}
1019
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001020size_t
1021SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
1022{
1023 assert (sc.comp_unit);
1024 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00001025 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026 if (dwarf_cu)
1027 {
1028 DWARFDIECollection function_dies;
Greg Clayton1f746072012-08-29 21:13:06 +00001029 const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030 size_t func_idx;
Greg Clayton1f746072012-08-29 21:13:06 +00001031 for (func_idx = 0; func_idx < num_functions; ++func_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001033 DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
1034 if (sc.comp_unit->FindFunctionByUID (die.GetID()).get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001035 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001036 if (ParseCompileUnitFunction(sc, die))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001037 ++functions_added;
1038 }
1039 }
1040 //FixupTypes();
1041 }
1042 return functions_added;
1043}
1044
1045bool
1046SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
1047{
1048 assert (sc.comp_unit);
Greg Clayton1f746072012-08-29 21:13:06 +00001049 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Greg Claytonda2455b2012-11-01 17:28:37 +00001050 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001052 const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053
Greg Claytonda2455b2012-11-01 17:28:37 +00001054 if (cu_die)
1055 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001056 const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
Matthew Gardinere81df3b2014-08-26 06:57:23 +00001057
Greg Clayton5ce1a842015-08-27 18:09:44 +00001058 const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001059
Greg Claytonda2455b2012-11-01 17:28:37 +00001060 // All file indexes in DWARF are one based and a file of index zero is
1061 // supposed to be the compile unit itself.
1062 support_files.Append (*sc.comp_unit);
1063
1064 return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
1065 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066 }
1067 return false;
1068}
1069
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001070bool
1071SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
1072{
1073 assert (sc.comp_unit);
1074 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1075 if (dwarf_cu)
1076 {
1077 if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
1078 {
1079 UpdateExternalModuleListIfNeeded();
Greg Claytone6b36cd2015-12-08 01:02:08 +00001080 for (const auto &pair : m_external_type_modules)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001081 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001082 imported_modules.push_back(pair.first);
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001083 }
1084 }
1085 }
1086 return false;
1087}
1088
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089struct ParseDWARFLineTableCallbackInfo
1090{
1091 LineTable* line_table;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001092 std::unique_ptr<LineSequence> sequence_ap;
Jaydeep Patil44d07fc2015-09-22 06:36:56 +00001093 lldb::addr_t addr_mask;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094};
1095
1096//----------------------------------------------------------------------
1097// ParseStatementTableCallback
1098//----------------------------------------------------------------------
1099static void
1100ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1101{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001102 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1103 {
1104 // Just started parsing the line table
1105 }
1106 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1107 {
1108 // Done parsing line table, nothing to do for the cleanup
1109 }
1110 else
1111 {
1112 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
Greg Clayton9422dd62013-03-04 21:46:16 +00001113 LineTable* line_table = info->line_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001114
Greg Clayton9422dd62013-03-04 21:46:16 +00001115 // If this is our first time here, we need to create a
1116 // sequence container.
1117 if (!info->sequence_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001118 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001119 info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
1120 assert(info->sequence_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001121 }
Greg Clayton9422dd62013-03-04 21:46:16 +00001122 line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
Jaydeep Patil44d07fc2015-09-22 06:36:56 +00001123 state.address & info->addr_mask,
Greg Clayton9422dd62013-03-04 21:46:16 +00001124 state.line,
1125 state.column,
1126 state.file,
1127 state.is_stmt,
1128 state.basic_block,
1129 state.prologue_end,
1130 state.epilogue_begin,
1131 state.end_sequence);
1132 if (state.end_sequence)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001134 // First, put the current sequence into the line table.
1135 line_table->InsertSequence(info->sequence_ap.get());
1136 // Then, empty it to prepare for the next sequence.
1137 info->sequence_ap->Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001138 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001139 }
1140}
1141
1142bool
1143SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1144{
1145 assert (sc.comp_unit);
1146 if (sc.comp_unit->GetLineTable() != NULL)
1147 return true;
1148
Greg Clayton1f746072012-08-29 21:13:06 +00001149 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150 if (dwarf_cu)
1151 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001152 const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Greg Clayton129d12c2011-11-28 03:29:03 +00001153 if (dwarf_cu_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001154 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001155 const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
Greg Clayton129d12c2011-11-28 03:29:03 +00001156 if (cu_line_offset != DW_INVALID_OFFSET)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001158 std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
Greg Clayton129d12c2011-11-28 03:29:03 +00001159 if (line_table_ap.get())
1160 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001161 ParseDWARFLineTableCallbackInfo info;
1162 info.line_table = line_table_ap.get();
Jaydeep Patil44d07fc2015-09-22 06:36:56 +00001163
1164 /*
1165 * MIPS:
1166 * The SymbolContext may not have a valid target, thus we may not be able
1167 * to call Address::GetOpcodeLoadAddress() which would clear the bit #0
1168 * for MIPS. Use ArchSpec to clear the bit #0.
1169 */
1170 ArchSpec arch;
1171 GetObjectFile()->GetArchitecture(arch);
1172 switch (arch.GetMachine())
1173 {
1174 case llvm::Triple::mips:
1175 case llvm::Triple::mipsel:
1176 case llvm::Triple::mips64:
1177 case llvm::Triple::mips64el:
1178 info.addr_mask = ~((lldb::addr_t)1);
1179 break;
1180 default:
1181 info.addr_mask = ~((lldb::addr_t)0);
1182 break;
1183 }
1184
Greg Claytonc7bece562013-01-25 18:06:21 +00001185 lldb::offset_t offset = cu_line_offset;
Greg Clayton129d12c2011-11-28 03:29:03 +00001186 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
Greg Clayton9422dd62013-03-04 21:46:16 +00001187 if (m_debug_map_symfile)
1188 {
1189 // We have an object file that has a line table with addresses
1190 // that are not linked. We need to link the line table and convert
1191 // the addresses that are relative to the .o file into addresses
1192 // for the main executable.
1193 sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
1194 }
1195 else
1196 {
1197 sc.comp_unit->SetLineTable(line_table_ap.release());
1198 return true;
1199 }
Greg Clayton129d12c2011-11-28 03:29:03 +00001200 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001201 }
1202 }
1203 }
1204 return false;
1205}
1206
1207size_t
Greg Clayton6071e6f2015-08-26 22:57:51 +00001208SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc,
1209 Block *parent_block,
1210 const DWARFDIE &orig_die,
1211 addr_t subprogram_low_pc,
1212 uint32_t depth)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213{
1214 size_t blocks_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001215 DWARFDIE die = orig_die;
1216 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001217 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001218 dw_tag_t tag = die.Tag();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001219
1220 switch (tag)
1221 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001222 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001223 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001224 case DW_TAG_lexical_block:
1225 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001226 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001227 if (tag == DW_TAG_subprogram)
1228 {
1229 // Skip any DW_TAG_subprogram DIEs that are inside
1230 // of a normal or inlined functions. These will be
1231 // parsed on their own as separate entities.
1232
1233 if (depth > 0)
1234 break;
1235
1236 block = parent_block;
1237 }
1238 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001239 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001240 BlockSP block_sp(new Block (die.GetID()));
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001241 parent_block->AddChild(block_sp);
1242 block = block_sp.get();
1243 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001244 DWARFRangeList ranges;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001245 const char *name = NULL;
1246 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001247
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001248 int decl_file = 0;
1249 int decl_line = 0;
1250 int decl_column = 0;
1251 int call_file = 0;
1252 int call_line = 0;
1253 int call_column = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001254 if (die.GetDIENamesAndRanges (name,
1255 mangled_name,
1256 ranges,
1257 decl_file, decl_line, decl_column,
1258 call_file, call_line, call_column, nullptr))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259 {
1260 if (tag == DW_TAG_subprogram)
1261 {
1262 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
Greg Claytonea3e7d52011-10-08 00:49:15 +00001263 subprogram_low_pc = ranges.GetMinRangeBase(0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001265 else if (tag == DW_TAG_inlined_subroutine)
1266 {
1267 // We get called here for inlined subroutines in two ways.
1268 // The first time is when we are making the Function object
1269 // for this inlined concrete instance. Since we're creating a top level block at
1270 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1271 // adjust the containing address.
1272 // The second time is when we are parsing the blocks inside the function that contains
1273 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1274 // function the offset will be for that function.
1275 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1276 {
Greg Claytonea3e7d52011-10-08 00:49:15 +00001277 subprogram_low_pc = ranges.GetMinRangeBase(0);
Jim Inghamb0be4422010-08-12 01:20:14 +00001278 }
1279 }
Greg Clayton103f3092015-01-15 03:04:37 +00001280
1281 const size_t num_ranges = ranges.GetSize();
1282 for (size_t i = 0; i<num_ranges; ++i)
1283 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001284 const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
Greg Clayton103f3092015-01-15 03:04:37 +00001285 const addr_t range_base = range.GetRangeBase();
1286 if (range_base >= subprogram_low_pc)
1287 block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
1288 else
1289 {
1290 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",
1291 block->GetID(),
1292 range_base,
1293 range.GetRangeEnd(),
1294 subprogram_low_pc);
1295 }
1296 }
1297 block->FinalizeRanges ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001298
1299 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1300 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001301 std::unique_ptr<Declaration> decl_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001303 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1304 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001305
Greg Clayton7b0992d2013-04-18 22:45:39 +00001306 std::unique_ptr<Declaration> call_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001307 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001308 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1309 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001310
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001311 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001312 }
1313
1314 ++blocks_added;
1315
Greg Clayton6071e6f2015-08-26 22:57:51 +00001316 if (die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001317 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001318 blocks_added += ParseFunctionBlocks (sc,
1319 block,
Greg Clayton6071e6f2015-08-26 22:57:51 +00001320 die.GetFirstChild(),
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001321 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001322 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001323 }
1324 }
1325 }
1326 break;
1327 default:
1328 break;
1329 }
1330
Greg Claytondd7feaf2011-08-12 17:54:33 +00001331 // Only parse siblings of the block if we are not at depth zero. A depth
1332 // of zero indicates we are currently parsing the top level
1333 // DW_TAG_subprogram DIE
1334
1335 if (depth == 0)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001336 die.Clear();
Greg Claytondd7feaf2011-08-12 17:54:33 +00001337 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00001338 die = die.GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001339 }
1340 return blocks_added;
1341}
1342
Greg Claytonf0705c82011-10-22 03:33:13 +00001343bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00001344SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
Greg Claytonc4ffd662013-03-08 01:37:30 +00001345{
1346 if (parent_die)
1347 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001348 for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling())
Greg Claytonc4ffd662013-03-08 01:37:30 +00001349 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001350 dw_tag_t tag = die.Tag();
Greg Claytonc4ffd662013-03-08 01:37:30 +00001351 bool check_virtuality = false;
1352 switch (tag)
1353 {
1354 case DW_TAG_inheritance:
1355 case DW_TAG_subprogram:
1356 check_virtuality = true;
1357 break;
1358 default:
1359 break;
1360 }
1361 if (check_virtuality)
1362 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001363 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
Greg Claytonc4ffd662013-03-08 01:37:30 +00001364 return true;
1365 }
1366 }
1367 }
1368 return false;
1369}
1370
Paul Hermanea188fc2015-09-16 18:48:30 +00001371void
1372SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
1373{
1374 TypeSystem *type_system = decl_ctx.GetTypeSystem();
1375 DWARFASTParser *ast_parser = type_system->GetDWARFParser();
1376 std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx);
1377
1378 for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
1379 for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling())
1380 ast_parser->GetDeclForUIDFromDWARF(decl);
1381}
1382
Paul Hermand628cbb2015-09-15 23:44:17 +00001383CompilerDecl
1384SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
1385{
1386 if (UserIDMatches(type_uid))
1387 {
1388 DWARFDebugInfo* debug_info = DebugInfo();
1389 if (debug_info)
1390 {
1391 DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
1392 if (die)
1393 {
1394 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1395 if (dwarf_ast)
1396 return dwarf_ast->GetDeclForUIDFromDWARF(die);
1397 }
1398 }
1399 }
1400 return CompilerDecl();
1401}
1402
Greg Clayton99558cc42015-08-24 23:46:31 +00001403CompilerDeclContext
1404SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001405{
Greg Clayton8b4edba2015-08-14 20:02:05 +00001406 if (UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001407 {
Greg Clayton8b4edba2015-08-14 20:02:05 +00001408 DWARFDebugInfo* debug_info = DebugInfo();
1409 if (debug_info)
1410 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001411 DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
Greg Clayton8b4edba2015-08-14 20:02:05 +00001412 if (die)
1413 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00001414 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1415 if (dwarf_ast)
1416 return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
Greg Clayton8b4edba2015-08-14 20:02:05 +00001417 }
1418 }
Sean Callanan72e49402011-08-05 23:43:37 +00001419 }
Greg Clayton99558cc42015-08-24 23:46:31 +00001420 return CompilerDeclContext();
Sean Callanan72e49402011-08-05 23:43:37 +00001421}
1422
Greg Clayton99558cc42015-08-24 23:46:31 +00001423CompilerDeclContext
1424SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
Sean Callanan72e49402011-08-05 23:43:37 +00001425{
Greg Clayton81c22f62011-10-19 18:09:39 +00001426 if (UserIDMatches(type_uid))
Greg Clayton8b4edba2015-08-14 20:02:05 +00001427 {
1428 DWARFDebugInfo* debug_info = DebugInfo();
1429 if (debug_info)
1430 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001431 DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
Greg Clayton8b4edba2015-08-14 20:02:05 +00001432 if (die)
1433 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00001434 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
1435 if (dwarf_ast)
1436 return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
Greg Clayton8b4edba2015-08-14 20:02:05 +00001437 }
1438 }
1439 }
Greg Clayton99558cc42015-08-24 23:46:31 +00001440 return CompilerDeclContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001441}
1442
Greg Clayton99558cc42015-08-24 23:46:31 +00001443
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001444Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001445SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001446{
Greg Clayton81c22f62011-10-19 18:09:39 +00001447 if (UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001448 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001449 DWARFDebugInfo* debug_info = DebugInfo();
1450 if (debug_info)
Greg Claytonca512b32011-01-14 04:54:56 +00001451 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001452 DWARFDIE type_die = debug_info->GetDIE (DIERef(type_uid));
Greg Clayton6071e6f2015-08-26 22:57:51 +00001453 if (type_die)
1454 {
1455 const bool assert_not_being_parsed = true;
1456 return ResolveTypeUID (type_die, assert_not_being_parsed);
1457 }
Greg Claytonca512b32011-01-14 04:54:56 +00001458 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001459 }
1460 return NULL;
1461}
1462
Greg Claytoncab36a32011-12-08 05:16:30 +00001463Type*
Greg Clayton6071e6f2015-08-26 22:57:51 +00001464SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed)
Sean Callanan5b26f272012-02-04 08:49:35 +00001465{
Greg Clayton6071e6f2015-08-26 22:57:51 +00001466 if (die)
Greg Claytoncab36a32011-12-08 05:16:30 +00001467 {
Greg Clayton5160ce52013-03-27 23:08:40 +00001468 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00001469 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001470 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00001471 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
Greg Clayton6071e6f2015-08-26 22:57:51 +00001472 die.GetOffset(),
1473 die.GetTagAsCString(),
1474 die.GetName());
Greg Clayton3bffb082011-12-10 02:15:28 +00001475
Greg Claytoncab36a32011-12-08 05:16:30 +00001476 // We might be coming in in the middle of a type tree (a class
1477 // withing a class, an enum within a class), so parse any needed
1478 // parent DIEs before we get to this one...
Greg Clayton6071e6f2015-08-26 22:57:51 +00001479 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die);
1480 if (decl_ctx_die)
Greg Claytoncab36a32011-12-08 05:16:30 +00001481 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001482 if (log)
Greg Claytoncab36a32011-12-08 05:16:30 +00001483 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001484 switch (decl_ctx_die.Tag())
1485 {
1486 case DW_TAG_structure_type:
1487 case DW_TAG_union_type:
1488 case DW_TAG_class_type:
1489 {
1490 // Get the type, which could be a forward declaration
1491 if (log)
1492 GetObjectFile()->GetModule()->LogMessage (log,
1493 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
1494 die.GetOffset(),
1495 die.GetTagAsCString(),
1496 die.GetName(),
1497 decl_ctx_die.GetOffset());
1498 }
1499 break;
Greg Claytoncab36a32011-12-08 05:16:30 +00001500
Greg Clayton6071e6f2015-08-26 22:57:51 +00001501 default:
1502 break;
1503 }
1504 }
Greg Claytoncab36a32011-12-08 05:16:30 +00001505 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001506 return ResolveType (die);
Greg Claytoncab36a32011-12-08 05:16:30 +00001507 }
1508 return NULL;
1509}
1510
Greg Clayton6beaaa62011-01-17 03:46:26 +00001511// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1512// SymbolFileDWARF objects to detect if this DWARF file is the one that
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001513// can resolve a compiler_type.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001514bool
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001515SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001516{
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001517 CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
Greg Claytone6b36cd2015-12-08 01:02:08 +00001518 if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
1519 {
1520 return true;
1521 }
1522 TypeSystem *type_system = compiler_type.GetTypeSystem();
1523 if (type_system)
1524 {
1525 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
1526 if (dwarf_ast)
1527 return dwarf_ast->CanCompleteType(compiler_type);
1528 }
1529 return false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001530}
1531
1532
Greg Clayton57ee3062013-07-11 22:46:58 +00001533bool
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001534SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001535{
Greg Claytone6b36cd2015-12-08 01:02:08 +00001536 TypeSystem *type_system = compiler_type.GetTypeSystem();
1537 if (type_system)
1538 {
1539 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
1540 if (dwarf_ast && dwarf_ast->CanCompleteType(compiler_type))
1541 return dwarf_ast->CompleteType(compiler_type);
1542 }
1543
Greg Clayton1be10fc2010-09-29 01:12:09 +00001544 // We have a struct/union/class/enum that needs to be fully resolved.
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001545 CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
1546 auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001547 if (die_it == GetForwardDeclClangTypeToDie().end())
Greg Clayton73b472d2010-10-27 03:32:59 +00001548 {
1549 // We have already resolved this type...
Greg Clayton57ee3062013-07-11 22:46:58 +00001550 return true;
Greg Clayton73b472d2010-10-27 03:32:59 +00001551 }
Tamas Berghammerf8fd9b52015-09-14 15:44:29 +00001552
1553 DWARFDebugInfo* debug_info = DebugInfo();
1554 DWARFDIE dwarf_die = debug_info->GetDIE(die_it->getSecond());
1555
Tamas Berghammer69d0b332015-10-09 12:43:08 +00001556 assert(UserIDMatches(die_it->getSecond().GetUID()) && "CompleteType called on the wrong SymbolFile");
1557
Greg Clayton73b472d2010-10-27 03:32:59 +00001558 // Once we start resolving this type, remove it from the forward declaration
1559 // map in case anyone child members or other types require this type to get resolved.
1560 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1561 // are done.
Tamas Berghammerf8fd9b52015-09-14 15:44:29 +00001562 GetForwardDeclClangTypeToDie().erase (die_it);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001563
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001564 Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001565
Greg Clayton5160ce52013-03-27 23:08:40 +00001566 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
Greg Clayton3bffb082011-12-10 02:15:28 +00001567 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001568 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
Daniel Malead01b2952012-11-29 21:49:15 +00001569 "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
Greg Clayton6071e6f2015-08-26 22:57:51 +00001570 dwarf_die.GetID(),
1571 dwarf_die.GetTagAsCString(),
Greg Claytond61c0fc2012-04-23 22:55:20 +00001572 type->GetName().AsCString());
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001573 assert (compiler_type);
Greg Clayton261ac3f2015-08-28 01:01:03 +00001574 DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
1575 if (dwarf_ast)
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001576 return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00001577 return false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001578}
1579
Greg Clayton8b4edba2015-08-14 20:02:05 +00001580Type*
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00001581SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed, bool resolve_function_context)
Greg Clayton8b4edba2015-08-14 20:02:05 +00001582{
Greg Clayton6071e6f2015-08-26 22:57:51 +00001583 if (die)
Greg Clayton8b4edba2015-08-14 20:02:05 +00001584 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001585 Type *type = GetDIEToType().lookup (die.GetDIE());
Greg Claytoncab36a32011-12-08 05:16:30 +00001586
Greg Claytonc685f8e2010-09-15 04:15:46 +00001587 if (type == NULL)
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00001588 type = GetTypeForDIE (die, resolve_function_context).get();
Greg Claytoncab36a32011-12-08 05:16:30 +00001589
Greg Clayton24739922010-10-13 03:15:28 +00001590 if (assert_not_being_parsed)
Jim Inghamc3549282012-01-11 02:21:12 +00001591 {
1592 if (type != DIE_IS_BEING_PARSED)
1593 return type;
1594
1595 GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
Greg Clayton6071e6f2015-08-26 22:57:51 +00001596 die.GetOffset(),
1597 die.GetTagAsCString(),
1598 die.GetName());
Jim Inghamc3549282012-01-11 02:21:12 +00001599
1600 }
1601 else
1602 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001603 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001604 return nullptr;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001605}
1606
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001607CompileUnit*
Greg Clayton53eb1c22012-04-02 22:59:12 +00001608SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001609{
1610 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton53eb1c22012-04-02 22:59:12 +00001611 if (dwarf_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001612 {
1613 // The symbol vendor doesn't know about this compile unit, we
1614 // need to parse and add it to the symbol vendor object.
Greg Clayton53eb1c22012-04-02 22:59:12 +00001615 return ParseCompileUnit(dwarf_cu, cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001616 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001617 return (CompileUnit*)dwarf_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001618}
1619
Greg Clayton8b4edba2015-08-14 20:02:05 +00001620size_t
1621SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets)
1622{
1623 method_die_offsets.clear();
1624 if (m_using_apple_tables)
1625 {
1626 if (m_apple_objc_ap.get())
1627 m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
1628 }
1629 else
1630 {
1631 if (!m_indexed)
1632 Index ();
1633
1634 m_objc_class_selectors_index.Find (class_name, method_die_offsets);
1635 }
1636 return method_die_offsets.size();
1637}
1638
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001639bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00001640SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001641{
Greg Clayton72310352013-02-23 04:12:47 +00001642 sc.Clear(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001643
Greg Clayton6071e6f2015-08-26 22:57:51 +00001644 if (die)
1645 {
1646 // Check if the symbol vendor already knows about this compile unit?
1647 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
1648
1649 sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get();
1650 if (sc.function == NULL)
1651 sc.function = ParseCompileUnitFunction(sc, die);
1652
1653 if (sc.function)
1654 {
1655 sc.module_sp = sc.function->CalculateSymbolContextModule();
1656 return true;
1657 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00001658 }
1659
1660 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001661}
1662
Greg Claytone6b36cd2015-12-08 01:02:08 +00001663lldb::ModuleSP
1664SymbolFileDWARF::GetDWOModule (ConstString name)
1665{
1666 UpdateExternalModuleListIfNeeded();
1667 const auto &pos = m_external_type_modules.find(name);
1668 if (pos != m_external_type_modules.end())
1669 return pos->second;
1670 else
1671 return lldb::ModuleSP();
1672}
1673
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001674void
1675SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
1676{
1677 if (m_fetched_external_modules)
1678 return;
1679 m_fetched_external_modules = true;
1680
1681 DWARFDebugInfo * debug_info = DebugInfo();
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001682
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001683 const uint32_t num_compile_units = GetNumCompileUnits();
1684 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1685 {
1686 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1687
Greg Clayton5ce1a842015-08-27 18:09:44 +00001688 const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
1689 if (die && die.HasChildren() == false)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001690 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001691 const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
1692
1693 if (name)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001694 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001695 ConstString const_name(name);
1696 if (m_external_type_modules.find(const_name) == m_external_type_modules.end())
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001697 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001698 ModuleSP module_sp;
1699 const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
1700 if (dwo_path)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001701 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001702 ModuleSpec dwo_module_spec;
1703 dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
1704 dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
1705 //printf ("Loading dwo = '%s'\n", dwo_path);
1706 Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001707 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00001708 m_external_type_modules[const_name] = module_sp;
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001709 }
1710 }
1711 }
1712 }
1713}
Greg Clayton2501e5e2015-01-15 02:59:20 +00001714
1715SymbolFileDWARF::GlobalVariableMap &
1716SymbolFileDWARF::GetGlobalAranges()
1717{
1718 if (!m_global_aranges_ap)
1719 {
1720 m_global_aranges_ap.reset (new GlobalVariableMap());
1721
1722 ModuleSP module_sp = GetObjectFile()->GetModule();
1723 if (module_sp)
1724 {
1725 const size_t num_cus = module_sp->GetNumCompileUnits();
1726 for (size_t i = 0; i < num_cus; ++i)
1727 {
1728 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
1729 if (cu_sp)
1730 {
1731 VariableListSP globals_sp = cu_sp->GetVariableList(true);
1732 if (globals_sp)
1733 {
1734 const size_t num_globals = globals_sp->GetSize();
1735 for (size_t g = 0; g < num_globals; ++g)
1736 {
1737 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
1738 if (var_sp && !var_sp->GetLocationIsConstantValueData())
1739 {
1740 const DWARFExpression &location = var_sp->LocationExpression();
1741 Value location_result;
1742 Error error;
1743 if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
1744 {
1745 if (location_result.GetValueType() == Value::eValueTypeFileAddress)
1746 {
1747 lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
1748 lldb::addr_t byte_size = 1;
1749 if (var_sp->GetType())
1750 byte_size = var_sp->GetType()->GetByteSize();
1751 m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
1752 }
1753 }
1754 }
1755 }
1756 }
1757 }
1758 }
1759 }
1760 m_global_aranges_ap->Sort();
1761 }
1762 return *m_global_aranges_ap;
1763}
1764
1765
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001766uint32_t
1767SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1768{
1769 Timer scoped_timer(__PRETTY_FUNCTION__,
Daniel Malead01b2952012-11-29 21:49:15 +00001770 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001771 static_cast<void*>(so_addr.GetSection().get()),
1772 so_addr.GetOffset(), resolve_scope);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001773 uint32_t resolved = 0;
Greg Clayton2501e5e2015-01-15 02:59:20 +00001774 if (resolve_scope & ( eSymbolContextCompUnit |
1775 eSymbolContextFunction |
1776 eSymbolContextBlock |
1777 eSymbolContextLineEntry |
1778 eSymbolContextVariable ))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001779 {
1780 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1781
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001782 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00001783 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001784 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001785 const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Greg Clayton2501e5e2015-01-15 02:59:20 +00001786 if (cu_offset == DW_INVALID_OFFSET)
1787 {
1788 // Global variables are not in the compile unit address ranges. The only way to
1789 // currently find global variables is to iterate over the .debug_pubnames or the
1790 // __apple_names table and find all items in there that point to DW_TAG_variable
1791 // DIEs and then find the address that matches.
1792 if (resolve_scope & eSymbolContextVariable)
1793 {
1794 GlobalVariableMap &map = GetGlobalAranges();
1795 const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
1796 if (entry && entry->data)
1797 {
1798 Variable *variable = entry->data;
1799 SymbolContextScope *scc = variable->GetSymbolContextScope();
1800 if (scc)
1801 {
1802 scc->CalculateSymbolContext(&sc);
1803 sc.variable = variable;
1804 }
1805 return sc.GetResolvedMask();
1806 }
1807 }
1808 }
1809 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001810 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001811 uint32_t cu_idx = DW_INVALID_INDEX;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001812 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx);
Greg Clayton53eb1c22012-04-02 22:59:12 +00001813 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001814 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001815 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001816 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001817 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001818 resolved |= eSymbolContextCompUnit;
1819
Greg Clayton6ab80132012-12-12 17:30:52 +00001820 bool force_check_line_table = false;
Greg Clayton526a4ae2012-05-16 22:09:01 +00001821 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1822 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001823 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1824 DWARFDIE block_die;
1825 if (function_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001826 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001827 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
Greg Clayton526a4ae2012-05-16 22:09:01 +00001828 if (sc.function == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001829 sc.function = ParseCompileUnitFunction(sc, function_die);
1830
1831 if (sc.function && (resolve_scope & eSymbolContextBlock))
1832 block_die = function_die.LookupDeepestBlock(file_vm_addr);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001833 }
1834 else
1835 {
1836 // We might have had a compile unit that had discontiguous
1837 // address ranges where the gaps are symbols that don't have
1838 // any debug info. Discontiguous compile unit address ranges
1839 // should only happen when there aren't other functions from
1840 // other compile units in these gaps. This helps keep the size
1841 // of the aranges down.
Greg Clayton6ab80132012-12-12 17:30:52 +00001842 force_check_line_table = true;
Greg Clayton526a4ae2012-05-16 22:09:01 +00001843 }
1844
1845 if (sc.function != NULL)
1846 {
1847 resolved |= eSymbolContextFunction;
1848
1849 if (resolve_scope & eSymbolContextBlock)
1850 {
1851 Block& block = sc.function->GetBlock (true);
1852
Greg Clayton6071e6f2015-08-26 22:57:51 +00001853 if (block_die)
1854 sc.block = block.FindBlockByID (block_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00001855 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00001856 sc.block = block.FindBlockByID (function_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00001857 if (sc.block)
1858 resolved |= eSymbolContextBlock;
1859 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001860 }
1861 }
Greg Clayton6ab80132012-12-12 17:30:52 +00001862
1863 if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
1864 {
1865 LineTable *line_table = sc.comp_unit->GetLineTable();
1866 if (line_table != NULL)
1867 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001868 // And address that makes it into this function should be in terms
1869 // of this debug file if there is no debug map, or it will be an
1870 // address in the .o file which needs to be fixed up to be in terms
1871 // of the debug map executable. Either way, calling FixupAddress()
1872 // will work for us.
1873 Address exe_so_addr (so_addr);
1874 if (FixupAddress(exe_so_addr))
Greg Clayton6ab80132012-12-12 17:30:52 +00001875 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001876 if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
Greg Clayton6ab80132012-12-12 17:30:52 +00001877 {
1878 resolved |= eSymbolContextLineEntry;
1879 }
1880 }
Greg Clayton6ab80132012-12-12 17:30:52 +00001881 }
1882 }
1883
1884 if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
1885 {
1886 // We might have had a compile unit that had discontiguous
1887 // address ranges where the gaps are symbols that don't have
1888 // any debug info. Discontiguous compile unit address ranges
1889 // should only happen when there aren't other functions from
1890 // other compile units in these gaps. This helps keep the size
1891 // of the aranges down.
1892 sc.comp_unit = NULL;
1893 resolved &= ~eSymbolContextCompUnit;
1894 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001895 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00001896 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001897 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001898 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
1899 cu_offset,
1900 cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001901 }
1902 }
1903 }
1904 }
1905 }
1906 return resolved;
1907}
1908
1909
1910
1911uint32_t
1912SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1913{
1914 const uint32_t prev_size = sc_list.GetSize();
1915 if (resolve_scope & eSymbolContextCompUnit)
1916 {
1917 DWARFDebugInfo* debug_info = DebugInfo();
1918 if (debug_info)
1919 {
1920 uint32_t cu_idx;
Greg Clayton53eb1c22012-04-02 22:59:12 +00001921 DWARFCompileUnit* dwarf_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001922
Greg Clayton53eb1c22012-04-02 22:59:12 +00001923 for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001924 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001925 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Sean Callananddd7a2a2013-10-03 22:27:29 +00001926 const bool full_match = (bool)file_spec.GetDirectory();
Greg Clayton1f746072012-08-29 21:13:06 +00001927 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001928 if (check_inlines || file_spec_matches_cu_file_spec)
1929 {
1930 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton53eb1c22012-04-02 22:59:12 +00001931 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001932 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001933 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001934 uint32_t file_idx = UINT32_MAX;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001935
Greg Clayton526a4ae2012-05-16 22:09:01 +00001936 // If we are looking for inline functions only and we don't
1937 // find it in the support files, we are done.
1938 if (check_inlines)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001939 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001940 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
1941 if (file_idx == UINT32_MAX)
1942 continue;
1943 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001944
Greg Clayton526a4ae2012-05-16 22:09:01 +00001945 if (line != 0)
1946 {
1947 LineTable *line_table = sc.comp_unit->GetLineTable();
1948
1949 if (line_table != NULL && line != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001950 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001951 // We will have already looked up the file index if
1952 // we are searching for inline entries.
1953 if (!check_inlines)
1954 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001955
Greg Clayton526a4ae2012-05-16 22:09:01 +00001956 if (file_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001957 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001958 uint32_t found_line;
1959 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1960 found_line = sc.line_entry.line;
1961
1962 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001963 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001964 sc.function = NULL;
1965 sc.block = NULL;
1966 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001967 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001968 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1969 if (file_vm_addr != LLDB_INVALID_ADDRESS)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001970 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001971 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1972 DWARFDIE block_die;
1973 if (function_die)
Greg Clayton526a4ae2012-05-16 22:09:01 +00001974 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001975 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
Greg Clayton526a4ae2012-05-16 22:09:01 +00001976 if (sc.function == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001977 sc.function = ParseCompileUnitFunction(sc, function_die);
1978
1979 if (sc.function && (resolve_scope & eSymbolContextBlock))
1980 block_die = function_die.LookupDeepestBlock(file_vm_addr);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001981 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001982
Greg Clayton526a4ae2012-05-16 22:09:01 +00001983 if (sc.function != NULL)
1984 {
1985 Block& block = sc.function->GetBlock (true);
1986
Greg Clayton6071e6f2015-08-26 22:57:51 +00001987 if (block_die)
1988 sc.block = block.FindBlockByID (block_die.GetID());
1989 else if (function_die)
1990 sc.block = block.FindBlockByID (function_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00001991 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001992 }
1993 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001994
Greg Clayton526a4ae2012-05-16 22:09:01 +00001995 sc_list.Append(sc);
1996 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1997 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001998 }
1999 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00002000 else if (file_spec_matches_cu_file_spec && !check_inlines)
2001 {
2002 // only append the context if we aren't looking for inline call sites
2003 // by file and line and if the file spec matches that of the compile unit
2004 sc_list.Append(sc);
2005 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002006 }
2007 else if (file_spec_matches_cu_file_spec && !check_inlines)
2008 {
2009 // only append the context if we aren't looking for inline call sites
2010 // by file and line and if the file spec matches that of the compile unit
2011 sc_list.Append(sc);
2012 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002013
Greg Clayton526a4ae2012-05-16 22:09:01 +00002014 if (!check_inlines)
2015 break;
2016 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002017 }
2018 }
2019 }
2020 }
2021 return sc_list.GetSize() - prev_size;
2022}
2023
2024void
2025SymbolFileDWARF::Index ()
2026{
2027 if (m_indexed)
2028 return;
2029 m_indexed = true;
2030 Timer scoped_timer (__PRETTY_FUNCTION__,
2031 "SymbolFileDWARF::Index (%s)",
Jim Ingham4af59612014-12-19 19:20:44 +00002032 GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002033
2034 DWARFDebugInfo* debug_info = DebugInfo();
2035 if (debug_info)
2036 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002037 const uint32_t num_compile_units = GetNumCompileUnits();
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002038 std::vector<NameToDIE> function_basename_index(num_compile_units);
2039 std::vector<NameToDIE> function_fullname_index(num_compile_units);
2040 std::vector<NameToDIE> function_method_index(num_compile_units);
2041 std::vector<NameToDIE> function_selector_index(num_compile_units);
2042 std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
2043 std::vector<NameToDIE> global_index(num_compile_units);
2044 std::vector<NameToDIE> type_index(num_compile_units);
2045 std::vector<NameToDIE> namespace_index(num_compile_units);
2046
2047 auto parser_fn = [this,
2048 debug_info,
2049 &function_basename_index,
2050 &function_fullname_index,
2051 &function_method_index,
2052 &function_selector_index,
2053 &objc_class_selectors_index,
2054 &global_index,
2055 &type_index,
2056 &namespace_index](uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002057 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00002058 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002059 bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002060
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002061 dwarf_cu->Index(function_basename_index[cu_idx],
2062 function_fullname_index[cu_idx],
2063 function_method_index[cu_idx],
2064 function_selector_index[cu_idx],
2065 objc_class_selectors_index[cu_idx],
2066 global_index[cu_idx],
2067 type_index[cu_idx],
2068 namespace_index[cu_idx]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002069
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002070 // Keep memory down by clearing DIEs if this generate function
2071 // caused them to be parsed
2072 if (clear_dies)
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002073 dwarf_cu->ClearDIEs(true);
2074
2075 return cu_idx;
2076 };
2077
2078 TaskRunner<uint32_t> task_runner;
2079 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2080 task_runner.AddTask(parser_fn, cu_idx);
2081
2082 while (true)
2083 {
2084 std::future<uint32_t> f = task_runner.WaitForNextCompletedTask();
2085 if (!f.valid())
2086 break;
2087 uint32_t cu_idx = f.get();
2088
2089 m_function_basename_index.Append(function_basename_index[cu_idx]);
2090 m_function_fullname_index.Append(function_fullname_index[cu_idx]);
2091 m_function_method_index.Append(function_method_index[cu_idx]);
2092 m_function_selector_index.Append(function_selector_index[cu_idx]);
2093 m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]);
2094 m_global_index.Append(global_index[cu_idx]);
2095 m_type_index.Append(type_index[cu_idx]);
2096 m_namespace_index.Append(namespace_index[cu_idx]);
Tamas Berghammerda4e8ed2015-10-20 15:43:40 +00002097 }
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002098
2099 TaskPool::RunTasks(
2100 [&]() { m_function_basename_index.Finalize(); },
2101 [&]() { m_function_fullname_index.Finalize(); },
2102 [&]() { m_function_method_index.Finalize(); },
2103 [&]() { m_function_selector_index.Finalize(); },
2104 [&]() { m_objc_class_selectors_index.Finalize(); },
2105 [&]() { m_global_index.Finalize(); },
2106 [&]() { m_type_index.Finalize(); },
2107 [&]() { m_namespace_index.Finalize(); });
Greg Claytonc685f8e2010-09-15 04:15:46 +00002108
Greg Clayton24739922010-10-13 03:15:28 +00002109#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00002110 StreamFile s(stdout, false);
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002111 s.Printf ("DWARF index for '%s':",
2112 GetObjectFile()->GetFileSpec().GetPath().c_str());
Greg Claytonba2d22d2010-11-13 22:57:37 +00002113 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
2114 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
2115 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
2116 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
2117 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
2118 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00002119 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Bruce Mitchenere171da52015-07-22 00:16:02 +00002120 s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002121#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002122 }
2123}
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002124
2125bool
Greg Clayton99558cc42015-08-24 23:46:31 +00002126SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx)
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002127{
Greg Clayton99558cc42015-08-24 23:46:31 +00002128 if (decl_ctx == nullptr || !decl_ctx->IsValid())
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002129 {
2130 // Invalid namespace decl which means we aren't matching only things
2131 // in this symbol file, so return true to indicate it matches this
2132 // symbol file.
2133 return true;
2134 }
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002135
Greg Clayton56939cb2015-09-17 22:23:34 +00002136 TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
2137 TypeSystem *type_system = GetTypeSystemForLanguage(decl_ctx_type_system->GetMinimumLanguage(nullptr));
2138 if (decl_ctx_type_system == type_system)
Greg Clayton99558cc42015-08-24 23:46:31 +00002139 return true; // The type systems match, return true
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002140
2141 // The namespace AST was valid, and it does not match...
Greg Clayton5160ce52013-03-27 23:08:40 +00002142 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Sean Callananc41e68b2011-10-13 21:08:11 +00002143
2144 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002145 GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
Sean Callananc41e68b2011-10-13 21:08:11 +00002146
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002147 return false;
2148}
2149
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002150uint32_t
Greg Clayton99558cc42015-08-24 23:46:31 +00002151SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002152{
Greg Clayton5160ce52013-03-27 23:08:40 +00002153 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002154
2155 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002156 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002157 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
Greg Claytone38a5ed2012-01-05 03:57:59 +00002158 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002159 static_cast<const void*>(parent_decl_ctx),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002160 append, max_matches);
2161
Greg Clayton99558cc42015-08-24 23:46:31 +00002162 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00002163 return 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002164
Greg Claytonc685f8e2010-09-15 04:15:46 +00002165 DWARFDebugInfo* info = DebugInfo();
2166 if (info == NULL)
2167 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002168
2169 // If we aren't appending the results to this list, then clear the list
2170 if (!append)
2171 variables.Clear();
2172
2173 // Remember how many variables are in the list before we search in case
2174 // we are appending the results to a variable list.
2175 const uint32_t original_size = variables.GetSize();
2176
Greg Claytond4a2b372011-09-12 23:21:58 +00002177 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002178
Greg Clayton97fbc342011-10-20 22:30:33 +00002179 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002180 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002181 if (m_apple_names_ap.get())
2182 {
2183 const char *name_cstr = name.GetCString();
Jim Inghamfa39bb42014-10-25 00:33:55 +00002184 llvm::StringRef basename;
2185 llvm::StringRef context;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002186
Jim Inghamaa816b82015-09-02 01:59:14 +00002187 if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename))
Jim Inghamfa39bb42014-10-25 00:33:55 +00002188 basename = name_cstr;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002189
Jim Inghamfa39bb42014-10-25 00:33:55 +00002190 m_apple_names_ap->FindByName (basename.data(), die_offsets);
Greg Clayton97fbc342011-10-20 22:30:33 +00002191 }
Greg Clayton7f995132011-10-04 22:41:51 +00002192 }
2193 else
2194 {
2195 // Index the DWARF if we haven't already
2196 if (!m_indexed)
2197 Index ();
2198
2199 m_global_index.Find (name, die_offsets);
2200 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002201
Greg Clayton437a1352012-04-09 22:43:43 +00002202 const size_t num_die_matches = die_offsets.size();
2203 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002204 {
Greg Clayton7f995132011-10-04 22:41:51 +00002205 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00002206 sc.module_sp = m_obj_file->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00002207 assert (sc.module_sp);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002208
Greg Claytond4a2b372011-09-12 23:21:58 +00002209 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton437a1352012-04-09 22:43:43 +00002210 bool done = false;
2211 for (size_t i=0; i<num_die_matches && !done; ++i)
Greg Claytond4a2b372011-09-12 23:21:58 +00002212 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002213 const DIERef& die_ref = die_offsets[i];
2214 DWARFDIE die = debug_info->GetDIE (die_ref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002215
Greg Clayton95d87902011-11-11 03:16:25 +00002216 if (die)
2217 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002218 switch (die.Tag())
Greg Clayton437a1352012-04-09 22:43:43 +00002219 {
2220 default:
2221 case DW_TAG_subprogram:
2222 case DW_TAG_inlined_subroutine:
2223 case DW_TAG_try_block:
2224 case DW_TAG_catch_block:
2225 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002226
Greg Clayton437a1352012-04-09 22:43:43 +00002227 case DW_TAG_variable:
2228 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002229 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002230
Greg Clayton99558cc42015-08-24 23:46:31 +00002231 if (parent_decl_ctx)
Greg Clayton8b4edba2015-08-14 20:02:05 +00002232 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002233 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2234 if (dwarf_ast)
Greg Clayton99558cc42015-08-24 23:46:31 +00002235 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002236 CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00002237 if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx)
2238 continue;
2239 }
Greg Clayton8b4edba2015-08-14 20:02:05 +00002240 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002241
Greg Clayton6071e6f2015-08-26 22:57:51 +00002242 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002243
Greg Clayton437a1352012-04-09 22:43:43 +00002244 if (variables.GetSize() - original_size >= max_matches)
2245 done = true;
2246 }
2247 break;
2248 }
Greg Clayton95d87902011-11-11 03:16:25 +00002249 }
2250 else
2251 {
2252 if (m_using_apple_tables)
2253 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002254 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002255 die_ref.die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00002256 }
2257 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002258 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002259 }
2260
2261 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00002262 const uint32_t num_matches = variables.GetSize() - original_size;
2263 if (log && num_matches > 0)
2264 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002265 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002266 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002267 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002268 static_cast<const void*>(parent_decl_ctx),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002269 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00002270 num_matches);
2271 }
2272 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002273}
2274
2275uint32_t
2276SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2277{
Greg Clayton5160ce52013-03-27 23:08:40 +00002278 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002279
Greg Clayton21f2a492011-10-06 00:09:08 +00002280 if (log)
2281 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002282 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002283 "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002284 regex.GetText(), append,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002285 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00002286 }
2287
Greg Claytonc685f8e2010-09-15 04:15:46 +00002288 DWARFDebugInfo* info = DebugInfo();
2289 if (info == NULL)
2290 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002291
2292 // If we aren't appending the results to this list, then clear the list
2293 if (!append)
2294 variables.Clear();
2295
2296 // Remember how many variables are in the list before we search in case
2297 // we are appending the results to a variable list.
2298 const uint32_t original_size = variables.GetSize();
2299
Greg Clayton7f995132011-10-04 22:41:51 +00002300 DIEArray die_offsets;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002301
Greg Clayton97fbc342011-10-20 22:30:33 +00002302 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002303 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002304 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00002305 {
2306 DWARFMappedHash::DIEInfoArray hash_data_array;
2307 if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2308 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2309 }
Greg Clayton7f995132011-10-04 22:41:51 +00002310 }
2311 else
2312 {
2313 // Index the DWARF if we haven't already
2314 if (!m_indexed)
2315 Index ();
2316
2317 m_global_index.Find (regex, die_offsets);
2318 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002319
Greg Claytonc685f8e2010-09-15 04:15:46 +00002320 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00002321 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002322 assert (sc.module_sp);
2323
Greg Clayton7f995132011-10-04 22:41:51 +00002324 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002325 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002326 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002327 DWARFDebugInfo* debug_info = DebugInfo();
2328 for (size_t i=0; i<num_matches; ++i)
2329 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002330 const DIERef& die_ref = die_offsets[i];
2331 DWARFDIE die = debug_info->GetDIE (die_ref);
Greg Clayton95d87902011-11-11 03:16:25 +00002332
2333 if (die)
2334 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002335 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002336
Greg Clayton6071e6f2015-08-26 22:57:51 +00002337 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002338
Greg Clayton95d87902011-11-11 03:16:25 +00002339 if (variables.GetSize() - original_size >= max_matches)
2340 break;
2341 }
2342 else
2343 {
2344 if (m_using_apple_tables)
2345 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002346 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002347 die_ref.die_offset, regex.GetText());
Greg Clayton95d87902011-11-11 03:16:25 +00002348 }
2349 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002350 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002351 }
2352
2353 // Return the number of variable that were appended to the list
2354 return variables.GetSize() - original_size;
2355}
2356
Greg Claytonaa044962011-10-13 00:59:38 +00002357
Jim Ingham4cda6e02011-10-07 22:23:45 +00002358bool
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002359SymbolFileDWARF::ResolveFunction (const DIERef& die_ref,
Pavel Labatha73d6572015-03-13 10:22:00 +00002360 bool include_inlines,
Jim Ingham4cda6e02011-10-07 22:23:45 +00002361 SymbolContextList& sc_list)
Greg Clayton9e315582011-09-02 04:03:59 +00002362{
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002363 DWARFDIE die = DebugInfo()->GetDIE (die_ref);
Greg Clayton6071e6f2015-08-26 22:57:51 +00002364 return ResolveFunction (die, include_inlines, sc_list);
Greg Claytonaa044962011-10-13 00:59:38 +00002365}
2366
2367
2368bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00002369SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002370 bool include_inlines,
Greg Claytonaa044962011-10-13 00:59:38 +00002371 SymbolContextList& sc_list)
2372{
Greg Clayton9e315582011-09-02 04:03:59 +00002373 SymbolContext sc;
Greg Claytonaa044962011-10-13 00:59:38 +00002374
Greg Clayton6071e6f2015-08-26 22:57:51 +00002375 if (!orig_die)
Greg Claytonaa044962011-10-13 00:59:38 +00002376 return false;
2377
Jim Ingham4cda6e02011-10-07 22:23:45 +00002378 // If we were passed a die that is not a function, just return false...
Greg Clayton6071e6f2015-08-26 22:57:51 +00002379 if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002380 return false;
Greg Clayton6071e6f2015-08-26 22:57:51 +00002381
2382 DWARFDIE die = orig_die;
2383 DWARFDIE inlined_die;
2384 if (die.Tag() == DW_TAG_inlined_subroutine)
Greg Clayton9e315582011-09-02 04:03:59 +00002385 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002386 inlined_die = die;
Greg Clayton9e315582011-09-02 04:03:59 +00002387
Greg Clayton6071e6f2015-08-26 22:57:51 +00002388 while (1)
Greg Clayton2bc22f82011-09-30 03:20:47 +00002389 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002390 die = die.GetParent();
2391
2392 if (die)
2393 {
2394 if (die.Tag() == DW_TAG_subprogram)
2395 break;
2396 }
2397 else
Jim Ingham4cda6e02011-10-07 22:23:45 +00002398 break;
Greg Clayton9e315582011-09-02 04:03:59 +00002399 }
2400 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00002401 assert (die && die.Tag() == DW_TAG_subprogram);
2402 if (GetFunction (die, sc))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002403 {
2404 Address addr;
2405 // Parse all blocks if needed
2406 if (inlined_die)
2407 {
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002408 Block &function_block = sc.function->GetBlock (true);
Greg Clayton6071e6f2015-08-26 22:57:51 +00002409 sc.block = function_block.FindBlockByID (inlined_die.GetID());
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002410 if (sc.block == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00002411 sc.block = function_block.FindBlockByID (inlined_die.GetOffset());
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002412 if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002413 addr.Clear();
2414 }
2415 else
2416 {
2417 sc.block = NULL;
2418 addr = sc.function->GetAddressRange().GetBaseAddress();
2419 }
2420
2421 if (addr.IsValid())
2422 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002423 sc_list.Append(sc);
Greg Claytonaa044962011-10-13 00:59:38 +00002424 return true;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002425 }
2426 }
2427
Greg Claytonaa044962011-10-13 00:59:38 +00002428 return false;
Greg Clayton9e315582011-09-02 04:03:59 +00002429}
2430
Greg Clayton7f995132011-10-04 22:41:51 +00002431void
2432SymbolFileDWARF::FindFunctions (const ConstString &name,
2433 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002434 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002435 SymbolContextList& sc_list)
2436{
Greg Claytond4a2b372011-09-12 23:21:58 +00002437 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002438 if (name_to_die.Find (name, die_offsets))
2439 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002440 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002441 }
2442}
2443
2444
2445void
2446SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2447 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002448 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002449 SymbolContextList& sc_list)
2450{
2451 DIEArray die_offsets;
2452 if (name_to_die.Find (regex, die_offsets))
2453 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002454 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002455 }
2456}
2457
2458
2459void
2460SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2461 const DWARFMappedHash::MemoryTable &memory_table,
Pavel Labatha73d6572015-03-13 10:22:00 +00002462 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002463 SymbolContextList& sc_list)
2464{
2465 DIEArray die_offsets;
Greg Claytond1767f02011-12-08 02:13:16 +00002466 DWARFMappedHash::DIEInfoArray hash_data_array;
2467 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
Greg Clayton7f995132011-10-04 22:41:51 +00002468 {
Greg Claytond1767f02011-12-08 02:13:16 +00002469 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
Pavel Labatha73d6572015-03-13 10:22:00 +00002470 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002471 }
2472}
2473
2474void
2475SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
Pavel Labatha73d6572015-03-13 10:22:00 +00002476 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002477 SymbolContextList& sc_list)
2478{
2479 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002480 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002481 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002482 for (size_t i=0; i<num_matches; ++i)
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002483 ResolveFunction (die_offsets[i], include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002484 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002485}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002486
Jim Ingham4cda6e02011-10-07 22:23:45 +00002487bool
Greg Clayton99558cc42015-08-24 23:46:31 +00002488SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx,
Greg Clayton6071e6f2015-08-26 22:57:51 +00002489 const DWARFDIE &die)
Greg Clayton99558cc42015-08-24 23:46:31 +00002490{
2491 // If we have no parent decl context to match this DIE matches, and if the parent
2492 // decl context isn't valid, we aren't trying to look for any particular decl
2493 // context so any die matches.
2494 if (decl_ctx == nullptr || !decl_ctx->IsValid())
2495 return true;
2496
Greg Clayton6071e6f2015-08-26 22:57:51 +00002497 if (die)
Greg Clayton99558cc42015-08-24 23:46:31 +00002498 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002499 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2500 if (dwarf_ast)
Greg Clayton99558cc42015-08-24 23:46:31 +00002501 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002502 CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00002503 if (actual_decl_ctx)
2504 return actual_decl_ctx == *decl_ctx;
2505 }
2506 }
2507 return false;
2508}
2509
Greg Clayton0c5cd902010-06-28 21:30:43 +00002510uint32_t
Greg Clayton99558cc42015-08-24 23:46:31 +00002511SymbolFileDWARF::FindFunctions (const ConstString &name,
2512 const CompilerDeclContext *parent_decl_ctx,
Sean Callanan9df05fb2012-02-10 22:52:19 +00002513 uint32_t name_type_mask,
2514 bool include_inlines,
Greg Clayton2bc22f82011-09-30 03:20:47 +00002515 bool append,
2516 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00002517{
2518 Timer scoped_timer (__PRETTY_FUNCTION__,
2519 "SymbolFileDWARF::FindFunctions (name = '%s')",
2520 name.AsCString());
2521
Greg Clayton43fe2172013-04-03 02:00:15 +00002522 // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
2523 assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
2524
Greg Clayton5160ce52013-03-27 23:08:40 +00002525 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002526
2527 if (log)
2528 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002529 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002530 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2531 name.GetCString(),
2532 name_type_mask,
2533 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00002534 }
2535
Greg Clayton0c5cd902010-06-28 21:30:43 +00002536 // If we aren't appending the results to this list, then clear the list
2537 if (!append)
2538 sc_list.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00002539
Greg Clayton99558cc42015-08-24 23:46:31 +00002540 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00002541 return 0;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002542
2543 // If name is empty then we won't find anything.
2544 if (name.IsEmpty())
2545 return 0;
Greg Clayton0c5cd902010-06-28 21:30:43 +00002546
2547 // Remember how many sc_list are in the list before we search in case
2548 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00002549
Jim Ingham4cda6e02011-10-07 22:23:45 +00002550 const char *name_cstr = name.GetCString();
Greg Clayton43fe2172013-04-03 02:00:15 +00002551
2552 const uint32_t original_size = sc_list.GetSize();
2553
Jim Ingham4cda6e02011-10-07 22:23:45 +00002554 DWARFDebugInfo* info = DebugInfo();
2555 if (info == NULL)
2556 return 0;
2557
Greg Clayton43fe2172013-04-03 02:00:15 +00002558 std::set<const DWARFDebugInfoEntry *> resolved_dies;
Greg Clayton97fbc342011-10-20 22:30:33 +00002559 if (m_using_apple_tables)
Greg Clayton4d01ace2011-09-29 16:58:15 +00002560 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002561 if (m_apple_names_ap.get())
Jim Ingham4cda6e02011-10-07 22:23:45 +00002562 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002563
2564 DIEArray die_offsets;
2565
2566 uint32_t num_matches = 0;
2567
Greg Clayton43fe2172013-04-03 02:00:15 +00002568 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonaa044962011-10-13 00:59:38 +00002569 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002570 // If they asked for the full name, match what they typed. At some point we may
2571 // want to canonicalize this (strip double spaces, etc. For now, we just add all the
2572 // dies that we find by exact match.
Jim Ingham4cda6e02011-10-07 22:23:45 +00002573 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002574 for (uint32_t i = 0; i < num_matches; i++)
2575 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002576 const DIERef& die_ref = die_offsets[i];
2577 DWARFDIE die = info->GetDIE (die_ref);
Greg Claytonaa044962011-10-13 00:59:38 +00002578 if (die)
2579 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002580 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002581 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002582
Greg Clayton6071e6f2015-08-26 22:57:51 +00002583 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002584 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002585 if (ResolveFunction (die, include_inlines, sc_list))
2586 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002587 }
Greg Claytonaa044962011-10-13 00:59:38 +00002588 }
Greg Clayton95d87902011-11-11 03:16:25 +00002589 else
2590 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002591 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002592 die_ref.die_offset, name_cstr);
Greg Clayton95d87902011-11-11 03:16:25 +00002593 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002594 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002595 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002596
2597 if (name_type_mask & eFunctionNameTypeSelector)
2598 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002599 if (parent_decl_ctx && parent_decl_ctx->IsValid())
Greg Clayton43fe2172013-04-03 02:00:15 +00002600 return 0; // no selectors in namespaces
Greg Clayton97fbc342011-10-20 22:30:33 +00002601
Greg Clayton43fe2172013-04-03 02:00:15 +00002602 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2603 // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
2604 // and if it is an ObjC method name, we're good.
Greg Clayton97fbc342011-10-20 22:30:33 +00002605
Greg Clayton43fe2172013-04-03 02:00:15 +00002606 for (uint32_t i = 0; i < num_matches; i++)
Greg Clayton97fbc342011-10-20 22:30:33 +00002607 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002608 const DIERef& die_ref = die_offsets[i];
2609 DWARFDIE die = info->GetDIE (die_ref);
Greg Clayton43fe2172013-04-03 02:00:15 +00002610 if (die)
Greg Clayton97fbc342011-10-20 22:30:33 +00002611 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002612 const char *die_name = die.GetName();
Jim Inghamaa816b82015-09-02 01:59:14 +00002613 if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
Greg Clayton97fbc342011-10-20 22:30:33 +00002614 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002615 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002616 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002617 if (ResolveFunction (die, include_inlines, sc_list))
2618 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002619 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002620 }
2621 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002622 else
2623 {
2624 GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002625 die_ref.die_offset, name_cstr);
Greg Clayton43fe2172013-04-03 02:00:15 +00002626 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002627 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002628 die_offsets.clear();
2629 }
2630
Greg Clayton99558cc42015-08-24 23:46:31 +00002631 if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase)
Greg Clayton43fe2172013-04-03 02:00:15 +00002632 {
2633 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
2634 // extract the base name, look that up, and if there is any other information in the name we were
2635 // passed in we have to post-filter based on that.
2636
2637 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
2638 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2639
2640 for (uint32_t i = 0; i < num_matches; i++)
2641 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002642 const DIERef& die_ref = die_offsets[i];
2643 DWARFDIE die = info->GetDIE (die_ref);
Greg Clayton43fe2172013-04-03 02:00:15 +00002644 if (die)
2645 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002646 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002647 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002648
Greg Clayton43fe2172013-04-03 02:00:15 +00002649
2650 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002651 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00002652 {
2653 bool keep_die = true;
2654 if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
2655 {
2656 // We are looking for either basenames or methods, so we need to
2657 // trim out the ones we won't want by looking at the type
2658 SymbolContext sc;
2659 if (sc_list.GetLastContext(sc))
2660 {
2661 if (sc.block)
2662 {
2663 // We have an inlined function
2664 }
2665 else if (sc.function)
2666 {
2667 Type *type = sc.function->GetType();
2668
Sean Callananc370a8a2013-09-18 22:59:55 +00002669 if (type)
Greg Clayton43fe2172013-04-03 02:00:15 +00002670 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002671 CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID());
2672 if (decl_ctx.IsStructUnionOrClass())
Greg Clayton43fe2172013-04-03 02:00:15 +00002673 {
Sean Callananc370a8a2013-09-18 22:59:55 +00002674 if (name_type_mask & eFunctionNameTypeBase)
2675 {
2676 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2677 keep_die = false;
2678 }
2679 }
2680 else
2681 {
2682 if (name_type_mask & eFunctionNameTypeMethod)
2683 {
2684 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2685 keep_die = false;
2686 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002687 }
2688 }
2689 else
2690 {
Sean Callananc370a8a2013-09-18 22:59:55 +00002691 GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002692 die_ref.die_offset);
Greg Clayton43fe2172013-04-03 02:00:15 +00002693 }
2694 }
2695 }
2696 }
2697 if (keep_die)
Greg Clayton6071e6f2015-08-26 22:57:51 +00002698 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002699 }
2700 }
2701 else
2702 {
2703 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002704 die_ref.die_offset, name_cstr);
Greg Clayton43fe2172013-04-03 02:00:15 +00002705 }
2706 }
2707 die_offsets.clear();
Jim Ingham4cda6e02011-10-07 22:23:45 +00002708 }
2709 }
Greg Clayton7f995132011-10-04 22:41:51 +00002710 }
2711 else
2712 {
2713
2714 // Index the DWARF if we haven't already
2715 if (!m_indexed)
2716 Index ();
2717
Greg Clayton7f995132011-10-04 22:41:51 +00002718 if (name_type_mask & eFunctionNameTypeFull)
Matt Kopecd6089962013-05-10 17:53:48 +00002719 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002720 FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002721
Ed Mastefc7baa02013-09-09 18:00:45 +00002722 // FIXME Temporary workaround for global/anonymous namespace
Robert Flack5cbd3bf2015-05-13 18:20:02 +00002723 // functions debugging FreeBSD and Linux binaries.
Matt Kopecd6089962013-05-10 17:53:48 +00002724 // If we didn't find any functions in the global namespace try
2725 // looking in the basename index but ignore any returned
Robert Flackeb83fab2015-05-15 18:59:59 +00002726 // functions that have a namespace but keep functions which
2727 // have an anonymous namespace
2728 // TODO: The arch in the object file isn't correct for MSVC
2729 // binaries on windows, we should find a way to make it
2730 // correct and handle those symbols as well.
Aidan Doddsc78e8992015-11-10 14:10:57 +00002731 if (sc_list.GetSize() == original_size)
Matt Kopecd6089962013-05-10 17:53:48 +00002732 {
Robert Flackeb83fab2015-05-15 18:59:59 +00002733 ArchSpec arch;
Greg Clayton99558cc42015-08-24 23:46:31 +00002734 if (!parent_decl_ctx &&
Robert Flackeb83fab2015-05-15 18:59:59 +00002735 GetObjectFile()->GetArchitecture(arch) &&
2736 (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
2737 arch.GetMachine() == llvm::Triple::hexagon))
Matt Kopecd6089962013-05-10 17:53:48 +00002738 {
Robert Flackeb83fab2015-05-15 18:59:59 +00002739 SymbolContextList temp_sc_list;
2740 FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
Matt Kopecd6089962013-05-10 17:53:48 +00002741 SymbolContext sc;
2742 for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
2743 {
2744 if (temp_sc_list.GetContextAtIndex(i, sc))
2745 {
Matt Kopeca189d492013-05-10 22:55:24 +00002746 ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
2747 ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
Robert Flackeb83fab2015-05-15 18:59:59 +00002748 // Mangled names on Linux and FreeBSD are of the form:
2749 // _ZN18function_namespace13function_nameEv.
Matt Kopec04e5d582013-05-14 19:00:41 +00002750 if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
2751 !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
Matt Kopecd6089962013-05-10 17:53:48 +00002752 {
2753 sc_list.Append(sc);
2754 }
2755 }
2756 }
2757 }
2758 }
Matt Kopecd6089962013-05-10 17:53:48 +00002759 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002760 DIEArray die_offsets;
Greg Clayton43fe2172013-04-03 02:00:15 +00002761 if (name_type_mask & eFunctionNameTypeBase)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002762 {
Greg Clayton43fe2172013-04-03 02:00:15 +00002763 uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
Greg Claytonaa044962011-10-13 00:59:38 +00002764 for (uint32_t i = 0; i < num_base; i++)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002765 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002766 DWARFDIE die = info->GetDIE (die_offsets[i]);
Greg Claytonaa044962011-10-13 00:59:38 +00002767 if (die)
2768 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002769 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002770 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002771
Greg Claytonaa044962011-10-13 00:59:38 +00002772 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002773 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002774 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002775 if (ResolveFunction (die, include_inlines, sc_list))
2776 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002777 }
Greg Claytonaa044962011-10-13 00:59:38 +00002778 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002779 }
2780 die_offsets.clear();
2781 }
2782
Greg Clayton43fe2172013-04-03 02:00:15 +00002783 if (name_type_mask & eFunctionNameTypeMethod)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002784 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002785 if (parent_decl_ctx && parent_decl_ctx->IsValid())
Sean Callanan213fdb82011-10-13 01:49:10 +00002786 return 0; // no methods in namespaces
2787
Greg Clayton43fe2172013-04-03 02:00:15 +00002788 uint32_t num_base = m_function_method_index.Find(name, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002789 {
Greg Claytonaa044962011-10-13 00:59:38 +00002790 for (uint32_t i = 0; i < num_base; i++)
2791 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002792 DWARFDIE die = info->GetDIE (die_offsets[i]);
Greg Claytonaa044962011-10-13 00:59:38 +00002793 if (die)
2794 {
Greg Claytonaa044962011-10-13 00:59:38 +00002795 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002796 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002797 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002798 if (ResolveFunction (die, include_inlines, sc_list))
2799 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002800 }
Greg Claytonaa044962011-10-13 00:59:38 +00002801 }
2802 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002803 }
2804 die_offsets.clear();
2805 }
Greg Clayton7f995132011-10-04 22:41:51 +00002806
Greg Clayton99558cc42015-08-24 23:46:31 +00002807 if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid()))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002808 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002809 FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002810 }
2811
Greg Clayton4d01ace2011-09-29 16:58:15 +00002812 }
2813
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002814 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00002815 const uint32_t num_matches = sc_list.GetSize() - original_size;
2816
2817 if (log && num_matches > 0)
2818 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002819 GetObjectFile()->GetModule()->LogMessage (log,
Pavel Labatha73d6572015-03-13 10:22:00 +00002820 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00002821 name.GetCString(),
2822 name_type_mask,
Pavel Labatha73d6572015-03-13 10:22:00 +00002823 include_inlines,
Greg Clayton437a1352012-04-09 22:43:43 +00002824 append,
2825 num_matches);
2826 }
2827 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002828}
2829
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002830uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +00002831SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002832{
2833 Timer scoped_timer (__PRETTY_FUNCTION__,
2834 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2835 regex.GetText());
2836
Greg Clayton5160ce52013-03-27 23:08:40 +00002837 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002838
2839 if (log)
2840 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002841 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002842 "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
2843 regex.GetText(),
2844 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00002845 }
2846
2847
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002848 // If we aren't appending the results to this list, then clear the list
2849 if (!append)
2850 sc_list.Clear();
2851
2852 // Remember how many sc_list are in the list before we search in case
2853 // we are appending the results to a variable list.
2854 uint32_t original_size = sc_list.GetSize();
2855
Greg Clayton97fbc342011-10-20 22:30:33 +00002856 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002857 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002858 if (m_apple_names_ap.get())
Pavel Labatha73d6572015-03-13 10:22:00 +00002859 FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002860 }
2861 else
2862 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002863 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00002864 if (!m_indexed)
2865 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002866
Pavel Labatha73d6572015-03-13 10:22:00 +00002867 FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002868
Pavel Labatha73d6572015-03-13 10:22:00 +00002869 FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002870 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002871
2872 // Return the number of variable that were appended to the list
2873 return sc_list.GetSize() - original_size;
2874}
Jim Ingham318c9f22011-08-26 19:44:13 +00002875
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002876uint32_t
Greg Claytond1767f02011-12-08 02:13:16 +00002877SymbolFileDWARF::FindTypes (const SymbolContext& sc,
2878 const ConstString &name,
Greg Clayton99558cc42015-08-24 23:46:31 +00002879 const CompilerDeclContext *parent_decl_ctx,
Greg Claytond1767f02011-12-08 02:13:16 +00002880 bool append,
2881 uint32_t max_matches,
Ravitheja Addepally40697302015-10-08 09:45:41 +00002882 TypeMap& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002883{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002884 DWARFDebugInfo* info = DebugInfo();
2885 if (info == NULL)
2886 return 0;
2887
Greg Clayton5160ce52013-03-27 23:08:40 +00002888 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002889
Greg Clayton21f2a492011-10-06 00:09:08 +00002890 if (log)
2891 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002892 if (parent_decl_ctx)
Greg Clayton5160ce52013-03-27 23:08:40 +00002893 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002894 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)",
Greg Clayton437a1352012-04-09 22:43:43 +00002895 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002896 static_cast<const void*>(parent_decl_ctx),
2897 parent_decl_ctx->GetName().AsCString("<NULL>"),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002898 append, max_matches);
Greg Clayton437a1352012-04-09 22:43:43 +00002899 else
Greg Clayton5160ce52013-03-27 23:08:40 +00002900 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002901 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002902 name.GetCString(), append,
Greg Clayton437a1352012-04-09 22:43:43 +00002903 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00002904 }
2905
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002906 // If we aren't appending the results to this list, then clear the list
2907 if (!append)
2908 types.Clear();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002909
Greg Clayton99558cc42015-08-24 23:46:31 +00002910 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00002911 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002912
Greg Claytond4a2b372011-09-12 23:21:58 +00002913 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002914
Greg Clayton97fbc342011-10-20 22:30:33 +00002915 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002916 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002917 if (m_apple_types_ap.get())
2918 {
2919 const char *name_cstr = name.GetCString();
2920 m_apple_types_ap->FindByName (name_cstr, die_offsets);
2921 }
Greg Clayton7f995132011-10-04 22:41:51 +00002922 }
2923 else
2924 {
2925 if (!m_indexed)
2926 Index ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002927
Greg Clayton7f995132011-10-04 22:41:51 +00002928 m_type_index.Find (name, die_offsets);
2929 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002930
Greg Clayton437a1352012-04-09 22:43:43 +00002931 const size_t num_die_matches = die_offsets.size();
Greg Clayton7f995132011-10-04 22:41:51 +00002932
Greg Clayton437a1352012-04-09 22:43:43 +00002933 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002934 {
Greg Clayton7f995132011-10-04 22:41:51 +00002935 const uint32_t initial_types_size = types.GetSize();
Greg Claytond4a2b372011-09-12 23:21:58 +00002936 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton437a1352012-04-09 22:43:43 +00002937 for (size_t i=0; i<num_die_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002938 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002939 const DIERef& die_ref = die_offsets[i];
2940 DWARFDIE die = debug_info->GetDIE (die_ref);
Greg Claytond4a2b372011-09-12 23:21:58 +00002941
Greg Clayton95d87902011-11-11 03:16:25 +00002942 if (die)
Greg Clayton73bf5db2011-06-17 01:22:15 +00002943 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002944 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002945 continue; // The containing decl contexts don't match
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002946
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00002947 Type *matching_type = ResolveType (die, true, true);
Greg Clayton95d87902011-11-11 03:16:25 +00002948 if (matching_type)
2949 {
2950 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone1cd1be2012-01-29 20:56:30 +00002951 types.InsertUnique (matching_type->shared_from_this());
Greg Clayton95d87902011-11-11 03:16:25 +00002952 if (types.GetSize() >= max_matches)
2953 break;
2954 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00002955 }
Greg Clayton95d87902011-11-11 03:16:25 +00002956 else
2957 {
2958 if (m_using_apple_tables)
2959 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002960 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002961 die_ref.die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00002962 }
2963 }
2964
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002965 }
Greg Clayton437a1352012-04-09 22:43:43 +00002966 const uint32_t num_matches = types.GetSize() - initial_types_size;
2967 if (log && num_matches)
2968 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002969 if (parent_decl_ctx)
Greg Clayton437a1352012-04-09 22:43:43 +00002970 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002971 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002972 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00002973 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002974 static_cast<const void*>(parent_decl_ctx),
2975 parent_decl_ctx->GetName().AsCString("<NULL>"),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002976 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00002977 num_matches);
2978 }
2979 else
2980 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002981 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002982 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00002983 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002984 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00002985 num_matches);
2986 }
2987 }
2988 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002989 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00002990 else
2991 {
2992 UpdateExternalModuleListIfNeeded();
2993
2994 for (const auto &pair : m_external_type_modules)
2995 {
2996 ModuleSP external_module_sp = pair.second;
2997 if (external_module_sp)
2998 {
2999 SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
3000 if (sym_vendor)
3001 {
3002 const uint32_t num_external_matches = sym_vendor->FindTypes (sc,
3003 name,
3004 parent_decl_ctx,
3005 append,
3006 max_matches,
3007 types);
3008 if (num_external_matches)
3009 return num_external_matches;
3010 }
3011 }
3012 }
3013 }
3014
3015 return 0;
3016}
3017
3018
3019size_t
3020SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
3021 bool append,
3022 TypeMap& types)
3023{
3024 if (!append)
3025 types.Clear();
3026
3027 if (context.empty())
3028 return 0;
3029
3030 DIEArray die_offsets;
3031
3032 ConstString name = context.back().name;
3033
3034 if (m_using_apple_tables)
3035 {
3036 if (m_apple_types_ap.get())
3037 {
3038 const char *name_cstr = name.GetCString();
3039 m_apple_types_ap->FindByName (name_cstr, die_offsets);
3040 }
3041 }
3042 else
3043 {
3044 if (!m_indexed)
3045 Index ();
3046
3047 m_type_index.Find (name, die_offsets);
3048 }
3049
3050 const size_t num_die_matches = die_offsets.size();
3051
3052 if (num_die_matches)
3053 {
3054 size_t num_matches = 0;
3055 DWARFDebugInfo* debug_info = DebugInfo();
3056 for (size_t i=0; i<num_die_matches; ++i)
3057 {
3058 const DIERef& die_ref = die_offsets[i];
3059 DWARFDIE die = debug_info->GetDIE (die_ref);
3060
3061 if (die)
3062 {
3063 std::vector<CompilerContext> die_context;
3064 die.GetDWOContext(die_context);
3065 if (die_context != context)
3066 continue;
3067
3068 Type *matching_type = ResolveType (die, true, true);
3069 if (matching_type)
3070 {
3071 // We found a type pointer, now find the shared pointer form our type list
3072 types.InsertUnique (matching_type->shared_from_this());
3073 ++num_matches;
3074 }
3075 }
3076 else
3077 {
3078 if (m_using_apple_tables)
3079 {
3080 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3081 die_ref.die_offset, name.GetCString());
3082 }
3083 }
3084
3085 }
3086 return num_matches;
3087 }
Greg Clayton7f995132011-10-04 22:41:51 +00003088 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003089}
3090
3091
Greg Clayton99558cc42015-08-24 23:46:31 +00003092CompilerDeclContext
Greg Clayton96d7d742010-11-10 23:42:09 +00003093SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00003094 const ConstString &name,
Greg Clayton99558cc42015-08-24 23:46:31 +00003095 const CompilerDeclContext *parent_decl_ctx)
Greg Clayton96d7d742010-11-10 23:42:09 +00003096{
Greg Clayton5160ce52013-03-27 23:08:40 +00003097 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00003098
3099 if (log)
3100 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003101 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003102 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
3103 name.GetCString());
Greg Clayton21f2a492011-10-06 00:09:08 +00003104 }
3105
Greg Clayton99558cc42015-08-24 23:46:31 +00003106 CompilerDeclContext namespace_decl_ctx;
3107
3108 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
3109 return namespace_decl_ctx;
3110
3111
Greg Clayton96d7d742010-11-10 23:42:09 +00003112 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00003113 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00003114 {
Greg Clayton7f995132011-10-04 22:41:51 +00003115 DIEArray die_offsets;
3116
Greg Clayton526e5af2010-11-13 03:52:47 +00003117 // Index if we already haven't to make sure the compile units
3118 // get indexed and make their global DIE index list
Greg Clayton97fbc342011-10-20 22:30:33 +00003119 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003120 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003121 if (m_apple_namespaces_ap.get())
3122 {
3123 const char *name_cstr = name.GetCString();
3124 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
3125 }
Greg Clayton7f995132011-10-04 22:41:51 +00003126 }
3127 else
3128 {
3129 if (!m_indexed)
3130 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00003131
Greg Clayton7f995132011-10-04 22:41:51 +00003132 m_namespace_index.Find (name, die_offsets);
3133 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003134
Greg Clayton7f995132011-10-04 22:41:51 +00003135 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003136 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00003137 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003138 DWARFDebugInfo* debug_info = DebugInfo();
3139 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00003140 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003141 const DIERef& die_ref = die_offsets[i];
3142 DWARFDIE die = debug_info->GetDIE (die_ref);
Greg Clayton6071e6f2015-08-26 22:57:51 +00003143
Greg Clayton95d87902011-11-11 03:16:25 +00003144 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00003145 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003146 if (!DIEInDeclContext (parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00003147 continue; // The containing decl contexts don't match
Greg Clayton95d87902011-11-11 03:16:25 +00003148
Greg Clayton261ac3f2015-08-28 01:01:03 +00003149 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
3150 if (dwarf_ast)
Greg Clayton8b4edba2015-08-14 20:02:05 +00003151 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00003152 namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00003153 if (namespace_decl_ctx)
Greg Clayton8b4edba2015-08-14 20:02:05 +00003154 break;
Greg Clayton95d87902011-11-11 03:16:25 +00003155 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003156 }
Greg Clayton95d87902011-11-11 03:16:25 +00003157 else
3158 {
3159 if (m_using_apple_tables)
3160 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003161 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003162 die_ref.die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00003163 }
3164 }
3165
Greg Clayton526e5af2010-11-13 03:52:47 +00003166 }
3167 }
Greg Clayton96d7d742010-11-10 23:42:09 +00003168 }
Greg Clayton99558cc42015-08-24 23:46:31 +00003169 if (log && namespace_decl_ctx)
Greg Clayton437a1352012-04-09 22:43:43 +00003170 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003171 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00003172 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"",
Greg Clayton437a1352012-04-09 22:43:43 +00003173 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00003174 static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()),
3175 static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()),
3176 namespace_decl_ctx.GetName().AsCString("<NULL>"));
Greg Clayton437a1352012-04-09 22:43:43 +00003177 }
3178
Greg Clayton99558cc42015-08-24 23:46:31 +00003179 return namespace_decl_ctx;
Greg Clayton96d7d742010-11-10 23:42:09 +00003180}
3181
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003182TypeSP
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00003183SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003184{
3185 TypeSP type_sp;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003186 if (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003187 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003188 Type *type_ptr = GetDIEToType().lookup (die.GetDIE());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003189 if (type_ptr == NULL)
3190 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003191 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
Greg Claytonca512b32011-01-14 04:54:56 +00003192 assert (lldb_cu);
3193 SymbolContext sc(lldb_cu);
Ravitheja Addepally40697302015-10-08 09:45:41 +00003194 const DWARFDebugInfoEntry* parent_die = die.GetParent().GetDIE();
3195 while (parent_die != nullptr)
3196 {
3197 if (parent_die->Tag() == DW_TAG_subprogram)
3198 break;
3199 parent_die = parent_die->GetParent();
3200 }
3201 SymbolContext sc_backup = sc;
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00003202 if (resolve_function_context && parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc))
Ravitheja Addepally40697302015-10-08 09:45:41 +00003203 sc = sc_backup;
3204
Greg Clayton6071e6f2015-08-26 22:57:51 +00003205 type_sp = ParseType(sc, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003206 }
3207 else if (type_ptr != DIE_IS_BEING_PARSED)
3208 {
3209 // Grab the existing type from the master types lists
Greg Claytone1cd1be2012-01-29 20:56:30 +00003210 type_sp = type_ptr->shared_from_this();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003211 }
3212
3213 }
3214 return type_sp;
3215}
3216
Greg Clayton2bc22f82011-09-30 03:20:47 +00003217
Greg Clayton6071e6f2015-08-26 22:57:51 +00003218DWARFDIE
3219SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003220{
Greg Clayton6071e6f2015-08-26 22:57:51 +00003221 if (orig_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003222 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003223 DWARFDIE die = orig_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003224
Greg Clayton6071e6f2015-08-26 22:57:51 +00003225 while (die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003226 {
3227 // If this is the original DIE that we are searching for a declaration
3228 // for, then don't look in the cache as we don't want our own decl
3229 // context to be our decl context...
Greg Clayton6071e6f2015-08-26 22:57:51 +00003230 if (orig_die != die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003231 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003232 switch (die.Tag())
Greg Clayton2bc22f82011-09-30 03:20:47 +00003233 {
3234 case DW_TAG_compile_unit:
3235 case DW_TAG_namespace:
3236 case DW_TAG_structure_type:
3237 case DW_TAG_union_type:
3238 case DW_TAG_class_type:
Paul Hermand628cbb2015-09-15 23:44:17 +00003239 case DW_TAG_lexical_block:
3240 case DW_TAG_subprogram:
Greg Clayton2bc22f82011-09-30 03:20:47 +00003241 return die;
3242
3243 default:
3244 break;
3245 }
3246 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003247
3248 DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
3249 if (spec_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003250 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003251 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
3252 if (decl_ctx_die)
3253 return decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003254 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003255
3256 DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
3257 if (abs_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003258 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003259 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
3260 if (decl_ctx_die)
3261 return decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003262 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003263
3264 die = die.GetParent();
Greg Clayton2bc22f82011-09-30 03:20:47 +00003265 }
3266 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003267 return DWARFDIE();
Greg Clayton2bc22f82011-09-30 03:20:47 +00003268}
3269
3270
Greg Clayton901c5ca2011-12-03 04:40:03 +00003271Symbol *
3272SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
3273{
3274 Symbol *objc_class_symbol = NULL;
3275 if (m_obj_file)
3276 {
Greg Clayton3046e662013-07-10 01:23:25 +00003277 Symtab *symtab = m_obj_file->GetSymtab ();
Greg Clayton901c5ca2011-12-03 04:40:03 +00003278 if (symtab)
3279 {
3280 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
3281 eSymbolTypeObjCClass,
3282 Symtab::eDebugNo,
3283 Symtab::eVisibilityAny);
3284 }
3285 }
3286 return objc_class_symbol;
3287}
3288
Greg Claytonc7f03b62012-01-12 04:33:28 +00003289// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
3290// then we can end up looking through all class types for a complete type and never find
3291// the full definition. We need to know if this attribute is supported, so we determine
3292// this here and cache th result. We also need to worry about the debug map DWARF file
3293// if we are doing darwin DWARF in .o file debugging.
3294bool
3295SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
3296{
3297 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
3298 {
3299 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
3300 if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
3301 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3302 else
3303 {
3304 DWARFDebugInfo* debug_info = DebugInfo();
3305 const uint32_t num_compile_units = GetNumCompileUnits();
3306 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
3307 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003308 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
3309 if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
Greg Claytonc7f03b62012-01-12 04:33:28 +00003310 {
3311 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3312 break;
3313 }
3314 }
3315 }
Greg Clayton1f746072012-08-29 21:13:06 +00003316 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
Greg Claytonc7f03b62012-01-12 04:33:28 +00003317 return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
3318 }
3319 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
3320}
Greg Clayton901c5ca2011-12-03 04:40:03 +00003321
3322// This function can be used when a DIE is found that is a forward declaration
3323// DIE and we want to try and find a type that has the complete definition.
3324TypeSP
Greg Clayton6071e6f2015-08-26 22:57:51 +00003325SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
Greg Claytonc7f03b62012-01-12 04:33:28 +00003326 const ConstString &type_name,
3327 bool must_be_implementation)
Greg Clayton901c5ca2011-12-03 04:40:03 +00003328{
3329
3330 TypeSP type_sp;
3331
Greg Claytonc7f03b62012-01-12 04:33:28 +00003332 if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
Greg Clayton901c5ca2011-12-03 04:40:03 +00003333 return type_sp;
3334
3335 DIEArray die_offsets;
3336
3337 if (m_using_apple_tables)
3338 {
3339 if (m_apple_types_ap.get())
3340 {
3341 const char *name_cstr = type_name.GetCString();
Greg Clayton68221ec2012-01-18 20:58:12 +00003342 m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003343 }
3344 }
3345 else
3346 {
3347 if (!m_indexed)
3348 Index ();
3349
3350 m_type_index.Find (type_name, die_offsets);
3351 }
3352
Greg Clayton901c5ca2011-12-03 04:40:03 +00003353 const size_t num_matches = die_offsets.size();
3354
Greg Clayton901c5ca2011-12-03 04:40:03 +00003355 if (num_matches)
3356 {
3357 DWARFDebugInfo* debug_info = DebugInfo();
3358 for (size_t i=0; i<num_matches; ++i)
3359 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003360 const DIERef& die_ref = die_offsets[i];
3361 DWARFDIE type_die = debug_info->GetDIE (die_ref);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003362
3363 if (type_die)
3364 {
3365 bool try_resolving_type = false;
3366
3367 // Don't try and resolve the DIE we are looking for with the DIE itself!
3368 if (type_die != die)
3369 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003370 switch (type_die.Tag())
Greg Clayton901c5ca2011-12-03 04:40:03 +00003371 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00003372 case DW_TAG_class_type:
3373 case DW_TAG_structure_type:
3374 try_resolving_type = true;
3375 break;
3376 default:
3377 break;
Greg Clayton901c5ca2011-12-03 04:40:03 +00003378 }
3379 }
3380
3381 if (try_resolving_type)
3382 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003383 if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type())
3384 try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003385
3386 if (try_resolving_type)
3387 {
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00003388 Type *resolved_type = ResolveType (type_die, false, true);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003389 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3390 {
Ed Mastea0191d12013-10-17 20:42:56 +00003391 DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
Greg Clayton6071e6f2015-08-26 22:57:51 +00003392 die.GetID(),
Jim Ingham4af59612014-12-19 19:20:44 +00003393 m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003394 type_die.GetID(),
3395 type_cu->GetID());
Greg Clayton901c5ca2011-12-03 04:40:03 +00003396
Greg Claytonc7f03b62012-01-12 04:33:28 +00003397 if (die)
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003398 GetDIEToType()[die.GetDIE()] = resolved_type;
Greg Claytone1cd1be2012-01-29 20:56:30 +00003399 type_sp = resolved_type->shared_from_this();
Greg Clayton901c5ca2011-12-03 04:40:03 +00003400 break;
3401 }
3402 }
3403 }
3404 }
3405 else
3406 {
3407 if (m_using_apple_tables)
3408 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003409 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003410 die_ref.die_offset, type_name.GetCString());
Greg Clayton901c5ca2011-12-03 04:40:03 +00003411 }
3412 }
3413
3414 }
3415 }
3416 return type_sp;
3417}
3418
Greg Claytona8022fa2012-04-24 21:22:41 +00003419
Greg Clayton80c26302012-02-05 06:12:47 +00003420//----------------------------------------------------------------------
3421// This function helps to ensure that the declaration contexts match for
3422// two different DIEs. Often times debug information will refer to a
3423// forward declaration of a type (the equivalent of "struct my_struct;".
3424// There will often be a declaration of that type elsewhere that has the
3425// full definition. When we go looking for the full type "my_struct", we
3426// will find one or more matches in the accelerator tables and we will
3427// then need to make sure the type was in the same declaration context
3428// as the original DIE. This function can efficiently compare two DIEs
3429// and will return true when the declaration context matches, and false
3430// when they don't.
3431//----------------------------------------------------------------------
Greg Clayton890ff562012-02-02 05:48:16 +00003432bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00003433SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1,
3434 const DWARFDIE &die2)
Greg Clayton890ff562012-02-02 05:48:16 +00003435{
Greg Claytona8022fa2012-04-24 21:22:41 +00003436 if (die1 == die2)
3437 return true;
3438
Greg Clayton890ff562012-02-02 05:48:16 +00003439 DWARFDIECollection decl_ctx_1;
3440 DWARFDIECollection decl_ctx_2;
Greg Clayton80c26302012-02-05 06:12:47 +00003441 //The declaration DIE stack is a stack of the declaration context
3442 // DIEs all the way back to the compile unit. If a type "T" is
3443 // declared inside a class "B", and class "B" is declared inside
3444 // a class "A" and class "A" is in a namespace "lldb", and the
3445 // namespace is in a compile unit, there will be a stack of DIEs:
3446 //
3447 // [0] DW_TAG_class_type for "B"
3448 // [1] DW_TAG_class_type for "A"
3449 // [2] DW_TAG_namespace for "lldb"
3450 // [3] DW_TAG_compile_unit for the source file.
3451 //
3452 // We grab both contexts and make sure that everything matches
3453 // all the way back to the compiler unit.
3454
3455 // First lets grab the decl contexts for both DIEs
Greg Clayton6071e6f2015-08-26 22:57:51 +00003456 die1.GetDeclContextDIEs (decl_ctx_1);
3457 die2.GetDeclContextDIEs (decl_ctx_2);
Greg Clayton80c26302012-02-05 06:12:47 +00003458 // Make sure the context arrays have the same size, otherwise
3459 // we are done
Greg Clayton890ff562012-02-02 05:48:16 +00003460 const size_t count1 = decl_ctx_1.Size();
3461 const size_t count2 = decl_ctx_2.Size();
3462 if (count1 != count2)
3463 return false;
Greg Clayton80c26302012-02-05 06:12:47 +00003464
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003465 // Make sure the DW_TAG values match all the way back up the
Greg Clayton80c26302012-02-05 06:12:47 +00003466 // compile unit. If they don't, then we are done.
Greg Clayton6071e6f2015-08-26 22:57:51 +00003467 DWARFDIE decl_ctx_die1;
3468 DWARFDIE decl_ctx_die2;
Greg Clayton890ff562012-02-02 05:48:16 +00003469 size_t i;
3470 for (i=0; i<count1; i++)
3471 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003472 decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3473 decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3474 if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
Greg Clayton890ff562012-02-02 05:48:16 +00003475 return false;
3476 }
Greg Clayton890ff562012-02-02 05:48:16 +00003477#if defined LLDB_CONFIGURATION_DEBUG
Greg Clayton80c26302012-02-05 06:12:47 +00003478
3479 // Make sure the top item in the decl context die array is always
3480 // DW_TAG_compile_unit. If it isn't then something went wrong in
Greg Clayton5ce1a842015-08-27 18:09:44 +00003481 // the DWARFDIE::GetDeclContextDIEs() function...
Greg Clayton6071e6f2015-08-26 22:57:51 +00003482 assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit);
Greg Clayton80c26302012-02-05 06:12:47 +00003483
Greg Clayton890ff562012-02-02 05:48:16 +00003484#endif
3485 // Always skip the compile unit when comparing by only iterating up to
Greg Clayton80c26302012-02-05 06:12:47 +00003486 // "count - 1". Here we compare the names as we go.
Greg Clayton890ff562012-02-02 05:48:16 +00003487 for (i=0; i<count1 - 1; i++)
3488 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003489 decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3490 decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3491 const char *name1 = decl_ctx_die1.GetName();
3492 const char *name2 = decl_ctx_die2.GetName();
Greg Clayton890ff562012-02-02 05:48:16 +00003493 // If the string was from a DW_FORM_strp, then the pointer will often
3494 // be the same!
Greg Clayton5569e642012-02-06 01:44:54 +00003495 if (name1 == name2)
3496 continue;
3497
3498 // Name pointers are not equal, so only compare the strings
3499 // if both are not NULL.
3500 if (name1 && name2)
Greg Clayton890ff562012-02-02 05:48:16 +00003501 {
Greg Clayton5569e642012-02-06 01:44:54 +00003502 // If the strings don't compare, we are done...
3503 if (strcmp(name1, name2) != 0)
Greg Clayton890ff562012-02-02 05:48:16 +00003504 return false;
Greg Clayton5569e642012-02-06 01:44:54 +00003505 }
3506 else
3507 {
3508 // One name was NULL while the other wasn't
3509 return false;
Greg Clayton890ff562012-02-02 05:48:16 +00003510 }
3511 }
Greg Clayton80c26302012-02-05 06:12:47 +00003512 // We made it through all of the checks and the declaration contexts
3513 // are equal.
Greg Clayton890ff562012-02-02 05:48:16 +00003514 return true;
3515}
Greg Clayton220a0072011-12-09 08:48:30 +00003516
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003517
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003518TypeSP
Greg Claytona8022fa2012-04-24 21:22:41 +00003519SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
3520{
3521 TypeSP type_sp;
3522
3523 const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
3524 if (dwarf_decl_ctx_count > 0)
3525 {
3526 const ConstString type_name(dwarf_decl_ctx[0].name);
3527 const dw_tag_t tag = dwarf_decl_ctx[0].tag;
3528
3529 if (type_name)
3530 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003531 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
Greg Claytona8022fa2012-04-24 21:22:41 +00003532 if (log)
3533 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003534 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003535 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
3536 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3537 dwarf_decl_ctx.GetQualifiedName());
3538 }
3539
3540 DIEArray die_offsets;
3541
3542 if (m_using_apple_tables)
3543 {
3544 if (m_apple_types_ap.get())
3545 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003546 const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
3547 const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
3548 if (has_tag && has_qualified_name_hash)
Greg Claytona8022fa2012-04-24 21:22:41 +00003549 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003550 const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
3551 const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
3552 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003553 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003554 m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
3555 }
3556 else if (has_tag)
3557 {
3558 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003559 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
Greg Claytona8022fa2012-04-24 21:22:41 +00003560 m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
3561 }
3562 else
3563 {
3564 m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
3565 }
3566 }
3567 }
3568 else
3569 {
3570 if (!m_indexed)
3571 Index ();
3572
3573 m_type_index.Find (type_name, die_offsets);
3574 }
3575
3576 const size_t num_matches = die_offsets.size();
3577
3578
Greg Claytona8022fa2012-04-24 21:22:41 +00003579 if (num_matches)
3580 {
3581 DWARFDebugInfo* debug_info = DebugInfo();
3582 for (size_t i=0; i<num_matches; ++i)
3583 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003584 const DIERef& die_ref = die_offsets[i];
3585 DWARFDIE type_die = debug_info->GetDIE (die_ref);
Greg Claytona8022fa2012-04-24 21:22:41 +00003586
3587 if (type_die)
3588 {
3589 bool try_resolving_type = false;
3590
3591 // Don't try and resolve the DIE we are looking for with the DIE itself!
Greg Clayton6071e6f2015-08-26 22:57:51 +00003592 const dw_tag_t type_tag = type_die.Tag();
Greg Claytona8022fa2012-04-24 21:22:41 +00003593 // Make sure the tags match
3594 if (type_tag == tag)
3595 {
3596 // The tags match, lets try resolving this type
3597 try_resolving_type = true;
3598 }
3599 else
3600 {
3601 // The tags don't match, but we need to watch our for a
3602 // forward declaration for a struct and ("struct foo")
3603 // ends up being a class ("class foo { ... };") or
3604 // vice versa.
3605 switch (type_tag)
3606 {
3607 case DW_TAG_class_type:
3608 // We had a "class foo", see if we ended up with a "struct foo { ... };"
3609 try_resolving_type = (tag == DW_TAG_structure_type);
3610 break;
3611 case DW_TAG_structure_type:
3612 // We had a "struct foo", see if we ended up with a "class foo { ... };"
3613 try_resolving_type = (tag == DW_TAG_class_type);
3614 break;
3615 default:
3616 // Tags don't match, don't event try to resolve
3617 // using this type whose name matches....
3618 break;
3619 }
3620 }
3621
3622 if (try_resolving_type)
3623 {
3624 DWARFDeclContext type_dwarf_decl_ctx;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003625 type_die.GetDWARFDeclContext (type_dwarf_decl_ctx);
Greg Claytona8022fa2012-04-24 21:22:41 +00003626
3627 if (log)
3628 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003629 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003630 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
3631 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3632 dwarf_decl_ctx.GetQualifiedName(),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003633 type_die.GetOffset(),
Greg Claytona8022fa2012-04-24 21:22:41 +00003634 type_dwarf_decl_ctx.GetQualifiedName());
3635 }
3636
3637 // Make sure the decl contexts match all the way up
3638 if (dwarf_decl_ctx == type_dwarf_decl_ctx)
3639 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003640 Type *resolved_type = ResolveType (type_die, false);
Greg Claytona8022fa2012-04-24 21:22:41 +00003641 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3642 {
3643 type_sp = resolved_type->shared_from_this();
3644 break;
3645 }
3646 }
3647 }
3648 else
3649 {
3650 if (log)
3651 {
3652 std::string qualified_name;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003653 type_die.GetQualifiedName(qualified_name);
Greg Clayton5160ce52013-03-27 23:08:40 +00003654 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003655 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
3656 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3657 dwarf_decl_ctx.GetQualifiedName(),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003658 type_die.GetOffset(),
Greg Claytona8022fa2012-04-24 21:22:41 +00003659 qualified_name.c_str());
3660 }
3661 }
3662 }
3663 else
3664 {
3665 if (m_using_apple_tables)
3666 {
3667 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003668 die_ref.die_offset, type_name.GetCString());
Greg Claytona8022fa2012-04-24 21:22:41 +00003669 }
3670 }
3671
3672 }
3673 }
3674 }
3675 }
3676 return type_sp;
3677}
3678
Greg Claytona8022fa2012-04-24 21:22:41 +00003679TypeSP
Greg Clayton6071e6f2015-08-26 22:57:51 +00003680SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003681{
Greg Clayton196e8cd2015-08-17 20:31:46 +00003682 TypeSP type_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003683
Greg Clayton6071e6f2015-08-26 22:57:51 +00003684 if (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003685 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003686 TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
3687
3688 if (type_system)
Greg Clayton196e8cd2015-08-17 20:31:46 +00003689 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00003690 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
3691 if (dwarf_ast)
Greg Clayton6071e6f2015-08-26 22:57:51 +00003692 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00003693 Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
3694 type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr);
3695 if (type_sp)
3696 {
3697 TypeList* type_list = GetTypeList();
3698 if (type_list)
3699 type_list->Insert(type_sp);
3700 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003701 }
Greg Clayton196e8cd2015-08-17 20:31:46 +00003702 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003703 }
Greg Clayton196e8cd2015-08-17 20:31:46 +00003704
3705 return type_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003706}
3707
3708size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003709SymbolFileDWARF::ParseTypes
3710(
3711 const SymbolContext& sc,
Greg Clayton6071e6f2015-08-26 22:57:51 +00003712 const DWARFDIE &orig_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003713 bool parse_siblings,
3714 bool parse_children
3715)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003716{
3717 size_t types_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003718 DWARFDIE die = orig_die;
3719 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003720 {
3721 bool type_is_new = false;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003722 if (ParseType(sc, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003723 {
3724 if (type_is_new)
3725 ++types_added;
3726 }
3727
Greg Clayton6071e6f2015-08-26 22:57:51 +00003728 if (parse_children && die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003729 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003730 if (die.Tag() == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003731 {
3732 SymbolContext child_sc(sc);
Greg Clayton6071e6f2015-08-26 22:57:51 +00003733 child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
3734 types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003735 }
3736 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00003737 types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003738 }
3739
3740 if (parse_siblings)
Greg Clayton6071e6f2015-08-26 22:57:51 +00003741 die = die.GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003742 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00003743 die.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003744 }
3745 return types_added;
3746}
3747
3748
3749size_t
3750SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3751{
3752 assert(sc.comp_unit && sc.function);
3753 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00003754 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003755 if (dwarf_cu)
3756 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003757 const dw_offset_t function_die_offset = sc.function->GetID();
3758 DWARFDIE function_die = dwarf_cu->GetDIE (function_die_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003759 if (function_die)
3760 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003761 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003762 }
3763 }
3764
3765 return functions_added;
3766}
3767
3768
3769size_t
3770SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3771{
3772 // At least a compile unit must be valid
3773 assert(sc.comp_unit);
3774 size_t types_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00003775 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003776 if (dwarf_cu)
3777 {
3778 if (sc.function)
3779 {
3780 dw_offset_t function_die_offset = sc.function->GetID();
Greg Clayton6071e6f2015-08-26 22:57:51 +00003781 DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
3782 if (func_die && func_die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003783 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003784 types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785 }
3786 }
3787 else
3788 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003789 DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
3790 if (dwarf_cu_die && dwarf_cu_die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003791 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003792 types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003793 }
3794 }
3795 }
3796
3797 return types_added;
3798}
3799
3800size_t
3801SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3802{
3803 if (sc.comp_unit != NULL)
3804 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003805 DWARFDebugInfo* info = DebugInfo();
3806 if (info == NULL)
3807 return 0;
3808
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003809 if (sc.function)
3810 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003811 DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID()));
Greg Clayton9422dd62013-03-04 21:46:16 +00003812
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003813 const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
Greg Claytonc7bece562013-01-25 18:06:21 +00003814 if (func_lo_pc != LLDB_INVALID_ADDRESS)
Greg Claytone38a5ed2012-01-05 03:57:59 +00003815 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003816 const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
Greg Claytonc662ec82011-06-17 22:10:16 +00003817
Greg Claytone38a5ed2012-01-05 03:57:59 +00003818 // Let all blocks know they have parse all their variables
3819 sc.function->GetBlock (false).SetDidParseVariables (true, true);
3820 return num_variables;
3821 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003822 }
3823 else if (sc.comp_unit)
3824 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003825 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
Greg Clayton9422dd62013-03-04 21:46:16 +00003826
3827 if (dwarf_cu == NULL)
3828 return 0;
3829
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003830 uint32_t vars_added = 0;
3831 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3832
3833 if (variables.get() == NULL)
3834 {
3835 variables.reset(new VariableList());
3836 sc.comp_unit->SetVariableList(variables);
3837
Greg Claytond4a2b372011-09-12 23:21:58 +00003838 DIEArray die_offsets;
Greg Clayton97fbc342011-10-20 22:30:33 +00003839 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003840 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003841 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00003842 {
3843 DWARFMappedHash::DIEInfoArray hash_data_array;
3844 if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
3845 dwarf_cu->GetNextCompileUnitOffset(),
3846 hash_data_array))
3847 {
3848 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
3849 }
3850 }
Greg Clayton7f995132011-10-04 22:41:51 +00003851 }
3852 else
3853 {
3854 // Index if we already haven't to make sure the compile units
3855 // get indexed and make their global DIE index list
3856 if (!m_indexed)
3857 Index ();
3858
3859 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
Greg Clayton7f995132011-10-04 22:41:51 +00003860 die_offsets);
3861 }
3862
3863 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003864 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003865 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003866 DWARFDebugInfo* debug_info = DebugInfo();
3867 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003868 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003869 const DIERef& die_ref = die_offsets[i];
3870 DWARFDIE die = debug_info->GetDIE (die_ref);
Greg Clayton95d87902011-11-11 03:16:25 +00003871 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00003872 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003873 VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
Greg Clayton95d87902011-11-11 03:16:25 +00003874 if (var_sp)
3875 {
3876 variables->AddVariableIfUnique (var_sp);
3877 ++vars_added;
3878 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003879 }
Greg Clayton95d87902011-11-11 03:16:25 +00003880 else
3881 {
3882 if (m_using_apple_tables)
3883 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003884 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);
Greg Clayton95d87902011-11-11 03:16:25 +00003885 }
3886 }
3887
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003888 }
3889 }
3890 }
3891 return vars_added;
3892 }
3893 }
3894 return 0;
3895}
3896
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003897VariableSP
3898SymbolFileDWARF::ParseVariableDIE
3899(
3900 const SymbolContext& sc,
Greg Clayton6071e6f2015-08-26 22:57:51 +00003901 const DWARFDIE &die,
Greg Clayton016a95e2010-09-14 02:20:48 +00003902 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003903)
3904{
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003905 if (die.GetDWARF() != this)
3906 return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
3907
Greg Clayton6071e6f2015-08-26 22:57:51 +00003908 VariableSP var_sp;
3909 if (!die)
3910 return var_sp;
3911
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003912 var_sp = GetDIEToVariable()[die.GetDIE()];
Greg Clayton83c5cd92010-11-14 22:13:40 +00003913 if (var_sp)
3914 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003915
Greg Clayton6071e6f2015-08-26 22:57:51 +00003916 const dw_tag_t tag = die.Tag();
Richard Mitton0a558352013-10-17 21:14:00 +00003917 ModuleSP module = GetObjectFile()->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00003918
3919 if ((tag == DW_TAG_variable) ||
3920 (tag == DW_TAG_constant) ||
3921 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003922 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003923 DWARFAttributes attributes;
3924 const size_t num_attributes = die.GetAttributes(attributes);
Paul Hermand628cbb2015-09-15 23:44:17 +00003925 DWARFDIE spec_die;
Greg Clayton7f995132011-10-04 22:41:51 +00003926 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003927 {
Greg Clayton7f995132011-10-04 22:41:51 +00003928 const char *name = NULL;
3929 const char *mangled = NULL;
3930 Declaration decl;
3931 uint32_t i;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003932 DWARFFormValue type_die_form;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003933 DWARFExpression location(die.GetCU());
Greg Clayton7f995132011-10-04 22:41:51 +00003934 bool is_external = false;
3935 bool is_artificial = false;
3936 bool location_is_const_value_data = false;
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003937 bool has_explicit_location = false;
Enrico Granata4ec130d2014-08-11 19:16:35 +00003938 DWARFFormValue const_value;
Greg Clayton23f59502012-07-17 03:23:13 +00003939 //AccessType accessibility = eAccessNone;
Greg Clayton7f995132011-10-04 22:41:51 +00003940
3941 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003942 {
Greg Clayton7f995132011-10-04 22:41:51 +00003943 dw_attr_t attr = attributes.AttributeAtIndex(i);
3944 DWARFFormValue form_value;
Greg Clayton54166af2014-11-22 01:58:59 +00003945
Greg Clayton6071e6f2015-08-26 22:57:51 +00003946 if (attributes.ExtractFormValueAtIndex(i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003947 {
Greg Clayton7f995132011-10-04 22:41:51 +00003948 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003949 {
Greg Clayton7f995132011-10-04 22:41:51 +00003950 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3951 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3952 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003953 case DW_AT_name: name = form_value.AsCString(); break;
Greg Clayton71415542012-12-08 00:24:40 +00003954 case DW_AT_linkage_name:
Greg Clayton6071e6f2015-08-26 22:57:51 +00003955 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003956 case DW_AT_type: type_die_form = form_value; break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00003957 case DW_AT_external: is_external = form_value.Boolean(); break;
Greg Clayton7f995132011-10-04 22:41:51 +00003958 case DW_AT_const_value:
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003959 // If we have already found a DW_AT_location attribute, ignore this attribute.
3960 if (!has_explicit_location)
3961 {
3962 location_is_const_value_data = true;
3963 // The constant value will be either a block, a data value or a string.
Ed Masteeeae7212013-10-24 20:43:47 +00003964 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003965 if (DWARFFormValue::IsBlockForm(form_value.Form()))
3966 {
3967 // Retrieve the value as a block expression.
3968 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3969 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00003970 location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003971 }
3972 else if (DWARFFormValue::IsDataForm(form_value.Form()))
3973 {
3974 // Retrieve the value as a data expression.
Tamas Berghammerb7c64652015-08-25 11:45:46 +00003975 DWARFFormValue::FixedFormSizes fixed_form_sizes =
3976 DWARFFormValue::GetFixedFormSizesForAddressSize (
3977 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
3978 attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003979 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
Tamas Berghammerb7c64652015-08-25 11:45:46 +00003980 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
Enrico Granata4ec130d2014-08-11 19:16:35 +00003981 if (data_length == 0)
3982 {
3983 const uint8_t *data_pointer = form_value.BlockData();
3984 if (data_pointer)
3985 {
Jason Molenda18f5fd32014-10-16 07:52:17 +00003986 form_value.Unsigned();
Enrico Granata4ec130d2014-08-11 19:16:35 +00003987 }
3988 else if (DWARFFormValue::IsDataForm(form_value.Form()))
3989 {
3990 // we need to get the byte size of the type later after we create the variable
3991 const_value = form_value;
3992 }
3993 }
3994 else
3995 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00003996 }
3997 else
3998 {
3999 // Retrieve the value as a string expression.
4000 if (form_value.Form() == DW_FORM_strp)
4001 {
Tamas Berghammerb7c64652015-08-25 11:45:46 +00004002 DWARFFormValue::FixedFormSizes fixed_form_sizes =
4003 DWARFFormValue::GetFixedFormSizesForAddressSize (
4004 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
4005 attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004006 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
Tamas Berghammerb7c64652015-08-25 11:45:46 +00004007 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
Richard Mitton0a558352013-10-17 21:14:00 +00004008 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004009 }
4010 else
4011 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004012 const char *str = form_value.AsCString();
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004013 uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
4014 uint32_t string_length = strlen(str) + 1;
Richard Mitton0a558352013-10-17 21:14:00 +00004015 location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004016 }
4017 }
4018 }
4019 break;
Greg Clayton7f995132011-10-04 22:41:51 +00004020 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004021 {
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004022 location_is_const_value_data = false;
4023 has_explicit_location = true;
Greg Clayton7f995132011-10-04 22:41:51 +00004024 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004025 {
Ed Masteeeae7212013-10-24 20:43:47 +00004026 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Clayton7f995132011-10-04 22:41:51 +00004027
4028 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4029 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00004030 location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
Greg Clayton7f995132011-10-04 22:41:51 +00004031 }
4032 else
4033 {
Tamas Berghammer1f5e4482015-09-16 12:37:06 +00004034 const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
Greg Clayton7f995132011-10-04 22:41:51 +00004035 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4036
Tamas Berghammer1f5e4482015-09-16 12:37:06 +00004037 size_t loc_list_length = DWARFExpression::LocationListSize(die.GetCU(), debug_loc_data, debug_loc_offset);
Greg Clayton7f995132011-10-04 22:41:51 +00004038 if (loc_list_length > 0)
4039 {
Richard Mitton0a558352013-10-17 21:14:00 +00004040 location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
Greg Clayton7f995132011-10-04 22:41:51 +00004041 assert (func_low_pc != LLDB_INVALID_ADDRESS);
Greg Clayton54166af2014-11-22 01:58:59 +00004042 location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
Greg Clayton7f995132011-10-04 22:41:51 +00004043 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004044 }
4045 }
Greg Clayton7f995132011-10-04 22:41:51 +00004046 break;
Paul Hermand628cbb2015-09-15 23:44:17 +00004047 case DW_AT_specification:
4048 {
4049 DWARFDebugInfo* debug_info = DebugInfo();
4050 if (debug_info)
4051 spec_die = debug_info->GetDIE(DIERef(form_value));
4052 break;
4053 }
Greg Clayton1c8ef472013-04-05 23:27:21 +00004054 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00004055 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7f995132011-10-04 22:41:51 +00004056 case DW_AT_declaration:
4057 case DW_AT_description:
4058 case DW_AT_endianity:
4059 case DW_AT_segment:
4060 case DW_AT_start_scope:
4061 case DW_AT_visibility:
4062 default:
4063 case DW_AT_abstract_origin:
4064 case DW_AT_sibling:
Greg Clayton7f995132011-10-04 22:41:51 +00004065 break;
4066 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004067 }
4068 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004069
Greg Clayton6071e6f2015-08-26 22:57:51 +00004070 const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
4071 const dw_tag_t parent_tag = die.GetParent().Tag();
4072 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);
Paul Herman10bc1a42015-08-18 22:46:57 +00004073
Greg Clayton9e9f2192013-05-17 00:55:28 +00004074 ValueType scope = eValueTypeInvalid;
4075
Greg Clayton6071e6f2015-08-26 22:57:51 +00004076 const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
Greg Clayton9e9f2192013-05-17 00:55:28 +00004077 SymbolContextScope * symbol_context_scope = NULL;
4078
Siva Chandra0783ab92015-03-24 18:32:27 +00004079 if (!mangled)
4080 {
4081 // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
4082 // generate fully qualified names of global variables with commands like "frame var j".
4083 // For example, if j were an int variable holding a value 4 and declared in a namespace
4084 // B which in turn is contained in a namespace A, the command "frame var j" returns
4085 // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
4086 // to generate a fully qualified name from the declaration context.
Greg Clayton6071e6f2015-08-26 22:57:51 +00004087 if (parent_tag == DW_TAG_compile_unit &&
Jim Ingham0e0984e2015-09-02 01:06:46 +00004088 Language::LanguageIsCPlusPlus(die.GetLanguage()))
Siva Chandra0783ab92015-03-24 18:32:27 +00004089 {
4090 DWARFDeclContext decl_ctx;
4091
Greg Clayton6071e6f2015-08-26 22:57:51 +00004092 die.GetDWARFDeclContext(decl_ctx);
Siva Chandra0783ab92015-03-24 18:32:27 +00004093 mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
4094 }
4095 }
4096
Greg Clayton9e9f2192013-05-17 00:55:28 +00004097 // DWARF doesn't specify if a DW_TAG_variable is a local, global
4098 // or static variable, so we have to do a little digging by
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004099 // looking at the location of a variable to see if it contains
Greg Clayton9e9f2192013-05-17 00:55:28 +00004100 // a DW_OP_addr opcode _somewhere_ in the definition. I say
4101 // somewhere because clang likes to combine small global variables
4102 // into the same symbol and have locations like:
4103 // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
4104 // So if we don't have a DW_TAG_formal_parameter, we can look at
4105 // the location to see if it contains a DW_OP_addr opcode, and
4106 // then we can correctly classify our variables.
4107 if (tag == DW_TAG_formal_parameter)
4108 scope = eValueTypeVariableArgument;
4109 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004110 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004111 bool op_error = false;
4112 // Check if the location has a DW_OP_addr with any address value...
4113 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
4114 if (!location_is_const_value_data)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004115 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004116 location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
4117 if (op_error)
Greg Clayton96c09682012-01-04 22:56:43 +00004118 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004119 StreamString strm;
4120 location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
Greg Clayton6071e6f2015-08-26 22:57:51 +00004121 GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
Greg Clayton96c09682012-01-04 22:56:43 +00004122 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00004123 }
Greg Claytond1767f02011-12-08 02:13:16 +00004124
Greg Clayton9e9f2192013-05-17 00:55:28 +00004125 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
4126 {
4127 if (is_external)
4128 scope = eValueTypeVariableGlobal;
4129 else
4130 scope = eValueTypeVariableStatic;
4131
4132
4133 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
4134
4135 if (debug_map_symfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004136 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004137 // When leaving the DWARF in the .o files on darwin,
4138 // when we have a global variable that wasn't initialized,
4139 // the .o file might not have allocated a virtual
4140 // address for the global variable. In this case it will
4141 // have created a symbol for the global variable
4142 // that is undefined/data and external and the value will
4143 // be the byte size of the variable. When we do the
4144 // address map in SymbolFileDWARFDebugMap we rely on
4145 // having an address, we need to do some magic here
4146 // so we can get the correct address for our global
4147 // variable. The address for all of these entries
4148 // will be zero, and there will be an undefined symbol
4149 // in this object file, and the executable will have
4150 // a matching symbol with a good address. So here we
4151 // dig up the correct address and replace it in the
4152 // location for the variable, and set the variable's
4153 // symbol context scope to be that of the main executable
4154 // so the file address will resolve correctly.
4155 bool linked_oso_file_addr = false;
4156 if (is_external && location_DW_OP_addr == 0)
Greg Clayton9422dd62013-03-04 21:46:16 +00004157 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004158 // we have a possible uninitialized extern global
4159 ConstString const_name(mangled ? mangled : name);
4160 ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
4161 if (debug_map_objfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004162 {
Greg Clayton3046e662013-07-10 01:23:25 +00004163 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
Greg Clayton9e9f2192013-05-17 00:55:28 +00004164 if (debug_map_symtab)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004165 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004166 Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
4167 eSymbolTypeData,
4168 Symtab::eDebugYes,
4169 Symtab::eVisibilityExtern);
4170 if (exe_symbol)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004171 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004172 if (exe_symbol->ValueIsAddress())
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004173 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004174 const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
Greg Clayton9e9f2192013-05-17 00:55:28 +00004175 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004176 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004177 if (location.Update_DW_OP_addr (exe_file_addr))
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004178 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004179 linked_oso_file_addr = true;
4180 symbol_context_scope = exe_symbol;
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004181 }
4182 }
4183 }
4184 }
4185 }
4186 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00004187 }
Greg Clayton9422dd62013-03-04 21:46:16 +00004188
Greg Clayton9e9f2192013-05-17 00:55:28 +00004189 if (!linked_oso_file_addr)
4190 {
4191 // The DW_OP_addr is not zero, but it contains a .o file address which
4192 // needs to be linked up correctly.
4193 const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
4194 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton9422dd62013-03-04 21:46:16 +00004195 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004196 // Update the file address for this variable
4197 location.Update_DW_OP_addr (exe_file_addr);
4198 }
4199 else
4200 {
4201 // Variable didn't make it into the final executable
4202 return var_sp;
Greg Clayton9422dd62013-03-04 21:46:16 +00004203 }
Greg Claytond1767f02011-12-08 02:13:16 +00004204 }
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004205 }
Greg Clayton5cf58b92011-10-05 22:22:08 +00004206 }
4207 else
4208 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004209 scope = eValueTypeVariableLocal;
Greg Clayton5cf58b92011-10-05 22:22:08 +00004210 }
Greg Clayton7f995132011-10-04 22:41:51 +00004211 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00004212
4213 if (symbol_context_scope == NULL)
4214 {
4215 switch (parent_tag)
4216 {
4217 case DW_TAG_subprogram:
4218 case DW_TAG_inlined_subroutine:
4219 case DW_TAG_lexical_block:
4220 if (sc.function)
4221 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004222 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
Greg Clayton9e9f2192013-05-17 00:55:28 +00004223 if (symbol_context_scope == NULL)
4224 symbol_context_scope = sc.function;
4225 }
4226 break;
4227
4228 default:
4229 symbol_context_scope = sc.comp_unit;
4230 break;
4231 }
4232 }
4233
4234 if (symbol_context_scope)
4235 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004236 SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID()));
Enrico Granata4ec130d2014-08-11 19:16:35 +00004237
4238 if (const_value.Form() && type_sp && type_sp->GetType())
Greg Clayton6071e6f2015-08-26 22:57:51 +00004239 location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
Enrico Granata4ec130d2014-08-11 19:16:35 +00004240
Greg Clayton6071e6f2015-08-26 22:57:51 +00004241 var_sp.reset (new Variable (die.GetID(),
Greg Clayton9e9f2192013-05-17 00:55:28 +00004242 name,
4243 mangled,
Enrico Granata4ec130d2014-08-11 19:16:35 +00004244 type_sp,
Greg Clayton9e9f2192013-05-17 00:55:28 +00004245 scope,
4246 symbol_context_scope,
4247 &decl,
4248 location,
4249 is_external,
Paul Herman10bc1a42015-08-18 22:46:57 +00004250 is_artificial,
4251 is_static_member));
Greg Clayton9e9f2192013-05-17 00:55:28 +00004252
4253 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
4254 }
4255 else
4256 {
4257 // Not ready to parse this variable yet. It might be a global
4258 // or static variable that is in a function scope and the function
4259 // in the symbol context wasn't filled in yet
4260 return var_sp;
4261 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004262 }
Greg Clayton7f995132011-10-04 22:41:51 +00004263 // Cache var_sp even if NULL (the variable was just a specification or
4264 // was missing vital information to be able to be displayed in the debugger
4265 // (missing location due to optimization, etc)) so we don't re-parse
4266 // this DIE over and over later...
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004267 GetDIEToVariable()[die.GetDIE()] = var_sp;
Paul Hermand628cbb2015-09-15 23:44:17 +00004268 if (spec_die)
4269 GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004270 }
4271 return var_sp;
4272}
4273
Greg Claytonc662ec82011-06-17 22:10:16 +00004274
Greg Clayton6071e6f2015-08-26 22:57:51 +00004275DWARFDIE
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004276SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref,
Greg Clayton6071e6f2015-08-26 22:57:51 +00004277 dw_offset_t spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004278{
4279 // Give the concrete function die specified by "func_die_offset", find the
4280 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4281 // to "spec_block_die_offset"
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004282 return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset);
Greg Claytonc662ec82011-06-17 22:10:16 +00004283}
4284
4285
Greg Clayton6071e6f2015-08-26 22:57:51 +00004286DWARFDIE
4287SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die,
4288 dw_offset_t spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004289{
4290 if (die)
4291 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004292 switch (die.Tag())
Greg Claytonc662ec82011-06-17 22:10:16 +00004293 {
4294 case DW_TAG_subprogram:
4295 case DW_TAG_inlined_subroutine:
4296 case DW_TAG_lexical_block:
4297 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004298 if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004299 return die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004300
Greg Clayton6071e6f2015-08-26 22:57:51 +00004301 if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004302 return die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004303 }
4304 break;
4305 }
4306
4307 // Give the concrete function die specified by "func_die_offset", find the
4308 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4309 // to "spec_block_die_offset"
Greg Clayton6071e6f2015-08-26 22:57:51 +00004310 for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling())
Greg Claytonc662ec82011-06-17 22:10:16 +00004311 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004312 DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset);
Greg Claytonc662ec82011-06-17 22:10:16 +00004313 if (result_die)
4314 return result_die;
4315 }
4316 }
4317
Greg Clayton6071e6f2015-08-26 22:57:51 +00004318 return DWARFDIE();
Greg Claytonc662ec82011-06-17 22:10:16 +00004319}
4320
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004321size_t
Greg Clayton6071e6f2015-08-26 22:57:51 +00004322SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
4323 const DWARFDIE &orig_die,
4324 const lldb::addr_t func_low_pc,
4325 bool parse_siblings,
4326 bool parse_children,
4327 VariableList* cc_variable_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004328{
Greg Clayton6071e6f2015-08-26 22:57:51 +00004329 if (!orig_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004330 return 0;
4331
Greg Claytonc662ec82011-06-17 22:10:16 +00004332 VariableListSP variable_list_sp;
4333
4334 size_t vars_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00004335 DWARFDIE die = orig_die;
4336 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004337 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004338 dw_tag_t tag = die.Tag();
Greg Claytonc662ec82011-06-17 22:10:16 +00004339
4340 // Check to see if we have already parsed this variable or constant?
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004341 VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
Greg Clayton6071e6f2015-08-26 22:57:51 +00004342 if (var_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004343 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004344 if (cc_variable_list)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004345 cc_variable_list->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004346 }
4347 else
4348 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004349 // We haven't already parsed it, lets do that now.
4350 if ((tag == DW_TAG_variable) ||
4351 (tag == DW_TAG_constant) ||
4352 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004353 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004354 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004355 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004356 DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
4357 dw_tag_t parent_tag = sc_parent_die.Tag();
Greg Claytonc662ec82011-06-17 22:10:16 +00004358 switch (parent_tag)
4359 {
4360 case DW_TAG_compile_unit:
4361 if (sc.comp_unit != NULL)
4362 {
4363 variable_list_sp = sc.comp_unit->GetVariableList(false);
4364 if (variable_list_sp.get() == NULL)
4365 {
4366 variable_list_sp.reset(new VariableList());
4367 sc.comp_unit->SetVariableList(variable_list_sp);
4368 }
4369 }
4370 else
4371 {
Daniel Malead01b2952012-11-29 21:49:15 +00004372 GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
Greg Clayton6071e6f2015-08-26 22:57:51 +00004373 sc_parent_die.GetID(),
4374 sc_parent_die.GetTagAsCString(),
4375 orig_die.GetID(),
4376 orig_die.GetTagAsCString());
Greg Claytonc662ec82011-06-17 22:10:16 +00004377 }
4378 break;
4379
4380 case DW_TAG_subprogram:
4381 case DW_TAG_inlined_subroutine:
4382 case DW_TAG_lexical_block:
4383 if (sc.function != NULL)
4384 {
4385 // Check to see if we already have parsed the variables for the given scope
4386
Greg Clayton6071e6f2015-08-26 22:57:51 +00004387 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
Greg Claytonc662ec82011-06-17 22:10:16 +00004388 if (block == NULL)
4389 {
4390 // This must be a specification or abstract origin with
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004391 // a concrete block counterpart in the current function. We need
Greg Claytonc662ec82011-06-17 22:10:16 +00004392 // to find the concrete block so we can correctly add the
4393 // variable to it
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004394 const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID()),
Greg Clayton6071e6f2015-08-26 22:57:51 +00004395 sc_parent_die.GetOffset());
Greg Claytonc662ec82011-06-17 22:10:16 +00004396 if (concrete_block_die)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004397 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
Greg Claytonc662ec82011-06-17 22:10:16 +00004398 }
4399
4400 if (block != NULL)
4401 {
4402 const bool can_create = false;
4403 variable_list_sp = block->GetBlockVariableList (can_create);
4404 if (variable_list_sp.get() == NULL)
4405 {
4406 variable_list_sp.reset(new VariableList());
4407 block->SetVariableList(variable_list_sp);
4408 }
4409 }
4410 }
4411 break;
4412
4413 default:
Daniel Malead01b2952012-11-29 21:49:15 +00004414 GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
Greg Clayton6071e6f2015-08-26 22:57:51 +00004415 orig_die.GetID(),
4416 orig_die.GetTagAsCString());
Greg Claytonc662ec82011-06-17 22:10:16 +00004417 break;
4418 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004419 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004420
4421 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004422 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004423 VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc));
Greg Clayton73bf5db2011-06-17 01:22:15 +00004424 if (var_sp)
4425 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004426 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00004427 if (cc_variable_list)
4428 cc_variable_list->AddVariableIfUnique (var_sp);
4429 ++vars_added;
4430 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004431 }
4432 }
4433 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004434
4435 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4436
Greg Clayton6071e6f2015-08-26 22:57:51 +00004437 if (!skip_children && parse_children && die.HasChildren())
Greg Claytonc662ec82011-06-17 22:10:16 +00004438 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004439 vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list);
Greg Claytonc662ec82011-06-17 22:10:16 +00004440 }
4441
4442 if (parse_siblings)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004443 die = die.GetSibling();
Greg Claytonc662ec82011-06-17 22:10:16 +00004444 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00004445 die.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004446 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004447 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004448}
4449
4450//------------------------------------------------------------------
4451// PluginInterface protocol
4452//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00004453ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004454SymbolFileDWARF::GetPluginName()
4455{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004456 return GetPluginNameStatic();
4457}
4458
4459uint32_t
4460SymbolFileDWARF::GetPluginVersion()
4461{
4462 return 1;
4463}
4464
4465void
Sean Callanancc427fa2011-07-30 02:42:06 +00004466SymbolFileDWARF::DumpIndexes ()
4467{
4468 StreamFile s(stdout, false);
4469
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00004470 s.Printf ("DWARF index for (%s) '%s':",
Sean Callanancc427fa2011-07-30 02:42:06 +00004471 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00004472 GetObjectFile()->GetFileSpec().GetPath().c_str());
Sean Callanancc427fa2011-07-30 02:42:06 +00004473 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
4474 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
4475 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
4476 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
4477 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
4478 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
4479 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Bruce Mitchenere171da52015-07-22 00:16:02 +00004480 s.Printf("\nNamespaces:\n"); m_namespace_index.Dump (&s);
Sean Callanancc427fa2011-07-30 02:42:06 +00004481}
4482
Greg Claytoncaab74e2012-01-28 00:48:57 +00004483
Greg Clayton1f746072012-08-29 21:13:06 +00004484SymbolFileDWARFDebugMap *
4485SymbolFileDWARF::GetDebugMapSymfile ()
4486{
4487 if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
4488 {
4489 lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
4490 if (module_sp)
4491 {
4492 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
4493 if (sym_vendor)
4494 m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
4495 }
4496 }
4497 return m_debug_map_symfile;
4498}
Tamas Berghammer1f5e4482015-09-16 12:37:06 +00004499
4500DWARFExpression::LocationListFormat
4501SymbolFileDWARF::GetLocationListFormat() const
4502{
4503 return DWARFExpression::RegularLocationList;
4504}