Page MenuHomeFreeBSD

D50132.id154776.diff
No OneTemporary

D50132.id154776.diff

diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -246,6 +246,7 @@
bool z_nodeflib : 1; /* Don't search default library path */
bool z_global : 1; /* Make the object global */
bool z_pie : 1; /* Object proclaimed itself PIE executable */
+ bool z_initfirst : 1; /* Proceed initializers before other objects */
bool static_tls : 1; /* Needs static TLS allocation */
bool static_tls_copied : 1; /* Needs static TLS copying */
bool ref_nodel : 1; /* Refcount increased to prevent dlclose */
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -1564,6 +1564,8 @@
obj->z_nodeflib = true;
if (dynp->d_un.d_val & DF_1_PIE)
obj->z_pie = true;
+ if (dynp->d_un.d_val & DF_1_INITFIRST)
+ obj->z_initfirst = true;
break;
default:
@@ -2570,25 +2572,55 @@
if (obj->init_scanned || obj->init_done)
return;
- obj->init_scanned = true;
- /* Recursively process the successor objects. */
- nobj = globallist_next(obj);
- if (nobj != NULL && obj != tail)
- initlist_add_objects(nobj, tail, list);
+ if (obj->z_initfirst) {
+ Objlist flist;
+ Objlist_Entry *tmp;
- /* Recursively process the needed objects. */
- if (obj->needed != NULL)
- initlist_add_neededs(obj->needed, list);
- if (obj->needed_filtees != NULL)
- initlist_add_neededs(obj->needed_filtees, list);
- if (obj->needed_aux_filtees != NULL)
- initlist_add_neededs(obj->needed_aux_filtees, list);
+ objlist_init(&flist);
+ /* Recursively process the needed objects. */
+ if (obj->needed != NULL)
+ initlist_add_neededs(obj->needed, &flist);
+ if (obj->needed_filtees != NULL)
+ initlist_add_neededs(obj->needed_filtees, &flist);
+ if (obj->needed_aux_filtees != NULL)
+ initlist_add_neededs(obj->needed_aux_filtees, &flist);
+ objlist_push_tail(&flist, obj);
- /* Add the object to the init list. */
- objlist_push_tail(list, obj);
+ /*
+ * This might result in the same object appearing more
+ * than once on the init list. objlist_call_init()
+ * uses obj->init_scanned to avoid dup calls.
+ */
+ STAILQ_REVERSE(&flist, Struct_Objlist_Entry, link);
+ STAILQ_FOREACH(tmp, &flist, link)
+ objlist_push_head(list, tmp->obj);
- /* Add the object to the global fini list in the reverse order. */
+ objlist_clear(&flist);
+ } else {
+ obj->init_scanned = true;
+
+ /* Recursively process the successor objects. */
+ nobj = globallist_next(obj);
+ if (nobj != NULL && obj != tail)
+ initlist_add_objects(nobj, tail, list);
+
+ /* Recursively process the needed objects. */
+ if (obj->needed != NULL)
+ initlist_add_neededs(obj->needed, list);
+ if (obj->needed_filtees != NULL)
+ initlist_add_neededs(obj->needed_filtees, list);
+ if (obj->needed_aux_filtees != NULL)
+ initlist_add_neededs(obj->needed_aux_filtees, list);
+
+ /* Add the object to the init list. */
+ objlist_push_tail(list, obj);
+ }
+
+ /*
+ * Add the object to the global fini list in the
+ * reverse order.
+ */
if ((obj->fini != (Elf_Addr)NULL ||
obj->fini_array != (Elf_Addr)NULL) &&
!obj->on_fini_list) {

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 12, 2:24 AM (5 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31323519
Default Alt Text
D50132.id154776.diff (3 KB)

Event Timeline