AppleObjCTrampolineHandler.h revision 296417
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
18// Other libraries and framework includes
19// Project includes
20#include "lldb/lldb-public.h"
21#include "lldb/Host/Mutex.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_function_code;
69    static const char *g_lookup_implementation_with_stret_function_code;
70    static const char *g_lookup_implementation_no_stret_function_code;
71
72    class AppleObjCVTables
73    {
74    public:
75        // These come from objc-gdb.h.
76        enum VTableFlags
77        {
78             eOBJC_TRAMPOLINE_MESSAGE = (1<<0),   // trampoline acts like objc_msgSend
79             eOBJC_TRAMPOLINE_STRET   = (1<<1),   // trampoline is struct-returning
80             eOBJC_TRAMPOLINE_VTABLE  = (1<<2)    // trampoline is vtable dispatcher
81        };
82
83    private:
84        struct VTableDescriptor
85        {
86            VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start) :
87                flags(in_flags),
88                code_start(in_code_start) {}
89
90            uint32_t flags;
91            lldb::addr_t code_start;
92        };
93
94        class VTableRegion
95        {
96        public:
97            VTableRegion() :
98                    m_valid (false),
99                    m_owner (NULL),
100                    m_header_addr (LLDB_INVALID_ADDRESS),
101                    m_code_start_addr(0),
102                    m_code_end_addr (0),
103                    m_next_region (0)
104            {}
105
106            VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);
107
108            void SetUpRegion();
109
110            lldb::addr_t GetNextRegionAddr ()
111            {
112                return m_next_region;
113            }
114
115            lldb::addr_t
116            GetCodeStart ()
117            {
118                return m_code_start_addr;
119            }
120
121            lldb::addr_t
122            GetCodeEnd ()
123            {
124                return m_code_end_addr;
125            }
126
127            uint32_t
128            GetFlagsForVTableAtAddress (lldb::addr_t address)
129            {
130                return 0;
131            }
132
133            bool
134            IsValid ()
135            {
136                return m_valid;
137            }
138
139            bool
140            AddressInRegion (lldb::addr_t addr, uint32_t &flags);
141
142            void
143            Dump (Stream &s);
144
145        public:
146            bool m_valid;
147            AppleObjCVTables *m_owner;
148            lldb::addr_t m_header_addr;
149            lldb::addr_t m_code_start_addr;
150            lldb::addr_t m_code_end_addr;
151            std::vector<VTableDescriptor> m_descriptors;
152            lldb::addr_t m_next_region;
153        };
154
155    public:
156        AppleObjCVTables(const lldb::ProcessSP &process_sp,
157                         const lldb::ModuleSP &objc_module_sp);
158
159        ~AppleObjCVTables();
160
161        bool
162        InitializeVTableSymbols ();
163
164        static bool RefreshTrampolines (void *baton,
165                                        StoppointCallbackContext *context,
166                                        lldb::user_id_t break_id,
167                                        lldb::user_id_t break_loc_id);
168        bool
169        ReadRegions ();
170
171        bool
172        ReadRegions (lldb::addr_t region_addr);
173
174        bool
175        IsAddressInVTables (lldb::addr_t addr, uint32_t &flags);
176
177        lldb::ProcessSP
178        GetProcessSP ()
179        {
180            return m_process_wp.lock();
181        }
182
183    private:
184        lldb::ProcessWP m_process_wp;
185        typedef std::vector<VTableRegion> region_collection;
186        lldb::addr_t m_trampoline_header;
187        lldb::break_id_t m_trampolines_changed_bp_id;
188        region_collection m_regions;
189        lldb::ModuleSP m_objc_module_sp;
190    };
191
192    static const DispatchFunction g_dispatch_functions[];
193
194    typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch fn address to the index in g_dispatch_functions
195    MsgsendMap m_msgSend_map;
196    lldb::ProcessWP m_process_wp;
197    lldb::ModuleSP m_objc_module_sp;
198    std::unique_ptr<UtilityFunction> m_impl_code;
199    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