diff options
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader/MacOSX-DYLD')
6 files changed, 6 insertions, 716 deletions
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.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ObjCTrampolineHandler.cpp deleted file mode 100644 index 943e8bab890..00000000000 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ObjCTrampolineHandler.cpp +++ /dev/null @@ -1,327 +0,0 @@ -//===-- ObjCTrampolineHandler.cpp ----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ObjCTrampolineHandler.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Module.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/Value.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Expression/ClangFunction.h" -#include "lldb/Core/Log.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[] = -{ - // 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 }, - {NULL} -}; - -bool -ObjCTrampolineHandler::ModuleIsObjCLibrary (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; -} - -ObjCTrampolineHandler::ObjCTrampolineHandler (ProcessSP process_sp, ModuleSP objc_module) : - m_process_sp (process_sp), - m_objc_module_sp (objc_module), - m_impl_fn_addr (LLDB_INVALID_ADDRESS), - m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS) -{ - // Look up the known resolution functions: - - ConstString get_impl_name("class_getMethodImplementation"); - ConstString get_impl_stret_name("class_getMethodImplementation_stret"); - - Target *target = m_process_sp ? &m_process_sp->GetTarget() : NULL; - const Symbol *class_getMethodImplementation = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_name, eSymbolTypeCode); - const Symbol *class_getMethodImplementation_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_stret_name, eSymbolTypeCode); - - if (class_getMethodImplementation) - m_impl_fn_addr = class_getMethodImplementation->GetValue().GetLoadAddress(target); - if (class_getMethodImplementation_stret) - m_impl_stret_fn_addr = class_getMethodImplementation_stret->GetValue().GetLoadAddress(target); - - // FIXME: Do some kind of logging here. - if (m_impl_fn_addr == LLDB_INVALID_ADDRESS || m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS) - return; - - // Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol - // names dynamically to figure out how to dispatch to them. If it becomes more complicated than this we can - // turn the g_dispatch_functions char * array into a template table, and populate the DispatchFunction map - // from there. - - for (int i = 0; g_dispatch_functions[i].name != NULL; i++) - { - ConstString name_const_str(g_dispatch_functions[i].name); - const Symbol *msgSend_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (name_const_str, eSymbolTypeCode); - if (msgSend_symbol) - { - // FixMe: Make g_dispatch_functions static table of DisptachFunctions, and have the map be address->index. - // Problem is we also need to lookup the dispatch function. For now we could have a side table of stret & non-stret - // dispatch functions. If that's as complex as it gets, we're fine. - - lldb::addr_t sym_addr = msgSend_symbol->GetValue().GetLoadAddress(target); - - m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i)); - } - } -} - -ThreadPlanSP -ObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_others) -{ - ThreadPlanSP ret_plan_sp; - lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC(); - - MsgsendMap::iterator pos; - pos = m_msgSend_map.find (curr_pc); - if (pos != m_msgSend_map.end()) - { - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); - - const DispatchFunction *this_dispatch = &g_dispatch_functions[(*pos).second]; - - lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0); - - Process *process = thread.CalculateProcess(); - const ABI *abi = process->GetABI(); - if (abi == NULL) - return ret_plan_sp; - - Target *target = thread.CalculateTarget(); - - // FIXME: Since neither the value nor the Clang QualType know their ASTContext, - // we have to make sure the type we put in our value list comes from the same ASTContext - // the ABI will use to get the argument values. THis is the bottom-most frame's module. - - ClangASTContext *clang_ast_context = target->GetScratchClangASTContext(); - ValueList argument_values; - Value input_value; - void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); - input_value.SetValueType (Value::eValueTypeScalar); - input_value.SetContext (Value::eContextTypeOpaqueClangQualType, clang_void_ptr_type); - - int obj_index; - int sel_index; - - // If this is a struct return dispatch, then the first argument is the - // return struct pointer, and the object is the second, and the selector is the third. - // Otherwise the object is the first and the selector the second. - if (this_dispatch->stret_return) - { - obj_index = 1; - sel_index = 2; - argument_values.PushValue(input_value); - argument_values.PushValue(input_value); - argument_values.PushValue(input_value); - } - else - { - obj_index = 0; - sel_index = 1; - argument_values.PushValue(input_value); - argument_values.PushValue(input_value); - } - - - bool success = abi->GetArgumentValues (thread, argument_values); - if (!success) - return ret_plan_sp; - - // Okay, the first value here is the object, we actually want the class of that object. - // For now we're just going with the ISA. - // FIXME: This should really be the return value of [object class] to properly handle KVO interposition. - - Value isa_value(*(argument_values.GetValueAtIndex(obj_index))); - - // This is a little cheesy, but since object->isa is the first field, - // making the object value a load address value and resolving it will get - // the pointer sized data pointed to by that value... - ExecutionContext exec_ctx; - thread.Calculate (exec_ctx); - - isa_value.SetValueType(Value::eValueTypeLoadAddress); - isa_value.ResolveValue(&exec_ctx, clang_ast_context->getASTContext()); - - if (this_dispatch->fixedup == DispatchFunction::eFixUpFixed) - { - // For the FixedUp method the Selector is actually a pointer to a - // structure, the second field of which is the selector number. - Value *sel_value = argument_values.GetValueAtIndex(sel_index); - sel_value->GetScalar() += process->GetAddressByteSize(); - sel_value->SetValueType(Value::eValueTypeLoadAddress); - sel_value->ResolveValue(&exec_ctx, clang_ast_context->getASTContext()); - } - else if (this_dispatch->fixedup == DispatchFunction::eFixUpToFix) - { - // FIXME: If the method dispatch is not "fixed up" then the selector is actually a - // pointer to the string name of the selector. We need to look that up... - // For now I'm going to punt on that and just return no plan. - if (log) - log->Printf ("Punting on stepping into un-fixed-up method dispatch."); - return ret_plan_sp; - } - - // FIXME: If this is a dispatch to the super-class, we need to get the super-class from - // the class, and disaptch to that instead. - // But for now I just punt and return no plan. - if (this_dispatch->is_super) - { - if (log) - log->Printf ("Punting on stepping into super method dispatch."); - return ret_plan_sp; - } - - ValueList dispatch_values; - dispatch_values.PushValue (isa_value); - dispatch_values.PushValue(*(argument_values.GetValueAtIndex(sel_index))); - - if (log) - { - log->Printf("Resolving method call for class - 0x%llx and selector - 0x%llx", - dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), - dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong()); - } - - lldb::addr_t impl_addr = LookupInCache (dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), - dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong()); - - if (impl_addr == LLDB_INVALID_ADDRESS) - { - - Address resolve_address(NULL, this_dispatch->stret_return ? m_impl_stret_fn_addr : m_impl_fn_addr); - - StreamString errors; - { - // Scope for mutex locker: - Mutex::Locker locker(m_impl_function_mutex); - if (!m_impl_function.get()) - { - m_impl_function.reset(new ClangFunction(process->GetTargetTriple().GetCString(), - clang_ast_context, - clang_void_ptr_type, - resolve_address, - dispatch_values)); - - unsigned num_errors = m_impl_function->CompileFunction(errors); - if (num_errors) - { - if (log) - log->Printf ("Error compiling function: \"%s\".", errors.GetData()); - return ret_plan_sp; - } - - errors.Clear(); - if (!m_impl_function->WriteFunctionWrapper(exec_ctx, errors)) - { - if (log) - log->Printf ("Error Inserting function: \"%s\".", errors.GetData()); - return ret_plan_sp; - } - } - - } - - errors.Clear(); - - // Now write down the argument values for this call. - lldb::addr_t args_addr = LLDB_INVALID_ADDRESS; - 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, - argument_values.GetValueAtIndex(0)->GetScalar().ULongLong(), - dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), - dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong(), - stop_others)); - } - else - { - if (log) - log->Printf ("Found implementation address in cache: 0x%llx", impl_addr); - - ret_plan_sp.reset (new ThreadPlanRunToAddress (thread, impl_addr, stop_others)); - } - } - - 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 () -{ - return m_impl_function.get(); -} 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/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.cpp deleted file mode 100644 index 7b4aa4e87cf..00000000000 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.cpp +++ /dev/null @@ -1,151 +0,0 @@ -//===-- ThreadPlanStepThroughObjCTrampoline.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 "ThreadPlanStepThroughObjCTrampoline.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/ThreadPlanRunToAddress.h" -#include "lldb/Core/Log.h" - -using namespace lldb_private; - -//---------------------------------------------------------------------- -// ThreadPlanStepThroughObjCTrampoline constructor -//---------------------------------------------------------------------- -ThreadPlanStepThroughObjCTrampoline::ThreadPlanStepThroughObjCTrampoline( - Thread &thread, - ObjCTrampolineHandler *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), - 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) -{ - -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -ThreadPlanStepThroughObjCTrampoline::~ThreadPlanStepThroughObjCTrampoline() -{ -} - -void -ThreadPlanStepThroughObjCTrampoline::DidPush () -{ - StreamString errors; - ExecutionContext exc_context; - m_thread.Calculate(exc_context); - m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_context, m_args_addr, errors, m_stop_others)); - m_func_sp->SetPrivate(true); - m_thread.QueueThreadPlan (m_func_sp, false); -} - -void -ThreadPlanStepThroughObjCTrampoline::GetDescription (Stream *s, - lldb::DescriptionLevel level) -{ - if (level == lldb::eDescriptionLevelBrief) - s->Printf("Step through ObjC trampoline"); - else - { - s->Printf ("Stepping to implementation of ObjC method - obj: 0x%llx class: 0x%llx selector: 0x%llx", - m_object_ptr, m_class_ptr, m_sel_ptr); - } -} - -bool -ThreadPlanStepThroughObjCTrampoline::ValidatePlan (Stream *error) -{ - return true; -} - -bool -ThreadPlanStepThroughObjCTrampoline::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. - return false; -} - -lldb::StateType -ThreadPlanStepThroughObjCTrampoline::RunState () -{ - return eStateRunning; -} - -bool -ThreadPlanStepThroughObjCTrampoline::ShouldStop (Event *event_ptr) -{ - if (m_func_sp.get() == NULL || m_thread.IsThreadPlanDone(m_func_sp.get())) - { - m_func_sp.reset(); - if (!m_run_to_sp) - { - Value target_addr_value; - ExecutionContext exc_context; - m_thread.Calculate(exc_context); - m_impl_function->FetchFunctionResults (exc_context, m_args_addr, target_addr_value); - m_impl_function->DeallocateFunctionResults(exc_context, m_args_addr); - lldb::addr_t target_addr = target_addr_value.GetScalar().ULongLong(); - Address target_address(NULL, target_addr); - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); - 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); - - // Extract the target address from the value: - - m_run_to_sp.reset(new ThreadPlanRunToAddress(m_thread, target_address, m_stop_others)); - m_thread.QueueThreadPlan(m_run_to_sp, false); - m_run_to_sp->SetPrivate(true); - return false; - } - else if (m_thread.IsThreadPlanDone(m_run_to_sp.get())) - { - SetPlanComplete(); - return true; - } - } - return false; -} - -// The base class MischiefManaged does some cleanup - so you have to call it -// in your MischiefManaged derived class. -bool -ThreadPlanStepThroughObjCTrampoline::MischiefManaged () -{ - if (IsPlanComplete()) - return true; - else - return false; -} - -bool -ThreadPlanStepThroughObjCTrampoline::WillStop() -{ - return true; -} diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.h deleted file mode 100644 index f30c333df6b..00000000000 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/ThreadPlanStepThroughObjCTrampoline.h +++ /dev/null @@ -1,95 +0,0 @@ -//===-- ThreadPlanStepThroughObjCTrampoline.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_ThreadPlanStepThroughObjCTrampoline_h_ -#define lldb_ThreadPlanStepThroughObjCTrampoline_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-types.h" -#include "lldb/lldb-enumerations.h" -#include "lldb/Target/ThreadPlan.h" -#include "ObjCTrampolineHandler.h" - -namespace lldb_private -{ - -class ThreadPlanStepThroughObjCTrampoline : public ThreadPlan -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ThreadPlanStepThroughObjCTrampoline(Thread &thread, - ObjCTrampolineHandler *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 void - GetDescription (Stream *s, - lldb::DescriptionLevel level); - - virtual bool - ValidatePlan (Stream *error); - - virtual bool - PlanExplainsStop (); - - - virtual lldb::StateType - RunState (); - - virtual bool - ShouldStop (Event *event_ptr); - - // The base class MischiefManaged does some cleanup - so you have to call it - // in your MischiefManaged derived class. - virtual bool - MischiefManaged (); - - virtual void - DidPush(); - - virtual bool - WillStop(); - - - -protected: - //------------------------------------------------------------------ - // Classes that inherit from ThreadPlanStepThroughObjCTrampoline can see and modify these - //------------------------------------------------------------------ - -private: - //------------------------------------------------------------------ - // For ThreadPlanStepThroughObjCTrampoline only - //------------------------------------------------------------------ - 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; - 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_ |

