X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=syscall.c;h=6aa1cd2d17c00f801b8208dc7b8ab68e6d823fd5;hb=3b9d315e8c5ff753ede067af121da9decad9d182;hp=1a9c5fc297fc104773a6d1c3054f555e66d2e681;hpb=3e9d71feaad428f0f8e335f83b86e9f2a16781fb;p=strace diff --git a/syscall.c b/syscall.c index 1a9c5fc2..6aa1cd2d 100644 --- a/syscall.c +++ b/syscall.c @@ -81,6 +81,9 @@ #define SI STACKTRACE_INVALIDATE_CACHE #define SE STACKTRACE_CAPTURE_ON_ENTER +#define SEN_NAME(syscall_name) SEN_ ## syscall_name +#define SEN(syscall_name) SEN_NAME(syscall_name), SYS_FUNC_NAME(syscall_name) + const struct_sysent sysent0[] = { #include "syscallent.h" }; @@ -98,6 +101,8 @@ static const struct_sysent sysent2[] = { #endif /* Now undef them since short defines cause wicked namespace pollution. */ +#undef SEN +#undef SEN_NAME #undef TD #undef TF #undef TI @@ -313,35 +318,23 @@ update_personality(struct tcb *tcp, unsigned int personality) return; tcp->currpers = personality; -# if defined(POWERPC64) - if (!qflag) { - static const char *const names[] = {"64 bit", "32 bit"}; - fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", - tcp->pid, names[personality]); - } -# elif defined(X86_64) - if (!qflag) { - static const char *const names[] = {"64 bit", "32 bit", "x32"}; - fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", - tcp->pid, names[personality]); - } -# elif defined(X32) - if (!qflag) { - static const char *const names[] = {"x32", "32 bit"}; - fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", - tcp->pid, names[personality]); - } -# elif defined(AARCH64) - if (!qflag) { - static const char *const names[] = {"32-bit", "AArch64"}; - fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", - tcp->pid, names[personality]); - } -# elif defined(TILE) +# undef PERSONALITY_NAMES +# if defined POWERPC64 +# define PERSONALITY_NAMES {"64 bit", "32 bit"} +# elif defined X86_64 +# define PERSONALITY_NAMES {"64 bit", "32 bit", "x32"} +# elif defined X32 +# define PERSONALITY_NAMES {"x32", "32 bit"} +# elif defined AARCH64 +# define PERSONALITY_NAMES {"32-bit", "AArch64"} +# elif defined TILE +# define PERSONALITY_NAMES {"64-bit", "32-bit"} +# endif +# ifdef PERSONALITY_NAMES if (!qflag) { - static const char *const names[] = {"64-bit", "32-bit"}; - fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", - tcp->pid, names[personality]); + static const char *const names[] = PERSONALITY_NAMES; + error_msg("[ Process PID=%d runs in %s mode. ]", + tcp->pid, names[personality]); } # endif } @@ -662,49 +655,56 @@ printargs_ld(struct tcb *tcp) static void dumpio(struct tcb *tcp) { - int (*func)(); + int sen; if (syserror(tcp)) return; if ((unsigned long) tcp->u_arg[0] >= num_quals) return; - func = tcp->s_ent->sys_func; - if (func == printargs) + sen = tcp->s_ent->sen; + if (SEN_printargs == sen) return; if (qual_flags[tcp->u_arg[0]] & QUAL_READ) { - if (func == sys_read || - func == sys_pread || - func == sys_recv || - func == sys_recvfrom) { + switch (sen) { + case SEN_read: + case SEN_pread: + case SEN_recv: + case SEN_recvfrom: dumpstr(tcp, tcp->u_arg[1], tcp->u_rval); return; - } else if (func == sys_readv) { + case SEN_readv: dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]); return; -#if HAVE_SENDMSG - } else if (func == sys_recvmsg) { +#ifdef HAVE_SENDMSG + case SEN_recvmsg: dumpiov_in_msghdr(tcp, tcp->u_arg[1]); return; - } else if (func == sys_recvmmsg) { + case SEN_recvmmsg: dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]); return; #endif } } if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) { - if (func == sys_write || - func == sys_pwrite || - func == sys_send || - func == sys_sendto) + switch (sen) { + case SEN_write: + case SEN_pwrite: + case SEN_send: + case SEN_sendto: dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); - else if (func == sys_writev) + break; + case SEN_writev: dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]); -#if HAVE_SENDMSG - else if (func == sys_sendmsg) + break; +#ifdef HAVE_SENDMSG + case SEN_sendmsg: dumpiov_in_msghdr(tcp, tcp->u_arg[1]); - else if (func == sys_sendmmsg) + break; + case SEN_sendmmsg: dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]); + break; #endif + } } } @@ -792,33 +792,30 @@ trace_syscall_entering(struct tcb *tcp) } #ifdef LINUX_MIPSO32 - if (sys_syscall == tcp->s_ent->sys_func) + if (SEN_syscall == tcp->s_ent->sen) decode_mips_subcall(tcp); #endif - if ( sys_execve == tcp->s_ent->sys_func + if ( SEN_execve == tcp->s_ent->sen # if defined(SPARC) || defined(SPARC64) - || sys_execv == tcp->s_ent->sys_func + || SEN_execv == tcp->s_ent->sen # endif ) { hide_log_until_execve = 0; } #if defined(SYS_socket_subcall) || defined(SYS_ipc_subcall) - while (1) { + switch (tcp->s_ent->sen) { # ifdef SYS_socket_subcall - if (tcp->s_ent->sys_func == sys_socketcall) { + case SEN_socketcall: decode_socket_subcall(tcp); break; - } # endif # ifdef SYS_ipc_subcall - if (tcp->s_ent->sys_func == sys_ipc) { + case SEN_ipc: decode_ipc_subcall(tcp); break; - } # endif - break; } #endif @@ -826,6 +823,7 @@ trace_syscall_entering(struct tcb *tcp) || (tracing_paths && !pathtrace_match(tcp)) ) { tcp->flags |= TCB_INSYSCALL | TCB_FILTERED; + tcp->sys_func_rval = 0; return 0; } @@ -848,7 +846,7 @@ trace_syscall_entering(struct tcb *tcp) tprintf("%s(", undefined_scno_name(tcp)); else tprintf("%s(", tcp->s_ent->sys_name); - if ((tcp->qual_flg & QUAL_RAW) && tcp->s_ent->sys_func != sys_exit) + if ((tcp->qual_flg & QUAL_RAW) && SEN_exit != tcp->s_ent->sen) res = printargs(tcp); else res = tcp->s_ent->sys_func(tcp); @@ -856,6 +854,7 @@ trace_syscall_entering(struct tcb *tcp) fflush(tcp->outf); ret: tcp->flags |= TCB_INSYSCALL; + tcp->sys_func_rval = res; /* Measure the entrance time as late as possible to avoid errors. */ if (Tflag || cflag) gettimeofday(&tcp->etime, NULL); @@ -885,10 +884,8 @@ trace_syscall_exiting(struct tcb *tcp) update_personality(tcp, tcp->currpers); #endif res = (get_regs_error ? -1 : get_syscall_result(tcp)); - if (res == 1) { - if (filtered(tcp) || hide_log_until_execve) - goto ret; - } + if (filtered(tcp) || hide_log_until_execve) + goto ret; if (cflag) { count_syscall(tcp, &tv); @@ -924,6 +921,7 @@ trace_syscall_exiting(struct tcb *tcp) tprints("= ? \n"); line_ended(); tcp->flags &= ~TCB_INSYSCALL; + tcp->sys_func_rval = 0; return res; } tcp->s_prev_ent = tcp->s_ent; @@ -942,7 +940,10 @@ trace_syscall_exiting(struct tcb *tcp) */ if (not_failing_only && tcp->u_error) goto ret; /* ignore failed syscalls */ - sys_res = tcp->s_ent->sys_func(tcp); + if (tcp->sys_func_rval & RVAL_DECODED) + sys_res = tcp->sys_func_rval; + else + sys_res = tcp->s_ent->sys_func(tcp); } tprints(") "); @@ -1072,8 +1073,7 @@ trace_syscall_exiting(struct tcb *tcp) */ #endif default: - fprintf(stderr, - "invalid rval format\n"); + error_msg("invalid rval format"); break; } } @@ -1096,6 +1096,7 @@ trace_syscall_exiting(struct tcb *tcp) ret: tcp->flags &= ~TCB_INSYSCALL; + tcp->sys_func_rval = 0; return 0; } @@ -1295,8 +1296,7 @@ get_scno(struct tcb *tcp) tcp->s_ent = &unknown; tcp->qual_flg = UNDEFINED_SCNO | QUAL_RAW | DEFAULT_QUAL_FLAGS; if (debug_flag) - fprintf(stderr, "pid %d invalid syscall %ld\n", - tcp->pid, scno); + error_msg("pid %d invalid syscall %ld", tcp->pid, scno); } return 1; }