summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorpk <pk@NetBSD.org>1998-03-15 23:10:21 +0000
committerpk <pk@NetBSD.org>1998-03-15 23:10:21 +0000
commit5ea8bb6d05e7d4385cbaf77be4be72bb675ca71b (patch)
treef7b58401b67cf94d5de44c579b2d50a4c747c568 /libexec
parent78836acdbad05cfb260e990e1a5d9202fff7ad5a (diff)
Implement RTLD_GLOBAL dlopen(3) flag.
Rename internal flags to avoid <dlfcn.h> name space collisions.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.aout_so/rtld.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/libexec/ld.aout_so/rtld.c b/libexec/ld.aout_so/rtld.c
index 0ab976ab789..a8a51dad4c0 100644
--- a/libexec/ld.aout_so/rtld.c
+++ b/libexec/ld.aout_so/rtld.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.56 1998/03/15 21:24:27 pk Exp $ */
+/* $NetBSD: rtld.c,v 1.57 1998/03/15 23:10:21 pk Exp $ */
/*
* Copyright (c) 1993 Paul Kranenburg
@@ -91,9 +91,10 @@ struct somap_private {
struct so_map *spd_parent;
int spd_refcount;
int spd_flags;
-#define RTLD_MAIN 1 /* Marks the main program */
-#define RTLD_RTLD 2 /* Marks the run-time linker */
-#define RTLD_DL 4 /* A dlopen'ed object */
+#define _RTLD_MAIN 1 /* Marks the main program */
+#define _RTLD_RTLD 2 /* Marks the run-time linker */
+#define _RTLD_DL 4 /* A dlopen'ed object */
+#define _RTLD_GLOBAL 8 /* Map is open to global search */
size_t spd_size;
#ifdef SUN_COMPAT
@@ -342,12 +343,12 @@ rtld(version, crtp, dp)
smp = alloc_link_map(main_progname, (struct sod *)0, (struct so_map *)0,
(caddr_t)0, 0, crtp->crt_dp);
LM_PRIVATE(smp)->spd_refcount++;
- LM_PRIVATE(smp)->spd_flags |= RTLD_MAIN;
+ LM_PRIVATE(smp)->spd_flags |= _RTLD_MAIN | _RTLD_GLOBAL;
smp = alloc_link_map(us, (struct sod *)0, (struct so_map *)0,
(caddr_t)crtp->crt_ba, 0, dp);
LM_PRIVATE(smp)->spd_refcount++;
- LM_PRIVATE(smp)->spd_flags |= RTLD_RTLD;
+ LM_PRIVATE(smp)->spd_flags |= _RTLD_RTLD;
/* Handle LD_PRELOAD's here */
ld_preload_path = getenv("LD_PRELOAD");
@@ -407,12 +408,16 @@ static int
load_subs(smp)
struct so_map *smp;
{
+ int flag = 0;
+
+ /* Propagate _RTLD_GLOBAL parent flag */
+ flag |= (LM_PRIVATE(smp)->spd_flags & _RTLD_GLOBAL);
for (; smp; smp = smp->som_next) {
struct sod *sodp;
long next = 0;
- if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
continue;
if (smp->som_dynamic)
@@ -436,6 +441,8 @@ load_subs(smp)
newmap = alloc_link_map(NULL, sodp, smp, 0, 0, 0);
}
LM_PRIVATE(newmap)->spd_refcount++;
+ /* Note: existing maps also acquire the new flag */
+ LM_PRIVATE(newmap)->spd_flags |= flag;
next = sodp->sod_next;
}
}
@@ -581,7 +588,7 @@ free_link_map(smp)
struct so_map *smp;
{
- if ((LM_PRIVATE(smp)->spd_flags & RTLD_DL) != 0) {
+ if ((LM_PRIVATE(smp)->spd_flags & _RTLD_DL) != 0) {
/* free synthetic sod structure allocated in __dlopen() */
free((char *)smp->som_sod->sod_name);
free(smp->som_sod);
@@ -746,21 +753,21 @@ init_maps(head)
/* Relocate all loaded objects according to their RRS segments */
for (smp = head; smp; smp = smp->som_next) {
- if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
continue;
reloc_map(smp);
}
/* Copy any relocated initialized data. */
for (smp = head; smp; smp = smp->som_next) {
- if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
continue;
reloc_copy(smp);
}
/* Call any object initialization routines. */
for (smp = head; smp; smp = smp->som_next) {
- if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
continue;
call_map(smp, ".init");
call_map(smp, "__init");
@@ -1054,10 +1061,18 @@ lookup(name, src_map, strong)
if (*src_map && smp != *src_map)
continue;
+ /*
+ * When doing a global search, consider only maps
+ * marked for global lookup.
+ */
+ if (*src_map == NULL &&
+ (LM_PRIVATE(smp)->spd_flags & _RTLD_GLOBAL) == 0)
+ continue;
+
if ((buckets = LD_BUCKETS(smp->som_dynamic)) == 0)
continue;
- if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
continue;
restart:
@@ -1449,6 +1464,7 @@ preload(paths)
errx(1, "preload: %s: cannot map object", cp);
}
LM_PRIVATE(nsmp)->spd_refcount++;
+ LM_PRIVATE(nsmp)->spd_flags |= _RTLD_GLOBAL;
}
free(paths);
return;
@@ -1581,6 +1597,8 @@ xprintf("%s: %s\n", name, strerror(errno));
free(sodp);
return NULL;
}
+ if ((mode & RTLD_GLOBAL) != 0)
+ LM_PRIVATE(smp)->spd_flags |= _RTLD_GLOBAL;
if (LM_PRIVATE(smp)->spd_refcount++ > 0) {
free((char *)sodp->sod_name);
@@ -1588,7 +1606,7 @@ xprintf("%s: %s\n", name, strerror(errno));
return smp;
}
- LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
+ LM_PRIVATE(smp)->spd_flags |= _RTLD_DL;
if (load_subs(smp) != 0) {
if (--LM_PRIVATE(smp)->spd_refcount == 0) {
@@ -1618,7 +1636,7 @@ xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refc
if (--LM_PRIVATE(smp)->spd_refcount != 0)
return 0;
- if ((LM_PRIVATE(smp)->spd_flags & RTLD_DL) == 0)
+ if ((LM_PRIVATE(smp)->spd_flags & _RTLD_DL) == 0)
return 0;
/* Dismantle shared object map and descriptor */
@@ -1683,7 +1701,7 @@ __dlexit()
/* Call any object initialization routines. */
for (smp = link_map_head; smp; smp = smp->som_next) {
- if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
continue;
call_map(smp, ".fini");
}