diff options
| author | Jim Ingham <jingham@apple.com> | 2011-04-16 00:01:13 +0000 |
|---|---|---|
| committer | Jim Ingham <jingham@apple.com> | 2011-04-16 00:01:13 +0000 |
| commit | 78a685aa2d8bbf48f25f2f93d4c0a74652eb0e9b (patch) | |
| tree | bccc15a9b0e04bef29c0d2ceeb85a3c355dc9586 /lldb/source/Plugins/LanguageRuntime | |
| parent | f46b33852c0294f1dba3303c6810902212fe749d (diff) | |
| download | bcm5719-llvm-78a685aa2d8bbf48f25f2f93d4c0a74652eb0e9b.tar.gz bcm5719-llvm-78a685aa2d8bbf48f25f2f93d4c0a74652eb0e9b.zip | |
Add support for "dynamic values" for C++ classes. This currently only works for "frame var" and for the
expressions that are simple enough to get passed to the "frame var" underpinnings. The parser code will
have to be changed to also query for the dynamic types & offsets as it is looking up variables.
The behavior of "frame var" is controlled in two ways. You can pass "-d {true/false} to the frame var
command to get the dynamic or static value of the variables you are printing.
There's also a general setting:
target.prefer-dynamic-value (boolean) = 'true'
which is consulted if you call "frame var" without supplying a value for the -d option.
llvm-svn: 129623
Diffstat (limited to 'lldb/source/Plugins/LanguageRuntime')
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 *); |

