| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: rtld.c,v 1.207 2020/09/22 00:41:27 kamil Exp $ */ | | 1 | /* $NetBSD: rtld.c,v 1.208 2021/05/30 02:26:08 joerg Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 1996 John D. Polstra. | | 4 | * Copyright 1996 John D. Polstra. |
5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | | 5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> |
6 | * Copyright 2002 Charles M. Hannum <root@ihack.net> | | 6 | * Copyright 2002 Charles M. Hannum <root@ihack.net> |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -30,27 +30,27 @@ | | | @@ -30,27 +30,27 @@ |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | /* | | 35 | /* |
36 | * Dynamic linker for ELF. | | 36 | * Dynamic linker for ELF. |
37 | * | | 37 | * |
38 | * John Polstra <jdp@polstra.com>. | | 38 | * John Polstra <jdp@polstra.com>. |
39 | */ | | 39 | */ |
40 | | | 40 | |
41 | #include <sys/cdefs.h> | | 41 | #include <sys/cdefs.h> |
42 | #ifndef lint | | 42 | #ifndef lint |
43 | __RCSID("$NetBSD: rtld.c,v 1.207 2020/09/22 00:41:27 kamil Exp $"); | | 43 | __RCSID("$NetBSD: rtld.c,v 1.208 2021/05/30 02:26:08 joerg Exp $"); |
44 | #endif /* not lint */ | | 44 | #endif /* not lint */ |
45 | | | 45 | |
46 | #include <sys/param.h> | | 46 | #include <sys/param.h> |
47 | #include <sys/atomic.h> | | 47 | #include <sys/atomic.h> |
48 | #include <sys/mman.h> | | 48 | #include <sys/mman.h> |
49 | #include <err.h> | | 49 | #include <err.h> |
50 | #include <errno.h> | | 50 | #include <errno.h> |
51 | #include <fcntl.h> | | 51 | #include <fcntl.h> |
52 | #include <lwp.h> | | 52 | #include <lwp.h> |
53 | #include <stdarg.h> | | 53 | #include <stdarg.h> |
54 | #include <stdio.h> | | 54 | #include <stdio.h> |
55 | #include <stdlib.h> | | 55 | #include <stdlib.h> |
56 | #include <string.h> | | 56 | #include <string.h> |
| @@ -1108,27 +1108,27 @@ _rtld_objmain_sym(const char *name) | | | @@ -1108,27 +1108,27 @@ _rtld_objmain_sym(const char *name) |
1108 | hash.sysv = _rtld_sysv_hash(name); | | 1108 | hash.sysv = _rtld_sysv_hash(name); |
1109 | hash.gnu = _rtld_gnu_hash(name); | | 1109 | hash.gnu = _rtld_gnu_hash(name); |
1110 | obj = _rtld_objmain; | | 1110 | obj = _rtld_objmain; |
1111 | _rtld_donelist_init(&donelist); | | 1111 | _rtld_donelist_init(&donelist); |
1112 | | | 1112 | |
1113 | def = _rtld_symlook_list(name, &hash, &_rtld_list_main, &obj, 0, | | 1113 | def = _rtld_symlook_list(name, &hash, &_rtld_list_main, &obj, 0, |
1114 | NULL, &donelist); | | 1114 | NULL, &donelist); |
1115 | | | 1115 | |
1116 | if (def != NULL) | | 1116 | if (def != NULL) |
1117 | return obj->relocbase + def->st_value; | | 1117 | return obj->relocbase + def->st_value; |
1118 | return NULL; | | 1118 | return NULL; |
1119 | } | | 1119 | } |
1120 | | | 1120 | |
1121 | #ifdef __powerpc__ | | 1121 | #if defined(__powerpc__) && !defined(__clang__) |
1122 | static __noinline void * | | 1122 | static __noinline void * |
1123 | hackish_return_address(void) | | 1123 | hackish_return_address(void) |
1124 | { | | 1124 | { |
1125 | #if __GNUC_PREREQ__(6,0) | | 1125 | #if __GNUC_PREREQ__(6,0) |
1126 | #pragma GCC diagnostic push | | 1126 | #pragma GCC diagnostic push |
1127 | #pragma GCC diagnostic ignored "-Wframe-address" | | 1127 | #pragma GCC diagnostic ignored "-Wframe-address" |
1128 | #endif | | 1128 | #endif |
1129 | return __builtin_return_address(1); | | 1129 | return __builtin_return_address(1); |
1130 | #if __GNUC_PREREQ__(6,0) | | 1130 | #if __GNUC_PREREQ__(6,0) |
1131 | #pragma GCC diagnostic pop | | 1131 | #pragma GCC diagnostic pop |
1132 | #endif | | 1132 | #endif |
1133 | } | | 1133 | } |
1134 | #endif | | 1134 | #endif |
| @@ -1274,52 +1274,52 @@ do_dlsym(void *handle, const char *name, | | | @@ -1274,52 +1274,52 @@ do_dlsym(void *handle, const char *name, |
1274 | _rtld_error("Undefined symbol \"%s\"", name); | | 1274 | _rtld_error("Undefined symbol \"%s\"", name); |
1275 | lookup_mutex_exit(); | | 1275 | lookup_mutex_exit(); |
1276 | return NULL; | | 1276 | return NULL; |
1277 | } | | 1277 | } |
1278 | | | 1278 | |
1279 | __strong_alias(__dlsym,dlsym) | | 1279 | __strong_alias(__dlsym,dlsym) |
1280 | void * | | 1280 | void * |
1281 | dlsym(void *handle, const char *name) | | 1281 | dlsym(void *handle, const char *name) |
1282 | { | | 1282 | { |
1283 | void *retaddr; | | 1283 | void *retaddr; |
1284 | | | 1284 | |
1285 | dbg(("dlsym of %s in %p", name, handle)); | | 1285 | dbg(("dlsym of %s in %p", name, handle)); |
1286 | | | 1286 | |
1287 | #ifdef __powerpc__ | | 1287 | #if defined(__powerpc__) && !defined(__clang__) |
1288 | retaddr = hackish_return_address(); | | 1288 | retaddr = hackish_return_address(); |
1289 | #else | | 1289 | #else |
1290 | retaddr = __builtin_return_address(0); | | 1290 | retaddr = __builtin_return_address(0); |
1291 | #endif | | 1291 | #endif |
1292 | return do_dlsym(handle, name, NULL, retaddr); | | 1292 | return do_dlsym(handle, name, NULL, retaddr); |
1293 | } | | 1293 | } |
1294 | | | 1294 | |
1295 | __strong_alias(__dlvsym,dlvsym) | | 1295 | __strong_alias(__dlvsym,dlvsym) |
1296 | void * | | 1296 | void * |
1297 | dlvsym(void *handle, const char *name, const char *version) | | 1297 | dlvsym(void *handle, const char *name, const char *version) |
1298 | { | | 1298 | { |
1299 | Ver_Entry *ventry = NULL; | | 1299 | Ver_Entry *ventry = NULL; |
1300 | Ver_Entry ver_entry; | | 1300 | Ver_Entry ver_entry; |
1301 | void *retaddr; | | 1301 | void *retaddr; |
1302 | | | 1302 | |
1303 | dbg(("dlvsym of %s@%s in %p", name, version ? version : NULL, handle)); | | 1303 | dbg(("dlvsym of %s@%s in %p", name, version ? version : NULL, handle)); |
1304 | | | 1304 | |
1305 | if (version != NULL) { | | 1305 | if (version != NULL) { |
1306 | ver_entry.name = version; | | 1306 | ver_entry.name = version; |
1307 | ver_entry.file = NULL; | | 1307 | ver_entry.file = NULL; |
1308 | ver_entry.hash = _rtld_sysv_hash(version); | | 1308 | ver_entry.hash = _rtld_sysv_hash(version); |
1309 | ver_entry.flags = 0; | | 1309 | ver_entry.flags = 0; |
1310 | ventry = &ver_entry; | | 1310 | ventry = &ver_entry; |
1311 | } | | 1311 | } |
1312 | #ifdef __powerpc__ | | 1312 | #if defined(__powerpc__) && !defined(__clang__) |
1313 | retaddr = hackish_return_address(); | | 1313 | retaddr = hackish_return_address(); |
1314 | #else | | 1314 | #else |
1315 | retaddr = __builtin_return_address(0); | | 1315 | retaddr = __builtin_return_address(0); |
1316 | #endif | | 1316 | #endif |
1317 | return do_dlsym(handle, name, ventry, retaddr); | | 1317 | return do_dlsym(handle, name, ventry, retaddr); |
1318 | } | | 1318 | } |
1319 | | | 1319 | |
1320 | __strong_alias(__dladdr,dladdr) | | 1320 | __strong_alias(__dladdr,dladdr) |
1321 | int | | 1321 | int |
1322 | dladdr(const void *addr, Dl_info *info) | | 1322 | dladdr(const void *addr, Dl_info *info) |
1323 | { | | 1323 | { |
1324 | const Obj_Entry *obj; | | 1324 | const Obj_Entry *obj; |
1325 | const Elf_Sym *def, *best_def; | | 1325 | const Elf_Sym *def, *best_def; |
| @@ -1397,27 +1397,27 @@ dladdr(const void *addr, Dl_info *info) | | | @@ -1397,27 +1397,27 @@ dladdr(const void *addr, Dl_info *info) |
1397 | | | 1397 | |
1398 | __strong_alias(__dlinfo,dlinfo) | | 1398 | __strong_alias(__dlinfo,dlinfo) |
1399 | int | | 1399 | int |
1400 | dlinfo(void *handle, int req, void *v) | | 1400 | dlinfo(void *handle, int req, void *v) |
1401 | { | | 1401 | { |
1402 | const Obj_Entry *obj; | | 1402 | const Obj_Entry *obj; |
1403 | void *retaddr; | | 1403 | void *retaddr; |
1404 | | | 1404 | |
1405 | dbg(("dlinfo for %p %d", handle, req)); | | 1405 | dbg(("dlinfo for %p %d", handle, req)); |
1406 | | | 1406 | |
1407 | _rtld_shared_enter(); | | 1407 | _rtld_shared_enter(); |
1408 | | | 1408 | |
1409 | if (handle == RTLD_SELF) { | | 1409 | if (handle == RTLD_SELF) { |
1410 | #ifdef __powerpc__ | | 1410 | #if defined(__powerpc__) && !defined(__clang__) |
1411 | retaddr = hackish_return_address(); | | 1411 | retaddr = hackish_return_address(); |
1412 | #else | | 1412 | #else |
1413 | retaddr = __builtin_return_address(0); | | 1413 | retaddr = __builtin_return_address(0); |
1414 | #endif | | 1414 | #endif |
1415 | if ((obj = _rtld_obj_from_addr(retaddr)) == NULL) { | | 1415 | if ((obj = _rtld_obj_from_addr(retaddr)) == NULL) { |
1416 | _rtld_error("Cannot determine caller's shared object"); | | 1416 | _rtld_error("Cannot determine caller's shared object"); |
1417 | _rtld_shared_exit(); | | 1417 | _rtld_shared_exit(); |
1418 | return -1; | | 1418 | return -1; |
1419 | } | | 1419 | } |
1420 | } else { | | 1420 | } else { |
1421 | if ((obj = _rtld_dlcheck(handle)) == NULL) { | | 1421 | if ((obj = _rtld_dlcheck(handle)) == NULL) { |
1422 | _rtld_shared_exit(); | | 1422 | _rtld_shared_exit(); |
1423 | return -1; | | 1423 | return -1; |