mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-23 19:28:36 +00:00
rtld: fix dlopen() for an object that is already mapped but not yet initialized
For instance, dso might be mapped as needed but not yet initialized from the other subtree of needed objects, while current object' constructor does dlopen() for the dso. Right now rtld does relocations and other processing based on the arrival of new objects in the global list, which is not happens there. Directly check for the initialization state of the object, for which we would return the handle. One practical use case of this support is e.g. dlopen("libthr.so", RTLD_NOLOAD) by libraries that are threading-aware but happy to live with libc pthread shims if the program is not multithreaded. Reviewed by: tijl Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
parent
ad056b5d35
commit
1005d3d053
|
@ -3714,7 +3714,6 @@ static Obj_Entry *
|
|||
dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
|
||||
int mode, RtldLockState *lockstate)
|
||||
{
|
||||
Obj_Entry *old_obj_tail;
|
||||
Obj_Entry *obj;
|
||||
Objlist initlist;
|
||||
RtldLockState mlockstate;
|
||||
|
@ -3731,7 +3730,6 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
|
|||
}
|
||||
GDB_STATE(RT_ADD,NULL);
|
||||
|
||||
old_obj_tail = globallist_curr(TAILQ_LAST(&obj_list, obj_entry_q));
|
||||
obj = NULL;
|
||||
if (name == NULL && fd == -1) {
|
||||
obj = obj_main;
|
||||
|
@ -3744,9 +3742,9 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
|
|||
obj->dl_refcount++;
|
||||
if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
|
||||
objlist_push_tail(&list_global, obj);
|
||||
if (globallist_next(old_obj_tail) != NULL) {
|
||||
/* We loaded something new. */
|
||||
assert(globallist_next(old_obj_tail) == obj);
|
||||
|
||||
if (!obj->init_done) {
|
||||
/* We loaded something new and have to init something. */
|
||||
if ((lo_flags & RTLD_LO_DEEPBIND) != 0)
|
||||
obj->symbolic = true;
|
||||
result = 0;
|
||||
|
|
Loading…
Reference in a new issue