Browse Source

[Pal] Append ELF binaries to tail of loaded_maps

Previously, Pal rtld code pushed binaries to head of loaded_maps list,
but code referencing this list iterated in-order. To preserve order of
binaries/libs specified in manifest (e.g., loader.preload), this commit
appends them to tail of the list.
Alex Merritt 5 years ago
parent
commit
7ac25ca556
1 changed files with 30 additions and 14 deletions
  1. 30 14
      Pal/src/db_rtld.c

+ 30 - 14
Pal/src/db_rtld.c

@@ -554,12 +554,21 @@ int add_elf_object(void * addr, PAL_HANDLE handle, int type)
     setup_elf_hash(map);
     ELF_DYNAMIC_RELOCATE(map);
 
-    struct link_map * prev = loaded_maps;
-    while (prev->l_next)
-        prev = prev->l_next;
-    map->l_prev = prev;
+    /* append to list (to preserve order of libs specified in
+     * manifest, e.g., loader.preload)
+     */
     map->l_next = NULL;
-    prev->l_next = map;
+    if (!loaded_maps) {
+        map->l_prev = NULL;
+        loaded_maps = map;
+    } else {
+        struct link_map * end = loaded_maps;
+        while (end->l_next)
+            end = end->l_next;
+        end->l_next = map;
+        map->l_prev = end;
+    }
+
     if (type == OBJECT_EXEC)
         exec_map = map;
 
@@ -888,11 +897,21 @@ int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type)
 done:
 #endif
 
-    if (loaded_maps)
-        loaded_maps->l_prev = map;
-    map->l_next = loaded_maps;
-    map->l_prev = NULL;
-    loaded_maps = map;
+    /* append to list (to preserve order of libs specified in
+     * manifest, e.g., loader.preload)
+     */
+    map->l_next = NULL;
+    if (!loaded_maps) {
+        map->l_prev = NULL;
+        loaded_maps = map;
+    } else {
+        struct link_map * end = loaded_maps;
+        while (end->l_next)
+            end = end->l_next;
+        end->l_next = map;
+        map->l_prev = end;
+    }
+
     if (map->l_type == OBJECT_EXEC)
         exec_map = map;
 
@@ -1359,10 +1378,7 @@ noreturn void start_execution (const char * first_argument,
             pal_state.tail_startup_time += _DkSystemTimeQuery() - before_tail;
 #endif
 
-    struct link_map * l = loaded_maps;
-    /* run entry point in reverse order */
-    for (; l->l_next ; l = l->l_next);
-    for (; l ; l = l->l_prev)
+    for (struct link_map * l = loaded_maps; l ; l = l->l_next)
         if (l->l_type == OBJECT_PRELOAD && l->l_entry)
             CALL_ENTRY(l, cookies);