]> granicus.if.org Git - strace/commitdiff
cleanup: make get_scno.c files more readable
authorDmitry V. Levin <ldv@altlinux.org>
Mon, 30 Nov 2015 01:46:52 +0000 (01:46 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 30 Nov 2015 01:46:52 +0000 (01:46 +0000)
Make get_scno.c files more self-contained.  While they are still
being included by syscall.c, the latter no longer provides
a function framework for them.

* linux/aarch64/get_scno.c (arch_get_scno): Define.
* linux/alpha/get_scno.c: Likewise.
* linux/arc/get_scno.c: Likewise.
* linux/arm/get_scno.c: Likewise.
* linux/avr32/get_scno.c: Likewise.
* linux/bfin/get_scno.c: Likewise.
* linux/crisv10/get_scno.c: Likewise.
* linux/hppa/get_scno.c: Likewise.
* linux/i386/get_scno.c: Likewise.
* linux/ia64/get_scno.c: Likewise.
* linux/m68k/get_scno.c: Likewise.
* linux/metag/get_scno.c: Likewise.
* linux/microblaze/get_scno.c: Likewise.
* linux/mips/get_scno.c: Likewise.
* linux/nios2/get_scno.c: Likewise.
* linux/or1k/get_scno.c: Likewise.
* linux/powerpc/get_scno.c: Likewise.
* linux/powerpc64/get_scno.c: Likewise.
* linux/s390/get_scno.c: Likewise.
* linux/sh/get_scno.c: Likewise.
* linux/sh64/get_scno.c: Likewise.
* linux/sparc/get_scno.c: Likewise.
* linux/sparc64/get_scno.c: Likewise.
* linux/tile/get_scno.c: Likewise.
* linux/x86_64/get_scno.c: Likewise.
* linux/xtensa/get_scno.c: Likewise.
* syscall.c (arch_get_scno): New declaration.
Include "get_scno.c" in file scope.
(get_scno): Use arch_get_scno.

Requested-by: Denys Vlasenko <dvlasenk@redhat.com>
27 files changed:
linux/aarch64/get_scno.c
linux/alpha/get_scno.c
linux/arc/get_scno.c
linux/arm/get_scno.c
linux/avr32/get_scno.c
linux/bfin/get_scno.c
linux/crisv10/get_scno.c
linux/hppa/get_scno.c
linux/i386/get_scno.c
linux/ia64/get_scno.c
linux/m68k/get_scno.c
linux/metag/get_scno.c
linux/microblaze/get_scno.c
linux/mips/get_scno.c
linux/nios2/get_scno.c
linux/or1k/get_scno.c
linux/powerpc/get_scno.c
linux/powerpc64/get_scno.c
linux/s390/get_scno.c
linux/sh/get_scno.c
linux/sh64/get_scno.c
linux/sparc/get_scno.c
linux/sparc64/get_scno.c
linux/tile/get_scno.c
linux/x86_64/get_scno.c
linux/xtensa/get_scno.c
syscall.c

index 610b38d7650f375496ad72d570b584d0f50b0f63..a712a94866dd9eaa8714f995c34a8eb2143a8407 100644 (file)
@@ -1,14 +1,24 @@
-switch (aarch64_io.iov_len) {
-       case sizeof(aarch64_regs):
-               /* We are in 64-bit mode */
-               scno = aarch64_regs.regs[8];
-               update_personality(tcp, 1);
-               break;
-       case sizeof(arm_regs):
-               /* We are in 32-bit mode */
-               /* Note: we don't support OABI, unlike 32-bit ARM build */
-               scno = arm_regs.ARM_r7;
-               scno = shuffle_scno(scno);
-               update_personality(tcp, 0);
-               break;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       long scno = 0;
+
+       switch (aarch64_io.iov_len) {
+               case sizeof(aarch64_regs):
+                       /* We are in 64-bit mode */
+                       scno = aarch64_regs.regs[8];
+                       update_personality(tcp, 1);
+                       break;
+               case sizeof(arm_regs):
+                       /* We are in 32-bit mode */
+                       /* Note: we don't support OABI, unlike 32-bit ARM build */
+                       scno = arm_regs.ARM_r7;
+                       scno = shuffle_scno(scno);
+                       update_personality(tcp, 0);
+                       break;
+       }
+
+       tcp->scno = scno;
+       return 1;
 }
index bf8c3ada594ef4bf0e1fdceca2d4a1a68b578a79..fc099216fbe4bd68512077ac72ea0c92e2ac4eef 100644 (file)
@@ -1,16 +1,26 @@
-if (upeek(tcp->pid, REG_A3, &alpha_a3) < 0)
-       return -1;
-if (upeek(tcp->pid, REG_R0, &scno) < 0)
-       return -1;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       long scno = 0;
 
-/*
- * Do some sanity checks to figure out if it's
- * really a syscall entry
- */
-if (!SCNO_IN_RANGE(scno)) {
-       if (alpha_a3 == 0 || alpha_a3 == -1) {
-               if (debug_flag)
-                       error_msg("stray syscall exit: r0 = %ld", scno);
-               return 0;
+       if (upeek(tcp->pid, REG_A3, &alpha_a3) < 0)
+               return -1;
+       if (upeek(tcp->pid, REG_R0, &scno) < 0)
+               return -1;
+
+       /*
+        * Do some sanity checks to figure out if it's
+        * really a syscall entry
+        */
+       if (!SCNO_IN_RANGE(scno)) {
+               if (alpha_a3 == 0 || alpha_a3 == -1) {
+                       if (debug_flag)
+                               error_msg("stray syscall exit: r0 = %ld", scno);
+                       return 0;
+               }
        }
+
+       tcp->scno = scno;
+       return 1;
 }
index cc45d46802a530a011c055ca3ed85345dbf037fa..d2046b2db514857505d87e0f4d7475bdbda9a3ba 100644 (file)
@@ -1 +1,7 @@
-scno = arc_regs.scratch.r8;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = arc_regs.scratch.r8;
+       return 1;
+}
index 6591aa84259197b717aa483904c89fd67d415fae..d9b6ffc51a3e39dcadedafca17da73bebb4df94f 100644 (file)
@@ -1,45 +1,57 @@
-/* Note: we support only 32-bit CPUs, not 26-bit */
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       long scno = 0;
+
+       /* Note: we support only 32-bit CPUs, not 26-bit */
 
 #if !defined(__ARM_EABI__) || ENABLE_ARM_OABI
-if (arm_regs.ARM_cpsr & 0x20) {
-       /* Thumb mode */
-       goto scno_in_r7;
-}
-/* ARM mode */
-/* Check EABI/OABI by examining SVC insn's low 24 bits */
-errno = 0;
-scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL);
-if (errno)
-       return -1;
-/* EABI syscall convention? */
-if ((unsigned long) scno != 0xef000000) {
-       /* No, it's OABI */
-       if ((scno & 0x0ff00000) != 0x0f900000) {
-               error_msg("pid %d unknown syscall trap 0x%08lx",
-                       tcp->pid, scno);
+       if (arm_regs.ARM_cpsr & 0x20) {
+               /* Thumb mode */
+               goto scno_in_r7;
+       }
+       /* ARM mode */
+       /* Check EABI/OABI by examining SVC insn's low 24 bits */
+       errno = 0;
+       scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL);
+       if (errno)
                return -1;
+       /* EABI syscall convention? */
+       if ((unsigned long) scno != 0xef000000) {
+               /* No, it's OABI */
+               if ((scno & 0x0ff00000) != 0x0f900000) {
+                       error_msg("pid %d unknown syscall trap 0x%08lx",
+                               tcp->pid, scno);
+                       return -1;
+               }
+               /* Fixup the syscall number */
+               scno &= 0x000fffff;
+       } else {
+       scno_in_r7:
+               scno = arm_regs.ARM_r7;
        }
-       /* Fixup the syscall number */
-       scno &= 0x000fffff;
-} else {
-scno_in_r7:
-       scno = arm_regs.ARM_r7;
-}
 #else /* __ARM_EABI__ || !ENABLE_ARM_OABI */
 
-scno = arm_regs.ARM_r7;
+       scno = arm_regs.ARM_r7;
 
 #endif
 
-scno = shuffle_scno(scno);
+       scno = shuffle_scno(scno);
+
+       /*
+        * Do some sanity checks to figure out
+        * whether it's really a syscall entry.
+        */
+       if (arm_regs.ARM_ip && !SCNO_IN_RANGE(scno)) {
+               if (debug_flag)
+                       error_msg("pid %d stray syscall exit:"
+                                 " ARM_ip = %ld, scno = %ld",
+                                 tcp->pid, arm_regs.ARM_ip,
+                                 shuffle_scno(scno));
+               return 0;
+       }
 
-/*
- * Do some sanity checks to figure out
- * whether it's really a syscall entry.
- */
-if (arm_regs.ARM_ip && !SCNO_IN_RANGE(scno)) {
-       if (debug_flag)
-               error_msg("pid %d stray syscall exit: ARM_ip = %ld, scno = %ld",
-                         tcp->pid, arm_regs.ARM_ip, shuffle_scno(scno));
-       return 0;
+       tcp->scno = scno;
+       return 1;
 }
index 014232990785ebfb8115761525a4ca8f67636ee2..092dad307115a23524c1bb3534a82849d3e715a3 100644 (file)
@@ -1 +1,7 @@
-scno = avr32_regs.r8;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = avr32_regs.r8;
+       return 1;
+}
index dfdb0a7ceda162d34bc0678c1eed47327a58aa9a..8c3a7d21658ec26ed4829ae69577307248035f65 100644 (file)
@@ -1,2 +1,6 @@
-if (upeek(tcp->pid, PT_ORIG_P0, &scno))
-       return -1;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       return upeek(tcp->pid, PT_ORIG_P0, &tcp->scno) < 0 ? -1 : 1;
+}
index 5bbbe8be00c14bdeaf8d7b952e5c32994eef6a53..14ff3386df794e1682ccc97120210a7ab3ce1195 100644 (file)
@@ -1,2 +1,6 @@
-if (upeek(tcp->pid, 4*PT_R9, &scno) < 0)
-       return -1;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       return upeek(tcp->pid, 4 * PT_R9, &tcp->scno) < 0 ? -1 : 1;
+}
index 0dc1a4653c691c411a65a7723a3cd1390d17f600..7da2fc403167c6c760dfca2d78b8f42af0a6225f 100644 (file)
@@ -1,2 +1,6 @@
-if (upeek(tcp->pid, PT_GR20, &scno) < 0)
-       return -1;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       return upeek(tcp->pid, PT_GR20, &tcp->scno) < 0 ? -1 : 1;
+}
index fa22fa6cc267720986fb44a2882df22c1e42a6f9..c2e55510d479d2501de99608bef093f019fade92 100644 (file)
@@ -1 +1,7 @@
-scno = i386_regs.orig_eax;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = i386_regs.orig_eax;
+       return 1;
+}
index 86333fd8405b9da8901de8d76b21a402e044f402..0ddc17a930c8859d69540f3740505b2afbbe8981 100644 (file)
@@ -1,5 +1,7 @@
-if (ia64_ia32mode) {
-       scno = ia64_regs.gr[0];
-} else {
-       scno = ia64_regs.gr[15];
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = ia64_ia32mode ? ia64_regs.gr[0] : ia64_regs.gr[15];
+       return 1;
 }
index 1a6d28e5e782b1c08388ac08bb01d4e2b4b33671..716a761618571d2a583e0d4cd23a4285f91b1273 100644 (file)
@@ -1,2 +1,6 @@
-if (upeek(tcp->pid, 4*PT_ORIG_D0, &scno) < 0)
-       return -1;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       return upeek(tcp->pid, 4 * PT_ORIG_D0, &tcp->scno) < 0 ? -1 : 1;
+}
index 45cfa48e476e7d3609fbcad84d6fc057c4fce1d1..6dc2ab4abf93ca6bcda263b0bc62f3e7b1687099 100644 (file)
@@ -1 +1,7 @@
-scno = metag_regs.dx[0][1];    /* syscall number in D1Re0 (D1.0) */
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = metag_regs.dx[0][1];  /* syscall number in D1Re0 (D1.0) */
+       return 1;
+}
index cf1d919b01a6980bb0091e98059448477fde03da..6f98f834c21c96f901e22c5fd8fe75a72e72a8d1 100644 (file)
@@ -1,2 +1,6 @@
-if (upeek(tcp->pid, 0, &scno) < 0)
-       return -1;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       return upeek(tcp->pid, 0, &tcp->scno) < 0 ? -1 : 1;
+}
index 126cedecb36f76706087d9d4fd1f16b1848bb458..f9b5e7d710ed56e8bfcebba0dab2b84ede5520d5 100644 (file)
@@ -1,9 +1,17 @@
-scno = mips_REG_V0;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = mips_REG_V0;
 
-if (!SCNO_IN_RANGE(scno)) {
-       if (mips_REG_A3 == 0 || mips_REG_A3 == (uint64_t) -1) {
-               if (debug_flag)
-                       error_msg("stray syscall exit: v0 = %ld", scno);
-               return 0;
+       if (!SCNO_IN_RANGE(tcp->scno)) {
+               if (mips_REG_A3 == 0 || mips_REG_A3 == (uint64_t) -1) {
+                       if (debug_flag)
+                               error_msg("stray syscall exit: v0 = %ld",
+                                         tcp->scno);
+                       return 0;
+               }
        }
+
+       return 1;
 }
index c820bceaf91b07945405c058b14c98dff3cc0f0e..f4db85eed533be80332aebfcacf31d9ed1af6669 100644 (file)
@@ -1 +1,7 @@
-scno = nios2_regs.regs[2];
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = nios2_regs.regs[2];
+       return 1;
+}
index 99fada29239e8bd279d9feceeb1fc574f4c14866..f446c90702e47241116748aeb7d476ad746f2d3c 100644 (file)
@@ -1 +1,7 @@
-scno = or1k_regs.gpr[11];
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = or1k_regs.gpr[11];
+       return 1;
+}
index a311734b3d53c83d9bc2cb6108d4ab7588194dad..ef06656ff38bd1fa8eb7bf70d22f2dfddcfc9c9d 100644 (file)
@@ -1 +1,7 @@
-scno = ppc_regs.gpr[0];
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = ppc_regs.gpr[0];
+       return 1;
+}
index 1e670102464bf0f13b9ae7b9af53de78a6bb4bbf..8a943e8da2f376ec005874407d8631311f4b66a9 100644 (file)
@@ -1,11 +1,15 @@
-scno = ppc_regs.gpr[0];
-unsigned int currpers;
-
-/*
- * Check for 64/32 bit mode.
- * Embedded implementations covered by Book E extension of PPC use
- * bit 0 (CM) of 32-bit Machine state register (MSR).
- * Other implementations use bit 0 (SF) of 64-bit MSR.
- */
-currpers = (ppc_regs.msr & 0x8000000080000000) ? 0 : 1;
-update_personality(tcp, currpers);
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = ppc_regs.gpr[0];
+       /*
+        * Check for 64/32 bit mode.
+        * Embedded implementations covered by Book E extension of PPC use
+        * bit 0 (CM) of 32-bit Machine state register (MSR).
+        * Other implementations use bit 0 (SF) of 64-bit MSR.
+        */
+       unsigned int currpers = (ppc_regs.msr & 0x8000000080000000) ? 0 : 1;
+       update_personality(tcp, currpers);
+       return 1;
+}
index b9e1c19d97e95ade8208870d9e3e3839178ee9ad..8650e1f13f9c7dda35de7929b2dc0c1a90f9bb27 100644 (file)
@@ -1 +1,7 @@
-scno = s390_regset.gprs[2];
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = s390_regset.gprs[2];
+       return 1;
+}
index b8ce272c3ecaa99c8958e85064a43f65345bde35..a9bc5d8fcd59e316af3bfd4e4d4820fd1fa7f475 100644 (file)
@@ -1,17 +1,27 @@
-/*
- * In the new syscall ABI, the system call number is in R3.
- */
-if (upeek(tcp->pid, 4*(REG_REG0+3), &scno) < 0)
-       return -1;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       long scno = 0;
 
-if (scno < 0) {
-       /* Odd as it may seem, a glibc bug has been known to cause
-          glibc to issue bogus negative syscall numbers.  So for
-          our purposes, make strace print what it *should* have been */
-       long correct_scno = (scno & 0xff);
-       if (debug_flag)
-               error_msg("Detected glibc bug: bogus system call"
-                         " number = %ld, correcting to %ld",
-                         scno, correct_scno);
-       scno = correct_scno;
+       /*
+        * In the new syscall ABI, the system call number is in R3.
+        */
+       if (upeek(tcp->pid, 4*(REG_REG0+3), &scno) < 0)
+               return -1;
+
+       if (scno < 0) {
+               /* Odd as it may seem, a glibc bug has been known to cause
+                  glibc to issue bogus negative syscall numbers.  So for
+                  our purposes, make strace print what it *should* have been */
+               long correct_scno = (scno & 0xff);
+               if (debug_flag)
+                       error_msg("Detected glibc bug: bogus system call"
+                                 " number = %ld, correcting to %ld",
+                                 scno, correct_scno);
+               scno = correct_scno;
+       }
+
+       tcp->scno = scno;
+       return 1;
 }
index 9e7ecd431333067a446cd889cb352b05df8d090f..50a52232a8e85f2088eb011f97762b184d079a7f 100644 (file)
@@ -1,3 +1,9 @@
-if (upeek(tcp->pid, REG_SYSCALL, &scno) < 0)
-       return -1;
-scno &= 0xFFFF;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       if (upeek(tcp->pid, REG_SYSCALL, &tcp->scno) < 0)
+               return -1;
+       tcp->scno &= 0xffff;
+       return 1;
+}
index b190b6c574a19712149eb7c5e2f0cf786336fff0..f041259d65a9f0d941841ed7408cf3fe229fbebb 100644 (file)
@@ -1 +1,7 @@
-scno = sparc_regs.u_regs[U_REG_G1];
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       tcp->scno = sparc_regs.u_regs[U_REG_G1];
+       return 1;
+}
index b92366e9d7b319860d3929c2ed9e26397ab02b46..32384e6986238fb47cb3f3b2c3d88006f663bb7a 100644 (file)
@@ -1,19 +1,25 @@
-/* Retrieve the syscall trap instruction. */
-unsigned long trap;
-errno = 0;
-trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)sparc_regs.tpc, 0);
-if (errno)
-       return -1;
-trap >>= 32;
-switch (trap) {
-case 0x91d02010:
-       /* Linux/SPARC syscall trap. */
-       update_personality(tcp, 0);
-       break;
-case 0x91d0206d:
-       /* Linux/SPARC64 syscall trap. */
-       update_personality(tcp, 1);
-       break;
-}
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       /* Retrieve the syscall trap instruction. */
+       unsigned long trap;
+       errno = 0;
+       trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)sparc_regs.tpc, 0);
+       if (errno)
+               return -1;
+       trap >>= 32;
+       switch (trap) {
+       case 0x91d02010:
+               /* Linux/SPARC syscall trap. */
+               update_personality(tcp, 0);
+               break;
+       case 0x91d0206d:
+               /* Linux/SPARC64 syscall trap. */
+               update_personality(tcp, 1);
+               break;
+       }
 
-scno = sparc_regs.u_regs[U_REG_G1];
+       tcp->scno = sparc_regs.u_regs[U_REG_G1];
+       return 1;
+}
index 1ae65c96b258798f0f5cd96b68dd18dac1f3cbab..e8403d9b2423bf9af99d2e37ce002ced9e631304 100644 (file)
@@ -1,17 +1,22 @@
-unsigned int currpers;
-
-scno = tile_regs.regs[10];
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       unsigned int currpers;
 
 #ifdef __tilepro__
-currpers = 1;
+       currpers = 1;
 #else
 # ifndef PT_FLAGS_COMPAT
 #  define PT_FLAGS_COMPAT 0x10000  /* from Linux 3.8 on */
 # endif
-if (tile_regs.flags & PT_FLAGS_COMPAT)
-       currpers = 1;
-else
-       currpers = 0;
+       if (tile_regs.flags & PT_FLAGS_COMPAT)
+               currpers = 1;
+       else
+               currpers = 0;
 #endif
+       update_personality(tcp, currpers);
+       tcp->scno = tile_regs.regs[10];
 
-update_personality(tcp, currpers);
+       return 1;
+}
index 02ff0a734387939c418ee42d01713a3c4a086aac..8b163de5968c3b295ca822ffd4449b4e437b2cb0 100644 (file)
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       long scno = 0;
+       unsigned int currpers;
+
 #ifndef __X32_SYSCALL_BIT
 # define __X32_SYSCALL_BIT     0x40000000
 #endif
 
-unsigned int currpers;
-
 #if 1
-/* GETREGSET of NT_PRSTATUS tells us regset size,
- * which unambiguously detects i386.
- *
- * Linux kernel distinguishes x86-64 and x32 processes
- * solely by looking at __X32_SYSCALL_BIT:
- * arch/x86/include/asm/compat.h::is_x32_task():
- * if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
- *         return true;
- */
-if (x86_io.iov_len == sizeof(i386_regs)) {
-       scno = i386_regs.orig_eax;
-       currpers = 1;
-} else {
-       scno = x86_64_regs.orig_rax;
-       currpers = 0;
-       if (scno & __X32_SYSCALL_BIT) {
-               /*
-                * Syscall number -1 requires special treatment:
-                * it might be a side effect of SECCOMP_RET_ERRNO
-                * filtering that sets orig_rax to -1
-                * in some versions of linux kernel.
-                * If that is the case, then
-                * __X32_SYSCALL_BIT logic does not apply.
-                */
-               if ((long long) x86_64_regs.orig_rax != -1) {
-                       scno -= __X32_SYSCALL_BIT;
-                       currpers = 2;
-               } else {
+       /*
+        * GETREGSET of NT_PRSTATUS tells us regset size,
+        * which unambiguously detects i386.
+        *
+        * Linux kernel distinguishes x86-64 and x32 processes
+        * solely by looking at __X32_SYSCALL_BIT:
+        * arch/x86/include/asm/compat.h::is_x32_task():
+        * if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
+        *         return true;
+        */
+       if (x86_io.iov_len == sizeof(i386_regs)) {
+               scno = i386_regs.orig_eax;
+               currpers = 1;
+       } else {
+               scno = x86_64_regs.orig_rax;
+               currpers = 0;
+               if (scno & __X32_SYSCALL_BIT) {
+                       /*
+                        * Syscall number -1 requires special treatment:
+                        * it might be a side effect of SECCOMP_RET_ERRNO
+                        * filtering that sets orig_rax to -1
+                        * in some versions of linux kernel.
+                        * If that is the case, then
+                        * __X32_SYSCALL_BIT logic does not apply.
+                        */
+                       if ((long long) x86_64_regs.orig_rax != -1) {
+                               scno -= __X32_SYSCALL_BIT;
+                               currpers = 2;
+                       } else {
 # ifdef X32
-                       currpers = 2;
+                               currpers = 2;
 # endif
+                       }
                }
        }
-}
 
 #elif 0
-/* cs = 0x33 for long mode (native 64 bit and x32)
- * cs = 0x23 for compatibility mode (32 bit)
- * ds = 0x2b for x32 mode (x86-64 in 32 bit)
- */
-scno = x86_64_regs.orig_rax;
-switch (x86_64_regs.cs) {
-       case 0x23: currpers = 1; break;
-       case 0x33:
-               if (x86_64_regs.ds == 0x2b) {
-                       currpers = 2;
-                       scno &= ~__X32_SYSCALL_BIT;
-               } else
-                       currpers = 0;
-               break;
-       default:
-               error_msg("Unknown value CS=0x%08X while "
-                         "detecting personality of process PID=%d",
-                         (int)x86_64_regs.cs, tcp->pid);
-               currpers = current_personality;
-               break;
-}
+       /*
+        * cs = 0x33 for long mode (native 64 bit and x32)
+        * cs = 0x23 for compatibility mode (32 bit)
+        * ds = 0x2b for x32 mode (x86-64 in 32 bit)
+        */
+       scno = x86_64_regs.orig_rax;
+       switch (x86_64_regs.cs) {
+               case 0x23: currpers = 1; break;
+               case 0x33:
+                       if (x86_64_regs.ds == 0x2b) {
+                               currpers = 2;
+                               scno &= ~__X32_SYSCALL_BIT;
+                       } else
+                               currpers = 0;
+                       break;
+               default:
+                       error_msg("Unknown value CS=0x%08X while "
+                                 "detecting personality of process PID=%d",
+                                 (int)x86_64_regs.cs, tcp->pid);
+                       currpers = current_personality;
+                       break;
+       }
 #elif 0
-/* This version analyzes the opcode of a syscall instruction.
- * (int 0x80 on i386 vs. syscall on x86-64)
- * It works, but is too complicated, and strictly speaking, unreliable.
- */
-unsigned long call, rip = x86_64_regs.rip;
-/* sizeof(syscall) == sizeof(int 0x80) == 2 */
-rip -= 2;
-errno = 0;
-call = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)rip, (char *)0);
-if (errno)
-       perror_msg("ptrace_peektext failed");
-switch (call & 0xffff) {
-       /* x86-64: syscall = 0x0f 0x05 */
-       case 0x050f: currpers = 0; break;
-       /* i386: int 0x80 = 0xcd 0x80 */
-       case 0x80cd: currpers = 1; break;
-       default:
-               currpers = current_personality;
-               error_msg("Unknown syscall opcode (0x%04X) while "
-                         "detecting personality of process PID=%d",
-                         (int)call, tcp->pid);
-               break;
-}
+       /*
+        * This version analyzes the opcode of a syscall instruction.
+        * (int 0x80 on i386 vs. syscall on x86-64)
+        * It works, but is too complicated, and strictly speaking, unreliable.
+        */
+       unsigned long call, rip = x86_64_regs.rip;
+       /* sizeof(syscall) == sizeof(int 0x80) == 2 */
+       rip -= 2;
+       errno = 0;
+       call = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)rip, (char *)0);
+       if (errno)
+               perror_msg("ptrace_peektext failed");
+       switch (call & 0xffff) {
+               /* x86-64: syscall = 0x0f 0x05 */
+               case 0x050f: currpers = 0; break;
+               /* i386: int 0x80 = 0xcd 0x80 */
+               case 0x80cd: currpers = 1; break;
+               default:
+                       currpers = current_personality;
+                       error_msg("Unknown syscall opcode (0x%04X) while "
+                                 "detecting personality of process PID=%d",
+                                 (int)call, tcp->pid);
+                       break;
+       }
 #endif
 
 #ifdef X32
-/* If we are built for a x32 system, then personality 0 is x32
- * (not x86_64), and stracing of x86_64 apps is not supported.
- * Stracing of i386 apps is still supported.
- */
-if (currpers == 0) {
-       error_msg("syscall_%lu(...) in unsupported "
-                 "64-bit mode of process PID=%d", scno, tcp->pid);
-       return 0;
-}
-currpers &= ~2; /* map 2,1 to 0,1 */
+       /*
+        * If we are built for a x32 system, then personality 0 is x32
+        * (not x86_64), and stracing of x86_64 apps is not supported.
+        * Stracing of i386 apps is still supported.
+        */
+       if (currpers == 0) {
+               error_msg("syscall_%lu(...) in unsupported "
+                         "64-bit mode of process PID=%d", scno, tcp->pid);
+               return 0;
+       }
+       currpers &= ~2; /* map 2,1 to 0,1 */
 #endif /* X32 */
 
-update_personality(tcp, currpers);
+       update_personality(tcp, currpers);
+       tcp->scno = scno;
+       return 1;
+}
index 4299163051e86659bca7069d65e68e4886382f3a..d230f73bdb75b44dcb4754fc49856e556010c99b 100644 (file)
@@ -1,2 +1,6 @@
-if (upeek(tcp->pid, SYSCALL_NR, &scno) < 0)
-       return -1;
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+       return upeek(tcp->pid, SYSCALL_NR, &tcp->scno) < 0 ? -1 : 1;
+}
index 91bd4fa9fb73de2bd3c39f65e4bd709ee9d6d217..3f43a57d04baecf54403aa175cafb9c6033b44a3 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -1302,7 +1302,11 @@ get_regs(pid_t pid)
 #endif
 }
 
-/* Returns:
+static int arch_get_scno(struct tcb *tcp);
+#include "get_scno.c"
+
+/*
+ * Returns:
  * 0: "ignore this ptrace stop", bail out of trace_syscall_entering() silently.
  * 1: ok, continue in trace_syscall_entering().
  * other: error, trace_syscall_entering() should print error indicator
@@ -1314,14 +1318,13 @@ get_scno(struct tcb *tcp)
        if (get_regs_error)
                return -1;
 
-       long scno = 0;
-
-#include "get_scno.c"
+       int rc = arch_get_scno(tcp);
+       if (rc != 1)
+               return rc;
 
-       tcp->scno = scno;
        if (SCNO_IS_VALID(tcp->scno)) {
-               tcp->s_ent = &sysent[scno];
-               tcp->qual_flg = qual_flags[scno];
+               tcp->s_ent = &sysent[tcp->scno];
+               tcp->qual_flg = qual_flags[tcp->scno];
        } else {
                static const struct_sysent unknown = {
                        .nargs = MAX_ARGS,
@@ -1332,7 +1335,7 @@ get_scno(struct tcb *tcp)
                tcp->s_ent = &unknown;
                tcp->qual_flg = UNDEFINED_SCNO | QUAL_RAW | DEFAULT_QUAL_FLAGS;
                if (debug_flag)
-                       error_msg("pid %d invalid syscall %ld", tcp->pid, scno);
+                       error_msg("pid %d invalid syscall %ld", tcp->pid, tcp->scno);
        }
        return 1;
 }