]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-misc.c
manual: Remove '.info' suffix in manual names passed to @ref [BZ #32962].
[thirdparty/glibc.git] / elf / dl-misc.c
CommitLineData
0501d603 1/* Miscellaneous support functions for dynamic linker
26420023 2 Copyright (C) 1997-2025 Free Software Foundation, Inc.
9498096c
UD
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
9498096c
UD
9
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
41bdb6e2 13 Lesser General Public License for more details.
9498096c 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
9498096c 18
b693d75f 19#include <_itoa.h>
0501d603 20#include <fcntl.h>
48896b9d 21#include <ldsodefs.h>
fc7f617d 22#include <link.h>
b693d75f 23#include <not-cancel.h>
e054f494 24#include <stdint.h>
b693d75f 25#include <stdlib.h>
0501d603
UD
26#include <sys/mman.h>
27#include <sys/stat.h>
b693d75f 28#include <unistd.h>
0501d603 29
0501d603 30/* Read the whole contents of FILE into new mmap'd space with given
40b07f5b
UD
31 protections. *SIZEP gets the size of the file. On error MAP_FAILED
32 is returned. */
0501d603
UD
33
34void *
35_dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
36{
40b07f5b 37 void *result = MAP_FAILED;
52a5fe70 38 struct __stat64_t64 st;
329ea513 39 int fd = __open64_nocancel (file, O_RDONLY | O_CLOEXEC);
40b07f5b 40 if (fd >= 0)
0501d603 41 {
52a5fe70 42 if (__fstat64_time64 (fd, &st) >= 0)
40b07f5b
UD
43 {
44 *sizep = st.st_size;
45
46 /* No need to map the file if it is empty. */
47 if (*sizep != 0)
48 /* Map a copy of the file contents. */
49 result = __mmap (NULL, *sizep, prot,
0501d603 50#ifdef MAP_COPY
40b07f5b 51 MAP_COPY
0501d603 52#else
40b07f5b 53 MAP_PRIVATE
0501d603
UD
54#endif
55#ifdef MAP_FILE
40b07f5b 56 | MAP_FILE
0501d603 57#endif
40b07f5b
UD
58 , fd, 0);
59 }
329ea513 60 __close_nocancel (fd);
0501d603 61 }
0501d603
UD
62 return result;
63}
9498096c 64
dd272e57
UD
65/* Test whether given NAME matches any of the names of the given object. */
66int
871b9158 67_dl_name_match_p (const char *name, const struct link_map *map)
dd272e57
UD
68{
69 if (strcmp (name, map->l_name) == 0)
70 return 1;
71
72 struct libname_list *runp = map->l_libname;
73
74 while (runp != NULL)
75 if (strcmp (name, runp->name) == 0)
76 return 1;
77 else
bdaf5003 78 runp = runp->next;
dd272e57
UD
79
80 return 0;
81}
eba0994e 82
eba0994e
UD
83unsigned long int
84_dl_higher_prime_number (unsigned long int n)
85{
86 /* These are primes that are near, but slightly smaller than, a
87 power of two. */
88 static const uint32_t primes[] = {
89 UINT32_C (7),
90 UINT32_C (13),
91 UINT32_C (31),
92 UINT32_C (61),
93 UINT32_C (127),
94 UINT32_C (251),
95 UINT32_C (509),
96 UINT32_C (1021),
97 UINT32_C (2039),
98 UINT32_C (4093),
99 UINT32_C (8191),
100 UINT32_C (16381),
101 UINT32_C (32749),
102 UINT32_C (65521),
103 UINT32_C (131071),
104 UINT32_C (262139),
105 UINT32_C (524287),
106 UINT32_C (1048573),
107 UINT32_C (2097143),
108 UINT32_C (4194301),
109 UINT32_C (8388593),
110 UINT32_C (16777213),
111 UINT32_C (33554393),
112 UINT32_C (67108859),
113 UINT32_C (134217689),
114 UINT32_C (268435399),
115 UINT32_C (536870909),
116 UINT32_C (1073741789),
117 UINT32_C (2147483647),
554881ef 118 /* 4294967291L */
eba0994e
UD
119 UINT32_C (2147483647) + UINT32_C (2147483644)
120 };
121
122 const uint32_t *low = &primes[0];
123 const uint32_t *high = &primes[sizeof (primes) / sizeof (primes[0])];
124
125 while (low != high)
126 {
127 const uint32_t *mid = low + (high - low) / 2;
128 if (n > *mid)
129 low = mid + 1;
130 else
131 high = mid;
132 }
133
134#if 0
135 /* If we've run out of primes, abort. */
136 if (n > *low)
137 {
138 fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
139 abort ();
140 }
141#endif
142
143 return *low;
144}
37b66c0b
L
145
146/* A stripped down strtoul-like implementation for very early use. It
147 does not set errno if the result is outside bounds because it may get
148 called before errno may have been set up. */
149
150uint64_t
37b66c0b
L
151_dl_strtoul (const char *nptr, char **endptr)
152{
153 uint64_t result = 0;
154 bool positive = true;
155 unsigned max_digit;
156
157 while (*nptr == ' ' || *nptr == '\t')
158 ++nptr;
159
160 if (*nptr == '-')
161 {
162 positive = false;
163 ++nptr;
164 }
165 else if (*nptr == '+')
166 ++nptr;
167
168 if (*nptr < '0' || *nptr > '9')
169 {
170 if (endptr != NULL)
171 *endptr = (char *) nptr;
172 return 0UL;
173 }
174
f94446c3
AZ
175 uint64_t cutoff = (UINT64_MAX * 2UL + 1UL) / 10;
176 uint64_t cutlim = (UINT64_MAX * 2UL + 1UL) % 10;
177
37b66c0b
L
178 int base = 10;
179 max_digit = 9;
180 if (*nptr == '0')
181 {
182 if (nptr[1] == 'x' || nptr[1] == 'X')
183 {
184 base = 16;
185 nptr += 2;
f94446c3
AZ
186 cutoff = (UINT64_MAX * 2UL + 1UL) / 16;
187 cutlim = (UINT64_MAX * 2UL + 1UL) % 16;
37b66c0b
L
188 }
189 else
190 {
191 base = 8;
192 max_digit = 7;
f94446c3
AZ
193 cutoff = (UINT64_MAX * 2UL + 1UL) / 8;
194 cutlim = (UINT64_MAX * 2UL + 1UL) % 8;
37b66c0b
L
195 }
196 }
197
198 while (1)
199 {
200 int digval;
201 if (*nptr >= '0' && *nptr <= '0' + max_digit)
202 digval = *nptr - '0';
203 else if (base == 16)
204 {
205 if (*nptr >= 'a' && *nptr <= 'f')
206 digval = *nptr - 'a' + 10;
207 else if (*nptr >= 'A' && *nptr <= 'F')
208 digval = *nptr - 'A' + 10;
209 else
210 break;
211 }
212 else
213 break;
214
f94446c3 215 if (result > cutoff || (result == cutoff && digval > cutlim))
37b66c0b
L
216 {
217 if (endptr != NULL)
218 *endptr = (char *) nptr;
219 return UINT64_MAX;
220 }
221 result *= base;
222 result += digval;
223 ++nptr;
224 }
225
226 if (endptr != NULL)
227 *endptr = (char *) nptr;
228
229 /* Avoid 64-bit multiplication. */
230 if (!positive)
231 result = -result;
232
233 return result;
234}