aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/LanguageRuntime/CPlusPlus
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/LanguageRuntime/CPlusPlus')
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp975
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h192
2 files changed, 552 insertions, 615 deletions
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index c49feb07200e..ddfbd864e92c 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -1,4 +1,5 @@
-//===-- ItaniumABILanguageRuntime.cpp --------------------------------------*- C++ -*-===//
+//===-- ItaniumABILanguageRuntime.cpp --------------------------------------*-
+//C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -40,579 +41,533 @@ using namespace lldb_private;
static const char *vtable_demangled_prefix = "vtable for ";
-bool
-ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
-{
- const bool check_cxx = true;
- const bool check_objc = false;
- return in_value.GetCompilerType().IsPossibleDynamicType (NULL, check_cxx, check_objc);
+bool ItaniumABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
+ const bool check_cxx = true;
+ const bool check_objc = false;
+ return in_value.GetCompilerType().IsPossibleDynamicType(NULL, check_cxx,
+ check_objc);
}
-TypeAndOrName
-ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(ValueObject &in_value, lldb::addr_t original_ptr,
- lldb::addr_t vtable_load_addr)
-{
- if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS)
- {
- // Find the symbol that contains the "vtable_load_addr" address
- Address vtable_addr;
- Target &target = m_process->GetTarget();
- if (!target.GetSectionLoadList().IsEmpty())
- {
- if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr, vtable_addr))
- {
- // See if we have cached info for this type already
- TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
- if (type_info)
- return type_info;
-
- SymbolContext sc;
- target.GetImages().ResolveSymbolContextForAddress(vtable_addr, eSymbolContextSymbol, sc);
- Symbol *symbol = sc.symbol;
- if (symbol != NULL)
- {
- const char *name = symbol->GetMangled().GetDemangledName(lldb::eLanguageTypeC_plus_plus).AsCString();
- if (name && strstr(name, vtable_demangled_prefix) == name)
- {
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n",
- original_ptr,
- in_value.GetTypeName().GetCString(),
- name);
- // We are a C++ class, that's good. Get the class name and look it up:
- const char *class_name = name + strlen(vtable_demangled_prefix);
- type_info.SetName(class_name);
- const bool exact_match = true;
- TypeList class_types;
-
- uint32_t num_matches = 0;
- // First look in the module that the vtable symbol came from
- // and look for a single exact match.
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- if (sc.module_sp)
- {
- num_matches = sc.module_sp->FindTypes (sc,
- ConstString(class_name),
- exact_match,
- 1,
- searched_symbol_files,
- class_types);
- }
-
- // If we didn't find a symbol, then move on to the entire
- // module list in the target and get as many unique matches
- // as possible
- if (num_matches == 0)
- {
- num_matches = target.GetImages().FindTypes(sc, ConstString(class_name), exact_match,
- UINT32_MAX, searched_symbol_files, class_types);
- }
-
- lldb::TypeSP type_sp;
- if (num_matches == 0)
- {
- if (log)
- log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", original_ptr);
- return TypeAndOrName();
- }
- if (num_matches == 1)
- {
- type_sp = class_types.GetTypeAtIndex(0);
- if (type_sp)
- {
- if (ClangASTContext::IsCXXClassType(type_sp->GetForwardCompilerType()))
- {
- if (log)
- log->Printf("0x%16.16" PRIx64
- ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
- "}, type-name='%s'\n",
- original_ptr, in_value.GetTypeName().AsCString(), type_sp->GetID(),
- type_sp->GetName().GetCString());
- type_info.SetTypeSP(type_sp);
- }
- }
- }
- else if (num_matches > 1)
- {
- size_t i;
- if (log)
- {
- for (i = 0; i < num_matches; i++)
- {
- type_sp = class_types.GetTypeAtIndex(i);
- if (type_sp)
- {
- if (log)
- log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types: uid={0x%" PRIx64 "}, type-name='%s'\n",
- original_ptr,
- in_value.GetTypeName().AsCString(),
- type_sp->GetID(),
- type_sp->GetName().GetCString());
- }
- }
- }
-
- for (i = 0; i < num_matches; i++)
- {
- type_sp = class_types.GetTypeAtIndex(i);
- if (type_sp)
- {
- if (ClangASTContext::IsCXXClassType(type_sp->GetForwardCompilerType()))
- {
- if (log)
- log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
- original_ptr,
- in_value.GetTypeName().AsCString(),
- type_sp->GetID(),
- type_sp->GetName().GetCString());
- type_info.SetTypeSP(type_sp);
- }
- }
- }
-
- if (log && i == num_matches)
- {
- log->Printf("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic "
- "types, didn't find a C++ match\n",
- original_ptr, in_value.GetTypeName().AsCString());
- }
- }
- if (type_info)
- SetDynamicTypeInfo(vtable_addr, type_info);
- return type_info;
- }
+TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
+ ValueObject &in_value, lldb::addr_t original_ptr,
+ lldb::addr_t vtable_load_addr) {
+ if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS) {
+ // Find the symbol that contains the "vtable_load_addr" address
+ Address vtable_addr;
+ Target &target = m_process->GetTarget();
+ if (!target.GetSectionLoadList().IsEmpty()) {
+ if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr,
+ vtable_addr)) {
+ // See if we have cached info for this type already
+ TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
+ if (type_info)
+ return type_info;
+
+ SymbolContext sc;
+ target.GetImages().ResolveSymbolContextForAddress(
+ vtable_addr, eSymbolContextSymbol, sc);
+ Symbol *symbol = sc.symbol;
+ if (symbol != NULL) {
+ const char *name =
+ symbol->GetMangled()
+ .GetDemangledName(lldb::eLanguageTypeC_plus_plus)
+ .AsCString();
+ if (name && strstr(name, vtable_demangled_prefix) == name) {
+ Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("0x%16.16" PRIx64
+ ": static-type = '%s' has vtable symbol '%s'\n",
+ original_ptr, in_value.GetTypeName().GetCString(),
+ name);
+ // We are a C++ class, that's good. Get the class name and look it
+ // up:
+ const char *class_name = name + strlen(vtable_demangled_prefix);
+ type_info.SetName(class_name);
+ const bool exact_match = true;
+ TypeList class_types;
+
+ uint32_t num_matches = 0;
+ // First look in the module that the vtable symbol came from
+ // and look for a single exact match.
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ if (sc.module_sp) {
+ num_matches = sc.module_sp->FindTypes(
+ sc, ConstString(class_name), exact_match, 1,
+ searched_symbol_files, class_types);
+ }
+
+ // If we didn't find a symbol, then move on to the entire
+ // module list in the target and get as many unique matches
+ // as possible
+ if (num_matches == 0) {
+ num_matches = target.GetImages().FindTypes(
+ sc, ConstString(class_name), exact_match, UINT32_MAX,
+ searched_symbol_files, class_types);
+ }
+
+ lldb::TypeSP type_sp;
+ if (num_matches == 0) {
+ if (log)
+ log->Printf("0x%16.16" PRIx64 ": is not dynamic\n",
+ original_ptr);
+ return TypeAndOrName();
+ }
+ if (num_matches == 1) {
+ type_sp = class_types.GetTypeAtIndex(0);
+ if (type_sp) {
+ if (ClangASTContext::IsCXXClassType(
+ type_sp->GetForwardCompilerType())) {
+ if (log)
+ log->Printf(
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
+ "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
+ type_info.SetTypeSP(type_sp);
+ }
+ }
+ } else if (num_matches > 1) {
+ size_t i;
+ if (log) {
+ for (i = 0; i < num_matches; i++) {
+ type_sp = class_types.GetTypeAtIndex(i);
+ if (type_sp) {
+ if (log)
+ log->Printf(
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has multiple matching dynamic "
+ "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
+ }
}
+ }
+
+ for (i = 0; i < num_matches; i++) {
+ type_sp = class_types.GetTypeAtIndex(i);
+ if (type_sp) {
+ if (ClangASTContext::IsCXXClassType(
+ type_sp->GetForwardCompilerType())) {
+ if (log)
+ log->Printf(
+ "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
+ "matching dynamic types, picking "
+ "this one: uid={0x%" PRIx64
+ "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
+ type_info.SetTypeSP(type_sp);
+ }
+ }
+ }
+
+ if (log && i == num_matches) {
+ log->Printf(
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has multiple matching dynamic "
+ "types, didn't find a C++ match\n",
+ original_ptr, in_value.GetTypeName().AsCString());
+ }
}
+ if (type_info)
+ SetDynamicTypeInfo(vtable_addr, type_info);
+ return type_info;
+ }
}
+ }
}
- return TypeAndOrName();
+ }
+ return TypeAndOrName();
}
-bool
-ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name, Address &dynamic_address,
- Value::ValueType &value_type)
-{
- // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
- // in the object. That will point to the "address point" within the vtable (not the beginning of the
- // vtable.) We can then look up the symbol containing this "address point" and that symbol's name
- // demangled will contain the full class name.
- // The second pointer above the "address point" is the "offset_to_top". We'll use that to get the
- // start of the value object which holds the dynamic type.
- //
-
- class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
-
- // 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;
-
- ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
-
- Process *process = exe_ctx.GetProcessPtr();
-
- if (process == nullptr)
- return false;
-
- Error error;
- const lldb::addr_t vtable_address_point = process->ReadPointerFromMemory(original_ptr, error);
-
- if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS)
- {
- return false;
- }
+bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &dynamic_address,
+ Value::ValueType &value_type) {
+ // For Itanium, if the type has a vtable pointer in the object, it will be at
+ // offset 0
+ // in the object. That will point to the "address point" within the vtable
+ // (not the beginning of the
+ // vtable.) We can then look up the symbol containing this "address point"
+ // and that symbol's name
+ // demangled will contain the full class name.
+ // The second pointer above the "address point" is the "offset_to_top". We'll
+ // use that to get the
+ // start of the value object which holds the dynamic type.
+ //
+
+ class_type_or_name.Clear();
+ value_type = Value::ValueType::eValueTypeScalar;
+
+ // 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;
+
+ ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (process == nullptr)
+ return false;
+
+ Error error;
+ const lldb::addr_t vtable_address_point =
+ process->ReadPointerFromMemory(original_ptr, error);
+
+ if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) {
+ return false;
+ }
- 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;
- }
+ 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;
+ }
- // 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;
- }
+ // 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;
+ }
}
+ }
- return class_type_or_name.IsEmpty() == false;
+ return class_type_or_name.IsEmpty() == false;
}
-TypeAndOrName
-ItaniumABILanguageRuntime::FixUpDynamicType(const TypeAndOrName& type_and_or_name,
- ValueObject& static_value)
-{
- CompilerType static_type(static_value.GetCompilerType());
- Flags static_type_flags(static_type.GetTypeInfo());
-
- TypeAndOrName ret(type_and_or_name);
- if (type_and_or_name.HasType())
- {
- // The type will always be the type of the dynamic object. If our parent's type was a pointer,
- // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
- // should be okay...
- CompilerType orig_type = type_and_or_name.GetCompilerType();
- CompilerType corrected_type = orig_type;
- if (static_type_flags.AllSet(eTypeIsPointer))
- corrected_type = orig_type.GetPointerType ();
- else if (static_type_flags.AllSet(eTypeIsReference))
- corrected_type = orig_type.GetLValueReferenceType();
- ret.SetCompilerType(corrected_type);
- }
- else
- {
- // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
- std::string corrected_name (type_and_or_name.GetName().GetCString());
- if (static_type_flags.AllSet(eTypeIsPointer))
- corrected_name.append(" *");
- else if (static_type_flags.AllSet(eTypeIsReference))
- corrected_name.append(" &");
- // the parent type should be a correctly pointer'ed or referenc'ed type
- ret.SetCompilerType(static_type);
- ret.SetName(corrected_name.c_str());
- }
- return ret;
+TypeAndOrName ItaniumABILanguageRuntime::FixUpDynamicType(
+ const TypeAndOrName &type_and_or_name, ValueObject &static_value) {
+ CompilerType static_type(static_value.GetCompilerType());
+ Flags static_type_flags(static_type.GetTypeInfo());
+
+ TypeAndOrName ret(type_and_or_name);
+ if (type_and_or_name.HasType()) {
+ // The type will always be the type of the dynamic object. If our parent's
+ // type was a pointer,
+ // then our type should be a pointer to the type of the dynamic object. If
+ // a reference, then the original type
+ // should be okay...
+ CompilerType orig_type = type_and_or_name.GetCompilerType();
+ CompilerType corrected_type = orig_type;
+ if (static_type_flags.AllSet(eTypeIsPointer))
+ corrected_type = orig_type.GetPointerType();
+ else if (static_type_flags.AllSet(eTypeIsReference))
+ corrected_type = orig_type.GetLValueReferenceType();
+ ret.SetCompilerType(corrected_type);
+ } else {
+ // If we are here we need to adjust our dynamic type name to include the
+ // correct & or * symbol
+ std::string corrected_name(type_and_or_name.GetName().GetCString());
+ if (static_type_flags.AllSet(eTypeIsPointer))
+ corrected_name.append(" *");
+ else if (static_type_flags.AllSet(eTypeIsReference))
+ corrected_name.append(" &");
+ // the parent type should be a correctly pointer'ed or referenc'ed type
+ ret.SetCompilerType(static_type);
+ ret.SetName(corrected_name.c_str());
+ }
+ return ret;
}
-bool
-ItaniumABILanguageRuntime::IsVTableName (const char *name)
-{
- if (name == NULL)
- return false;
-
- // Can we maybe ask Clang about this?
- if (strstr (name, "_vptr$") == name)
- return true;
- else
- return false;
+bool ItaniumABILanguageRuntime::IsVTableName(const char *name) {
+ if (name == NULL)
+ return false;
+
+ // Can we maybe ask Clang about this?
+ if (strstr(name, "_vptr$") == name)
+ return true;
+ else
+ return false;
}
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
LanguageRuntime *
-ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language)
-{
- // FIXME: We have to check the process and make sure we actually know that this process supports
- // the Itanium ABI.
- if (language == eLanguageTypeC_plus_plus ||
- language == eLanguageTypeC_plus_plus_03 ||
- language == eLanguageTypeC_plus_plus_11 ||
- language == eLanguageTypeC_plus_plus_14)
- return new ItaniumABILanguageRuntime (process);
- else
- return NULL;
+ItaniumABILanguageRuntime::CreateInstance(Process *process,
+ lldb::LanguageType language) {
+ // FIXME: We have to check the process and make sure we actually know that
+ // this process supports
+ // the Itanium ABI.
+ if (language == eLanguageTypeC_plus_plus ||
+ language == eLanguageTypeC_plus_plus_03 ||
+ language == eLanguageTypeC_plus_plus_11 ||
+ language == eLanguageTypeC_plus_plus_14)
+ return new ItaniumABILanguageRuntime(process);
+ else
+ return NULL;
}
-class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed
-{
+class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed {
public:
- CommandObjectMultiwordItaniumABI_Demangle (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "demangle",
- "Demangle a C++ mangled name.",
- "language cplusplus demangle")
- {
- CommandArgumentEntry arg;
- CommandArgumentData index_arg;
-
- // Define the first (and only) variant of this arg.
- index_arg.arg_type = eArgTypeSymbol;
- index_arg.arg_repetition = eArgRepeatPlus;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (index_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectMultiwordItaniumABI_Demangle() override = default;
-
+ CommandObjectMultiwordItaniumABI_Demangle(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "demangle",
+ "Demangle a C++ mangled name.",
+ "language cplusplus demangle") {
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
+
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeSymbol;
+ index_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectMultiwordItaniumABI_Demangle() override = default;
+
protected:
- bool
- DoExecute(Args& command, CommandReturnObject &result) override
- {
- bool demangled_any = false;
- bool error_any = false;
- for (size_t i = 0; i < command.GetArgumentCount(); i++)
- {
- auto arg = command.GetArgumentAtIndex(i);
- if (arg && *arg)
- {
- ConstString mangled_cs(arg);
-
- // the actual Mangled class should be strict about this, but on the command line
- // if you're copying mangled names out of 'nm' on Darwin, they will come out with
- // an extra underscore - be willing to strip this on behalf of the user
- // This is the moral equivalent of the -_/-n options to c++filt
- if (mangled_cs.GetStringRef().startswith("__Z"))
- mangled_cs.SetCString(arg+1);
-
- Mangled mangled(mangled_cs, true);
- if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus)
- {
- ConstString demangled(mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
- demangled_any = true;
- result.AppendMessageWithFormat("%s ---> %s\n", arg, demangled.GetCString());
- }
- else
- {
- error_any = true;
- result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n", arg);
- }
- }
- }
-
- result.SetStatus(error_any ? lldb::eReturnStatusFailed :
- (demangled_any ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult));
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ bool demangled_any = false;
+ bool error_any = false;
+ for (auto &entry : command.entries()) {
+ if (entry.ref.empty())
+ continue;
+
+ // the actual Mangled class should be strict about this, but on the
+ // command line if you're copying mangled names out of 'nm' on Darwin,
+ // they will come out with an extra underscore - be willing to strip
+ // this on behalf of the user. This is the moral equivalent of the -_/-n
+ // options to c++filt
+ auto name = entry.ref;
+ if (name.startswith("__Z"))
+ name = name.drop_front();
+
+ Mangled mangled(name, true);
+ if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) {
+ ConstString demangled(
+ mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
+ demangled_any = true;
+ result.AppendMessageWithFormat("%s ---> %s\n", entry.ref.str().c_str(),
+ demangled.GetCString());
+ } else {
+ error_any = true;
+ result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n",
+ entry.ref.str().c_str());
+ }
}
+
+ result.SetStatus(
+ error_any ? lldb::eReturnStatusFailed
+ : (demangled_any ? lldb::eReturnStatusSuccessFinishResult
+ : lldb::eReturnStatusSuccessFinishNoResult));
+ return result.Succeeded();
+ }
};
-class CommandObjectMultiwordItaniumABI : public CommandObjectMultiword
-{
+class CommandObjectMultiwordItaniumABI : public CommandObjectMultiword {
public:
- CommandObjectMultiwordItaniumABI(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "cplusplus", "Commands for operating on the C++ language runtime.",
- "cplusplus <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("demangle", CommandObjectSP (new CommandObjectMultiwordItaniumABI_Demangle (interpreter)));
- }
-
- ~CommandObjectMultiwordItaniumABI() override = default;
+ CommandObjectMultiwordItaniumABI(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "cplusplus",
+ "Commands for operating on the C++ language runtime.",
+ "cplusplus <subcommand> [<subcommand-options>]") {
+ LoadSubCommand(
+ "demangle",
+ CommandObjectSP(
+ new CommandObjectMultiwordItaniumABI_Demangle(interpreter)));
+ }
+
+ ~CommandObjectMultiwordItaniumABI() override = default;
};
-void
-ItaniumABILanguageRuntime::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "Itanium ABI for the C++ language",
- CreateInstance,
- [] (CommandInterpreter& interpreter) -> lldb::CommandObjectSP {
- return CommandObjectSP(new CommandObjectMultiwordItaniumABI(interpreter));
- });
+void ItaniumABILanguageRuntime::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "Itanium ABI for the C++ language", CreateInstance,
+ [](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
+ return CommandObjectSP(
+ new CommandObjectMultiwordItaniumABI(interpreter));
+ });
}
-void
-ItaniumABILanguageRuntime::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void ItaniumABILanguageRuntime::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-ItaniumABILanguageRuntime::GetPluginNameStatic()
-{
- static ConstString g_name("itanium");
- return g_name;
+lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginNameStatic() {
+ static ConstString g_name("itanium");
+ return g_name;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-ItaniumABILanguageRuntime::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ItaniumABILanguageRuntime::GetPluginVersion()
-{
- return 1;
+uint32_t ItaniumABILanguageRuntime::GetPluginVersion() { return 1; }
+
+BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver(
+ Breakpoint *bkpt, bool catch_bp, bool throw_bp) {
+ return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false);
}
-BreakpointResolverSP
-ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
-{
- return CreateExceptionResolver (bkpt, catch_bp, throw_bp, false);
+BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver(
+ Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) {
+ // One complication here is that most users DON'T want to stop at
+ // __cxa_allocate_expression, but until we can do
+ // anything better with predicting unwinding the expression parser does. So
+ // we have two forms of the exception
+ // breakpoints, one for expressions that leaves out __cxa_allocate_exception,
+ // and one that includes it.
+ // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint
+ // in the runtime the former.
+ static const char *g_catch_name = "__cxa_begin_catch";
+ static const char *g_throw_name1 = "__cxa_throw";
+ static const char *g_throw_name2 = "__cxa_rethrow";
+ static const char *g_exception_throw_name = "__cxa_allocate_exception";
+ std::vector<const char *> exception_names;
+ exception_names.reserve(4);
+ if (catch_bp)
+ exception_names.push_back(g_catch_name);
+
+ if (throw_bp) {
+ exception_names.push_back(g_throw_name1);
+ exception_names.push_back(g_throw_name2);
+ }
+
+ if (for_expressions)
+ exception_names.push_back(g_exception_throw_name);
+
+ BreakpointResolverSP resolver_sp(new BreakpointResolverName(
+ bkpt, exception_names.data(), exception_names.size(),
+ eFunctionNameTypeBase, eLanguageTypeUnknown, 0, eLazyBoolNo));
+
+ return resolver_sp;
}
-BreakpointResolverSP
-ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions)
-{
- // One complication here is that most users DON'T want to stop at __cxa_allocate_expression, but until we can do
- // anything better with predicting unwinding the expression parser does. So we have two forms of the exception
- // breakpoints, one for expressions that leaves out __cxa_allocate_exception, and one that includes it.
- // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint in the runtime the former.
- static const char *g_catch_name = "__cxa_begin_catch";
- static const char *g_throw_name1 = "__cxa_throw";
- static const char *g_throw_name2 = "__cxa_rethrow";
- static const char *g_exception_throw_name = "__cxa_allocate_exception";
- std::vector<const char *> exception_names;
- exception_names.reserve(4);
- if (catch_bp)
- exception_names.push_back(g_catch_name);
-
- if (throw_bp)
- {
- exception_names.push_back(g_throw_name1);
- exception_names.push_back(g_throw_name2);
- }
+lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() {
+ Target &target = m_process->GetTarget();
- if (for_expressions)
- exception_names.push_back(g_exception_throw_name);
-
- BreakpointResolverSP resolver_sp (new BreakpointResolverName (bkpt,
- exception_names.data(),
- exception_names.size(),
- eFunctionNameTypeBase,
- eLanguageTypeUnknown,
- 0,
- eLazyBoolNo));
-
- return resolver_sp;
+ if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) {
+ // 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));
+ return target.GetSearchFilterForModuleList(&filter_modules);
+ } else {
+ return LanguageRuntime::CreateExceptionSearchFilter();
+ }
}
+lldb::BreakpointSP ItaniumABILanguageRuntime::CreateExceptionBreakpoint(
+ bool catch_bp, bool throw_bp, bool for_expressions, bool is_internal) {
+ Target &target = m_process->GetTarget();
+ FileSpecList filter_modules;
+ BreakpointResolverSP exception_resolver_sp =
+ CreateExceptionResolver(NULL, catch_bp, throw_bp, for_expressions);
+ SearchFilterSP filter_sp(CreateExceptionSearchFilter());
+ const bool hardware = false;
+ const bool resolve_indirect_functions = false;
+ return target.CreateBreakpoint(filter_sp, exception_resolver_sp, is_internal,
+ hardware, resolve_indirect_functions);
+}
+void ItaniumABILanguageRuntime::SetExceptionBreakpoints() {
+ if (!m_process)
+ return;
-lldb::SearchFilterSP
-ItaniumABILanguageRuntime::CreateExceptionSearchFilter ()
-{
- Target &target = m_process->GetTarget();
+ const bool catch_bp = false;
+ const bool throw_bp = true;
+ const bool is_internal = true;
+ const bool for_expressions = true;
- if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
- {
- // 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));
- return target.GetSearchFilterForModuleList(&filter_modules);
- }
- else
- {
- return LanguageRuntime::CreateExceptionSearchFilter();
- }
-}
-
-lldb::BreakpointSP
-ItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp,
- bool throw_bp,
- bool for_expressions,
- bool is_internal)
-{
- Target &target = m_process->GetTarget();
- FileSpecList filter_modules;
- BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
- SearchFilterSP filter_sp (CreateExceptionSearchFilter ());
- const bool hardware = false;
- const bool resolve_indirect_functions = false;
- return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal, hardware, resolve_indirect_functions);
-}
+ // For the exception breakpoints set by the Expression parser, we'll be a
+ // little more aggressive and
+ // stop at exception allocation as well.
-void
-ItaniumABILanguageRuntime::SetExceptionBreakpoints ()
-{
- if (!m_process)
- return;
-
- const bool catch_bp = false;
- const bool throw_bp = true;
- const bool is_internal = true;
- const bool for_expressions = true;
-
- // For the exception breakpoints set by the Expression parser, we'll be a little more aggressive and
- // stop at exception allocation as well.
-
+ if (m_cxx_exception_bp_sp) {
+ m_cxx_exception_bp_sp->SetEnabled(true);
+ } else {
+ m_cxx_exception_bp_sp = CreateExceptionBreakpoint(
+ catch_bp, throw_bp, for_expressions, is_internal);
if (m_cxx_exception_bp_sp)
- {
- m_cxx_exception_bp_sp->SetEnabled (true);
- }
- else
- {
- m_cxx_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, for_expressions, is_internal);
- if (m_cxx_exception_bp_sp)
- m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
- }
-
+ m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
+ }
}
-void
-ItaniumABILanguageRuntime::ClearExceptionBreakpoints ()
-{
- if (!m_process)
- return;
-
- if (m_cxx_exception_bp_sp)
- {
- m_cxx_exception_bp_sp->SetEnabled (false);
- }
+void ItaniumABILanguageRuntime::ClearExceptionBreakpoints() {
+ if (!m_process)
+ return;
+
+ if (m_cxx_exception_bp_sp) {
+ m_cxx_exception_bp_sp->SetEnabled(false);
+ }
}
-bool
-ItaniumABILanguageRuntime::ExceptionBreakpointsAreSet ()
-{
- return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled();
+bool ItaniumABILanguageRuntime::ExceptionBreakpointsAreSet() {
+ return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled();
}
-bool
-ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
-{
- if (!m_process)
- return false;
-
- if (!stop_reason ||
- stop_reason->GetStopReason() != eStopReasonBreakpoint)
- return false;
-
- uint64_t break_site_id = stop_reason->GetValue();
- return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(break_site_id,
- m_cxx_exception_bp_sp->GetID());
-
+bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop(
+ lldb::StopInfoSP stop_reason) {
+ if (!m_process)
+ return false;
+
+ if (!stop_reason || stop_reason->GetStopReason() != eStopReasonBreakpoint)
+ return false;
+
+ uint64_t break_site_id = stop_reason->GetValue();
+ return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(
+ break_site_id, m_cxx_exception_bp_sp->GetID());
}
-TypeAndOrName
-ItaniumABILanguageRuntime::GetDynamicTypeInfo(const lldb_private::Address &vtable_addr)
-{
- std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
- DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr);
- if (pos == m_dynamic_type_map.end())
- return TypeAndOrName();
- else
- return pos->second;
+TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo(
+ const lldb_private::Address &vtable_addr) {
+ std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr);
+ if (pos == m_dynamic_type_map.end())
+ return TypeAndOrName();
+ else
+ return pos->second;
}
-void
-ItaniumABILanguageRuntime::SetDynamicTypeInfo(const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info)
-{
- std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
- m_dynamic_type_map[vtable_addr] = type_info;
+void ItaniumABILanguageRuntime::SetDynamicTypeInfo(
+ const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info) {
+ std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ m_dynamic_type_map[vtable_addr] = type_info;
}
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index 86bd728d6c6f..480c32691c8b 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -18,116 +18,98 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Core/Value.h"
#include "lldb/Symbol/Type.h"
-#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/CPPLanguageRuntime.h"
-#include "lldb/Core/Value.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
- class ItaniumABILanguageRuntime :
- public lldb_private::CPPLanguageRuntime
- {
- public:
- ~ItaniumABILanguageRuntime() override = default;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::LanguageRuntime *
- CreateInstance (Process *process, lldb::LanguageType language);
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- bool
- IsVTableName(const char *name) override;
-
- bool
- GetDynamicTypeAndAddress(ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
-
- TypeAndOrName
- FixUpDynamicType(const TypeAndOrName& type_and_or_name,
- ValueObject& static_value) override;
-
- bool
- CouldHaveDynamicValue(ValueObject &in_value) override;
-
- void
- SetExceptionBreakpoints() override;
-
- void
- ClearExceptionBreakpoints() override;
-
- bool
- ExceptionBreakpointsAreSet() override;
-
- bool
- ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
-
- lldb::BreakpointResolverSP
- CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
-
- lldb::SearchFilterSP
- CreateExceptionSearchFilter() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- protected:
- lldb::BreakpointResolverSP
- CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions);
-
- lldb::BreakpointSP
- CreateExceptionBreakpoint(bool catch_bp,
- bool throw_bp,
- bool for_expressions,
- bool is_internal);
-
- private:
- typedef std::map<lldb_private::Address, TypeAndOrName> DynamicTypeCache;
-
- ItaniumABILanguageRuntime(Process *process)
- : // Call CreateInstance instead.
- lldb_private::CPPLanguageRuntime(process),
- m_cxx_exception_bp_sp(),
- m_dynamic_type_map(),
- m_dynamic_type_map_mutex()
- {
- }
-
- lldb::BreakpointSP m_cxx_exception_bp_sp;
- DynamicTypeCache m_dynamic_type_map;
- std::mutex m_dynamic_type_map_mutex;
-
- TypeAndOrName
- GetTypeInfoFromVTableAddress(ValueObject &in_value, lldb::addr_t original_ptr, lldb::addr_t vtable_addr);
-
- TypeAndOrName
- GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
-
- void
- SetDynamicTypeInfo(const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info);
- };
-
+
+class ItaniumABILanguageRuntime : public lldb_private::CPPLanguageRuntime {
+public:
+ ~ItaniumABILanguageRuntime() override = default;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ bool IsVTableName(const char *name) override;
+
+ bool GetDynamicTypeAndAddress(ValueObject &in_value,
+ lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name,
+ Address &address,
+ Value::ValueType &value_type) override;
+
+ TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
+ ValueObject &static_value) override;
+
+ bool CouldHaveDynamicValue(ValueObject &in_value) override;
+
+ void SetExceptionBreakpoints() override;
+
+ void ClearExceptionBreakpoints() override;
+
+ bool ExceptionBreakpointsAreSet() override;
+
+ bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
+
+ lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
+ bool catch_bp,
+ bool throw_bp) override;
+
+ lldb::SearchFilterSP CreateExceptionSearchFilter() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+protected:
+ lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
+ bool catch_bp,
+ bool throw_bp,
+ bool for_expressions);
+
+ lldb::BreakpointSP CreateExceptionBreakpoint(bool catch_bp, bool throw_bp,
+ bool for_expressions,
+ bool is_internal);
+
+private:
+ typedef std::map<lldb_private::Address, TypeAndOrName> DynamicTypeCache;
+
+ ItaniumABILanguageRuntime(Process *process)
+ : // Call CreateInstance instead.
+ lldb_private::CPPLanguageRuntime(process),
+ m_cxx_exception_bp_sp(), m_dynamic_type_map(),
+ m_dynamic_type_map_mutex() {}
+
+ lldb::BreakpointSP m_cxx_exception_bp_sp;
+ DynamicTypeCache m_dynamic_type_map;
+ std::mutex m_dynamic_type_map_mutex;
+
+ TypeAndOrName GetTypeInfoFromVTableAddress(ValueObject &in_value,
+ lldb::addr_t original_ptr,
+ lldb::addr_t vtable_addr);
+
+ TypeAndOrName GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
+
+ void SetDynamicTypeInfo(const lldb_private::Address &vtable_addr,
+ const TypeAndOrName &type_info);
+};
+
} // namespace lldb_private
#endif // liblldb_ItaniumABILanguageRuntime_h_