Home | History | Annotate | Download | only in AppleObjCRuntime
      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
     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         {
     87             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:
     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 
    112             lldb::addr_t GetNextRegionAddr ()
    113             {
    114                 return m_next_region;
    115             }
    116 
    117             lldb::addr_t
    118             GetCodeStart ()
    119             {
    120                 return m_code_start_addr;
    121             }
    122 
    123             lldb::addr_t
    124             GetCodeEnd ()
    125             {
    126                 return m_code_end_addr;
    127             }
    128 
    129             uint32_t
    130             GetFlagsForVTableAtAddress (lldb::addr_t address)
    131             {
    132                 return 0;
    133             }
    134 
    135             bool
    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 
    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