]> granicus.if.org Git - strace/blobdiff - syscall.c
mem: decode hugetlb page size in mmap flags
[strace] / syscall.c
index c78436b952235fdca5f6959ff1b9d987ba249370..b1047feb67f0ec2cb43180f1e59b00f963b03ddf 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -35,6 +35,7 @@
 #include "defs.h"
 #include "native_defs.h"
 #include "nsig.h"
+#include "number_set.h"
 #include <sys/param.h>
 
 /* for struct iovec */
 #include "syscall.h"
 
 /* Define these shorthand notations to simplify the syscallent files. */
-#define TD TRACE_DESC
-#define TF TRACE_FILE
-#define TI TRACE_IPC
-#define TN TRACE_NETWORK
-#define TP TRACE_PROCESS
-#define TS TRACE_SIGNAL
-#define TM TRACE_MEMORY
-#define TST TRACE_STAT
-#define TLST TRACE_LSTAT
-#define TFST TRACE_FSTAT
-#define TSTA TRACE_STAT_LIKE
-#define TSF TRACE_STATFS
-#define TFSF TRACE_FSTATFS
-#define TSFA TRACE_STATFS_LIKE
-#define NF SYSCALL_NEVER_FAILS
-#define MA MAX_ARGS
-#define SI STACKTRACE_INVALIDATE_CACHE
-#define SE STACKTRACE_CAPTURE_ON_ENTER
-#define CST COMPAT_SYSCALL_TYPES
+#include "sysent_shorthand_defs.h"
 
 #define SEN(syscall_name) SEN_ ## syscall_name, SYS_FUNC_NAME(sys_ ## syscall_name)
 
@@ -111,26 +94,7 @@ static const struct_sysent sysent2[] = {
 #endif
 
 /* Now undef them since short defines cause wicked namespace pollution. */
-#undef SEN
-#undef TD
-#undef TF
-#undef TI
-#undef TN
-#undef TP
-#undef TS
-#undef TM
-#undef TST
-#undef TLST
-#undef TFST
-#undef TSTA
-#undef TSF
-#undef TFSF
-#undef TSFA
-#undef NF
-#undef MA
-#undef SI
-#undef SE
-#undef CST
+#include "sysent_shorthand_undefs.h"
 
 /*
  * `ioctlent[012].h' files are automatically generated by the auxiliary
@@ -344,16 +308,12 @@ update_personality(struct tcb *tcp, unsigned int personality)
        tcp->currpers = personality;
 
 # undef PERSONALITY_NAMES
-# if defined POWERPC64
-#  define PERSONALITY_NAMES {"64 bit", "32 bit"}
-# elif defined X86_64
+# if defined X86_64
 #  define PERSONALITY_NAMES {"64 bit", "32 bit", "x32"}
 # elif defined X32
 #  define PERSONALITY_NAMES {"x32", "32 bit"}
-# elif defined AARCH64
+# elif SUPPORTED_PERSONALITIES == 2
 #  define PERSONALITY_NAMES {"64 bit", "32 bit"}
-# elif defined TILE
-#  define PERSONALITY_NAMES {"64-bit", "32-bit"}
 # endif
 # ifdef PERSONALITY_NAMES
        if (!qflag) {
@@ -468,7 +428,7 @@ dumpio(struct tcb *tcp)
        if (fd < 0)
                return;
 
-       if (is_number_in_set(fd, &read_set)) {
+       if (is_number_in_set(fd, read_set)) {
                switch (tcp->s_ent->sen) {
                case SEN_read:
                case SEN_pread:
@@ -491,7 +451,7 @@ dumpio(struct tcb *tcp)
                        return;
                }
        }
-       if (is_number_in_set(fd, &write_set)) {
+       if (is_number_in_set(fd, write_set)) {
                switch (tcp->s_ent->sen) {
                case SEN_write:
                case SEN_pwrite:
@@ -610,9 +570,9 @@ tamper_with_syscall_entering(struct tcb *tcp, unsigned int *signo)
 
        opts->first = opts->step;
 
-       if (opts->signo > 0)
-               *signo = opts->signo;
-       if (opts->rval != INJECT_OPTS_RVAL_DEFAULT && !arch_set_scno(tcp, -1))
+       if (opts->data.flags & INJECT_F_SIGNAL)
+               *signo = opts->data.signo;
+       if (opts->data.flags & INJECT_F_RETVAL && !arch_set_scno(tcp, -1))
                tcp->flags |= TCB_TAMPERED;
 
        return 0;
@@ -626,17 +586,17 @@ tamper_with_syscall_exiting(struct tcb *tcp)
        if (!opts)
                return 0;
 
-       if (opts->rval >= 0) {
+       if (opts->data.rval >= 0) {
                kernel_long_t u_rval = tcp->u_rval;
 
-               tcp->u_rval = opts->rval;
+               tcp->u_rval = opts->data.rval;
                if (arch_set_success(tcp)) {
                        tcp->u_rval = u_rval;
                } else {
                        tcp->u_error = 0;
                }
        } else {
-               unsigned long new_error = -opts->rval;
+               unsigned long new_error = -opts->data.rval;
 
                if (new_error != tcp->u_error && new_error <= MAX_ERRNO_VALUE) {
                        unsigned long u_error = tcp->u_error;
@@ -717,9 +677,7 @@ syscall_entering_trace(struct tcb *tcp, unsigned int *sig)
                        break;
        }
 
-       if (!(tcp->qual_flg & QUAL_TRACE)
-        || (tracing_paths && !pathtrace_match(tcp))
-       ) {
+       if (!traced(tcp) || (tracing_paths && !pathtrace_match(tcp))) {
                tcp->flags |= TCB_FILTERED;
                return 0;
        }
@@ -730,7 +688,7 @@ syscall_entering_trace(struct tcb *tcp, unsigned int *sig)
                return 0;
        }
 
-       if (tcp->qual_flg & QUAL_INJECT)
+       if (inject(tcp))
                tamper_with_syscall_entering(tcp, sig);
 
        if (cflag == CFLAG_ONLY_STATS) {
@@ -746,8 +704,7 @@ syscall_entering_trace(struct tcb *tcp, unsigned int *sig)
 
        printleader(tcp);
        tprintf("%s(", tcp->s_ent->sys_name);
-       int res = (tcp->qual_flg & QUAL_RAW)
-               ? printargs(tcp) : tcp->s_ent->sys_func(tcp);
+       int res = raw(tcp) ? printargs(tcp) : tcp->s_ent->sys_func(tcp);
        fflush(tcp->outf);
        return res;
 }
@@ -841,7 +798,7 @@ syscall_exiting_trace(struct tcb *tcp, struct timeval tv, int res)
        tcp->s_prev_ent = tcp->s_ent;
 
        int sys_res = 0;
-       if (tcp->qual_flg & QUAL_RAW) {
+       if (raw(tcp)) {
                /* sys_res = printargs(tcp); - but it's nop on sysexit */
        } else {
        /* FIXME: not_failing_only (IOW, option -z) is broken:
@@ -864,7 +821,7 @@ syscall_exiting_trace(struct tcb *tcp, struct timeval tv, int res)
        tabto();
        unsigned long u_error = tcp->u_error;
 
-       if (tcp->qual_flg & QUAL_RAW) {
+       if (raw(tcp)) {
                if (u_error) {
                        tprintf("= -1 (errno %lu)", u_error);
                } else {
@@ -872,8 +829,7 @@ syscall_exiting_trace(struct tcb *tcp, struct timeval tv, int res)
                }
                if (syscall_tampered(tcp))
                        tprints(" (INJECTED)");
-       }
-       else if (!(sys_res & RVAL_NONE) && u_error) {
+       } else if (!(sys_res & RVAL_NONE) && u_error) {
                const char *u_error_str;
 
                switch (u_error) {
@@ -944,8 +900,7 @@ syscall_exiting_trace(struct tcb *tcp, struct timeval tv, int res)
                        tprints(" (INJECTED)");
                if ((sys_res & RVAL_STR) && tcp->auxstr)
                        tprintf(" (%s)", tcp->auxstr);
-       }
-       else {
+       } else {
                if (sys_res & RVAL_NONE)
                        tprints("= ?");
                else {
@@ -983,8 +938,7 @@ syscall_exiting_trace(struct tcb *tcp, struct timeval tv, int res)
                                if (show_fd_path) {
                                        tprints("= ");
                                        printfd(tcp, tcp->u_rval);
-                               }
-                               else
+                               } else
                                        tprintf("= %" PRI_kld, tcp->u_rval);
                                break;
                        default:
@@ -1050,26 +1004,6 @@ restore_cleared_syserror(struct tcb *tcp)
        tcp->u_error = saved_u_error;
 }
 
-/*
- * Check the syscall return value register value for whether it is
- * a negated errno code indicating an error, or a success return value.
- */
-static inline bool
-is_negated_errno(kernel_ulong_t val)
-{
-       /* Linux kernel defines MAX_ERRNO to 4095. */
-       kernel_ulong_t max = -(kernel_long_t) 4095;
-
-#ifndef current_klongsize
-       if (current_klongsize < sizeof(val)) {
-               val = (uint32_t) val;
-               max = (uint32_t) max;
-       }
-#endif /* !current_klongsize */
-
-       return val >= max;
-}
-
 #include "arch_regs.c"
 
 #ifdef HAVE_GETRVAL2
@@ -1325,5 +1259,5 @@ syscall_name(kernel_ulong_t scno)
        if (current_personality == X32_PERSONALITY_NUMBER)
                scno &= ~__X32_SYSCALL_BIT;
 #endif
-       return scno_is_valid(scno) ? sysent[scno].sys_name: NULL;
+       return scno_is_valid(scno) ? sysent[scno].sys_name : NULL;
 }