1 //===-- AppleObjCTrampolineHandler.h ----------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H
10 #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H
16 #include "lldb/Expression/UtilityFunction.h"
17 #include "lldb/lldb-public.h"
19 namespace lldb_private {
21 class AppleObjCTrampolineHandler {
23 AppleObjCTrampolineHandler(const lldb::ProcessSP &process_sp,
24 const lldb::ModuleSP &objc_module_sp);
26 ~AppleObjCTrampolineHandler();
28 lldb::ThreadPlanSP GetStepThroughDispatchPlan(Thread &thread,
31 FunctionCaller *GetLookupImplementationFunctionCaller();
33 bool AddrIsMsgForward(lldb::addr_t addr) const {
34 return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr);
37 struct DispatchFunction {
39 enum FixUpState { eFixUpNone, eFixUpFixed, eFixUpToFix };
48 lldb::addr_t SetupDispatchFunction(Thread &thread,
49 ValueList &dispatch_values);
50 const DispatchFunction *FindDispatchFunction(lldb::addr_t addr);
51 void ForEachDispatchFunction(std::function<void(lldb::addr_t,
52 const DispatchFunction &)>);
55 static const char *g_lookup_implementation_function_name;
56 static const char *g_lookup_implementation_with_stret_function_code;
57 static const char *g_lookup_implementation_no_stret_function_code;
59 class AppleObjCVTables {
61 // These come from objc-gdb.h.
63 eOBJC_TRAMPOLINE_MESSAGE = (1 << 0), // trampoline acts like objc_msgSend
64 eOBJC_TRAMPOLINE_STRET = (1 << 1), // trampoline is struct-returning
65 eOBJC_TRAMPOLINE_VTABLE = (1 << 2) // trampoline is vtable dispatcher
69 struct VTableDescriptor {
70 VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start)
71 : flags(in_flags), code_start(in_code_start) {}
74 lldb::addr_t code_start;
80 : m_valid(false), m_owner(nullptr),
81 m_header_addr(LLDB_INVALID_ADDRESS), m_code_start_addr(0),
82 m_code_end_addr(0), m_next_region(0) {}
84 VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);
88 lldb::addr_t GetNextRegionAddr() { return m_next_region; }
90 lldb::addr_t GetCodeStart() { return m_code_start_addr; }
92 lldb::addr_t GetCodeEnd() { return m_code_end_addr; }
94 uint32_t GetFlagsForVTableAtAddress(lldb::addr_t address) { return 0; }
96 bool IsValid() { return m_valid; }
98 bool AddressInRegion(lldb::addr_t addr, uint32_t &flags);
100 void Dump(Stream &s);
103 AppleObjCVTables *m_owner;
104 lldb::addr_t m_header_addr;
105 lldb::addr_t m_code_start_addr;
106 lldb::addr_t m_code_end_addr;
107 std::vector<VTableDescriptor> m_descriptors;
108 lldb::addr_t m_next_region;
112 AppleObjCVTables(const lldb::ProcessSP &process_sp,
113 const lldb::ModuleSP &objc_module_sp);
117 bool InitializeVTableSymbols();
119 static bool RefreshTrampolines(void *baton,
120 StoppointCallbackContext *context,
121 lldb::user_id_t break_id,
122 lldb::user_id_t break_loc_id);
125 bool ReadRegions(lldb::addr_t region_addr);
127 bool IsAddressInVTables(lldb::addr_t addr, uint32_t &flags);
129 lldb::ProcessSP GetProcessSP() { return m_process_wp.lock(); }
132 lldb::ProcessWP m_process_wp;
133 typedef std::vector<VTableRegion> region_collection;
134 lldb::addr_t m_trampoline_header;
135 lldb::break_id_t m_trampolines_changed_bp_id;
136 region_collection m_regions;
137 lldb::ModuleSP m_objc_module_sp;
140 static const DispatchFunction g_dispatch_functions[];
141 static const char *g_opt_dispatch_names[];
143 using MsgsendMap = std::map<lldb::addr_t, int>; // This table maps an dispatch
144 // fn address to the index in
145 // g_dispatch_functions
146 MsgsendMap m_msgSend_map;
147 MsgsendMap m_opt_dispatch_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_up;
160 } // namespace lldb_private
162 #endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H