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
This commit is contained in:
parent
5dc7bbafc8
commit
4495a80b97
@ -1290,7 +1290,6 @@ init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *dlp)
|
||||
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--;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user