(root)/
strace-6.5/
src/
execve.c
       1  /*
       2   * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
       3   * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
       4   * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
       5   * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
       6   * Copyright (c) 2007 Roland McGrath <roland@redhat.com>
       7   * Copyright (c) 2011-2012 Denys Vlasenko <vda.linux@googlemail.com>
       8   * Copyright (c) 2010-2015 Dmitry V. Levin <ldv@strace.io>
       9   * Copyright (c) 2014-2021 The strace developers.
      10   * All rights reserved.
      11   *
      12   * SPDX-License-Identifier: LGPL-2.1-or-later
      13   */
      14  
      15  #include "defs.h"
      16  
      17  static void
      18  printargv(struct tcb *const tcp, kernel_ulong_t addr)
      19  {
      20  	if (!addr || !verbose(tcp)) {
      21  		printaddr(addr);
      22  		return;
      23  	}
      24  
      25  	const unsigned int wordsize = current_wordsize;
      26  	kernel_ulong_t prev_addr = 0;
      27  	unsigned int n = 0;
      28  
      29  	for (;; prev_addr = addr, addr += wordsize, ++n) {
      30  		union {
      31  			unsigned int w32;
      32  			kernel_ulong_t wl;
      33  			char data[sizeof(kernel_ulong_t)];
      34  		} cp;
      35  
      36  		if (addr < prev_addr || umoven(tcp, addr, wordsize, cp.data)) {
      37  			if (n == 0) {
      38  				printaddr(addr);
      39  				return;
      40  			}
      41  			tprint_array_next();
      42  			tprint_more_data_follows();
      43  			printaddr_comment(addr);
      44  			break;
      45  		}
      46  
      47  		const kernel_ulong_t word = (wordsize == sizeof(cp.w32))
      48  					    ? (kernel_ulong_t) cp.w32 : cp.wl;
      49  		if (n == 0)
      50  			tprint_array_begin();
      51  		if (word == 0)
      52  			break;
      53  		if (n != 0)
      54  			tprint_array_next();
      55  
      56  		if (abbrev(tcp) && n >= max_strlen) {
      57  			tprint_more_data_follows();
      58  			break;
      59  		}
      60  
      61  		printstr(tcp, word);
      62  	}
      63  
      64  	tprint_array_end();
      65  }
      66  
      67  static void
      68  printargc(struct tcb *const tcp, kernel_ulong_t addr)
      69  {
      70  	printaddr(addr);
      71  
      72  	if (!addr || !verbose(tcp))
      73  		return;
      74  
      75  	const unsigned int wordsize = current_wordsize;
      76  	kernel_ulong_t prev_addr = 0;
      77  	unsigned int n;
      78  
      79  	for (n = 0; addr > prev_addr; prev_addr = addr, addr += wordsize, ++n) {
      80  		kernel_ulong_t word = 0;
      81  		if (umoven(tcp, addr, wordsize, &word)) {
      82  			if (n == 0)
      83  				return;
      84  
      85  			addr = 0;
      86  			break;
      87  		}
      88  		if (word == 0)
      89  			break;
      90  	}
      91  	tprintf_comment("%u var%s%s",
      92  			n, n == 1 ? "" : "s",
      93  			addr < prev_addr ? ", unterminated" : "");
      94  }
      95  
      96  static void
      97  decode_execve(struct tcb *tcp, const unsigned int index)
      98  {
      99  	/* pathname */
     100  	printpath(tcp, tcp->u_arg[index + 0]);
     101  	tprint_arg_next();
     102  
     103  	/* argv */
     104  	printargv(tcp, tcp->u_arg[index + 1]);
     105  	tprint_arg_next();
     106  
     107  	/* envp */
     108  	(abbrev(tcp) ? printargc : printargv) (tcp, tcp->u_arg[index + 2]);
     109  }
     110  
     111  SYS_FUNC(execve)
     112  {
     113  	decode_execve(tcp, 0);
     114  
     115  	return RVAL_DECODED;
     116  }
     117  
     118  SYS_FUNC(execveat)
     119  {
     120  	/* dirfd */
     121  	print_dirfd(tcp, tcp->u_arg[0]);
     122  	tprint_arg_next();
     123  
     124  	/* pathname, argv, envp */
     125  	decode_execve(tcp, 1);
     126  	tprint_arg_next();
     127  
     128  	/* flags */
     129  	printflags(at_flags, tcp->u_arg[4], "AT_???");
     130  
     131  	return RVAL_DECODED;
     132  }
     133  
     134  #if defined(SPARC) || defined(SPARC64)
     135  SYS_FUNC(execv)
     136  {
     137  	/* pathname */
     138  	printpath(tcp, tcp->u_arg[0]);
     139  	tprint_arg_next();
     140  
     141  	/* argv */
     142  	printargv(tcp, tcp->u_arg[1]);
     143  
     144  	return RVAL_DECODED;
     145  }
     146  #endif /* SPARC || SPARC64 */