diff --git a/glibc-dlopen-nodelete-fixes-1.patch b/glibc-dlopen-nodelete-fixes-1.patch deleted file mode 100644 index 36136ad..0000000 --- a/glibc-dlopen-nodelete-fixes-1.patch +++ /dev/null @@ -1,1226 +0,0 @@ -Author: Florian Weimer -Date: Tue Dec 3 18:13:51 2019 +0100 - - dlopen: Fix issues related to NODELETE handling and relocations - - The assumption behind the assert in activate_nodelete was wrong: - - Inconsistency detected by ld.so: dl-open.c: 459: activate_nodelete: - Assertion `!imap->l_init_called || imap->l_type != lt_loaded' failed! (edit) - - It can happen that an already-loaded object that is in the local - scope is promoted to NODELETE status, via binding to a unique - symbol. - - Similarly, it is possible that such NODELETE promotion occurs to - an already-loaded object from the global scope. This is why the - loop in activate_nodelete has to cover all objects in the namespace - of the new object. - - In do_lookup_unique, it could happen that the NODELETE status of - an already-loaded object was overwritten with a pending NODELETE - status. As a result, if dlopen fails, this could cause a loss of - the NODELETE status of the affected object, eventually resulting - in an incorrect unload. - - Fixes commit f63b73814f74032c0e5d0a83300e3d864ef905e5 ("Remove all - loaded objects if dlopen fails, ignoring NODELETE [BZ #20839]"). - -diff --git a/elf/Makefile b/elf/Makefile -index b2b3be203fbaf1ca..72a5aa88b1025e76 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -191,7 +191,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ - tst-audit1 tst-audit2 tst-audit8 tst-audit9 \ - tst-addr1 tst-thrlock \ - tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \ -- tst-nodelete) \ -+ tst-nodelete tst-dlopen-nodelete-reloc) \ - tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ - tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ - tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ -@@ -271,7 +271,24 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ - tst-auditmod9a tst-auditmod9b \ - $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ - tst-nodelete-uniquemod tst-nodelete-rtldmod \ -- tst-nodelete-zmod) \ -+ tst-nodelete-zmod \ -+ tst-dlopen-nodelete-reloc-mod1 \ -+ tst-dlopen-nodelete-reloc-mod2 \ -+ tst-dlopen-nodelete-reloc-mod3 \ -+ tst-dlopen-nodelete-reloc-mod4 \ -+ tst-dlopen-nodelete-reloc-mod5 \ -+ tst-dlopen-nodelete-reloc-mod6 \ -+ tst-dlopen-nodelete-reloc-mod7 \ -+ tst-dlopen-nodelete-reloc-mod8 \ -+ tst-dlopen-nodelete-reloc-mod9 \ -+ tst-dlopen-nodelete-reloc-mod10 \ -+ tst-dlopen-nodelete-reloc-mod11 \ -+ tst-dlopen-nodelete-reloc-mod12 \ -+ tst-dlopen-nodelete-reloc-mod13 \ -+ tst-dlopen-nodelete-reloc-mod14 \ -+ tst-dlopen-nodelete-reloc-mod15 \ -+ tst-dlopen-nodelete-reloc-mod16 \ -+ tst-dlopen-nodelete-reloc-mod17) \ - tst-initordera1 tst-initorderb1 \ - tst-initordera2 tst-initorderb2 \ - tst-initordera3 tst-initordera4 \ -@@ -1627,3 +1644,48 @@ $(objpfx)tst-dlopenfailmod1.so: \ - $(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so - LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so - $(objpfx)tst-dlopenfailmod2.so: $(shared-thread-library) -+ -+$(objpfx)tst-dlopen-nodelete-reloc: $(libdl) -+$(objpfx)tst-dlopen-nodelete-reloc.out: \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod1.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod2.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod3.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod4.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod5.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod6.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod7.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod8.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod9.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod10.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod11.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod12.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod13.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod14.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod16.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod17.so -+tst-dlopen-nodelete-reloc-mod2.so-no-z-defs = yes -+LDFLAGS-tst-dlopen-nodelete-reloc-mod2.so = -Wl,-z,nodelete -+$(objpfx)tst-dlopen-nodelete-reloc-mod4.so: \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod3.so -+LDFLAGS-tst-dlopen-nodelete-reloc-mod4.so = -Wl,--no-as-needed -+$(objpfx)tst-dlopen-nodelete-reloc-mod5.so: \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod4.so -+LDFLAGS-tst-dlopen-nodelete-reloc-mod5.so = -Wl,-z,nodelete,--no-as-needed -+tst-dlopen-nodelete-reloc-mod5.so-no-z-defs = yes -+tst-dlopen-nodelete-reloc-mod7.so-no-z-defs = yes -+$(objpfx)tst-dlopen-nodelete-reloc-mod8.so: $(libdl) -+$(objpfx)tst-dlopen-nodelete-reloc-mod10.so: $(libdl) -+tst-dlopen-nodelete-reloc-mod11.so-no-z-defs = yes -+$(objpfx)tst-dlopen-nodelete-reloc-mod13.so: \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod12.so -+$(objpfx)tst-dlopen-nodelete-reloc-mod15.so: \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod14.so -+tst-dlopen-nodelete-reloc-mod16.so-no-z-defs = yes -+$(objpfx)tst-dlopen-nodelete-reloc-mod16.so: \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod15.so -+LDFLAGS-tst-dlopen-nodelete-reloc-mod16.so = -Wl,--no-as-needed -+$(objpfx)tst-dlopen-nodelete-reloc-mod17.so: \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ -+ $(objpfx)tst-dlopen-nodelete-reloc-mod16.so -+LDFLAGS-tst-dlopen-nodelete-reloc-mod17.so = -Wl,--no-as-needed -diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c -index a2e85a55686086c9..99846918c3453694 100644 ---- a/elf/dl-lookup.c -+++ b/elf/dl-lookup.c -@@ -311,12 +311,12 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, - enter_unique_sym (entries, size, - new_hash, strtab + sym->st_name, sym, map); - -- if (map->l_type == lt_loaded) -+ if (map->l_type == lt_loaded -+ && map->l_nodelete == link_map_nodelete_inactive) - { - /* Make sure we don't unload this object by - setting the appropriate flag. */ -- if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) -- && map->l_nodelete == link_map_nodelete_inactive) -+ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)) - _dl_debug_printf ("\ - marking %s [%lu] as NODELETE due to unique symbol\n", - map->l_name, map->l_ns); -diff --git a/elf/dl-open.c b/elf/dl-open.c -index df9f29a5e5683bf2..56f213323ce5cf65 100644 ---- a/elf/dl-open.c -+++ b/elf/dl-open.c -@@ -433,34 +433,21 @@ TLS generation counter wrapped! Please report this.")); - after dlopen failure is not possible, so that _dl_close can clean - up objects if necessary. */ - static void --activate_nodelete (struct link_map *new, int mode) -+activate_nodelete (struct link_map *new) - { -- if (mode & RTLD_NODELETE || new->l_nodelete == link_map_nodelete_pending) -- { -- if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) -- _dl_debug_printf ("activating NODELETE for %s [%lu]\n", -- new->l_name, new->l_ns); -- new->l_nodelete = link_map_nodelete_active; -- } -- -- for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) -- { -- struct link_map *imap = new->l_searchlist.r_list[i]; -- if (imap->l_nodelete == link_map_nodelete_pending) -- { -- if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) -- _dl_debug_printf ("activating NODELETE for %s [%lu]\n", -- imap->l_name, imap->l_ns); -- -- /* Only new objects should have set -- link_map_nodelete_pending. Existing objects should not -- have gained any new dependencies and therefore cannot -- reach NODELETE status. */ -- assert (!imap->l_init_called || imap->l_type != lt_loaded); -+ /* It is necessary to traverse the entire namespace. References to -+ objects in the global scope and unique symbol bindings can force -+ NODELETE status for objects outside the local scope. */ -+ for (struct link_map *l = GL (dl_ns)[new->l_ns]._ns_loaded; l != NULL; -+ l = l->l_next) -+ if (l->l_nodelete == link_map_nodelete_pending) -+ { -+ if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) -+ _dl_debug_printf ("activating NODELETE for %s [%lu]\n", -+ l->l_name, l->l_ns); - -- imap->l_nodelete = link_map_nodelete_active; -- } -- } -+ l->l_nodelete = link_map_nodelete_active; -+ } - } - - /* struct dl_init_args and call_dl_init are used to call _dl_init with -@@ -721,7 +708,7 @@ dl_open_worker (void *a) - All memory allocations for new objects must have happened - before. */ - -- activate_nodelete (new, mode); -+ activate_nodelete (new); - - /* Second stage after resize_scopes: Actually perform the scope - update. After this, dlsym and lazy binding can bind to new -diff --git a/elf/tst-dlopen-nodelete-reloc-mod1.c b/elf/tst-dlopen-nodelete-reloc-mod1.c -new file mode 100644 -index 0000000000000000..8927a9f851410268 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod1.c -@@ -0,0 +1,39 @@ -+/* Test propagation of NODELETE to an already-loaded object via relocation. -+ Non-NODELETE helper module. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include -+#include -+#include -+ -+/* Globally exported. Set by the main program to true before -+ termination, and used by tst-dlopen-nodelete-reloc-mod2.so to -+ trigger marking his module as NODELETE (and also for its destructor -+ check). */ -+bool may_finalize_mod1 = false; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod1) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod1.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod10.c b/elf/tst-dlopen-nodelete-reloc-mod10.c -new file mode 100644 -index 0000000000000000..30748b73ec7daed3 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod10.c -@@ -0,0 +1,41 @@ -+/* Helper module to load tst-dlopen-nodelete-reloc-mod11.so. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include -+#include -+#include -+#include -+ -+static void *handle; -+ -+static void __attribute__ ((constructor)) -+init (void) -+{ -+ handle = dlopen ("tst-dlopen-nodelete-reloc-mod11.so", RTLD_NOW); -+ if (handle == NULL) -+ { -+ printf ("error: dlopen in module 10: %s\n", dlerror ()); -+ _exit (1); -+ } -+} -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ dlclose (handle); -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod11.cc b/elf/tst-dlopen-nodelete-reloc-mod11.cc -new file mode 100644 -index 0000000000000000..48c910403e782c83 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod11.cc -@@ -0,0 +1,49 @@ -+/* Second module defining a unique symbol (loaded indirectly). -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "tst-dlopen-nodelete-reloc.h" -+ -+#include -+#include -+#include -+ -+/* Just a flag here, not used for NODELETE processing. */ -+bool may_finalize_mod11 = false; -+ -+/* Trigger the creation of a unique symbol reference. This should -+ cause tst-dlopen-nodelete-reloc-mod9.so to be marked as -+ NODELETE. */ -+ -+extern template struct unique_symbol<9>; -+ -+int -+global_function_mod11 (void) -+{ -+ return unique_symbol<9>::value; -+} -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod11) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod11.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod12.cc b/elf/tst-dlopen-nodelete-reloc-mod12.cc -new file mode 100644 -index 0000000000000000..5c093fd02d1fd0c7 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod12.cc -@@ -0,0 +1,42 @@ -+/* First module for NODELETE test defining a unique symbol (with DT_NEEDED). -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "tst-dlopen-nodelete-reloc.h" -+ -+#include -+#include -+#include -+ -+/* Just a flag here, not used for NODELETE processing. */ -+bool may_finalize_mod12 = false; -+ -+/* Explicit instantiation. This produces a unique symbol definition -+ which is not referenced by the library itself, so the library is -+ not marked NODELETE. */ -+template struct unique_symbol<12>; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod12) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod12.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod13.cc b/elf/tst-dlopen-nodelete-reloc-mod13.cc -new file mode 100644 -index 0000000000000000..caf4fd1cc9e1c1e1 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod13.cc -@@ -0,0 +1,48 @@ -+/* Second module for NODELETE test defining a unique symbol (with DT_NEEDED). -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "tst-dlopen-nodelete-reloc.h" -+ -+#include -+#include -+#include -+ -+/* Just a flag here, not used for NODELETE processing. */ -+bool may_finalize_mod13 = false; -+ -+extern template struct unique_symbol<12>; -+ -+/* Trigger the creation of a unique symbol reference. This should -+ cause tst-dlopen-nodelete-reloc-mod12.so to be marked as -+ NODELETE. */ -+int -+global_function_mod13 (void) -+{ -+ return unique_symbol<12>::value; -+} -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod13) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod13.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod13.h b/elf/tst-dlopen-nodelete-reloc-mod13.h -new file mode 100644 -index 0000000000000000..5d338481a34a5714 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod13.h -@@ -0,0 +1,24 @@ -+/* Inline function which produces a unique symbol. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+inline char * -+third_function_with_local_static (void) -+{ -+ static char local; -+ return &local; -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod14.cc b/elf/tst-dlopen-nodelete-reloc-mod14.cc -new file mode 100644 -index 0000000000000000..e67621a2a2f8509a ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod14.cc -@@ -0,0 +1,42 @@ -+/* This object must retain NODELETE status after a dlopen failure. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "tst-dlopen-nodelete-reloc.h" -+ -+#include -+#include -+#include -+ -+/* Just a flag here, not used for NODELETE processing. */ -+bool may_finalize_mod14 = false; -+ -+/* Explicit instantiation. This produces a unique symbol definition -+ which is not referenced by the library itself, so the library is -+ not marked NODELETE. */ -+template struct unique_symbol<14>; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod14) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod14.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod15.cc b/elf/tst-dlopen-nodelete-reloc-mod15.cc -new file mode 100644 -index 0000000000000000..ff7a64edd1813119 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod15.cc -@@ -0,0 +1,41 @@ -+/* Helper object to mark tst-dlopen-nodelete-reloc-mod14.so as NODELETE. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "tst-dlopen-nodelete-reloc.h" -+ -+#include -+#include -+#include -+ -+extern template struct unique_symbol<14>; -+ -+/* Trigger the creation of a unique symbol reference. This should -+ cause tst-dlopen-nodelete-reloc-mod14.so to be marked as -+ NODELETE. */ -+int -+global_function_mod15 (void) -+{ -+ return unique_symbol<14>::value; -+} -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ /* This object is never loaded completely. */ -+ puts ("error: tst-dlopen-nodelete-reloc-mod15.so destructor invoked"); -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod16.c b/elf/tst-dlopen-nodelete-reloc-mod16.c -new file mode 100644 -index 0000000000000000..f836f04fb5420286 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod16.c -@@ -0,0 +1,27 @@ -+/* Object with an undefined symbol to trigger a relocation failure. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+/* The reference to undefined_mod16 triggers a relocation failure. */ -+ -+extern int undefined_mod16; -+ -+int -+global_function_mod15 (void) -+{ -+ return undefined_mod16; -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod17.c b/elf/tst-dlopen-nodelete-reloc-mod17.c -new file mode 100644 -index 0000000000000000..426562edd9a3ffee ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod17.c -@@ -0,0 +1,19 @@ -+/* Top-level object with dependency on an object that fails relocation. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+/* The dependencies do all the work. */ -diff --git a/elf/tst-dlopen-nodelete-reloc-mod2.c b/elf/tst-dlopen-nodelete-reloc-mod2.c -new file mode 100644 -index 0000000000000000..81ea8e5af2d00b93 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod2.c -@@ -0,0 +1,38 @@ -+/* Test propagation of NODELETE to an already-loaded object via relocation. -+ NODELETE helper module. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include -+#include -+#include -+ -+/* Defined in tst-dlopen-nodelete-reloc-mod1.so. This dependency is -+ not expressed via DT_NEEDED, so this reference marks the other -+ object as NODELETE dynamically, during initially relocation. */ -+extern bool may_finalize_mod1; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod1) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod2.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod3.c b/elf/tst-dlopen-nodelete-reloc-mod3.c -new file mode 100644 -index 0000000000000000..d33f4ec7630c6a1e ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod3.c -@@ -0,0 +1,38 @@ -+/* Test propagation of NODELETE to an already-loaded object via relocation. -+ Non-NODELETE helper module. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include -+#include -+#include -+ -+/* Globally exported. Set by the main program to true before -+ termination, and used by tst-dlopen-nodelete-reloc-mod4.so, -+ tst-dlopen-nodelete-reloc-mod5.so. */ -+bool may_finalize_mod3 = false; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod3) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod3.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod4.c b/elf/tst-dlopen-nodelete-reloc-mod4.c -new file mode 100644 -index 0000000000000000..7e6633aebb1e2f00 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod4.c -@@ -0,0 +1,37 @@ -+/* Test propagation of NODELETE to an already-loaded object via relocation. -+ Intermediate helper module. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include -+#include -+#include -+ -+/* Defined in tst-dlopen-nodelete-reloc-mod3.so. The dependency is -+ expressed via DT_NEEDED. */ -+extern bool may_finalize_mod3; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod3) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod4.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod5.c b/elf/tst-dlopen-nodelete-reloc-mod5.c -new file mode 100644 -index 0000000000000000..f876fa0f97c48b5c ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod5.c -@@ -0,0 +1,38 @@ -+/* Test propagation of NODELETE to an already-loaded object via relocation. -+ NODELETE helper module. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include -+#include -+#include -+ -+/* Defined in tst-dlopen-nodelete-reloc-mod3.so. The dependency is -+ expressed via DT_NEEDED on the intermedia DSO -+ tst-dlopen-nodelete-reloc-mod3.so. */ -+extern bool may_finalize_mod3; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod3) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod5.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod6.cc b/elf/tst-dlopen-nodelete-reloc-mod6.cc -new file mode 100644 -index 0000000000000000..180f5b5842f1c2b0 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod6.cc -@@ -0,0 +1,42 @@ -+/* First module for NODELETE test defining a unique symbol. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "tst-dlopen-nodelete-reloc.h" -+ -+#include -+#include -+#include -+ -+/* Just a flag here, not used for NODELETE processing. */ -+bool may_finalize_mod6 = false; -+ -+/* Explicit instantiation. This produces a unique symbol definition -+ which is not referenced by the library itself, so the library is -+ not marked NODELETE. */ -+template struct unique_symbol<6>; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod6) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod6.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod7.cc b/elf/tst-dlopen-nodelete-reloc-mod7.cc -new file mode 100644 -index 0000000000000000..c85e7c991b098bf5 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod7.cc -@@ -0,0 +1,48 @@ -+/* Second module for NODELETE test defining a unique symbol. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "tst-dlopen-nodelete-reloc.h" -+ -+#include -+#include -+#include -+ -+/* Just a flag here, not used for NODELETE processing. */ -+bool may_finalize_mod7 = false; -+ -+extern template struct unique_symbol<6>; -+ -+/* Trigger the creation of a unique symbol reference. This should -+ cause tst-dlopen-nodelete-reloc-mod6.so to be marked as -+ NODELETE. */ -+int -+global_function_mod7 (void) -+{ -+ return unique_symbol<6>::value; -+} -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod7) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod7.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod8.c b/elf/tst-dlopen-nodelete-reloc-mod8.c -new file mode 100644 -index 0000000000000000..ebb1c35fab57e319 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod8.c -@@ -0,0 +1,41 @@ -+/* Helper module to load tst-dlopen-nodelete-reloc-mod9.so. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include -+#include -+#include -+#include -+ -+static void *handle; -+ -+static void __attribute__ ((constructor)) -+init (void) -+{ -+ handle = dlopen ("tst-dlopen-nodelete-reloc-mod9.so", RTLD_NOW); -+ if (handle == NULL) -+ { -+ printf ("error: dlopen in module 8: %s\n", dlerror ()); -+ _exit (1); -+ } -+} -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ dlclose (handle); -+} -diff --git a/elf/tst-dlopen-nodelete-reloc-mod9.cc b/elf/tst-dlopen-nodelete-reloc-mod9.cc -new file mode 100644 -index 0000000000000000..06fb49cdf753cb41 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc-mod9.cc -@@ -0,0 +1,42 @@ -+/* First module defining a unique symbol (loaded indirectly). -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "tst-dlopen-nodelete-reloc.h" -+ -+#include -+#include -+#include -+ -+/* Just a flag here, not used for NODELETE processing. */ -+bool may_finalize_mod9 = false; -+ -+/* Explicit instantiation. This produces a unique symbol definition -+ which is not referenced by the library itself, so the library is -+ not marked NODELETE. */ -+template struct unique_symbol<9>; -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ if (!may_finalize_mod9) -+ { -+ puts ("error: tst-dlopen-nodelete-reloc-mod9.so destructor" -+ " called too early"); -+ _exit (1); -+ } -+} -diff --git a/elf/tst-dlopen-nodelete-reloc.c b/elf/tst-dlopen-nodelete-reloc.c -new file mode 100644 -index 0000000000000000..d3de90a9f5d3cca8 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc.c -@@ -0,0 +1,178 @@ -+/* Test interactions of dlopen, NODELETE, and relocations. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+/* This test exercises NODELETE propagation due to data relocations -+ and unique symbols, and the interaction with already-loaded -+ objects. Some test objects are written in C++, to produce unique -+ symbol definitions. -+ -+ First test: Global scope variant, data relocation as the NODELETE -+ trigger. mod1 is loaded first with a separate dlopen call. -+ -+ mod2 ---(may_finalize_mod1 relocation dependency)---> mod1 -+ (NODELETE) (marked as NODELETE) -+ -+ Second test: Local scope variant, data relocation. mod3 is loaded -+ first, then mod5. -+ -+ mod5 ---(DT_NEEDED)---> mod4 ---(DT_NEEDED)---> mod3 -+ (NODELETE) (not NODELETE) ^ -+ \ / (marked as -+ `--(may_finalize_mod3 relocation dependency)--/ NODELETE) -+ -+ Third test: Shared local scope with unique symbol. mod6 is loaded -+ first, then mod7. No explicit dependencies between the two -+ objects, so first object has to be opened with RTLD_GLOBAL. -+ -+ mod7 ---(unique symbol)---> mod6 -+ (marked as NODELETE) -+ -+ Forth test: Non-shared scopes with unique symbol. mod8 and mod10 -+ are loaded from the main program. mod8 loads mod9 from an ELF -+ constructor, mod10 loads mod11. There are no DT_NEEDED -+ dependencies. mod9 is promoted to the global scope form the main -+ program. The unique symbol dependency is: -+ -+ mod9 ---(unique symbol)---> mod11 -+ (marked as NODELETE) -+ -+ Fifth test: Shared local scope with unique symbol, like test 3, but -+ this time, there is also a DT_NEEDED dependency (so no RTLD_GLOBAL -+ needed): -+ -+ DT_NEEDED -+ mod13 ---(unique symbol)---> mod12 -+ (marked as NODELETE) -+ -+ Sixth test: NODELETE status is retained after relocation failure -+ with unique symbol dependency. The object graph ensures that the -+ unique symbol binding is processed before the dlopen failure. -+ -+ DT_NEEDED -+ mod17 --(DT_NEEDED)--> mod15 --(unique symbol)--> mod14 -+ \ ^ (RTLD_NODELETE) -+ \ (DT_NEEDED) -+ \ | -+ `---(DT_NEEDED)--> mod16 -+ (fails to relocate) -+ -+ mod14 must remain NODELETE after opening mod17 failed. */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int -+do_test (void) -+{ -+ /* First case: global scope, regular data symbol. Open the object -+ which is not NODELETE initially. */ -+ void *mod1 = xdlopen ("tst-dlopen-nodelete-reloc-mod1.so", -+ RTLD_NOW | RTLD_GLOBAL); -+ /* This is used to indicate that the ELF destructor may be -+ called. */ -+ bool *may_finalize_mod1 = xdlsym (mod1, "may_finalize_mod1"); -+ /* Open the NODELETE object. */ -+ void *mod2 = xdlopen ("tst-dlopen-nodelete-reloc-mod2.so", RTLD_NOW); -+ /* This has no effect because the DSO is directly marked as -+ NODELETE. */ -+ xdlclose (mod2); -+ /* This has no effect because the DSO has been indirectly marked as -+ NODELETE due to a relocation dependency. */ -+ xdlclose (mod1); -+ -+ /* Second case: local scope, regular data symbol. Open the object -+ which is not NODELETE initially. */ -+ void *mod3 = xdlopen ("tst-dlopen-nodelete-reloc-mod3.so", RTLD_NOW); -+ bool *may_finalize_mod3 = xdlsym (mod3, "may_finalize_mod3"); -+ /* Open the NODELETE object. */ -+ void *mod5 = xdlopen ("tst-dlopen-nodelete-reloc-mod5.so", RTLD_NOW); -+ /* Again those have no effect because of NODELETE. */ -+ xdlclose (mod5); -+ xdlclose (mod3); -+ -+ /* Third case: Unique symbol. */ -+ void *mod6 = xdlopen ("tst-dlopen-nodelete-reloc-mod6.so", -+ RTLD_NOW | RTLD_GLOBAL); -+ bool *may_finalize_mod6 = xdlsym (mod6, "may_finalize_mod6"); -+ void *mod7 = xdlopen ("tst-dlopen-nodelete-reloc-mod7.so", RTLD_NOW); -+ bool *may_finalize_mod7 = xdlsym (mod7, "may_finalize_mod7"); -+ /* This should not have any effect because of the unique symbol and -+ the resulting NODELETE status. */ -+ xdlclose (mod6); -+ /* mod7 is not NODELETE and can be closed. */ -+ *may_finalize_mod7 = true; -+ xdlclose (mod7); -+ -+ /* Fourth case: Unique symbol, indirect loading. */ -+ void *mod8 = xdlopen ("tst-dlopen-nodelete-reloc-mod8.so", RTLD_NOW); -+ /* Also promote to global scope. */ -+ void *mod9 = xdlopen ("tst-dlopen-nodelete-reloc-mod9.so", -+ RTLD_NOW | RTLD_NOLOAD | RTLD_GLOBAL); -+ bool *may_finalize_mod9 = xdlsym (mod9, "may_finalize_mod9"); -+ xdlclose (mod9); /* Drop mod9 reference. */ -+ void *mod10 = xdlopen ("tst-dlopen-nodelete-reloc-mod10.so", RTLD_NOW); -+ void *mod11 = xdlopen ("tst-dlopen-nodelete-reloc-mod11.so", -+ RTLD_NOW | RTLD_NOLOAD); -+ bool *may_finalize_mod11 = xdlsym (mod11, "may_finalize_mod11"); -+ xdlclose (mod11); /* Drop mod11 reference. */ -+ /* mod11 is not NODELETE and can be closed. */ -+ *may_finalize_mod11 = true; -+ /* Trigger closing of mod11, too. */ -+ xdlclose (mod10); -+ /* Does not trigger closing of mod9. */ -+ xdlclose (mod8); -+ -+ /* Fifth case: Unique symbol, with DT_NEEDED dependency. */ -+ void *mod12 = xdlopen ("tst-dlopen-nodelete-reloc-mod12.so", RTLD_NOW); -+ bool *may_finalize_mod12 = xdlsym (mod12, "may_finalize_mod12"); -+ void *mod13 = xdlopen ("tst-dlopen-nodelete-reloc-mod13.so", RTLD_NOW); -+ bool *may_finalize_mod13 = xdlsym (mod13, "may_finalize_mod13"); -+ /* This should not have any effect because of the unique symbol. */ -+ xdlclose (mod12); -+ /* mod13 is not NODELETE and can be closed. */ -+ *may_finalize_mod13 = true; -+ xdlclose (mod13); -+ -+ /* Sixth case: Unique symbol binding must not cause loss of NODELETE -+ status. */ -+ void *mod14 = xdlopen ("tst-dlopen-nodelete-reloc-mod14.so", -+ RTLD_NOW | RTLD_NODELETE); -+ bool *may_finalize_mod14 = xdlsym (mod14, "may_finalize_mod14"); -+ TEST_VERIFY (dlopen ("tst-dlopen-nodelete-reloc-mod17.so", RTLD_NOW) -+ == NULL); -+ const char *message = dlerror (); -+ printf ("info: test 6 message: %s\n", message); -+ /* This must not close the object, it must still be NODELETE. */ -+ xdlclose (mod14); -+ xdlopen ("tst-dlopen-nodelete-reloc-mod14.so", RTLD_NOW | RTLD_NOLOAD); -+ -+ /* Prepare for process exit. Destructors for NODELETE objects will -+ be invoked. */ -+ *may_finalize_mod1 = true; -+ *may_finalize_mod3 = true; -+ *may_finalize_mod6 = true; -+ *may_finalize_mod9 = true; -+ *may_finalize_mod12 = true; -+ *may_finalize_mod14 = true; -+ return 0; -+} -+ -+#include -diff --git a/elf/tst-dlopen-nodelete-reloc.h b/elf/tst-dlopen-nodelete-reloc.h -new file mode 100644 -index 0000000000000000..8844de622631f575 ---- /dev/null -+++ b/elf/tst-dlopen-nodelete-reloc.h -@@ -0,0 +1,35 @@ -+/* Template to produce unique symbols. -+ Copyright (C) 2019 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+/* This template produces a unique symbol definition for an explicit -+ template instantiation (without also incorporating a reference), -+ and an extern template declaration can be used to reference that -+ symbol from another object. The modid parameter is just a -+ placeholder to create different symbols (because it affects the -+ name mangling of the static value member). By convention, it -+ should match the number of the module that contains the -+ definition. */ -+ -+template -+struct unique_symbol -+{ -+ static int value; -+}; -+ -+template -+int unique_symbol::value; diff --git a/glibc-dlopen-nodelete-fixes-2.patch b/glibc-dlopen-nodelete-fixes-2.patch deleted file mode 100644 index 54fdafa..0000000 --- a/glibc-dlopen-nodelete-fixes-2.patch +++ /dev/null @@ -1,296 +0,0 @@ -Author: Florian Weimer -Date: Thu Dec 5 13:32:42 2019 +0100 - - dlopen: Rework handling of pending NODELETE status - - To avoid a read-modify-write cycle on the l_nodelete field, this - commit introduces two flags for active NODELETE status (irrevocable) - and pending NODELETE status (revocable until activate_nodelete) is - invoked. As a result, NODELETE processing in dlopen does not - introduce further reasons why lazy binding from signal handlers - is unsafe during dlopen, and a subsequent commit can remove signal - blocking from dlopen. - -diff --git a/elf/dl-close.c b/elf/dl-close.c -index e35a62daf6fa98a1..df1df6fb298b2319 100644 ---- a/elf/dl-close.c -+++ b/elf/dl-close.c -@@ -197,7 +197,7 @@ _dl_close_worker (struct link_map *map, bool force) - /* Check whether this object is still used. */ - if (l->l_type == lt_loaded - && l->l_direct_opencount == 0 -- && l->l_nodelete != link_map_nodelete_active -+ && !l->l_nodelete_active - /* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why - acquire is sufficient and correct. */ - && atomic_load_acquire (&l->l_tls_dtor_count) == 0 -@@ -279,8 +279,7 @@ _dl_close_worker (struct link_map *map, bool force) - - if (!used[i]) - { -- assert (imap->l_type == lt_loaded -- && imap->l_nodelete != link_map_nodelete_active); -+ assert (imap->l_type == lt_loaded && !imap->l_nodelete_active); - - /* Call its termination function. Do not do it for - half-cooked objects. Temporarily disable exception -@@ -830,7 +829,7 @@ _dl_close (void *_map) - before we took the lock. There is no way to detect this (see below) - so we proceed assuming this isn't the case. First see whether we - can remove the object at all. */ -- if (__glibc_unlikely (map->l_nodelete == link_map_nodelete_active)) -+ if (__glibc_unlikely (map->l_nodelete_active)) - { - /* Nope. Do nothing. */ - __rtld_lock_unlock_recursive (GL(dl_load_lock)); -diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c -index 99846918c3453694..759b45a2c977175a 100644 ---- a/elf/dl-lookup.c -+++ b/elf/dl-lookup.c -@@ -187,6 +187,28 @@ enter_unique_sym (struct unique_sym *table, size_t size, - table[idx].map = map; - } - -+/* Mark MAP as NODELETE according to the lookup mode in FLAGS. During -+ initial relocation, NODELETE state is pending only. */ -+static void -+mark_nodelete (struct link_map *map, int flags) -+{ -+ if (flags & DL_LOOKUP_FOR_RELOCATE) -+ map->l_nodelete_pending = true; -+ else -+ map->l_nodelete_active = true; -+} -+ -+/* Return true if MAP is marked as NODELETE according to the lookup -+ mode in FLAGS> */ -+static bool -+is_nodelete (struct link_map *map, int flags) -+{ -+ /* Non-pending NODELETE always counts. Pending NODELETE only counts -+ during initial relocation processing. */ -+ return map->l_nodelete_active -+ || ((flags & DL_LOOKUP_FOR_RELOCATE) && map->l_nodelete_pending); -+} -+ - /* Utility function for do_lookup_x. Lookup an STB_GNU_UNIQUE symbol - in the unique symbol table, creating a new entry if necessary. - Return the matching symbol in RESULT. */ -@@ -311,8 +333,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, - enter_unique_sym (entries, size, - new_hash, strtab + sym->st_name, sym, map); - -- if (map->l_type == lt_loaded -- && map->l_nodelete == link_map_nodelete_inactive) -+ if (map->l_type == lt_loaded && !is_nodelete (map, flags)) - { - /* Make sure we don't unload this object by - setting the appropriate flag. */ -@@ -320,10 +341,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, - _dl_debug_printf ("\ - marking %s [%lu] as NODELETE due to unique symbol\n", - map->l_name, map->l_ns); -- if (flags & DL_LOOKUP_FOR_RELOCATE) -- map->l_nodelete = link_map_nodelete_pending; -- else -- map->l_nodelete = link_map_nodelete_active; -+ mark_nodelete (map, flags); - } - } - ++tab->n_elements; -@@ -586,7 +604,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) - dependencies may pick an dependency which can be dlclose'd, but - such IFUNC resolvers are undefined anyway. */ - assert (map->l_type == lt_loaded); -- if (map->l_nodelete != link_map_nodelete_inactive) -+ if (is_nodelete (map, flags)) - return 0; - - struct link_map_reldeps *l_reldeps -@@ -694,17 +712,16 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) - - /* Redo the NODELETE check, as when dl_load_lock wasn't held - yet this could have changed. */ -- if (map->l_nodelete != link_map_nodelete_inactive) -+ if (is_nodelete (map, flags)) - goto out; - - /* If the object with the undefined reference cannot be removed ever - just make sure the same is true for the object which contains the - definition. */ -- if (undef_map->l_type != lt_loaded -- || (undef_map->l_nodelete != link_map_nodelete_inactive)) -+ if (undef_map->l_type != lt_loaded || is_nodelete (map, flags)) - { - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) -- && map->l_nodelete == link_map_nodelete_inactive) -+ && !is_nodelete (map, flags)) - { - if (undef_map->l_name[0] == '\0') - _dl_debug_printf ("\ -@@ -716,11 +733,7 @@ marking %s [%lu] as NODELETE due to reference to %s [%lu]\n", - map->l_name, map->l_ns, - undef_map->l_name, undef_map->l_ns); - } -- -- if (flags & DL_LOOKUP_FOR_RELOCATE) -- map->l_nodelete = link_map_nodelete_pending; -- else -- map->l_nodelete = link_map_nodelete_active; -+ mark_nodelete (map, flags); - goto out; - } - -@@ -746,17 +759,14 @@ marking %s [%lu] as NODELETE due to reference to %s [%lu]\n", - cannot be unloaded. This is semantically the correct - behavior. */ - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) -- && map->l_nodelete == link_map_nodelete_inactive) -+ && !is_nodelete (map, flags)) - _dl_debug_printf ("\ - marking %s [%lu] as NODELETE due to memory allocation failure\n", - map->l_name, map->l_ns); -- if (flags & DL_LOOKUP_FOR_RELOCATE) -- /* In case of non-lazy binding, we could actually -- report the memory allocation error, but for now, we -- use the conservative approximation as well. */ -- map->l_nodelete = link_map_nodelete_pending; -- else -- map->l_nodelete = link_map_nodelete_active; -+ /* In case of non-lazy binding, we could actually report -+ the memory allocation error, but for now, we use the -+ conservative approximation as well. */ -+ mark_nodelete (map, flags); - goto out; - } - else -diff --git a/elf/dl-open.c b/elf/dl-open.c -index 56f213323ce5cf65..c23341be5892fb12 100644 ---- a/elf/dl-open.c -+++ b/elf/dl-open.c -@@ -440,13 +440,17 @@ activate_nodelete (struct link_map *new) - NODELETE status for objects outside the local scope. */ - for (struct link_map *l = GL (dl_ns)[new->l_ns]._ns_loaded; l != NULL; - l = l->l_next) -- if (l->l_nodelete == link_map_nodelete_pending) -+ if (l->l_nodelete_pending) - { - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) - _dl_debug_printf ("activating NODELETE for %s [%lu]\n", - l->l_name, l->l_ns); - -- l->l_nodelete = link_map_nodelete_active; -+ l->l_nodelete_active = true; -+ -+ /* This is just a debugging aid, to indicate that -+ activate_nodelete has run for this map. */ -+ l->l_nodelete_pending = false; - } - } - -@@ -549,10 +553,10 @@ dl_open_worker (void *a) - if (__glibc_unlikely (mode & RTLD_NODELETE)) - { - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES) -- && new->l_nodelete == link_map_nodelete_inactive) -+ && !new->l_nodelete_active) - _dl_debug_printf ("marking %s [%lu] as NODELETE\n", - new->l_name, new->l_ns); -- new->l_nodelete = link_map_nodelete_active; -+ new->l_nodelete_active = true; - } - - /* Finalize the addition to the global scope. */ -@@ -568,7 +572,7 @@ dl_open_worker (void *a) - /* Schedule NODELETE marking for the directly loaded object if - requested. */ - if (__glibc_unlikely (mode & RTLD_NODELETE)) -- new->l_nodelete = link_map_nodelete_pending; -+ new->l_nodelete_pending = true; - - /* Load that object's dependencies. */ - _dl_map_object_deps (new, NULL, 0, 0, -@@ -683,7 +687,7 @@ dl_open_worker (void *a) - _dl_start_profile (); - - /* Prevent unloading the object. */ -- GL(dl_profile_map)->l_nodelete = link_map_nodelete_active; -+ GL(dl_profile_map)->l_nodelete_active = true; - } - } - else -@@ -882,9 +886,9 @@ no more namespaces available for dlmopen()")); - happens inside dl_open_worker. */ - __libc_signal_restore_set (&args.original_signal_mask); - -- /* All link_map_nodelete_pending objects should have been -- deleted at this point, which is why it is not necessary -- to reset the flag here. */ -+ /* All l_nodelete_pending objects should have been deleted -+ at this point, which is why it is not necessary to reset -+ the flag here. */ - } - else - __libc_signal_restore_set (&args.original_signal_mask); -diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h -index 075683d729447a40..ea4e304bef282a6f 100644 ---- a/elf/get-dynamic-info.h -+++ b/elf/get-dynamic-info.h -@@ -164,7 +164,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) - { - l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; - if (l->l_flags_1 & DF_1_NODELETE) -- l->l_nodelete = link_map_nodelete_pending; -+ l->l_nodelete_pending = true; - - /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like - to assert this, but we can't. Users have been setting -diff --git a/include/link.h b/include/link.h -index 2e771e433a36e6cd..2acc8363802d6d64 100644 ---- a/include/link.h -+++ b/include/link.h -@@ -79,22 +79,6 @@ struct r_search_path_struct - int malloced; - }; - --/* Type used by the l_nodelete member. */ --enum link_map_nodelete --{ -- /* This link map can be deallocated. */ -- link_map_nodelete_inactive = 0, /* Zero-initialized in _dl_new_object. */ -- -- /* This link map cannot be deallocated. */ -- link_map_nodelete_active, -- -- /* This link map cannot be deallocated after dlopen has succeded. -- dlopen turns this into link_map_nodelete_active. dlclose treats -- this intermediate state as link_map_nodelete_active. */ -- link_map_nodelete_pending, --}; -- -- - /* Structure describing a loaded shared object. The `l_next' and `l_prev' - members form a chain of all the shared objects loaded at startup. - -@@ -218,10 +202,17 @@ struct link_map - freed, ie. not allocated with - the dummy malloc in ld.so. */ - -- /* Actually of type enum link_map_nodelete. Separate byte due to -- a read in add_dependency in elf/dl-lookup.c outside the loader -- lock. Only valid for l_type == lt_loaded. */ -- unsigned char l_nodelete; -+ /* NODELETE status of the map. Only valid for maps of type -+ lt_loaded. Lazy binding sets l_nodelete_active directly, -+ potentially from signal handlers. Initial loading of an -+ DF_1_NODELETE object set l_nodelete_pending. Relocation may -+ set l_nodelete_pending as well. l_nodelete_pending maps are -+ promoted to l_nodelete_active status in the final stages of -+ dlopen, prior to calling ELF constructors. dlclose only -+ refuses to unload l_nodelete_active maps, the pending status is -+ ignored. */ -+ bool l_nodelete_active; -+ bool l_nodelete_pending; - - #include - diff --git a/glibc-dlopen-nodelete-fixes-3.patch b/glibc-dlopen-nodelete-fixes-3.patch deleted file mode 100644 index 56252dd..0000000 --- a/glibc-dlopen-nodelete-fixes-3.patch +++ /dev/null @@ -1,130 +0,0 @@ -Author: Florian Weimer -Date: Thu Dec 5 16:20:30 2019 +0100 - - dlopen: Do not block signals - - Blocking signals causes issues with certain anti-malware solutions - which rely on an unblocked SIGSYS signal for system calls they - intercept. - - This reverts commit a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23 - ("Block signals during the initial part of dlopen") and adds - comments related to async signal safety to active_nodelete and - its caller. - - Note that this does not make lazy binding async-signal-safe with regards - to dlopen. It merely avoids introducing new async-signal-safety hazards - as part of the NODELETE changes. - -diff --git a/elf/dl-open.c b/elf/dl-open.c -index c23341be5892fb12..5a1c5b53269f1236 100644 ---- a/elf/dl-open.c -+++ b/elf/dl-open.c -@@ -34,7 +34,6 @@ - #include - #include - #include --#include - - #include - #include -@@ -53,10 +52,6 @@ struct dl_open_args - /* Namespace ID. */ - Lmid_t nsid; - -- /* Original signal mask. Used for unblocking signal handlers before -- running ELF constructors. */ -- sigset_t original_signal_mask; -- - /* Original value of _ns_global_scope_pending_adds. Set by - dl_open_worker. Only valid if nsid is a real namespace - (non-negative). */ -@@ -446,6 +441,9 @@ activate_nodelete (struct link_map *new) - _dl_debug_printf ("activating NODELETE for %s [%lu]\n", - l->l_name, l->l_ns); - -+ /* The flag can already be true at this point, e.g. a signal -+ handler may have triggered lazy binding and set NODELETE -+ status immediately. */ - l->l_nodelete_active = true; - - /* This is just a debugging aid, to indicate that -@@ -520,16 +518,12 @@ dl_open_worker (void *a) - if (new == NULL) - { - assert (mode & RTLD_NOLOAD); -- __libc_signal_restore_set (&args->original_signal_mask); - return; - } - - if (__glibc_unlikely (mode & __RTLD_SPROF)) -- { -- /* This happens only if we load a DSO for 'sprof'. */ -- __libc_signal_restore_set (&args->original_signal_mask); -- return; -- } -+ /* This happens only if we load a DSO for 'sprof'. */ -+ return; - - /* This object is directly loaded. */ - ++new->l_direct_opencount; -@@ -565,7 +559,6 @@ dl_open_worker (void *a) - - assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); - -- __libc_signal_restore_set (&args->original_signal_mask); - return; - } - -@@ -712,6 +705,12 @@ dl_open_worker (void *a) - All memory allocations for new objects must have happened - before. */ - -+ /* Finalize the NODELETE status first. This comes before -+ update_scopes, so that lazy binding will not see pending NODELETE -+ state for newly loaded objects. There is a compiler barrier in -+ update_scopes which ensures that the changes from -+ activate_nodelete are visible before new objects show up in the -+ local scope. */ - activate_nodelete (new); - - /* Second stage after resize_scopes: Actually perform the scope -@@ -745,10 +744,6 @@ dl_open_worker (void *a) - if (mode & RTLD_GLOBAL) - add_to_global_resize (new); - -- /* Unblock signals. Data structures are now consistent, and -- application code may run. */ -- __libc_signal_restore_set (&args->original_signal_mask); -- - /* Run the initializer functions of new objects. Temporarily - disable the exception handler, so that lazy binding failures are - fatal. */ -@@ -838,10 +833,6 @@ no more namespaces available for dlmopen()")); - args.argv = argv; - args.env = env; - -- /* Recursive lazy binding during manipulation of the dynamic loader -- structures may result in incorrect behavior. */ -- __libc_signal_block_all (&args.original_signal_mask); -- - struct dl_exception exception; - int errcode = _dl_catch_exception (&exception, dl_open_worker, &args); - -@@ -882,16 +873,10 @@ no more namespaces available for dlmopen()")); - - _dl_close_worker (args.map, true); - -- /* Restore the signal mask. In the success case, this -- happens inside dl_open_worker. */ -- __libc_signal_restore_set (&args.original_signal_mask); -- - /* All l_nodelete_pending objects should have been deleted - at this point, which is why it is not necessary to reset - the flag here. */ - } -- else -- __libc_signal_restore_set (&args.original_signal_mask); - - assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); - diff --git a/glibc.spec b/glibc.spec index 3a5c106..598e1d7 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1,4 +1,4 @@ -%define glibcsrcdir glibc-2.30.9000-349-g0487ebed22 +%define glibcsrcdir glibc-2.30.9000-396-g3dcad8158f %define glibcversion 2.30.9000 # Pre-release tarballs are pulled in from git using a command that is # effectively: @@ -87,7 +87,7 @@ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 25%{?dist} +Release: 26%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -158,9 +158,6 @@ Patch17: glibc-cs-path.patch Patch18: glibc-c-utf8-locale.patch Patch23: glibc-python3.patch Patch29: glibc-fedora-nsswitch.patch -Patch30: glibc-dlopen-nodelete-fixes-1.patch -Patch31: glibc-dlopen-nodelete-fixes-2.patch -Patch32: glibc-dlopen-nodelete-fixes-3.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2044,6 +2041,57 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Thu Dec 19 2019 Patsy Franklin - 2.30.9000-26 +- Auto-sync with upstream branch master, + commit 3dcad8158f43d71d5b8f6f317f82952ddf3468f3. +- hurd: Do not make sigprocmask available in ld.so +- build-many-glibcs.py: Do not build C++ PCHs by default +- hurd: Make getrandom honour GRND_NONBLOCK +- tunables: report sbrk() failure +- build-many-glibcs.py: Add mipsisa64r6el-linux-gnu target +- mips: Do not include hi and lo in __SYSCALL_CLOBBERS for R6 +- ldbl-128ibm-compat: Add ISO C99 versions of scanf functions +- ldbl-128ibm-compat: Fix selection of GNU and ISO C99 scanf +- hurd: Fix local PLT +- dlopen: Do not block signals +- dlopen: Rework handling of pending NODELETE status +- dlopen: Fix issues related to NODELETE handling and relocations +- hurd: Fix __close_nocancel_nostatus availability +- hurd: add getrandom and getentropy implementations +- hurd: Implement __close_nocancel_nostatus +- manual: clarify fopen with the x flag +- S390: Use sysdeps/ieee754/dbl-64/wordsize-64 on s390x. +- S390: Implement roundtoint and converttoint and define TOINT_INTRINSICS. +- S390: Implement math-barriers math_opt_barrier and math_force_eval. +- S390: Use libc_fe* macros in fe* functions. +- S390: Implement libc_fe* macros. +- S390: Use convert-to-fixed instruction for llround functions. +- S390: Use convert-to-fixed instruction for lround functions. +- S390: Use convert-to-fixed instruction for llrint functions. +- S390: Use convert-to-fixed instruction for lrint functions. +- S390: Use load-fp-integer instruction for roundeven functions. +- Adjust s_copysignl.c regarding code style. +- Adjust s_ceilf.c and s_ceill.c regarding code style. +- Adjust s_floorf.c and s_floorl.c regarding code style. +- Adjust s_rintf.c and s_rintl.c regarding code style. +- Adjust s_nearbyintf.c and s_nearbyintl.c regarding code style. +- Use GCC builtins for copysign functions if desired. +- Use GCC builtins for round functions if desired. +- Use GCC builtins for trunc functions if desired. +- Use GCC builtins for ceil functions if desired. +- Use GCC builtins for floor functions if desired. +- Use GCC builtins for rint functions if desired. +- Use GCC builtins for nearbyint functions if desired. +- Always use wordsize-64 version of s_round.c. +- Always use wordsize-64 version of s_trunc.c. +- Always use wordsize-64 version of s_ceil.c. +- Always use wordsize-64 version of s_floor.c. +- Always use wordsize-64 version of s_rint.c. +- Always use wordsize-64 version of s_nearbyint.c. +- ldconfig: Do not print a warning for a missing ld.so.conf file +- hurd: Fix using altstack while in an RPC call to be aborted +- Fix failure when CFLAGS contains -DNDEBUG (Bug 25251) + * Mon Dec 09 2019 DJ Delorie - 2.30.9000-25 - Auto-sync with upstream branch master, commit 0487ebed2278b20971af4cabf186fd3681adccf0. diff --git a/sources b/sources index b88442c..362357e 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (glibc-2.30.9000-349-g0487ebed22.tar.xz) = 1f0ac304fa08e66e8a94394b65125ee95872b2046bd499cb982a53da4b60198d9e5f4843b3974d2612614a8095b3e377077a50c7e5cf3359d019173b80634df1 +SHA512 (glibc-2.30.9000-396-g3dcad8158f.tar.xz) = 0d1f2a6ccef1d22f47ba468f94c30dcffb2b4ef0bfe6f7393c8d747d2172802af4020b94f072bed9ea32f19c444474eb1faf75f620a70d75cb0bf471bf8cc9ff