(root)/
strace-6.5/
src/
linux/
mips/
get_syscall_args.c
       1  /*
       2   * Copyright (c) 2015-2021 The strace developers.
       3   * All rights reserved.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   */
       7  
       8  /* Return -1 on error or 1 on success (never 0!). */
       9  static int
      10  arch_get_syscall_args(struct tcb *tcp)
      11  {
      12  #if defined LINUX_MIPSN64 || defined LINUX_MIPSN32
      13  	tcp->u_arg[0] = mips_REG_A0;
      14  	tcp->u_arg[1] = mips_REG_A1;
      15  	tcp->u_arg[2] = mips_REG_A2;
      16  	tcp->u_arg[3] = mips_REG_A3;
      17  	tcp->u_arg[4] = mips_REG_A4;
      18  	tcp->u_arg[5] = mips_REG_A5;
      19  #elif defined LINUX_MIPSO32
      20  	tcp->u_arg[0] = mips_REG_A0;
      21  	tcp->u_arg[1] = mips_REG_A1;
      22  	tcp->u_arg[2] = mips_REG_A2;
      23  	tcp->u_arg[3] = mips_REG_A3;
      24  	if (n_args(tcp) > 4
      25  	    && umoven(tcp, mips_REG_SP + 4 * sizeof(tcp->u_arg[0]),
      26  		      (n_args(tcp) - 4) * sizeof(tcp->u_arg[0]),
      27  		      &tcp->u_arg[4]) < 0) {
      28  		error_msg("pid %d: cannot fetch 5th and 6th syscall arguments"
      29  			  " from tracee's memory", tcp->pid);
      30  
      31  		/*
      32  		 * Let's proceed with the first 4 arguments
      33  		 * instead of reporting the failure.
      34  		 */
      35  		memset(&tcp->u_arg[4], 0,
      36  		       (n_args(tcp) - 4) * sizeof(tcp->u_arg[0]));
      37  	}
      38  #else
      39  # error unsupported mips abi
      40  #endif
      41  	return 1;
      42  }
      43  
      44  #ifdef LINUX_MIPSO32
      45  static void
      46  arch_get_syscall_args_extra(struct tcb *tcp, const unsigned int n)
      47  {
      48  	/* This assumes n >= 4. */
      49  	if (n_args(tcp) > n
      50  	    && umoven(tcp, mips_REG_SP + n * sizeof(tcp->u_arg[0]),
      51  		      (n_args(tcp) - n) * sizeof(tcp->u_arg[0]),
      52  		      &tcp->u_arg[n]) < 0) {
      53  		/*
      54  		 * Let's proceed with the first n arguments
      55  		 * instead of reporting the failure.
      56  		 */
      57  		memset(&tcp->u_arg[n], 0,
      58  		       (n_args(tcp) - n) * sizeof(tcp->u_arg[0]));
      59  	}
      60  }
      61  #endif
      62  
      63  #ifdef SYS_syscall_subcall
      64  static void
      65  decode_syscall_subcall(struct tcb *tcp)
      66  {
      67  	if (!scno_is_valid(tcp->u_arg[0]))
      68  		return;
      69  	tcp->true_scno = tcp->scno = tcp->u_arg[0];
      70  	tcp->qual_flg = qual_flags(tcp->scno);
      71  	tcp->s_ent = &sysent[tcp->scno];
      72  	memmove(&tcp->u_arg[0], &tcp->u_arg[1],
      73  		sizeof(tcp->u_arg) - sizeof(tcp->u_arg[0]));
      74  	/*
      75  	 * Fetching the last arg of 7-arg syscalls (fadvise64_64
      76  	 * and sync_file_range) requires additional code,
      77  	 * see arch_get_syscall_args() above.
      78  	 */
      79  	if (n_args(tcp) == MAX_ARGS) {
      80  		if (umoven(tcp,
      81  			   mips_REG_SP + MAX_ARGS * sizeof(tcp->u_arg[0]),
      82  			   sizeof(tcp->u_arg[0]),
      83  			   &tcp->u_arg[MAX_ARGS - 1]) < 0)
      84  		tcp->u_arg[MAX_ARGS - 1] = 0;
      85  	}
      86  }
      87  #endif /* SYS_syscall_subcall */