Back to index

glibc  2.9
dlmopen.c
Go to the documentation of this file.
00001 /* Load a shared object at run time.
00002    Copyright (C) 1995-2000,2003,2004,2006 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <dlfcn.h>
00021 #include <errno.h>
00022 #include <libintl.h>
00023 #include <stddef.h>
00024 #include <unistd.h>
00025 #include <ldsodefs.h>
00026 
00027 #if !defined SHARED && defined IS_IN_libdl
00028 
00029 void *
00030 dlmopen (Lmid_t nsid, const char *file, int mode)
00031 {
00032   return __dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
00033 }
00034 static_link_warning (dlmopen)
00035 
00036 #else
00037 
00038 struct dlmopen_args
00039 {
00040   /* Namespace ID.  */
00041   Lmid_t nsid;
00042   /* The arguments for dlopen_doit.  */
00043   const char *file;
00044   int mode;
00045   /* The return value of dlopen_doit.  */
00046   void *new;
00047   /* Address of the caller.  */
00048   const void *caller;
00049 };
00050 
00051 static void
00052 dlmopen_doit (void *a)
00053 {
00054   struct dlmopen_args *args = (struct dlmopen_args *) a;
00055 
00056   /* Non-shared code has no support for multiple namespaces.  */
00057   if (args->nsid != LM_ID_BASE)
00058     {
00059 # ifdef SHARED
00060       /* If trying to open the link map for the main executable the namespace
00061         must be the main one.  */
00062       if (args->file == NULL)
00063 # endif
00064        GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
00065 
00066       /* It makes no sense to use RTLD_GLOBAL when loading a DSO into
00067         a namespace other than the base namespace.  */
00068       if (__builtin_expect (args->mode & RTLD_GLOBAL, 0))
00069        GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid mode"));
00070     }
00071 
00072   args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
00073                           args->caller,
00074                           args->nsid, __dlfcn_argc, __dlfcn_argv,
00075                           __environ);
00076 }
00077 
00078 
00079 void *
00080 __dlmopen (Lmid_t nsid, const char *file, int mode DL_CALLER_DECL)
00081 {
00082 # ifdef SHARED
00083   if (__builtin_expect (_dlfcn_hook != NULL, 0))
00084     return _dlfcn_hook->dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
00085 # endif
00086 
00087   struct dlmopen_args args;
00088   args.nsid = nsid;
00089   args.file = file;
00090   args.mode = mode;
00091   args.caller = DL_CALLER;
00092 
00093 # ifdef SHARED
00094   return _dlerror_run (dlmopen_doit, &args) ? NULL : args.new;
00095 # else
00096   if (_dlerror_run (dlmopen_doit, &args))
00097     return NULL;
00098 
00099   __libc_register_dl_open_hook ((struct link_map *) args.new);
00100   __libc_register_dlfcn_hook ((struct link_map *) args.new);
00101 
00102   return args.new;
00103 # endif
00104 }
00105 # ifdef SHARED
00106 strong_alias (__dlmopen, dlmopen)
00107 # endif
00108 #endif