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