AppleObjCTrampolineHandler.h revision 341825
1//===-- AppleObjCTrampolineHandler.h ----------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef lldb_AppleObjCTrampolineHandler_h_ 11#define lldb_AppleObjCTrampolineHandler_h_ 12 13// C Includes 14// C++ Includes 15#include <map> 16#include <mutex> 17#include <vector> 18 19// Other libraries and framework includes 20// Project includes 21#include "lldb/Expression/UtilityFunction.h" 22#include "lldb/lldb-public.h" 23 24namespace lldb_private { 25 26class AppleObjCTrampolineHandler { 27public: 28 AppleObjCTrampolineHandler(const lldb::ProcessSP &process_sp, 29 const lldb::ModuleSP &objc_module_sp); 30 31 ~AppleObjCTrampolineHandler(); 32 33 lldb::ThreadPlanSP GetStepThroughDispatchPlan(Thread &thread, 34 bool stop_others); 35 36 FunctionCaller *GetLookupImplementationFunctionCaller(); 37 38 bool AddrIsMsgForward(lldb::addr_t addr) const { 39 return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr); 40 } 41 42 struct DispatchFunction { 43 public: 44 typedef enum { eFixUpNone, eFixUpFixed, eFixUpToFix } FixUpState; 45 46 const char *name; 47 bool stret_return; 48 bool is_super; 49 bool is_super2; 50 FixUpState fixedup; 51 }; 52 53 lldb::addr_t SetupDispatchFunction(Thread &thread, 54 ValueList &dispatch_values); 55 56private: 57 static const char *g_lookup_implementation_function_name; 58 static const char *g_lookup_implementation_with_stret_function_code; 59 static const char *g_lookup_implementation_no_stret_function_code; 60 61 class AppleObjCVTables { 62 public: 63 // These come from objc-gdb.h. 64 enum VTableFlags { 65 eOBJC_TRAMPOLINE_MESSAGE = (1 << 0), // trampoline acts like objc_msgSend 66 eOBJC_TRAMPOLINE_STRET = (1 << 1), // trampoline is struct-returning 67 eOBJC_TRAMPOLINE_VTABLE = (1 << 2) // trampoline is vtable dispatcher 68 }; 69 70 private: 71 struct VTableDescriptor { 72 VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start) 73 : flags(in_flags), code_start(in_code_start) {} 74 75 uint32_t flags; 76 lldb::addr_t code_start; 77 }; 78 79 class VTableRegion { 80 public: 81 VTableRegion() 82 : m_valid(false), m_owner(NULL), m_header_addr(LLDB_INVALID_ADDRESS), 83 m_code_start_addr(0), m_code_end_addr(0), m_next_region(0) {} 84 85 VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr); 86 87 void SetUpRegion(); 88 89 lldb::addr_t GetNextRegionAddr() { return m_next_region; } 90 91 lldb::addr_t GetCodeStart() { return m_code_start_addr; } 92 93 lldb::addr_t GetCodeEnd() { return m_code_end_addr; } 94 95 uint32_t GetFlagsForVTableAtAddress(lldb::addr_t address) { return 0; } 96 97 bool IsValid() { return m_valid; } 98 99 bool AddressInRegion(lldb::addr_t addr, uint32_t &flags); 100 101 void Dump(Stream &s); 102 103 public: 104 bool m_valid; 105 AppleObjCVTables *m_owner; 106 lldb::addr_t m_header_addr; 107 lldb::addr_t m_code_start_addr; 108 lldb::addr_t m_code_end_addr; 109 std::vector<VTableDescriptor> m_descriptors; 110 lldb::addr_t m_next_region; 111 }; 112 113 public: 114 AppleObjCVTables(const lldb::ProcessSP &process_sp, 115 const lldb::ModuleSP &objc_module_sp); 116 117 ~AppleObjCVTables(); 118 119 bool InitializeVTableSymbols(); 120 121 static bool RefreshTrampolines(void *baton, 122 StoppointCallbackContext *context, 123 lldb::user_id_t break_id, 124 lldb::user_id_t break_loc_id); 125 bool ReadRegions(); 126 127 bool ReadRegions(lldb::addr_t region_addr); 128 129 bool IsAddressInVTables(lldb::addr_t addr, uint32_t &flags); 130 131 lldb::ProcessSP GetProcessSP() { return m_process_wp.lock(); } 132 133 private: 134 lldb::ProcessWP m_process_wp; 135 typedef std::vector<VTableRegion> region_collection; 136 lldb::addr_t m_trampoline_header; 137 lldb::break_id_t m_trampolines_changed_bp_id; 138 region_collection m_regions; 139 lldb::ModuleSP m_objc_module_sp; 140 }; 141 142 static const DispatchFunction g_dispatch_functions[]; 143 144 typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch 145 // fn address to the index in 146 // g_dispatch_functions 147 MsgsendMap m_msgSend_map; 148 lldb::ProcessWP m_process_wp; 149 lldb::ModuleSP m_objc_module_sp; 150 const char *m_lookup_implementation_function_code; 151 std::unique_ptr<UtilityFunction> m_impl_code; 152 std::mutex m_impl_function_mutex; 153 lldb::addr_t m_impl_fn_addr; 154 lldb::addr_t m_impl_stret_fn_addr; 155 lldb::addr_t m_msg_forward_addr; 156 lldb::addr_t m_msg_forward_stret_addr; 157 std::unique_ptr<AppleObjCVTables> m_vtables_ap; 158}; 159 160} // namespace lldb_private 161 162#endif // lldb_AppleObjCTrampolineHandler_h_ 163