AppleObjCTrampolineHandler.h revision 355940
1//===-- AppleObjCTrampolineHandler.h ----------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#ifndef lldb_AppleObjCTrampolineHandler_h_ 10#define lldb_AppleObjCTrampolineHandler_h_ 11 12#include <map> 13#include <mutex> 14#include <vector> 15 16#include "lldb/Expression/UtilityFunction.h" 17#include "lldb/lldb-public.h" 18 19namespace lldb_private { 20 21class AppleObjCTrampolineHandler { 22public: 23 AppleObjCTrampolineHandler(const lldb::ProcessSP &process_sp, 24 const lldb::ModuleSP &objc_module_sp); 25 26 ~AppleObjCTrampolineHandler(); 27 28 lldb::ThreadPlanSP GetStepThroughDispatchPlan(Thread &thread, 29 bool stop_others); 30 31 FunctionCaller *GetLookupImplementationFunctionCaller(); 32 33 bool AddrIsMsgForward(lldb::addr_t addr) const { 34 return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr); 35 } 36 37 struct DispatchFunction { 38 public: 39 enum FixUpState { eFixUpNone, eFixUpFixed, eFixUpToFix }; 40 41 const char *name; 42 bool stret_return; 43 bool is_super; 44 bool is_super2; 45 FixUpState fixedup; 46 }; 47 48 lldb::addr_t SetupDispatchFunction(Thread &thread, 49 ValueList &dispatch_values); 50 51private: 52 static const char *g_lookup_implementation_function_name; 53 static const char *g_lookup_implementation_with_stret_function_code; 54 static const char *g_lookup_implementation_no_stret_function_code; 55 56 class AppleObjCVTables { 57 public: 58 // These come from objc-gdb.h. 59 enum VTableFlags { 60 eOBJC_TRAMPOLINE_MESSAGE = (1 << 0), // trampoline acts like objc_msgSend 61 eOBJC_TRAMPOLINE_STRET = (1 << 1), // trampoline is struct-returning 62 eOBJC_TRAMPOLINE_VTABLE = (1 << 2) // trampoline is vtable dispatcher 63 }; 64 65 private: 66 struct VTableDescriptor { 67 VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start) 68 : flags(in_flags), code_start(in_code_start) {} 69 70 uint32_t flags; 71 lldb::addr_t code_start; 72 }; 73 74 class VTableRegion { 75 public: 76 VTableRegion() 77 : m_valid(false), m_owner(nullptr), 78 m_header_addr(LLDB_INVALID_ADDRESS), m_code_start_addr(0), 79 m_code_end_addr(0), m_next_region(0) {} 80 81 VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr); 82 83 void SetUpRegion(); 84 85 lldb::addr_t GetNextRegionAddr() { return m_next_region; } 86 87 lldb::addr_t GetCodeStart() { return m_code_start_addr; } 88 89 lldb::addr_t GetCodeEnd() { return m_code_end_addr; } 90 91 uint32_t GetFlagsForVTableAtAddress(lldb::addr_t address) { return 0; } 92 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 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_up; 154}; 155 156} // namespace lldb_private 157 158#endif // lldb_AppleObjCTrampolineHandler_h_ 159