Implement RTLD_NOLOAD flag for dlopen(3).
Requested and tested by: jkim Reviewed by: kan Approved by: re (kensmith)
This commit is contained in:
parent
874bb76647
commit
49e8c06b45
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=195745
@ -48,6 +48,7 @@
|
||||
#define RTLD_LOCAL 0 /* Opposite of RTLD_GLOBAL, and the default. */
|
||||
#define RTLD_TRACE 0x200 /* Trace loaded objects and exit. */
|
||||
#define RTLD_NODELETE 0x01000 /* Do not remove members. */
|
||||
#define RTLD_NOLOAD 0x02000 /* Do not load if not already loaded. */
|
||||
|
||||
/*
|
||||
* Request arguments for dlinfo().
|
||||
|
@ -32,7 +32,7 @@
|
||||
.\" @(#) dlopen.3 1.6 90/01/31 SMI
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 1, 2009
|
||||
.Dd July 7, 2009
|
||||
.Os
|
||||
.Dt DLOPEN 3
|
||||
.Sh NAME
|
||||
@ -148,6 +148,13 @@ The same behaviour may be requested by
|
||||
.Fl "z nodelete"
|
||||
option of the static linker
|
||||
.Xr ld 1 .
|
||||
.It Dv RTLD_NOLOAD
|
||||
Ony return valid handle for the object if it is already loaded in
|
||||
the process address space, otherwise
|
||||
.Dv NULL
|
||||
is returned.
|
||||
Other mode flags may be specified, which will be applied for promotion
|
||||
for the found object.
|
||||
.El
|
||||
.Pp
|
||||
If
|
||||
|
@ -105,7 +105,7 @@ static void linkmap_add(Obj_Entry *);
|
||||
static void linkmap_delete(Obj_Entry *);
|
||||
static int load_needed_objects(Obj_Entry *);
|
||||
static int load_preload_objects(void);
|
||||
static Obj_Entry *load_object(const char *, const Obj_Entry *);
|
||||
static Obj_Entry *load_object(const char *, const Obj_Entry *, int);
|
||||
static Obj_Entry *obj_from_addr(const void *);
|
||||
static void objlist_call_fini(Objlist *, bool, int *);
|
||||
static void objlist_call_init(Objlist *, int *);
|
||||
@ -1432,7 +1432,8 @@ load_needed_objects(Obj_Entry *first)
|
||||
Needed_Entry *needed;
|
||||
|
||||
for (needed = obj->needed; needed != NULL; needed = needed->next) {
|
||||
obj1 = needed->obj = load_object(obj->strtab + needed->name, obj);
|
||||
obj1 = needed->obj = load_object(obj->strtab + needed->name, obj,
|
||||
false);
|
||||
if (obj1 == NULL && !ld_tracing)
|
||||
return -1;
|
||||
if (obj1 != NULL && obj1->z_nodelete && !obj1->ref_nodel) {
|
||||
@ -1463,7 +1464,7 @@ load_preload_objects(void)
|
||||
|
||||
savech = p[len];
|
||||
p[len] = '\0';
|
||||
if (load_object(p, NULL) == NULL)
|
||||
if (load_object(p, NULL, false) == NULL)
|
||||
return -1; /* XXX - cleanup */
|
||||
p[len] = savech;
|
||||
p += len;
|
||||
@ -1480,7 +1481,7 @@ load_preload_objects(void)
|
||||
* on failure.
|
||||
*/
|
||||
static Obj_Entry *
|
||||
load_object(const char *name, const Obj_Entry *refobj)
|
||||
load_object(const char *name, const Obj_Entry *refobj, int noload)
|
||||
{
|
||||
Obj_Entry *obj;
|
||||
int fd = -1;
|
||||
@ -1526,6 +1527,8 @@ load_object(const char *name, const Obj_Entry *refobj)
|
||||
close(fd);
|
||||
return obj;
|
||||
}
|
||||
if (noload)
|
||||
return (NULL);
|
||||
|
||||
/* First use of this object, so we must map it in */
|
||||
obj = do_load_object(fd, name, path, &sb);
|
||||
@ -1982,13 +1985,14 @@ dlopen(const char *name, int mode)
|
||||
Obj_Entry **old_obj_tail;
|
||||
Obj_Entry *obj;
|
||||
Objlist initlist;
|
||||
int result, lockstate, nodelete;
|
||||
int result, lockstate, nodelete, noload;
|
||||
|
||||
LD_UTRACE(UTRACE_DLOPEN_START, NULL, NULL, 0, mode, name);
|
||||
ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1";
|
||||
if (ld_tracing != NULL)
|
||||
environ = (char **)*get_program_var_addr("environ");
|
||||
nodelete = mode & RTLD_NODELETE;
|
||||
noload = mode & RTLD_NOLOAD;
|
||||
|
||||
objlist_init(&initlist);
|
||||
|
||||
@ -2001,7 +2005,7 @@ dlopen(const char *name, int mode)
|
||||
obj = obj_main;
|
||||
obj->refcount++;
|
||||
} else {
|
||||
obj = load_object(name, obj_main);
|
||||
obj = load_object(name, obj_main, noload);
|
||||
}
|
||||
|
||||
if (obj) {
|
||||
|
Loading…
Reference in New Issue
Block a user