Author: kib
Date: Fri Jul 17 19:45:42 2009
New Revision: 195745
URL: http://svn.freebsd.org/changeset/base/195745
Log:
Implement RTLD_NOLOAD flag for dlopen(3).
Requested and tested by: jkim
Reviewed by: kan
Approved by: re (kensmith)
Modified:
head/include/dlfcn.h
head/lib/libc/gen/dlopen.3
head/libexec/rtld-elf/rtld.c
Modified: head/include/dlfcn.h
==
--- head/include/dlfcn.hFri Jul 17 19:38:07 2009(r195744)
+++ head/include/dlfcn.hFri Jul 17 19:45:42 2009(r195745)
@@ -48,6 +48,7 @@
#defineRTLD_LOCAL 0 /* Opposite of RTLD_GLOBAL, and the
default. */
#defineRTLD_TRACE 0x200 /* Trace loaded objects and exit. */
#defineRTLD_NODELETE 0x01000 /* Do not remove members. */
+#defineRTLD_NOLOAD 0x02000 /* Do not load if not already loaded. */
/*
* Request arguments for dlinfo().
Modified: head/lib/libc/gen/dlopen.3
==
--- head/lib/libc/gen/dlopen.3 Fri Jul 17 19:38:07 2009(r195744)
+++ head/lib/libc/gen/dlopen.3 Fri Jul 17 19:45:42 2009(r195745)
@@ -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
Modified: head/libexec/rtld-elf/rtld.c
==
--- head/libexec/rtld-elf/rtld.cFri Jul 17 19:38:07 2009
(r195744)
+++ head/libexec/rtld-elf/rtld.cFri Jul 17 19:45:42 2009
(r195745)
@@ -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_
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) {
___
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to svn-src-all-unsubscr...@freebsd.org