elf: Make glibc.rtld.enable_secure ignore alias environment variables
[glibc.git] / elf / tst-decorate-maps.c
blob6d04344ba26184c3cd54bcb3b4e97704571972e2
1 /* Check the VMA name decoration.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <stdlib.h>
20 #include <string.h>
21 #include <support/check.h>
22 #include <support/support.h>
23 #include <support/test-driver.h>
24 #include <support/xstdio.h>
25 #include <support/xthread.h>
26 #include <support/xunistd.h>
27 #include <sys/mman.h>
29 #ifndef MAP_STACK
30 # define MAP_STACK 0
31 #endif
33 static pthread_barrier_t b;
35 static int expected_n_arenas;
37 static void *
38 tf (void *closure)
40 void *p = xmalloc (1024);
42 /* Wait the thread startup, so thread stack is allocated. */
43 xpthread_barrier_wait (&b);
45 /* Wait the test to read the process mapping. */
46 xpthread_barrier_wait (&b);
48 free (p);
50 return NULL;
53 struct proc_maps_t
55 int n_def_threads;
56 int n_user_threads;
57 int n_arenas;
58 int n_malloc_mmap;
61 static struct proc_maps_t
62 read_proc_maps (void)
64 if (test_verbose)
65 printf ("=== print process %jd memory mapping ===\n",
66 (intmax_t) getpid ());
67 struct proc_maps_t r = { 0 };
69 FILE *f = xfopen ("/proc/self/maps", "r");
70 char *line = NULL;
71 size_t line_len = 0;
72 while (xgetline (&line, &line_len, f))
74 if (test_verbose)
75 printf ("%s", line);
76 if (strstr (line, "[anon: glibc: pthread stack:") != NULL)
77 r.n_def_threads++;
78 else if (strstr (line, "[anon: glibc: pthread user stack:") != NULL)
79 r.n_user_threads++;
80 else if (strstr (line, "[anon: glibc: malloc arena]") != NULL)
81 r.n_arenas++;
82 else if (strstr (line, "[anon: glibc: malloc]") != NULL)
83 r.n_malloc_mmap++;
84 /* On some architectures and depending on the page size, the loader can
85 also allocate some memory during dependencies loading and it will be
86 marked as 'loader malloc'. However, if the system page size is large
87 enough, the initial data page will be enough for all required
88 allocation and there will be no extra loader mmap. To avoid false
89 negatives, the test does not check for such pages. */
91 free (line);
92 xfclose (f);
94 if (test_verbose)
95 printf ("===\n");
96 return r;
99 static void
100 do_test_threads (bool set_guard)
102 enum
104 num_def_threads = 8,
105 num_user_threads = 2,
106 num_threads = num_def_threads + num_user_threads,
109 xpthread_barrier_init (&b, NULL, num_threads + 1);
111 /* Issue a large malloc to trigger a mmap call. */
112 void *p = xmalloc (256 * 1024);
114 pthread_t thr[num_threads];
116 int i = 0;
117 for (; i < num_threads - num_user_threads; i++)
119 pthread_attr_t attr;
120 xpthread_attr_init (&attr);
121 /* The guard page is not annotated. */
122 if (!set_guard)
123 xpthread_attr_setguardsize (&attr, 0);
124 thr[i] = xpthread_create (&attr, tf, NULL);
125 xpthread_attr_destroy (&attr);
127 for (; i < num_threads; i++)
129 pthread_attr_t attr;
130 xpthread_attr_init (&attr);
131 size_t stacksize = support_small_thread_stack_size ();
132 void *stack = xmmap (0,
133 stacksize,
134 PROT_READ | PROT_WRITE,
135 MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK,
136 -1);
137 xpthread_attr_setstack (&attr, stack, stacksize);
138 if (!set_guard)
139 xpthread_attr_setguardsize (&attr, 0);
140 thr[i] = xpthread_create (&attr, tf, NULL);
141 xpthread_attr_destroy (&attr);
145 /* Wait all threads to finshed statup and stack allocation. */
146 xpthread_barrier_wait (&b);
149 struct proc_maps_t r = read_proc_maps ();
150 TEST_COMPARE (r.n_def_threads, num_def_threads);
151 TEST_COMPARE (r.n_user_threads, num_user_threads);
152 TEST_COMPARE (r.n_arenas, expected_n_arenas);
153 TEST_COMPARE (r.n_malloc_mmap, 1);
156 /* Let the threads finish. */
157 xpthread_barrier_wait (&b);
159 for (int i = 0; i < num_threads; i++)
160 xpthread_join (thr[i]);
163 struct proc_maps_t r = read_proc_maps ();
164 TEST_COMPARE (r.n_def_threads, 0);
165 TEST_COMPARE (r.n_user_threads, 0);
166 TEST_COMPARE (r.n_arenas, expected_n_arenas);
167 TEST_COMPARE (r.n_malloc_mmap, 1);
170 free (p);
173 static void
174 do_prepare (int argc, char *argv[])
176 TEST_VERIFY_EXIT (argc == 2);
177 expected_n_arenas = strtol (argv[1], NULL, 10);
178 expected_n_arenas = expected_n_arenas - 1;
180 #define PREPARE do_prepare
182 static int
183 do_test (void)
185 support_need_proc ("Reads /proc/self/maps to get stack names.");
187 if (!support_set_vma_name_supported ())
188 FAIL_UNSUPPORTED ("kernel does not support PR_SET_VMA_ANON_NAME");
190 do_test_threads (false);
191 do_test_threads (true);
193 return 0;
196 #include <support/test-driver.c>