(root)/
strace-6.5/
tests/
prctl-tid_address.c
       1  /*
       2   * Check decoding of prctl PR_GET_TID_ADDRESS operation.
       3   *
       4   * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
       5   * Copyright (c) 2016-2021 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include "scno.h"
      13  
      14  #include <inttypes.h>
      15  #include <stdio.h>
      16  #include <unistd.h>
      17  #include <linux/prctl.h>
      18  
      19  static const char *
      20  sprintaddr(kernel_ulong_t addr)
      21  {
      22  	static char buf[sizeof("0x") + sizeof(addr) * 2];
      23  
      24  	if (addr) {
      25  		snprintf(buf, sizeof(buf), "%#llx", (unsigned long long) addr);
      26  
      27  		return buf;
      28  	}
      29  
      30  	return "NULL";
      31  }
      32  
      33  int
      34  main(void)
      35  {
      36  	static const kernel_ulong_t bogus_addr =
      37  		(kernel_ulong_t) 0xfffffffffffffffdULL;
      38  
      39  	/* Note that kernel puts kernel-sized pointer even on x32 */
      40  	TAIL_ALLOC_OBJECT_CONST_PTR(kernel_ulong_t, ptr);
      41  	long rc;
      42  	long set_ok;
      43  
      44  	prctl_marker();
      45  
      46  	*ptr = (kernel_ulong_t) 0xbadc0dedda7a1057ULL;
      47  
      48  	rc = syscall(__NR_prctl, PR_GET_TID_ADDRESS, NULL);
      49  	printf("prctl(PR_GET_TID_ADDRESS, NULL) = %s\n", sprintrc(rc));
      50  
      51  	rc = syscall(__NR_prctl, PR_GET_TID_ADDRESS, bogus_addr);
      52  	printf("prctl(PR_GET_TID_ADDRESS, %#llx) = %s\n",
      53  	       (unsigned long long) bogus_addr, sprintrc(rc));
      54  
      55  	rc = syscall(__NR_prctl, PR_GET_TID_ADDRESS, ptr);
      56  	if (rc) {
      57  		printf("prctl(PR_GET_TID_ADDRESS, %p) = %s\n",
      58  		       ptr, sprintrc(rc));
      59  	} else {
      60  		printf("prctl(PR_GET_TID_ADDRESS, [%s]) = %s\n",
      61  		       sprintaddr(*ptr), sprintrc(rc));
      62  	}
      63  
      64  	set_ok = syscall(__NR_set_tid_address, bogus_addr);
      65  
      66  	rc = syscall(__NR_prctl, PR_GET_TID_ADDRESS, ptr);
      67  	if (rc) {
      68  		printf("prctl(PR_GET_TID_ADDRESS, %p) = %s\n",
      69  		       ptr, sprintrc(rc));
      70  	} else {
      71  		printf("prctl(PR_GET_TID_ADDRESS, [%s]) = %s\n",
      72  		       sprintaddr(set_ok ? bogus_addr : *ptr), sprintrc(rc));
      73  	}
      74  
      75  	puts("+++ exited with 0 +++");
      76  	return 0;
      77  }