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