(root)/
strace-6.5/
src/
linux/
x86_64/
get_scno.c
       1  /*
       2   * Copyright (c) 2002 Andi Kleen <ak@suse.de>
       3   * Copyright (c) 2002 Michal Ludvig <mludvig@suse.cz>
       4   * Copyright (c) 2002 Roland McGrath <roland@redhat.com>
       5   * Copyright (c) 2008-2013 Denys Vlasenko <vda.linux@googlemail.com>
       6   * Copyright (c) 2012 H.J. Lu <hongjiu.lu@intel.com>
       7   * Copyright (c) 2010-2015 Dmitry V. Levin <ldv@strace.io>
       8   * Copyright (c) 2015-2021 The strace developers.
       9   * All rights reserved.
      10   *
      11   * SPDX-License-Identifier: LGPL-2.1-or-later
      12   */
      13  
      14  /* Return codes: 1 - ok, 0 - ignore, other - error. */
      15  static int
      16  arch_get_scno(struct tcb *tcp)
      17  {
      18  	kernel_ulong_t scno = 0;
      19  	unsigned int currpers;
      20  
      21  	/*
      22  	 * GETREGSET of NT_PRSTATUS tells us regset size,
      23  	 * which unambiguously detects i386.
      24  	 *
      25  	 * Linux kernel distinguishes x86-64 and x32 processes
      26  	 * solely by looking at __X32_SYSCALL_BIT:
      27  	 * arch/x86/include/asm/compat.h::is_x32_task():
      28  	 * if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
      29  	 *	return true;
      30  	 */
      31  	if (x86_io.iov_len == sizeof(i386_regs)) {
      32  		scno = i386_regs.orig_eax;
      33  		currpers = 1;
      34  	} else {
      35  		scno = x86_64_regs.orig_rax;
      36  		currpers = 0;
      37  		if (scno & __X32_SYSCALL_BIT) {
      38  			/*
      39  			 * Syscall number -1 requires special treatment:
      40  			 * it might be a side effect of SECCOMP_RET_ERRNO
      41  			 * filtering that sets orig_rax to -1
      42  			 * in some versions of linux kernel.
      43  			 * If that is the case, then
      44  			 * __X32_SYSCALL_BIT logic does not apply.
      45  			 */
      46  			if ((long long) x86_64_regs.orig_rax != -1) {
      47  				currpers = 2;
      48  			} else {
      49  #ifdef X32
      50  				currpers = 2;
      51  #endif
      52  			}
      53  		}
      54  	}
      55  
      56  #ifdef X32
      57  	/*
      58  	 * If we are built for a x32 system, then personality 0 is x32
      59  	 * (not x86_64), and stracing of x86_64 apps is not supported.
      60  	 * Stracing of i386 apps is still supported.
      61  	 */
      62  	if (currpers == 0) {
      63  		error_msg("syscall_%" PRI_klu "(...) in unsupported "
      64  			  "64-bit mode of process PID=%d", scno, tcp->pid);
      65  		return 0;
      66  	}
      67  	currpers &= ~2; /* map 2,1 to 0,1 */
      68  #endif /* X32 */
      69  
      70  	update_personality(tcp, currpers);
      71  	tcp->scno = scno;
      72  	return 1;
      73  }