diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 | 
| commit | 94994d372d014ce4c8758b9605d63fae651bd8aa (patch) | |
| tree | 51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp | |
| parent | 39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp')
| -rw-r--r-- | source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp | 188 | 
1 files changed, 123 insertions, 65 deletions
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index fc661bbbf2c9b..49a3d40d7b371 100644 --- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -14,9 +14,11 @@  #include "lldb/Core/Mangled.h"  #include "lldb/Core/Module.h"  #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h"  #include "lldb/Core/ValueObject.h"  #include "lldb/Core/ValueObjectMemory.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/FunctionCaller.h"  #include "lldb/Interpreter/CommandObject.h"  #include "lldb/Interpreter/CommandObjectMultiword.h"  #include "lldb/Interpreter/CommandReturnObject.h" @@ -32,6 +34,7 @@  #include "lldb/Target/Thread.h"  #include "lldb/Utility/ConstString.h"  #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h"  #include "lldb/Utility/Status.h"  #include <vector> @@ -98,7 +101,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(              llvm::DenseSet<SymbolFile *> searched_symbol_files;              if (sc.module_sp) {                num_matches = sc.module_sp->FindTypes( -                  sc, ConstString(lookup_name), exact_match, 1, +                  ConstString(lookup_name), exact_match, 1,                    searched_symbol_files, class_types);              } @@ -106,7 +109,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(              // list in the target and get as many unique matches as possible              if (num_matches == 0) {                num_matches = target.GetImages().FindTypes( -                  sc, ConstString(lookup_name), exact_match, UINT32_MAX, +                  nullptr, ConstString(lookup_name), exact_match, UINT32_MAX,                    searched_symbol_files, class_types);              } @@ -204,71 +207,71 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(    // Only a pointer or reference type can have a different dynamic and static    // type: -  if (CouldHaveDynamicValue(in_value)) { -    // First job, pull out the address at 0 offset from the object. -    AddressType address_type; -    lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); -    if (original_ptr == LLDB_INVALID_ADDRESS) -      return false; +  if (!CouldHaveDynamicValue(in_value)) +    return false; -    ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); +  // First job, pull out the address at 0 offset from the object. +  AddressType address_type; +  lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); +  if (original_ptr == LLDB_INVALID_ADDRESS) +    return false; -    Process *process = exe_ctx.GetProcessPtr(); +  ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); -    if (process == nullptr) -      return false; +  Process *process = exe_ctx.GetProcessPtr(); -    Status error; -    const lldb::addr_t vtable_address_point = -        process->ReadPointerFromMemory(original_ptr, error); +  if (process == nullptr) +    return false; -    if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) { -      return false; -    } +  Status error; +  const lldb::addr_t vtable_address_point = +      process->ReadPointerFromMemory(original_ptr, error); -    class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr, -                                                      vtable_address_point); - -    if (class_type_or_name) { -      TypeSP type_sp = class_type_or_name.GetTypeSP(); -      // There can only be one type with a given name, so we've just found -      // duplicate definitions, and this one will do as well as any other. We -      // don't consider something to have a dynamic type if it is the same as -      // the static type.  So compare against the value we were handed. -      if (type_sp) { -        if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), -                                          type_sp->GetForwardCompilerType())) { -          // The dynamic type we found was the same type, so we don't have a -          // dynamic type here... -          return false; -        } +  if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) +    return false; -        // The offset_to_top is two pointers above the vtable pointer. -        const uint32_t addr_byte_size = process->GetAddressByteSize(); -        const lldb::addr_t offset_to_top_location = -            vtable_address_point - 2 * addr_byte_size; -        // Watch for underflow, offset_to_top_location should be less than -        // vtable_address_point -        if (offset_to_top_location >= vtable_address_point) -          return false; -        const int64_t offset_to_top = process->ReadSignedIntegerFromMemory( -            offset_to_top_location, addr_byte_size, INT64_MIN, error); - -        if (offset_to_top == INT64_MIN) -          return false; -        // So the dynamic type is a value that starts at offset_to_top above -        // the original address. -        lldb::addr_t dynamic_addr = original_ptr + offset_to_top; -        if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress( -                dynamic_addr, dynamic_address)) { -          dynamic_address.SetRawAddress(dynamic_addr); -        } -        return true; -      } -    } +  class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr, +                                                    vtable_address_point); + +  if (!class_type_or_name) +    return false; + +  TypeSP type_sp = class_type_or_name.GetTypeSP(); +  // There can only be one type with a given name, so we've just found +  // duplicate definitions, and this one will do as well as any other. We +  // don't consider something to have a dynamic type if it is the same as +  // the static type.  So compare against the value we were handed. +  if (!type_sp) +    return true; + +  if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), +                                    type_sp->GetForwardCompilerType())) { +    // The dynamic type we found was the same type, so we don't have a +    // dynamic type here... +    return false;    } -  return class_type_or_name.IsEmpty() == false; +  // The offset_to_top is two pointers above the vtable pointer. +  const uint32_t addr_byte_size = process->GetAddressByteSize(); +  const lldb::addr_t offset_to_top_location = +      vtable_address_point - 2 * addr_byte_size; +  // Watch for underflow, offset_to_top_location should be less than +  // vtable_address_point +  if (offset_to_top_location >= vtable_address_point) +    return false; +  const int64_t offset_to_top = process->ReadSignedIntegerFromMemory( +      offset_to_top_location, addr_byte_size, INT64_MIN, error); + +  if (offset_to_top == INT64_MIN) +    return false; +  // So the dynamic type is a value that starts at offset_to_top above +  // the original address. +  lldb::addr_t dynamic_addr = original_ptr + offset_to_top; +  if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress( +          dynamic_addr, dynamic_address)) { +    dynamic_address.SetRawAddress(dynamic_addr); +  } +  return true;  }  TypeAndOrName ItaniumABILanguageRuntime::FixUpDynamicType( @@ -309,10 +312,7 @@ bool ItaniumABILanguageRuntime::IsVTableName(const char *name) {      return false;    // Can we maybe ask Clang about this? -  if (strstr(name, "_vptr$") == name) -    return true; -  else -    return false; +  return strstr(name, "_vptr$") == name;  }  //------------------------------------------------------------------ @@ -483,8 +483,8 @@ lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() {      // Limit the number of modules that are searched for these breakpoints for      // Apple binaries.      FileSpecList filter_modules; -    filter_modules.Append(FileSpec("libc++abi.dylib", false)); -    filter_modules.Append(FileSpec("libSystem.B.dylib", false)); +    filter_modules.Append(FileSpec("libc++abi.dylib")); +    filter_modules.Append(FileSpec("libSystem.B.dylib"));      return target.GetSearchFilterForModuleList(&filter_modules);    } else {      return LanguageRuntime::CreateExceptionSearchFilter(); @@ -552,6 +552,64 @@ bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop(        break_site_id, m_cxx_exception_bp_sp->GetID());  } +ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread( +    ThreadSP thread_sp) { +  if (!thread_sp->SafeToCallFunctions()) +    return {}; + +  ClangASTContext *clang_ast_context = +      m_process->GetTarget().GetScratchClangASTContext(); +  CompilerType voidstar = +      clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + +  DiagnosticManager diagnostics; +  ExecutionContext exe_ctx; +  EvaluateExpressionOptions options; + +  options.SetUnwindOnError(true); +  options.SetIgnoreBreakpoints(true); +  options.SetStopOthers(true); +  options.SetTimeout(std::chrono::milliseconds(500)); +  options.SetTryAllThreads(false); +  thread_sp->CalculateExecutionContext(exe_ctx); + +  const ModuleList &modules = m_process->GetTarget().GetImages(); +  SymbolContextList contexts; +  SymbolContext context; + +  modules.FindSymbolsWithNameAndType( +      ConstString("__cxa_current_exception_type"), eSymbolTypeCode, contexts); +  contexts.GetContextAtIndex(0, context); +  Address addr = context.symbol->GetAddress(); + +  Status error; +  FunctionCaller *function_caller = +      m_process->GetTarget().GetFunctionCallerForLanguage( +          eLanguageTypeC, voidstar, addr, ValueList(), "caller", error); + +  ExpressionResults func_call_ret; +  Value results; +  func_call_ret = function_caller->ExecuteFunction(exe_ctx, nullptr, options, +                                                   diagnostics, results); +  if (func_call_ret != eExpressionCompleted || !error.Success()) { +    return ValueObjectSP(); +  } + +  size_t ptr_size = m_process->GetAddressByteSize(); +  addr_t result_ptr = results.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); +  addr_t exception_addr = +      m_process->ReadPointerFromMemory(result_ptr - ptr_size, error); + +  lldb_private::formatters::InferiorSizedWord exception_isw(exception_addr, +                                                            *m_process); +  ValueObjectSP exception = ValueObject::CreateValueObjectFromData( +      "exception", exception_isw.GetAsData(m_process->GetByteOrder()), exe_ctx, +      voidstar); +  exception = exception->GetDynamicValue(eDynamicDontRunTarget); + +  return exception; +} +  TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo(      const lldb_private::Address &vtable_addr) {    std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);  | 
