Implement RTLD_GLOBAL dlopen(3) flag.
Rename internal flags to avoid <dlfcn.h> name space collisions.
This commit is contained in:
parent
78836acdba
commit
5ea8bb6d05
|
@ -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
|
* Copyright (c) 1993 Paul Kranenburg
|
||||||
|
@ -91,9 +91,10 @@ struct somap_private {
|
||||||
struct so_map *spd_parent;
|
struct so_map *spd_parent;
|
||||||
int spd_refcount;
|
int spd_refcount;
|
||||||
int spd_flags;
|
int spd_flags;
|
||||||
#define RTLD_MAIN 1 /* Marks the main program */
|
#define _RTLD_MAIN 1 /* Marks the main program */
|
||||||
#define RTLD_RTLD 2 /* Marks the run-time linker */
|
#define _RTLD_RTLD 2 /* Marks the run-time linker */
|
||||||
#define RTLD_DL 4 /* A dlopen'ed object */
|
#define _RTLD_DL 4 /* A dlopen'ed object */
|
||||||
|
#define _RTLD_GLOBAL 8 /* Map is open to global search */
|
||||||
size_t spd_size;
|
size_t spd_size;
|
||||||
|
|
||||||
#ifdef SUN_COMPAT
|
#ifdef SUN_COMPAT
|
||||||
|
@ -342,12 +343,12 @@ rtld(version, crtp, dp)
|
||||||
smp = alloc_link_map(main_progname, (struct sod *)0, (struct so_map *)0,
|
smp = alloc_link_map(main_progname, (struct sod *)0, (struct so_map *)0,
|
||||||
(caddr_t)0, 0, crtp->crt_dp);
|
(caddr_t)0, 0, crtp->crt_dp);
|
||||||
LM_PRIVATE(smp)->spd_refcount++;
|
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,
|
smp = alloc_link_map(us, (struct sod *)0, (struct so_map *)0,
|
||||||
(caddr_t)crtp->crt_ba, 0, dp);
|
(caddr_t)crtp->crt_ba, 0, dp);
|
||||||
LM_PRIVATE(smp)->spd_refcount++;
|
LM_PRIVATE(smp)->spd_refcount++;
|
||||||
LM_PRIVATE(smp)->spd_flags |= RTLD_RTLD;
|
LM_PRIVATE(smp)->spd_flags |= _RTLD_RTLD;
|
||||||
|
|
||||||
/* Handle LD_PRELOAD's here */
|
/* Handle LD_PRELOAD's here */
|
||||||
ld_preload_path = getenv("LD_PRELOAD");
|
ld_preload_path = getenv("LD_PRELOAD");
|
||||||
|
@ -407,12 +408,16 @@ static int
|
||||||
load_subs(smp)
|
load_subs(smp)
|
||||||
struct so_map *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) {
|
for (; smp; smp = smp->som_next) {
|
||||||
struct sod *sodp;
|
struct sod *sodp;
|
||||||
long next = 0;
|
long next = 0;
|
||||||
|
|
||||||
if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
|
if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (smp->som_dynamic)
|
if (smp->som_dynamic)
|
||||||
|
@ -436,6 +441,8 @@ load_subs(smp)
|
||||||
newmap = alloc_link_map(NULL, sodp, smp, 0, 0, 0);
|
newmap = alloc_link_map(NULL, sodp, smp, 0, 0, 0);
|
||||||
}
|
}
|
||||||
LM_PRIVATE(newmap)->spd_refcount++;
|
LM_PRIVATE(newmap)->spd_refcount++;
|
||||||
|
/* Note: existing maps also acquire the new flag */
|
||||||
|
LM_PRIVATE(newmap)->spd_flags |= flag;
|
||||||
next = sodp->sod_next;
|
next = sodp->sod_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,7 +588,7 @@ free_link_map(smp)
|
||||||
struct so_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 synthetic sod structure allocated in __dlopen() */
|
||||||
free((char *)smp->som_sod->sod_name);
|
free((char *)smp->som_sod->sod_name);
|
||||||
free(smp->som_sod);
|
free(smp->som_sod);
|
||||||
|
@ -746,21 +753,21 @@ init_maps(head)
|
||||||
|
|
||||||
/* Relocate all loaded objects according to their RRS segments */
|
/* Relocate all loaded objects according to their RRS segments */
|
||||||
for (smp = head; smp; smp = smp->som_next) {
|
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;
|
continue;
|
||||||
reloc_map(smp);
|
reloc_map(smp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy any relocated initialized data. */
|
/* Copy any relocated initialized data. */
|
||||||
for (smp = head; smp; smp = smp->som_next) {
|
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;
|
continue;
|
||||||
reloc_copy(smp);
|
reloc_copy(smp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call any object initialization routines. */
|
/* Call any object initialization routines. */
|
||||||
for (smp = head; smp; smp = smp->som_next) {
|
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;
|
continue;
|
||||||
call_map(smp, ".init");
|
call_map(smp, ".init");
|
||||||
call_map(smp, "__init");
|
call_map(smp, "__init");
|
||||||
|
@ -1054,10 +1061,18 @@ lookup(name, src_map, strong)
|
||||||
if (*src_map && smp != *src_map)
|
if (*src_map && smp != *src_map)
|
||||||
continue;
|
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)
|
if ((buckets = LD_BUCKETS(smp->som_dynamic)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
|
if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
|
@ -1449,6 +1464,7 @@ preload(paths)
|
||||||
errx(1, "preload: %s: cannot map object", cp);
|
errx(1, "preload: %s: cannot map object", cp);
|
||||||
}
|
}
|
||||||
LM_PRIVATE(nsmp)->spd_refcount++;
|
LM_PRIVATE(nsmp)->spd_refcount++;
|
||||||
|
LM_PRIVATE(nsmp)->spd_flags |= _RTLD_GLOBAL;
|
||||||
}
|
}
|
||||||
free(paths);
|
free(paths);
|
||||||
return;
|
return;
|
||||||
|
@ -1581,6 +1597,8 @@ xprintf("%s: %s\n", name, strerror(errno));
|
||||||
free(sodp);
|
free(sodp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if ((mode & RTLD_GLOBAL) != 0)
|
||||||
|
LM_PRIVATE(smp)->spd_flags |= _RTLD_GLOBAL;
|
||||||
|
|
||||||
if (LM_PRIVATE(smp)->spd_refcount++ > 0) {
|
if (LM_PRIVATE(smp)->spd_refcount++ > 0) {
|
||||||
free((char *)sodp->sod_name);
|
free((char *)sodp->sod_name);
|
||||||
|
@ -1588,7 +1606,7 @@ xprintf("%s: %s\n", name, strerror(errno));
|
||||||
return smp;
|
return smp;
|
||||||
}
|
}
|
||||||
|
|
||||||
LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
|
LM_PRIVATE(smp)->spd_flags |= _RTLD_DL;
|
||||||
|
|
||||||
if (load_subs(smp) != 0) {
|
if (load_subs(smp) != 0) {
|
||||||
if (--LM_PRIVATE(smp)->spd_refcount == 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)
|
if (--LM_PRIVATE(smp)->spd_refcount != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((LM_PRIVATE(smp)->spd_flags & RTLD_DL) == 0)
|
if ((LM_PRIVATE(smp)->spd_flags & _RTLD_DL) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Dismantle shared object map and descriptor */
|
/* Dismantle shared object map and descriptor */
|
||||||
|
@ -1683,7 +1701,7 @@ __dlexit()
|
||||||
|
|
||||||
/* Call any object initialization routines. */
|
/* Call any object initialization routines. */
|
||||||
for (smp = link_map_head; smp; smp = smp->som_next) {
|
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;
|
continue;
|
||||||
call_map(smp, ".fini");
|
call_map(smp, ".fini");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* Copyright (c) 1993 Paul Kranenburg
|
||||||
|
@ -91,9 +91,10 @@ struct somap_private {
|
||||||
struct so_map *spd_parent;
|
struct so_map *spd_parent;
|
||||||
int spd_refcount;
|
int spd_refcount;
|
||||||
int spd_flags;
|
int spd_flags;
|
||||||
#define RTLD_MAIN 1 /* Marks the main program */
|
#define _RTLD_MAIN 1 /* Marks the main program */
|
||||||
#define RTLD_RTLD 2 /* Marks the run-time linker */
|
#define _RTLD_RTLD 2 /* Marks the run-time linker */
|
||||||
#define RTLD_DL 4 /* A dlopen'ed object */
|
#define _RTLD_DL 4 /* A dlopen'ed object */
|
||||||
|
#define _RTLD_GLOBAL 8 /* Map is open to global search */
|
||||||
size_t spd_size;
|
size_t spd_size;
|
||||||
|
|
||||||
#ifdef SUN_COMPAT
|
#ifdef SUN_COMPAT
|
||||||
|
@ -342,12 +343,12 @@ rtld(version, crtp, dp)
|
||||||
smp = alloc_link_map(main_progname, (struct sod *)0, (struct so_map *)0,
|
smp = alloc_link_map(main_progname, (struct sod *)0, (struct so_map *)0,
|
||||||
(caddr_t)0, 0, crtp->crt_dp);
|
(caddr_t)0, 0, crtp->crt_dp);
|
||||||
LM_PRIVATE(smp)->spd_refcount++;
|
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,
|
smp = alloc_link_map(us, (struct sod *)0, (struct so_map *)0,
|
||||||
(caddr_t)crtp->crt_ba, 0, dp);
|
(caddr_t)crtp->crt_ba, 0, dp);
|
||||||
LM_PRIVATE(smp)->spd_refcount++;
|
LM_PRIVATE(smp)->spd_refcount++;
|
||||||
LM_PRIVATE(smp)->spd_flags |= RTLD_RTLD;
|
LM_PRIVATE(smp)->spd_flags |= _RTLD_RTLD;
|
||||||
|
|
||||||
/* Handle LD_PRELOAD's here */
|
/* Handle LD_PRELOAD's here */
|
||||||
ld_preload_path = getenv("LD_PRELOAD");
|
ld_preload_path = getenv("LD_PRELOAD");
|
||||||
|
@ -407,12 +408,16 @@ static int
|
||||||
load_subs(smp)
|
load_subs(smp)
|
||||||
struct so_map *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) {
|
for (; smp; smp = smp->som_next) {
|
||||||
struct sod *sodp;
|
struct sod *sodp;
|
||||||
long next = 0;
|
long next = 0;
|
||||||
|
|
||||||
if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
|
if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (smp->som_dynamic)
|
if (smp->som_dynamic)
|
||||||
|
@ -436,6 +441,8 @@ load_subs(smp)
|
||||||
newmap = alloc_link_map(NULL, sodp, smp, 0, 0, 0);
|
newmap = alloc_link_map(NULL, sodp, smp, 0, 0, 0);
|
||||||
}
|
}
|
||||||
LM_PRIVATE(newmap)->spd_refcount++;
|
LM_PRIVATE(newmap)->spd_refcount++;
|
||||||
|
/* Note: existing maps also acquire the new flag */
|
||||||
|
LM_PRIVATE(newmap)->spd_flags |= flag;
|
||||||
next = sodp->sod_next;
|
next = sodp->sod_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,7 +588,7 @@ free_link_map(smp)
|
||||||
struct so_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 synthetic sod structure allocated in __dlopen() */
|
||||||
free((char *)smp->som_sod->sod_name);
|
free((char *)smp->som_sod->sod_name);
|
||||||
free(smp->som_sod);
|
free(smp->som_sod);
|
||||||
|
@ -746,21 +753,21 @@ init_maps(head)
|
||||||
|
|
||||||
/* Relocate all loaded objects according to their RRS segments */
|
/* Relocate all loaded objects according to their RRS segments */
|
||||||
for (smp = head; smp; smp = smp->som_next) {
|
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;
|
continue;
|
||||||
reloc_map(smp);
|
reloc_map(smp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy any relocated initialized data. */
|
/* Copy any relocated initialized data. */
|
||||||
for (smp = head; smp; smp = smp->som_next) {
|
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;
|
continue;
|
||||||
reloc_copy(smp);
|
reloc_copy(smp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call any object initialization routines. */
|
/* Call any object initialization routines. */
|
||||||
for (smp = head; smp; smp = smp->som_next) {
|
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;
|
continue;
|
||||||
call_map(smp, ".init");
|
call_map(smp, ".init");
|
||||||
call_map(smp, "__init");
|
call_map(smp, "__init");
|
||||||
|
@ -1054,10 +1061,18 @@ lookup(name, src_map, strong)
|
||||||
if (*src_map && smp != *src_map)
|
if (*src_map && smp != *src_map)
|
||||||
continue;
|
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)
|
if ((buckets = LD_BUCKETS(smp->som_dynamic)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
|
if (LM_PRIVATE(smp)->spd_flags & _RTLD_RTLD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
|
@ -1449,6 +1464,7 @@ preload(paths)
|
||||||
errx(1, "preload: %s: cannot map object", cp);
|
errx(1, "preload: %s: cannot map object", cp);
|
||||||
}
|
}
|
||||||
LM_PRIVATE(nsmp)->spd_refcount++;
|
LM_PRIVATE(nsmp)->spd_refcount++;
|
||||||
|
LM_PRIVATE(nsmp)->spd_flags |= _RTLD_GLOBAL;
|
||||||
}
|
}
|
||||||
free(paths);
|
free(paths);
|
||||||
return;
|
return;
|
||||||
|
@ -1581,6 +1597,8 @@ xprintf("%s: %s\n", name, strerror(errno));
|
||||||
free(sodp);
|
free(sodp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if ((mode & RTLD_GLOBAL) != 0)
|
||||||
|
LM_PRIVATE(smp)->spd_flags |= _RTLD_GLOBAL;
|
||||||
|
|
||||||
if (LM_PRIVATE(smp)->spd_refcount++ > 0) {
|
if (LM_PRIVATE(smp)->spd_refcount++ > 0) {
|
||||||
free((char *)sodp->sod_name);
|
free((char *)sodp->sod_name);
|
||||||
|
@ -1588,7 +1606,7 @@ xprintf("%s: %s\n", name, strerror(errno));
|
||||||
return smp;
|
return smp;
|
||||||
}
|
}
|
||||||
|
|
||||||
LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
|
LM_PRIVATE(smp)->spd_flags |= _RTLD_DL;
|
||||||
|
|
||||||
if (load_subs(smp) != 0) {
|
if (load_subs(smp) != 0) {
|
||||||
if (--LM_PRIVATE(smp)->spd_refcount == 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)
|
if (--LM_PRIVATE(smp)->spd_refcount != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((LM_PRIVATE(smp)->spd_flags & RTLD_DL) == 0)
|
if ((LM_PRIVATE(smp)->spd_flags & _RTLD_DL) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Dismantle shared object map and descriptor */
|
/* Dismantle shared object map and descriptor */
|
||||||
|
@ -1683,7 +1701,7 @@ __dlexit()
|
||||||
|
|
||||||
/* Call any object initialization routines. */
|
/* Call any object initialization routines. */
|
||||||
for (smp = link_map_head; smp; smp = smp->som_next) {
|
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;
|
continue;
|
||||||
call_map(smp, ".fini");
|
call_map(smp, ".fini");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue