]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
Update llvm, clang and lldb to trunk r257626, and update build glue.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / LanguageRuntime / CPlusPlus / ItaniumABI / ItaniumABILanguageRuntime.cpp
1 //===-- ItaniumABILanguageRuntime.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 "ItaniumABILanguageRuntime.h"
11
12 #include "lldb/Breakpoint/BreakpointLocation.h"
13 #include "lldb/Core/ConstString.h"
14 #include "lldb/Core/Error.h"
15 #include "lldb/Core/Log.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Scalar.h"
19 #include "lldb/Core/ValueObject.h"
20 #include "lldb/Core/ValueObjectMemory.h"
21 #include "lldb/Symbol/ClangASTContext.h"
22 #include "lldb/Symbol/Symbol.h"
23 #include "lldb/Symbol/TypeList.h"
24 #include "lldb/Target/Process.h"
25 #include "lldb/Target/RegisterContext.h"
26 #include "lldb/Target/SectionLoadList.h"
27 #include "lldb/Target/StopInfo.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Target/Thread.h"
30
31 #include <vector>
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 static const char *vtable_demangled_prefix = "vtable for ";
37
38 bool
39 ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
40 {
41     const bool check_cxx = true;
42     const bool check_objc = false;
43     return in_value.GetCompilerType().IsPossibleDynamicType (NULL, check_cxx, check_objc);
44 }
45
46 bool
47 ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, 
48                                                      lldb::DynamicValueType use_dynamic, 
49                                                      TypeAndOrName &class_type_or_name, 
50                                                      Address &dynamic_address,
51                                                      Value::ValueType &value_type)
52 {
53     // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
54     // in the object.  That will point to the "address point" within the vtable (not the beginning of the
55     // vtable.)  We can then look up the symbol containing this "address point" and that symbol's name 
56     // demangled will contain the full class name.
57     // The second pointer above the "address point" is the "offset_to_top".  We'll use that to get the
58     // start of the value object which holds the dynamic type.
59     //
60     
61     class_type_or_name.Clear();
62     value_type = Value::ValueType::eValueTypeScalar;
63     
64     // Only a pointer or reference type can have a different dynamic and static type:
65     if (CouldHaveDynamicValue (in_value))
66     {
67         // First job, pull out the address at 0 offset from the object.
68         AddressType address_type;
69         lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
70         if (original_ptr == LLDB_INVALID_ADDRESS)
71             return false;
72         
73         ExecutionContext exe_ctx (in_value.GetExecutionContextRef());
74
75         Target *target = exe_ctx.GetTargetPtr();
76         Process *process = exe_ctx.GetProcessPtr();
77
78         char memory_buffer[16];
79         DataExtractor data(memory_buffer, sizeof(memory_buffer), 
80                            process->GetByteOrder(), 
81                            process->GetAddressByteSize());
82         size_t address_byte_size = process->GetAddressByteSize();
83         Error error;
84         size_t bytes_read = process->ReadMemory (original_ptr, 
85                                                  memory_buffer, 
86                                                  address_byte_size, 
87                                                  error);
88         if (!error.Success() || (bytes_read != address_byte_size))
89         {
90             return false;
91         }
92         
93         lldb::offset_t offset = 0;
94         lldb::addr_t vtable_address_point = data.GetAddress (&offset);
95             
96         if (offset == 0)
97             return false;
98         
99         // Now find the symbol that contains this address:
100         
101         SymbolContext sc;
102         Address address_point_address;
103         if (target && !target->GetSectionLoadList().IsEmpty())
104         {
105             if (target->GetSectionLoadList().ResolveLoadAddress (vtable_address_point, address_point_address))
106             {
107                 target->GetImages().ResolveSymbolContextForAddress (address_point_address, eSymbolContextSymbol, sc);
108                 Symbol *symbol = sc.symbol;
109                 if (symbol != NULL)
110                 {
111                     const char *name = symbol->GetMangled().GetDemangledName(lldb::eLanguageTypeC_plus_plus).AsCString();
112                     if (name && strstr(name, vtable_demangled_prefix) == name)
113                     {
114                         Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
115                         if (log)
116                             log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n",
117                                          original_ptr,
118                                          in_value.GetTypeName().GetCString(),
119                                          name);
120                         // We are a C++ class, that's good.  Get the class name and look it up:
121                         const char *class_name = name + strlen(vtable_demangled_prefix);
122                         class_type_or_name.SetName (class_name);
123                         const bool exact_match = true;
124                         TypeList class_types;
125                         
126                         uint32_t num_matches = 0;
127                         // First look in the module that the vtable symbol came from
128                         // and look for a single exact match.
129                         if (sc.module_sp)
130                         {
131                             num_matches = sc.module_sp->FindTypes (sc,
132                                                                    ConstString(class_name),
133                                                                    exact_match,
134                                                                    1,
135                                                                    class_types);
136                         }
137                         
138                         // If we didn't find a symbol, then move on to the entire
139                         // module list in the target and get as many unique matches
140                         // as possible
141                         if (num_matches == 0)
142                         {
143                             num_matches = target->GetImages().FindTypes (sc,
144                                                                          ConstString(class_name),
145                                                                          exact_match,
146                                                                          UINT32_MAX,
147                                                                          class_types);
148                         }
149                         
150                         lldb::TypeSP type_sp;
151                         if (num_matches == 0)
152                         {
153                             if (log)
154                                 log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", original_ptr);
155                             return false;
156                         }
157                         if (num_matches == 1)
158                         {
159                             type_sp = class_types.GetTypeAtIndex(0);
160                             if (log)
161                                 log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has dynamic type: uid={0x%" PRIx64 "}, type-name='%s'\n",
162                                              original_ptr,
163                                              in_value.GetTypeName().AsCString(),
164                                              type_sp->GetID(),
165                                              type_sp->GetName().GetCString());
166
167                             class_type_or_name.SetTypeSP(class_types.GetTypeAtIndex(0));
168                         }
169                         else if (num_matches > 1)
170                         {
171                             size_t i;
172                             if (log)
173                             {
174                                 for (i = 0; i < num_matches; i++)
175                                 {
176                                     type_sp = class_types.GetTypeAtIndex(i);
177                                     if (type_sp)
178                                     {
179                                         if (log)
180                                             log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types: uid={0x%" PRIx64 "}, type-name='%s'\n",
181                                                          original_ptr,
182                                                          in_value.GetTypeName().AsCString(),
183                                                          type_sp->GetID(),
184                                                          type_sp->GetName().GetCString());
185                                     }
186                                 }
187                             }
188
189                             for (i = 0; i < num_matches; i++)
190                             {
191                                 type_sp = class_types.GetTypeAtIndex(i);
192                                 if (type_sp)
193                                 {
194                                     if (ClangASTContext::IsCXXClassType(type_sp->GetFullCompilerType ()))
195                                     {
196                                         if (log)
197                                             log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
198                                                          original_ptr,
199                                                          in_value.GetTypeName().AsCString(),
200                                                          type_sp->GetID(),
201                                                          type_sp->GetName().GetCString());
202                                         class_type_or_name.SetTypeSP(type_sp);
203                                         break;
204                                     }
205                                 }
206                             }
207                             
208                             if (i == num_matches)
209                             {
210                                 if (log)
211                                     log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, didn't find a C++ match\n",
212                                                  original_ptr,
213                                                  in_value.GetTypeName().AsCString());
214                                 return false;
215                             }
216                         }
217
218                         // There can only be one type with a given name,
219                         // so we've just found duplicate definitions, and this
220                         // one will do as well as any other.
221                         // We don't consider something to have a dynamic type if
222                         // it is the same as the static type.  So compare against
223                         // the value we were handed.
224                         if (type_sp)
225                         {
226                             if (ClangASTContext::AreTypesSame (in_value.GetCompilerType(),
227                                                                type_sp->GetFullCompilerType ()))
228                             {
229                                 // The dynamic type we found was the same type,
230                                 // so we don't have a dynamic type here...
231                                 return false;
232                             }
233
234                             // The offset_to_top is two pointers above the address.
235                             Address offset_to_top_address = address_point_address;
236                             int64_t slide = -2 * ((int64_t) target->GetArchitecture().GetAddressByteSize());
237                             offset_to_top_address.Slide (slide);
238                             
239                             Error error;
240                             lldb::addr_t offset_to_top_location = offset_to_top_address.GetLoadAddress(target);
241                             
242                             size_t bytes_read = process->ReadMemory (offset_to_top_location, 
243                                                                      memory_buffer, 
244                                                                      address_byte_size, 
245                                                                      error);
246                                                                      
247                             if (!error.Success() || (bytes_read != address_byte_size))
248                             {
249                                 return false;
250                             }
251                             
252                             offset = 0;
253                             int64_t offset_to_top = data.GetMaxS64(&offset, process->GetAddressByteSize());
254                             
255                             // So the dynamic type is a value that starts at offset_to_top
256                             // above the original address.
257                             lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
258                             if (!target->GetSectionLoadList().ResolveLoadAddress (dynamic_addr, dynamic_address))
259                             {
260                                 dynamic_address.SetRawAddress(dynamic_addr);
261                             }
262                             return true;
263                         }
264                     }
265                 }
266             }
267         }
268     }
269     
270     return class_type_or_name.IsEmpty() == false;
271 }
272
273 TypeAndOrName
274 ItaniumABILanguageRuntime::FixUpDynamicType(const TypeAndOrName& type_and_or_name,
275                                             ValueObject& static_value)
276 {
277     CompilerType static_type(static_value.GetCompilerType());
278     Flags static_type_flags(static_type.GetTypeInfo());
279     
280     TypeAndOrName ret(type_and_or_name);
281     if (type_and_or_name.HasType())
282     {
283         // The type will always be the type of the dynamic object.  If our parent's type was a pointer,
284         // then our type should be a pointer to the type of the dynamic object.  If a reference, then the original type
285         // should be okay...
286         CompilerType orig_type = type_and_or_name.GetCompilerType();
287         CompilerType corrected_type = orig_type;
288         if (static_type_flags.AllSet(eTypeIsPointer))
289             corrected_type = orig_type.GetPointerType ();
290         else if (static_type_flags.AllSet(eTypeIsReference))
291             corrected_type = orig_type.GetLValueReferenceType();
292         ret.SetCompilerType(corrected_type);
293     }
294     else
295     {
296         // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
297         std::string corrected_name (type_and_or_name.GetName().GetCString());
298         if (static_type_flags.AllSet(eTypeIsPointer))
299             corrected_name.append(" *");
300         else if (static_type_flags.AllSet(eTypeIsReference))
301             corrected_name.append(" &");
302         // the parent type should be a correctly pointer'ed or referenc'ed type
303         ret.SetCompilerType(static_type);
304         ret.SetName(corrected_name.c_str());
305     }
306     return ret;
307 }
308
309 bool
310 ItaniumABILanguageRuntime::IsVTableName (const char *name)
311 {
312     if (name == NULL)
313         return false;
314         
315     // Can we maybe ask Clang about this?
316     if (strstr (name, "_vptr$") == name)
317         return true;
318     else
319         return false;
320 }
321
322 //------------------------------------------------------------------
323 // Static Functions
324 //------------------------------------------------------------------
325 LanguageRuntime *
326 ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language)
327 {
328     // FIXME: We have to check the process and make sure we actually know that this process supports
329     // the Itanium ABI.
330     if (language == eLanguageTypeC_plus_plus ||
331         language == eLanguageTypeC_plus_plus_03 ||
332         language == eLanguageTypeC_plus_plus_11 ||
333         language == eLanguageTypeC_plus_plus_14)
334         return new ItaniumABILanguageRuntime (process);
335     else
336         return NULL;
337 }
338
339 void
340 ItaniumABILanguageRuntime::Initialize()
341 {
342     PluginManager::RegisterPlugin (GetPluginNameStatic(),
343                                    "Itanium ABI for the C++ language",
344                                    CreateInstance);    
345 }
346
347 void
348 ItaniumABILanguageRuntime::Terminate()
349 {
350     PluginManager::UnregisterPlugin (CreateInstance);
351 }
352
353 lldb_private::ConstString
354 ItaniumABILanguageRuntime::GetPluginNameStatic()
355 {
356     static ConstString g_name("itanium");
357     return g_name;
358 }
359
360 //------------------------------------------------------------------
361 // PluginInterface protocol
362 //------------------------------------------------------------------
363 lldb_private::ConstString
364 ItaniumABILanguageRuntime::GetPluginName()
365 {
366     return GetPluginNameStatic();
367 }
368
369 uint32_t
370 ItaniumABILanguageRuntime::GetPluginVersion()
371 {
372     return 1;
373 }
374
375 BreakpointResolverSP
376 ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
377 {
378     return CreateExceptionResolver (bkpt, catch_bp, throw_bp, false);
379 }
380
381 BreakpointResolverSP
382 ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions)
383 {
384     // One complication here is that most users DON'T want to stop at __cxa_allocate_expression, but until we can do
385     // anything better with predicting unwinding the expression parser does.  So we have two forms of the exception
386     // breakpoints, one for expressions that leaves out __cxa_allocate_exception, and one that includes it.
387     // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint in the runtime the former.
388     static const char *g_catch_name = "__cxa_begin_catch";
389     static const char *g_throw_name1 = "__cxa_throw";
390     static const char *g_throw_name2 = "__cxa_rethrow";
391     static const char *g_exception_throw_name = "__cxa_allocate_exception";
392     std::vector<const char *> exception_names;
393     exception_names.reserve(4);
394     if (catch_bp)
395         exception_names.push_back(g_catch_name);
396
397     if (throw_bp)
398     {
399         exception_names.push_back(g_throw_name1);
400         exception_names.push_back(g_throw_name2);
401     }
402
403     if (for_expressions)
404         exception_names.push_back(g_exception_throw_name);
405     
406     BreakpointResolverSP resolver_sp (new BreakpointResolverName (bkpt,
407                                                                   exception_names.data(),
408                                                                   exception_names.size(),
409                                                                   eFunctionNameTypeBase,
410                                                                   eLanguageTypeUnknown,
411                                                                   eLazyBoolNo));
412
413     return resolver_sp;
414 }
415
416
417
418 lldb::SearchFilterSP
419 ItaniumABILanguageRuntime::CreateExceptionSearchFilter ()
420 {
421     Target &target = m_process->GetTarget();
422
423     if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
424     {
425         // Limit the number of modules that are searched for these breakpoints for
426         // Apple binaries.
427         FileSpecList filter_modules;
428         filter_modules.Append(FileSpec("libc++abi.dylib", false));
429         filter_modules.Append(FileSpec("libSystem.B.dylib", false));
430         return target.GetSearchFilterForModuleList(&filter_modules);
431     }
432     else
433     {
434         return LanguageRuntime::CreateExceptionSearchFilter();
435     }
436 }
437
438 lldb::BreakpointSP
439 ItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp,
440                                                       bool throw_bp,
441                                                       bool for_expressions,
442                                                       bool is_internal)
443 {
444     Target &target = m_process->GetTarget();
445     FileSpecList filter_modules;
446     BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
447     SearchFilterSP filter_sp (CreateExceptionSearchFilter ());
448     const bool hardware = false;
449     const bool resolve_indirect_functions = false;
450     return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal, hardware, resolve_indirect_functions);
451 }
452
453 void
454 ItaniumABILanguageRuntime::SetExceptionBreakpoints ()
455 {
456     if (!m_process)
457         return;
458     
459     const bool catch_bp = false;
460     const bool throw_bp = true;
461     const bool is_internal = true;
462     const bool for_expressions = true;
463     
464     // For the exception breakpoints set by the Expression parser, we'll be a little more aggressive and
465     // stop at exception allocation as well.
466     
467     if (m_cxx_exception_bp_sp)
468     {
469         m_cxx_exception_bp_sp->SetEnabled (true);
470     }
471     else
472     {
473         m_cxx_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, for_expressions, is_internal);
474         if (m_cxx_exception_bp_sp)
475             m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
476     }
477     
478 }
479
480 void
481 ItaniumABILanguageRuntime::ClearExceptionBreakpoints ()
482 {
483     if (!m_process)
484         return;
485     
486     if (m_cxx_exception_bp_sp)
487     {
488         m_cxx_exception_bp_sp->SetEnabled (false);
489     }    
490 }
491
492 bool
493 ItaniumABILanguageRuntime::ExceptionBreakpointsAreSet ()
494 {
495     return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled();
496 }
497
498 bool
499 ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
500 {
501     if (!m_process)
502         return false;
503     
504     if (!stop_reason || 
505         stop_reason->GetStopReason() != eStopReasonBreakpoint)
506         return false;
507     
508     uint64_t break_site_id = stop_reason->GetValue();
509     return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(break_site_id,
510                                                                                m_cxx_exception_bp_sp->GetID());
511     
512 }