]> granicus.if.org Git - strace/blob - tests/prctl-tid_address.c
Update copyright headers
[strace] / 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-2018 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 <asm/unistd.h>
13 #include <linux/prctl.h>
14
15 #if defined __NR_prctl && defined __NR_set_tid_address && \
16         defined PR_GET_TID_ADDRESS
17
18 # include <inttypes.h>
19 # include <stdio.h>
20 # include <unistd.h>
21
22 static const char *
23 sprintaddr(kernel_ulong_t addr)
24 {
25         static char buf[sizeof("0x") + sizeof(addr) * 2];
26
27         if (addr) {
28                 snprintf(buf, sizeof(buf), "%#llx", (unsigned long long) addr);
29
30                 return buf;
31         }
32
33         return "NULL";
34 }
35
36 int
37 main(void)
38 {
39         static const kernel_ulong_t bogus_addr =
40                 (kernel_ulong_t) 0xfffffffffffffffdULL;
41
42         /* Note that kernel puts kernel-sized pointer even on x32 */
43         TAIL_ALLOC_OBJECT_CONST_PTR(kernel_ulong_t, ptr);
44         long rc;
45         long set_ok;
46
47         *ptr = (kernel_ulong_t) 0xbadc0dedda7a1057ULL;
48
49         rc = syscall(__NR_prctl, PR_GET_TID_ADDRESS, NULL);
50         printf("prctl(PR_GET_TID_ADDRESS, NULL) = %s\n", sprintrc(rc));
51
52         rc = syscall(__NR_prctl, PR_GET_TID_ADDRESS, bogus_addr);
53         printf("prctl(PR_GET_TID_ADDRESS, %#llx) = %s\n",
54                (unsigned long long) bogus_addr, sprintrc(rc));
55
56         rc = syscall(__NR_prctl, PR_GET_TID_ADDRESS, ptr);
57         if (rc) {
58                 printf("prctl(PR_GET_TID_ADDRESS, %p) = %s\n",
59                        ptr, sprintrc(rc));
60         } else {
61                 printf("prctl(PR_GET_TID_ADDRESS, [%s]) = %s\n",
62                        sprintaddr(*ptr), sprintrc(rc));
63         }
64
65         set_ok = syscall(__NR_set_tid_address, bogus_addr);
66
67         rc = syscall(__NR_prctl, PR_GET_TID_ADDRESS, ptr);
68         if (rc) {
69                 printf("prctl(PR_GET_TID_ADDRESS, %p) = %s\n",
70                        ptr, sprintrc(rc));
71         } else {
72                 printf("prctl(PR_GET_TID_ADDRESS, [%s]) = %s\n",
73                        sprintaddr(set_ok ? bogus_addr : *ptr), sprintrc(rc));
74         }
75
76         puts("+++ exited with 0 +++");
77         return 0;
78 }
79
80 #else
81
82 SKIP_MAIN_UNDEFINED("__NR_prctl && __NR_set_tid_address && PR_GET_TID_ADDRESS")
83
84 #endif