nptl: Decorate thread stack on pthread_create
[platform/upstream/glibc.git] / elf / dl-deps.c
index e12c353..0549b4a 100644 (file)
@@ -1,5 +1,5 @@
 /* Load the dependencies of a mapped object.
-   Copyright (C) 1996-2019 Free Software Foundation, Inc.
+   Copyright (C) 1996-2023 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -14,7 +14,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+   <https://www.gnu.org/licenses/>.  */
 
 #include <atomic.h>
 #include <assert.h>
@@ -68,22 +68,6 @@ openaux (void *a)
                              args->map->l_ns);
 }
 
-static ptrdiff_t
-_dl_build_local_scope (struct link_map **list, struct link_map *map)
-{
-  struct link_map **p = list;
-  struct link_map **q;
-
-  *p++ = map;
-  map->l_reserved = 1;
-  if (map->l_initfini)
-    for (q = map->l_initfini + 1; *q; ++q)
-      if (! (*q)->l_reserved)
-       p += _dl_build_local_scope (p, *q);
-  return p - list;
-}
-
-
 /* We use a very special kind of list to track the path
    through the list of loaded shared objects.  We have to
    produce a flat list with unique members of all involved objects.
@@ -485,78 +469,36 @@ _dl_map_object_deps (struct link_map *map,
 
   map->l_searchlist.r_list = &l_initfini[nlist + 1];
   map->l_searchlist.r_nlist = nlist;
+  unsigned int map_index = UINT_MAX;
 
   for (nlist = 0, runp = known; runp; runp = runp->next)
     {
+      /* _dl_sort_maps ignores l_faked object, so it is safe to not consider
+        them for nlist.  */
       if (__builtin_expect (trace_mode, 0) && runp->map->l_faked)
        /* This can happen when we trace the loading.  */
        --map->l_searchlist.r_nlist;
       else
-       map->l_searchlist.r_list[nlist++] = runp->map;
+       {
+         if (runp->map == map)
+           map_index = nlist;
+         map->l_searchlist.r_list[nlist++] = runp->map;
+       }
 
       /* Now clear all the mark bits we set in the objects on the search list
         to avoid duplicates, so the next call starts fresh.  */
       runp->map->l_reserved = 0;
     }
 
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
-      && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
-    {
-      /* If we are to compute conflicts, we have to build local scope
-        for each library, not just the ultimate loader.  */
-      for (i = 0; i < nlist; ++i)
-       {
-         struct link_map *l = map->l_searchlist.r_list[i];
-         unsigned int j, cnt;
-
-         /* The local scope has been already computed.  */
-         if (l == map
-             || (l->l_local_scope[0]
-                 && l->l_local_scope[0]->r_nlist) != 0)
-           continue;
-
-         if (l->l_info[AUXTAG] || l->l_info[FILTERTAG])
-           {
-             /* As current DT_AUXILIARY/DT_FILTER implementation needs to be
-                rewritten, no need to bother with prelinking the old
-                implementation.  */
-             _dl_signal_error (EINVAL, l->l_name, NULL, N_("\
-Filters not supported with LD_TRACE_PRELINKING"));
-           }
-
-         cnt = _dl_build_local_scope (l_initfini, l);
-         assert (cnt <= nlist);
-         for (j = 0; j < cnt; j++)
-           {
-             l_initfini[j]->l_reserved = 0;
-             if (j && __builtin_expect (l_initfini[j]->l_info[DT_SYMBOLIC]
-                                        != NULL, 0))
-               l->l_symbolic_in_local_scope = true;
-           }
-
-         l->l_local_scope[0] =
-           (struct r_scope_elem *) malloc (sizeof (struct r_scope_elem)
-                                           + (cnt
-                                              * sizeof (struct link_map *)));
-         if (l->l_local_scope[0] == NULL)
-           _dl_signal_error (ENOMEM, map->l_name, NULL,
-                             N_("cannot allocate symbol search list"));
-         l->l_local_scope[0]->r_nlist = cnt;
-         l->l_local_scope[0]->r_list =
-           (struct link_map **) (l->l_local_scope[0] + 1);
-         memcpy (l->l_local_scope[0]->r_list, l_initfini,
-                 cnt * sizeof (struct link_map *));
-       }
-    }
-
   /* Maybe we can remove some relocation dependencies now.  */
-  assert (map->l_searchlist.r_list[0] == map);
   struct link_map_reldeps *l_reldeps = NULL;
   if (map->l_reldeps != NULL)
     {
-      for (i = 1; i < nlist; ++i)
+      for (i = 0; i < nlist; ++i)
        map->l_searchlist.r_list[i]->l_reserved = 1;
 
+      /* Avoid removing relocation dependencies of the main binary.  */
+      map->l_reserved = 0;
       struct link_map **list = &map->l_reldeps->list[0];
       for (i = 0; i < map->l_reldeps->act; ++i)
        if (list[i]->l_reserved)
@@ -581,17 +523,35 @@ Filters not supported with LD_TRACE_PRELINKING"));
              }
          }
 
-      for (i = 1; i < nlist; ++i)
+      for (i = 0; i < nlist; ++i)
        map->l_searchlist.r_list[i]->l_reserved = 0;
     }
 
-  /* Sort the initializer list to take dependencies into account.  The binary
-     itself will always be initialize last.  */
-  memcpy (l_initfini, map->l_searchlist.r_list,
-         nlist * sizeof (struct link_map *));
-  /* We can skip looking for the binary itself which is at the front of
-     the search list.  */
-  _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
+  /* Sort the initializer list to take dependencies into account.  Always
+     initialize the binary itself last.  */
+  assert (map_index < nlist);
+  if (map_index > 0)
+    {
+      /* Copy the binary into position 0.  */
+      l_initfini[0] = map->l_searchlist.r_list[map_index];
+
+      /* Copy the filtees.  */
+      for (i = 0; i < map_index; ++i)
+       l_initfini[i+1] = map->l_searchlist.r_list[i];
+
+      /* Copy the remainder.  */
+      for (i = map_index + 1; i < nlist; ++i)
+       l_initfini[i] = map->l_searchlist.r_list[i];
+    }
+  else
+    memcpy (l_initfini, map->l_searchlist.r_list,
+           nlist * sizeof (struct link_map *));
+
+  /* If libc.so.6 is the main map, it participates in the sort, so
+     that the relocation order is correct regarding libc.so.6.  */
+  _dl_sort_maps (l_initfini, nlist,
+                (l_initfini[0] != GL (dl_ns)[l_initfini[0]->l_ns].libc_map),
+                false);
 
   /* Terminate the list of dependencies.  */
   l_initfini[nlist] = NULL;