//===-- AppleObjCTrampolineHandler.h ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef lldb_AppleObjCTrampolineHandler_h_
#define lldb_AppleObjCTrampolineHandler_h_
// C Includes
// C++ Includes
#include <map>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Host/Mutex.h"
namespace lldb_private
{
class AppleObjCTrampolineHandler {
public:
AppleObjCTrampolineHandler (const lldb::ProcessSP &process_sp,
const lldb::ModuleSP &objc_module_sp);
~AppleObjCTrampolineHandler();
lldb::ThreadPlanSP
GetStepThroughDispatchPlan (Thread &thread,
bool stop_others);
ClangFunction *
GetLookupImplementationWrapperFunction ();
bool
AddrIsMsgForward (lldb::addr_t addr) const
{
return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr);
}
struct DispatchFunction {
public:
typedef enum
{
eFixUpNone,
eFixUpFixed,
eFixUpToFix
} FixUpState;
const char *name;
bool stret_return;
bool is_super;
bool is_super2;
FixUpState fixedup;
};
lldb::addr_t
SetupDispatchFunction (Thread &thread, ValueList &dispatch_values);
private:
static const char *g_lookup_implementation_function_name;
static const char *g_lookup_implementation_function_code;
static const char *g_lookup_implementation_with_stret_function_code;
static const char *g_lookup_implementation_no_stret_function_code;
class AppleObjCVTables
{
public:
// These come from objc-gdb.h.
enum VTableFlags
{
eOBJC_TRAMPOLINE_MESSAGE = (1<<0), // trampoline acts like objc_msgSend
eOBJC_TRAMPOLINE_STRET = (1<<1), // trampoline is struct-returning
eOBJC_TRAMPOLINE_VTABLE = (1<<2) // trampoline is vtable dispatcher
};
private:
struct VTableDescriptor
{
VTableDescriptor(uint32_t in_flags, lldb::addr_t in_code_start) :
flags(in_flags),
code_start(in_code_start) {}
uint32_t flags;
lldb::addr_t code_start;
};
class VTableRegion
{
public:
VTableRegion() :
m_valid (false),
m_owner (NULL),
m_header_addr (LLDB_INVALID_ADDRESS),
m_code_start_addr(0),
m_code_end_addr (0),
m_next_region (0)
{}
VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);
void SetUpRegion();
lldb::addr_t GetNextRegionAddr ()
{
return m_next_region;
}
lldb::addr_t
GetCodeStart ()
{
return m_code_start_addr;
}
lldb::addr_t
GetCodeEnd ()
{
return m_code_end_addr;
}
uint32_t
GetFlagsForVTableAtAddress (lldb::addr_t address)
{
return 0;
}
bool
IsValid ()
{
return m_valid;
}
bool
AddressInRegion (lldb::addr_t addr, uint32_t &flags);
void
Dump (Stream &s);
public:
bool m_valid;
AppleObjCVTables *m_owner;
lldb::addr_t m_header_addr;
lldb::addr_t m_code_start_addr;
lldb::addr_t m_code_end_addr;
std::vector<VTableDescriptor> m_descriptors;
lldb::addr_t m_next_region;
};
public:
AppleObjCVTables(const lldb::ProcessSP &process_sp,
const lldb::ModuleSP &objc_module_sp);
~AppleObjCVTables();
bool
InitializeVTableSymbols ();
static bool RefreshTrampolines (void *baton,
StoppointCallbackContext *context,
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
bool
ReadRegions ();
bool
ReadRegions (lldb::addr_t region_addr);
bool
IsAddressInVTables (lldb::addr_t addr, uint32_t &flags);
Process *GetProcess ()
{
return m_process_sp.get();
}
private:
lldb::ProcessSP m_process_sp;
typedef std::vector<VTableRegion> region_collection;
lldb::addr_t m_trampoline_header;
lldb::break_id_t m_trampolines_changed_bp_id;
region_collection m_regions;
lldb::ModuleSP m_objc_module_sp;
};
static const DispatchFunction g_dispatch_functions[];
typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch fn address to the index in g_dispatch_functions
MsgsendMap m_msgSend_map;
lldb::ProcessSP m_process_sp;
lldb::ModuleSP m_objc_module_sp;
std::unique_ptr<ClangFunction> m_impl_function;
std::unique_ptr<ClangUtilityFunction> m_impl_code;
Mutex m_impl_function_mutex;
lldb::addr_t m_impl_fn_addr;
lldb::addr_t m_impl_stret_fn_addr;
lldb::addr_t m_msg_forward_addr;
lldb::addr_t m_msg_forward_stret_addr;
std::unique_ptr<AppleObjCVTables> m_vtables_ap;
};
} // using namespace lldb_private
#endif // lldb_AppleObjCTrampolineHandler_h_