svn commit: r190543 - in head: include libexec/rtld-elf sys/sys
Robert Noland
rnoland at FreeBSD.org
Mon Mar 30 07:46:04 PDT 2009
On Mon, 2009-03-30 at 08:47 +0000, Konstantin Belousov wrote:
> Author: kib
> Date: Mon Mar 30 08:47:28 2009
> New Revision: 190543
> URL: http://svn.freebsd.org/changeset/base/190543
>
> Log:
> Implement support for RTLD_NODELETE flag for dlopen() and -z nodelete
> static linker option. Do it by incrementing reference count on the loaded
> object and its dependencies.
Cool, I can drop my patches to compiz now.
robert.
> Reviewed by: davidxu, kan
>
> Modified:
> head/include/dlfcn.h
> head/libexec/rtld-elf/rtld.c
> head/libexec/rtld-elf/rtld.h
> head/sys/sys/elf_common.h
>
> Modified: head/include/dlfcn.h
> ==============================================================================
> --- head/include/dlfcn.h Mon Mar 30 08:44:29 2009 (r190542)
> +++ head/include/dlfcn.h Mon Mar 30 08:47:28 2009 (r190543)
> @@ -47,6 +47,7 @@
> #define RTLD_GLOBAL 0x100 /* Make symbols globally available. */
> #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. */
>
> /*
> * Request arguments for dlinfo().
>
> Modified: head/libexec/rtld-elf/rtld.c
> ==============================================================================
> --- head/libexec/rtld-elf/rtld.c Mon Mar 30 08:44:29 2009 (r190542)
> +++ head/libexec/rtld-elf/rtld.c Mon Mar 30 08:47:28 2009 (r190543)
> @@ -937,6 +937,8 @@ digest_dynamic(Obj_Entry *obj, int early
> /* XXX */;
> if (dynp->d_un.d_val & DF_1_BIND_NOW)
> obj->bind_now = true;
> + if (dynp->d_un.d_val & DF_1_NODELETE)
> + obj->z_nodelete = true;
> break;
>
> default:
> @@ -1422,15 +1424,21 @@ is_exported(const Elf_Sym *def)
> static int
> load_needed_objects(Obj_Entry *first)
> {
> - Obj_Entry *obj;
> + Obj_Entry *obj, *obj1;
>
> for (obj = first; obj != NULL; obj = obj->next) {
> Needed_Entry *needed;
>
> for (needed = obj->needed; needed != NULL; needed = needed->next) {
> - needed->obj = load_object(obj->strtab + needed->name, obj);
> - if (needed->obj == NULL && !ld_tracing)
> + obj1 = needed->obj = load_object(obj->strtab + needed->name, obj);
> + if (obj1 == NULL && !ld_tracing)
> return -1;
> + if (obj1 != NULL && obj1->z_nodelete && !obj1->ref_nodel) {
> + dbg("obj %s nodelete", obj1->path);
> + init_dag(obj1);
> + ref_dag(obj1);
> + obj1->ref_nodel = true;
> + }
> }
> }
>
> @@ -1976,12 +1984,13 @@ dlopen(const char *name, int mode)
> Obj_Entry **old_obj_tail;
> Obj_Entry *obj;
> Objlist initlist;
> - int result, lockstate;
> + int result, lockstate, nodelete;
>
> 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;
>
> objlist_init(&initlist);
>
> @@ -2029,6 +2038,11 @@ dlopen(const char *name, int mode)
> if (ld_tracing)
> goto trace;
> }
> + if (obj != NULL && (nodelete || obj->z_nodelete) && !obj->ref_nodel) {
> + dbg("obj %s nodelete", obj->path);
> + ref_dag(obj);
> + obj->z_nodelete = obj->ref_nodel = true;
> + }
> }
>
> LD_UTRACE(UTRACE_DLOPEN_STOP, obj, NULL, 0, obj ? obj->dl_refcount : 0,
>
> Modified: head/libexec/rtld-elf/rtld.h
> ==============================================================================
> --- head/libexec/rtld-elf/rtld.h Mon Mar 30 08:44:29 2009 (r190542)
> +++ head/libexec/rtld-elf/rtld.h Mon Mar 30 08:47:28 2009 (r190543)
> @@ -217,6 +217,8 @@ typedef struct Struct_Obj_Entry {
> bool tls_done : 1; /* Already allocated offset for static TLS */
> bool phdr_alloc : 1; /* Phdr is allocated and needs to be freed. */
> bool z_origin : 1; /* Process rpath and soname tokens */
> + bool z_nodelete : 1; /* Do not unload the object and dependencies */
> + bool ref_nodel : 1; /* refcount increased to prevent dlclose */
>
> struct link_map linkmap; /* for GDB and dlinfo() */
> Objlist dldags; /* Object belongs to these dlopened DAGs (%) */
>
> Modified: head/sys/sys/elf_common.h
> ==============================================================================
> --- head/sys/sys/elf_common.h Mon Mar 30 08:44:29 2009 (r190542)
> +++ head/sys/sys/elf_common.h Mon Mar 30 08:47:28 2009 (r190543)
> @@ -469,6 +469,7 @@ typedef struct {
> /* Values for DT_FLAGS_1 */
> #define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */
> #define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */
> +#define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */
> #define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */
>
> /* Values for n_type. Used in core files. */
--
Robert Noland <rnoland at FreeBSD.org>
FreeBSD
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: This is a digitally signed message part
Url : http://lists.freebsd.org/pipermail/svn-src-head/attachments/20090330/257976f7/attachment.pgp
More information about the svn-src-head
mailing list