1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#ifdef SB_SCHIZO
static const struct syscall_entry syscall_table_32[] = {
#define S(s) { SB_SYS_x86_##s, SB_NR_##s, #s },
#include "trace_syscalls_x86.h"
#undef S
{ SB_NR_UNDEF, SB_NR_UNDEF, NULL },
};
static const struct syscall_entry syscall_table_64[] = {
#define S(s) { SB_SYS_x86_64_##s, SB_NR_##s, #s },
#include "trace_syscalls_x86_64.h"
#undef S
{ SB_NR_UNDEF, SB_NR_UNDEF, NULL },
};
static bool pers_is_32(void)
{
switch (do_peekuser(8 * CS)) {
case 0x23: return true;
case 0x33: return false;
default: sb_abort();
}
}
static const struct syscall_entry *trace_check_personality(void)
{
return pers_is_32() ? syscall_table_32 : syscall_table_64;
}
#else
static bool pers_is_32(void)
{
return false;
}
#endif
static int trace_sysnum(void)
{
return do_peekuser(8 * ORIG_RAX);
}
static long trace_raw_ret(void *vregs)
{
trace_regs *regs = vregs;
return pers_is_32() ? (int)regs->rax : regs->rax;
}
static void trace_set_sysnum(void *vregs, long nr)
{
do_pokeuser(8 * ORIG_RAX, nr);
}
static void trace_set_ret(void *vregs, int err)
{
do_pokeuser(8 * RAX, -err);
}
static unsigned long trace_arg(void *vregs, int num)
{
trace_regs *regs = vregs;
if (pers_is_32())
switch (num) {
case 1: return regs->rbx;
case 2: return regs->rcx;
case 3: return regs->rdx;
case 4: return regs->rsi;
case 5: return regs->rdi;
case 6: return regs->rbp;
default: return -1;
}
else
switch (num) {
case 1: return regs->rdi;
case 2: return regs->rsi;
case 3: return regs->rdx;
case 4: return regs->r10;
case 5: return regs->r8;
case 6: return regs->r9;
default: return -1;
}
}
#ifdef DEBUG
static void trace_dump_regs(void *vregs)
{
trace_regs *regs = vregs;
sb_printf("{ ");
#define D(r) sb_printf(#r":%lu ", regs->r)
D(rax);
D(rdi);
D(rsi);
D(rdx);
D(r10);
D(r8);
D(r9);
#undef D
sb_printf("}");
}
#endif
|