blob: 36f4d2b8ca4100ab099a394bbbb2072efb9d9e65 [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"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000038#include "lldb/Symbol/ClangUtil.h"
39#include "lldb/Symbol/CompileUnit.h"
Paul Hermand628cbb2015-09-15 23:44:17 +000040#include "lldb/Symbol/CompilerDecl.h"
41#include "lldb/Symbol/CompilerDeclContext.h"
Siva Chandrad8335e92015-12-16 00:22:08 +000042#include "lldb/Symbol/DebugMacros.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000043#include "lldb/Symbol/LineTable.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#include "lldb/Symbol/ObjectFile.h"
45#include "lldb/Symbol/SymbolVendor.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000046#include "lldb/Symbol/TypeMap.h"
Bruce Mitchener937e3962015-09-21 16:56:08 +000047#include "lldb/Symbol/TypeSystem.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048#include "lldb/Symbol/VariableList.h"
49
Jim Inghamaa816b82015-09-02 01:59:14 +000050#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
51#include "Plugins/Language/ObjC/ObjCLanguage.h"
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000052
Jim Ingham0e0984e2015-09-02 01:06:46 +000053#include "lldb/Target/Language.h"
54
Tamas Berghammer2ff88702015-10-23 10:34:49 +000055#include "lldb/Utility/TaskPool.h"
56
Greg Clayton261ac3f2015-08-28 01:01:03 +000057#include "DWARFASTParser.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000058#include "DWARFASTParserClang.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059#include "DWARFCompileUnit.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000060#include "DWARFDIECollection.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061#include "DWARFDebugAbbrev.h"
62#include "DWARFDebugAranges.h"
63#include "DWARFDebugInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064#include "DWARFDebugLine.h"
Siva Chandrad8335e92015-12-16 00:22:08 +000065#include "DWARFDebugMacro.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066#include "DWARFDebugPubnames.h"
67#include "DWARFDebugRanges.h"
Greg Claytona8022fa2012-04-24 21:22:41 +000068#include "DWARFDeclContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069#include "DWARFFormValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000071#include "SymbolFileDWARFDebugMap.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000072#include "SymbolFileDWARFDwo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
74#include <map>
75
Matthew Gardinere81df3b2014-08-26 06:57:23 +000076#include <ctype.h>
77#include <string.h>
78
Greg Clayton62742b12010-11-11 01:09:45 +000079//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000080
81#ifdef ENABLE_DEBUG_PRINTF
82#include <stdio.h>
Ed Mastea0191d12013-10-17 20:42:56 +000083#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
Greg Claytonc93237c2010-10-01 20:48:32 +000084#else
85#define DEBUG_PRINTF(fmt, ...)
86#endif
87
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088using namespace lldb;
89using namespace lldb_private;
90
Greg Clayton219cf312012-03-30 00:51:13 +000091//static inline bool
92//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
93//{
94// switch (tag)
95// {
96// default:
97// break;
98// case DW_TAG_subprogram:
99// case DW_TAG_inlined_subroutine:
100// case DW_TAG_class_type:
101// case DW_TAG_structure_type:
102// case DW_TAG_union_type:
103// return true;
104// }
105// return false;
106//}
107//
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000108
109namespace {
110
111 PropertyDefinition
112 g_properties[] =
113 {
114 { "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." },
115 { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr }
116 };
117
118 enum
119 {
120 ePropertySymLinkPaths
121 };
122
123
124 class PluginProperties : public Properties
125 {
126 public:
127 static ConstString
128 GetSettingName()
129 {
130 return SymbolFileDWARF::GetPluginNameStatic();
131 }
132
133 PluginProperties()
134 {
135 m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
136 m_collection_sp->Initialize(g_properties);
137 }
138
139 FileSpecList&
140 GetSymLinkPaths()
141 {
142 OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths);
143 assert(option_value);
144 return option_value->GetCurrentValue();
145 }
146
147 };
148
149 typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
150
151 static const SymbolFileDWARFPropertiesSP&
152 GetGlobalPluginProperties()
153 {
154 static const auto g_settings_sp(std::make_shared<PluginProperties>());
155 return g_settings_sp;
156 }
157
158} // anonymous namespace end
159
160
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000161static const char*
162removeHostnameFromPathname(const char* path_from_dwarf)
163{
164 if (!path_from_dwarf || !path_from_dwarf[0])
165 {
166 return path_from_dwarf;
167 }
Enrico Granata99e5e222015-07-27 21:27:02 +0000168
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000169 const char *colon_pos = strchr(path_from_dwarf, ':');
Enrico Granata99e5e222015-07-27 21:27:02 +0000170 if (nullptr == colon_pos)
171 {
172 return path_from_dwarf;
173 }
174
175 const char *slash_pos = strchr(path_from_dwarf, '/');
176 if (slash_pos && (slash_pos < colon_pos))
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000177 {
178 return path_from_dwarf;
179 }
180
181 // check whether we have a windows path, and so the first character
182 // is a drive-letter not a hostname.
183 if (
184 colon_pos == path_from_dwarf + 1 &&
185 isalpha(*path_from_dwarf) &&
186 strlen(path_from_dwarf) > 2 &&
187 '\\' == path_from_dwarf[2])
188 {
189 return path_from_dwarf;
190 }
Enrico Granata99e5e222015-07-27 21:27:02 +0000191
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000192 return colon_pos + 1;
193}
194
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000195static const char*
196resolveCompDir(const char* path_from_dwarf)
197{
198 if (!path_from_dwarf)
199 return nullptr;
200
201 // DWARF2/3 suggests the form hostname:pathname for compilation directory.
202 // Remove the host part if present.
203 const char* local_path = removeHostnameFromPathname(path_from_dwarf);
204 if (!local_path)
205 return nullptr;
206
207 bool is_symlink = false;
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000208 FileSpec local_path_spec(local_path, false);
209 const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
210 for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
211 is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true);
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000212
213 if (!is_symlink)
214 return local_path;
215
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000216 if (!local_path_spec.IsSymbolicLink())
217 return local_path;
218
219 FileSpec resolved_local_path_spec;
220 const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
221 if (error.Success())
222 return resolved_local_path_spec.GetCString();
223
224 return nullptr;
225}
226
227
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228void
229SymbolFileDWARF::Initialize()
230{
231 LogChannelDWARF::Initialize();
232 PluginManager::RegisterPlugin (GetPluginNameStatic(),
233 GetPluginDescriptionStatic(),
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000234 CreateInstance,
235 DebuggerInitialize);
236}
237
238void
239SymbolFileDWARF::DebuggerInitialize(Debugger &debugger)
240{
241 if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName()))
242 {
243 const bool is_global_setting = true;
244 PluginManager::CreateSettingForSymbolFilePlugin(debugger,
245 GetGlobalPluginProperties()->GetValueProperties(),
246 ConstString ("Properties for the dwarf symbol-file plug-in."),
247 is_global_setting);
248 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249}
250
251void
252SymbolFileDWARF::Terminate()
253{
254 PluginManager::UnregisterPlugin (CreateInstance);
255 LogChannelDWARF::Initialize();
256}
257
258
Greg Clayton57abc5d2013-05-10 21:47:16 +0000259lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260SymbolFileDWARF::GetPluginNameStatic()
261{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000262 static ConstString g_name("dwarf");
263 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264}
265
266const char *
267SymbolFileDWARF::GetPluginDescriptionStatic()
268{
269 return "DWARF and DWARF3 debug symbol file reader.";
270}
271
272
273SymbolFile*
274SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
275{
276 return new SymbolFileDWARF(obj_file);
277}
278
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000279TypeList *
280SymbolFileDWARF::GetTypeList ()
281{
Greg Clayton2f869fe2016-03-30 20:14:35 +0000282 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
283 if (debug_map_symfile)
284 return debug_map_symfile->GetTypeList();
285 else
286 return m_obj_file->GetModule()->GetTypeList();
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000287
288}
Greg Claytonf02500c2013-06-18 22:51:05 +0000289void
Greg Clayton6071e6f2015-08-26 22:57:51 +0000290SymbolFileDWARF::GetTypes (const DWARFDIE &die,
Greg Claytonf02500c2013-06-18 22:51:05 +0000291 dw_offset_t min_die_offset,
292 dw_offset_t max_die_offset,
293 uint32_t type_mask,
294 TypeSet &type_set)
295{
Greg Clayton6071e6f2015-08-26 22:57:51 +0000296 if (die)
Greg Claytonf02500c2013-06-18 22:51:05 +0000297 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000298 const dw_offset_t die_offset = die.GetOffset();
299
300 if (die_offset >= max_die_offset)
301 return;
302
303 if (die_offset >= min_die_offset)
Greg Claytonf02500c2013-06-18 22:51:05 +0000304 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000305 const dw_tag_t tag = die.Tag();
Greg Claytonf02500c2013-06-18 22:51:05 +0000306
Greg Clayton6071e6f2015-08-26 22:57:51 +0000307 bool add_type = false;
308
309 switch (tag)
Greg Claytonf02500c2013-06-18 22:51:05 +0000310 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000311 case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
312 case DW_TAG_unspecified_type:
313 case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
314 case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
315 case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
316 case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
317 case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
318 case DW_TAG_subroutine_type:
319 case DW_TAG_subprogram:
320 case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
321 case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
322 case DW_TAG_rvalue_reference_type:
323 case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
324 case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
325 case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
326 }
Greg Claytonf02500c2013-06-18 22:51:05 +0000327
Greg Clayton6071e6f2015-08-26 22:57:51 +0000328 if (add_type)
329 {
330 const bool assert_not_being_parsed = true;
331 Type *type = ResolveTypeUID (die, assert_not_being_parsed);
332 if (type)
Greg Claytonf02500c2013-06-18 22:51:05 +0000333 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000334 if (type_set.find(type) == type_set.end())
335 type_set.insert(type);
Greg Claytonf02500c2013-06-18 22:51:05 +0000336 }
337 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000338 }
339
340 for (DWARFDIE child_die = die.GetFirstChild();
341 child_die.IsValid();
342 child_die = child_die.GetSibling())
343 {
344 GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set);
Greg Claytonf02500c2013-06-18 22:51:05 +0000345 }
346 }
347}
348
349size_t
350SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
351 uint32_t type_mask,
352 TypeList &type_list)
353
354{
355 TypeSet type_set;
356
357 CompileUnit *comp_unit = NULL;
358 DWARFCompileUnit* dwarf_cu = NULL;
359 if (sc_scope)
360 comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
361
362 if (comp_unit)
363 {
364 dwarf_cu = GetDWARFCompileUnit(comp_unit);
365 if (dwarf_cu == 0)
366 return 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +0000367 GetTypes (dwarf_cu->DIE(),
Greg Claytonf02500c2013-06-18 22:51:05 +0000368 dwarf_cu->GetOffset(),
369 dwarf_cu->GetNextCompileUnitOffset(),
370 type_mask,
371 type_set);
372 }
373 else
374 {
375 DWARFDebugInfo* info = DebugInfo();
376 if (info)
377 {
378 const size_t num_cus = info->GetNumCompileUnits();
379 for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
380 {
381 dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
382 if (dwarf_cu)
383 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000384 GetTypes (dwarf_cu->DIE(),
Greg Claytonf02500c2013-06-18 22:51:05 +0000385 0,
386 UINT32_MAX,
387 type_mask,
388 type_set);
389 }
390 }
391 }
392 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000393
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000394 std::set<CompilerType> compiler_type_set;
Greg Claytonf02500c2013-06-18 22:51:05 +0000395 size_t num_types_added = 0;
396 for (Type *type : type_set)
397 {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000398 CompilerType compiler_type = type->GetForwardCompilerType ();
399 if (compiler_type_set.find(compiler_type) == compiler_type_set.end())
Greg Clayton0fc4f312013-06-20 01:23:18 +0000400 {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000401 compiler_type_set.insert(compiler_type);
Greg Clayton0fc4f312013-06-20 01:23:18 +0000402 type_list.Insert (type->shared_from_this());
403 ++num_types_added;
404 }
Greg Claytonf02500c2013-06-18 22:51:05 +0000405 }
406 return num_types_added;
407}
408
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000409
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410//----------------------------------------------------------------------
411// Gets the first parent that is a lexical block, function or inlined
412// subroutine, or compile unit.
413//----------------------------------------------------------------------
Greg Clayton6071e6f2015-08-26 22:57:51 +0000414DWARFDIE
415SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416{
Greg Clayton6071e6f2015-08-26 22:57:51 +0000417 DWARFDIE die;
418 for (die = child_die.GetParent(); die; die = die.GetParent())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000419 {
Greg Clayton6071e6f2015-08-26 22:57:51 +0000420 dw_tag_t tag = die.Tag();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421
422 switch (tag)
423 {
424 case DW_TAG_compile_unit:
425 case DW_TAG_subprogram:
426 case DW_TAG_inlined_subroutine:
427 case DW_TAG_lexical_block:
428 return die;
429 }
430 }
Greg Clayton6071e6f2015-08-26 22:57:51 +0000431 return DWARFDIE();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432}
433
434
Greg Clayton450e3f32010-10-12 02:24:53 +0000435SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
436 SymbolFile (objfile),
Greg Clayton81c22f62011-10-19 18:09:39 +0000437 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 +0000438 m_debug_map_module_wp (),
Greg Clayton450e3f32010-10-12 02:24:53 +0000439 m_debug_map_symfile (NULL),
Greg Claytond4a2b372011-09-12 23:21:58 +0000440 m_data_debug_abbrev (),
441 m_data_debug_aranges (),
442 m_data_debug_frame (),
443 m_data_debug_info (),
444 m_data_debug_line (),
Siva Chandrad8335e92015-12-16 00:22:08 +0000445 m_data_debug_macro (),
Greg Claytond4a2b372011-09-12 23:21:58 +0000446 m_data_debug_loc (),
447 m_data_debug_ranges (),
448 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000449 m_data_apple_names (),
450 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000451 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 m_info(),
454 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000455 m_apple_names_ap (),
456 m_apple_types_ap (),
457 m_apple_namespaces_ap (),
Greg Clayton5009f9d2011-10-27 17:55:14 +0000458 m_apple_objc_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000459 m_function_basename_index(),
460 m_function_fullname_index(),
461 m_function_method_index(),
462 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000463 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000464 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000465 m_type_index(),
466 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000467 m_indexed (false),
Greg Clayton97fbc342011-10-20 22:30:33 +0000468 m_using_apple_tables (false),
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000469 m_fetched_external_modules (false),
Greg Claytonc7f03b62012-01-12 04:33:28 +0000470 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000471 m_ranges(),
472 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473{
474}
475
476SymbolFileDWARF::~SymbolFileDWARF()
477{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000478}
479
480static const ConstString &
481GetDWARFMachOSegmentName ()
482{
483 static ConstString g_dwarf_section_name ("__DWARF");
484 return g_dwarf_section_name;
485}
486
Greg Claytone576ab22011-02-15 00:19:15 +0000487UniqueDWARFASTTypeMap &
488SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
489{
Greg Clayton2f869fe2016-03-30 20:14:35 +0000490 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
491 if (debug_map_symfile)
492 return debug_map_symfile->GetUniqueDWARFASTTypeMap ();
493 else
494 return m_unique_ast_type_map;
Greg Claytone576ab22011-02-15 00:19:15 +0000495}
496
Greg Clayton8b4edba2015-08-14 20:02:05 +0000497TypeSystem *
498SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
499{
Greg Clayton2f869fe2016-03-30 20:14:35 +0000500 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000501 TypeSystem *type_system;
Greg Clayton8b4edba2015-08-14 20:02:05 +0000502 if (debug_map_symfile)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000503 {
504 type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
505 }
Greg Clayton8b4edba2015-08-14 20:02:05 +0000506 else
Ryan Brown57bee1e2015-09-14 22:45:11 +0000507 {
508 type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
509 if (type_system)
510 type_system->SetSymbolFile(this);
511 }
512 return type_system;
Greg Clayton8b4edba2015-08-14 20:02:05 +0000513}
514
Greg Clayton6beaaa62011-01-17 03:46:26 +0000515void
516SymbolFileDWARF::InitializeObject()
517{
Greg Claytone72dfb32012-02-24 01:59:29 +0000518 ModuleSP module_sp (m_obj_file->GetModule());
519 if (module_sp)
Greg Clayton6beaaa62011-01-17 03:46:26 +0000520 {
Greg Clayton3046e662013-07-10 01:23:25 +0000521 const SectionList *section_list = module_sp->GetSectionList();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000522 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
523
524 // Memory map the DWARF mach-o segment so we have everything mmap'ed
525 // to keep our heap memory usage down.
526 if (section)
Greg Claytonc9660542012-02-05 02:38:54 +0000527 m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000528 }
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000529
Greg Clayton4d01ace2011-09-29 16:58:15 +0000530 get_apple_names_data();
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000531 if (m_data_apple_names.m_data.GetByteSize() > 0)
Greg Clayton7f995132011-10-04 22:41:51 +0000532 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000533 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names.m_data,
534 get_debug_str_data(),
535 ".apple_names"));
Greg Clayton97fbc342011-10-20 22:30:33 +0000536 if (m_apple_names_ap->IsValid())
537 m_using_apple_tables = true;
538 else
Greg Clayton7f995132011-10-04 22:41:51 +0000539 m_apple_names_ap.reset();
540 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000541 get_apple_types_data();
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000542 if (m_data_apple_types.m_data.GetByteSize() > 0)
Greg Clayton7f995132011-10-04 22:41:51 +0000543 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000544 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types.m_data,
545 get_debug_str_data(),
546 ".apple_types"));
Greg Clayton97fbc342011-10-20 22:30:33 +0000547 if (m_apple_types_ap->IsValid())
548 m_using_apple_tables = true;
549 else
Greg Clayton7f995132011-10-04 22:41:51 +0000550 m_apple_types_ap.reset();
551 }
552
553 get_apple_namespaces_data();
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000554 if (m_data_apple_namespaces.m_data.GetByteSize() > 0)
Greg Clayton7f995132011-10-04 22:41:51 +0000555 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000556 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces.m_data,
557 get_debug_str_data(),
558 ".apple_namespaces"));
Greg Clayton97fbc342011-10-20 22:30:33 +0000559 if (m_apple_namespaces_ap->IsValid())
560 m_using_apple_tables = true;
561 else
Greg Clayton7f995132011-10-04 22:41:51 +0000562 m_apple_namespaces_ap.reset();
563 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000564
Greg Clayton5009f9d2011-10-27 17:55:14 +0000565 get_apple_objc_data();
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000566 if (m_data_apple_objc.m_data.GetByteSize() > 0)
Greg Clayton5009f9d2011-10-27 17:55:14 +0000567 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000568 m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc.m_data,
569 get_debug_str_data(),
570 ".apple_objc"));
Greg Clayton5009f9d2011-10-27 17:55:14 +0000571 if (m_apple_objc_ap->IsValid())
572 m_using_apple_tables = true;
573 else
574 m_apple_objc_ap.reset();
575 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000576}
577
578bool
579SymbolFileDWARF::SupportedVersion(uint16_t version)
580{
Greg Claytonabcbfe52013-04-04 00:00:36 +0000581 return version == 2 || version == 3 || version == 4;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582}
583
584uint32_t
Sean Callananbfaf54d2011-12-03 04:38:43 +0000585SymbolFileDWARF::CalculateAbilities ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000586{
587 uint32_t abilities = 0;
588 if (m_obj_file != NULL)
589 {
590 const Section* section = NULL;
591 const SectionList *section_list = m_obj_file->GetSectionList();
592 if (section_list == NULL)
593 return 0;
594
595 uint64_t debug_abbrev_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 uint64_t debug_info_file_size = 0;
597 uint64_t debug_line_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000598
Greg Clayton6beaaa62011-01-17 03:46:26 +0000599 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600
601 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000602 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603
Greg Clayton4ceb9982010-07-21 22:54:26 +0000604 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605 if (section != NULL)
606 {
Greg Clayton47037bc2012-03-27 02:40:46 +0000607 debug_info_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000608
Greg Clayton4ceb9982010-07-21 22:54:26 +0000609 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000611 debug_abbrev_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612
Greg Clayton4ceb9982010-07-21 22:54:26 +0000613 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000614 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000615 debug_line_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000616 }
Greg Clayton6c596612012-05-18 21:47:20 +0000617 else
618 {
619 const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
620 if (symfile_dir_cstr)
621 {
622 if (strcasestr(symfile_dir_cstr, ".dsym"))
623 {
624 if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
625 {
626 // We have a dSYM file that didn't have a any debug info.
627 // If the string table has a size of 1, then it was made from
628 // an executable with no debug info, or from an executable that
629 // was stripped.
630 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
631 if (section && section->GetFileSize() == 1)
632 {
633 m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
634 }
635 }
636 }
637 }
638 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639
640 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
641 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
642
643 if (debug_line_file_size > 0)
644 abilities |= LineTables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645 }
646 return abilities;
647}
648
Ed Masteeeae7212013-10-24 20:43:47 +0000649const DWARFDataExtractor&
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000650SymbolFileDWARF::GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000651{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000652 std::call_once(data_segment.m_flag,
653 &SymbolFileDWARF::LoadSectionData,
654 this,
655 sect_type,
656 std::ref(data_segment.m_data));
657 return data_segment.m_data;
658}
659
660void
661SymbolFileDWARF::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data)
662{
663 ModuleSP module_sp (m_obj_file->GetModule());
664 const SectionList *section_list = module_sp->GetSectionList();
665 if (section_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000667 SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
668 if (section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000669 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000670 // See if we memory mapped the DWARF segment?
671 if (m_dwarf_data.GetByteSize())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672 {
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000673 data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize());
674 }
675 else
676 {
677 if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
678 data.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679 }
680 }
681 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000682}
683
Ed Masteeeae7212013-10-24 20:43:47 +0000684const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000685SymbolFileDWARF::get_debug_abbrev_data()
686{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000687 return GetCachedSectionData (eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688}
689
Ed Masteeeae7212013-10-24 20:43:47 +0000690const DWARFDataExtractor&
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000691SymbolFileDWARF::get_debug_addr_data()
692{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000693 return GetCachedSectionData (eSectionTypeDWARFDebugAddr, m_data_debug_addr);
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000694}
695
696const DWARFDataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000697SymbolFileDWARF::get_debug_aranges_data()
698{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000699 return GetCachedSectionData (eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
Greg Claytond4a2b372011-09-12 23:21:58 +0000700}
701
Ed Masteeeae7212013-10-24 20:43:47 +0000702const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703SymbolFileDWARF::get_debug_frame_data()
704{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000705 return GetCachedSectionData (eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000706}
707
Ed Masteeeae7212013-10-24 20:43:47 +0000708const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000709SymbolFileDWARF::get_debug_info_data()
710{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000711 return GetCachedSectionData (eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000712}
713
Ed Masteeeae7212013-10-24 20:43:47 +0000714const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000715SymbolFileDWARF::get_debug_line_data()
716{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000717 return GetCachedSectionData (eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718}
719
Ed Masteeeae7212013-10-24 20:43:47 +0000720const DWARFDataExtractor&
Siva Chandrad8335e92015-12-16 00:22:08 +0000721SymbolFileDWARF::get_debug_macro_data()
722{
723 return GetCachedSectionData (eSectionTypeDWARFDebugMacro, m_data_debug_macro);
724}
725
726const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727SymbolFileDWARF::get_debug_loc_data()
728{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000729 return GetCachedSectionData (eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000730}
731
Ed Masteeeae7212013-10-24 20:43:47 +0000732const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733SymbolFileDWARF::get_debug_ranges_data()
734{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000735 return GetCachedSectionData (eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000736}
737
Ed Masteeeae7212013-10-24 20:43:47 +0000738const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739SymbolFileDWARF::get_debug_str_data()
740{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000741 return GetCachedSectionData (eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000742}
743
Ed Masteeeae7212013-10-24 20:43:47 +0000744const DWARFDataExtractor&
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000745SymbolFileDWARF::get_debug_str_offsets_data()
746{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000747 return GetCachedSectionData (eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets);
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000748}
749
750const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000751SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000752{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000753 return GetCachedSectionData (eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000754}
755
Ed Masteeeae7212013-10-24 20:43:47 +0000756const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000757SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000758{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000759 return GetCachedSectionData (eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000760}
761
Ed Masteeeae7212013-10-24 20:43:47 +0000762const DWARFDataExtractor&
Greg Clayton7f995132011-10-04 22:41:51 +0000763SymbolFileDWARF::get_apple_namespaces_data()
764{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000765 return GetCachedSectionData (eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000766}
767
Ed Masteeeae7212013-10-24 20:43:47 +0000768const DWARFDataExtractor&
Greg Clayton5009f9d2011-10-27 17:55:14 +0000769SymbolFileDWARF::get_apple_objc_data()
770{
Tamas Berghammer90b4dce2015-10-22 11:14:37 +0000771 return GetCachedSectionData (eSectionTypeDWARFAppleObjC, m_data_apple_objc);
Greg Clayton7f995132011-10-04 22:41:51 +0000772}
773
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774
775DWARFDebugAbbrev*
776SymbolFileDWARF::DebugAbbrev()
777{
778 if (m_abbr.get() == NULL)
779 {
Ed Masteeeae7212013-10-24 20:43:47 +0000780 const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000781 if (debug_abbrev_data.GetByteSize() > 0)
782 {
783 m_abbr.reset(new DWARFDebugAbbrev());
784 if (m_abbr.get())
785 m_abbr->Parse(debug_abbrev_data);
786 }
787 }
788 return m_abbr.get();
789}
790
791const DWARFDebugAbbrev*
792SymbolFileDWARF::DebugAbbrev() const
793{
794 return m_abbr.get();
795}
796
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000797
798DWARFDebugInfo*
799SymbolFileDWARF::DebugInfo()
800{
801 if (m_info.get() == NULL)
802 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000803 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
804 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000805 if (get_debug_info_data().GetByteSize() > 0)
806 {
807 m_info.reset(new DWARFDebugInfo());
808 if (m_info.get())
809 {
810 m_info->SetDwarfData(this);
811 }
812 }
813 }
814 return m_info.get();
815}
816
817const DWARFDebugInfo*
818SymbolFileDWARF::DebugInfo() const
819{
820 return m_info.get();
821}
822
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823DWARFCompileUnit*
Greg Clayton1f746072012-08-29 21:13:06 +0000824SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825{
Greg Claytonea4a5bb2015-09-04 22:29:46 +0000826 if (!comp_unit)
827 return nullptr;
828
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 DWARFDebugInfo* info = DebugInfo();
Greg Clayton1f746072012-08-29 21:13:06 +0000830 if (info)
831 {
Greg Clayton2f869fe2016-03-30 20:14:35 +0000832 // 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 Clayton2f869fe2016-03-30 20:14:35 +0000835 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
836 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
837 dwarf_cu->SetUserData(comp_unit);
838 return dwarf_cu;
Greg Clayton1f746072012-08-29 21:13:06 +0000839 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840 return NULL;
841}
842
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000843
844DWARFDebugRanges*
845SymbolFileDWARF::DebugRanges()
846{
847 if (m_ranges.get() == NULL)
848 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000849 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
850 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851 if (get_debug_ranges_data().GetByteSize() > 0)
852 {
853 m_ranges.reset(new DWARFDebugRanges());
854 if (m_ranges.get())
855 m_ranges->Extract(this);
856 }
857 }
858 return m_ranges.get();
859}
860
861const DWARFDebugRanges*
862SymbolFileDWARF::DebugRanges() const
863{
864 return m_ranges.get();
865}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866
Greg Clayton53eb1c22012-04-02 22:59:12 +0000867lldb::CompUnitSP
868SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000869{
Greg Clayton53eb1c22012-04-02 22:59:12 +0000870 CompUnitSP cu_sp;
871 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000872 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000873 CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
874 if (comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000875 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000876 // We already parsed this compile unit, had out a shared pointer to it
877 cu_sp = comp_unit->shared_from_this();
878 }
879 else
880 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000881 if (dwarf_cu->GetSymbolFileDWARF() != this)
882 {
883 return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
884 }
Greg Clayton2f869fe2016-03-30 20:14:35 +0000885 else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000886 {
Greg Clayton1f746072012-08-29 21:13:06 +0000887 // Let the debug map create the compile unit
888 cu_sp = m_debug_map_symfile->GetCompileUnit(this);
889 dwarf_cu->SetUserData(cu_sp.get());
890 }
891 else
892 {
893 ModuleSP module_sp (m_obj_file->GetModule());
894 if (module_sp)
Greg Clayton53eb1c22012-04-02 22:59:12 +0000895 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000896 const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
Greg Clayton1f746072012-08-29 21:13:06 +0000897 if (cu_die)
Greg Clayton53eb1c22012-04-02 22:59:12 +0000898 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000899 FileSpec cu_file_spec{cu_die.GetName(), false};
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000900 if (cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +0000901 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000902 // If we have a full path to the compile unit, we don't need to resolve
903 // the file. This can be expensive e.g. when the source files are NFS mounted.
Chaoren Lin372e9062015-06-09 17:54:27 +0000904 if (cu_file_spec.IsRelative())
Greg Clayton53eb1c22012-04-02 22:59:12 +0000905 {
Greg Clayton5ce1a842015-08-27 18:09:44 +0000906 const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000907 cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
Greg Clayton1f746072012-08-29 21:13:06 +0000908 }
909
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000910 std::string remapped_file;
911 if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
912 cu_file_spec.SetFile(remapped_file, false);
David Srbeckyd515e942015-07-08 14:00:04 +0000913 }
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000914
Greg Clayton5ce1a842015-08-27 18:09:44 +0000915 LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
Chaoren Lin0c5a9c12015-06-05 00:28:06 +0000916
Jason Molendac7099582015-07-31 05:47:00 +0000917 bool is_optimized = dwarf_cu->GetIsOptimized ();
David Srbeckyd515e942015-07-08 14:00:04 +0000918 cu_sp.reset(new CompileUnit (module_sp,
919 dwarf_cu,
920 cu_file_spec,
Greg Clayton6071e6f2015-08-26 22:57:51 +0000921 dwarf_cu->GetID(),
Jason Molenda6ab659a2015-07-29 00:42:47 +0000922 cu_language,
923 is_optimized));
David Srbeckyd515e942015-07-08 14:00:04 +0000924 if (cu_sp)
925 {
926 // If we just created a compile unit with an invalid file spec, try and get the
927 // first entry in the supports files from the line table as that should be the
928 // compile unit.
929 if (!cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +0000930 {
David Srbeckyd515e942015-07-08 14:00:04 +0000931 cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
932 if (cu_file_spec)
933 {
934 (FileSpec &)(*cu_sp) = cu_file_spec;
935 // Also fix the invalid file spec which was copied from the compile unit.
936 cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
937 }
Greg Clayton53eb1c22012-04-02 22:59:12 +0000938 }
David Srbeckyd515e942015-07-08 14:00:04 +0000939
940 dwarf_cu->SetUserData(cu_sp.get());
941
942 // Figure out the compile unit index if we weren't given one
943 if (cu_idx == UINT32_MAX)
944 DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
945
946 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
Greg Clayton53eb1c22012-04-02 22:59:12 +0000947 }
948 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949 }
950 }
951 }
952 }
Greg Clayton53eb1c22012-04-02 22:59:12 +0000953 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954}
955
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956uint32_t
957SymbolFileDWARF::GetNumCompileUnits()
958{
959 DWARFDebugInfo* info = DebugInfo();
960 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962 return 0;
963}
964
965CompUnitSP
966SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
967{
Greg Clayton53eb1c22012-04-02 22:59:12 +0000968 CompUnitSP cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000969 DWARFDebugInfo* info = DebugInfo();
970 if (info)
971 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000972 DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
973 if (dwarf_cu)
974 cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000975 }
Greg Clayton53eb1c22012-04-02 22:59:12 +0000976 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977}
978
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000979Function *
Greg Clayton6071e6f2015-08-26 22:57:51 +0000980SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981{
Greg Clayton6071e6f2015-08-26 22:57:51 +0000982 if (die.IsValid())
983 {
984 TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000985
Greg Clayton6071e6f2015-08-26 22:57:51 +0000986 if (type_system)
987 {
Greg Clayton261ac3f2015-08-28 01:01:03 +0000988 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
989 if (dwarf_ast)
990 return dwarf_ast->ParseFunctionFromDWARF(sc, die);
Greg Clayton6071e6f2015-08-26 22:57:51 +0000991 }
992 }
993 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000994}
995
Greg Clayton9422dd62013-03-04 21:46:16 +0000996bool
997SymbolFileDWARF::FixupAddress (Address &addr)
998{
Greg Clayton2f869fe2016-03-30 20:14:35 +0000999 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile();
Greg Clayton9422dd62013-03-04 21:46:16 +00001000 if (debug_map_symfile)
1001 {
1002 return debug_map_symfile->LinkOSOAddress(addr);
1003 }
1004 // This is a normal DWARF file, no address fixups need to happen
1005 return true;
1006}
Greg Clayton1f746072012-08-29 21:13:06 +00001007lldb::LanguageType
1008SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
1009{
1010 assert (sc.comp_unit);
1011 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1012 if (dwarf_cu)
Greg Clayton5ce1a842015-08-27 18:09:44 +00001013 return dwarf_cu->GetLanguageType();
1014 else
1015 return eLanguageTypeUnknown;
Greg Clayton1f746072012-08-29 21:13:06 +00001016}
1017
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001018size_t
1019SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
1020{
1021 assert (sc.comp_unit);
1022 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00001023 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001024 if (dwarf_cu)
1025 {
1026 DWARFDIECollection function_dies;
Greg Clayton1f746072012-08-29 21:13:06 +00001027 const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001028 size_t func_idx;
Greg Clayton1f746072012-08-29 21:13:06 +00001029 for (func_idx = 0; func_idx < num_functions; ++func_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001031 DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
1032 if (sc.comp_unit->FindFunctionByUID (die.GetID()).get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001034 if (ParseCompileUnitFunction(sc, die))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001035 ++functions_added;
1036 }
1037 }
1038 //FixupTypes();
1039 }
1040 return functions_added;
1041}
1042
1043bool
1044SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
1045{
1046 assert (sc.comp_unit);
Greg Clayton1f746072012-08-29 21:13:06 +00001047 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Greg Claytonda2455b2012-11-01 17:28:37 +00001048 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001050 const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051
Greg Claytonda2455b2012-11-01 17:28:37 +00001052 if (cu_die)
1053 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001054 const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
Greg Clayton5ce1a842015-08-27 18:09:44 +00001055 const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
Tamas Berghammer1966ac32016-01-11 14:56:05 +00001056 if (stmt_list != DW_INVALID_OFFSET)
1057 {
1058 // All file indexes in DWARF are one based and a file of index zero is
1059 // supposed to be the compile unit itself.
1060 support_files.Append (*sc.comp_unit);
1061 return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(),
1062 get_debug_line_data(),
1063 cu_comp_dir,
1064 stmt_list,
1065 support_files);
1066 }
Greg Claytonda2455b2012-11-01 17:28:37 +00001067 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068 }
1069 return false;
1070}
1071
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001072bool
1073SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
1074{
1075 assert (sc.comp_unit);
1076 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1077 if (dwarf_cu)
1078 {
1079 if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
1080 {
1081 UpdateExternalModuleListIfNeeded();
Sean Callananb0300a42016-01-14 21:46:09 +00001082
1083 if (sc.comp_unit)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001084 {
Sean Callananb0300a42016-01-14 21:46:09 +00001085 const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
1086
1087 if (die)
1088 {
1089 for (DWARFDIE child_die = die.GetFirstChild();
1090 child_die;
1091 child_die = child_die.GetSibling())
1092 {
1093 if (child_die.Tag() == DW_TAG_imported_declaration)
1094 {
1095 if (DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import))
1096 {
1097 if (module_die.Tag() == DW_TAG_module)
1098 {
1099 if (const char *name = module_die.GetAttributeValueAsString(DW_AT_name, nullptr))
1100 {
1101 ConstString const_name(name);
1102 imported_modules.push_back(const_name);
1103 }
1104 }
1105 }
1106 }
1107 }
1108 }
1109 }
1110 else
1111 {
1112 for (const auto &pair : m_external_type_modules)
1113 {
1114 imported_modules.push_back(pair.first);
1115 }
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001116 }
1117 }
1118 }
1119 return false;
1120}
1121
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001122struct ParseDWARFLineTableCallbackInfo
1123{
1124 LineTable* line_table;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001125 std::unique_ptr<LineSequence> sequence_ap;
Jaydeep Patil44d07fc2015-09-22 06:36:56 +00001126 lldb::addr_t addr_mask;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127};
1128
1129//----------------------------------------------------------------------
1130// ParseStatementTableCallback
1131//----------------------------------------------------------------------
1132static void
1133ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1134{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1136 {
1137 // Just started parsing the line table
1138 }
1139 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1140 {
1141 // Done parsing line table, nothing to do for the cleanup
1142 }
1143 else
1144 {
1145 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
Greg Clayton9422dd62013-03-04 21:46:16 +00001146 LineTable* line_table = info->line_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147
Greg Clayton9422dd62013-03-04 21:46:16 +00001148 // If this is our first time here, we need to create a
1149 // sequence container.
1150 if (!info->sequence_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001151 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001152 info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
1153 assert(info->sequence_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001154 }
Greg Clayton9422dd62013-03-04 21:46:16 +00001155 line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
Jaydeep Patil44d07fc2015-09-22 06:36:56 +00001156 state.address & info->addr_mask,
Greg Clayton9422dd62013-03-04 21:46:16 +00001157 state.line,
1158 state.column,
1159 state.file,
1160 state.is_stmt,
1161 state.basic_block,
1162 state.prologue_end,
1163 state.epilogue_begin,
1164 state.end_sequence);
1165 if (state.end_sequence)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001167 // First, put the current sequence into the line table.
1168 line_table->InsertSequence(info->sequence_ap.get());
1169 // Then, empty it to prepare for the next sequence.
1170 info->sequence_ap->Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001171 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 }
1173}
1174
1175bool
1176SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1177{
1178 assert (sc.comp_unit);
1179 if (sc.comp_unit->GetLineTable() != NULL)
1180 return true;
1181
Greg Clayton1f746072012-08-29 21:13:06 +00001182 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001183 if (dwarf_cu)
1184 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001185 const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Greg Clayton129d12c2011-11-28 03:29:03 +00001186 if (dwarf_cu_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001187 {
Greg Clayton5ce1a842015-08-27 18:09:44 +00001188 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 +00001189 if (cu_line_offset != DW_INVALID_OFFSET)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001190 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001191 std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
Greg Clayton129d12c2011-11-28 03:29:03 +00001192 if (line_table_ap.get())
1193 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001194 ParseDWARFLineTableCallbackInfo info;
1195 info.line_table = line_table_ap.get();
Jaydeep Patil44d07fc2015-09-22 06:36:56 +00001196
1197 /*
1198 * MIPS:
1199 * The SymbolContext may not have a valid target, thus we may not be able
1200 * to call Address::GetOpcodeLoadAddress() which would clear the bit #0
1201 * for MIPS. Use ArchSpec to clear the bit #0.
1202 */
1203 ArchSpec arch;
1204 GetObjectFile()->GetArchitecture(arch);
1205 switch (arch.GetMachine())
1206 {
1207 case llvm::Triple::mips:
1208 case llvm::Triple::mipsel:
1209 case llvm::Triple::mips64:
1210 case llvm::Triple::mips64el:
1211 info.addr_mask = ~((lldb::addr_t)1);
1212 break;
1213 default:
1214 info.addr_mask = ~((lldb::addr_t)0);
1215 break;
1216 }
1217
Greg Claytonc7bece562013-01-25 18:06:21 +00001218 lldb::offset_t offset = cu_line_offset;
Greg Clayton129d12c2011-11-28 03:29:03 +00001219 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
Greg Clayton2f869fe2016-03-30 20:14:35 +00001220 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
1221 if (debug_map_symfile)
Greg Clayton9422dd62013-03-04 21:46:16 +00001222 {
1223 // We have an object file that has a line table with addresses
1224 // that are not linked. We need to link the line table and convert
1225 // the addresses that are relative to the .o file into addresses
1226 // for the main executable.
Greg Clayton2f869fe2016-03-30 20:14:35 +00001227 sc.comp_unit->SetLineTable (debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
Greg Clayton9422dd62013-03-04 21:46:16 +00001228 }
1229 else
1230 {
1231 sc.comp_unit->SetLineTable(line_table_ap.release());
1232 return true;
1233 }
Greg Clayton129d12c2011-11-28 03:29:03 +00001234 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001235 }
1236 }
1237 }
1238 return false;
1239}
1240
Siva Chandrad8335e92015-12-16 00:22:08 +00001241lldb_private::DebugMacrosSP
1242SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset)
1243{
1244 auto iter = m_debug_macros_map.find(*offset);
1245 if (iter != m_debug_macros_map.end())
1246 return iter->second;
1247
1248 const DWARFDataExtractor &debug_macro_data = get_debug_macro_data();
1249 if (debug_macro_data.GetByteSize() == 0)
1250 return DebugMacrosSP();
1251
1252 lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());
1253 m_debug_macros_map[*offset] = debug_macros_sp;
1254
1255 const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
1256 DWARFDebugMacroEntry::ReadMacroEntries(
1257 debug_macro_data, get_debug_str_data(), header.OffsetIs64Bit(), offset, this, debug_macros_sp);
1258
1259 return debug_macros_sp;
1260}
1261
1262bool
1263SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext& sc)
1264{
1265 assert (sc.comp_unit);
1266
1267 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1268 if (dwarf_cu == nullptr)
1269 return false;
1270
1271 const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1272 if (!dwarf_cu_die)
1273 return false;
1274
1275 lldb::offset_t sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
1276 if (sect_offset == DW_INVALID_OFFSET)
1277 sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros, DW_INVALID_OFFSET);
1278 if (sect_offset == DW_INVALID_OFFSET)
1279 return false;
1280
1281 sc.comp_unit->SetDebugMacros(ParseDebugMacros(&sect_offset));
1282
1283 return true;
1284}
1285
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001286size_t
Greg Clayton6071e6f2015-08-26 22:57:51 +00001287SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc,
1288 Block *parent_block,
1289 const DWARFDIE &orig_die,
1290 addr_t subprogram_low_pc,
1291 uint32_t depth)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001292{
1293 size_t blocks_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001294 DWARFDIE die = orig_die;
1295 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001297 dw_tag_t tag = die.Tag();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001298
1299 switch (tag)
1300 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001301 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001302 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001303 case DW_TAG_lexical_block:
1304 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001305 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001306 if (tag == DW_TAG_subprogram)
1307 {
1308 // Skip any DW_TAG_subprogram DIEs that are inside
1309 // of a normal or inlined functions. These will be
1310 // parsed on their own as separate entities.
1311
1312 if (depth > 0)
1313 break;
1314
1315 block = parent_block;
1316 }
1317 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001318 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001319 BlockSP block_sp(new Block (die.GetID()));
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001320 parent_block->AddChild(block_sp);
1321 block = block_sp.get();
1322 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001323 DWARFRangeList ranges;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001324 const char *name = NULL;
1325 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001326
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001327 int decl_file = 0;
1328 int decl_line = 0;
1329 int decl_column = 0;
1330 int call_file = 0;
1331 int call_line = 0;
1332 int call_column = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001333 if (die.GetDIENamesAndRanges (name,
1334 mangled_name,
1335 ranges,
1336 decl_file, decl_line, decl_column,
1337 call_file, call_line, call_column, nullptr))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001338 {
1339 if (tag == DW_TAG_subprogram)
1340 {
1341 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
Greg Claytonea3e7d52011-10-08 00:49:15 +00001342 subprogram_low_pc = ranges.GetMinRangeBase(0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001343 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001344 else if (tag == DW_TAG_inlined_subroutine)
1345 {
1346 // We get called here for inlined subroutines in two ways.
1347 // The first time is when we are making the Function object
1348 // for this inlined concrete instance. Since we're creating a top level block at
1349 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1350 // adjust the containing address.
1351 // The second time is when we are parsing the blocks inside the function that contains
1352 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1353 // function the offset will be for that function.
1354 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1355 {
Greg Claytonea3e7d52011-10-08 00:49:15 +00001356 subprogram_low_pc = ranges.GetMinRangeBase(0);
Jim Inghamb0be4422010-08-12 01:20:14 +00001357 }
1358 }
Greg Clayton103f3092015-01-15 03:04:37 +00001359
1360 const size_t num_ranges = ranges.GetSize();
1361 for (size_t i = 0; i<num_ranges; ++i)
1362 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001363 const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
Greg Clayton103f3092015-01-15 03:04:37 +00001364 const addr_t range_base = range.GetRangeBase();
1365 if (range_base >= subprogram_low_pc)
1366 block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
1367 else
1368 {
1369 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",
1370 block->GetID(),
1371 range_base,
1372 range.GetRangeEnd(),
1373 subprogram_low_pc);
1374 }
1375 }
1376 block->FinalizeRanges ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001377
1378 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1379 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001380 std::unique_ptr<Declaration> decl_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001381 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001382 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1383 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001384
Greg Clayton7b0992d2013-04-18 22:45:39 +00001385 std::unique_ptr<Declaration> call_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001386 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001387 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1388 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001389
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001390 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001391 }
1392
1393 ++blocks_added;
1394
Greg Clayton6071e6f2015-08-26 22:57:51 +00001395 if (die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001396 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001397 blocks_added += ParseFunctionBlocks (sc,
1398 block,
Greg Clayton6071e6f2015-08-26 22:57:51 +00001399 die.GetFirstChild(),
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001400 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001401 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001402 }
1403 }
1404 }
1405 break;
1406 default:
1407 break;
1408 }
1409
Greg Claytondd7feaf2011-08-12 17:54:33 +00001410 // Only parse siblings of the block if we are not at depth zero. A depth
1411 // of zero indicates we are currently parsing the top level
1412 // DW_TAG_subprogram DIE
1413
1414 if (depth == 0)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001415 die.Clear();
Greg Claytondd7feaf2011-08-12 17:54:33 +00001416 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00001417 die = die.GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001418 }
1419 return blocks_added;
1420}
1421
Greg Claytonf0705c82011-10-22 03:33:13 +00001422bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00001423SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
Greg Claytonc4ffd662013-03-08 01:37:30 +00001424{
1425 if (parent_die)
1426 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001427 for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling())
Greg Claytonc4ffd662013-03-08 01:37:30 +00001428 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001429 dw_tag_t tag = die.Tag();
Greg Claytonc4ffd662013-03-08 01:37:30 +00001430 bool check_virtuality = false;
1431 switch (tag)
1432 {
1433 case DW_TAG_inheritance:
1434 case DW_TAG_subprogram:
1435 check_virtuality = true;
1436 break;
1437 default:
1438 break;
1439 }
1440 if (check_virtuality)
1441 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001442 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
Greg Claytonc4ffd662013-03-08 01:37:30 +00001443 return true;
1444 }
1445 }
1446 }
1447 return false;
1448}
1449
Paul Hermanea188fc2015-09-16 18:48:30 +00001450void
1451SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
1452{
1453 TypeSystem *type_system = decl_ctx.GetTypeSystem();
1454 DWARFASTParser *ast_parser = type_system->GetDWARFParser();
1455 std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx);
1456
1457 for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
1458 for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling())
1459 ast_parser->GetDeclForUIDFromDWARF(decl);
1460}
1461
Paul Hermand628cbb2015-09-15 23:44:17 +00001462CompilerDecl
1463SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
1464{
Greg Clayton2f869fe2016-03-30 20:14:35 +00001465 DWARFDIE die = GetDIE(DIERef(type_uid, this));
1466 if (die)
1467 return die.GetDecl();
Paul Hermand628cbb2015-09-15 23:44:17 +00001468 return CompilerDecl();
1469}
1470
Greg Clayton99558cc42015-08-24 23:46:31 +00001471CompilerDeclContext
1472SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001473{
Greg Clayton2f869fe2016-03-30 20:14:35 +00001474 DWARFDIE die = GetDIE(DIERef(type_uid, this));
1475 if (die)
1476 return die.GetDeclContext();
Greg Clayton99558cc42015-08-24 23:46:31 +00001477 return CompilerDeclContext();
Sean Callanan72e49402011-08-05 23:43:37 +00001478}
1479
Greg Clayton99558cc42015-08-24 23:46:31 +00001480CompilerDeclContext
1481SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
Sean Callanan72e49402011-08-05 23:43:37 +00001482{
Greg Clayton2f869fe2016-03-30 20:14:35 +00001483 DWARFDIE die = GetDIE (DIERef(type_uid, this));
1484 if (die)
1485 return die.GetContainingDeclContext();
Greg Clayton99558cc42015-08-24 23:46:31 +00001486 return CompilerDeclContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001487}
1488
Greg Clayton99558cc42015-08-24 23:46:31 +00001489
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001490Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001491SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001492{
Greg Clayton2f869fe2016-03-30 20:14:35 +00001493 DWARFDIE type_die = GetDIE (DIERef(type_uid, this));
1494 if (type_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001495 {
Greg Clayton2f869fe2016-03-30 20:14:35 +00001496 const bool assert_not_being_parsed = true;
1497 return ResolveTypeUID (type_die, assert_not_being_parsed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001498 }
1499 return NULL;
1500}
1501
Greg Claytoncab36a32011-12-08 05:16:30 +00001502Type*
Greg Clayton2f869fe2016-03-30 20:14:35 +00001503SymbolFileDWARF::ResolveTypeUID (const DIERef &die_ref)
1504{
1505 return ResolveType (GetDIE(die_ref), true);
1506}
1507
1508Type*
Greg Clayton6071e6f2015-08-26 22:57:51 +00001509SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed)
Sean Callanan5b26f272012-02-04 08:49:35 +00001510{
Greg Clayton6071e6f2015-08-26 22:57:51 +00001511 if (die)
Greg Claytoncab36a32011-12-08 05:16:30 +00001512 {
Greg Clayton5160ce52013-03-27 23:08:40 +00001513 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00001514 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001515 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00001516 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
Greg Clayton6071e6f2015-08-26 22:57:51 +00001517 die.GetOffset(),
1518 die.GetTagAsCString(),
1519 die.GetName());
Greg Clayton3bffb082011-12-10 02:15:28 +00001520
Greg Claytoncab36a32011-12-08 05:16:30 +00001521 // We might be coming in in the middle of a type tree (a class
1522 // withing a class, an enum within a class), so parse any needed
1523 // parent DIEs before we get to this one...
Greg Clayton6071e6f2015-08-26 22:57:51 +00001524 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die);
1525 if (decl_ctx_die)
Greg Claytoncab36a32011-12-08 05:16:30 +00001526 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001527 if (log)
Greg Claytoncab36a32011-12-08 05:16:30 +00001528 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001529 switch (decl_ctx_die.Tag())
1530 {
1531 case DW_TAG_structure_type:
1532 case DW_TAG_union_type:
1533 case DW_TAG_class_type:
1534 {
1535 // Get the type, which could be a forward declaration
1536 if (log)
1537 GetObjectFile()->GetModule()->LogMessage (log,
1538 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
1539 die.GetOffset(),
1540 die.GetTagAsCString(),
1541 die.GetName(),
1542 decl_ctx_die.GetOffset());
1543 }
1544 break;
Greg Claytoncab36a32011-12-08 05:16:30 +00001545
Greg Clayton6071e6f2015-08-26 22:57:51 +00001546 default:
1547 break;
1548 }
1549 }
Greg Claytoncab36a32011-12-08 05:16:30 +00001550 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001551 return ResolveType (die);
Greg Claytoncab36a32011-12-08 05:16:30 +00001552 }
1553 return NULL;
1554}
1555
Greg Clayton6beaaa62011-01-17 03:46:26 +00001556// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1557// SymbolFileDWARF objects to detect if this DWARF file is the one that
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001558// can resolve a compiler_type.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001559bool
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001560SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001561{
Zachary Turnerd133f6a2016-03-28 22:53:41 +00001562 CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
Greg Claytone6b36cd2015-12-08 01:02:08 +00001563 if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
1564 {
1565 return true;
1566 }
1567 TypeSystem *type_system = compiler_type.GetTypeSystem();
Zachary Turnerd133f6a2016-03-28 22:53:41 +00001568
1569 ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
1570 if (!clang_type_system)
1571 return false;
1572 DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
1573 return ast_parser->GetClangASTImporter().CanImport(compiler_type);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001574}
1575
1576
Greg Clayton57ee3062013-07-11 22:46:58 +00001577bool
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001578SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001579{
Greg Claytonfb85e622016-02-09 22:36:24 +00001580 lldb_private::Mutex::Locker locker(GetObjectFile()->GetModule()->GetMutex());
1581
Zachary Turnerd133f6a2016-03-28 22:53:41 +00001582 ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
1583 if (clang_type_system)
Greg Claytone6b36cd2015-12-08 01:02:08 +00001584 {
Zachary Turnerd133f6a2016-03-28 22:53:41 +00001585 DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
1586 if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type))
1587 return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
Greg Claytone6b36cd2015-12-08 01:02:08 +00001588 }
1589
Greg Clayton1be10fc2010-09-29 01:12:09 +00001590 // We have a struct/union/class/enum that needs to be fully resolved.
Zachary Turnerd133f6a2016-03-28 22:53:41 +00001591 CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001592 auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001593 if (die_it == GetForwardDeclClangTypeToDie().end())
Greg Clayton73b472d2010-10-27 03:32:59 +00001594 {
1595 // We have already resolved this type...
Greg Clayton57ee3062013-07-11 22:46:58 +00001596 return true;
Greg Clayton73b472d2010-10-27 03:32:59 +00001597 }
Tamas Berghammerf8fd9b52015-09-14 15:44:29 +00001598
Greg Clayton2f869fe2016-03-30 20:14:35 +00001599 DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
1600 if (dwarf_die)
1601 {
1602 // Once we start resolving this type, remove it from the forward declaration
1603 // map in case anyone child members or other types require this type to get resolved.
1604 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1605 // are done.
1606 GetForwardDeclClangTypeToDie().erase (die_it);
Tamas Berghammerf8fd9b52015-09-14 15:44:29 +00001607
Greg Clayton2f869fe2016-03-30 20:14:35 +00001608 Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
Tamas Berghammer69d0b332015-10-09 12:43:08 +00001609
Greg Clayton2f869fe2016-03-30 20:14:35 +00001610 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
1611 if (log)
1612 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
1613 "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
1614 dwarf_die.GetID(),
1615 dwarf_die.GetTagAsCString(),
1616 type->GetName().AsCString());
1617 assert (compiler_type);
1618 DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
1619 if (dwarf_ast)
1620 return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
1621 }
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00001622 return false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001623}
1624
Greg Clayton8b4edba2015-08-14 20:02:05 +00001625Type*
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00001626SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed, bool resolve_function_context)
Greg Clayton8b4edba2015-08-14 20:02:05 +00001627{
Greg Clayton6071e6f2015-08-26 22:57:51 +00001628 if (die)
Greg Clayton8b4edba2015-08-14 20:02:05 +00001629 {
Greg Clayton2f869fe2016-03-30 20:14:35 +00001630 Type *type = GetTypeForDIE (die, resolve_function_context).get();
Greg Claytoncab36a32011-12-08 05:16:30 +00001631
Greg Clayton24739922010-10-13 03:15:28 +00001632 if (assert_not_being_parsed)
Jim Inghamc3549282012-01-11 02:21:12 +00001633 {
1634 if (type != DIE_IS_BEING_PARSED)
1635 return type;
1636
1637 GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
Greg Clayton6071e6f2015-08-26 22:57:51 +00001638 die.GetOffset(),
1639 die.GetTagAsCString(),
1640 die.GetName());
Jim Inghamc3549282012-01-11 02:21:12 +00001641
1642 }
1643 else
1644 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001645 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00001646 return nullptr;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001647}
1648
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001649CompileUnit*
Greg Clayton53eb1c22012-04-02 22:59:12 +00001650SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651{
1652 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton53eb1c22012-04-02 22:59:12 +00001653 if (dwarf_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001654 {
1655 // The symbol vendor doesn't know about this compile unit, we
1656 // need to parse and add it to the symbol vendor object.
Greg Clayton53eb1c22012-04-02 22:59:12 +00001657 return ParseCompileUnit(dwarf_cu, cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001658 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001659 return (CompileUnit*)dwarf_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001660}
1661
Greg Clayton8b4edba2015-08-14 20:02:05 +00001662size_t
1663SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets)
1664{
1665 method_die_offsets.clear();
1666 if (m_using_apple_tables)
1667 {
1668 if (m_apple_objc_ap.get())
1669 m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
1670 }
1671 else
1672 {
1673 if (!m_indexed)
1674 Index ();
1675
1676 m_objc_class_selectors_index.Find (class_name, method_die_offsets);
1677 }
1678 return method_die_offsets.size();
1679}
1680
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001681bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00001682SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001683{
Greg Clayton72310352013-02-23 04:12:47 +00001684 sc.Clear(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001685
Greg Clayton6071e6f2015-08-26 22:57:51 +00001686 if (die)
1687 {
1688 // Check if the symbol vendor already knows about this compile unit?
1689 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
1690
1691 sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get();
1692 if (sc.function == NULL)
1693 sc.function = ParseCompileUnitFunction(sc, die);
1694
1695 if (sc.function)
1696 {
1697 sc.module_sp = sc.function->CalculateSymbolContextModule();
1698 return true;
1699 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00001700 }
1701
1702 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001703}
1704
Greg Claytone6b36cd2015-12-08 01:02:08 +00001705lldb::ModuleSP
1706SymbolFileDWARF::GetDWOModule (ConstString name)
1707{
1708 UpdateExternalModuleListIfNeeded();
1709 const auto &pos = m_external_type_modules.find(name);
1710 if (pos != m_external_type_modules.end())
1711 return pos->second;
1712 else
1713 return lldb::ModuleSP();
1714}
1715
Greg Clayton2f869fe2016-03-30 20:14:35 +00001716DWARFDIE
1717SymbolFileDWARF::GetDIE (const DIERef &die_ref)
1718{
1719 DWARFDebugInfo * debug_info = DebugInfo();
1720 if (debug_info)
1721 return debug_info->GetDIE(die_ref);
1722 else
1723 return DWARFDIE();
1724}
1725
1726
Pavel Labatheb0c5c872016-03-29 13:42:02 +00001727std::unique_ptr<SymbolFileDWARFDwo>
1728SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
1729{
1730 const char *dwo_name = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
1731 if (!dwo_name)
1732 return nullptr;
1733
1734 FileSpec dwo_file(dwo_name, true);
1735 if (dwo_file.IsRelative())
1736 {
1737 const char *comp_dir = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_comp_dir, nullptr);
1738 if (!comp_dir)
1739 return nullptr;
1740
1741 dwo_file.SetFile(comp_dir, true);
1742 dwo_file.AppendPathComponent(dwo_name);
1743 }
1744
1745 if (!dwo_file.Exists())
1746 return nullptr;
1747
1748 const lldb::offset_t file_offset = 0;
1749 DataBufferSP dwo_file_data_sp;
1750 lldb::offset_t dwo_file_data_offset = 0;
1751 ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(GetObjectFile()->GetModule(), &dwo_file, file_offset,
1752 dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset);
1753 if (dwo_obj_file == nullptr)
1754 return nullptr;
1755
1756 return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
1757}
1758
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001759void
1760SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
1761{
1762 if (m_fetched_external_modules)
1763 return;
1764 m_fetched_external_modules = true;
1765
1766 DWARFDebugInfo * debug_info = DebugInfo();
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001767
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001768 const uint32_t num_compile_units = GetNumCompileUnits();
1769 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1770 {
1771 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1772
Greg Clayton5ce1a842015-08-27 18:09:44 +00001773 const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
1774 if (die && die.HasChildren() == false)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001775 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001776 const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
1777
1778 if (name)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001779 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001780 ConstString const_name(name);
1781 if (m_external_type_modules.find(const_name) == m_external_type_modules.end())
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001782 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001783 ModuleSP module_sp;
1784 const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
1785 if (dwo_path)
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001786 {
Greg Claytone6b36cd2015-12-08 01:02:08 +00001787 ModuleSpec dwo_module_spec;
1788 dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
1789 dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
1790 //printf ("Loading dwo = '%s'\n", dwo_path);
1791 Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001792 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00001793 m_external_type_modules[const_name] = module_sp;
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001794 }
1795 }
1796 }
1797 }
1798}
Greg Clayton2501e5e2015-01-15 02:59:20 +00001799
1800SymbolFileDWARF::GlobalVariableMap &
1801SymbolFileDWARF::GetGlobalAranges()
1802{
1803 if (!m_global_aranges_ap)
1804 {
1805 m_global_aranges_ap.reset (new GlobalVariableMap());
1806
1807 ModuleSP module_sp = GetObjectFile()->GetModule();
1808 if (module_sp)
1809 {
1810 const size_t num_cus = module_sp->GetNumCompileUnits();
1811 for (size_t i = 0; i < num_cus; ++i)
1812 {
1813 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
1814 if (cu_sp)
1815 {
1816 VariableListSP globals_sp = cu_sp->GetVariableList(true);
1817 if (globals_sp)
1818 {
1819 const size_t num_globals = globals_sp->GetSize();
1820 for (size_t g = 0; g < num_globals; ++g)
1821 {
1822 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
1823 if (var_sp && !var_sp->GetLocationIsConstantValueData())
1824 {
1825 const DWARFExpression &location = var_sp->LocationExpression();
1826 Value location_result;
1827 Error error;
Tamas Berghammer5b42c7a2016-02-26 14:21:10 +00001828 if (location.Evaluate(nullptr, nullptr, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr, location_result, &error))
Greg Clayton2501e5e2015-01-15 02:59:20 +00001829 {
1830 if (location_result.GetValueType() == Value::eValueTypeFileAddress)
1831 {
1832 lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
1833 lldb::addr_t byte_size = 1;
1834 if (var_sp->GetType())
1835 byte_size = var_sp->GetType()->GetByteSize();
1836 m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
1837 }
1838 }
1839 }
1840 }
1841 }
1842 }
1843 }
1844 }
1845 m_global_aranges_ap->Sort();
1846 }
1847 return *m_global_aranges_ap;
1848}
1849
1850
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001851uint32_t
1852SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1853{
1854 Timer scoped_timer(__PRETTY_FUNCTION__,
Daniel Malead01b2952012-11-29 21:49:15 +00001855 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001856 static_cast<void*>(so_addr.GetSection().get()),
1857 so_addr.GetOffset(), resolve_scope);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001858 uint32_t resolved = 0;
Greg Clayton2501e5e2015-01-15 02:59:20 +00001859 if (resolve_scope & ( eSymbolContextCompUnit |
1860 eSymbolContextFunction |
1861 eSymbolContextBlock |
1862 eSymbolContextLineEntry |
1863 eSymbolContextVariable ))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001864 {
1865 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1866
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001867 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00001868 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001869 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001870 const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Greg Clayton2501e5e2015-01-15 02:59:20 +00001871 if (cu_offset == DW_INVALID_OFFSET)
1872 {
1873 // Global variables are not in the compile unit address ranges. The only way to
1874 // currently find global variables is to iterate over the .debug_pubnames or the
1875 // __apple_names table and find all items in there that point to DW_TAG_variable
1876 // DIEs and then find the address that matches.
1877 if (resolve_scope & eSymbolContextVariable)
1878 {
1879 GlobalVariableMap &map = GetGlobalAranges();
1880 const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
1881 if (entry && entry->data)
1882 {
1883 Variable *variable = entry->data;
1884 SymbolContextScope *scc = variable->GetSymbolContextScope();
1885 if (scc)
1886 {
1887 scc->CalculateSymbolContext(&sc);
1888 sc.variable = variable;
1889 }
1890 return sc.GetResolvedMask();
1891 }
1892 }
1893 }
1894 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001895 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001896 uint32_t cu_idx = DW_INVALID_INDEX;
Greg Clayton6071e6f2015-08-26 22:57:51 +00001897 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx);
Greg Clayton53eb1c22012-04-02 22:59:12 +00001898 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001899 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001900 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001901 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001902 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001903 resolved |= eSymbolContextCompUnit;
1904
Greg Clayton6ab80132012-12-12 17:30:52 +00001905 bool force_check_line_table = false;
Greg Clayton526a4ae2012-05-16 22:09:01 +00001906 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1907 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001908 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
1909 DWARFDIE block_die;
1910 if (function_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001911 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00001912 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
Greg Clayton526a4ae2012-05-16 22:09:01 +00001913 if (sc.function == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00001914 sc.function = ParseCompileUnitFunction(sc, function_die);
1915
1916 if (sc.function && (resolve_scope & eSymbolContextBlock))
1917 block_die = function_die.LookupDeepestBlock(file_vm_addr);
Greg Clayton526a4ae2012-05-16 22:09:01 +00001918 }
1919 else
1920 {
1921 // We might have had a compile unit that had discontiguous
1922 // address ranges where the gaps are symbols that don't have
1923 // any debug info. Discontiguous compile unit address ranges
1924 // should only happen when there aren't other functions from
1925 // other compile units in these gaps. This helps keep the size
1926 // of the aranges down.
Greg Clayton6ab80132012-12-12 17:30:52 +00001927 force_check_line_table = true;
Greg Clayton526a4ae2012-05-16 22:09:01 +00001928 }
1929
1930 if (sc.function != NULL)
1931 {
1932 resolved |= eSymbolContextFunction;
1933
1934 if (resolve_scope & eSymbolContextBlock)
1935 {
1936 Block& block = sc.function->GetBlock (true);
1937
Greg Clayton6071e6f2015-08-26 22:57:51 +00001938 if (block_die)
1939 sc.block = block.FindBlockByID (block_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00001940 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00001941 sc.block = block.FindBlockByID (function_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00001942 if (sc.block)
1943 resolved |= eSymbolContextBlock;
1944 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001945 }
1946 }
Greg Clayton6ab80132012-12-12 17:30:52 +00001947
1948 if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
1949 {
1950 LineTable *line_table = sc.comp_unit->GetLineTable();
1951 if (line_table != NULL)
1952 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001953 // And address that makes it into this function should be in terms
1954 // of this debug file if there is no debug map, or it will be an
1955 // address in the .o file which needs to be fixed up to be in terms
1956 // of the debug map executable. Either way, calling FixupAddress()
1957 // will work for us.
1958 Address exe_so_addr (so_addr);
1959 if (FixupAddress(exe_so_addr))
Greg Clayton6ab80132012-12-12 17:30:52 +00001960 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001961 if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
Greg Clayton6ab80132012-12-12 17:30:52 +00001962 {
1963 resolved |= eSymbolContextLineEntry;
1964 }
1965 }
Greg Clayton6ab80132012-12-12 17:30:52 +00001966 }
1967 }
1968
1969 if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
1970 {
1971 // We might have had a compile unit that had discontiguous
1972 // address ranges where the gaps are symbols that don't have
1973 // any debug info. Discontiguous compile unit address ranges
1974 // should only happen when there aren't other functions from
1975 // other compile units in these gaps. This helps keep the size
1976 // of the aranges down.
1977 sc.comp_unit = NULL;
1978 resolved &= ~eSymbolContextCompUnit;
1979 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001980 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00001981 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001982 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00001983 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
1984 cu_offset,
1985 cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001986 }
1987 }
1988 }
1989 }
1990 }
1991 return resolved;
1992}
1993
1994
1995
1996uint32_t
1997SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1998{
1999 const uint32_t prev_size = sc_list.GetSize();
2000 if (resolve_scope & eSymbolContextCompUnit)
2001 {
2002 DWARFDebugInfo* debug_info = DebugInfo();
2003 if (debug_info)
2004 {
2005 uint32_t cu_idx;
Greg Clayton53eb1c22012-04-02 22:59:12 +00002006 DWARFCompileUnit* dwarf_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002007
Greg Clayton53eb1c22012-04-02 22:59:12 +00002008 for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002009 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00002010 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Sean Callananddd7a2a2013-10-03 22:27:29 +00002011 const bool full_match = (bool)file_spec.GetDirectory();
Greg Clayton1f746072012-08-29 21:13:06 +00002012 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 +00002013 if (check_inlines || file_spec_matches_cu_file_spec)
2014 {
2015 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton53eb1c22012-04-02 22:59:12 +00002016 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00002017 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002018 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00002019 uint32_t file_idx = UINT32_MAX;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002020
Greg Clayton526a4ae2012-05-16 22:09:01 +00002021 // If we are looking for inline functions only and we don't
2022 // find it in the support files, we are done.
2023 if (check_inlines)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002024 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00002025 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
2026 if (file_idx == UINT32_MAX)
2027 continue;
2028 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002029
Greg Clayton526a4ae2012-05-16 22:09:01 +00002030 if (line != 0)
2031 {
2032 LineTable *line_table = sc.comp_unit->GetLineTable();
2033
2034 if (line_table != NULL && line != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002035 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00002036 // We will have already looked up the file index if
2037 // we are searching for inline entries.
2038 if (!check_inlines)
2039 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002040
Greg Clayton526a4ae2012-05-16 22:09:01 +00002041 if (file_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002042 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00002043 uint32_t found_line;
2044 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
2045 found_line = sc.line_entry.line;
2046
2047 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002048 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00002049 sc.function = NULL;
2050 sc.block = NULL;
2051 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002052 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00002053 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
2054 if (file_vm_addr != LLDB_INVALID_ADDRESS)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002055 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002056 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
2057 DWARFDIE block_die;
2058 if (function_die)
Greg Clayton526a4ae2012-05-16 22:09:01 +00002059 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002060 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
Greg Clayton526a4ae2012-05-16 22:09:01 +00002061 if (sc.function == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00002062 sc.function = ParseCompileUnitFunction(sc, function_die);
2063
2064 if (sc.function && (resolve_scope & eSymbolContextBlock))
2065 block_die = function_die.LookupDeepestBlock(file_vm_addr);
Greg Clayton526a4ae2012-05-16 22:09:01 +00002066 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002067
Greg Clayton526a4ae2012-05-16 22:09:01 +00002068 if (sc.function != NULL)
2069 {
2070 Block& block = sc.function->GetBlock (true);
2071
Greg Clayton6071e6f2015-08-26 22:57:51 +00002072 if (block_die)
2073 sc.block = block.FindBlockByID (block_die.GetID());
2074 else if (function_die)
2075 sc.block = block.FindBlockByID (function_die.GetID());
Greg Clayton526a4ae2012-05-16 22:09:01 +00002076 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002077 }
2078 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002079
Greg Clayton526a4ae2012-05-16 22:09:01 +00002080 sc_list.Append(sc);
2081 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
2082 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002083 }
2084 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00002085 else if (file_spec_matches_cu_file_spec && !check_inlines)
2086 {
2087 // only append the context if we aren't looking for inline call sites
2088 // by file and line and if the file spec matches that of the compile unit
2089 sc_list.Append(sc);
2090 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002091 }
2092 else if (file_spec_matches_cu_file_spec && !check_inlines)
2093 {
2094 // only append the context if we aren't looking for inline call sites
2095 // by file and line and if the file spec matches that of the compile unit
2096 sc_list.Append(sc);
2097 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002098
Greg Clayton526a4ae2012-05-16 22:09:01 +00002099 if (!check_inlines)
2100 break;
2101 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002102 }
2103 }
2104 }
2105 }
2106 return sc_list.GetSize() - prev_size;
2107}
2108
2109void
2110SymbolFileDWARF::Index ()
2111{
2112 if (m_indexed)
2113 return;
2114 m_indexed = true;
2115 Timer scoped_timer (__PRETTY_FUNCTION__,
2116 "SymbolFileDWARF::Index (%s)",
Jim Ingham4af59612014-12-19 19:20:44 +00002117 GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002118
2119 DWARFDebugInfo* debug_info = DebugInfo();
2120 if (debug_info)
2121 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002122 const uint32_t num_compile_units = GetNumCompileUnits();
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002123 std::vector<NameToDIE> function_basename_index(num_compile_units);
2124 std::vector<NameToDIE> function_fullname_index(num_compile_units);
2125 std::vector<NameToDIE> function_method_index(num_compile_units);
2126 std::vector<NameToDIE> function_selector_index(num_compile_units);
2127 std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
2128 std::vector<NameToDIE> global_index(num_compile_units);
2129 std::vector<NameToDIE> type_index(num_compile_units);
2130 std::vector<NameToDIE> namespace_index(num_compile_units);
2131
2132 auto parser_fn = [this,
2133 debug_info,
2134 &function_basename_index,
2135 &function_fullname_index,
2136 &function_method_index,
2137 &function_selector_index,
2138 &objc_class_selectors_index,
2139 &global_index,
2140 &type_index,
2141 &namespace_index](uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002142 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00002143 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002144 bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002145
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002146 dwarf_cu->Index(function_basename_index[cu_idx],
2147 function_fullname_index[cu_idx],
2148 function_method_index[cu_idx],
2149 function_selector_index[cu_idx],
2150 objc_class_selectors_index[cu_idx],
2151 global_index[cu_idx],
2152 type_index[cu_idx],
2153 namespace_index[cu_idx]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002154
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002155 // Keep memory down by clearing DIEs if this generate function
2156 // caused them to be parsed
2157 if (clear_dies)
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002158 dwarf_cu->ClearDIEs(true);
2159
2160 return cu_idx;
2161 };
2162
2163 TaskRunner<uint32_t> task_runner;
2164 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2165 task_runner.AddTask(parser_fn, cu_idx);
2166
2167 while (true)
2168 {
2169 std::future<uint32_t> f = task_runner.WaitForNextCompletedTask();
2170 if (!f.valid())
2171 break;
2172 uint32_t cu_idx = f.get();
2173
2174 m_function_basename_index.Append(function_basename_index[cu_idx]);
2175 m_function_fullname_index.Append(function_fullname_index[cu_idx]);
2176 m_function_method_index.Append(function_method_index[cu_idx]);
2177 m_function_selector_index.Append(function_selector_index[cu_idx]);
2178 m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]);
2179 m_global_index.Append(global_index[cu_idx]);
2180 m_type_index.Append(type_index[cu_idx]);
2181 m_namespace_index.Append(namespace_index[cu_idx]);
Tamas Berghammerda4e8ed2015-10-20 15:43:40 +00002182 }
Tamas Berghammer2ff88702015-10-23 10:34:49 +00002183
2184 TaskPool::RunTasks(
2185 [&]() { m_function_basename_index.Finalize(); },
2186 [&]() { m_function_fullname_index.Finalize(); },
2187 [&]() { m_function_method_index.Finalize(); },
2188 [&]() { m_function_selector_index.Finalize(); },
2189 [&]() { m_objc_class_selectors_index.Finalize(); },
2190 [&]() { m_global_index.Finalize(); },
2191 [&]() { m_type_index.Finalize(); },
2192 [&]() { m_namespace_index.Finalize(); });
Greg Claytonc685f8e2010-09-15 04:15:46 +00002193
Greg Clayton24739922010-10-13 03:15:28 +00002194#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00002195 StreamFile s(stdout, false);
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002196 s.Printf ("DWARF index for '%s':",
2197 GetObjectFile()->GetFileSpec().GetPath().c_str());
Greg Claytonba2d22d2010-11-13 22:57:37 +00002198 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
2199 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
2200 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
2201 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
2202 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
2203 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00002204 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Bruce Mitchenere171da52015-07-22 00:16:02 +00002205 s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002206#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002207 }
2208}
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002209
2210bool
Greg Clayton99558cc42015-08-24 23:46:31 +00002211SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx)
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002212{
Greg Clayton99558cc42015-08-24 23:46:31 +00002213 if (decl_ctx == nullptr || !decl_ctx->IsValid())
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002214 {
2215 // Invalid namespace decl which means we aren't matching only things
2216 // in this symbol file, so return true to indicate it matches this
2217 // symbol file.
2218 return true;
2219 }
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002220
Greg Clayton56939cb2015-09-17 22:23:34 +00002221 TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
2222 TypeSystem *type_system = GetTypeSystemForLanguage(decl_ctx_type_system->GetMinimumLanguage(nullptr));
2223 if (decl_ctx_type_system == type_system)
Greg Clayton99558cc42015-08-24 23:46:31 +00002224 return true; // The type systems match, return true
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002225
2226 // The namespace AST was valid, and it does not match...
Greg Clayton5160ce52013-03-27 23:08:40 +00002227 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Sean Callananc41e68b2011-10-13 21:08:11 +00002228
2229 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002230 GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
Sean Callananc41e68b2011-10-13 21:08:11 +00002231
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002232 return false;
2233}
2234
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002235uint32_t
Greg Clayton99558cc42015-08-24 23:46:31 +00002236SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002237{
Greg Clayton5160ce52013-03-27 23:08:40 +00002238 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002239
2240 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002241 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002242 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
Greg Claytone38a5ed2012-01-05 03:57:59 +00002243 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002244 static_cast<const void*>(parent_decl_ctx),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002245 append, max_matches);
2246
Greg Clayton99558cc42015-08-24 23:46:31 +00002247 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00002248 return 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002249
Greg Claytonc685f8e2010-09-15 04:15:46 +00002250 DWARFDebugInfo* info = DebugInfo();
2251 if (info == NULL)
2252 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002253
2254 // If we aren't appending the results to this list, then clear the list
2255 if (!append)
2256 variables.Clear();
2257
2258 // Remember how many variables are in the list before we search in case
2259 // we are appending the results to a variable list.
2260 const uint32_t original_size = variables.GetSize();
2261
Greg Claytond4a2b372011-09-12 23:21:58 +00002262 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002263
Greg Clayton97fbc342011-10-20 22:30:33 +00002264 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002265 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002266 if (m_apple_names_ap.get())
2267 {
2268 const char *name_cstr = name.GetCString();
Jim Inghamfa39bb42014-10-25 00:33:55 +00002269 llvm::StringRef basename;
2270 llvm::StringRef context;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002271
Jim Inghamaa816b82015-09-02 01:59:14 +00002272 if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename))
Jim Inghamfa39bb42014-10-25 00:33:55 +00002273 basename = name_cstr;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002274
Jim Inghamfa39bb42014-10-25 00:33:55 +00002275 m_apple_names_ap->FindByName (basename.data(), die_offsets);
Greg Clayton97fbc342011-10-20 22:30:33 +00002276 }
Greg Clayton7f995132011-10-04 22:41:51 +00002277 }
2278 else
2279 {
2280 // Index the DWARF if we haven't already
2281 if (!m_indexed)
2282 Index ();
2283
2284 m_global_index.Find (name, die_offsets);
2285 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002286
Greg Clayton437a1352012-04-09 22:43:43 +00002287 const size_t num_die_matches = die_offsets.size();
2288 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002289 {
Greg Clayton7f995132011-10-04 22:41:51 +00002290 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00002291 sc.module_sp = m_obj_file->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00002292 assert (sc.module_sp);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002293
Greg Clayton437a1352012-04-09 22:43:43 +00002294 bool done = false;
2295 for (size_t i=0; i<num_die_matches && !done; ++i)
Greg Claytond4a2b372011-09-12 23:21:58 +00002296 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002297 const DIERef& die_ref = die_offsets[i];
Greg Clayton2f869fe2016-03-30 20:14:35 +00002298 DWARFDIE die = GetDIE (die_ref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002299
Greg Clayton95d87902011-11-11 03:16:25 +00002300 if (die)
2301 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002302 switch (die.Tag())
Greg Clayton437a1352012-04-09 22:43:43 +00002303 {
2304 default:
2305 case DW_TAG_subprogram:
2306 case DW_TAG_inlined_subroutine:
2307 case DW_TAG_try_block:
2308 case DW_TAG_catch_block:
2309 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002310
Greg Clayton437a1352012-04-09 22:43:43 +00002311 case DW_TAG_variable:
2312 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002313 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002314
Greg Clayton99558cc42015-08-24 23:46:31 +00002315 if (parent_decl_ctx)
Greg Clayton8b4edba2015-08-14 20:02:05 +00002316 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002317 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2318 if (dwarf_ast)
Greg Clayton99558cc42015-08-24 23:46:31 +00002319 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002320 CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00002321 if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx)
2322 continue;
2323 }
Greg Clayton8b4edba2015-08-14 20:02:05 +00002324 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002325
Greg Clayton6071e6f2015-08-26 22:57:51 +00002326 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002327
Greg Clayton437a1352012-04-09 22:43:43 +00002328 if (variables.GetSize() - original_size >= max_matches)
2329 done = true;
2330 }
2331 break;
2332 }
Greg Clayton95d87902011-11-11 03:16:25 +00002333 }
2334 else
2335 {
2336 if (m_using_apple_tables)
2337 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002338 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 +00002339 die_ref.die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00002340 }
2341 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002342 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002343 }
2344
2345 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00002346 const uint32_t num_matches = variables.GetSize() - original_size;
2347 if (log && num_matches > 0)
2348 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002349 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00002350 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002351 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00002352 static_cast<const void*>(parent_decl_ctx),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002353 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00002354 num_matches);
2355 }
2356 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002357}
2358
2359uint32_t
2360SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2361{
Greg Clayton5160ce52013-03-27 23:08:40 +00002362 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002363
Greg Clayton21f2a492011-10-06 00:09:08 +00002364 if (log)
2365 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002366 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002367 "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002368 regex.GetText(), append,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002369 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00002370 }
2371
Greg Claytonc685f8e2010-09-15 04:15:46 +00002372 DWARFDebugInfo* info = DebugInfo();
2373 if (info == NULL)
2374 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002375
2376 // If we aren't appending the results to this list, then clear the list
2377 if (!append)
2378 variables.Clear();
2379
2380 // Remember how many variables are in the list before we search in case
2381 // we are appending the results to a variable list.
2382 const uint32_t original_size = variables.GetSize();
2383
Greg Clayton7f995132011-10-04 22:41:51 +00002384 DIEArray die_offsets;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002385
Greg Clayton97fbc342011-10-20 22:30:33 +00002386 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002387 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002388 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00002389 {
2390 DWARFMappedHash::DIEInfoArray hash_data_array;
2391 if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2392 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2393 }
Greg Clayton7f995132011-10-04 22:41:51 +00002394 }
2395 else
2396 {
2397 // Index the DWARF if we haven't already
2398 if (!m_indexed)
2399 Index ();
2400
2401 m_global_index.Find (regex, die_offsets);
2402 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002403
Greg Claytonc685f8e2010-09-15 04:15:46 +00002404 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00002405 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002406 assert (sc.module_sp);
2407
Greg Clayton7f995132011-10-04 22:41:51 +00002408 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002409 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002410 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002411 for (size_t i=0; i<num_matches; ++i)
2412 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002413 const DIERef& die_ref = die_offsets[i];
Greg Clayton2f869fe2016-03-30 20:14:35 +00002414 DWARFDIE die = GetDIE (die_ref);
Greg Clayton95d87902011-11-11 03:16:25 +00002415
2416 if (die)
2417 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002418 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002419
Greg Clayton6071e6f2015-08-26 22:57:51 +00002420 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002421
Greg Clayton95d87902011-11-11 03:16:25 +00002422 if (variables.GetSize() - original_size >= max_matches)
2423 break;
2424 }
2425 else
2426 {
2427 if (m_using_apple_tables)
2428 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002429 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 +00002430 die_ref.die_offset, regex.GetText());
Greg Clayton95d87902011-11-11 03:16:25 +00002431 }
2432 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002433 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002434 }
2435
2436 // Return the number of variable that were appended to the list
2437 return variables.GetSize() - original_size;
2438}
2439
Greg Claytonaa044962011-10-13 00:59:38 +00002440
Jim Ingham4cda6e02011-10-07 22:23:45 +00002441bool
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002442SymbolFileDWARF::ResolveFunction (const DIERef& die_ref,
Pavel Labatha73d6572015-03-13 10:22:00 +00002443 bool include_inlines,
Jim Ingham4cda6e02011-10-07 22:23:45 +00002444 SymbolContextList& sc_list)
Greg Clayton9e315582011-09-02 04:03:59 +00002445{
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002446 DWARFDIE die = DebugInfo()->GetDIE (die_ref);
Greg Clayton6071e6f2015-08-26 22:57:51 +00002447 return ResolveFunction (die, include_inlines, sc_list);
Greg Claytonaa044962011-10-13 00:59:38 +00002448}
2449
2450
2451bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00002452SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002453 bool include_inlines,
Greg Claytonaa044962011-10-13 00:59:38 +00002454 SymbolContextList& sc_list)
2455{
Greg Clayton9e315582011-09-02 04:03:59 +00002456 SymbolContext sc;
Greg Claytonaa044962011-10-13 00:59:38 +00002457
Greg Clayton6071e6f2015-08-26 22:57:51 +00002458 if (!orig_die)
Greg Claytonaa044962011-10-13 00:59:38 +00002459 return false;
2460
Jim Ingham4cda6e02011-10-07 22:23:45 +00002461 // If we were passed a die that is not a function, just return false...
Greg Clayton6071e6f2015-08-26 22:57:51 +00002462 if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002463 return false;
Greg Clayton6071e6f2015-08-26 22:57:51 +00002464
2465 DWARFDIE die = orig_die;
2466 DWARFDIE inlined_die;
2467 if (die.Tag() == DW_TAG_inlined_subroutine)
Greg Clayton9e315582011-09-02 04:03:59 +00002468 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002469 inlined_die = die;
Greg Clayton9e315582011-09-02 04:03:59 +00002470
Greg Clayton6071e6f2015-08-26 22:57:51 +00002471 while (1)
Greg Clayton2bc22f82011-09-30 03:20:47 +00002472 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002473 die = die.GetParent();
2474
2475 if (die)
2476 {
2477 if (die.Tag() == DW_TAG_subprogram)
2478 break;
2479 }
2480 else
Jim Ingham4cda6e02011-10-07 22:23:45 +00002481 break;
Greg Clayton9e315582011-09-02 04:03:59 +00002482 }
2483 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00002484 assert (die && die.Tag() == DW_TAG_subprogram);
2485 if (GetFunction (die, sc))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002486 {
2487 Address addr;
2488 // Parse all blocks if needed
2489 if (inlined_die)
2490 {
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002491 Block &function_block = sc.function->GetBlock (true);
Greg Clayton6071e6f2015-08-26 22:57:51 +00002492 sc.block = function_block.FindBlockByID (inlined_die.GetID());
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002493 if (sc.block == NULL)
Greg Clayton6071e6f2015-08-26 22:57:51 +00002494 sc.block = function_block.FindBlockByID (inlined_die.GetOffset());
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00002495 if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002496 addr.Clear();
2497 }
2498 else
2499 {
2500 sc.block = NULL;
2501 addr = sc.function->GetAddressRange().GetBaseAddress();
2502 }
2503
2504 if (addr.IsValid())
2505 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002506 sc_list.Append(sc);
Greg Claytonaa044962011-10-13 00:59:38 +00002507 return true;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002508 }
2509 }
2510
Greg Claytonaa044962011-10-13 00:59:38 +00002511 return false;
Greg Clayton9e315582011-09-02 04:03:59 +00002512}
2513
Greg Clayton7f995132011-10-04 22:41:51 +00002514void
2515SymbolFileDWARF::FindFunctions (const ConstString &name,
2516 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002517 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002518 SymbolContextList& sc_list)
2519{
Greg Claytond4a2b372011-09-12 23:21:58 +00002520 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002521 if (name_to_die.Find (name, die_offsets))
2522 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002523 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002524 }
2525}
2526
2527
2528void
2529SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2530 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00002531 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002532 SymbolContextList& sc_list)
2533{
2534 DIEArray die_offsets;
2535 if (name_to_die.Find (regex, die_offsets))
2536 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002537 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002538 }
2539}
2540
2541
2542void
2543SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2544 const DWARFMappedHash::MemoryTable &memory_table,
Pavel Labatha73d6572015-03-13 10:22:00 +00002545 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002546 SymbolContextList& sc_list)
2547{
2548 DIEArray die_offsets;
Greg Claytond1767f02011-12-08 02:13:16 +00002549 DWARFMappedHash::DIEInfoArray hash_data_array;
2550 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
Greg Clayton7f995132011-10-04 22:41:51 +00002551 {
Greg Claytond1767f02011-12-08 02:13:16 +00002552 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
Pavel Labatha73d6572015-03-13 10:22:00 +00002553 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002554 }
2555}
2556
2557void
2558SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
Pavel Labatha73d6572015-03-13 10:22:00 +00002559 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00002560 SymbolContextList& sc_list)
2561{
2562 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002563 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002564 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002565 for (size_t i=0; i<num_matches; ++i)
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002566 ResolveFunction (die_offsets[i], include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002567 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002568}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002569
Jim Ingham4cda6e02011-10-07 22:23:45 +00002570bool
Greg Clayton99558cc42015-08-24 23:46:31 +00002571SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx,
Greg Clayton6071e6f2015-08-26 22:57:51 +00002572 const DWARFDIE &die)
Greg Clayton99558cc42015-08-24 23:46:31 +00002573{
2574 // If we have no parent decl context to match this DIE matches, and if the parent
2575 // decl context isn't valid, we aren't trying to look for any particular decl
2576 // context so any die matches.
2577 if (decl_ctx == nullptr || !decl_ctx->IsValid())
2578 return true;
2579
Greg Clayton6071e6f2015-08-26 22:57:51 +00002580 if (die)
Greg Clayton99558cc42015-08-24 23:46:31 +00002581 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002582 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
2583 if (dwarf_ast)
Greg Clayton99558cc42015-08-24 23:46:31 +00002584 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00002585 CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00002586 if (actual_decl_ctx)
2587 return actual_decl_ctx == *decl_ctx;
2588 }
2589 }
2590 return false;
2591}
2592
Greg Clayton0c5cd902010-06-28 21:30:43 +00002593uint32_t
Greg Clayton99558cc42015-08-24 23:46:31 +00002594SymbolFileDWARF::FindFunctions (const ConstString &name,
2595 const CompilerDeclContext *parent_decl_ctx,
Sean Callanan9df05fb2012-02-10 22:52:19 +00002596 uint32_t name_type_mask,
2597 bool include_inlines,
Greg Clayton2bc22f82011-09-30 03:20:47 +00002598 bool append,
2599 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00002600{
2601 Timer scoped_timer (__PRETTY_FUNCTION__,
2602 "SymbolFileDWARF::FindFunctions (name = '%s')",
2603 name.AsCString());
2604
Greg Clayton43fe2172013-04-03 02:00:15 +00002605 // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
2606 assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
2607
Greg Clayton5160ce52013-03-27 23:08:40 +00002608 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002609
2610 if (log)
2611 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002612 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002613 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2614 name.GetCString(),
2615 name_type_mask,
2616 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00002617 }
2618
Greg Clayton0c5cd902010-06-28 21:30:43 +00002619 // If we aren't appending the results to this list, then clear the list
2620 if (!append)
2621 sc_list.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00002622
Greg Clayton99558cc42015-08-24 23:46:31 +00002623 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00002624 return 0;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002625
2626 // If name is empty then we won't find anything.
2627 if (name.IsEmpty())
2628 return 0;
Greg Clayton0c5cd902010-06-28 21:30:43 +00002629
2630 // Remember how many sc_list are in the list before we search in case
2631 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00002632
Jim Ingham4cda6e02011-10-07 22:23:45 +00002633 const char *name_cstr = name.GetCString();
Greg Clayton43fe2172013-04-03 02:00:15 +00002634
2635 const uint32_t original_size = sc_list.GetSize();
2636
Jim Ingham4cda6e02011-10-07 22:23:45 +00002637 DWARFDebugInfo* info = DebugInfo();
2638 if (info == NULL)
2639 return 0;
2640
Greg Clayton43fe2172013-04-03 02:00:15 +00002641 std::set<const DWARFDebugInfoEntry *> resolved_dies;
Greg Clayton97fbc342011-10-20 22:30:33 +00002642 if (m_using_apple_tables)
Greg Clayton4d01ace2011-09-29 16:58:15 +00002643 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002644 if (m_apple_names_ap.get())
Jim Ingham4cda6e02011-10-07 22:23:45 +00002645 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002646
2647 DIEArray die_offsets;
2648
2649 uint32_t num_matches = 0;
2650
Greg Clayton43fe2172013-04-03 02:00:15 +00002651 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonaa044962011-10-13 00:59:38 +00002652 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002653 // If they asked for the full name, match what they typed. At some point we may
2654 // want to canonicalize this (strip double spaces, etc. For now, we just add all the
2655 // dies that we find by exact match.
Jim Ingham4cda6e02011-10-07 22:23:45 +00002656 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002657 for (uint32_t i = 0; i < num_matches; i++)
2658 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002659 const DIERef& die_ref = die_offsets[i];
2660 DWARFDIE die = info->GetDIE (die_ref);
Greg Claytonaa044962011-10-13 00:59:38 +00002661 if (die)
2662 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002663 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002664 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002665
Greg Clayton6071e6f2015-08-26 22:57:51 +00002666 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002667 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002668 if (ResolveFunction (die, include_inlines, sc_list))
2669 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002670 }
Greg Claytonaa044962011-10-13 00:59:38 +00002671 }
Greg Clayton95d87902011-11-11 03:16:25 +00002672 else
2673 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002674 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 +00002675 die_ref.die_offset, name_cstr);
Greg Clayton95d87902011-11-11 03:16:25 +00002676 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002677 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002678 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002679
2680 if (name_type_mask & eFunctionNameTypeSelector)
2681 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002682 if (parent_decl_ctx && parent_decl_ctx->IsValid())
Greg Clayton43fe2172013-04-03 02:00:15 +00002683 return 0; // no selectors in namespaces
Greg Clayton97fbc342011-10-20 22:30:33 +00002684
Greg Clayton43fe2172013-04-03 02:00:15 +00002685 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2686 // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
2687 // and if it is an ObjC method name, we're good.
Greg Clayton97fbc342011-10-20 22:30:33 +00002688
Greg Clayton43fe2172013-04-03 02:00:15 +00002689 for (uint32_t i = 0; i < num_matches; i++)
Greg Clayton97fbc342011-10-20 22:30:33 +00002690 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002691 const DIERef& die_ref = die_offsets[i];
2692 DWARFDIE die = info->GetDIE (die_ref);
Greg Clayton43fe2172013-04-03 02:00:15 +00002693 if (die)
Greg Clayton97fbc342011-10-20 22:30:33 +00002694 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002695 const char *die_name = die.GetName();
Jim Inghamaa816b82015-09-02 01:59:14 +00002696 if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
Greg Clayton97fbc342011-10-20 22:30:33 +00002697 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002698 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002699 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002700 if (ResolveFunction (die, include_inlines, sc_list))
2701 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002702 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002703 }
2704 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002705 else
2706 {
2707 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 +00002708 die_ref.die_offset, name_cstr);
Greg Clayton43fe2172013-04-03 02:00:15 +00002709 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002710 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002711 die_offsets.clear();
2712 }
2713
Greg Clayton99558cc42015-08-24 23:46:31 +00002714 if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase)
Greg Clayton43fe2172013-04-03 02:00:15 +00002715 {
2716 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
2717 // extract the base name, look that up, and if there is any other information in the name we were
2718 // passed in we have to post-filter based on that.
2719
2720 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
2721 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2722
2723 for (uint32_t i = 0; i < num_matches; i++)
2724 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002725 const DIERef& die_ref = die_offsets[i];
2726 DWARFDIE die = info->GetDIE (die_ref);
Greg Clayton43fe2172013-04-03 02:00:15 +00002727 if (die)
2728 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002729 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002730 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002731
Greg Clayton43fe2172013-04-03 02:00:15 +00002732
2733 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002734 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00002735 {
2736 bool keep_die = true;
2737 if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
2738 {
2739 // We are looking for either basenames or methods, so we need to
2740 // trim out the ones we won't want by looking at the type
2741 SymbolContext sc;
2742 if (sc_list.GetLastContext(sc))
2743 {
2744 if (sc.block)
2745 {
2746 // We have an inlined function
2747 }
2748 else if (sc.function)
2749 {
2750 Type *type = sc.function->GetType();
2751
Sean Callananc370a8a2013-09-18 22:59:55 +00002752 if (type)
Greg Clayton43fe2172013-04-03 02:00:15 +00002753 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002754 CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID());
2755 if (decl_ctx.IsStructUnionOrClass())
Greg Clayton43fe2172013-04-03 02:00:15 +00002756 {
Sean Callananc370a8a2013-09-18 22:59:55 +00002757 if (name_type_mask & eFunctionNameTypeBase)
2758 {
2759 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2760 keep_die = false;
2761 }
2762 }
2763 else
2764 {
2765 if (name_type_mask & eFunctionNameTypeMethod)
2766 {
2767 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
2768 keep_die = false;
2769 }
Greg Clayton43fe2172013-04-03 02:00:15 +00002770 }
2771 }
2772 else
2773 {
Sean Callananc370a8a2013-09-18 22:59:55 +00002774 GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002775 die_ref.die_offset);
Greg Clayton43fe2172013-04-03 02:00:15 +00002776 }
2777 }
2778 }
2779 }
2780 if (keep_die)
Greg Clayton6071e6f2015-08-26 22:57:51 +00002781 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002782 }
2783 }
2784 else
2785 {
2786 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 +00002787 die_ref.die_offset, name_cstr);
Greg Clayton43fe2172013-04-03 02:00:15 +00002788 }
2789 }
2790 die_offsets.clear();
Jim Ingham4cda6e02011-10-07 22:23:45 +00002791 }
2792 }
Greg Clayton7f995132011-10-04 22:41:51 +00002793 }
2794 else
2795 {
2796
2797 // Index the DWARF if we haven't already
2798 if (!m_indexed)
2799 Index ();
2800
Greg Clayton7f995132011-10-04 22:41:51 +00002801 if (name_type_mask & eFunctionNameTypeFull)
Matt Kopecd6089962013-05-10 17:53:48 +00002802 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002803 FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002804
Ed Mastefc7baa02013-09-09 18:00:45 +00002805 // FIXME Temporary workaround for global/anonymous namespace
Robert Flack5cbd3bf2015-05-13 18:20:02 +00002806 // functions debugging FreeBSD and Linux binaries.
Matt Kopecd6089962013-05-10 17:53:48 +00002807 // If we didn't find any functions in the global namespace try
2808 // looking in the basename index but ignore any returned
Robert Flackeb83fab2015-05-15 18:59:59 +00002809 // functions that have a namespace but keep functions which
2810 // have an anonymous namespace
2811 // TODO: The arch in the object file isn't correct for MSVC
2812 // binaries on windows, we should find a way to make it
2813 // correct and handle those symbols as well.
Aidan Doddsc78e8992015-11-10 14:10:57 +00002814 if (sc_list.GetSize() == original_size)
Matt Kopecd6089962013-05-10 17:53:48 +00002815 {
Robert Flackeb83fab2015-05-15 18:59:59 +00002816 ArchSpec arch;
Greg Clayton99558cc42015-08-24 23:46:31 +00002817 if (!parent_decl_ctx &&
Robert Flackeb83fab2015-05-15 18:59:59 +00002818 GetObjectFile()->GetArchitecture(arch) &&
2819 (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
2820 arch.GetMachine() == llvm::Triple::hexagon))
Matt Kopecd6089962013-05-10 17:53:48 +00002821 {
Robert Flackeb83fab2015-05-15 18:59:59 +00002822 SymbolContextList temp_sc_list;
2823 FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
Matt Kopecd6089962013-05-10 17:53:48 +00002824 SymbolContext sc;
2825 for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
2826 {
2827 if (temp_sc_list.GetContextAtIndex(i, sc))
2828 {
Matt Kopeca189d492013-05-10 22:55:24 +00002829 ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
2830 ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
Robert Flackeb83fab2015-05-15 18:59:59 +00002831 // Mangled names on Linux and FreeBSD are of the form:
2832 // _ZN18function_namespace13function_nameEv.
Matt Kopec04e5d582013-05-14 19:00:41 +00002833 if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
2834 !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
Matt Kopecd6089962013-05-10 17:53:48 +00002835 {
2836 sc_list.Append(sc);
2837 }
2838 }
2839 }
2840 }
2841 }
Matt Kopecd6089962013-05-10 17:53:48 +00002842 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002843 DIEArray die_offsets;
Greg Clayton43fe2172013-04-03 02:00:15 +00002844 if (name_type_mask & eFunctionNameTypeBase)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002845 {
Greg Clayton43fe2172013-04-03 02:00:15 +00002846 uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
Greg Claytonaa044962011-10-13 00:59:38 +00002847 for (uint32_t i = 0; i < num_base; i++)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002848 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002849 DWARFDIE die = info->GetDIE (die_offsets[i]);
Greg Claytonaa044962011-10-13 00:59:38 +00002850 if (die)
2851 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002852 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00002853 continue; // The containing decl contexts don't match
Greg Clayton8b4edba2015-08-14 20:02:05 +00002854
Greg Claytonaa044962011-10-13 00:59:38 +00002855 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002856 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002857 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002858 if (ResolveFunction (die, include_inlines, sc_list))
2859 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002860 }
Greg Claytonaa044962011-10-13 00:59:38 +00002861 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002862 }
2863 die_offsets.clear();
2864 }
2865
Greg Clayton43fe2172013-04-03 02:00:15 +00002866 if (name_type_mask & eFunctionNameTypeMethod)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002867 {
Greg Clayton99558cc42015-08-24 23:46:31 +00002868 if (parent_decl_ctx && parent_decl_ctx->IsValid())
Sean Callanan213fdb82011-10-13 01:49:10 +00002869 return 0; // no methods in namespaces
2870
Greg Clayton43fe2172013-04-03 02:00:15 +00002871 uint32_t num_base = m_function_method_index.Find(name, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002872 {
Greg Claytonaa044962011-10-13 00:59:38 +00002873 for (uint32_t i = 0; i < num_base; i++)
2874 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002875 DWARFDIE die = info->GetDIE (die_offsets[i]);
Greg Claytonaa044962011-10-13 00:59:38 +00002876 if (die)
2877 {
Greg Claytonaa044962011-10-13 00:59:38 +00002878 // If we get to here, the die is good, and we should add it:
Greg Clayton6071e6f2015-08-26 22:57:51 +00002879 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
Greg Clayton43fe2172013-04-03 02:00:15 +00002880 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00002881 if (ResolveFunction (die, include_inlines, sc_list))
2882 resolved_dies.insert(die.GetDIE());
Greg Clayton43fe2172013-04-03 02:00:15 +00002883 }
Greg Claytonaa044962011-10-13 00:59:38 +00002884 }
2885 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002886 }
2887 die_offsets.clear();
2888 }
Greg Clayton7f995132011-10-04 22:41:51 +00002889
Greg Clayton99558cc42015-08-24 23:46:31 +00002890 if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid()))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002891 {
Pavel Labatha73d6572015-03-13 10:22:00 +00002892 FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002893 }
2894
Greg Clayton4d01ace2011-09-29 16:58:15 +00002895 }
2896
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002897 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00002898 const uint32_t num_matches = sc_list.GetSize() - original_size;
2899
2900 if (log && num_matches > 0)
2901 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002902 GetObjectFile()->GetModule()->LogMessage (log,
Pavel Labatha73d6572015-03-13 10:22:00 +00002903 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00002904 name.GetCString(),
2905 name_type_mask,
Pavel Labatha73d6572015-03-13 10:22:00 +00002906 include_inlines,
Greg Clayton437a1352012-04-09 22:43:43 +00002907 append,
2908 num_matches);
2909 }
2910 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002911}
2912
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002913uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +00002914SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002915{
2916 Timer scoped_timer (__PRETTY_FUNCTION__,
2917 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2918 regex.GetText());
2919
Greg Clayton5160ce52013-03-27 23:08:40 +00002920 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00002921
2922 if (log)
2923 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002924 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002925 "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
2926 regex.GetText(),
2927 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00002928 }
2929
2930
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002931 // If we aren't appending the results to this list, then clear the list
2932 if (!append)
2933 sc_list.Clear();
2934
2935 // Remember how many sc_list are in the list before we search in case
2936 // we are appending the results to a variable list.
2937 uint32_t original_size = sc_list.GetSize();
2938
Greg Clayton97fbc342011-10-20 22:30:33 +00002939 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002940 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002941 if (m_apple_names_ap.get())
Pavel Labatha73d6572015-03-13 10:22:00 +00002942 FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002943 }
2944 else
2945 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002946 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00002947 if (!m_indexed)
2948 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002949
Pavel Labatha73d6572015-03-13 10:22:00 +00002950 FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002951
Pavel Labatha73d6572015-03-13 10:22:00 +00002952 FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002953 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002954
2955 // Return the number of variable that were appended to the list
2956 return sc_list.GetSize() - original_size;
2957}
Jim Ingham318c9f22011-08-26 19:44:13 +00002958
Siva Chandra9293fc42016-01-07 23:32:34 +00002959void
2960SymbolFileDWARF::GetMangledNamesForFunction (const std::string &scope_qualified_name,
2961 std::vector<ConstString> &mangled_names)
2962{
2963 DWARFDebugInfo* info = DebugInfo();
2964 uint32_t num_comp_units = 0;
2965 if (info)
2966 num_comp_units = info->GetNumCompileUnits();
2967
2968 for (uint32_t i = 0; i < num_comp_units; i++)
2969 {
2970 DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i);
2971 if (cu == nullptr)
2972 continue;
2973
2974 SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
2975 if (dwo)
2976 dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
2977 }
2978
2979 NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name);
2980 if (iter == m_function_scope_qualified_name_map.end())
2981 return;
2982
2983 DIERefSetSP set_sp = (*iter).second;
2984 std::set<DIERef>::iterator set_iter;
2985 for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++)
2986 {
2987 DWARFDIE die = DebugInfo()->GetDIE (*set_iter);
2988 mangled_names.push_back(ConstString(die.GetMangledName()));
2989 }
2990}
2991
2992
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002993uint32_t
Greg Claytond1767f02011-12-08 02:13:16 +00002994SymbolFileDWARF::FindTypes (const SymbolContext& sc,
2995 const ConstString &name,
Greg Clayton99558cc42015-08-24 23:46:31 +00002996 const CompilerDeclContext *parent_decl_ctx,
Greg Claytond1767f02011-12-08 02:13:16 +00002997 bool append,
Greg Claytonae088e52016-02-10 21:28:13 +00002998 uint32_t max_matches,
2999 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
Ravitheja Addepally40697302015-10-08 09:45:41 +00003000 TypeMap& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003001{
Greg Claytonae088e52016-02-10 21:28:13 +00003002 // If we aren't appending the results to this list, then clear the list
3003 if (!append)
3004 types.Clear();
3005
3006 // Make sure we haven't already searched this SymbolFile before...
3007 if (searched_symbol_files.count(this))
3008 return 0;
3009 else
3010 searched_symbol_files.insert(this);
3011
Greg Claytonc685f8e2010-09-15 04:15:46 +00003012 DWARFDebugInfo* info = DebugInfo();
3013 if (info == NULL)
3014 return 0;
3015
Greg Clayton5160ce52013-03-27 23:08:40 +00003016 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003017
Greg Clayton21f2a492011-10-06 00:09:08 +00003018 if (log)
3019 {
Greg Clayton99558cc42015-08-24 23:46:31 +00003020 if (parent_decl_ctx)
Greg Clayton5160ce52013-03-27 23:08:40 +00003021 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00003022 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)",
Greg Clayton437a1352012-04-09 22:43:43 +00003023 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00003024 static_cast<const void*>(parent_decl_ctx),
3025 parent_decl_ctx->GetName().AsCString("<NULL>"),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003026 append, max_matches);
Greg Clayton437a1352012-04-09 22:43:43 +00003027 else
Greg Clayton5160ce52013-03-27 23:08:40 +00003028 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00003029 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003030 name.GetCString(), append,
Greg Clayton437a1352012-04-09 22:43:43 +00003031 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00003032 }
3033
Greg Clayton99558cc42015-08-24 23:46:31 +00003034 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
Ed Maste4c24b122013-10-17 20:13:14 +00003035 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003036
Greg Claytond4a2b372011-09-12 23:21:58 +00003037 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003038
Greg Clayton97fbc342011-10-20 22:30:33 +00003039 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003040 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003041 if (m_apple_types_ap.get())
3042 {
3043 const char *name_cstr = name.GetCString();
3044 m_apple_types_ap->FindByName (name_cstr, die_offsets);
3045 }
Greg Clayton7f995132011-10-04 22:41:51 +00003046 }
3047 else
3048 {
3049 if (!m_indexed)
3050 Index ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003051
Greg Clayton7f995132011-10-04 22:41:51 +00003052 m_type_index.Find (name, die_offsets);
3053 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003054
Greg Clayton437a1352012-04-09 22:43:43 +00003055 const size_t num_die_matches = die_offsets.size();
Greg Clayton7f995132011-10-04 22:41:51 +00003056
Greg Clayton437a1352012-04-09 22:43:43 +00003057 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003058 {
Greg Clayton7f995132011-10-04 22:41:51 +00003059 const uint32_t initial_types_size = types.GetSize();
Greg Clayton437a1352012-04-09 22:43:43 +00003060 for (size_t i=0; i<num_die_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003061 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003062 const DIERef& die_ref = die_offsets[i];
Greg Clayton2f869fe2016-03-30 20:14:35 +00003063 DWARFDIE die = GetDIE (die_ref);
Greg Claytond4a2b372011-09-12 23:21:58 +00003064
Greg Clayton95d87902011-11-11 03:16:25 +00003065 if (die)
Greg Clayton73bf5db2011-06-17 01:22:15 +00003066 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003067 if (!DIEInDeclContext(parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00003068 continue; // The containing decl contexts don't match
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003069
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00003070 Type *matching_type = ResolveType (die, true, true);
Greg Clayton95d87902011-11-11 03:16:25 +00003071 if (matching_type)
3072 {
3073 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone1cd1be2012-01-29 20:56:30 +00003074 types.InsertUnique (matching_type->shared_from_this());
Greg Clayton95d87902011-11-11 03:16:25 +00003075 if (types.GetSize() >= max_matches)
3076 break;
3077 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00003078 }
Greg Clayton95d87902011-11-11 03:16:25 +00003079 else
3080 {
3081 if (m_using_apple_tables)
3082 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003083 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 +00003084 die_ref.die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00003085 }
3086 }
3087
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003088 }
Greg Clayton437a1352012-04-09 22:43:43 +00003089 const uint32_t num_matches = types.GetSize() - initial_types_size;
3090 if (log && num_matches)
3091 {
Greg Clayton99558cc42015-08-24 23:46:31 +00003092 if (parent_decl_ctx)
Greg Clayton437a1352012-04-09 22:43:43 +00003093 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003094 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00003095 "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 +00003096 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00003097 static_cast<const void*>(parent_decl_ctx),
3098 parent_decl_ctx->GetName().AsCString("<NULL>"),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003099 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00003100 num_matches);
3101 }
3102 else
3103 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003104 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00003105 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00003106 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003107 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00003108 num_matches);
3109 }
3110 }
3111 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003112 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00003113 else
3114 {
3115 UpdateExternalModuleListIfNeeded();
3116
3117 for (const auto &pair : m_external_type_modules)
3118 {
3119 ModuleSP external_module_sp = pair.second;
3120 if (external_module_sp)
3121 {
3122 SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
3123 if (sym_vendor)
3124 {
3125 const uint32_t num_external_matches = sym_vendor->FindTypes (sc,
3126 name,
3127 parent_decl_ctx,
3128 append,
3129 max_matches,
Greg Claytonae088e52016-02-10 21:28:13 +00003130 searched_symbol_files,
Greg Claytone6b36cd2015-12-08 01:02:08 +00003131 types);
3132 if (num_external_matches)
3133 return num_external_matches;
3134 }
3135 }
3136 }
3137 }
3138
3139 return 0;
3140}
3141
3142
3143size_t
3144SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
3145 bool append,
3146 TypeMap& types)
3147{
3148 if (!append)
3149 types.Clear();
3150
3151 if (context.empty())
3152 return 0;
3153
3154 DIEArray die_offsets;
3155
3156 ConstString name = context.back().name;
3157
Sean Callanan9b0cfe22016-01-14 18:59:49 +00003158 if (!name)
3159 return 0;
3160
Greg Claytone6b36cd2015-12-08 01:02:08 +00003161 if (m_using_apple_tables)
3162 {
3163 if (m_apple_types_ap.get())
3164 {
3165 const char *name_cstr = name.GetCString();
3166 m_apple_types_ap->FindByName (name_cstr, die_offsets);
3167 }
3168 }
3169 else
3170 {
3171 if (!m_indexed)
3172 Index ();
3173
3174 m_type_index.Find (name, die_offsets);
3175 }
3176
3177 const size_t num_die_matches = die_offsets.size();
3178
3179 if (num_die_matches)
3180 {
3181 size_t num_matches = 0;
Greg Claytone6b36cd2015-12-08 01:02:08 +00003182 for (size_t i=0; i<num_die_matches; ++i)
3183 {
3184 const DIERef& die_ref = die_offsets[i];
Greg Clayton2f869fe2016-03-30 20:14:35 +00003185 DWARFDIE die = GetDIE (die_ref);
Greg Claytone6b36cd2015-12-08 01:02:08 +00003186
3187 if (die)
3188 {
3189 std::vector<CompilerContext> die_context;
3190 die.GetDWOContext(die_context);
3191 if (die_context != context)
3192 continue;
3193
3194 Type *matching_type = ResolveType (die, true, true);
3195 if (matching_type)
3196 {
3197 // We found a type pointer, now find the shared pointer form our type list
3198 types.InsertUnique (matching_type->shared_from_this());
3199 ++num_matches;
3200 }
3201 }
3202 else
3203 {
3204 if (m_using_apple_tables)
3205 {
3206 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3207 die_ref.die_offset, name.GetCString());
3208 }
3209 }
3210
3211 }
3212 return num_matches;
3213 }
Greg Clayton7f995132011-10-04 22:41:51 +00003214 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003215}
3216
3217
Greg Clayton99558cc42015-08-24 23:46:31 +00003218CompilerDeclContext
Greg Clayton96d7d742010-11-10 23:42:09 +00003219SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00003220 const ConstString &name,
Greg Clayton99558cc42015-08-24 23:46:31 +00003221 const CompilerDeclContext *parent_decl_ctx)
Greg Clayton96d7d742010-11-10 23:42:09 +00003222{
Greg Clayton5160ce52013-03-27 23:08:40 +00003223 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00003224
3225 if (log)
3226 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003227 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003228 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
3229 name.GetCString());
Greg Clayton21f2a492011-10-06 00:09:08 +00003230 }
3231
Greg Clayton99558cc42015-08-24 23:46:31 +00003232 CompilerDeclContext namespace_decl_ctx;
3233
3234 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
3235 return namespace_decl_ctx;
3236
3237
Greg Clayton96d7d742010-11-10 23:42:09 +00003238 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00003239 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00003240 {
Greg Clayton7f995132011-10-04 22:41:51 +00003241 DIEArray die_offsets;
3242
Greg Clayton526e5af2010-11-13 03:52:47 +00003243 // Index if we already haven't to make sure the compile units
3244 // get indexed and make their global DIE index list
Greg Clayton97fbc342011-10-20 22:30:33 +00003245 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003246 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003247 if (m_apple_namespaces_ap.get())
3248 {
3249 const char *name_cstr = name.GetCString();
3250 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
3251 }
Greg Clayton7f995132011-10-04 22:41:51 +00003252 }
3253 else
3254 {
3255 if (!m_indexed)
3256 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00003257
Greg Clayton7f995132011-10-04 22:41:51 +00003258 m_namespace_index.Find (name, die_offsets);
3259 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003260
Greg Clayton7f995132011-10-04 22:41:51 +00003261 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003262 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00003263 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003264 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00003265 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003266 const DIERef& die_ref = die_offsets[i];
Greg Clayton2f869fe2016-03-30 20:14:35 +00003267 DWARFDIE die = GetDIE (die_ref);
Greg Clayton6071e6f2015-08-26 22:57:51 +00003268
Greg Clayton95d87902011-11-11 03:16:25 +00003269 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00003270 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003271 if (!DIEInDeclContext (parent_decl_ctx, die))
Greg Clayton99558cc42015-08-24 23:46:31 +00003272 continue; // The containing decl contexts don't match
Greg Clayton95d87902011-11-11 03:16:25 +00003273
Greg Clayton261ac3f2015-08-28 01:01:03 +00003274 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
3275 if (dwarf_ast)
Greg Clayton8b4edba2015-08-14 20:02:05 +00003276 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00003277 namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die);
Greg Clayton99558cc42015-08-24 23:46:31 +00003278 if (namespace_decl_ctx)
Greg Clayton8b4edba2015-08-14 20:02:05 +00003279 break;
Greg Clayton95d87902011-11-11 03:16:25 +00003280 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003281 }
Greg Clayton95d87902011-11-11 03:16:25 +00003282 else
3283 {
3284 if (m_using_apple_tables)
3285 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003286 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 +00003287 die_ref.die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00003288 }
3289 }
3290
Greg Clayton526e5af2010-11-13 03:52:47 +00003291 }
3292 }
Greg Clayton96d7d742010-11-10 23:42:09 +00003293 }
Greg Clayton99558cc42015-08-24 23:46:31 +00003294 if (log && namespace_decl_ctx)
Greg Clayton437a1352012-04-09 22:43:43 +00003295 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003296 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton99558cc42015-08-24 23:46:31 +00003297 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"",
Greg Clayton437a1352012-04-09 22:43:43 +00003298 name.GetCString(),
Greg Clayton99558cc42015-08-24 23:46:31 +00003299 static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()),
3300 static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()),
3301 namespace_decl_ctx.GetName().AsCString("<NULL>"));
Greg Clayton437a1352012-04-09 22:43:43 +00003302 }
3303
Greg Clayton99558cc42015-08-24 23:46:31 +00003304 return namespace_decl_ctx;
Greg Clayton96d7d742010-11-10 23:42:09 +00003305}
3306
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003307TypeSP
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00003308SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003309{
3310 TypeSP type_sp;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003311 if (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003312 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003313 Type *type_ptr = GetDIEToType().lookup (die.GetDIE());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003314 if (type_ptr == NULL)
3315 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003316 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
Greg Claytonca512b32011-01-14 04:54:56 +00003317 assert (lldb_cu);
3318 SymbolContext sc(lldb_cu);
Ravitheja Addepally40697302015-10-08 09:45:41 +00003319 const DWARFDebugInfoEntry* parent_die = die.GetParent().GetDIE();
3320 while (parent_die != nullptr)
3321 {
3322 if (parent_die->Tag() == DW_TAG_subprogram)
3323 break;
3324 parent_die = parent_die->GetParent();
3325 }
3326 SymbolContext sc_backup = sc;
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00003327 if (resolve_function_context && parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc))
Ravitheja Addepally40697302015-10-08 09:45:41 +00003328 sc = sc_backup;
3329
Greg Clayton6071e6f2015-08-26 22:57:51 +00003330 type_sp = ParseType(sc, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003331 }
3332 else if (type_ptr != DIE_IS_BEING_PARSED)
3333 {
3334 // Grab the existing type from the master types lists
Greg Claytone1cd1be2012-01-29 20:56:30 +00003335 type_sp = type_ptr->shared_from_this();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003336 }
3337
3338 }
3339 return type_sp;
3340}
3341
Greg Clayton2bc22f82011-09-30 03:20:47 +00003342
Greg Clayton6071e6f2015-08-26 22:57:51 +00003343DWARFDIE
3344SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003345{
Greg Clayton6071e6f2015-08-26 22:57:51 +00003346 if (orig_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003347 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003348 DWARFDIE die = orig_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003349
Greg Clayton6071e6f2015-08-26 22:57:51 +00003350 while (die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003351 {
3352 // If this is the original DIE that we are searching for a declaration
3353 // for, then don't look in the cache as we don't want our own decl
3354 // context to be our decl context...
Greg Clayton6071e6f2015-08-26 22:57:51 +00003355 if (orig_die != die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003356 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003357 switch (die.Tag())
Greg Clayton2bc22f82011-09-30 03:20:47 +00003358 {
3359 case DW_TAG_compile_unit:
3360 case DW_TAG_namespace:
3361 case DW_TAG_structure_type:
3362 case DW_TAG_union_type:
3363 case DW_TAG_class_type:
Paul Hermand628cbb2015-09-15 23:44:17 +00003364 case DW_TAG_lexical_block:
3365 case DW_TAG_subprogram:
Greg Clayton2bc22f82011-09-30 03:20:47 +00003366 return die;
3367
3368 default:
3369 break;
3370 }
3371 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003372
3373 DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
3374 if (spec_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003375 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003376 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
3377 if (decl_ctx_die)
3378 return decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003379 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003380
3381 DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
3382 if (abs_die)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003383 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003384 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
3385 if (decl_ctx_die)
3386 return decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003387 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003388
3389 die = die.GetParent();
Greg Clayton2bc22f82011-09-30 03:20:47 +00003390 }
3391 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003392 return DWARFDIE();
Greg Clayton2bc22f82011-09-30 03:20:47 +00003393}
3394
3395
Greg Clayton901c5ca2011-12-03 04:40:03 +00003396Symbol *
3397SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
3398{
3399 Symbol *objc_class_symbol = NULL;
3400 if (m_obj_file)
3401 {
Greg Clayton3046e662013-07-10 01:23:25 +00003402 Symtab *symtab = m_obj_file->GetSymtab ();
Greg Clayton901c5ca2011-12-03 04:40:03 +00003403 if (symtab)
3404 {
3405 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
3406 eSymbolTypeObjCClass,
3407 Symtab::eDebugNo,
3408 Symtab::eVisibilityAny);
3409 }
3410 }
3411 return objc_class_symbol;
3412}
3413
Greg Claytonc7f03b62012-01-12 04:33:28 +00003414// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
3415// then we can end up looking through all class types for a complete type and never find
3416// the full definition. We need to know if this attribute is supported, so we determine
3417// this here and cache th result. We also need to worry about the debug map DWARF file
3418// if we are doing darwin DWARF in .o file debugging.
3419bool
3420SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
3421{
3422 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
3423 {
3424 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
3425 if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
3426 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3427 else
3428 {
3429 DWARFDebugInfo* debug_info = DebugInfo();
3430 const uint32_t num_compile_units = GetNumCompileUnits();
3431 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
3432 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003433 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
3434 if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
Greg Claytonc7f03b62012-01-12 04:33:28 +00003435 {
3436 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
3437 break;
3438 }
3439 }
3440 }
Greg Clayton1f746072012-08-29 21:13:06 +00003441 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
Greg Claytonc7f03b62012-01-12 04:33:28 +00003442 return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
3443 }
3444 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
3445}
Greg Clayton901c5ca2011-12-03 04:40:03 +00003446
3447// This function can be used when a DIE is found that is a forward declaration
3448// DIE and we want to try and find a type that has the complete definition.
3449TypeSP
Greg Clayton6071e6f2015-08-26 22:57:51 +00003450SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
Greg Claytonc7f03b62012-01-12 04:33:28 +00003451 const ConstString &type_name,
3452 bool must_be_implementation)
Greg Clayton901c5ca2011-12-03 04:40:03 +00003453{
3454
3455 TypeSP type_sp;
3456
Greg Claytonc7f03b62012-01-12 04:33:28 +00003457 if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
Greg Clayton901c5ca2011-12-03 04:40:03 +00003458 return type_sp;
3459
3460 DIEArray die_offsets;
3461
3462 if (m_using_apple_tables)
3463 {
3464 if (m_apple_types_ap.get())
3465 {
3466 const char *name_cstr = type_name.GetCString();
Greg Clayton68221ec2012-01-18 20:58:12 +00003467 m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003468 }
3469 }
3470 else
3471 {
3472 if (!m_indexed)
3473 Index ();
3474
3475 m_type_index.Find (type_name, die_offsets);
3476 }
3477
Greg Clayton901c5ca2011-12-03 04:40:03 +00003478 const size_t num_matches = die_offsets.size();
3479
Greg Clayton901c5ca2011-12-03 04:40:03 +00003480 if (num_matches)
3481 {
Greg Clayton901c5ca2011-12-03 04:40:03 +00003482 for (size_t i=0; i<num_matches; ++i)
3483 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003484 const DIERef& die_ref = die_offsets[i];
Greg Clayton2f869fe2016-03-30 20:14:35 +00003485 DWARFDIE type_die = GetDIE (die_ref);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003486
3487 if (type_die)
3488 {
3489 bool try_resolving_type = false;
3490
3491 // Don't try and resolve the DIE we are looking for with the DIE itself!
3492 if (type_die != die)
3493 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003494 switch (type_die.Tag())
Greg Clayton901c5ca2011-12-03 04:40:03 +00003495 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00003496 case DW_TAG_class_type:
3497 case DW_TAG_structure_type:
3498 try_resolving_type = true;
3499 break;
3500 default:
3501 break;
Greg Clayton901c5ca2011-12-03 04:40:03 +00003502 }
3503 }
3504
3505 if (try_resolving_type)
3506 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003507 if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type())
3508 try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003509
3510 if (try_resolving_type)
3511 {
Ravitheja Addepally46bcbaa2015-11-03 14:24:24 +00003512 Type *resolved_type = ResolveType (type_die, false, true);
Greg Clayton901c5ca2011-12-03 04:40:03 +00003513 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3514 {
Ed Mastea0191d12013-10-17 20:42:56 +00003515 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 +00003516 die.GetID(),
Jim Ingham4af59612014-12-19 19:20:44 +00003517 m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003518 type_die.GetID(),
3519 type_cu->GetID());
Greg Clayton901c5ca2011-12-03 04:40:03 +00003520
Greg Claytonc7f03b62012-01-12 04:33:28 +00003521 if (die)
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003522 GetDIEToType()[die.GetDIE()] = resolved_type;
Greg Claytone1cd1be2012-01-29 20:56:30 +00003523 type_sp = resolved_type->shared_from_this();
Greg Clayton901c5ca2011-12-03 04:40:03 +00003524 break;
3525 }
3526 }
3527 }
3528 }
3529 else
3530 {
3531 if (m_using_apple_tables)
3532 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003533 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 +00003534 die_ref.die_offset, type_name.GetCString());
Greg Clayton901c5ca2011-12-03 04:40:03 +00003535 }
3536 }
3537
3538 }
3539 }
3540 return type_sp;
3541}
3542
Greg Claytona8022fa2012-04-24 21:22:41 +00003543
Greg Clayton80c26302012-02-05 06:12:47 +00003544//----------------------------------------------------------------------
3545// This function helps to ensure that the declaration contexts match for
3546// two different DIEs. Often times debug information will refer to a
3547// forward declaration of a type (the equivalent of "struct my_struct;".
3548// There will often be a declaration of that type elsewhere that has the
3549// full definition. When we go looking for the full type "my_struct", we
3550// will find one or more matches in the accelerator tables and we will
3551// then need to make sure the type was in the same declaration context
3552// as the original DIE. This function can efficiently compare two DIEs
3553// and will return true when the declaration context matches, and false
3554// when they don't.
3555//----------------------------------------------------------------------
Greg Clayton890ff562012-02-02 05:48:16 +00003556bool
Greg Clayton6071e6f2015-08-26 22:57:51 +00003557SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1,
3558 const DWARFDIE &die2)
Greg Clayton890ff562012-02-02 05:48:16 +00003559{
Greg Claytona8022fa2012-04-24 21:22:41 +00003560 if (die1 == die2)
3561 return true;
3562
Greg Clayton890ff562012-02-02 05:48:16 +00003563 DWARFDIECollection decl_ctx_1;
3564 DWARFDIECollection decl_ctx_2;
Greg Clayton80c26302012-02-05 06:12:47 +00003565 //The declaration DIE stack is a stack of the declaration context
3566 // DIEs all the way back to the compile unit. If a type "T" is
3567 // declared inside a class "B", and class "B" is declared inside
3568 // a class "A" and class "A" is in a namespace "lldb", and the
3569 // namespace is in a compile unit, there will be a stack of DIEs:
3570 //
3571 // [0] DW_TAG_class_type for "B"
3572 // [1] DW_TAG_class_type for "A"
3573 // [2] DW_TAG_namespace for "lldb"
3574 // [3] DW_TAG_compile_unit for the source file.
3575 //
3576 // We grab both contexts and make sure that everything matches
3577 // all the way back to the compiler unit.
3578
3579 // First lets grab the decl contexts for both DIEs
Greg Clayton6071e6f2015-08-26 22:57:51 +00003580 die1.GetDeclContextDIEs (decl_ctx_1);
3581 die2.GetDeclContextDIEs (decl_ctx_2);
Greg Clayton80c26302012-02-05 06:12:47 +00003582 // Make sure the context arrays have the same size, otherwise
3583 // we are done
Greg Clayton890ff562012-02-02 05:48:16 +00003584 const size_t count1 = decl_ctx_1.Size();
3585 const size_t count2 = decl_ctx_2.Size();
3586 if (count1 != count2)
3587 return false;
Greg Clayton80c26302012-02-05 06:12:47 +00003588
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003589 // Make sure the DW_TAG values match all the way back up the
Greg Clayton80c26302012-02-05 06:12:47 +00003590 // compile unit. If they don't, then we are done.
Greg Clayton6071e6f2015-08-26 22:57:51 +00003591 DWARFDIE decl_ctx_die1;
3592 DWARFDIE decl_ctx_die2;
Greg Clayton890ff562012-02-02 05:48:16 +00003593 size_t i;
3594 for (i=0; i<count1; i++)
3595 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003596 decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3597 decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3598 if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
Greg Clayton890ff562012-02-02 05:48:16 +00003599 return false;
3600 }
Greg Clayton890ff562012-02-02 05:48:16 +00003601#if defined LLDB_CONFIGURATION_DEBUG
Greg Clayton80c26302012-02-05 06:12:47 +00003602
3603 // Make sure the top item in the decl context die array is always
3604 // DW_TAG_compile_unit. If it isn't then something went wrong in
Greg Clayton5ce1a842015-08-27 18:09:44 +00003605 // the DWARFDIE::GetDeclContextDIEs() function...
Greg Clayton6071e6f2015-08-26 22:57:51 +00003606 assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit);
Greg Clayton80c26302012-02-05 06:12:47 +00003607
Greg Clayton890ff562012-02-02 05:48:16 +00003608#endif
3609 // Always skip the compile unit when comparing by only iterating up to
Greg Clayton80c26302012-02-05 06:12:47 +00003610 // "count - 1". Here we compare the names as we go.
Greg Clayton890ff562012-02-02 05:48:16 +00003611 for (i=0; i<count1 - 1; i++)
3612 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003613 decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
3614 decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
3615 const char *name1 = decl_ctx_die1.GetName();
3616 const char *name2 = decl_ctx_die2.GetName();
Greg Clayton890ff562012-02-02 05:48:16 +00003617 // If the string was from a DW_FORM_strp, then the pointer will often
3618 // be the same!
Greg Clayton5569e642012-02-06 01:44:54 +00003619 if (name1 == name2)
3620 continue;
3621
3622 // Name pointers are not equal, so only compare the strings
3623 // if both are not NULL.
3624 if (name1 && name2)
Greg Clayton890ff562012-02-02 05:48:16 +00003625 {
Greg Clayton5569e642012-02-06 01:44:54 +00003626 // If the strings don't compare, we are done...
3627 if (strcmp(name1, name2) != 0)
Greg Clayton890ff562012-02-02 05:48:16 +00003628 return false;
Greg Clayton5569e642012-02-06 01:44:54 +00003629 }
3630 else
3631 {
3632 // One name was NULL while the other wasn't
3633 return false;
Greg Clayton890ff562012-02-02 05:48:16 +00003634 }
3635 }
Greg Clayton80c26302012-02-05 06:12:47 +00003636 // We made it through all of the checks and the declaration contexts
3637 // are equal.
Greg Clayton890ff562012-02-02 05:48:16 +00003638 return true;
3639}
Greg Clayton220a0072011-12-09 08:48:30 +00003640
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003641
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003642TypeSP
Greg Claytona8022fa2012-04-24 21:22:41 +00003643SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
3644{
3645 TypeSP type_sp;
3646
3647 const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
3648 if (dwarf_decl_ctx_count > 0)
3649 {
3650 const ConstString type_name(dwarf_decl_ctx[0].name);
3651 const dw_tag_t tag = dwarf_decl_ctx[0].tag;
3652
3653 if (type_name)
3654 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003655 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
Greg Claytona8022fa2012-04-24 21:22:41 +00003656 if (log)
3657 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003658 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003659 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
3660 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3661 dwarf_decl_ctx.GetQualifiedName());
3662 }
3663
3664 DIEArray die_offsets;
3665
3666 if (m_using_apple_tables)
3667 {
3668 if (m_apple_types_ap.get())
3669 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003670 const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
3671 const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
3672 if (has_tag && has_qualified_name_hash)
Greg Claytona8022fa2012-04-24 21:22:41 +00003673 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003674 const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
3675 const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
3676 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003677 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00003678 m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
3679 }
3680 else if (has_tag)
3681 {
3682 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003683 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
Greg Claytona8022fa2012-04-24 21:22:41 +00003684 m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
3685 }
3686 else
3687 {
3688 m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
3689 }
3690 }
3691 }
3692 else
3693 {
3694 if (!m_indexed)
3695 Index ();
3696
3697 m_type_index.Find (type_name, die_offsets);
3698 }
3699
3700 const size_t num_matches = die_offsets.size();
3701
3702
Greg Claytona8022fa2012-04-24 21:22:41 +00003703 if (num_matches)
3704 {
Greg Claytona8022fa2012-04-24 21:22:41 +00003705 for (size_t i=0; i<num_matches; ++i)
3706 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003707 const DIERef& die_ref = die_offsets[i];
Greg Clayton2f869fe2016-03-30 20:14:35 +00003708 DWARFDIE type_die = GetDIE (die_ref);
Greg Claytona8022fa2012-04-24 21:22:41 +00003709
3710 if (type_die)
3711 {
3712 bool try_resolving_type = false;
3713
3714 // Don't try and resolve the DIE we are looking for with the DIE itself!
Greg Clayton6071e6f2015-08-26 22:57:51 +00003715 const dw_tag_t type_tag = type_die.Tag();
Greg Claytona8022fa2012-04-24 21:22:41 +00003716 // Make sure the tags match
3717 if (type_tag == tag)
3718 {
3719 // The tags match, lets try resolving this type
3720 try_resolving_type = true;
3721 }
3722 else
3723 {
3724 // The tags don't match, but we need to watch our for a
3725 // forward declaration for a struct and ("struct foo")
3726 // ends up being a class ("class foo { ... };") or
3727 // vice versa.
3728 switch (type_tag)
3729 {
3730 case DW_TAG_class_type:
3731 // We had a "class foo", see if we ended up with a "struct foo { ... };"
3732 try_resolving_type = (tag == DW_TAG_structure_type);
3733 break;
3734 case DW_TAG_structure_type:
3735 // We had a "struct foo", see if we ended up with a "class foo { ... };"
3736 try_resolving_type = (tag == DW_TAG_class_type);
3737 break;
3738 default:
3739 // Tags don't match, don't event try to resolve
3740 // using this type whose name matches....
3741 break;
3742 }
3743 }
3744
3745 if (try_resolving_type)
3746 {
3747 DWARFDeclContext type_dwarf_decl_ctx;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003748 type_die.GetDWARFDeclContext (type_dwarf_decl_ctx);
Greg Claytona8022fa2012-04-24 21:22:41 +00003749
3750 if (log)
3751 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003752 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003753 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
3754 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3755 dwarf_decl_ctx.GetQualifiedName(),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003756 type_die.GetOffset(),
Greg Claytona8022fa2012-04-24 21:22:41 +00003757 type_dwarf_decl_ctx.GetQualifiedName());
3758 }
3759
3760 // Make sure the decl contexts match all the way up
3761 if (dwarf_decl_ctx == type_dwarf_decl_ctx)
3762 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003763 Type *resolved_type = ResolveType (type_die, false);
Greg Claytona8022fa2012-04-24 21:22:41 +00003764 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3765 {
3766 type_sp = resolved_type->shared_from_this();
3767 break;
3768 }
3769 }
3770 }
3771 else
3772 {
3773 if (log)
3774 {
3775 std::string qualified_name;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003776 type_die.GetQualifiedName(qualified_name);
Greg Clayton5160ce52013-03-27 23:08:40 +00003777 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00003778 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
3779 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
3780 dwarf_decl_ctx.GetQualifiedName(),
Greg Clayton6071e6f2015-08-26 22:57:51 +00003781 type_die.GetOffset(),
Greg Claytona8022fa2012-04-24 21:22:41 +00003782 qualified_name.c_str());
3783 }
3784 }
3785 }
3786 else
3787 {
3788 if (m_using_apple_tables)
3789 {
3790 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 +00003791 die_ref.die_offset, type_name.GetCString());
Greg Claytona8022fa2012-04-24 21:22:41 +00003792 }
3793 }
3794
3795 }
3796 }
3797 }
3798 }
3799 return type_sp;
3800}
3801
Greg Claytona8022fa2012-04-24 21:22:41 +00003802TypeSP
Greg Clayton6071e6f2015-08-26 22:57:51 +00003803SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003804{
Greg Clayton196e8cd2015-08-17 20:31:46 +00003805 TypeSP type_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003806
Greg Clayton6071e6f2015-08-26 22:57:51 +00003807 if (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003808 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003809 TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
3810
3811 if (type_system)
Greg Clayton196e8cd2015-08-17 20:31:46 +00003812 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00003813 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
3814 if (dwarf_ast)
Greg Clayton6071e6f2015-08-26 22:57:51 +00003815 {
Greg Clayton261ac3f2015-08-28 01:01:03 +00003816 Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
3817 type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr);
3818 if (type_sp)
3819 {
3820 TypeList* type_list = GetTypeList();
3821 if (type_list)
3822 type_list->Insert(type_sp);
Siva Chandra9293fc42016-01-07 23:32:34 +00003823
3824 if (die.Tag() == DW_TAG_subprogram)
3825 {
3826 DIERef die_ref = die.GetDIERef();
3827 std::string scope_qualified_name(GetDeclContextForUID(die.GetID()).GetScopeQualifiedName().AsCString(""));
3828 if (scope_qualified_name.size())
3829 {
3830 NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name);
3831 if (iter != m_function_scope_qualified_name_map.end())
3832 (*iter).second->insert(die_ref);
3833 else
3834 {
3835 DIERefSetSP new_set(new std::set<DIERef>);
3836 new_set->insert(die_ref);
3837 m_function_scope_qualified_name_map.emplace(std::make_pair(scope_qualified_name, new_set));
3838 }
3839 }
3840 }
Greg Clayton261ac3f2015-08-28 01:01:03 +00003841 }
Greg Clayton6071e6f2015-08-26 22:57:51 +00003842 }
Greg Clayton196e8cd2015-08-17 20:31:46 +00003843 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003844 }
Greg Clayton196e8cd2015-08-17 20:31:46 +00003845
3846 return type_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003847}
3848
3849size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003850SymbolFileDWARF::ParseTypes
3851(
3852 const SymbolContext& sc,
Greg Clayton6071e6f2015-08-26 22:57:51 +00003853 const DWARFDIE &orig_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003854 bool parse_siblings,
3855 bool parse_children
3856)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003857{
3858 size_t types_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003859 DWARFDIE die = orig_die;
3860 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003861 {
3862 bool type_is_new = false;
Greg Clayton6071e6f2015-08-26 22:57:51 +00003863 if (ParseType(sc, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003864 {
3865 if (type_is_new)
3866 ++types_added;
3867 }
3868
Greg Clayton6071e6f2015-08-26 22:57:51 +00003869 if (parse_children && die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003870 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003871 if (die.Tag() == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003872 {
3873 SymbolContext child_sc(sc);
Greg Clayton6071e6f2015-08-26 22:57:51 +00003874 child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
3875 types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003876 }
3877 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00003878 types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003879 }
3880
3881 if (parse_siblings)
Greg Clayton6071e6f2015-08-26 22:57:51 +00003882 die = die.GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003883 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00003884 die.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003885 }
3886 return types_added;
3887}
3888
3889
3890size_t
3891SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3892{
3893 assert(sc.comp_unit && sc.function);
3894 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00003895 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003896 if (dwarf_cu)
3897 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003898 const dw_offset_t function_die_offset = sc.function->GetID();
3899 DWARFDIE function_die = dwarf_cu->GetDIE (function_die_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003900 if (function_die)
3901 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003902 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003903 }
3904 }
3905
3906 return functions_added;
3907}
3908
3909
3910size_t
3911SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3912{
3913 // At least a compile unit must be valid
3914 assert(sc.comp_unit);
3915 size_t types_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00003916 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003917 if (dwarf_cu)
3918 {
3919 if (sc.function)
3920 {
3921 dw_offset_t function_die_offset = sc.function->GetID();
Greg Clayton6071e6f2015-08-26 22:57:51 +00003922 DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
3923 if (func_die && func_die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003924 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003925 types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003926 }
3927 }
3928 else
3929 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003930 DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
3931 if (dwarf_cu_die && dwarf_cu_die.HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003932 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003933 types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003934 }
3935 }
3936 }
3937
3938 return types_added;
3939}
3940
3941size_t
3942SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3943{
3944 if (sc.comp_unit != NULL)
3945 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003946 DWARFDebugInfo* info = DebugInfo();
3947 if (info == NULL)
3948 return 0;
3949
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003950 if (sc.function)
3951 {
Greg Clayton2f869fe2016-03-30 20:14:35 +00003952 DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
Greg Clayton9422dd62013-03-04 21:46:16 +00003953
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003954 const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
Greg Claytonc7bece562013-01-25 18:06:21 +00003955 if (func_lo_pc != LLDB_INVALID_ADDRESS)
Greg Claytone38a5ed2012-01-05 03:57:59 +00003956 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003957 const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
Greg Claytonc662ec82011-06-17 22:10:16 +00003958
Greg Claytone38a5ed2012-01-05 03:57:59 +00003959 // Let all blocks know they have parse all their variables
3960 sc.function->GetBlock (false).SetDidParseVariables (true, true);
3961 return num_variables;
3962 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003963 }
3964 else if (sc.comp_unit)
3965 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00003966 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
Greg Clayton9422dd62013-03-04 21:46:16 +00003967
3968 if (dwarf_cu == NULL)
3969 return 0;
3970
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003971 uint32_t vars_added = 0;
3972 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3973
3974 if (variables.get() == NULL)
3975 {
3976 variables.reset(new VariableList());
3977 sc.comp_unit->SetVariableList(variables);
3978
Greg Claytond4a2b372011-09-12 23:21:58 +00003979 DIEArray die_offsets;
Greg Clayton97fbc342011-10-20 22:30:33 +00003980 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003981 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003982 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00003983 {
3984 DWARFMappedHash::DIEInfoArray hash_data_array;
3985 if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
3986 dwarf_cu->GetNextCompileUnitOffset(),
3987 hash_data_array))
3988 {
3989 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
3990 }
3991 }
Greg Clayton7f995132011-10-04 22:41:51 +00003992 }
3993 else
3994 {
3995 // Index if we already haven't to make sure the compile units
3996 // get indexed and make their global DIE index list
3997 if (!m_indexed)
3998 Index ();
3999
4000 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
Greg Clayton7f995132011-10-04 22:41:51 +00004001 die_offsets);
4002 }
4003
4004 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00004005 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004006 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004007 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004008 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004009 const DIERef& die_ref = die_offsets[i];
Greg Clayton2f869fe2016-03-30 20:14:35 +00004010 DWARFDIE die = GetDIE (die_ref);
Greg Clayton95d87902011-11-11 03:16:25 +00004011 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00004012 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004013 VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
Greg Clayton95d87902011-11-11 03:16:25 +00004014 if (var_sp)
4015 {
4016 variables->AddVariableIfUnique (var_sp);
4017 ++vars_added;
4018 }
Greg Claytond4a2b372011-09-12 23:21:58 +00004019 }
Greg Clayton95d87902011-11-11 03:16:25 +00004020 else
4021 {
4022 if (m_using_apple_tables)
4023 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004024 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 +00004025 }
4026 }
4027
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004028 }
4029 }
4030 }
4031 return vars_added;
4032 }
4033 }
4034 return 0;
4035}
4036
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004037VariableSP
4038SymbolFileDWARF::ParseVariableDIE
4039(
4040 const SymbolContext& sc,
Greg Clayton6071e6f2015-08-26 22:57:51 +00004041 const DWARFDIE &die,
Greg Clayton016a95e2010-09-14 02:20:48 +00004042 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004043)
4044{
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004045 if (die.GetDWARF() != this)
4046 return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
4047
Greg Clayton6071e6f2015-08-26 22:57:51 +00004048 VariableSP var_sp;
4049 if (!die)
4050 return var_sp;
4051
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004052 var_sp = GetDIEToVariable()[die.GetDIE()];
Greg Clayton83c5cd92010-11-14 22:13:40 +00004053 if (var_sp)
4054 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004055
Greg Clayton6071e6f2015-08-26 22:57:51 +00004056 const dw_tag_t tag = die.Tag();
Richard Mitton0a558352013-10-17 21:14:00 +00004057 ModuleSP module = GetObjectFile()->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00004058
4059 if ((tag == DW_TAG_variable) ||
4060 (tag == DW_TAG_constant) ||
4061 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004062 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004063 DWARFAttributes attributes;
4064 const size_t num_attributes = die.GetAttributes(attributes);
Paul Hermand628cbb2015-09-15 23:44:17 +00004065 DWARFDIE spec_die;
Greg Clayton7f995132011-10-04 22:41:51 +00004066 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004067 {
Greg Clayton7f995132011-10-04 22:41:51 +00004068 const char *name = NULL;
4069 const char *mangled = NULL;
4070 Declaration decl;
4071 uint32_t i;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004072 DWARFFormValue type_die_form;
Greg Clayton6071e6f2015-08-26 22:57:51 +00004073 DWARFExpression location(die.GetCU());
Greg Clayton7f995132011-10-04 22:41:51 +00004074 bool is_external = false;
4075 bool is_artificial = false;
4076 bool location_is_const_value_data = false;
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004077 bool has_explicit_location = false;
Enrico Granata4ec130d2014-08-11 19:16:35 +00004078 DWARFFormValue const_value;
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004079 Variable::RangeList scope_ranges;
Greg Clayton23f59502012-07-17 03:23:13 +00004080 //AccessType accessibility = eAccessNone;
Greg Clayton7f995132011-10-04 22:41:51 +00004081
4082 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004083 {
Greg Clayton7f995132011-10-04 22:41:51 +00004084 dw_attr_t attr = attributes.AttributeAtIndex(i);
4085 DWARFFormValue form_value;
Greg Clayton54166af2014-11-22 01:58:59 +00004086
Greg Clayton6071e6f2015-08-26 22:57:51 +00004087 if (attributes.ExtractFormValueAtIndex(i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004088 {
Greg Clayton7f995132011-10-04 22:41:51 +00004089 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004090 {
Greg Clayton7f995132011-10-04 22:41:51 +00004091 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4092 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4093 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Greg Clayton6071e6f2015-08-26 22:57:51 +00004094 case DW_AT_name: name = form_value.AsCString(); break;
Greg Clayton71415542012-12-08 00:24:40 +00004095 case DW_AT_linkage_name:
Greg Clayton6071e6f2015-08-26 22:57:51 +00004096 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004097 case DW_AT_type: type_die_form = form_value; break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00004098 case DW_AT_external: is_external = form_value.Boolean(); break;
Greg Clayton7f995132011-10-04 22:41:51 +00004099 case DW_AT_const_value:
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004100 // If we have already found a DW_AT_location attribute, ignore this attribute.
4101 if (!has_explicit_location)
4102 {
4103 location_is_const_value_data = true;
4104 // The constant value will be either a block, a data value or a string.
Ed Masteeeae7212013-10-24 20:43:47 +00004105 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004106 if (DWARFFormValue::IsBlockForm(form_value.Form()))
4107 {
4108 // Retrieve the value as a block expression.
4109 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4110 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00004111 location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004112 }
4113 else if (DWARFFormValue::IsDataForm(form_value.Form()))
4114 {
4115 // Retrieve the value as a data expression.
Tamas Berghammerb7c64652015-08-25 11:45:46 +00004116 DWARFFormValue::FixedFormSizes fixed_form_sizes =
4117 DWARFFormValue::GetFixedFormSizesForAddressSize (
4118 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
4119 attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004120 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
Tamas Berghammerb7c64652015-08-25 11:45:46 +00004121 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
Enrico Granata4ec130d2014-08-11 19:16:35 +00004122 if (data_length == 0)
4123 {
4124 const uint8_t *data_pointer = form_value.BlockData();
4125 if (data_pointer)
4126 {
Jason Molenda18f5fd32014-10-16 07:52:17 +00004127 form_value.Unsigned();
Enrico Granata4ec130d2014-08-11 19:16:35 +00004128 }
4129 else if (DWARFFormValue::IsDataForm(form_value.Form()))
4130 {
4131 // we need to get the byte size of the type later after we create the variable
4132 const_value = form_value;
4133 }
4134 }
4135 else
4136 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004137 }
4138 else
4139 {
4140 // Retrieve the value as a string expression.
4141 if (form_value.Form() == DW_FORM_strp)
4142 {
Tamas Berghammerb7c64652015-08-25 11:45:46 +00004143 DWARFFormValue::FixedFormSizes fixed_form_sizes =
4144 DWARFFormValue::GetFixedFormSizesForAddressSize (
4145 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
4146 attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004147 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
Tamas Berghammerb7c64652015-08-25 11:45:46 +00004148 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
Richard Mitton0a558352013-10-17 21:14:00 +00004149 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004150 }
4151 else
4152 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004153 const char *str = form_value.AsCString();
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004154 uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
4155 uint32_t string_length = strlen(str) + 1;
Richard Mitton0a558352013-10-17 21:14:00 +00004156 location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004157 }
4158 }
4159 }
4160 break;
Greg Clayton7f995132011-10-04 22:41:51 +00004161 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004162 {
Andrew Kaylorb32581f2013-02-13 19:57:06 +00004163 location_is_const_value_data = false;
4164 has_explicit_location = true;
Greg Clayton7f995132011-10-04 22:41:51 +00004165 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004166 {
Ed Masteeeae7212013-10-24 20:43:47 +00004167 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Clayton7f995132011-10-04 22:41:51 +00004168
4169 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4170 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00004171 location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
Greg Clayton7f995132011-10-04 22:41:51 +00004172 }
4173 else
4174 {
Tamas Berghammer1f5e4482015-09-16 12:37:06 +00004175 const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
Greg Clayton7f995132011-10-04 22:41:51 +00004176 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4177
Tamas Berghammer1f5e4482015-09-16 12:37:06 +00004178 size_t loc_list_length = DWARFExpression::LocationListSize(die.GetCU(), debug_loc_data, debug_loc_offset);
Greg Clayton7f995132011-10-04 22:41:51 +00004179 if (loc_list_length > 0)
4180 {
Richard Mitton0a558352013-10-17 21:14:00 +00004181 location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
Greg Clayton7f995132011-10-04 22:41:51 +00004182 assert (func_low_pc != LLDB_INVALID_ADDRESS);
Greg Clayton54166af2014-11-22 01:58:59 +00004183 location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
Greg Clayton7f995132011-10-04 22:41:51 +00004184 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004185 }
4186 }
Greg Clayton7f995132011-10-04 22:41:51 +00004187 break;
Paul Hermand628cbb2015-09-15 23:44:17 +00004188 case DW_AT_specification:
Greg Clayton2f869fe2016-03-30 20:14:35 +00004189 spec_die = GetDIE(DIERef(form_value));
Paul Hermand628cbb2015-09-15 23:44:17 +00004190 break;
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004191 case DW_AT_start_scope:
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004192 {
Greg Clayton31460392016-03-18 20:33:49 +00004193 if (form_value.Form() == DW_FORM_sec_offset)
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004194 {
Greg Clayton31460392016-03-18 20:33:49 +00004195 DWARFRangeList dwarf_scope_ranges;
4196 const DWARFDebugRanges* debug_ranges = DebugRanges();
4197 debug_ranges->FindRanges(form_value.Unsigned(), dwarf_scope_ranges);
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004198
Greg Clayton31460392016-03-18 20:33:49 +00004199 // All DW_AT_start_scope are relative to the base address of the
4200 // compile unit. We add the compile unit base address to make
4201 // sure all the addresses are properly fixed up.
4202 for (size_t i = 0, count = dwarf_scope_ranges.GetSize(); i < count; ++i)
4203 {
4204 const DWARFRangeList::Entry& range = dwarf_scope_ranges.GetEntryRef(i);
4205 scope_ranges.Append(range.GetRangeBase() + die.GetCU()->GetBaseAddress(),
4206 range.GetByteSize());
4207 }
4208 }
4209 else
4210 {
4211 // TODO: Handle the case when DW_AT_start_scope have form constant. The
4212 // dwarf spec is a bit ambiguous about what is the expected behavior in
4213 // case the enclosing block have a non coninious address range and the
4214 // DW_AT_start_scope entry have a form constant.
4215 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_start_scope has unsupported form type (0x%x)\n",
4216 die.GetID(),
4217 form_value.Form());
4218 }
4219
4220 scope_ranges.Sort();
4221 scope_ranges.CombineConsecutiveRanges();
4222 }
4223 break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00004224 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00004225 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7f995132011-10-04 22:41:51 +00004226 case DW_AT_declaration:
4227 case DW_AT_description:
4228 case DW_AT_endianity:
4229 case DW_AT_segment:
Greg Clayton7f995132011-10-04 22:41:51 +00004230 case DW_AT_visibility:
4231 default:
4232 case DW_AT_abstract_origin:
4233 case DW_AT_sibling:
Greg Clayton7f995132011-10-04 22:41:51 +00004234 break;
4235 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004236 }
4237 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004238
Greg Clayton6071e6f2015-08-26 22:57:51 +00004239 const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
4240 const dw_tag_t parent_tag = die.GetParent().Tag();
4241 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 +00004242
Greg Clayton9e9f2192013-05-17 00:55:28 +00004243 ValueType scope = eValueTypeInvalid;
4244
Greg Clayton6071e6f2015-08-26 22:57:51 +00004245 const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
Greg Clayton9e9f2192013-05-17 00:55:28 +00004246 SymbolContextScope * symbol_context_scope = NULL;
4247
Siva Chandra0783ab92015-03-24 18:32:27 +00004248 if (!mangled)
4249 {
4250 // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
4251 // generate fully qualified names of global variables with commands like "frame var j".
4252 // For example, if j were an int variable holding a value 4 and declared in a namespace
4253 // B which in turn is contained in a namespace A, the command "frame var j" returns
4254 // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
4255 // to generate a fully qualified name from the declaration context.
Greg Clayton6071e6f2015-08-26 22:57:51 +00004256 if (parent_tag == DW_TAG_compile_unit &&
Jim Ingham0e0984e2015-09-02 01:06:46 +00004257 Language::LanguageIsCPlusPlus(die.GetLanguage()))
Siva Chandra0783ab92015-03-24 18:32:27 +00004258 {
4259 DWARFDeclContext decl_ctx;
4260
Greg Clayton6071e6f2015-08-26 22:57:51 +00004261 die.GetDWARFDeclContext(decl_ctx);
Siva Chandra0783ab92015-03-24 18:32:27 +00004262 mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
4263 }
4264 }
4265
Greg Clayton9e9f2192013-05-17 00:55:28 +00004266 // DWARF doesn't specify if a DW_TAG_variable is a local, global
4267 // or static variable, so we have to do a little digging by
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004268 // looking at the location of a variable to see if it contains
Greg Clayton9e9f2192013-05-17 00:55:28 +00004269 // a DW_OP_addr opcode _somewhere_ in the definition. I say
4270 // somewhere because clang likes to combine small global variables
4271 // into the same symbol and have locations like:
4272 // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
4273 // So if we don't have a DW_TAG_formal_parameter, we can look at
4274 // the location to see if it contains a DW_OP_addr opcode, and
4275 // then we can correctly classify our variables.
4276 if (tag == DW_TAG_formal_parameter)
4277 scope = eValueTypeVariableArgument;
4278 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004279 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004280 bool op_error = false;
4281 // Check if the location has a DW_OP_addr with any address value...
4282 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
4283 if (!location_is_const_value_data)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004284 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004285 location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
4286 if (op_error)
Greg Clayton96c09682012-01-04 22:56:43 +00004287 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004288 StreamString strm;
4289 location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
Greg Clayton6071e6f2015-08-26 22:57:51 +00004290 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 +00004291 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00004292 }
Greg Claytond1767f02011-12-08 02:13:16 +00004293
Greg Clayton9e9f2192013-05-17 00:55:28 +00004294 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
4295 {
4296 if (is_external)
4297 scope = eValueTypeVariableGlobal;
4298 else
4299 scope = eValueTypeVariableStatic;
4300
4301
Greg Clayton2f869fe2016-03-30 20:14:35 +00004302 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
Greg Clayton9e9f2192013-05-17 00:55:28 +00004303
4304 if (debug_map_symfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004305 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004306 // When leaving the DWARF in the .o files on darwin,
4307 // when we have a global variable that wasn't initialized,
4308 // the .o file might not have allocated a virtual
4309 // address for the global variable. In this case it will
4310 // have created a symbol for the global variable
4311 // that is undefined/data and external and the value will
4312 // be the byte size of the variable. When we do the
4313 // address map in SymbolFileDWARFDebugMap we rely on
4314 // having an address, we need to do some magic here
4315 // so we can get the correct address for our global
4316 // variable. The address for all of these entries
4317 // will be zero, and there will be an undefined symbol
4318 // in this object file, and the executable will have
4319 // a matching symbol with a good address. So here we
4320 // dig up the correct address and replace it in the
4321 // location for the variable, and set the variable's
4322 // symbol context scope to be that of the main executable
4323 // so the file address will resolve correctly.
4324 bool linked_oso_file_addr = false;
4325 if (is_external && location_DW_OP_addr == 0)
Greg Clayton9422dd62013-03-04 21:46:16 +00004326 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004327 // we have a possible uninitialized extern global
4328 ConstString const_name(mangled ? mangled : name);
4329 ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
4330 if (debug_map_objfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004331 {
Greg Clayton3046e662013-07-10 01:23:25 +00004332 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
Greg Clayton9e9f2192013-05-17 00:55:28 +00004333 if (debug_map_symtab)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004334 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004335 Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
4336 eSymbolTypeData,
4337 Symtab::eDebugYes,
4338 Symtab::eVisibilityExtern);
4339 if (exe_symbol)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004340 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004341 if (exe_symbol->ValueIsAddress())
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004342 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004343 const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
Greg Clayton9e9f2192013-05-17 00:55:28 +00004344 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004345 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004346 if (location.Update_DW_OP_addr (exe_file_addr))
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004347 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004348 linked_oso_file_addr = true;
4349 symbol_context_scope = exe_symbol;
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004350 }
4351 }
4352 }
4353 }
4354 }
4355 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00004356 }
Greg Clayton9422dd62013-03-04 21:46:16 +00004357
Greg Clayton9e9f2192013-05-17 00:55:28 +00004358 if (!linked_oso_file_addr)
4359 {
4360 // The DW_OP_addr is not zero, but it contains a .o file address which
4361 // needs to be linked up correctly.
4362 const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
4363 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton9422dd62013-03-04 21:46:16 +00004364 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00004365 // Update the file address for this variable
4366 location.Update_DW_OP_addr (exe_file_addr);
4367 }
4368 else
4369 {
4370 // Variable didn't make it into the final executable
4371 return var_sp;
Greg Clayton9422dd62013-03-04 21:46:16 +00004372 }
Greg Claytond1767f02011-12-08 02:13:16 +00004373 }
Greg Clayton2fc93ea2011-11-13 04:15:56 +00004374 }
Greg Clayton5cf58b92011-10-05 22:22:08 +00004375 }
4376 else
4377 {
Ewan Crawford37395ad2015-12-17 11:59:47 +00004378 if (location_is_const_value_data)
4379 scope = eValueTypeVariableStatic;
4380 else
4381 scope = eValueTypeVariableLocal;
Greg Clayton5cf58b92011-10-05 22:22:08 +00004382 }
Greg Clayton7f995132011-10-04 22:41:51 +00004383 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00004384
4385 if (symbol_context_scope == NULL)
4386 {
4387 switch (parent_tag)
4388 {
4389 case DW_TAG_subprogram:
4390 case DW_TAG_inlined_subroutine:
4391 case DW_TAG_lexical_block:
4392 if (sc.function)
4393 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004394 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
Greg Clayton9e9f2192013-05-17 00:55:28 +00004395 if (symbol_context_scope == NULL)
4396 symbol_context_scope = sc.function;
4397 }
4398 break;
4399
4400 default:
4401 symbol_context_scope = sc.comp_unit;
4402 break;
4403 }
4404 }
4405
4406 if (symbol_context_scope)
4407 {
Greg Clayton2f869fe2016-03-30 20:14:35 +00004408 SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004409
Enrico Granata4ec130d2014-08-11 19:16:35 +00004410 if (const_value.Form() && type_sp && type_sp->GetType())
Greg Clayton6071e6f2015-08-26 22:57:51 +00004411 location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004412
Greg Clayton6071e6f2015-08-26 22:57:51 +00004413 var_sp.reset (new Variable (die.GetID(),
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004414 name,
Greg Clayton9e9f2192013-05-17 00:55:28 +00004415 mangled,
Enrico Granata4ec130d2014-08-11 19:16:35 +00004416 type_sp,
Tamas Berghammer72ac8a82016-02-25 12:23:37 +00004417 scope,
4418 symbol_context_scope,
4419 scope_ranges,
4420 &decl,
4421 location,
4422 is_external,
Paul Herman10bc1a42015-08-18 22:46:57 +00004423 is_artificial,
4424 is_static_member));
Greg Clayton9e9f2192013-05-17 00:55:28 +00004425
4426 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
4427 }
4428 else
4429 {
4430 // Not ready to parse this variable yet. It might be a global
4431 // or static variable that is in a function scope and the function
4432 // in the symbol context wasn't filled in yet
4433 return var_sp;
4434 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004435 }
Greg Clayton7f995132011-10-04 22:41:51 +00004436 // Cache var_sp even if NULL (the variable was just a specification or
4437 // was missing vital information to be able to be displayed in the debugger
4438 // (missing location due to optimization, etc)) so we don't re-parse
4439 // this DIE over and over later...
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004440 GetDIEToVariable()[die.GetDIE()] = var_sp;
Paul Hermand628cbb2015-09-15 23:44:17 +00004441 if (spec_die)
4442 GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004443 }
4444 return var_sp;
4445}
4446
Greg Claytonc662ec82011-06-17 22:10:16 +00004447
Greg Clayton6071e6f2015-08-26 22:57:51 +00004448DWARFDIE
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004449SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref,
Greg Clayton6071e6f2015-08-26 22:57:51 +00004450 dw_offset_t spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004451{
4452 // Give the concrete function die specified by "func_die_offset", find the
4453 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4454 // to "spec_block_die_offset"
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004455 return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset);
Greg Claytonc662ec82011-06-17 22:10:16 +00004456}
4457
4458
Greg Clayton6071e6f2015-08-26 22:57:51 +00004459DWARFDIE
4460SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die,
4461 dw_offset_t spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004462{
4463 if (die)
4464 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004465 switch (die.Tag())
Greg Claytonc662ec82011-06-17 22:10:16 +00004466 {
4467 case DW_TAG_subprogram:
4468 case DW_TAG_inlined_subroutine:
4469 case DW_TAG_lexical_block:
4470 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004471 if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004472 return die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004473
Greg Clayton6071e6f2015-08-26 22:57:51 +00004474 if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
Greg Claytonc662ec82011-06-17 22:10:16 +00004475 return die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004476 }
4477 break;
4478 }
4479
4480 // Give the concrete function die specified by "func_die_offset", find the
4481 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4482 // to "spec_block_die_offset"
Greg Clayton6071e6f2015-08-26 22:57:51 +00004483 for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling())
Greg Claytonc662ec82011-06-17 22:10:16 +00004484 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004485 DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset);
Greg Claytonc662ec82011-06-17 22:10:16 +00004486 if (result_die)
4487 return result_die;
4488 }
4489 }
4490
Greg Clayton6071e6f2015-08-26 22:57:51 +00004491 return DWARFDIE();
Greg Claytonc662ec82011-06-17 22:10:16 +00004492}
4493
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004494size_t
Greg Clayton6071e6f2015-08-26 22:57:51 +00004495SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
4496 const DWARFDIE &orig_die,
4497 const lldb::addr_t func_low_pc,
4498 bool parse_siblings,
4499 bool parse_children,
4500 VariableList* cc_variable_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004501{
Greg Clayton6071e6f2015-08-26 22:57:51 +00004502 if (!orig_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004503 return 0;
4504
Greg Claytonc662ec82011-06-17 22:10:16 +00004505 VariableListSP variable_list_sp;
4506
4507 size_t vars_added = 0;
Greg Clayton6071e6f2015-08-26 22:57:51 +00004508 DWARFDIE die = orig_die;
4509 while (die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004510 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004511 dw_tag_t tag = die.Tag();
Greg Claytonc662ec82011-06-17 22:10:16 +00004512
4513 // Check to see if we have already parsed this variable or constant?
Tamas Berghammereb882fc2015-09-09 10:20:48 +00004514 VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
Greg Clayton6071e6f2015-08-26 22:57:51 +00004515 if (var_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004516 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004517 if (cc_variable_list)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004518 cc_variable_list->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004519 }
4520 else
4521 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004522 // We haven't already parsed it, lets do that now.
4523 if ((tag == DW_TAG_variable) ||
4524 (tag == DW_TAG_constant) ||
4525 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004526 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004527 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004528 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004529 DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
4530 dw_tag_t parent_tag = sc_parent_die.Tag();
Greg Claytonc662ec82011-06-17 22:10:16 +00004531 switch (parent_tag)
4532 {
4533 case DW_TAG_compile_unit:
4534 if (sc.comp_unit != NULL)
4535 {
4536 variable_list_sp = sc.comp_unit->GetVariableList(false);
4537 if (variable_list_sp.get() == NULL)
4538 {
4539 variable_list_sp.reset(new VariableList());
4540 sc.comp_unit->SetVariableList(variable_list_sp);
4541 }
4542 }
4543 else
4544 {
Daniel Malead01b2952012-11-29 21:49:15 +00004545 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 +00004546 sc_parent_die.GetID(),
4547 sc_parent_die.GetTagAsCString(),
4548 orig_die.GetID(),
4549 orig_die.GetTagAsCString());
Greg Claytonc662ec82011-06-17 22:10:16 +00004550 }
4551 break;
4552
4553 case DW_TAG_subprogram:
4554 case DW_TAG_inlined_subroutine:
4555 case DW_TAG_lexical_block:
4556 if (sc.function != NULL)
4557 {
4558 // Check to see if we already have parsed the variables for the given scope
4559
Greg Clayton6071e6f2015-08-26 22:57:51 +00004560 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
Greg Claytonc662ec82011-06-17 22:10:16 +00004561 if (block == NULL)
4562 {
4563 // This must be a specification or abstract origin with
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004564 // a concrete block counterpart in the current function. We need
Greg Claytonc662ec82011-06-17 22:10:16 +00004565 // to find the concrete block so we can correctly add the
4566 // variable to it
Greg Clayton2f869fe2016-03-30 20:14:35 +00004567 const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID(), this),
Greg Clayton6071e6f2015-08-26 22:57:51 +00004568 sc_parent_die.GetOffset());
Greg Claytonc662ec82011-06-17 22:10:16 +00004569 if (concrete_block_die)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004570 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
Greg Claytonc662ec82011-06-17 22:10:16 +00004571 }
4572
4573 if (block != NULL)
4574 {
4575 const bool can_create = false;
4576 variable_list_sp = block->GetBlockVariableList (can_create);
4577 if (variable_list_sp.get() == NULL)
4578 {
4579 variable_list_sp.reset(new VariableList());
4580 block->SetVariableList(variable_list_sp);
4581 }
4582 }
4583 }
4584 break;
4585
4586 default:
Daniel Malead01b2952012-11-29 21:49:15 +00004587 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 +00004588 orig_die.GetID(),
4589 orig_die.GetTagAsCString());
Greg Claytonc662ec82011-06-17 22:10:16 +00004590 break;
4591 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004592 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004593
4594 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004595 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004596 VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc));
Greg Clayton73bf5db2011-06-17 01:22:15 +00004597 if (var_sp)
4598 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004599 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00004600 if (cc_variable_list)
4601 cc_variable_list->AddVariableIfUnique (var_sp);
4602 ++vars_added;
4603 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004604 }
4605 }
4606 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004607
4608 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4609
Greg Clayton6071e6f2015-08-26 22:57:51 +00004610 if (!skip_children && parse_children && die.HasChildren())
Greg Claytonc662ec82011-06-17 22:10:16 +00004611 {
Greg Clayton6071e6f2015-08-26 22:57:51 +00004612 vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list);
Greg Claytonc662ec82011-06-17 22:10:16 +00004613 }
4614
4615 if (parse_siblings)
Greg Clayton6071e6f2015-08-26 22:57:51 +00004616 die = die.GetSibling();
Greg Claytonc662ec82011-06-17 22:10:16 +00004617 else
Greg Clayton6071e6f2015-08-26 22:57:51 +00004618 die.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004619 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004620 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004621}
4622
4623//------------------------------------------------------------------
4624// PluginInterface protocol
4625//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00004626ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004627SymbolFileDWARF::GetPluginName()
4628{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004629 return GetPluginNameStatic();
4630}
4631
4632uint32_t
4633SymbolFileDWARF::GetPluginVersion()
4634{
4635 return 1;
4636}
4637
4638void
Sean Callanancc427fa2011-07-30 02:42:06 +00004639SymbolFileDWARF::DumpIndexes ()
4640{
4641 StreamFile s(stdout, false);
4642
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00004643 s.Printf ("DWARF index for (%s) '%s':",
Sean Callanancc427fa2011-07-30 02:42:06 +00004644 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00004645 GetObjectFile()->GetFileSpec().GetPath().c_str());
Sean Callanancc427fa2011-07-30 02:42:06 +00004646 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
4647 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
4648 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
4649 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
4650 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
4651 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
4652 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Bruce Mitchenere171da52015-07-22 00:16:02 +00004653 s.Printf("\nNamespaces:\n"); m_namespace_index.Dump (&s);
Sean Callanancc427fa2011-07-30 02:42:06 +00004654}
4655
Greg Claytoncaab74e2012-01-28 00:48:57 +00004656
Greg Clayton1f746072012-08-29 21:13:06 +00004657SymbolFileDWARFDebugMap *
Greg Clayton2f869fe2016-03-30 20:14:35 +00004658SymbolFileDWARF::GetDebugMapSymfile()
Greg Clayton1f746072012-08-29 21:13:06 +00004659{
4660 if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
4661 {
4662 lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
4663 if (module_sp)
4664 {
4665 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
4666 if (sym_vendor)
4667 m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
4668 }
4669 }
4670 return m_debug_map_symfile;
4671}
Tamas Berghammer1f5e4482015-09-16 12:37:06 +00004672
4673DWARFExpression::LocationListFormat
4674SymbolFileDWARF::GetLocationListFormat() const
4675{
4676 return DWARFExpression::RegularLocationList;
4677}