@@ -324,6 +324,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
#ifdef DEBUG
gemu_log("freebsd syscall %d\n", num);
#endif
+ instr_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
if(do_strace)
print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -423,6 +424,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
#ifdef DEBUG
gemu_log("netbsd syscall %d\n", num);
#endif
+ instr_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 0);
trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 0);
if(do_strace)
print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -499,6 +501,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
#ifdef DEBUG
gemu_log("openbsd syscall %d\n", num);
#endif
+ instr_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 0);
trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 0);
if(do_strace)
print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -121,3 +121,17 @@ QI_VPUBLIC void qi_event_set_guest_mem_before_exec(
ERROR_IF(!instr_get_state(), "called outside instrumentation");
instr_set_event(guest_mem_before_exec, fn);
}
+
+
+void (*instr_event__guest_user_syscall)(
+ QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+ uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+
+QI_VPUBLIC void qi_event_set_guest_user_syscall(
+ void (*fn)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
+ uint64_t arg7, uint64_t arg8))
+{
+ ERROR_IF(!instr_get_state(), "called outside instrumentation");
+ instr_set_event(guest_user_syscall, fn);
+}
@@ -68,6 +68,13 @@ extern void (*instr_event__guest_mem_before_exec)(
static inline void instr_guest_mem_before_exec(
CPUState *vcpu, uint64_t vaddr, TraceMemInfo info);
+extern void (*instr_event__guest_user_syscall)(
+ QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+ uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+static inline void instr_guest_user_syscall(
+ CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+ uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+
#include "instrument/events.inc.h"
@@ -77,3 +77,19 @@ static inline void instr_guest_mem_before_exec(
instr_set_state(INSTR_STATE_DISABLE);
}
}
+
+static inline void instr_guest_user_syscall(
+ CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+ uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8)
+{
+ void (*cb)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
+ uint64_t arg7, uint64_t arg8)
+ = instr_get_event(guest_user_syscall);
+ if (cb) {
+ instr_set_state(INSTR_STATE_ENABLE);
+ QICPU vcpu_ = instr_cpu_set(vcpu);
+ (*cb)(vcpu_, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+ instr_set_state(INSTR_STATE_DISABLE);
+ }
+}
@@ -153,6 +153,7 @@ InstrUnloadError instr_unload(int64_t handle_id)
instr_set_event(guest_cpu_reset, NULL);
instr_set_event(guest_mem_before_trans, NULL);
instr_set_event(guest_mem_before_exec, NULL);
+ instr_set_event(guest_user_syscall, NULL);
/* this should never fail */
if (dlclose(handle->dlhandle) < 0) {
@@ -134,6 +134,21 @@ void qi_event_gen_guest_mem_before_exec(
void qi_event_set_guest_mem_before_exec(
void (*fn)(QICPU vcpu, uint64_t vaddr, QIMemInfo info));
+/*
+ * Start executing a guest system call in syscall emulation mode.
+ *
+ * @num: System call number.
+ * @arg*: System call argument value.
+ *
+ * Mode: user
+ * Targets: TCG(all)
+ * Time: exec
+ */
+void qi_event_set_guest_user_syscall(
+ void (*fn)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
+ uint64_t arg7, uint64_t arg8));
+
#ifdef __cplusplus
}
#endif
@@ -7723,6 +7723,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#ifdef DEBUG
gemu_log("syscall %d", num);
#endif
+ instr_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
if(do_strace)
print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -18,3 +18,6 @@ void (*instr_event__guest_mem_before_trans)(
QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info);
void (*instr_event__guest_mem_before_exec)(
QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info);
+void (*instr_event__guest_user_syscall)(
+ QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+ uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- bsd-user/syscall.c | 3 +++ instrument/control.c | 14 ++++++++++++++ instrument/events.h | 7 +++++++ instrument/events.inc.h | 16 ++++++++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 15 +++++++++++++++ linux-user/syscall.c | 1 + stubs/instrument.c | 3 +++ 8 files changed, 60 insertions(+)