]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-lookup.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / elf / dl-lookup.c
CommitLineData
d66e34cd 1/* Look up a symbol in the loaded objects.
2b778ceb 2 Copyright (C) 1995-2021 Free Software Foundation, Inc.
afd4eb37 3 This file is part of the GNU C Library.
d66e34cd 4
afd4eb37 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.
d66e34cd 9
afd4eb37
UD
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.
d66e34cd 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/>. */
d66e34cd 18
f671aeab 19#include <alloca.h>
407fe3bb 20#include <libintl.h>
cf197e41 21#include <stdlib.h>
8d6468d0 22#include <string.h>
3db52d94 23#include <unistd.h>
a42195db 24#include <ldsodefs.h>
8f480b4b 25#include <dl-hash.h>
bc9f6000 26#include <dl-machine.h>
4e35ef2c 27#include <sysdep-cancel.h>
ec999b8e 28#include <libc-lock.h>
f1cc669a 29#include <tls.h>
1ec79f26 30#include <atomic.h>
50a2d83c 31#include <elf_machine_sym_no_match.h>
c84142e8 32
a853022c
UD
33#include <assert.h>
34
b0982c4a 35#define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
266180eb 36
84384f5b
UD
37struct sym_val
38 {
84384f5b 39 const ElfW(Sym) *s;
0c367d92 40 struct link_map *m;
84384f5b
UD
41 };
42
43
8352b484 44/* Statistics function. */
d6b5d570
UD
45#ifdef SHARED
46# define bump_num_relocations() ++GL(dl_num_relocations)
be4b5a95 47#else
d6b5d570 48# define bump_num_relocations() ((void) 0)
be4b5a95
UD
49#endif
50
8e25d1e7
CD
51/* Utility function for do_lookup_x. The caller is called with undef_name,
52 ref, version, flags and type_class, and those are passed as the first
53 five arguments. The caller then computes sym, symidx, strtab, and map
54 and passes them as the next four arguments. Lastly the caller passes in
55 versioned_sym and num_versions which are modified by check_match during
56 the checking process. */
57static const ElfW(Sym) *
58check_match (const char *const undef_name,
59 const ElfW(Sym) *const ref,
60 const struct r_found_version *const version,
61 const int flags,
62 const int type_class,
63 const ElfW(Sym) *const sym,
64 const Elf_Symndx symidx,
65 const char *const strtab,
66 const struct link_map *const map,
67 const ElfW(Sym) **const versioned_sym,
68 int *const num_versions)
69{
70 unsigned int stt = ELFW(ST_TYPE) (sym->st_info);
71 assert (ELF_RTYPE_CLASS_PLT == 1);
cc7d0447 72 if (__glibc_unlikely ((sym->st_value == 0 /* No value. */
bac15a72 73 && sym->st_shndx != SHN_ABS
8e25d1e7 74 && stt != STT_TLS)
50a2d83c 75 || elf_machine_sym_no_match (sym)
cc7d0447 76 || (type_class & (sym->st_shndx == SHN_UNDEF))))
8e25d1e7
CD
77 return NULL;
78
79 /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,
80 STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no
81 code/data definitions. */
82#define ALLOWED_STT \
83 ((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) \
84 | (1 << STT_COMMON) | (1 << STT_TLS) | (1 << STT_GNU_IFUNC))
85 if (__glibc_unlikely (((1 << stt) & ALLOWED_STT) == 0))
86 return NULL;
87
88 if (sym != ref && strcmp (strtab + sym->st_name, undef_name))
89 /* Not the symbol we are looking for. */
90 return NULL;
91
92 const ElfW(Half) *verstab = map->l_versyms;
93 if (version != NULL)
94 {
95 if (__glibc_unlikely (verstab == NULL))
96 {
97 /* We need a versioned symbol but haven't found any. If
98 this is the object which is referenced in the verneed
99 entry it is a bug in the library since a symbol must
100 not simply disappear.
101
102 It would also be a bug in the object since it means that
103 the list of required versions is incomplete and so the
104 tests in dl-version.c haven't found a problem.*/
105 assert (version->filename == NULL
106 || ! _dl_name_match_p (version->filename, map));
107
108 /* Otherwise we accept the symbol. */
109 }
110 else
111 {
112 /* We can match the version information or use the
113 default one if it is not hidden. */
114 ElfW(Half) ndx = verstab[symidx] & 0x7fff;
115 if ((map->l_versions[ndx].hash != version->hash
116 || strcmp (map->l_versions[ndx].name, version->name))
117 && (version->hidden || map->l_versions[ndx].hash
118 || (verstab[symidx] & 0x8000)))
119 /* It's not the version we want. */
120 return NULL;
121 }
122 }
123 else
124 {
125 /* No specific version is selected. There are two ways we
126 can got here:
127
128 - a binary which does not include versioning information
129 is loaded
130
131 - dlsym() instead of dlvsym() is used to get a symbol which
132 might exist in more than one form
133
134 If the library does not provide symbol version information
135 there is no problem at all: we simply use the symbol if it
136 is defined.
137
138 These two lookups need to be handled differently if the
139 library defines versions. In the case of the old
140 unversioned application the oldest (default) version
141 should be used. In case of a dlsym() call the latest and
142 public interface should be returned. */
143 if (verstab != NULL)
144 {
145 if ((verstab[symidx] & 0x7fff)
146 >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
147 {
148 /* Don't accept hidden symbols. */
149 if ((verstab[symidx] & 0x8000) == 0
150 && (*num_versions)++ == 0)
151 /* No version so far. */
152 *versioned_sym = sym;
153
154 return NULL;
155 }
156 }
157 }
158
159 /* There cannot be another entry for this symbol so stop here. */
160 return sym;
161}
162
7b8fb2b8
RM
163/* Utility function for do_lookup_unique. Add a symbol to TABLE. */
164static void
165enter_unique_sym (struct unique_sym *table, size_t size,
166 unsigned int hash, const char *name,
167 const ElfW(Sym) *sym, const struct link_map *map)
168{
169 size_t idx = hash % size;
170 size_t hash2 = 1 + hash % (size - 2);
171 while (table[idx].name != NULL)
172 {
173 idx += hash2;
174 if (idx >= size)
175 idx -= size;
176 }
177
178 table[idx].hashval = hash;
179 table[idx].name = name;
180 table[idx].sym = sym;
181 table[idx].map = map;
182}
183
f8ed116a
FW
184/* Mark MAP as NODELETE according to the lookup mode in FLAGS. During
185 initial relocation, NODELETE state is pending only. */
186static void
187mark_nodelete (struct link_map *map, int flags)
188{
189 if (flags & DL_LOOKUP_FOR_RELOCATE)
190 map->l_nodelete_pending = true;
191 else
192 map->l_nodelete_active = true;
193}
194
195/* Return true if MAP is marked as NODELETE according to the lookup
196 mode in FLAGS> */
197static bool
198is_nodelete (struct link_map *map, int flags)
199{
200 /* Non-pending NODELETE always counts. Pending NODELETE only counts
201 during initial relocation processing. */
202 return map->l_nodelete_active
203 || ((flags & DL_LOOKUP_FOR_RELOCATE) && map->l_nodelete_pending);
204}
205
f393b4aa
WN
206/* Utility function for do_lookup_x. Lookup an STB_GNU_UNIQUE symbol
207 in the unique symbol table, creating a new entry if necessary.
208 Return the matching symbol in RESULT. */
209static void
210do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
f63b7381 211 struct link_map *map, struct sym_val *result,
f393b4aa 212 int type_class, const ElfW(Sym) *sym, const char *strtab,
f63b7381
FW
213 const ElfW(Sym) *ref, const struct link_map *undef_map,
214 int flags)
f393b4aa 215{
7b8fb2b8
RM
216 /* We have to determine whether we already found a symbol with this
217 name before. If not then we have to add it to the search table.
218 If we already found a definition we have to use it. */
f393b4aa
WN
219
220 struct unique_sym_table *tab
221 = &GL(dl_ns)[map->l_ns]._ns_unique_sym_table;
222
223 __rtld_lock_lock_recursive (tab->lock);
224
225 struct unique_sym *entries = tab->entries;
226 size_t size = tab->size;
227 if (entries != NULL)
228 {
229 size_t idx = new_hash % size;
230 size_t hash2 = 1 + new_hash % (size - 2);
231 while (1)
232 {
233 if (entries[idx].hashval == new_hash
234 && strcmp (entries[idx].name, undef_name) == 0)
235 {
236 if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
237 {
238 /* We possibly have to initialize the central
239 copy from the copy addressed through the
240 relocation. */
241 result->s = sym;
f63b7381 242 result->m = map;
f393b4aa
WN
243 }
244 else
245 {
246 result->s = entries[idx].sym;
247 result->m = (struct link_map *) entries[idx].map;
248 }
249 __rtld_lock_unlock_recursive (tab->lock);
250 return;
251 }
252
253 if (entries[idx].name == NULL)
254 break;
255
256 idx += hash2;
257 if (idx >= size)
258 idx -= size;
259 }
260
261 if (size * 3 <= tab->n_elements * 4)
262 {
263 /* Expand the table. */
264#ifdef RTLD_CHECK_FOREIGN_CALL
265 /* This must not happen during runtime relocations. */
266 assert (!RTLD_CHECK_FOREIGN_CALL);
267#endif
268 size_t newsize = _dl_higher_prime_number (size + 1);
269 struct unique_sym *newentries
270 = calloc (sizeof (struct unique_sym), newsize);
271 if (newentries == NULL)
272 {
273 nomem:
274 __rtld_lock_unlock_recursive (tab->lock);
275 _dl_fatal_printf ("out of memory\n");
276 }
277
278 for (idx = 0; idx < size; ++idx)
279 if (entries[idx].name != NULL)
7b8fb2b8
RM
280 enter_unique_sym (newentries, newsize, entries[idx].hashval,
281 entries[idx].name, entries[idx].sym,
282 entries[idx].map);
f393b4aa
WN
283
284 tab->free (entries);
285 tab->size = newsize;
286 size = newsize;
287 entries = tab->entries = newentries;
3a0ecccb 288 tab->free = __rtld_free;
f393b4aa
WN
289 }
290 }
291 else
292 {
293#ifdef RTLD_CHECK_FOREIGN_CALL
294 /* This must not happen during runtime relocations. */
295 assert (!RTLD_CHECK_FOREIGN_CALL);
296#endif
297
298#ifdef SHARED
299 /* If tab->entries is NULL, but tab->size is not, it means
300 this is the second, conflict finding, lookup for
301 LD_TRACE_PRELINKING in _dl_debug_bindings. Don't
302 allocate anything and don't enter anything into the
303 hash table. */
304 if (__glibc_unlikely (tab->size))
305 {
306 assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
307 goto success;
308 }
309#endif
310
311#define INITIAL_NUNIQUE_SYM_TABLE 31
312 size = INITIAL_NUNIQUE_SYM_TABLE;
313 entries = calloc (sizeof (struct unique_sym), size);
314 if (entries == NULL)
315 goto nomem;
316
317 tab->entries = entries;
318 tab->size = size;
3a0ecccb 319 tab->free = __rtld_free;
f393b4aa
WN
320 }
321
322 if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
7b8fb2b8 323 enter_unique_sym (entries, size, new_hash, strtab + sym->st_name, ref,
f393b4aa
WN
324 undef_map);
325 else
326 {
7b8fb2b8
RM
327 enter_unique_sym (entries, size,
328 new_hash, strtab + sym->st_name, sym, map);
f393b4aa 329
f8ed116a 330 if (map->l_type == lt_loaded && !is_nodelete (map, flags))
f63b7381
FW
331 {
332 /* Make sure we don't unload this object by
333 setting the appropriate flag. */
365624e2 334 if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS))
f63b7381
FW
335 _dl_debug_printf ("\
336marking %s [%lu] as NODELETE due to unique symbol\n",
337 map->l_name, map->l_ns);
f8ed116a 338 mark_nodelete (map, flags);
f63b7381 339 }
f393b4aa
WN
340 }
341 ++tab->n_elements;
342
343#ifdef SHARED
344 success:
345#endif
346 __rtld_lock_unlock_recursive (tab->lock);
347
348 result->s = sym;
349 result->m = (struct link_map *) map;
350}
8352b484 351
786b74f4
UD
352/* Inner part of the lookup functions. We return a value > 0 if we
353 found the symbol, the value 0 if nothing is found and < 0 if
354 something bad happened. */
355static int
356__attribute_noinline__
357do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
358 unsigned long int *old_hash, const ElfW(Sym) *ref,
359 struct sym_val *result, struct r_scope_elem *scope, size_t i,
360 const struct r_found_version *const version, int flags,
361 struct link_map *skip, int type_class, struct link_map *undef_map)
362{
363 size_t n = scope->r_nlist;
364 /* Make sure we read the value before proceeding. Otherwise we
365 might use r_list pointing to the initial scope and r_nlist being
366 the value after a resize. That is the only path in dl-open.c not
367 protected by GSCOPE. A read barrier here might be to expensive. */
368 __asm volatile ("" : "+r" (n), "+m" (scope->r_list));
369 struct link_map **list = scope->r_list;
370
371 do
372 {
786b74f4
UD
373 const struct link_map *map = list[i]->l_real;
374
375 /* Here come the extra test needed for `_dl_lookup_symbol_skip'. */
376 if (map == skip)
377 continue;
378
379 /* Don't search the executable when resolving a copy reloc. */
380 if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)
381 continue;
382
383 /* Do not look into objects which are going to be removed. */
384 if (map->l_removed)
385 continue;
386
387 /* Print some debugging info if wanted. */
a1ffb40e 388 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS))
786b74f4 389 _dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n",
b9375348 390 undef_name, DSO_FILENAME (map->l_name),
786b74f4
UD
391 map->l_ns);
392
393 /* If the hash table is empty there is nothing to do here. */
394 if (map->l_nbuckets == 0)
395 continue;
396
f6488e2b
WN
397 Elf_Symndx symidx;
398 int num_versions = 0;
399 const ElfW(Sym) *versioned_sym = NULL;
400
786b74f4
UD
401 /* The tables for this map. */
402 const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
403 const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
404
786b74f4
UD
405 const ElfW(Sym) *sym;
406 const ElfW(Addr) *bitmask = map->l_gnu_bitmask;
a1ffb40e 407 if (__glibc_likely (bitmask != NULL))
786b74f4
UD
408 {
409 ElfW(Addr) bitmask_word
410 = bitmask[(new_hash / __ELF_NATIVE_CLASS)
411 & map->l_gnu_bitmask_idxbits];
412
413 unsigned int hashbit1 = new_hash & (__ELF_NATIVE_CLASS - 1);
414 unsigned int hashbit2 = ((new_hash >> map->l_gnu_shift)
415 & (__ELF_NATIVE_CLASS - 1));
416
cc7d0447
WN
417 if (__glibc_unlikely ((bitmask_word >> hashbit1)
418 & (bitmask_word >> hashbit2) & 1))
786b74f4
UD
419 {
420 Elf32_Word bucket = map->l_gnu_buckets[new_hash
421 % map->l_nbuckets];
422 if (bucket != 0)
423 {
424 const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket];
425
426 do
427 if (((*hasharr ^ new_hash) >> 1) == 0)
428 {
23c1c256 429 symidx = ELF_MACHINE_HASH_SYMIDX (map, hasharr);
8e25d1e7
CD
430 sym = check_match (undef_name, ref, version, flags,
431 type_class, &symtab[symidx], symidx,
432 strtab, map, &versioned_sym,
433 &num_versions);
786b74f4
UD
434 if (sym != NULL)
435 goto found_it;
436 }
437 while ((*hasharr++ & 1u) == 0);
438 }
439 }
440 /* No symbol found. */
441 symidx = SHN_UNDEF;
442 }
443 else
444 {
445 if (*old_hash == 0xffffffff)
446 *old_hash = _dl_elf_hash (undef_name);
447
448 /* Use the old SysV-style hash table. Search the appropriate
449 hash bucket in this object's symbol table for a definition
450 for the same symbol name. */
451 for (symidx = map->l_buckets[*old_hash % map->l_nbuckets];
452 symidx != STN_UNDEF;
453 symidx = map->l_chain[symidx])
454 {
8e25d1e7
CD
455 sym = check_match (undef_name, ref, version, flags,
456 type_class, &symtab[symidx], symidx,
457 strtab, map, &versioned_sym,
458 &num_versions);
786b74f4
UD
459 if (sym != NULL)
460 goto found_it;
461 }
462 }
463
464 /* If we have seen exactly one versioned symbol while we are
465 looking for an unversioned symbol and the version is not the
466 default version we still accept this symbol since there are
467 no possible ambiguities. */
468 sym = num_versions == 1 ? versioned_sym : NULL;
469
470 if (sym != NULL)
471 {
472 found_it:
62da1e3b
L
473 /* When UNDEF_MAP is NULL, which indicates we are called from
474 do_lookup_x on relocation against protected data, we skip
475 the data definion in the executable from copy reloc. */
476 if (ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA
477 && undef_map == NULL
478 && map->l_type == lt_executable
479 && type_class == ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA)
480 {
481 const ElfW(Sym) *s;
482 unsigned int i;
483
484#if ! ELF_MACHINE_NO_RELA
485 if (map->l_info[DT_RELA] != NULL
486 && map->l_info[DT_RELASZ] != NULL
487 && map->l_info[DT_RELASZ]->d_un.d_val != 0)
488 {
489 const ElfW(Rela) *rela
490 = (const ElfW(Rela) *) D_PTR (map, l_info[DT_RELA]);
491 unsigned int rela_count
492 = map->l_info[DT_RELASZ]->d_un.d_val / sizeof (*rela);
493
494 for (i = 0; i < rela_count; i++, rela++)
495 if (elf_machine_type_class (ELFW(R_TYPE) (rela->r_info))
496 == ELF_RTYPE_CLASS_COPY)
497 {
498 s = &symtab[ELFW(R_SYM) (rela->r_info)];
499 if (!strcmp (strtab + s->st_name, undef_name))
500 goto skip;
501 }
502 }
503#endif
504#if ! ELF_MACHINE_NO_REL
505 if (map->l_info[DT_REL] != NULL
506 && map->l_info[DT_RELSZ] != NULL
507 && map->l_info[DT_RELSZ]->d_un.d_val != 0)
508 {
509 const ElfW(Rel) *rel
510 = (const ElfW(Rel) *) D_PTR (map, l_info[DT_REL]);
511 unsigned int rel_count
512 = map->l_info[DT_RELSZ]->d_un.d_val / sizeof (*rel);
513
514 for (i = 0; i < rel_count; i++, rel++)
515 if (elf_machine_type_class (ELFW(R_TYPE) (rel->r_info))
516 == ELF_RTYPE_CLASS_COPY)
517 {
518 s = &symtab[ELFW(R_SYM) (rel->r_info)];
519 if (!strcmp (strtab + s->st_name, undef_name))
520 goto skip;
521 }
522 }
523#endif
524 }
525
b6084a95
MR
526 /* Hidden and internal symbols are local, ignore them. */
527 if (__glibc_unlikely (dl_symbol_visibility_binds_local_p (sym)))
528 goto skip;
529
cc7d0447 530 switch (ELFW(ST_BIND) (sym->st_info))
786b74f4
UD
531 {
532 case STB_WEAK:
533 /* Weak definition. Use this value if we don't find another. */
a1ffb40e 534 if (__glibc_unlikely (GLRO(dl_dynamic_weak)))
786b74f4
UD
535 {
536 if (! result->s)
537 {
538 result->s = sym;
539 result->m = (struct link_map *) map;
540 }
541 break;
542 }
543 /* FALLTHROUGH */
544 case STB_GLOBAL:
786b74f4
UD
545 /* Global definition. Just what we need. */
546 result->s = sym;
547 result->m = (struct link_map *) map;
548 return 1;
549
550 case STB_GNU_UNIQUE:;
f63b7381
FW
551 do_lookup_unique (undef_name, new_hash, (struct link_map *) map,
552 result, type_class, sym, strtab, ref,
553 undef_map, flags);
f393b4aa 554 return 1;
786b74f4
UD
555
556 default:
557 /* Local symbols are ignored. */
558 break;
559 }
560 }
561
62da1e3b 562skip:
f0b2132b 563 ;
786b74f4
UD
564 }
565 while (++i < n);
566
567 /* We have not found anything until now. */
568 return 0;
569}
84384f5b 570
84384f5b 571
871b9158
UD
572static uint_fast32_t
573dl_new_hash (const char *s)
574{
575 uint_fast32_t h = 5381;
576 for (unsigned char c = *s; c != '\0'; c = *++s)
577 h = h * 33 + c;
578 return h & 0xffffffff;
579}
580
581
cf197e41
UD
582/* Add extra dependency on MAP to UNDEF_MAP. */
583static int
b90395e6 584add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
cf197e41 585{
c4bb124a 586 struct link_map *runp;
cf197e41
UD
587 unsigned int i;
588 int result = 0;
589
aff4519d
UD
590 /* Avoid self-references and references to objects which cannot be
591 unloaded anyway. */
c4bb124a
UD
592 if (undef_map == map)
593 return 0;
594
f63b7381
FW
595 /* Avoid references to objects which cannot be unloaded anyway. We
596 do not need to record dependencies if this object goes away
597 during dlopen failure, either. IFUNC resolvers with relocation
598 dependencies may pick an dependency which can be dlclose'd, but
599 such IFUNC resolvers are undefined anyway. */
385b4cf4 600 assert (map->l_type == lt_loaded);
f8ed116a 601 if (is_nodelete (map, flags))
385b4cf4
UD
602 return 0;
603
604 struct link_map_reldeps *l_reldeps
605 = atomic_forced_read (undef_map->l_reldeps);
606
607 /* Make sure l_reldeps is read before l_initfini. */
608 atomic_read_barrier ();
609
610 /* Determine whether UNDEF_MAP already has a reference to MAP. First
611 look in the normal dependencies. */
612 struct link_map **l_initfini = atomic_forced_read (undef_map->l_initfini);
613 if (l_initfini != NULL)
614 {
615 for (i = 0; l_initfini[i] != NULL; ++i)
616 if (l_initfini[i] == map)
617 return 0;
618 }
619
620 /* No normal dependency. See whether we already had to add it
621 to the special list of dynamic dependencies. */
622 unsigned int l_reldepsact = 0;
623 if (l_reldeps != NULL)
624 {
625 struct link_map **list = &l_reldeps->list[0];
626 l_reldepsact = l_reldeps->act;
627 for (i = 0; i < l_reldepsact; ++i)
628 if (list[i] == map)
629 return 0;
630 }
631
b90395e6 632 /* Save serial number of the target MAP. */
385b4cf4 633 unsigned long long serial = map->l_serial;
aff4519d 634
b90395e6 635 /* Make sure nobody can unload the object while we are at it. */
a1ffb40e 636 if (__glibc_unlikely (flags & DL_LOOKUP_GSCOPE_LOCK))
aff4519d 637 {
b90395e6
UD
638 /* We can't just call __rtld_lock_lock_recursive (GL(dl_load_lock))
639 here, that can result in ABBA deadlock. */
640 THREAD_GSCOPE_RESET_FLAG ();
641 __rtld_lock_lock_recursive (GL(dl_load_lock));
b90395e6
UD
642 /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
643 it can e.g. point to unallocated memory. So avoid the optimizer
644 treating the above read from MAP->l_serial as ensurance it
645 can safely dereference it. */
646 map = atomic_forced_read (map);
b90395e6 647
385b4cf4
UD
648 /* From this point on it is unsafe to dereference MAP, until it
649 has been found in one of the lists. */
cf197e41 650
385b4cf4
UD
651 /* Redo the l_initfini check in case undef_map's l_initfini
652 changed in the mean time. */
653 if (undef_map->l_initfini != l_initfini
654 && undef_map->l_initfini != NULL)
655 {
656 l_initfini = undef_map->l_initfini;
657 for (i = 0; l_initfini[i] != NULL; ++i)
658 if (l_initfini[i] == map)
659 goto out_check;
660 }
cf197e41 661
385b4cf4
UD
662 /* Redo the l_reldeps check if undef_map's l_reldeps changed in
663 the mean time. */
664 if (undef_map->l_reldeps != NULL)
665 {
666 if (undef_map->l_reldeps != l_reldeps)
667 {
668 struct link_map **list = &undef_map->l_reldeps->list[0];
669 l_reldepsact = undef_map->l_reldeps->act;
670 for (i = 0; i < l_reldepsact; ++i)
671 if (list[i] == map)
672 goto out_check;
673 }
674 else if (undef_map->l_reldeps->act > l_reldepsact)
675 {
676 struct link_map **list
677 = &undef_map->l_reldeps->list[0];
678 i = l_reldepsact;
679 l_reldepsact = undef_map->l_reldeps->act;
680 for (; i < l_reldepsact; ++i)
681 if (list[i] == map)
682 goto out_check;
683 }
684 }
c4bb124a 685 }
385b4cf4
UD
686 else
687 __rtld_lock_lock_recursive (GL(dl_load_lock));
c4bb124a
UD
688
689 /* The object is not yet in the dependency list. Before we add
690 it make sure just one more time the object we are about to
691 reference is still available. There is a brief period in
692 which the object could have been removed since we found the
693 definition. */
c0f62c56 694 runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
c4bb124a
UD
695 while (runp != NULL && runp != map)
696 runp = runp->l_next;
697
698 if (runp != NULL)
699 {
b90395e6
UD
700 /* The object is still available. */
701
702 /* MAP could have been dlclosed, freed and then some other dlopened
703 library could have the same link_map pointer. */
704 if (map->l_serial != serial)
705 goto out_check;
706
385b4cf4
UD
707 /* Redo the NODELETE check, as when dl_load_lock wasn't held
708 yet this could have changed. */
f8ed116a 709 if (is_nodelete (map, flags))
b90395e6
UD
710 goto out;
711
712 /* If the object with the undefined reference cannot be removed ever
713 just make sure the same is true for the object which contains the
714 definition. */
f8ed116a 715 if (undef_map->l_type != lt_loaded || is_nodelete (map, flags))
b90395e6 716 {
f63b7381 717 if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)
f8ed116a 718 && !is_nodelete (map, flags))
f63b7381
FW
719 {
720 if (undef_map->l_name[0] == '\0')
721 _dl_debug_printf ("\
722marking %s [%lu] as NODELETE due to reference to main program\n",
723 map->l_name, map->l_ns);
724 else
725 _dl_debug_printf ("\
726marking %s [%lu] as NODELETE due to reference to %s [%lu]\n",
727 map->l_name, map->l_ns,
728 undef_map->l_name, undef_map->l_ns);
729 }
f8ed116a 730 mark_nodelete (map, flags);
b90395e6
UD
731 goto out;
732 }
733
734 /* Add the reference now. */
a1ffb40e 735 if (__glibc_unlikely (l_reldepsact >= undef_map->l_reldepsmax))
cf197e41 736 {
c4bb124a
UD
737 /* Allocate more memory for the dependency list. Since this
738 can never happen during the startup phase we can use
739 `realloc'. */
385b4cf4
UD
740 struct link_map_reldeps *newp;
741 unsigned int max
742 = undef_map->l_reldepsmax ? undef_map->l_reldepsmax * 2 : 10;
743
b48a267b
UD
744#ifdef RTLD_PREPARE_FOREIGN_CALL
745 RTLD_PREPARE_FOREIGN_CALL;
746#endif
747
385b4cf4
UD
748 newp = malloc (sizeof (*newp) + max * sizeof (struct link_map *));
749 if (newp == NULL)
750 {
751 /* If we didn't manage to allocate memory for the list this is
752 no fatal problem. We simply make sure the referenced object
753 cannot be unloaded. This is semantically the correct
754 behavior. */
f63b7381 755 if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)
f8ed116a 756 && !is_nodelete (map, flags))
f63b7381
FW
757 _dl_debug_printf ("\
758marking %s [%lu] as NODELETE due to memory allocation failure\n",
759 map->l_name, map->l_ns);
f8ed116a
FW
760 /* In case of non-lazy binding, we could actually report
761 the memory allocation error, but for now, we use the
762 conservative approximation as well. */
763 mark_nodelete (map, flags);
385b4cf4
UD
764 goto out;
765 }
cf197e41 766 else
385b4cf4
UD
767 {
768 if (l_reldepsact)
769 memcpy (&newp->list[0], &undef_map->l_reldeps->list[0],
770 l_reldepsact * sizeof (struct link_map *));
771 newp->list[l_reldepsact] = map;
772 newp->act = l_reldepsact + 1;
773 atomic_write_barrier ();
774 void *old = undef_map->l_reldeps;
775 undef_map->l_reldeps = newp;
776 undef_map->l_reldepsmax = max;
777 if (old)
778 _dl_scope_free (old);
779 }
cf197e41 780 }
715899d1 781 else
385b4cf4
UD
782 {
783 undef_map->l_reldeps->list[l_reldepsact] = map;
784 atomic_write_barrier ();
785 undef_map->l_reldeps->act = l_reldepsact + 1;
786 }
c4bb124a 787
c4bb124a 788 /* Display information if we are debugging. */
a1ffb40e 789 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
154d10bd 790 _dl_debug_printf ("\
c0f62c56 791\nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
b9375348 792 DSO_FILENAME (map->l_name),
c0f62c56 793 map->l_ns,
b9375348 794 DSO_FILENAME (undef_map->l_name),
c0f62c56 795 undef_map->l_ns);
cf197e41 796 }
c4bb124a
UD
797 else
798 /* Whoa, that was bad luck. We have to search again. */
799 result = -1;
cf197e41 800
c4bb124a 801 out:
cf197e41 802 /* Release the lock. */
d3c9f895 803 __rtld_lock_unlock_recursive (GL(dl_load_lock));
cf197e41 804
a1ffb40e 805 if (__glibc_unlikely (flags & DL_LOOKUP_GSCOPE_LOCK))
385b4cf4
UD
806 THREAD_GSCOPE_SET_FLAG ();
807
cf197e41 808 return result;
b90395e6
UD
809
810 out_check:
811 if (map->l_serial != serial)
812 result = -1;
813 goto out;
cf197e41
UD
814}
815
32e6df36 816static void
32e6df36 817_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
c0a777e8 818 const ElfW(Sym) **ref, struct sym_val *value,
7969407a
UD
819 const struct r_found_version *version, int type_class,
820 int protected);
647eb037 821
84384f5b 822
bdf4a4f1 823/* Search loaded objects' symbol tables for a definition of the symbol
609cf614
UD
824 UNDEF_NAME, perhaps with a requested version for the symbol.
825
826 We must never have calls to the audit functions inside this function
827 or in any function which gets called. If this would happen the audit
828 code might create a thread which can throw off all the scope locking. */
c0282c06 829lookup_t
bdf4a4f1
UD
830_dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
831 const ElfW(Sym) **ref,
832 struct r_scope_elem *symbol_scope[],
833 const struct r_found_version *version,
834 int type_class, int flags, struct link_map *skip_map)
84384f5b 835{
871b9158
UD
836 const uint_fast32_t new_hash = dl_new_hash (undef_name);
837 unsigned long int old_hash = 0xffffffff;
0c367d92 838 struct sym_val current_value = { NULL, NULL };
bdf4a4f1 839 struct r_scope_elem **scope = symbol_scope;
84384f5b 840
be4b5a95 841 bump_num_relocations ();
48f6496e 842
ca136bb0
FW
843 /* DL_LOOKUP_RETURN_NEWEST does not make sense for versioned
844 lookups. */
845 assert (version == NULL || !(flags & DL_LOOKUP_RETURN_NEWEST));
c84142e8 846
bdf4a4f1 847 size_t i = 0;
a1ffb40e 848 if (__glibc_unlikely (skip_map != NULL))
3c457089
UD
849 /* Search the relevant loaded objects for a definition. */
850 while ((*scope)->r_list[i] != skip_map)
851 ++i;
32e6df36 852
c84142e8 853 /* Search the relevant loaded objects for a definition. */
bdf4a4f1 854 for (size_t start = i; *scope != NULL; start = 0, ++scope)
f0b2132b
FW
855 if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
856 &current_value, *scope, start, version, flags,
857 skip_map, type_class, undef_map) != 0)
858 break;
c84142e8 859
a1ffb40e 860 if (__glibc_unlikely (current_value.s == NULL))
0c367d92 861 {
bdf4a4f1 862 if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
ff9f1c5f 863 && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
c90b5d28
UD
864 {
865 /* We could find no value for a strong reference. */
9363dbb8 866 const char *reference_name = undef_map ? undef_map->l_name : "";
bdf4a4f1
UD
867 const char *versionstr = version ? ", version " : "";
868 const char *versionname = (version && version->name
869 ? version->name : "");
2449ae7b 870 struct dl_exception exception;
c90b5d28 871 /* XXX We cannot translate the message. */
2449ae7b
FW
872 _dl_exception_create_format
873 (&exception, DSO_FILENAME (reference_name),
874 "undefined symbol: %s%s%s",
875 undef_name, versionstr, versionname);
876 _dl_signal_cexception (0, &exception, N_("symbol lookup error"));
877 _dl_exception_free (&exception);
c90b5d28 878 }
0c367d92
UD
879 *ref = NULL;
880 return 0;
881 }
882
bdf4a4f1
UD
883 int protected = (*ref
884 && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED);
a1ffb40e 885 if (__glibc_unlikely (protected != 0))
6aa29abe 886 {
78575a84 887 /* It is very tricky. We need to figure out what value to
2af63968 888 return for the protected symbol. */
697119d6 889 if (type_class == ELF_RTYPE_CLASS_PLT)
6aa29abe 890 {
697119d6
UD
891 if (current_value.s != NULL && current_value.m != undef_map)
892 {
893 current_value.s = *ref;
894 current_value.m = undef_map;
895 }
896 }
897 else
898 {
899 struct sym_val protected_value = { NULL, NULL };
900
9363dbb8 901 for (scope = symbol_scope; *scope != NULL; i = 0, ++scope)
871b9158
UD
902 if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
903 &protected_value, *scope, i, version, flags,
62da1e3b
L
904 skip_map,
905 (ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA
906 && ELFW(ST_TYPE) ((*ref)->st_info) == STT_OBJECT
907 && type_class == ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA)
908 ? ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA
909 : ELF_RTYPE_CLASS_PLT, NULL) != 0)
697119d6
UD
910 break;
911
9363dbb8 912 if (protected_value.s != NULL && protected_value.m != undef_map)
697119d6
UD
913 {
914 current_value.s = *ref;
915 current_value.m = undef_map;
916 }
6aa29abe 917 }
6aa29abe 918 }
32e6df36 919
78575a84
UD
920 /* We have to check whether this would bind UNDEF_MAP to an object
921 in the global scope which was dynamically loaded. In this case
922 we have to prevent the latter from being unloaded unless the
923 UNDEF_MAP object is also unloaded. */
cc7d0447 924 if (__glibc_unlikely (current_value.m->l_type == lt_loaded)
78575a84
UD
925 /* Don't do this for explicit lookups as opposed to implicit
926 runtime lookups. */
bdf4a4f1 927 && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
78575a84 928 /* Add UNDEF_MAP to the dependencies. */
b90395e6 929 && add_dependency (undef_map, current_value.m, flags) < 0)
78575a84
UD
930 /* Something went wrong. Perhaps the object we tried to reference
931 was just removed. Try finding another definition. */
b90395e6
UD
932 return _dl_lookup_symbol_x (undef_name, undef_map, ref,
933 (flags & DL_LOOKUP_GSCOPE_LOCK)
934 ? undef_map->l_scope : symbol_scope,
e4eb675d 935 version, type_class, flags, skip_map);
78575a84 936
7a11603d 937 /* The object is used. */
a1ffb40e 938 if (__glibc_unlikely (current_value.m->l_used == 0))
2af63968 939 current_value.m->l_used = 1;
7a11603d 940
cc7d0447
WN
941 if (__glibc_unlikely (GLRO(dl_debug_mask)
942 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK)))
c0a777e8 943 _dl_debug_bindings (undef_name, undef_map, ref,
32e6df36
UD
944 &current_value, version, type_class, protected);
945
946 *ref = current_value.s;
947 return LOOKUP_VALUE (current_value.m);
c84142e8
UD
948}
949
950
d66e34cd
RM
951/* Cache the location of MAP's hash table. */
952
953void
954_dl_setup_hash (struct link_map *map)
955{
a1eca9f3 956 Elf_Symndx *hash;
f41c8091 957
23c1c256 958 if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL))
871b9158
UD
959 {
960 Elf32_Word *hash32
23c1c256 961 = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]);
871b9158
UD
962 map->l_nbuckets = *hash32++;
963 Elf32_Word symbias = *hash32++;
964 Elf32_Word bitmask_nwords = *hash32++;
965 /* Must be a power of two. */
966 assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
967 map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
968 map->l_gnu_shift = *hash32++;
969
970 map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
971 hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
972
973 map->l_gnu_buckets = hash32;
974 hash32 += map->l_nbuckets;
975 map->l_gnu_chain_zero = hash32 - symbias;
23c1c256
MS
976
977 /* Initialize MIPS xhash translation table. */
978 ELF_MACHINE_XHASH_SETUP (hash32, symbias, map);
979
871b9158
UD
980 return;
981 }
982
f41c8091
UD
983 if (!map->l_info[DT_HASH])
984 return;
9a88a2d7 985 hash = (void *) D_PTR (map, l_info[DT_HASH]);
f41c8091 986
d66e34cd 987 map->l_nbuckets = *hash++;
1bc33071
UD
988 /* Skip nchain. */
989 hash++;
d66e34cd
RM
990 map->l_buckets = hash;
991 hash += map->l_nbuckets;
992 map->l_chain = hash;
993}
80d9c5f0 994
f9f2a150 995
32e6df36 996static void
32e6df36 997_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
c0a777e8 998 const ElfW(Sym) **ref, struct sym_val *value,
f9f2a150
UD
999 const struct r_found_version *version, int type_class,
1000 int protected)
32e6df36
UD
1001{
1002 const char *reference_name = undef_map->l_name;
1003
afdca0f2 1004 if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
32e6df36 1005 {
21e2d3a4 1006 _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
b9375348 1007 DSO_FILENAME (reference_name),
21e2d3a4 1008 undef_map->l_ns,
b9375348 1009 DSO_FILENAME (value->m->l_name),
21e2d3a4 1010 value->m->l_ns,
154d10bd 1011 protected ? "protected" : "normal", undef_name);
32e6df36
UD
1012 if (version)
1013 _dl_debug_printf_c (" [%s]\n", version->name);
1014 else
1015 _dl_debug_printf_c ("\n");
1016 }
1017#ifdef SHARED
afdca0f2 1018 if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
32e6df36 1019 {
f3d18efb
L
1020/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with
1021 LD_TRACE_PRELINKING. */
1022#define RTYPE_CLASS_VALID 8
1023#define RTYPE_CLASS_PLT (8|1)
1024#define RTYPE_CLASS_COPY (8|2)
1025#define RTYPE_CLASS_TLS (8|4)
1026#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1
1027# error ELF_RTYPE_CLASS_PLT must be 0 or 1!
1028#endif
1029#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2
1030# error ELF_RTYPE_CLASS_COPY must be 0 or 2!
1031#endif
32e6df36
UD
1032 int conflict = 0;
1033 struct sym_val val = { NULL, NULL };
1034
afdca0f2 1035 if ((GLRO(dl_trace_prelink_map) == NULL
c0f62c56
UD
1036 || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
1037 && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
32e6df36 1038 {
871b9158
UD
1039 const uint_fast32_t new_hash = dl_new_hash (undef_name);
1040 unsigned long int old_hash = 0xffffffff;
4ad43b62
UD
1041 struct unique_sym *saved_entries
1042 = GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries;
32e6df36 1043
4ad43b62 1044 GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = NULL;
871b9158 1045 do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
bdf4a4f1 1046 undef_map->l_local_scope[0], 0, version, 0, NULL,
415ac3df 1047 type_class, undef_map);
32e6df36
UD
1048 if (val.s != value->s || val.m != value->m)
1049 conflict = 1;
cc7d0447 1050 else if (__glibc_unlikely (undef_map->l_symbolic_in_local_scope)
4ad43b62 1051 && val.s
cc7d0447
WN
1052 && __glibc_unlikely (ELFW(ST_BIND) (val.s->st_info)
1053 == STB_GNU_UNIQUE))
4ad43b62
UD
1054 {
1055 /* If it is STB_GNU_UNIQUE and undef_map's l_local_scope
1056 contains any DT_SYMBOLIC libraries, unfortunately there
1057 can be conflicts even if the above is equal. As symbol
1058 resolution goes from the last library to the first and
1059 if a STB_GNU_UNIQUE symbol is found in some late DT_SYMBOLIC
1060 library, it would be the one that is looked up. */
1061 struct sym_val val2 = { NULL, NULL };
1062 size_t n;
1063 struct r_scope_elem *scope = undef_map->l_local_scope[0];
1064
1065 for (n = 0; n < scope->r_nlist; n++)
1066 if (scope->r_list[n] == val.m)
1067 break;
1068
1069 for (n++; n < scope->r_nlist; n++)
1070 if (scope->r_list[n]->l_info[DT_SYMBOLIC] != NULL
1071 && do_lookup_x (undef_name, new_hash, &old_hash, *ref,
1072 &val2,
1073 &scope->r_list[n]->l_symbolic_searchlist,
1074 0, version, 0, NULL, type_class,
1075 undef_map) > 0)
1076 {
1077 conflict = 1;
1078 val = val2;
1079 break;
1080 }
1081 }
1082 GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = saved_entries;
32e6df36
UD
1083 }
1084
02125962
JJ
1085 if (value->s)
1086 {
f3d18efb
L
1087 /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
1088 bits since since prelink only uses them. */
1089 type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY;
cc7d0447
WN
1090 if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
1091 == STT_TLS))
f3d18efb
L
1092 /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS. */
1093 type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID;
cc7d0447
WN
1094 else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
1095 == STT_GNU_IFUNC))
f3d18efb
L
1096 /* Set the RTYPE_CLASS_VALID bit. */
1097 type_class |= RTYPE_CLASS_VALID;
02125962 1098 }
1d0ad773 1099
32e6df36 1100 if (conflict
afdca0f2
UD
1101 || GLRO(dl_trace_prelink_map) == undef_map
1102 || GLRO(dl_trace_prelink_map) == NULL
02125962 1103 || type_class >= 4)
32e6df36
UD
1104 {
1105 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
1106 conflict ? "conflict" : "lookup",
32e6df36 1107 (int) sizeof (ElfW(Addr)) * 2,
d347a4ab 1108 (size_t) undef_map->l_map_start,
32e6df36 1109 (int) sizeof (ElfW(Addr)) * 2,
d347a4ab 1110 (size_t) (((ElfW(Addr)) *ref) - undef_map->l_map_start),
32e6df36 1111 (int) sizeof (ElfW(Addr)) * 2,
d347a4ab
UD
1112 (size_t) (value->s ? value->m->l_map_start : 0),
1113 (int) sizeof (ElfW(Addr)) * 2,
1114 (size_t) (value->s ? value->s->st_value : 0));
32e6df36
UD
1115
1116 if (conflict)
1117 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
1118 (int) sizeof (ElfW(Addr)) * 2,
d347a4ab 1119 (size_t) (val.s ? val.m->l_map_start : 0),
32e6df36 1120 (int) sizeof (ElfW(Addr)) * 2,
d347a4ab 1121 (size_t) (val.s ? val.s->st_value : 0));
32e6df36
UD
1122
1123 _dl_printf ("/%x %s\n", type_class, undef_name);
1124 }
1125 }
1126#endif
1127}