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