aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile12
-rw-r--r--elf/dl-load.c37
-rw-r--r--elf/dl-open.c2
3 files changed, 44 insertions, 7 deletions
diff --git a/elf/Makefile b/elf/Makefile
index db6d4283ba..b18aafe8e7 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -86,16 +86,20 @@ endif
ifeq (yes,$(build-shared))
tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
constload1 order $(tests-vis-$(have-protected)) noload \
- $(tests-nodelete-$(have-z-nodelete))
+ $(tests-nodelete-$(have-z-nodelete)) \
+ $(tests-nodlopen-$(have-z-nodlopen))
tests-vis-yes = vismain
tests-nodelete-yes = nodelete
+tests-nodlopen-yes = nodlopen
endif
modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
testobj1_1 failobj constload2 constload3 \
dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \
- $(modules-nodelete-$(have-z-nodelete))
+ $(modules-nodelete-$(have-z-nodelete)) \
+ $(modules-nodlopen-$(have-z-nodlopen))
modules-vis-yes = vismod1 vismod2 vismod3
modules-nodelete-yes = nodelmod1 nodelmod2
+modules-nodlopen-yes = nodlopenmod
extra-objs += $(addsuffix .os,$(strip $(modules-names)))
include ../Rules
@@ -302,3 +306,7 @@ $(objpfx)noload.out: $(objpfx)testobj5.so
LDFLAGS-nodelmod1.so = -Wl,--enable-new-dtags,-z,nodelete
$(objpfx)nodelete: $(libdl)
$(objpfx)nodelete.out: $(objpfx)nodelmod1.so $(objpfx)nodelmod2.so
+
+LDFLAGS-nodlopenmod.so = -Wl,--enable-new-dtags,-z,nodlopen
+$(objpfx)nodlopen: $(libdl)
+$(objpfx)nodlopen.out: $(objpfx)nodlopenmod.so
diff --git a/elf/dl-load.c b/elf/dl-load.c
index fbf82e2068..1e5ad5073d 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -688,7 +688,7 @@ static
#endif
struct link_map *
_dl_map_object_from_fd (const char *name, int fd, char *realname,
- struct link_map *loader, int l_type, int noload)
+ struct link_map *loader, int l_type, int mode)
{
/* This is the expected ELF header. */
#define ELF32_CLASS ELFCLASS32
@@ -752,7 +752,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
return l;
}
- if (noload)
+ if (mode & RTLD_NOLOAD)
/* We are not supposed to load the object unless it is already
loaded. So return now. */
return NULL;
@@ -1097,6 +1097,35 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
}
elf_get_dynamic_info (l);
+
+ /* Make sure we are dlopen()ing an object which has the DF_1_NOOPEN
+ flag set. */
+ if (__builtin_expect (l->l_flags_1 & DF_1_NOOPEN, 0)
+ && (mode & __RTLD_DLOPEN))
+ {
+ /* Remove from the module list. */
+ assert (l->l_next == NULL);
+#ifdef SHARED
+ if (l->l_prev == NULL)
+ /* No other module loaded. */
+ _dl_loaded = NULL;
+ else
+#endif
+ l->l_prev->l_next = NULL;
+
+ /* We are not supposed to load this object. Free all resources. */
+ __munmap ((void *) l->l_map_start, l->l_map_end - l->l_map_start);
+
+ free (l->l_libname);
+
+ if (l->l_phdr_allocated)
+ free ((void *) l->l_phdr);
+
+ free (l);
+
+ _dl_signal_error (0, name, N_("shared object cannot be dlopen()ed"));
+ }
+
if (l->l_info[DT_HASH])
_dl_setup_hash (l);
@@ -1306,7 +1335,7 @@ open_path (const char *name, size_t namelen, int preloaded,
struct link_map *
internal_function
_dl_map_object (struct link_map *loader, const char *name, int preloaded,
- int type, int trace_mode, int noload)
+ int type, int trace_mode, int mode)
{
int fd;
char *realname;
@@ -1506,5 +1535,5 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
_dl_signal_error (errno, name, N_("cannot open shared object file"));
}
- return _dl_map_object_from_fd (name, fd, realname, loader, type, noload);
+ return _dl_map_object_from_fd (name, fd, realname, loader, type, mode);
}
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 477ecdf62e..60a8f1ad5b 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -145,7 +145,7 @@ dl_open_worker (void *a)
/* Load the named object. */
args->map = new = _dl_map_object (NULL, file, 0, lt_loaded, 0,
- mode & RTLD_NOLOAD);
+ mode);
/* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
set and the object is not already loaded. */