diff options
Diffstat (limited to 'lldb')
33 files changed, 633 insertions, 556 deletions
diff --git a/lldb/include/lldb/Core/Value.h b/lldb/include/lldb/Core/Value.h index c321f4e359f..87eb7272525 100644 --- a/lldb/include/lldb/Core/Value.h +++ b/lldb/include/lldb/Core/Value.h @@ -119,9 +119,6 @@ public: lldb::Format GetValueDefaultFormat (); - void * - GetValueOpaqueClangQualType (); - size_t GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr); diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index ec521331975..9c89710f960 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -59,6 +59,9 @@ public: virtual ConstString GetTypeName() = 0; + virtual lldb::LanguageType + GetObjectRuntimeLanguage(); + virtual void UpdateValue (ExecutionContextScope *exe_scope) = 0; diff --git a/lldb/include/lldb/Target/CPPLanguageRuntime.h b/lldb/include/lldb/Target/CPPLanguageRuntime.h index 08b2a8d5321..e4906f9d716 100644 --- a/lldb/include/lldb/Target/CPPLanguageRuntime.h +++ b/lldb/include/lldb/Target/CPPLanguageRuntime.h @@ -36,6 +36,9 @@ public: virtual bool IsVTableName (const char *name) = 0; + virtual bool + GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope); + protected: //------------------------------------------------------------------ // Classes that inherit from CPPLanguageRuntime can see and modify these diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h index bacf21b990d..3066b9258da 100644 --- a/lldb/include/lldb/Target/LanguageRuntime.h +++ b/lldb/include/lldb/Target/LanguageRuntime.h @@ -14,8 +14,10 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/lldb-include.h" #include "lldb/Core/PluginInterface.h" #include "lldb/lldb-private.h" +#include "lldb/Target/ExecutionContextScope.h" namespace lldb_private { @@ -32,13 +34,19 @@ public: virtual lldb::LanguageType GetLanguageType () const = 0; + virtual bool + GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope) = 0; + + virtual lldb::ValueObjectSP + GetDynamicValue (lldb::ValueObjectSP in_value, ExecutionContextScope *exe_scope) = 0; + protected: //------------------------------------------------------------------ // Classes that inherit from LanguageRuntime can see and modify these //------------------------------------------------------------------ LanguageRuntime(Process *process); + Process *m_process; private: - Process *m_process_ptr; DISALLOW_COPY_AND_ASSIGN (LanguageRuntime); }; diff --git a/lldb/include/lldb/Target/ObjCLanguageRuntime.h b/lldb/include/lldb/Target/ObjCLanguageRuntime.h index c2616147d29..81da4a6defe 100644 --- a/lldb/include/lldb/Target/ObjCLanguageRuntime.h +++ b/lldb/include/lldb/Target/ObjCLanguageRuntime.h @@ -12,10 +12,12 @@ // C Includes // C++ Includes +#include <map> + // Other libraries and framework includes // Project includes -#include "lldb/Core/PluginInterface.h" #include "lldb/lldb-private.h" +#include "lldb/Core/PluginInterface.h" #include "lldb/Target/LanguageRuntime.h" namespace lldb_private { @@ -33,12 +35,79 @@ public: return lldb::eLanguageTypeObjC; } + virtual bool + IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0; + + virtual bool + ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0; + + virtual bool + HasReadObjCLibrary () = 0; + + virtual lldb::ThreadPlanSP + GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0; + + lldb::addr_t + LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel); + + void + AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr); + protected: //------------------------------------------------------------------ // Classes that inherit from ObjCLanguageRuntime can see and modify these //------------------------------------------------------------------ ObjCLanguageRuntime(Process *process); private: + // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver + // function over and over. + + // FIXME: We need to watch for the loading of Protocols, and flush the cache for any + // class that we see so changed. + + struct ClassAndSel + { + ClassAndSel() + { + sel_addr = LLDB_INVALID_ADDRESS; + class_addr = LLDB_INVALID_ADDRESS; + } + ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) : + class_addr (in_class_addr), + sel_addr(in_sel_addr) + { + } + bool operator== (const ClassAndSel &rhs) + { + if (class_addr == rhs.class_addr + && sel_addr == rhs.sel_addr) + return true; + else + return false; + } + + bool operator< (const ClassAndSel &rhs) const + { + if (class_addr < rhs.class_addr) + return true; + else if (class_addr > rhs.class_addr) + return false; + else + { + if (sel_addr < rhs.sel_addr) + return true; + else + return false; + } + } + + lldb::addr_t class_addr; + lldb::addr_t sel_addr; + }; + + typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap; + MsgImplMap m_impl_cache; + DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime); }; diff --git a/lldb/include/lldb/Target/ObjCObjectPrinter.h b/lldb/include/lldb/Target/ObjCObjectPrinter.h deleted file mode 100644 index fab777403f7..00000000000 --- a/lldb/include/lldb/Target/ObjCObjectPrinter.h +++ /dev/null @@ -1,49 +0,0 @@ -//===-- ObjCObjectPrinter.h ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ObjCObjectPrinter_h_ -#define liblldb_ObjCObjectPrinter_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/ConstString.h" -#include "lldb/Core/Error.h" -// Project includes - -namespace lldb_private { - - class ObjCObjectPrinter - { - public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ObjCObjectPrinter (Process &process); - - virtual - ~ObjCObjectPrinter (); - - bool - PrintObject (Stream &str, Value &object_ptr, ExecutionContext &exe_ctx); - protected: - Process &m_process; - std::auto_ptr<Address> m_PrintForDebugger_addr; - - Address *GetPrintForDebuggerAddr(); - private: - //------------------------------------------------------------------ - // For ObjCObjectPrinter only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (ObjCObjectPrinter); - }; - -} // namespace lldb_private - -#endif // liblldb_ObjCObjectPrinter_h_ diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 3f97ec1d9ea..4b096b82d90 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -30,7 +30,6 @@ #include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Target/ExecutionContextScope.h" -#include "lldb/Target/ObjCObjectPrinter.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/UnixSignals.h" @@ -1598,9 +1597,6 @@ public: ClangPersistentVariables & GetPersistentVariables(); - ObjCObjectPrinter & - GetObjCObjectPrinter(); - protected: //------------------------------------------------------------------ // Member variables @@ -1627,7 +1623,6 @@ protected: UnixSignals m_unix_signals; /// This is the current signal set for this process. ConstString m_target_triple; lldb::ABISP m_abi_sp; - ObjCObjectPrinter m_objc_object_printer; typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection; LanguageRuntimeCollection m_language_runtimes; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 673165e36a6..82b45215caa 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -87,7 +87,6 @@ class Module; class ModuleList; class Mutex; class ObjCLanguageRuntime; -class ObjCObjectPrinter; class ObjectContainer; class ObjectFile; class Options; diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 4383ec97144..9ad57b1b26f 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -290,14 +290,11 @@ 26D5B15111B07550009A862E /* unw_getcontext.s in Sources */ = {isa = PBXBuildFile; fileRef = 9654F7BA1197DA3F00F72B43 /* unw_getcontext.s */; }; 26D5B15211B07550009A862E /* LibUnwindRegisterContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B4666F11A2091600CF6220 /* LibUnwindRegisterContext.cpp */; }; 26D5B15311B07550009A862E /* ABIMacOSX_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 497650CE11A21BEE008DDB57 /* ABIMacOSX_i386.cpp */; }; - 26D5B15411B07550009A862E /* ObjCTrampolineHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C51FF1611A4C486007C962F /* ObjCTrampolineHandler.cpp */; }; 26D5B15511B07550009A862E /* Baton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A0604811A5D03C00F75969 /* Baton.cpp */; }; 26D5B15611B07550009A862E /* CommandObjectArgs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 499F381F11A5B3F300F5CE02 /* CommandObjectArgs.cpp */; }; - 26D5B15711B07550009A862E /* ThreadPlanStepThroughObjCTrampoline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF4473E11A8687100EF971E /* ThreadPlanStepThroughObjCTrampoline.cpp */; }; 26D5B15911B07550009A862E /* UnwindLibUnwind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E3EEBE11A98A1900FBADB6 /* UnwindLibUnwind.cpp */; }; 26D5B15A11B07550009A862E /* UnwindMacOSXFrameBackchain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E3EEE311A9901300FBADB6 /* UnwindMacOSXFrameBackchain.cpp */; }; 26D5B15B11B07550009A862E /* RegisterContextMacOSXFrameBackchain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E3EEF711A994E800FBADB6 /* RegisterContextMacOSXFrameBackchain.cpp */; }; - 26D5B15C11B07550009A862E /* ObjCObjectPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */; }; 26D5B18E11B07979009A862E /* libuwind.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 9654F7B31197DA3F00F72B43 /* libuwind.cxx */; }; 26DE1E6B11616C2E00A093E2 /* lldb-forward-rtti.h in Headers */ = {isa = PBXBuildFile; fileRef = 26DE1E6911616C2E00A093E2 /* lldb-forward-rtti.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26DE1E6C11616C2E00A093E2 /* lldb-forward.h in Headers */ = {isa = PBXBuildFile; fileRef = 26DE1E6A11616C2E00A093E2 /* lldb-forward.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -351,6 +348,10 @@ 49FB515E121481B000DF8983 /* DWARFExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */; }; 4C08CDE811C81EF8001610A8 /* ThreadSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */; }; 4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */; }; + 4C0A91D812511CB900CA6636 /* AppleObjCTrampolineHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A91D412511CB900CA6636 /* AppleObjCTrampolineHandler.cpp */; }; + 4C0A91D912511CB900CA6636 /* AppleObjCTrampolineHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C0A91D512511CB900CA6636 /* AppleObjCTrampolineHandler.h */; }; + 4C0A91DA12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A91D612511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */; }; + 4C0A91DB12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C0A91D712511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h */; }; 4C139EA5124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C139EA3124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp */; }; 4C139EA6124A8B03000BFF8D /* AppleObjCRuntimeV2.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C139EA4124A8B03000BFF8D /* AppleObjCRuntimeV2.h */; }; 4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */; }; @@ -949,8 +950,6 @@ 49A8A39F11D568A300AD3B68 /* ASTResultSynthesizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTResultSynthesizer.cpp; path = source/Expression/ASTResultSynthesizer.cpp; sourceTree = "<group>"; }; 49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTResultSynthesizer.h; path = include/lldb/Expression/ASTResultSynthesizer.h; sourceTree = "<group>"; }; 49BB309511F79450001A4197 /* TaggedASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedASTType.h; path = include/lldb/Symbol/TaggedASTType.h; sourceTree = "<group>"; }; - 49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCObjectPrinter.cpp; path = source/Target/ObjCObjectPrinter.cpp; sourceTree = "<group>"; }; - 49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCObjectPrinter.h; path = include/lldb/Target/ObjCObjectPrinter.h; sourceTree = "<group>"; }; 49CF9829122C70BD007A0B96 /* IRDynamicChecks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRDynamicChecks.cpp; path = source/Expression/IRDynamicChecks.cpp; sourceTree = "<group>"; }; 49CF9833122C718B007A0B96 /* IRDynamicChecks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRDynamicChecks.h; path = include/lldb/Expression/IRDynamicChecks.h; sourceTree = "<group>"; }; 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangPersistentVariables.h; path = include/lldb/Expression/ClangPersistentVariables.h; sourceTree = "<group>"; }; @@ -971,6 +970,10 @@ 4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSpec.h; path = include/lldb/Target/ThreadSpec.h; sourceTree = "<group>"; }; 4C09CB73116BD98B00C7A725 /* CommandCompletions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandCompletions.h; path = include/lldb/Interpreter/CommandCompletions.h; sourceTree = "<group>"; }; 4C09CB74116BD98B00C7A725 /* CommandCompletions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandCompletions.cpp; path = source/Commands/CommandCompletions.cpp; sourceTree = "<group>"; }; + 4C0A91D412511CB900CA6636 /* AppleObjCTrampolineHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AppleObjCTrampolineHandler.cpp; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCTrampolineHandler.cpp; sourceTree = "<group>"; }; + 4C0A91D512511CB900CA6636 /* AppleObjCTrampolineHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppleObjCTrampolineHandler.h; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCTrampolineHandler.h; sourceTree = "<group>"; }; + 4C0A91D612511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AppleThreadPlanStepThroughObjCTrampoline.cpp; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleThreadPlanStepThroughObjCTrampoline.cpp; sourceTree = "<group>"; }; + 4C0A91D712511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppleThreadPlanStepThroughObjCTrampoline.h; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleThreadPlanStepThroughObjCTrampoline.h; sourceTree = "<group>"; }; 4C139EA3124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AppleObjCRuntimeV2.cpp; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp; sourceTree = "<group>"; }; 4C139EA4124A8B03000BFF8D /* AppleObjCRuntimeV2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppleObjCRuntimeV2.h; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h; sourceTree = "<group>"; }; 4C43DEF9110641F300E55CBF /* ThreadPlanShouldStopHere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanShouldStopHere.h; path = include/lldb/Target/ThreadPlanShouldStopHere.h; sourceTree = "<group>"; }; @@ -979,8 +982,6 @@ 4C43DF8611069BFD00E55CBF /* ThreadPlanStepOverRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepOverRange.h; path = include/lldb/Target/ThreadPlanStepOverRange.h; sourceTree = "<group>"; }; 4C43DF8911069C3200E55CBF /* ThreadPlanStepInRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepInRange.cpp; path = source/Target/ThreadPlanStepInRange.cpp; sourceTree = "<group>"; }; 4C43DF8A11069C3200E55CBF /* ThreadPlanStepOverRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepOverRange.cpp; path = source/Target/ThreadPlanStepOverRange.cpp; sourceTree = "<group>"; }; - 4C51FF1511A4C485007C962F /* ObjCTrampolineHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjCTrampolineHandler.h; sourceTree = "<group>"; }; - 4C51FF1611A4C486007C962F /* ObjCTrampolineHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjCTrampolineHandler.cpp; sourceTree = "<group>"; }; 4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectCommands.cpp; path = source/Commands/CommandObjectCommands.cpp; sourceTree = "<group>"; }; 4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectCommands.h; path = source/Commands/CommandObjectCommands.h; sourceTree = "<group>"; }; 4C74CB6212288704006A8171 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; }; @@ -1009,8 +1010,6 @@ 4CEE62FD1145F2130064CF93 /* ProcessGDBRemoteLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProcessGDBRemoteLog.h; path = "source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"; sourceTree = "<group>"; }; 4CEE62FE1145F2130064CF93 /* ThreadGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadGDBRemote.cpp; path = "source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp"; sourceTree = "<group>"; }; 4CEE62FF1145F2130064CF93 /* ThreadGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadGDBRemote.h; path = "source/Plugins/Process/gdb-remote/ThreadGDBRemote.h"; sourceTree = "<group>"; }; - 4CF4473D11A8687100EF971E /* ThreadPlanStepThroughObjCTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadPlanStepThroughObjCTrampoline.h; sourceTree = "<group>"; }; - 4CF4473E11A8687100EF971E /* ThreadPlanStepThroughObjCTrampoline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadPlanStepThroughObjCTrampoline.cpp; sourceTree = "<group>"; }; 69A01E1B1236C5D400C660B5 /* Condition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Condition.cpp; sourceTree = "<group>"; }; 69A01E1C1236C5D400C660B5 /* Host.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Host.cpp; sourceTree = "<group>"; }; 69A01E1E1236C5D400C660B5 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = "<group>"; }; @@ -1239,14 +1238,10 @@ 260C897910F57C5600BB2B04 /* MacOSX-DYLD */ = { isa = PBXGroup; children = ( - 260C897A10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.cpp */, 260C897B10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.h */, - 260C897C10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLDLog.cpp */, + 260C897A10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.cpp */, 260C897D10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLDLog.h */, - 4C51FF1511A4C485007C962F /* ObjCTrampolineHandler.h */, - 4C51FF1611A4C486007C962F /* ObjCTrampolineHandler.cpp */, - 4CF4473D11A8687100EF971E /* ThreadPlanStepThroughObjCTrampoline.h */, - 4CF4473E11A8687100EF971E /* ThreadPlanStepThroughObjCTrampoline.cpp */, + 260C897C10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLDLog.cpp */, ); path = "MacOSX-DYLD"; sourceTree = "<group>"; @@ -2013,8 +2008,6 @@ 4CB4430A12491DDA00C13DC2 /* LanguageRuntime.cpp */, 4CB443F612499B6E00C13DC2 /* ObjCLanguageRuntime.h */, 4CB443F212499B5000C13DC2 /* ObjCLanguageRuntime.cpp */, - 49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */, - 49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */, 495BBACF119A0DE700418BEA /* PathMappingList.h */, 495BBACB119A0DBE00418BEA /* PathMappingList.cpp */, 26BC7DF310F1B81A00F91463 /* Process.h */, @@ -2188,8 +2181,12 @@ 4C139EA2124A8AE5000BFF8D /* AppleRuntimeV2 */ = { isa = PBXGroup; children = ( - 4C139EA3124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp */, + 4C0A91D512511CB900CA6636 /* AppleObjCTrampolineHandler.h */, + 4C0A91D412511CB900CA6636 /* AppleObjCTrampolineHandler.cpp */, + 4C0A91D712511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h */, + 4C0A91D612511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */, 4C139EA4124A8B03000BFF8D /* AppleObjCRuntimeV2.h */, + 4C139EA3124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp */, ); name = AppleRuntimeV2; sourceTree = "<group>"; @@ -2378,6 +2375,8 @@ 4CB443F712499B6E00C13DC2 /* ObjCLanguageRuntime.h in Headers */, 96A6D9CA1249D98800250B38 /* ArchVolatileRegs-x86.h in Headers */, 4C139EA6124A8B03000BFF8D /* AppleObjCRuntimeV2.h in Headers */, + 4C0A91D912511CB900CA6636 /* AppleObjCTrampolineHandler.h in Headers */, + 4C0A91DB12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2432,7 +2431,6 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, @@ -2765,14 +2763,11 @@ 26D5B15111B07550009A862E /* unw_getcontext.s in Sources */, 26D5B15211B07550009A862E /* LibUnwindRegisterContext.cpp in Sources */, 26D5B15311B07550009A862E /* ABIMacOSX_i386.cpp in Sources */, - 26D5B15411B07550009A862E /* ObjCTrampolineHandler.cpp in Sources */, 26D5B15511B07550009A862E /* Baton.cpp in Sources */, 26D5B15611B07550009A862E /* CommandObjectArgs.cpp in Sources */, - 26D5B15711B07550009A862E /* ThreadPlanStepThroughObjCTrampoline.cpp in Sources */, 26D5B15911B07550009A862E /* UnwindLibUnwind.cpp in Sources */, 26D5B15A11B07550009A862E /* UnwindMacOSXFrameBackchain.cpp in Sources */, 26D5B15B11B07550009A862E /* RegisterContextMacOSXFrameBackchain.cpp in Sources */, - 26D5B15C11B07550009A862E /* ObjCObjectPrinter.cpp in Sources */, 26680324116005D9008E1FE4 /* SBThread.cpp in Sources */, 26680326116005DB008E1FE4 /* SBTarget.cpp in Sources */, 26680327116005DC008E1FE4 /* SBSourceManager.cpp in Sources */, @@ -2850,6 +2845,8 @@ 96A6D9C61249D96F00250B38 /* ArchVolatileRegs.cpp in Sources */, 96A6D9C91249D98800250B38 /* ArchVolatileRegs-x86.cpp in Sources */, 4C139EA5124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp in Sources */, + 4C0A91D812511CB900CA6636 /* AppleObjCTrampolineHandler.cpp in Sources */, + 4C0A91DA12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp index 6105080e27c..8ccb67c620e 100644 --- a/lldb/source/Core/Value.cpp +++ b/lldb/source/Core/Value.cpp @@ -206,18 +206,6 @@ Value::Dump (Stream* strm) Value::GetContextTypeAsCString(m_context_type)); } -void * -Value::GetOpaqueClangQualType() -{ - if (m_context_type == eContextTypeValue) - return ((Value*)m_context)->GetOpaqueClangQualType (); - - if (m_context_type == eContextTypeOpaqueClangQualType) - return m_context; - - return NULL; -} - Value::ValueType Value::GetValueType() const { @@ -429,10 +417,10 @@ Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr) } void * -Value::GetValueOpaqueClangQualType () +Value::GetOpaqueClangQualType () { if (m_context_type == eContextTypeValue) - return ((Value*)m_context)->GetValueOpaqueClangQualType(); + return ((Value*)m_context)->GetOpaqueClangQualType(); switch (m_context_type) { diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index a030ee5975c..6bb03927168 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -15,6 +15,7 @@ // C++ Includes // Other libraries and framework includes #include "llvm/Support/raw_ostream.h" +#include "clang/AST/Type.h" // Project includes #include "lldb/Core/DataBufferHeap.h" @@ -27,6 +28,7 @@ #include "lldb/Symbol/Type.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" @@ -530,44 +532,25 @@ ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope) return m_summary_str.c_str(); } - const char * ValueObject::GetObjectDescription (ExecutionContextScope *exe_scope) { if (!m_object_desc_str.empty()) return m_object_desc_str.c_str(); - if (!ClangASTContext::IsPointerType (GetOpaqueClangQualType())) - return NULL; - if (!GetValueIsValid()) return NULL; Process *process = exe_scope->CalculateProcess(); - - if (!process) + if (process == NULL) return NULL; + + StreamString s; - Scalar scalar; - - if (!ClangASTType::GetValueAsScalar (GetClangAST(), - GetOpaqueClangQualType(), - GetDataExtractor(), - 0, - GetByteSize(), - scalar)) - return NULL; - - ExecutionContext exe_ctx; - exe_scope->Calculate(exe_ctx); + lldb::LanguageType language = GetObjectRuntimeLanguage(); + LanguageRuntime *runtime = process->GetLanguageRuntime(language); - Value val(scalar); - val.SetContext(Value::eContextTypeOpaqueClangQualType, - ClangASTContext::GetVoidPtrType(GetClangAST(), false)); - - StreamString s; - // FIXME: Check the runtime this object belongs to and get the appropriate object printer for the object kind. - if (process->GetObjCObjectPrinter().PrintObject(s, val, exe_ctx)) + if (runtime && runtime->GetObjectDescription(s, *this, exe_scope)) { m_object_desc_str.append (s.GetData()); } @@ -770,6 +753,39 @@ ValueObject::Write () } +lldb::LanguageType +ValueObject::GetObjectRuntimeLanguage () +{ + void *opaque_qual_type = GetOpaqueClangQualType(); + if (opaque_qual_type == NULL) + return lldb::eLanguageTypeC; + + // If the type is a reference, then resolve it to what it refers to first: + clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType()); + if (qual_type->isAnyPointerType()) + { + if (qual_type->isObjCObjectPointerType()) + return lldb::eLanguageTypeObjC; + + clang::QualType pointee_type (qual_type->getPointeeType()); + if (pointee_type->getCXXRecordDeclForPointerType() != NULL) + return lldb::eLanguageTypeC_plus_plus; + if (pointee_type->isObjCObjectOrInterfaceType()) + return lldb::eLanguageTypeObjC; + if (pointee_type->isObjCClassType()) + return lldb::eLanguageTypeObjC; + } + else + { + if (ClangASTContext::IsObjCClassType (opaque_qual_type)) + return lldb::eLanguageTypeObjC; + if (ClangASTContext::IsCXXClassType (opaque_qual_type)); + return lldb::eLanguageTypeC_plus_plus; + } + + return lldb::eLanguageTypeC; +} + void ValueObject::AddSyntheticChild (const ConstString &key, ValueObjectSP& valobj_sp) { @@ -832,8 +848,6 @@ ValueObject::SetDynamicValue () // Check that the runtime class is correct for determining the most specific class. // If it is a C++ class, see if it is dynamic: - //if (!decl->isDynamicClass()) - // return false; - + return true; } diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp index 3093582998c..73af56c07d2 100644 --- a/lldb/source/Core/ValueObjectChild.cpp +++ b/lldb/source/Core/ValueObjectChild.cpp @@ -204,4 +204,3 @@ ValueObjectChild::IsInScope (StackFrame *frame) { return m_parent->IsInScope (frame); } - diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index bba4ba1b47c..cf465fb945f 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -93,8 +93,6 @@ ValueObjectVariable::GetValueType() const return lldb::eValueTypeInvalid; } - - void ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope) { diff --git a/lldb/source/Expression/ClangExpressionVariable.cpp b/lldb/source/Expression/ClangExpressionVariable.cpp index 3931cfb2e74..88e78dae116 100644 --- a/lldb/source/Expression/ClangExpressionVariable.cpp +++ b/lldb/source/Expression/ClangExpressionVariable.cpp @@ -97,7 +97,7 @@ ClangExpressionVariable::Print (Stream &output_stream, if (format == lldb::eFormatDefault) format = val.GetValueDefaultFormat (); - void *clang_type = val.GetValueOpaqueClangQualType (); + void *clang_type = val.GetOpaqueClangQualType (); output_stream.Printf("%s = ", m_name.c_str()); diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp index e6606a2296c..4035479cc82 100644 --- a/lldb/source/Expression/ClangFunction.cpp +++ b/lldb/source/Expression/ClangFunction.cpp @@ -322,7 +322,7 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, if (arg_value->GetValueType() == Value::eValueTypeHostAddress && arg_value->GetContextType() == Value::eContextTypeOpaqueClangQualType && - ClangASTContext::IsPointerType(arg_value->GetValueOpaqueClangQualType())) + ClangASTContext::IsPointerType(arg_value->GetOpaqueClangQualType())) continue; const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext()); diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index a5956428692..73a333f2bdf 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -15,6 +15,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" @@ -61,8 +62,7 @@ DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) : m_dyld_all_image_infos(), m_break_id(LLDB_INVALID_BREAK_ID), m_dyld_image_infos(), - m_mutex(Mutex::eMutexTypeRecursive), - m_objc_trampoline_handler_ap(NULL) + m_mutex(Mutex::eMutexTypeRecursive) { } @@ -648,14 +648,15 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() // to save time. // Also, I'm assuming there can be only one libobjc dylib loaded... - if (m_objc_trampoline_handler_ap.get() == NULL) + ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(); + if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary()) { size_t num_modules = loaded_module_list.GetSize(); for (int i = 0; i < num_modules; i++) { - if (ObjCTrampolineHandler::ModuleIsObjCLibrary (loaded_module_list.GetModuleAtIndex (i))) + if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i))) { - m_objc_trampoline_handler_ap.reset (new ObjCTrampolineHandler(m_process->GetSP(), loaded_module_list.GetModuleAtIndex (i))); + objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i)); break; } } @@ -1137,9 +1138,6 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop log->Printf ("Could not find symbol for step through."); } - if (thread_plan_sp == NULL && m_objc_trampoline_handler_ap.get()) - thread_plan_sp = m_objc_trampoline_handler_ap->GetStepThroughDispatchPlan (thread, stop_others); - return thread_plan_sp; } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h index 44fb329e35e..8f22dbdcb63 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h @@ -25,8 +25,6 @@ #include "lldb/Host/Mutex.h" #include "lldb/Target/Process.h" -#include "ObjCTrampolineHandler.h" - class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoader { public: @@ -352,7 +350,6 @@ protected: DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information mutable lldb_private::Mutex m_mutex; lldb_private::Process::Notifications m_notification_callbacks; - std::auto_ptr<lldb_private::ObjCTrampolineHandler> m_objc_trampoline_handler_ap; private: DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD); diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ObjCTrampolineHandler.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ObjCTrampolineHandler.h deleted file mode 100644 index 961a5cc4d94..00000000000 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ObjCTrampolineHandler.h +++ /dev/null @@ -1,132 +0,0 @@ -//===-- ObjCTrampolineHandler.h ----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef lldb_ObjCTrampolineHandler_h_ -#define lldb_ObjCTrampolineHandler_h_ - -// C Includes -// C++ Includes -#include <map> -#include <string> -// Other libraries and framework includes -// Project includes -#include "lldb/Expression/ClangExpression.h" -#include "lldb/Expression/ClangFunction.h" -#include "lldb/Host/Mutex.h" - - -namespace lldb_private -{ -using namespace lldb; - -class ObjCTrampolineHandler { -public: - - ObjCTrampolineHandler (ProcessSP process_sp, ModuleSP objc_module_sp); - - ~ObjCTrampolineHandler() {} - - static bool ModuleIsObjCLibrary (const ModuleSP &module_sp); - - ThreadPlanSP - GetStepThroughDispatchPlan (Thread &thread, bool stop_others); - - void - AddToCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr); - - lldb::addr_t - LookupInCache (lldb::addr_t class_addr, lldb::addr_t sel); - - ClangFunction * - GetLookupImplementationWrapperFunction (); - - - struct DispatchFunction { - public: - typedef enum - { - eFixUpNone, - eFixUpFixed, - eFixUpToFix - } FixUpState; - - const char *name; - bool stret_return; - bool is_super; - FixUpState fixedup; - }; - -private: - static const DispatchFunction g_dispatch_functions[]; - - typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch fn address to the index in g_dispatch_functions - MsgsendMap m_msgSend_map; - ProcessSP m_process_sp; - ModuleSP m_objc_module_sp; - lldb::addr_t get_impl_addr; - std::auto_ptr<ClangFunction> m_impl_function; - Mutex m_impl_function_mutex; - lldb::addr_t m_impl_fn_addr; - lldb::addr_t m_impl_stret_fn_addr; - - - // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver - // function over and over. - - // FIXME: We need to watch for the loading of Protocols, and flush the cache for any - // class that we see so changed. - - struct ClassAndSel - { - ClassAndSel() - { - sel_addr = LLDB_INVALID_ADDRESS; - class_addr = LLDB_INVALID_ADDRESS; - } - ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) : - class_addr (in_class_addr), - sel_addr(in_sel_addr) - { - } - bool operator== (const ClassAndSel &rhs) - { - if (class_addr == rhs.class_addr - && sel_addr == rhs.sel_addr) - return true; - else - return false; - } - - bool operator< (const ClassAndSel &rhs) const - { - if (class_addr < rhs.class_addr) - return true; - else if (class_addr > rhs.class_addr) - return false; - else - { - if (sel_addr < rhs.sel_addr) - return true; - else - return false; - } - } - - lldb::addr_t class_addr; - lldb::addr_t sel_addr; - }; - - typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap; - MsgImplMap m_impl_cache; - -}; - -} // using namespace lldb_private - -#endif // lldb_ObjCTrampolineHandler_h_ diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index ee54e319a6b..425c8f73a6c 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -29,6 +29,26 @@ static const char *pluginName = "ItaniumABILanguageRuntime"; static const char *pluginDesc = "Itanium ABI for the C++ language"; static const char *pluginShort = "language.itanium"; +lldb::ValueObjectSP +ItaniumABILanguageRuntime::GetDynamicValue (ValueObjectSP in_value, ExecutionContextScope *exe_scope) +{ + ValueObjectSP ret_sp; + return ret_sp; +} + +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 //------------------------------------------------------------------ @@ -96,16 +116,3 @@ ItaniumABILanguageRuntime::EnablePluginLogging (Stream *strm, Args &command) { return NULL; } - -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; -} diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index 4ae6a89bad8..817c0760340 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -30,6 +30,9 @@ namespace lldb_private { virtual bool IsVTableName (const char *name); + virtual lldb::ValueObjectSP + GetDynamicValue (lldb::ValueObjectSP in_value, ExecutionContextScope *exe_scope); + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp index 655e72ed6c7..6d9d302653a 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp @@ -8,13 +8,18 @@ //===----------------------------------------------------------------------===// #include "AppleObjCRuntimeV2.h" +#include "AppleObjCTrampolineHandler.h" #include "lldb/Core/ConstString.h" #include "lldb/Core/Error.h" +#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Scalar.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Expression/ClangFunction.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" @@ -29,6 +34,162 @@ static const char *pluginName = "AppleObjCRuntimeV2"; static const char *pluginDesc = "Apple Objective C Language Runtime - Version 2"; static const char *pluginShort = "language.apple.objc.v2"; +bool +AppleObjCRuntimeV2::GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope) +{ + ExecutionContext exe_ctx; + exe_scope->Calculate(exe_ctx); + + if (!exe_ctx.process) + return false; + + // We need other parts of the exe_ctx, but the processes have to match. + assert (m_process == exe_ctx.process); + + // ObjC objects can only be pointers: + if (!ClangASTContext::IsPointerType (object.GetOpaqueClangQualType())) + return NULL; + + // Get the function address for the print function. + const Address *function_address = GetPrintForDebuggerAddr(); + if (!function_address) + return false; + + // Make the argument list: we pass one arg, the address of our pointer, to the print function. + Scalar scalar; + + if (!ClangASTType::GetValueAsScalar (object.GetClangAST(), + object.GetOpaqueClangQualType(), + object.GetDataExtractor(), + 0, + object.GetByteSize(), + scalar)) + return NULL; + + Value val(scalar); + val.SetContext(Value::eContextTypeOpaqueClangQualType, + ClangASTContext::GetVoidPtrType(object.GetClangAST(), false)); + + ValueList arg_value_list; + arg_value_list.PushValue(val); + + // This is the return value: + const char *target_triple = exe_ctx.process->GetTargetTriple().GetCString(); + ClangASTContext *ast_context = exe_ctx.target->GetScratchClangASTContext(); + + void *return_qualtype = ast_context->GetCStringType(true); + Value ret; + ret.SetContext(Value::eContextTypeOpaqueClangQualType, return_qualtype); + + // Now we're ready to call the function: + ClangFunction func(target_triple, ast_context, return_qualtype, *function_address, arg_value_list); + StreamString error_stream; + + lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS; + func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream); + + ClangFunction::ExecutionResults results + = func.ExecuteFunction(exe_ctx, &wrapper_struct_addr, error_stream, true, 1000, true, ret); + if (results != ClangFunction::eExecutionCompleted) + { + str.Printf("Error evaluating Print Object function: %d.\n", results); + return false; + } + + addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); + + // FIXME: poor man's strcpy - we should have a "read memory as string interface... + + Error error; + std::vector<char> desc; + while (1) + { + char byte = '\0'; + if (exe_ctx.process->ReadMemory(result_ptr + desc.size(), &byte, 1, error) != 1) + break; + + desc.push_back(byte); + + if (byte == '\0') + break; + } + + if (!desc.empty()) + { + str.PutCString(&desc.front()); + return true; + } + return false; + +} + +Address * +AppleObjCRuntimeV2::GetPrintForDebuggerAddr() +{ + if (!m_PrintForDebugger_addr.get()) + { + ModuleList &modules = m_process->GetTarget().GetImages(); + + SymbolContextList contexts; + SymbolContext context; + + if((!modules.FindSymbolsWithNameAndType(ConstString ("_NSPrintForDebugger"), eSymbolTypeCode, contexts)) && + (!modules.FindSymbolsWithNameAndType(ConstString ("_CFPrintForDebugger"), eSymbolTypeCode, contexts))) + return NULL; + + contexts.GetContextAtIndex(0, context); + + m_PrintForDebugger_addr.reset(new Address(context.symbol->GetValue())); + } + + return m_PrintForDebugger_addr.get(); +} + +lldb::ValueObjectSP +AppleObjCRuntimeV2::GetDynamicValue (lldb::ValueObjectSP in_value, ExecutionContextScope *exe_scope) +{ + lldb::ValueObjectSP ret_sp; + return ret_sp; +} + +bool +AppleObjCRuntimeV2::IsModuleObjCLibrary (const ModuleSP &module_sp) +{ + const FileSpec &module_file_spec = module_sp->GetFileSpec(); + static ConstString ObjCName ("libobjc.A.dylib"); + + if (module_file_spec) + { + if (module_file_spec.GetFilename() == ObjCName) + return true; + } + + return false; +} + +bool +AppleObjCRuntimeV2::ReadObjCLibrary (const ModuleSP &module_sp) +{ + // Maybe check here and if we have a handler already, and the UUID of this module is the same as the one in the + // current module, then we don't have to reread it? + m_objc_trampoline_handler_ap.reset(new AppleObjCTrampolineHandler (m_process->GetSP(), module_sp)); + if (m_objc_trampoline_handler_ap.get() != NULL) + { + m_read_objc_library = true; + return true; + } + else + return false; +} + +ThreadPlanSP +AppleObjCRuntimeV2::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) +{ + ThreadPlanSP thread_plan_sp; + thread_plan_sp = m_objc_trampoline_handler_ap->GetStepThroughDispatchPlan (thread, stop_others); + return thread_plan_sp; +} + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h index 9c447b82f8d..17c94bcf538 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h @@ -17,53 +17,88 @@ #include "lldb/lldb-private.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/ObjCLanguageRuntime.h" -#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObject.h" +#include "AppleObjCTrampolineHandler.h" +#include "AppleThreadPlanStepThroughObjCTrampoline.h" namespace lldb_private { - class AppleObjCRuntimeV2 : - public lldb_private::ObjCLanguageRuntime +class AppleObjCRuntimeV2 : + public lldb_private::ObjCLanguageRuntime +{ +public: + ~AppleObjCRuntimeV2() { } + + // These are generic runtime functions: + virtual bool + GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope); + + virtual lldb::ValueObjectSP + GetDynamicValue (lldb::ValueObjectSP in_value, ExecutionContextScope *exe_scope); + + // These are the ObjC specific functions. + virtual bool + IsModuleObjCLibrary (const lldb::ModuleSP &module_sp); + + virtual bool + ReadObjCLibrary (const lldb::ModuleSP &module_sp); + + virtual bool + HasReadObjCLibrary () { - public: - ~AppleObjCRuntimeV2() { } - - - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static void - Initialize(); - - static void - Terminate(); - - static lldb_private::LanguageRuntime * - CreateInstance (Process *process, lldb::LanguageType language); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - virtual const char * - GetPluginName(); - - virtual const char * - GetShortPluginName(); - - virtual uint32_t - GetPluginVersion(); - - virtual void - GetPluginCommandHelp (const char *command, lldb_private::Stream *strm); - - virtual lldb_private::Error - ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm); - - virtual lldb_private::Log * - EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command); - protected: - private: - AppleObjCRuntimeV2(Process *process) : lldb_private::ObjCLanguageRuntime(process) { } // Call CreateInstance instead. - }; + return m_read_objc_library; + } + + virtual lldb::ThreadPlanSP + GetStepThroughTrampolinePlan (Thread &thread, bool stop_others); + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static lldb_private::LanguageRuntime * + CreateInstance (Process *process, lldb::LanguageType language); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + virtual const char * + GetPluginName(); + + virtual const char * + GetShortPluginName(); + + virtual uint32_t + GetPluginVersion(); + + virtual void + GetPluginCommandHelp (const char *command, lldb_private::Stream *strm); + + virtual lldb_private::Error + ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm); + + virtual lldb_private::Log * + EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command); +protected: + Address * + GetPrintForDebuggerAddr(); + +private: + std::auto_ptr<Address> m_PrintForDebugger_addr; + bool m_read_objc_library; + std::auto_ptr<lldb_private::AppleObjCTrampolineHandler> m_objc_trampoline_handler_ap; + + AppleObjCRuntimeV2(Process *process) : + lldb_private::ObjCLanguageRuntime(process), + m_read_objc_library (false), + m_objc_trampoline_handler_ap(NULL) + { } // Call CreateInstance instead. +}; } // namespace lldb_private diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCTrampolineHandler.cpp index 943e8bab890..f086d1b1da8 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ObjCTrampolineHandler.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCTrampolineHandler.cpp @@ -1,4 +1,4 @@ -//===-- ObjCTrampolineHandler.cpp ----------------------------*- C++ -*-===// +//===-- AppleObjCTrampolineHandler.cpp ----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,59 +7,61 @@ // //===----------------------------------------------------------------------===// -#include "ObjCTrampolineHandler.h" +#include "AppleObjCTrampolineHandler.h" // C Includes // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/Module.h" +#include "AppleThreadPlanStepThroughObjCTrampoline.h" + #include "lldb/Core/ConstString.h" #include "lldb/Core/FileSpec.h" -#include "lldb/Target/Thread.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Process.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" #include "lldb/Core/Value.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Expression/ClangFunction.h" -#include "lldb/Core/Log.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/ObjCLanguageRuntime.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" #include "lldb/Target/ExecutionContext.h" -#include "ThreadPlanStepThroughObjCTrampoline.h" #include "lldb/Target/ThreadPlanRunToAddress.h" using namespace lldb; using namespace lldb_private; -const ObjCTrampolineHandler::DispatchFunction -ObjCTrampolineHandler::g_dispatch_functions[] = +const AppleObjCTrampolineHandler::DispatchFunction +AppleObjCTrampolineHandler::g_dispatch_functions[] = { // NAME STRET SUPER FIXUP TYPE - {"objc_msgSend", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSend_fixup", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSend_fixedup", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSend_stret", true, false, ObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSend_stret_fixup", true, false, ObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSend_stret_fixedup", true, false, ObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSend_fpret", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSend_fpret_fixup", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSend_fpret_fixedup", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSend_fp2ret", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSend_fp2ret_fixup", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSend_fp2ret_fixedup", false, false, ObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSendSuper", false, true, ObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSendSuper_stret", true, true, ObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSendSuper2", false, true, ObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSendSuper2_fixup", false, true, ObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSendSuper2_fixedup", false, true, ObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSendSuper2_stret", true, true, ObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSendSuper2_stret_fixup", true, true, ObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSendSuper2_stret_fixedup", true, true, ObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, + {"objc_msgSend", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, + {"objc_msgSend_fixup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, + {"objc_msgSend_fixedup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, + {"objc_msgSend_stret", true, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, + {"objc_msgSend_stret_fixup", true, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, + {"objc_msgSend_stret_fixedup", true, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, + {"objc_msgSend_fpret", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, + {"objc_msgSend_fpret_fixup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, + {"objc_msgSend_fpret_fixedup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, + {"objc_msgSend_fp2ret", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, + {"objc_msgSend_fp2ret_fixup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, + {"objc_msgSend_fp2ret_fixedup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, + {"objc_msgSendSuper", false, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, + {"objc_msgSendSuper_stret", true, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, + {"objc_msgSendSuper2", false, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, + {"objc_msgSendSuper2_fixup", false, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, + {"objc_msgSendSuper2_fixedup", false, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, + {"objc_msgSendSuper2_stret", true, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, + {"objc_msgSendSuper2_stret_fixup", true, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, + {"objc_msgSendSuper2_stret_fixedup", true, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, {NULL} }; bool -ObjCTrampolineHandler::ModuleIsObjCLibrary (const ModuleSP &module_sp) +AppleObjCTrampolineHandler::ModuleIsObjCLibrary (const ModuleSP &module_sp) { const FileSpec &module_file_spec = module_sp->GetFileSpec(); static ConstString ObjCName ("libobjc.A.dylib"); @@ -73,7 +75,7 @@ ObjCTrampolineHandler::ModuleIsObjCLibrary (const ModuleSP &module_sp) return false; } -ObjCTrampolineHandler::ObjCTrampolineHandler (ProcessSP process_sp, ModuleSP objc_module) : +AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (ProcessSP process_sp, ModuleSP objc_module) : m_process_sp (process_sp), m_objc_module_sp (objc_module), m_impl_fn_addr (LLDB_INVALID_ADDRESS), @@ -120,7 +122,7 @@ ObjCTrampolineHandler::ObjCTrampolineHandler (ProcessSP process_sp, ModuleSP obj } ThreadPlanSP -ObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_others) +AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_others) { ThreadPlanSP ret_plan_sp; lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC(); @@ -234,8 +236,9 @@ ObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_oth dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong()); } - - lldb::addr_t impl_addr = LookupInCache (dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), + ObjCLanguageRuntime *objc_runtime = m_process_sp->GetObjCLanguageRuntime (); + assert(objc_runtime != NULL); + lldb::addr_t impl_addr = objc_runtime->LookupInMethodCache (dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong()); if (impl_addr == LLDB_INVALID_ADDRESS) @@ -281,7 +284,7 @@ ObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_oth if (!m_impl_function->WriteFunctionArguments (exec_ctx, args_addr, resolve_address, dispatch_values, errors)) return ret_plan_sp; - ret_plan_sp.reset (new ThreadPlanStepThroughObjCTrampoline (thread, this, args_addr, + ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread, this, args_addr, argument_values.GetValueAtIndex(0)->GetScalar().ULongLong(), dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong(), @@ -299,29 +302,8 @@ ObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_oth return ret_plan_sp; } -void -ObjCTrampolineHandler::AddToCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); - if (log) - { - log->Printf ("Caching: class 0x%llx selector 0x%llx implementation 0x%llx.", class_addr, selector, impl_addr); - } - m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr)); -} - -lldb::addr_t -ObjCTrampolineHandler::LookupInCache (lldb::addr_t class_addr, lldb::addr_t selector) -{ - MsgImplMap::iterator pos, end = m_impl_cache.end(); - pos = m_impl_cache.find (ClassAndSel(class_addr, selector)); - if (pos != end) - return (*pos).second; - return LLDB_INVALID_ADDRESS; -} - ClangFunction * -ObjCTrampolineHandler::GetLookupImplementationWrapperFunction () +AppleObjCTrampolineHandler::GetLookupImplementationWrapperFunction () { return m_impl_function.get(); } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCTrampolineHandler.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCTrampolineHandler.h new file mode 100644 index 00000000000..5e80bac414c --- /dev/null +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCTrampolineHandler.h @@ -0,0 +1,77 @@ +//===-- AppleObjCTrampolineHandler.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_AppleObjCTrampolineHandler_h_ +#define lldb_AppleObjCTrampolineHandler_h_ + +// C Includes +// C++ Includes +#include <map> +#include <string> +// Other libraries and framework includes +// Project includes +#include "lldb/Expression/ClangExpression.h" +#include "lldb/Expression/ClangFunction.h" +#include "lldb/Host/Mutex.h" + + +namespace lldb_private +{ +using namespace lldb; + +class AppleObjCTrampolineHandler { +public: + + AppleObjCTrampolineHandler (ProcessSP process_sp, ModuleSP objc_module_sp); + + ~AppleObjCTrampolineHandler() {} + + static bool ModuleIsObjCLibrary (const ModuleSP &module_sp); + + ThreadPlanSP + GetStepThroughDispatchPlan (Thread &thread, bool stop_others); + + ClangFunction * + GetLookupImplementationWrapperFunction (); + + + struct DispatchFunction { + public: + typedef enum + { + eFixUpNone, + eFixUpFixed, + eFixUpToFix + } FixUpState; + + const char *name; + bool stret_return; + bool is_super; + FixUpState fixedup; + }; + +private: + static const DispatchFunction g_dispatch_functions[]; + + typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch fn address to the index in g_dispatch_functions + MsgsendMap m_msgSend_map; + ProcessSP m_process_sp; + ModuleSP m_objc_module_sp; + lldb::addr_t get_impl_addr; + std::auto_ptr<ClangFunction> m_impl_function; + Mutex m_impl_function_mutex; + lldb::addr_t m_impl_fn_addr; + lldb::addr_t m_impl_stret_fn_addr; + + +}; + +} // using namespace lldb_private + +#endif // lldb_AppleObjCTrampolineHandler_h_ diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleThreadPlanStepThroughObjCTrampoline.cpp index 7b4aa4e87cf..62b75d509b3 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepThroughObjCTrampoline.cpp --------------------------*- C++ -*-===// +//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp --------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,12 +11,14 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "ThreadPlanStepThroughObjCTrampoline.h" +#include "AppleThreadPlanStepThroughObjCTrampoline.h" +#include "AppleObjCTrampolineHandler.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Expression/ClangExpression.h" #include "lldb/Expression/ClangFunction.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/ThreadPlanRunToAddress.h" #include "lldb/Core/Log.h" @@ -25,22 +27,23 @@ using namespace lldb_private; //---------------------------------------------------------------------- // ThreadPlanStepThroughObjCTrampoline constructor //---------------------------------------------------------------------- -ThreadPlanStepThroughObjCTrampoline::ThreadPlanStepThroughObjCTrampoline( +AppleThreadPlanStepThroughObjCTrampoline::AppleThreadPlanStepThroughObjCTrampoline( Thread &thread, - ObjCTrampolineHandler *trampoline_handler, + AppleObjCTrampolineHandler *trampoline_handler, lldb::addr_t args_addr, lldb::addr_t object_ptr, lldb::addr_t class_ptr, lldb::addr_t sel_ptr, bool stop_others) : - ThreadPlan (ThreadPlan::eKindGeneric, "MacOSX Step through ObjC Trampoline", thread, eVoteNoOpinion, eVoteNoOpinion), - m_args_addr (args_addr), + ThreadPlan (ThreadPlan::eKindGeneric, "MacOSX Step through ObjC Trampoline", thread, + lldb::eVoteNoOpinion, lldb::eVoteNoOpinion), m_stop_others (stop_others), - m_objc_trampoline_handler (trampoline_handler), - m_impl_function (trampoline_handler->GetLookupImplementationWrapperFunction()), m_object_ptr (object_ptr), m_class_ptr (class_ptr), - m_sel_ptr (sel_ptr) + m_sel_ptr (sel_ptr), + m_args_addr (args_addr), + m_objc_trampoline_handler (trampoline_handler), + m_impl_function (trampoline_handler->GetLookupImplementationWrapperFunction()) { } @@ -48,12 +51,12 @@ ThreadPlanStepThroughObjCTrampoline::ThreadPlanStepThroughObjCTrampoline( //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -ThreadPlanStepThroughObjCTrampoline::~ThreadPlanStepThroughObjCTrampoline() +AppleThreadPlanStepThroughObjCTrampoline::~AppleThreadPlanStepThroughObjCTrampoline() { } void -ThreadPlanStepThroughObjCTrampoline::DidPush () +AppleThreadPlanStepThroughObjCTrampoline::DidPush () { StreamString errors; ExecutionContext exc_context; @@ -64,7 +67,7 @@ ThreadPlanStepThroughObjCTrampoline::DidPush () } void -ThreadPlanStepThroughObjCTrampoline::GetDescription (Stream *s, +AppleThreadPlanStepThroughObjCTrampoline::GetDescription (Stream *s, lldb::DescriptionLevel level) { if (level == lldb::eDescriptionLevelBrief) @@ -77,13 +80,13 @@ ThreadPlanStepThroughObjCTrampoline::GetDescription (Stream *s, } bool -ThreadPlanStepThroughObjCTrampoline::ValidatePlan (Stream *error) +AppleThreadPlanStepThroughObjCTrampoline::ValidatePlan (Stream *error) { return true; } bool -ThreadPlanStepThroughObjCTrampoline::PlanExplainsStop () +AppleThreadPlanStepThroughObjCTrampoline::PlanExplainsStop () { // This plan should actually never stop when it is on the top of the plan // stack, since it does all it's running in client plans. @@ -91,13 +94,13 @@ ThreadPlanStepThroughObjCTrampoline::PlanExplainsStop () } lldb::StateType -ThreadPlanStepThroughObjCTrampoline::RunState () +AppleThreadPlanStepThroughObjCTrampoline::RunState () { return eStateRunning; } bool -ThreadPlanStepThroughObjCTrampoline::ShouldStop (Event *event_ptr) +AppleThreadPlanStepThroughObjCTrampoline::ShouldStop (Event *event_ptr) { if (m_func_sp.get() == NULL || m_thread.IsThreadPlanDone(m_func_sp.get())) { @@ -115,7 +118,9 @@ ThreadPlanStepThroughObjCTrampoline::ShouldStop (Event *event_ptr) if (log) log->Printf("Running to ObjC method implementation: 0x%llx", target_addr); - m_objc_trampoline_handler->AddToCache (m_class_ptr, m_sel_ptr, target_addr); + ObjCLanguageRuntime *objc_runtime = GetThread().GetProcess().GetObjCLanguageRuntime(); + assert (objc_runtime != NULL); + objc_runtime->AddToMethodCache (m_class_ptr, m_sel_ptr, target_addr); // Extract the target address from the value: @@ -136,7 +141,7 @@ ThreadPlanStepThroughObjCTrampoline::ShouldStop (Event *event_ptr) // The base class MischiefManaged does some cleanup - so you have to call it // in your MischiefManaged derived class. bool -ThreadPlanStepThroughObjCTrampoline::MischiefManaged () +AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged () { if (IsPlanComplete()) return true; @@ -145,7 +150,7 @@ ThreadPlanStepThroughObjCTrampoline::MischiefManaged () } bool -ThreadPlanStepThroughObjCTrampoline::WillStop() +AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleThreadPlanStepThroughObjCTrampoline.h index f30c333df6b..207c88ddc80 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleThreadPlanStepThroughObjCTrampoline.h @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepThroughObjCTrampoline.h --------------------------*- C++ -*-===// +//===-- AppleThreadPlanStepThroughObjCTrampoline.h --------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ThreadPlanStepThroughObjCTrampoline_h_ -#define lldb_ThreadPlanStepThroughObjCTrampoline_h_ +#ifndef lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ +#define lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ // C Includes // C++ Includes @@ -17,26 +17,26 @@ #include "lldb/lldb-types.h" #include "lldb/lldb-enumerations.h" #include "lldb/Target/ThreadPlan.h" -#include "ObjCTrampolineHandler.h" +#include "AppleObjCTrampolineHandler.h" namespace lldb_private { -class ThreadPlanStepThroughObjCTrampoline : public ThreadPlan +class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan { public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - ThreadPlanStepThroughObjCTrampoline(Thread &thread, - ObjCTrampolineHandler *trampoline_handler, + AppleThreadPlanStepThroughObjCTrampoline(Thread &thread, + AppleObjCTrampolineHandler *trampoline_handler, lldb::addr_t args_addr, lldb::addr_t object_ptr, lldb::addr_t class_ptr, lldb::addr_t sel_ptr, bool stop_others); - virtual ~ThreadPlanStepThroughObjCTrampoline(); + virtual ~AppleThreadPlanStepThroughObjCTrampoline(); virtual void GetDescription (Stream *s, @@ -70,26 +70,27 @@ public: protected: //------------------------------------------------------------------ - // Classes that inherit from ThreadPlanStepThroughObjCTrampoline can see and modify these + // Classes that inherit from AppleThreadPlanStepThroughObjCTrampoline can see and modify these //------------------------------------------------------------------ private: //------------------------------------------------------------------ - // For ThreadPlanStepThroughObjCTrampoline only + // For AppleThreadPlanStepThroughObjCTrampoline only //------------------------------------------------------------------ + bool m_stop_others; + lldb::addr_t m_object_ptr; + lldb::addr_t m_class_ptr; + lldb::addr_t m_sel_ptr; + ThreadPlanSP m_func_sp; // This is the function call plan. We fill it at start, then set it // to NULL when this plan is done. That way we know to go to: lldb::addr_t m_args_addr; // Stores the address for our step through function result structure. ThreadPlanSP m_run_to_sp; // The plan that runs to the target. - bool m_stop_others; - ObjCTrampolineHandler *m_objc_trampoline_handler; + AppleObjCTrampolineHandler *m_objc_trampoline_handler; ClangFunction *m_impl_function; // This is a pointer to a impl function that // is owned by the client that pushes this plan. - lldb::addr_t m_object_ptr; - lldb::addr_t m_class_ptr; - lldb::addr_t m_sel_ptr; }; } // namespace lldb_private -#endif // lldb_ThreadPlanStepThroughObjCTrampoline_h_ +#endif // lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ diff --git a/lldb/source/Target/CPPLanguageRuntime.cpp b/lldb/source/Target/CPPLanguageRuntime.cpp index 3e825bb2c3a..d694b7702b3 100644 --- a/lldb/source/Target/CPPLanguageRuntime.cpp +++ b/lldb/source/Target/CPPLanguageRuntime.cpp @@ -9,6 +9,7 @@ #include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Target/ExecutionContext.h" using namespace lldb; using namespace lldb_private; @@ -24,4 +25,11 @@ CPPLanguageRuntime::CPPLanguageRuntime (Process *process) : LanguageRuntime (process) { -}
\ No newline at end of file +} + +bool +CPPLanguageRuntime::GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope) +{ + // C++ has no generic way to do this. + return false; +} diff --git a/lldb/source/Target/LanguageRuntime.cpp b/lldb/source/Target/LanguageRuntime.cpp index 00c35f80633..3b5b3299844 100644 --- a/lldb/source/Target/LanguageRuntime.cpp +++ b/lldb/source/Target/LanguageRuntime.cpp @@ -35,7 +35,8 @@ LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language) //---------------------------------------------------------------------- // Constructor //---------------------------------------------------------------------- -LanguageRuntime::LanguageRuntime(Process *process) +LanguageRuntime::LanguageRuntime(Process *process) : + m_process (process) { } diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp index ab7e7e55a90..0a136336a26 100644 --- a/lldb/source/Target/ObjCLanguageRuntime.cpp +++ b/lldb/source/Target/ObjCLanguageRuntime.cpp @@ -7,8 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Target/ObjCLanguageRuntime.h" +#include "lldb/Core/Log.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Target/ObjCLanguageRuntime.h" using namespace lldb; using namespace lldb_private; @@ -24,4 +25,26 @@ ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) : LanguageRuntime (process) { -}
\ No newline at end of file +} + +void +ObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr) +{ + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); + if (log) + { + log->Printf ("Caching: class 0x%llx selector 0x%llx implementation 0x%llx.", class_addr, selector, impl_addr); + } + m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr)); +} + +lldb::addr_t +ObjCLanguageRuntime::LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t selector) +{ + MsgImplMap::iterator pos, end = m_impl_cache.end(); + pos = m_impl_cache.find (ClassAndSel(class_addr, selector)); + if (pos != end) + return (*pos).second; + return LLDB_INVALID_ADDRESS; +} + diff --git a/lldb/source/Target/ObjCObjectPrinter.cpp b/lldb/source/Target/ObjCObjectPrinter.cpp deleted file mode 100644 index 72015e2d650..00000000000 --- a/lldb/source/Target/ObjCObjectPrinter.cpp +++ /dev/null @@ -1,122 +0,0 @@ -//===-- ObjCObjectPrinter.cpp -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/StreamString.h" -#include "lldb/Expression/ClangFunction.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" - -#include "lldb/Target/ObjCObjectPrinter.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// ObjCObjectPrinter constructor -//---------------------------------------------------------------------- -ObjCObjectPrinter::ObjCObjectPrinter (Process &process) : - m_process(process) -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -ObjCObjectPrinter::~ObjCObjectPrinter () -{ -} - -bool -ObjCObjectPrinter::PrintObject (Stream &str, Value &object_ptr, ExecutionContext &exe_ctx) -{ - if (!exe_ctx.process) - return false; - - const Address *function_address = GetPrintForDebuggerAddr(); - - if (!function_address) - return false; - - const char *target_triple = exe_ctx.process->GetTargetTriple().GetCString(); - ClangASTContext *ast_context = exe_ctx.target->GetScratchClangASTContext(); - - void *return_qualtype = ast_context->GetCStringType(true); - Value ret; - ret.SetContext(Value::eContextTypeOpaqueClangQualType, return_qualtype); - - ValueList arg_value_list; - arg_value_list.PushValue(object_ptr); - - ClangFunction func(target_triple, ast_context, return_qualtype, *function_address, arg_value_list); - StreamString error_stream; - - lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS; - func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream); - // FIXME: Check result of ExecuteFunction. - ClangFunction::ExecutionResults results - = func.ExecuteFunction(exe_ctx, &wrapper_struct_addr, error_stream, true, 1000, true, ret); - if (results != ClangFunction::eExecutionCompleted) - { - str.Printf("Error evaluating Print Object function: %d.\n", results); - return false; - } - - addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); - - // poor man's strcpy - - Error error; - std::vector<char> desc; - while (1) - { - char byte = '\0'; - if (exe_ctx.process->ReadMemory(result_ptr + desc.size(), &byte, 1, error) != 1) - break; - - desc.push_back(byte); - - if (byte == '\0') - break; - } - - if (!desc.empty()) - { - str.PutCString(&desc.front()); - return true; - } - return false; -} - -Address * -ObjCObjectPrinter::GetPrintForDebuggerAddr() -{ - if (!m_PrintForDebugger_addr.get()) - { - ModuleList &modules = m_process.GetTarget().GetImages(); - - SymbolContextList contexts; - SymbolContext context; - - if((!modules.FindSymbolsWithNameAndType(ConstString ("_NSPrintForDebugger"), eSymbolTypeCode, contexts)) && - (!modules.FindSymbolsWithNameAndType(ConstString ("_CFPrintForDebugger"), eSymbolTypeCode, contexts))) - return NULL; - - contexts.GetContextAtIndex(0, context); - - m_PrintForDebugger_addr.reset(new Address(context.symbol->GetValue())); - } - - return m_PrintForDebugger_addr.get(); -} - diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 646a8e8a807..9086c15e805 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -84,7 +84,6 @@ Process::Process(Target &target, Listener &listener) : m_notifications (), m_listener(listener), m_unix_signals (), - m_objc_object_printer(*this), m_persistent_vars() { UpdateInstanceName(); @@ -1839,12 +1838,6 @@ Process::GetPersistentVariables() return m_persistent_vars; } -ObjCObjectPrinter & -Process::GetObjCObjectPrinter() -{ - return m_objc_object_printer; -} - uint32_t Process::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids) { diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index d4fbfdf3bfb..fb4ad9a3bf2 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -16,6 +16,7 @@ #include "lldb/Host/Host.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" @@ -662,7 +663,16 @@ Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_c ThreadPlan * Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads) { + // Try the dynamic loader first: ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads)); + // If that didn't come up with anything, try the ObjC runtime plugin: + if (thread_plan_sp.get() == NULL) + { + ObjCLanguageRuntime *objc_runtime = GetProcess().GetObjCLanguageRuntime(); + if (objc_runtime) + thread_plan_sp = objc_runtime->GetStepThroughTrampolinePlan (*this, stop_other_threads); + } + if (thread_plan_sp.get() == NULL) { thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads)); diff --git a/lldb/source/Target/ThreadPlanStepThrough.cpp b/lldb/source/Target/ThreadPlanStepThrough.cpp index 7fb7538af3f..5aaa984b8ba 100644 --- a/lldb/source/Target/ThreadPlanStepThrough.cpp +++ b/lldb/source/Target/ThreadPlanStepThrough.cpp @@ -17,6 +17,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Stream.h" #include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -93,6 +94,14 @@ ThreadPlanStepThrough::WillResume (StateType resume_state, bool current_plan) if (current_plan) { ThreadPlanSP sub_plan_sp(m_thread.GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (m_thread, m_stop_others)); + // If that didn't come up with anything, try the ObjC runtime plugin: + if (sub_plan_sp == NULL) + { + ObjCLanguageRuntime *objc_runtime = m_thread.GetProcess().GetObjCLanguageRuntime(); + if (objc_runtime) + sub_plan_sp = objc_runtime->GetStepThroughTrampolinePlan (m_thread, m_stop_others); + } + if (sub_plan_sp != NULL) PushPlan (sub_plan_sp); } |