diff options
Diffstat (limited to 'source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h')
-rw-r--r-- | source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h new file mode 100644 index 000000000000..42d3461ddfa5 --- /dev/null +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h @@ -0,0 +1,209 @@ +//===-- 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 <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-public.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Expression/UtilityFunction.h" + +namespace lldb_private +{ + +class AppleObjCTrampolineHandler { +public: + AppleObjCTrampolineHandler (const lldb::ProcessSP &process_sp, + const lldb::ModuleSP &objc_module_sp); + + ~AppleObjCTrampolineHandler(); + + lldb::ThreadPlanSP + GetStepThroughDispatchPlan (Thread &thread, + bool stop_others); + + FunctionCaller * + GetLookupImplementationFunctionCaller (); + + bool + AddrIsMsgForward (lldb::addr_t addr) const + { + return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr); + } + + struct DispatchFunction { + public: + typedef enum + { + eFixUpNone, + eFixUpFixed, + eFixUpToFix + } FixUpState; + + const char *name; + bool stret_return; + bool is_super; + bool is_super2; + FixUpState fixedup; + }; + + lldb::addr_t + SetupDispatchFunction (Thread &thread, ValueList &dispatch_values); + +private: + static const char *g_lookup_implementation_function_name; + static const char *g_lookup_implementation_function_code; + static const char *g_lookup_implementation_with_stret_function_code; + static const char *g_lookup_implementation_no_stret_function_code; + + class AppleObjCVTables + { + public: + // These come from objc-gdb.h. + enum VTableFlags + { + eOBJC_TRAMPOLINE_MESSAGE = (1<<0), // trampoline acts like objc_msgSend + eOBJC_TRAMPOLINE_STRET = (1<<1), // trampoline is struct-returning + eOBJC_TRAMPOLINE_VTABLE = (1<<2) // trampoline is vtable dispatcher + }; + + private: + struct VTableDescriptor + { + VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start) : + flags(in_flags), + code_start(in_code_start) {} + + uint32_t flags; + lldb::addr_t code_start; + }; + + class VTableRegion + { + public: + VTableRegion() : + m_valid (false), + m_owner (NULL), + m_header_addr (LLDB_INVALID_ADDRESS), + m_code_start_addr(0), + m_code_end_addr (0), + m_next_region (0) + {} + + VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr); + + void SetUpRegion(); + + lldb::addr_t GetNextRegionAddr () + { + return m_next_region; + } + + lldb::addr_t + GetCodeStart () + { + return m_code_start_addr; + } + + lldb::addr_t + GetCodeEnd () + { + return m_code_end_addr; + } + + uint32_t + GetFlagsForVTableAtAddress (lldb::addr_t address) + { + return 0; + } + + bool + IsValid () + { + return m_valid; + } + + bool + AddressInRegion (lldb::addr_t addr, uint32_t &flags); + + void + Dump (Stream &s); + + public: + bool m_valid; + AppleObjCVTables *m_owner; + lldb::addr_t m_header_addr; + lldb::addr_t m_code_start_addr; + lldb::addr_t m_code_end_addr; + std::vector<VTableDescriptor> m_descriptors; + lldb::addr_t m_next_region; + }; + + public: + AppleObjCVTables(const lldb::ProcessSP &process_sp, + const lldb::ModuleSP &objc_module_sp); + + ~AppleObjCVTables(); + + bool + InitializeVTableSymbols (); + + static bool RefreshTrampolines (void *baton, + StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + bool + ReadRegions (); + + bool + ReadRegions (lldb::addr_t region_addr); + + bool + IsAddressInVTables (lldb::addr_t addr, uint32_t &flags); + + lldb::ProcessSP + GetProcessSP () + { + return m_process_wp.lock(); + } + + private: + lldb::ProcessWP m_process_wp; + typedef std::vector<VTableRegion> region_collection; + lldb::addr_t m_trampoline_header; + lldb::break_id_t m_trampolines_changed_bp_id; + region_collection m_regions; + lldb::ModuleSP m_objc_module_sp; + }; + + 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; + lldb::ProcessWP m_process_wp; + lldb::ModuleSP m_objc_module_sp; + std::unique_ptr<UtilityFunction> m_impl_code; + Mutex m_impl_function_mutex; + lldb::addr_t m_impl_fn_addr; + lldb::addr_t m_impl_stret_fn_addr; + lldb::addr_t m_msg_forward_addr; + lldb::addr_t m_msg_forward_stret_addr; + std::unique_ptr<AppleObjCVTables> m_vtables_ap; +}; + +} // namespace lldb_private + +#endif // lldb_AppleObjCTrampolineHandler_h_ |