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.h        Fri Jul 17 19:38:07 2009        (r195744)
+++ head/include/dlfcn.h        Fri Jul 17 19:45:42 2009        (r195745)
@@ -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().

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.c        Fri Jul 17 19:38:07 2009        
(r195744)
+++ head/libexec/rtld-elf/rtld.c        Fri 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"

Reply via email to