Date: Thu, 4 Nov 2010 09:29:00 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r214777 - head/libexec/rtld-elf Message-ID: <201011040929.oA49T0Xb050498@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Nov 4 09:29:00 2010 New Revision: 214777 URL: http://svn.freebsd.org/changeset/base/214777 Log: In r214728, if dlopen() is called for the object that has been already loaded as a dependency and marked -z nodlopen, object' DAG is already initialized by load_needed_objects(). Due to this, the init_dag() call from dlopen() does not increment refcount for the object [1]. Change init_dag() to not increment DAG refcount. Require explicit calls to ref_dag() to increment, and assert that ref_dag() and unref_dag() are called for root that has dag initialized. To fix the noted issue, unconditionally call both init_dag() and ref_dag() in dlopen() for the case when the object was already loaded, making it similar to the case of newly loaded object. Noted by: jh [1] Reviewed by: jh, kan MFC after: 6 days Modified: head/libexec/rtld-elf/rtld.c Modified: head/libexec/rtld-elf/rtld.c ============================================================================== --- head/libexec/rtld-elf/rtld.c Thu Nov 4 09:19:14 2010 (r214776) +++ head/libexec/rtld-elf/rtld.c Thu Nov 4 09:29:00 2010 (r214777) @@ -1290,7 +1290,6 @@ init_dag1(Obj_Entry *root, Obj_Entry *ob if (donelist_check(dlp, obj)) return; - obj->refcount++; objlist_push_tail(&obj->dldags, root); objlist_push_tail(&root->dagmembers, obj); for (needed = obj->needed; needed != NULL; needed = needed->next) @@ -2031,6 +2030,7 @@ dlopen(const char *name, int mode) assert(*old_obj_tail == obj); result = load_needed_objects(obj, RTLD_LO_DLOPEN); init_dag(obj); + ref_dag(obj); if (result != -1) result = rtld_verify_versions(&obj->dagmembers); if (result != -1 && ld_tracing) @@ -2054,10 +2054,8 @@ dlopen(const char *name, int mode) * already loaded as a dependency, initialize the dag * starting at it. */ - if (obj->dl_refcount == 1) - init_dag(obj); - else - ref_dag(obj); + init_dag(obj); + ref_dag(obj); if (ld_tracing) goto trace; @@ -3085,6 +3083,7 @@ ref_dag(Obj_Entry *root) { Objlist_Entry *elm; + assert(root->dag_inited); STAILQ_FOREACH(elm, &root->dagmembers, link) elm->obj->refcount++; } @@ -3094,6 +3093,7 @@ unref_dag(Obj_Entry *root) { Objlist_Entry *elm; + assert(root->dag_inited); STAILQ_FOREACH(elm, &root->dagmembers, link) elm->obj->refcount--; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011040929.oA49T0Xb050498>