]>
Commit | Line | Data |
---|---|---|
c84142e8 | 1 | /* Load a shared object at run time. |
04277e02 | 2 | Copyright (C) 1995-2019 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 | |
d66e34cd | 19 | #include <dlfcn.h> |
3e539cb4 | 20 | #include <libintl.h> |
b2b28911 | 21 | #include <stddef.h> |
9dcafc55 UD |
22 | #include <unistd.h> |
23 | #include <ldsodefs.h> | |
d66e34cd | 24 | |
9b42a0b3 | 25 | #if !defined SHARED && IS_IN (libdl) |
5f21997b UD |
26 | |
27 | void * | |
28 | dlopen (const char *file, int mode) | |
29 | { | |
30 | return __dlopen (file, mode, RETURN_ADDRESS (0)); | |
31 | } | |
32 | static_link_warning (dlopen) | |
33 | ||
34 | #else | |
35 | ||
993b3242 | 36 | struct dlopen_args |
d66e34cd | 37 | { |
993b3242 UD |
38 | /* The arguments for dlopen_doit. */ |
39 | const char *file; | |
40 | int mode; | |
41 | /* The return value of dlopen_doit. */ | |
94e365c6 | 42 | void *new; |
dc5efe83 UD |
43 | /* Address of the caller. */ |
44 | const void *caller; | |
993b3242 UD |
45 | }; |
46 | ||
c0f62c56 UD |
47 | |
48 | /* Non-shared code has no support for multiple namespaces. */ | |
5f21997b UD |
49 | # ifdef SHARED |
50 | # define NS __LM_ID_CALLER | |
51 | # else | |
52 | # define NS LM_ID_BASE | |
53 | # endif | |
c0f62c56 UD |
54 | |
55 | ||
993b3242 UD |
56 | static void |
57 | dlopen_doit (void *a) | |
58 | { | |
59 | struct dlopen_args *args = (struct dlopen_args *) a; | |
60 | ||
3e539cb4 | 61 | if (args->mode & ~(RTLD_BINDING_MASK | RTLD_NOLOAD | RTLD_DEEPBIND |
0a26fc4d UD |
62 | | RTLD_GLOBAL | RTLD_LOCAL | RTLD_NODELETE |
63 | | __RTLD_SPROF)) | |
9e78f6f6 | 64 | _dl_signal_error (0, NULL, NULL, _("invalid mode parameter")); |
3e539cb4 | 65 | |
9dcafc55 UD |
66 | args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN, |
67 | args->caller, | |
68 | args->file == NULL ? LM_ID_BASE : NS, | |
69 | __dlfcn_argc, __dlfcn_argv, __environ); | |
993b3242 UD |
70 | } |
71 | ||
72 | ||
73 | void * | |
5f21997b | 74 | __dlopen (const char *file, int mode DL_CALLER_DECL) |
993b3242 | 75 | { |
5f21997b | 76 | # ifdef SHARED |
8e1472d2 | 77 | if (!rtld_active ()) |
5f21997b UD |
78 | return _dlfcn_hook->dlopen (file, mode, DL_CALLER); |
79 | # endif | |
80 | ||
993b3242 UD |
81 | struct dlopen_args args; |
82 | args.file = file; | |
83 | args.mode = mode; | |
5f21997b | 84 | args.caller = DL_CALLER; |
d66e34cd | 85 | |
5f21997b | 86 | # ifdef SHARED |
993b3242 | 87 | return _dlerror_run (dlopen_doit, &args) ? NULL : args.new; |
5f21997b UD |
88 | # else |
89 | if (_dlerror_run (dlopen_doit, &args)) | |
90 | return NULL; | |
91 | ||
92 | __libc_register_dl_open_hook ((struct link_map *) args.new); | |
93 | __libc_register_dlfcn_hook ((struct link_map *) args.new); | |
94 | ||
95 | return args.new; | |
96 | # endif | |
d66e34cd | 97 | } |
5f21997b UD |
98 | # ifdef SHARED |
99 | # include <shlib-compat.h> | |
100 | strong_alias (__dlopen, __dlopen_check) | |
16710d58 | 101 | versioned_symbol (libdl, __dlopen_check, dlopen, GLIBC_2_1); |
5f21997b UD |
102 | # endif |
103 | #endif |