Commit ea97ecff authored by Gabor Buella's avatar Gabor Buella

syscall logging example - handle non-returning syscalls

parent 63a99ca3
......@@ -56,7 +56,7 @@ static const struct syscall_desc table[] = {
SARGS(brk, rdec, arg_),
SARGS(rt_sigaction, rdec, arg_, arg_, arg_),
SARGS(rt_sigprocmask, rdec, arg_, arg_, arg_, arg_),
SARGS(rt_sigreturn, rdec, arg_none),
SARGS(rt_sigreturn, rnoreturn, arg_none),
SARGS(ioctl, rdec, arg_fd, arg_, arg_),
SARGS(pread64, rdec, arg_fd, arg_, arg_, arg_),
SARGS(pwrite64, rdec, arg_fd, arg_, arg_, arg_),
......@@ -101,7 +101,7 @@ static const struct syscall_desc table[] = {
SARGS(fork, rdec, arg_none),
SARGS(vfork, rdec, arg_none),
SARGS(execve, rdec, arg_, arg_, arg_),
SARGS(exit, rdec, arg_), /* XXX */
SARGS(exit, rnoreturn, arg_),
SARGS(wait4, rdec, arg_, arg_, arg_, arg_),
SARGS(kill, rdec, arg_, arg_),
SARGS(uname, rdec, arg_),
......@@ -255,7 +255,7 @@ static const struct syscall_desc table[] = {
SARGS(clock_gettime, rdec, arg_, arg_),
SARGS(clock_getres, rdec, arg_, arg_),
SARGS(clock_nanosleep, rdec, arg_, arg_, arg_, arg_),
SARGS(exit_group, rdec, arg_), /* XXX */
SARGS(exit_group, rnoreturn, arg_),
SARGS(epoll_wait, rdec, arg_fd, arg_, arg_, arg_),
SARGS(epoll_ctl, rdec, arg_fd, arg_, arg_fd, arg_),
SARGS(tgkill, rdec, arg_, arg_, arg_),
......
......@@ -47,7 +47,8 @@ enum return_type {
rhex,
rdec,
runsigned,
rmode
rmode,
rnoreturn
};
struct syscall_desc {
......
......@@ -775,40 +775,44 @@ print_known_syscall(char *dst, const struct syscall_desc *desc,
}
}
dst = print_cstr(dst, ") = ");
switch (desc->return_type) {
case rhex:
dst = print_hex(dst, result);
break;
case rdec:
dst = print_rdec(dst, result);
break;
case runsigned:
dst = print_runsigned(dst, result);
break;
case rmode:
dst = print_mode_t(dst, result);
break;
*dst++ = ')';
if (desc->return_type != rnoreturn) {
dst = print_cstr(dst, " = ");
switch (desc->return_type) {
default:
case rhex:
dst = print_hex(dst, result);
break;
case rdec:
dst = print_rdec(dst, result);
break;
case runsigned:
dst = print_runsigned(dst, result);
break;
case rmode:
dst = print_mode_t(dst, result);
break;
}
}
return dst;
}
static ssize_t
print_syscall(char *dst, long syscall_number, long args[6], long result)
static void
print_syscall(const struct syscall_desc *desc,
long syscall_number, const long args[6], long result)
{
const struct syscall_desc *desc =
get_syscall_desc(syscall_number, args);
char local_buffer[0x300];
char *c;
if (desc != NULL)
c = print_known_syscall(dst, desc, args, result);
c = print_known_syscall(local_buffer, desc, args, result);
else
c = print_unknown_syscall(dst, syscall_number, args, result);
c = print_unknown_syscall(local_buffer, syscall_number,
args, result);
*c++ = '\n';
return c - dst;
append_buffer(local_buffer, c - local_buffer);
}
static int
......@@ -818,17 +822,21 @@ hook(long syscall_number,
long arg4, long arg5,
long *result)
{
*result = syscall_no_intercept(syscall_number,
arg0, arg1, arg2, arg3, arg4, arg5);
long args[6] = {arg0, arg1, arg2, arg3, arg4, arg5};
const struct syscall_desc *desc =
get_syscall_desc(syscall_number, args);
char local_buffer[0x300];
ssize_t len;
if (desc != NULL && desc->return_type == rnoreturn) {
print_syscall(desc, syscall_number, args, 0);
if (syscall_number == SYS_exit_group && buffer_offset > 0)
syscall_no_intercept(SYS_write, log_fd,
buffer, buffer_offset);
}
len = print_syscall(local_buffer, syscall_number, args, *result);
*result = syscall_no_intercept(syscall_number,
arg0, arg1, arg2, arg3, arg4, arg5);
append_buffer(local_buffer, len);
print_syscall(desc, syscall_number, args, *result);
return 0;
}
......@@ -848,10 +856,3 @@ start(void)
intercept_hook_point = &hook;
}
static __attribute__((destructor)) void
end(void)
{
if (buffer_offset > 0)
syscall_no_intercept(SYS_write, log_fd, buffer, buffer_offset);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment