Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add userdata context variable API to PPP callbacks #1116

Merged
merged 5 commits into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ msg() {
}

# Default targets to build. Change with argument. small = i386-softmmu
TARGET_LIST="x86_64-softmmu,i386-softmmu,arm-softmmu,aarch64-softmmu,ppc-softmmu,mips-softmmu,mipsel-softmmu"
TARGET_LIST="x86_64-softmmu,i386-softmmu,arm-softmmu,aarch64-softmmu,ppc-softmmu,mips-softmmu,mipsel-softmmu,mips64-softmmu"
LLVM_CONFIG_BINARY="${LLVM_CONFIG_BINARY:-llvm-config-11}"

pypanda=""
Expand Down
8 changes: 8 additions & 0 deletions panda/Makefile.panda.target
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ else
llvmmorph-$(TARGET_MIPS) += llvm-helpers-mips.bc
endif

MIPS64_HELPERS = dsp_helper.bc2 helper.bc2 lmi_helper.bc2 msa_helper.bc2
MIPS64_HELPERS += op_helper.bc2
llvm-$(TARGET_MIPS64) += fpu/softfloat.bc2
llvm-$(TARGET_MIPS64) += $(addprefix target/mips/,$(MIPS64_HELPERS))

# only support mips64, not mipsel64
llvmmorph-$(TARGET_MIPS64) += llvm-helpers-mips64.bc

CLANG_FILTER = -Wold-style-declaration -fstack-protector-strong -Wno-error=cpp -g -O0 -O1 -O2 -O3 -mcx16 -Wno-shift-negative-value
QEMU_BC2FLAGS:=$(filter-out $(CLANG_FILTER),$(QEMU_CFLAGS) $(CFLAGS)) -O1 -I../target/$(TARGET_BASE_ARCH)
%.bc2: %.c $(GENERATED_FILES)
Expand Down
3 changes: 3 additions & 0 deletions panda/docs/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,9 @@ following.

2. Create a type for the callback function. Put this in the .h file for Plugin
A. If the callback's name is `foo`, then this type has to be called `foo_t`.
This type shold be generated using the `PPP_CB_TYPEDEF` macro in the form of
`PPP_CB_TYPEDEF(return_type, name, arguments...);`. For example
`PPP_CB_TYPEDEF(void, foo, CPUState *env, target_ptr_t pc);`.

3. Use the macro `PPP_RUN_CB` at the line chosen in 1. This macro takes all the
arguments you want the callback to get, so it will look like a function call.
Expand Down
154 changes: 123 additions & 31 deletions panda/include/panda/plugin_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,20 @@ extern "C" { \
void ppp_add_cb_##cb_name(cb_name##_t fptr) ; \
void ppp_add_cb_##cb_name##_slot(cb_name##_t fptr, int slot_num) ; \
bool ppp_remove_cb_##cb_name(cb_name##_t fptr) ; \
\
void ppp_add_cb_##cb_name##_with_context(cb_name##_with_context_t fptr, void* context) ; \
void ppp_add_cb_##cb_name##_slot_with_context(cb_name##_with_context_t fptr, int slot_num, void* context) ; \
bool ppp_remove_cb_##cb_name##_with_context(cb_name##_with_context_t fptr, void* context) ; \
}
#else
#define PPP_PROT_REG_CB(cb_name) \
void ppp_add_cb_##cb_name(cb_name##_t fptr) ; \
void ppp_add_cb_##cb_name##_slot(cb_name##_t fptr, int slot_num) ; \
bool ppp_remove_cb_##cb_name(cb_name##_t fptr) ;
bool ppp_remove_cb_##cb_name(cb_name##_t fptr) ;\
\
void ppp_add_cb_##cb_name##_with_context(cb_name##_with_context_t fptr, void* context) ; \
void ppp_add_cb_##cb_name##_slot_with_context(cb_name##_with_context_t fptr, int slot_num, void* context) ; \
bool ppp_remove_cb_##cb_name##_with_context(cb_name##_with_context_t fptr, void* context) ;
#endif

/*
Expand All @@ -67,39 +75,86 @@ bool ppp_remove_cb_##cb_name(cb_name##_t fptr) ;
as there isnt any attempt, here, to detect if you leave a slot empty
*/

#define PPP_CB_BOILERPLATE(cb_name) \
cb_name##_t ppp_##cb_name##_cb[PPP_MAX_CB]; \
int ppp_##cb_name##_num_cb = 0; \
\
void ppp_add_cb_##cb_name(cb_name##_t fptr) { \
assert (ppp_##cb_name##_num_cb < PPP_MAX_CB); \
ppp_##cb_name##_cb[ppp_##cb_name##_num_cb] = fptr; \
ppp_##cb_name##_num_cb += 1; \
} \
\
void ppp_add_cb_##cb_name##_slot(cb_name##_t fptr, int slot_num) { \
assert (slot_num < PPP_MAX_CB); \
ppp_##cb_name##_cb[slot_num] = fptr; \
ppp_##cb_name##_num_cb = MAX(slot_num, ppp_##cb_name##_num_cb); \
} \
bool ppp_remove_cb_##cb_name(cb_name##_t fptr) { \
int i = 0; \
bool found = false; \
for (; i<MIN(PPP_MAX_CB,ppp_##cb_name##_num_cb); i++){ \
if (!found && fptr == ppp_##cb_name##_cb[i]) { \
found = true; \
ppp_##cb_name##_num_cb--; \
} \
if (found && i < PPP_MAX_CB -2 ){ \
ppp_##cb_name##_cb[i] = ppp_##cb_name##_cb[i+1]; \
} \
} \
return found; \
#define PPP_CB_BOILERPLATE(cb_name) \
cb_name##_t ppp_##cb_name##_cb[PPP_MAX_CB]; \
int ppp_##cb_name##_num_cb = 0; \
\
void ppp_add_cb_##cb_name(cb_name##_t fptr) { \
assert (ppp_##cb_name##_num_cb < PPP_MAX_CB); \
ppp_##cb_name##_cb[ppp_##cb_name##_num_cb] = fptr; \
ppp_##cb_name##_num_cb += 1; \
} \
\
void ppp_add_cb_##cb_name##_slot(cb_name##_t fptr, int slot_num) { \
assert (slot_num < PPP_MAX_CB); \
ppp_##cb_name##_cb[slot_num] = fptr; \
ppp_##cb_name##_num_cb = MAX(slot_num, ppp_##cb_name##_num_cb); \
} \
bool ppp_remove_cb_##cb_name(cb_name##_t fptr) { \
int i = 0; \
bool found = false; \
for (; i<MIN(PPP_MAX_CB,ppp_##cb_name##_num_cb); i++){ \
if (!found && fptr == ppp_##cb_name##_cb[i]) { \
found = true; \
ppp_##cb_name##_num_cb--; \
} \
if (found && i < PPP_MAX_CB -2 ){ \
ppp_##cb_name##_cb[i] = ppp_##cb_name##_cb[i+1]; \
} \
} \
return found; \
} \
cb_name##_with_context_t ppp_##cb_name##_cb_with_context[PPP_MAX_CB]; \
void* ppp_##cb_name##_cb_context[PPP_MAX_CB]; \
int ppp_##cb_name##_num_cb_with_context = 0; \
\
void ppp_add_cb_##cb_name##_with_context( \
cb_name##_with_context_t fptr, \
void* context \
) { \
assert (ppp_##cb_name##_num_cb_with_context < PPP_MAX_CB); \
ppp_##cb_name##_cb_with_context[ppp_##cb_name##_num_cb_with_context] = fptr; \
ppp_##cb_name##_cb_context[ppp_##cb_name##_num_cb_with_context] = context; \
ppp_##cb_name##_num_cb_with_context += 1; \
} \
\
void ppp_add_cb_##cb_name##_slot_with_context( \
cb_name##_with_context_t fptr, int slot_num, void* context \
) { \
assert (slot_num < PPP_MAX_CB); \
ppp_##cb_name##_cb_with_context[slot_num] = fptr; \
ppp_##cb_name##_cb_context[slot_num] = context; \
ppp_##cb_name##_num_cb_with_context = MAX( \
slot_num, ppp_##cb_name##_num_cb_with_context \
); \
} \
bool ppp_remove_cb_##cb_name##_with_context( \
cb_name##_with_context_t fptr, void* context \
) { \
int i = 0; \
bool found = false; \
for (; i<MIN(PPP_MAX_CB,ppp_##cb_name##_num_cb_with_context); i++){ \
if ( \
!found && fptr == ppp_##cb_name##_cb_with_context[i] \
&& ppp_##cb_name##_cb_context[i] == context \
) { \
found = true; \
ppp_##cb_name##_num_cb_with_context--; \
} \
if (found && i < PPP_MAX_CB -2 ){ \
ppp_##cb_name##_cb_with_context[i] = ppp_##cb_name##_cb_with_context[i+1];\
ppp_##cb_name##_cb_context[i] = ppp_##cb_name##_cb_context[i+1]; \
} \
} \
return found; \
}

#define PPP_CB_EXTERN(cb_name) \
extern cb_name##_t ppp_##cb_name##_cb[PPP_MAX_CB]; \
extern int ppp_##cb_name##_num_cb;
extern int ppp_##cb_name##_num_cb;\
extern cb_name##_with_context_t ppp_##cb_name##_cb_with_context[PPP_MAX_CB]; \
extern void* ppp_##cb_name##_cb_context[PPP_MAX_CB]; \
extern int ppp_##cb_name##_num_cb_with_context;

/*
And employ this where you want the callback functions to be called
Expand All @@ -113,6 +168,14 @@ extern int ppp_##cb_name##_num_cb;
ppp_##cb_name##_cb[ppp_cb_ind]( __VA_ARGS__ ) ; \
} \
} \
for (ppp_cb_ind = 0; \
ppp_cb_ind < ppp_##cb_name##_num_cb_with_context; \
ppp_cb_ind++) { \
if (ppp_##cb_name##_cb_with_context[ppp_cb_ind] != NULL) { \
void* context = ppp_##cb_name##_cb_context[ppp_cb_ind]; \
ppp_##cb_name##_cb_with_context[ppp_cb_ind](context, __VA_ARGS__ ) ; \
} \
} \
}

// If any of the registered functions returns true, take the if body
Expand All @@ -128,7 +191,8 @@ extern int ppp_##cb_name##_num_cb;
} \
}; if (__ret)

#define PPP_CHECK_CB(cb_name) (ppp_##cb_name##_num_cb > 0)
#define PPP_CHECK_CB(cb_name) \
((ppp_##cb_name##_num_cb > 0) || (ppp_##cb_name##_num_cb_with_context > 0))

/****************************************************************
This stuff gets used in "plugin B", i.e., the plugin that wants
Expand All @@ -150,6 +214,20 @@ to add a callback to be run inside of plugin A.
add_cb (cb_func); \
}

#define PPP_REG_CB_WITH_CONTEXT(other_plugin, cb_name, cb_func, context) \
{ \
dlerror(); \
void *op = panda_get_plugin_by_name(other_plugin); \
if (!op) { \
printf("In trying to add plugin callback, couldn't load %s plugin\n", other_plugin); \
assert (op); \
} \
void (*add_cb)(cb_name##_with_context_t fptr, void* context) = \
(void (*)(cb_name##_with_context_t, void*)) \
dlsym(op, "ppp_add_cb_" #cb_name "_with_context"); \
assert (add_cb != 0); \
add_cb (cb_func, context); \
}


// Use to disable (delete) a ppp-callback
Expand All @@ -166,4 +244,18 @@ to add a callback to be run inside of plugin A.
rm_cb (cb_func); \
}

#define PPP_REMOVE_CB_WITH_CONTEXT(other_plugin, cb_name, cb_func, context) \
{ \
dlerror(); \
void *op = panda_get_plugin_by_name(other_plugin); \
if (!op) { \
printf("In trying to remove plugin callback, couldn't load %s plugin\n", other_plugin); \
assert (op); \
} \
void (*rm_cb)(cb_name##_with_context_t fptr, void* context) = \
(void (*)(cb_name##_t, void*)) dlsym(op, "ppp_remove_cb_" #cb_name "_with_context"); \
assert (rm_cb != 0); \
rm_cb (cb_func, context); \
}

#endif // __PANDA_PLUGIN_PLUGIN_H_
5 changes: 5 additions & 0 deletions panda/include/panda/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ typedef target_ulong target_ptr_t;
*/
typedef int32_t target_pid_t;

/** @brief macro for defining a PPP callback typedef */
#define PPP_CB_TYPEDEF(ret_type, cb_name, ...) \
typedef ret_type (*cb_name##_t)(__VA_ARGS__); \
typedef ret_type (*cb_name##_with_context_t)(void* context, __VA_ARGS__);

/** @brief Print format for guest VM pids. */
#define TARGET_PID_FMT "%u"

Expand Down
2 changes: 1 addition & 1 deletion panda/plugins/asidstory/asidstory.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

// the type for the ppp callback for when asidstory decides a process has changed
// and we have decent OsiProc.
typedef void (* on_proc_change_t)(CPUState *env, target_ulong asid, OsiProc *proc);
PPP_CB_TYPEDEF(void,on_proc_change,CPUState *env, target_ulong asid, OsiProc *proc);


#endif
4 changes: 2 additions & 2 deletions panda/plugins/callstack_instr/callstack_instr.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
// between this and END_PYPANDA_NEEDS_THIS except includes of other
// files in this directory that contain subsections like this one.

typedef void (*on_call_t)(CPUState *env, target_ulong func);
typedef void (*on_ret_t)(CPUState *env, target_ulong func);
PPP_CB_TYPEDEF(void, on_call, CPUState *env, target_ulong func);
PPP_CB_TYPEDEF(void, on_ret, CPUState *env, target_ulong func);

// END_PYPANDA_NEEDS_THIS -- do not delete this comment!

Expand Down
2 changes: 1 addition & 1 deletion panda/plugins/forcedexec/forcedexec_ppp.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// between this and END_PYPANDA_NEEDS_THIS except includes of other
// files in this directory that contain subsections like this one.

typedef bool (*on_branch_t)(CPUState *env, TranslationBlock *tb, size_t branch_insn);
PPP_CB_TYPEDEF(bool, on_branch, CPUState *env, TranslationBlock *tb, size_t branch_insn);

// END_PYPANDA_NEEDS_THIS -- do not delete this comment!

Expand Down
20 changes: 10 additions & 10 deletions panda/plugins/hooks2/hooks2_ppp.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@
// files in this directory that contain subsections like this one.

// Hook functions must be of this type
typedef bool (*hooks2_func_t)(CPUState *, TranslationBlock *, void *);
PPP_CB_TYPEDEF(bool,hooks2_func,CPUState *, TranslationBlock *, void *);


typedef void (*on_process_start_t)(CPUState *cpu,const char *procname,target_ulong asid,target_pid_t pid);
PPP_CB_TYPEDEF(void,on_process_start,CPUState *cpu,const char *procname,target_ulong asid,target_pid_t pid);

typedef void (*on_process_end_t)(CPUState *cpu,const char *procname,target_ulong asid,target_pid_t pid);
PPP_CB_TYPEDEF(void,on_process_end,CPUState *cpu,const char *procname,target_ulong asid,target_pid_t pid);

typedef void (*on_thread_start_t)(CPUState* cpu,const char *procname,target_ulong asid,target_pid_t pid,target_pid_t tid);
PPP_CB_TYPEDEF(void,on_thread_start,CPUState* cpu,const char *procname,target_ulong asid,target_pid_t pid,target_pid_t tid);

typedef void (*on_thread_end_t)(CPUState* cpu,const char *procname,target_ulong asid,target_pid_t pid,target_pid_t tid);
PPP_CB_TYPEDEF(void,on_thread_end,CPUState* cpu,const char *procname,target_ulong asid,target_pid_t pid,target_pid_t tid);

typedef void (*on_mmap_updated_t)(CPUState* cpu,const char *libname,target_ulong base,target_ulong size);
PPP_CB_TYPEDEF(void,on_mmap_updated,CPUState* cpu,const char *libname,target_ulong base,target_ulong size);


typedef int (*_add_hooks2_t)(hooks2_func_t hook,void *cb_data,bool is_kernel,const char *procname,const char *libname,target_ulong trace_start,target_ulong trace_stop,target_ulong range_begin,target_ulong range_end);
PPP_CB_TYPEDEF(int,_add_hooks2,hooks2_func_t hook,void *cb_data,bool is_kernel,const char *procname,const char *libname,target_ulong trace_start,target_ulong trace_stop,target_ulong range_begin,target_ulong range_end);

typedef void (*_enable_hooks2_t)(int id);
typedef void (*_disable_hooks2_t)(int id);
PPP_CB_TYPEDEF(void,_enable_hooks2,int id);
PPP_CB_TYPEDEF(void,_disable_hooks2,int id);

// END_PYPANDA_NEEDS_THIS -- do not delete this comment!
#endif
#endif
2 changes: 1 addition & 1 deletion panda/plugins/loaded/loaded.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef __LOADED_H_
#define __LOADED_H_

typedef void (* on_library_load_t)(CPUState *env, target_ulong pc, char *filename, target_ulong base_addr, target_ulong size);
PPP_CB_TYPEDEF(void,on_library_load,CPUState *env, target_ulong pc, char *filename, target_ulong base_addr, target_ulong size);

#endif
Loading