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 <vector> 17 // Other libraries and framework includes 18 // Project includes 19 #include "lldb/lldb-public.h" 20 #include "lldb/Host/Mutex.h" 21 22 23 namespace lldb_private 24 { 25 26 class AppleObjCTrampolineHandler { 27 public: 28 29 AppleObjCTrampolineHandler (const lldb::ProcessSP &process_sp, 30 const lldb::ModuleSP &objc_module_sp); 31 32 ~AppleObjCTrampolineHandler(); 33 34 lldb::ThreadPlanSP 35 GetStepThroughDispatchPlan (Thread &thread, 36 bool stop_others); 37 38 ClangFunction * 39 GetLookupImplementationWrapperFunction (); 40 41 bool AddrIsMsgForward(lldb::addr_t addr)42 AddrIsMsgForward (lldb::addr_t addr) const 43 { 44 return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr); 45 } 46 47 48 struct DispatchFunction { 49 public: 50 typedef enum 51 { 52 eFixUpNone, 53 eFixUpFixed, 54 eFixUpToFix 55 } FixUpState; 56 57 const char *name; 58 bool stret_return; 59 bool is_super; 60 bool is_super2; 61 FixUpState fixedup; 62 }; 63 64 lldb::addr_t 65 SetupDispatchFunction (Thread &thread, ValueList &dispatch_values); 66 67 private: 68 static const char *g_lookup_implementation_function_name; 69 static const char *g_lookup_implementation_function_code; 70 static const char *g_lookup_implementation_with_stret_function_code; 71 static const char *g_lookup_implementation_no_stret_function_code; 72 73 class AppleObjCVTables 74 { 75 public: 76 // These come from objc-gdb.h. 77 enum VTableFlags 78 { 79 eOBJC_TRAMPOLINE_MESSAGE = (1<<0), // trampoline acts like objc_msgSend 80 eOBJC_TRAMPOLINE_STRET = (1<<1), // trampoline is struct-returning 81 eOBJC_TRAMPOLINE_VTABLE = (1<<2) // trampoline is vtable dispatcher 82 }; 83 84 private: 85 struct VTableDescriptor 86 { VTableDescriptorVTableDescriptor87 VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start) : 88 flags(in_flags), 89 code_start(in_code_start) {} 90 91 uint32_t flags; 92 lldb::addr_t code_start; 93 }; 94 95 96 class VTableRegion 97 { 98 public: VTableRegion()99 VTableRegion() : 100 m_valid (false), 101 m_owner (NULL), 102 m_header_addr (LLDB_INVALID_ADDRESS), 103 m_code_start_addr(0), 104 m_code_end_addr (0), 105 m_next_region (0) 106 {} 107 108 VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr); 109 110 void SetUpRegion(); 111 GetNextRegionAddr()112 lldb::addr_t GetNextRegionAddr () 113 { 114 return m_next_region; 115 } 116 117 lldb::addr_t GetCodeStart()118 GetCodeStart () 119 { 120 return m_code_start_addr; 121 } 122 123 lldb::addr_t GetCodeEnd()124 GetCodeEnd () 125 { 126 return m_code_end_addr; 127 } 128 129 uint32_t GetFlagsForVTableAtAddress(lldb::addr_t address)130 GetFlagsForVTableAtAddress (lldb::addr_t address) 131 { 132 return 0; 133 } 134 135 bool IsValid()136 IsValid () 137 { 138 return m_valid; 139 } 140 141 bool 142 AddressInRegion (lldb::addr_t addr, uint32_t &flags); 143 144 void 145 Dump (Stream &s); 146 147 public: 148 bool m_valid; 149 AppleObjCVTables *m_owner; 150 lldb::addr_t m_header_addr; 151 lldb::addr_t m_code_start_addr; 152 lldb::addr_t m_code_end_addr; 153 std::vector<VTableDescriptor> m_descriptors; 154 lldb::addr_t m_next_region; 155 }; 156 157 public: 158 AppleObjCVTables(const lldb::ProcessSP &process_sp, 159 const lldb::ModuleSP &objc_module_sp); 160 161 ~AppleObjCVTables(); 162 163 bool 164 InitializeVTableSymbols (); 165 166 static bool RefreshTrampolines (void *baton, 167 StoppointCallbackContext *context, 168 lldb::user_id_t break_id, 169 lldb::user_id_t break_loc_id); 170 bool 171 ReadRegions (); 172 173 bool 174 ReadRegions (lldb::addr_t region_addr); 175 176 bool 177 IsAddressInVTables (lldb::addr_t addr, uint32_t &flags); 178 GetProcess()179 Process *GetProcess () 180 { 181 return m_process_sp.get(); 182 } 183 184 private: 185 lldb::ProcessSP m_process_sp; 186 typedef std::vector<VTableRegion> region_collection; 187 lldb::addr_t m_trampoline_header; 188 lldb::break_id_t m_trampolines_changed_bp_id; 189 region_collection m_regions; 190 lldb::ModuleSP m_objc_module_sp; 191 192 }; 193 194 static const DispatchFunction g_dispatch_functions[]; 195 196 typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch fn address to the index in g_dispatch_functions 197 MsgsendMap m_msgSend_map; 198 lldb::ProcessSP m_process_sp; 199 lldb::ModuleSP m_objc_module_sp; 200 std::unique_ptr<ClangFunction> m_impl_function; 201 std::unique_ptr<ClangUtilityFunction> m_impl_code; 202 Mutex m_impl_function_mutex; 203 lldb::addr_t m_impl_fn_addr; 204 lldb::addr_t m_impl_stret_fn_addr; 205 lldb::addr_t m_msg_forward_addr; 206 lldb::addr_t m_msg_forward_stret_addr; 207 std::unique_ptr<AppleObjCVTables> m_vtables_ap; 208 209 210 }; 211 212 } // using namespace lldb_private 213 214 #endif // lldb_AppleObjCTrampolineHandler_h_ 215