diff options
Diffstat (limited to 'lldb/source/Plugins')
8 files changed, 158 insertions, 25 deletions
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index b0f7733c2cd..fb4c98dc441 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -15,6 +15,8 @@ #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/Symbol/ClangASTContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -30,12 +32,134 @@ using namespace lldb_private; static const char *pluginName = "ItaniumABILanguageRuntime"; static const char *pluginDesc = "Itanium ABI for the C++ language"; static const char *pluginShort = "language.itanium"; +static const char *vtable_demangled_prefix = "vtable for "; -lldb::ValueObjectSP -ItaniumABILanguageRuntime::GetDynamicValue (ValueObjectSP in_value) +bool +ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value) +{ + return in_value.IsPointerOrReferenceType(); +} + +bool +ItaniumABILanguageRuntime::GetDynamicValue (ValueObject &in_value, lldb::TypeSP &dynamic_type_sp, Address &dynamic_address) { - ValueObjectSP ret_sp; - return ret_sp; + // 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. + // + + // Only a pointer or reference type can have a different dynamic and static type: + if (CouldHaveDynamicValue (in_value)) + { + // FIXME: Can we get the Clang Type and ask it if the thing is really virtual? That would avoid false positives, + // at the cost of not looking for the dynamic type of objects if DWARF->Clang gets it wrong. + + // 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, true); + if (original_ptr == LLDB_INVALID_ADDRESS) + return false; + + Target *target = in_value.GetUpdatePoint().GetTarget(); + Process *process = in_value.GetUpdatePoint().GetProcess(); + + char memory_buffer[16]; + DataExtractor data(memory_buffer, sizeof(memory_buffer), + process->GetByteOrder(), + process->GetAddressByteSize()); + size_t address_byte_size = process->GetAddressByteSize(); + Error error; + size_t bytes_read = process->ReadMemory (original_ptr, + memory_buffer, + address_byte_size, + error); + if (!error.Success() || (bytes_read != address_byte_size)) + { + return false; + } + + uint32_t offset_ptr = 0; + lldb::addr_t vtable_address_point = data.GetAddress (&offset_ptr); + + if (offset_ptr == 0) + return false; + + // Now find the symbol that contains this address: + + SymbolContext sc; + Address address_point_address; + if (target && !target->GetSectionLoadList().IsEmpty()) + { + if (target->GetSectionLoadList().ResolveLoadAddress (vtable_address_point, address_point_address)) + { + target->GetImages().ResolveSymbolContextForAddress (address_point_address, eSymbolContextSymbol, sc); + Symbol *symbol = sc.symbol; + if (symbol != NULL) + { + const char *name = symbol->GetMangled().GetDemangledName().AsCString(); + if (strstr(name, vtable_demangled_prefix) == 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); + TypeList class_types; + uint32_t num_matches = target->GetImages().FindTypes (sc, + ConstString(class_name), + true, + UINT32_MAX, + class_types); + if (num_matches == 1) + { + dynamic_type_sp = class_types.GetTypeAtIndex(0); + } + else if (num_matches > 1) + { + // How to sort out which of the type matches to pick? + } + + if (!dynamic_type_sp) + return false; + + // The offset_to_top is two pointers above the address. + Address offset_to_top_address = address_point_address; + int64_t slide = -2 * ((int64_t) target->GetArchitecture().GetAddressByteSize()); + offset_to_top_address.Slide (slide); + + Error error; + lldb::addr_t offset_to_top_location = offset_to_top_address.GetLoadAddress(target); + + size_t bytes_read = process->ReadMemory (offset_to_top_location, + memory_buffer, + address_byte_size, + error); + + if (!error.Success() || (bytes_read != address_byte_size)) + { + return false; + } + + offset_ptr = 0; + int64_t offset_to_top = data.GetMaxS64(&offset_ptr, process->GetAddressByteSize()); + + // 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 (!target->GetSectionLoadList().ResolveLoadAddress (dynamic_addr, dynamic_address)) + { + dynamic_address.SetOffset(dynamic_addr); + dynamic_address.SetSection(NULL); + } + return true; + } + } + } + } + + } + + return false; } bool diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index d7ac04adc20..421ac12725f 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -30,9 +30,12 @@ namespace lldb_private { virtual bool IsVTableName (const char *name); - virtual lldb::ValueObjectSP - GetDynamicValue (lldb::ValueObjectSP in_value); - + virtual bool + GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address); + + virtual bool + CouldHaveDynamicValue (ValueObject &in_value); + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 392abeeaebf..08af0b68431 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -191,11 +191,16 @@ AppleObjCRuntime::GetPrintForDebuggerAddr() return m_PrintForDebugger_addr.get(); } -lldb::ValueObjectSP -AppleObjCRuntime::GetDynamicValue (lldb::ValueObjectSP in_value) +bool +AppleObjCRuntime::CouldHaveDynamicValue (ValueObject &in_value) +{ + return in_value.IsPointerType(); +} + +bool +AppleObjCRuntime::GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address) { - lldb::ValueObjectSP ret_sp; - return ret_sp; + return false; } bool diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h index 1c500e39be1..e7e0f71d956 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h @@ -37,8 +37,11 @@ public: virtual bool GetObjectDescription (Stream &str, ValueObject &object); - virtual lldb::ValueObjectSP - GetDynamicValue (lldb::ValueObjectSP in_value); + virtual bool + CouldHaveDynamicValue (ValueObject &in_value); + + virtual bool + GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address); // These are the ObjC specific functions. diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index 46747571198..000f14e3df1 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -40,11 +40,10 @@ static const char *pluginName = "AppleObjCRuntimeV1"; static const char *pluginDesc = "Apple Objective C Language Runtime - Version 1"; static const char *pluginShort = "language.apple.objc.v1"; -lldb::ValueObjectSP -AppleObjCRuntimeV1::GetDynamicValue (lldb::ValueObjectSP in_value) +bool +AppleObjCRuntimeV1::GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address) { - lldb::ValueObjectSP ret_sp; - return ret_sp; + return false; } //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h index 2b815b18091..975c018b4e9 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h @@ -31,8 +31,8 @@ public: ~AppleObjCRuntimeV1() { } // These are generic runtime functions: - virtual lldb::ValueObjectSP - GetDynamicValue (lldb::ValueObjectSP in_value); + virtual bool + GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address); virtual ClangUtilityFunction * CreateObjectChecker (const char *); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 5d276dcd02d..c6e3533a09d 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -46,11 +46,10 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process, ModuleSP &objc_module_ m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(ConstString("gdb_object_getClass")) != NULL); } -lldb::ValueObjectSP -AppleObjCRuntimeV2::GetDynamicValue (lldb::ValueObjectSP in_value) +bool +AppleObjCRuntimeV2::GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address) { - lldb::ValueObjectSP ret_sp; - return ret_sp; + return false; } //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index d2bd414bfc3..0015dd2f424 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -31,8 +31,8 @@ public: ~AppleObjCRuntimeV2() { } // These are generic runtime functions: - virtual lldb::ValueObjectSP - GetDynamicValue (lldb::ValueObjectSP in_value); + virtual bool + GetDynamicValue (ValueObject &in_value, lldb::TypeSP &type_sp, Address &address); virtual ClangUtilityFunction * CreateObjectChecker (const char *); |

