diff options
author | kib <kib@FreeBSD.org> | 2009-07-17 19:45:42 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-07-17 19:45:42 +0000 |
commit | a106aba3da6cf54be8c26869ab0827d68235af9d (patch) | |
tree | 69ab2c09c37b5924f7909584ef7c3c9d0b31c062 | |
parent | db1bf25adde7f22207c0905ba9e8d3ff76ea87d4 (diff) | |
download | FreeBSD-src-a106aba3da6cf54be8c26869ab0827d68235af9d.zip FreeBSD-src-a106aba3da6cf54be8c26869ab0827d68235af9d.tar.gz |
Implement RTLD_NOLOAD flag for dlopen(3).
Requested and tested by: jkim
Reviewed by: kan
Approved by: re (kensmith)
-rw-r--r-- | include/dlfcn.h | 1 | ||||
-rw-r--r-- | lib/libc/gen/dlopen.3 | 9 | ||||
-rw-r--r-- | libexec/rtld-elf/rtld.c | 16 |
3 files changed, 19 insertions, 7 deletions
diff --git a/include/dlfcn.h b/include/dlfcn.h index 9fac620..b1a9738 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -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(). diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3 index 187f817..6488bef 100644 --- a/lib/libc/gen/dlopen.3 +++ b/lib/libc/gen/dlopen.3 @@ -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 diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 56634c5..721fe89 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -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) { |