summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Stastny2022-02-14 23:06:27 +0100
committerMilan Stastny2022-02-14 23:06:27 +0100
commit8fbe8792dda4a6565aa0e2c8dc268674be2e82f3 (patch)
tree0394a9f2e9ac249ebd251a26336b0d6583130679
parent32abdc11cf4eb01032fc37e5c05ffdf7b7d15157 (diff)
downloadaur-glibc-dso.tar.gz
Revert to main glibc
-rw-r--r--.SRCINFO56
-rw-r--r--0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch308
-rw-r--r--0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch135
-rw-r--r--0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch26
-rw-r--r--PKGBUILD245
-rw-r--r--bz27343.patch48
-rw-r--r--glibc.install5
-rw-r--r--lib32-glibc.conf1
-rwxr-xr-xlocale-gen42
-rw-r--r--locale.gen.txt23
-rw-r--r--sdt-config.h6
-rw-r--r--sdt.h430
-rw-r--r--v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch1974
-rw-r--r--v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch569
14 files changed, 7 insertions, 3861 deletions
diff --git a/.SRCINFO b/.SRCINFO
index e165633572f8..324fd6d5f2e0 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,65 +1,15 @@
pkgbase = glibc-dso
pkgver = 2.33
- pkgrel = 10
+ pkgrel = 11
url = https://www.gnu.org/software/libc
arch = x86_64
license = GPL
license = LGPL
- makedepends = git
- makedepends = gd
- makedepends = lib32-gcc-libs
- makedepends = python
- makedepends = cpio
- optdepends = perl: for mtrace
- options = !strip
- options = staticlibs
- source = https://ftp.gnu.org/gnu/glibc/glibc-2.33.tar.xz
- source = https://ftp.gnu.org/gnu/glibc/glibc-2.33.tar.xz.sig
- source = locale.gen.txt
- source = locale-gen
- source = lib32-glibc.conf
- source = sdt.h
- source = sdt-config.h
- source = bz27343.patch
- source = 0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch
- source = 0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch
- source = 0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch
- source = v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch
- source = v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch
- validpgpkeys = 7273542B39962DF7B299931416792B4EA25340F8
- validpgpkeys = BC7C7372637EC10C57D7AA6579C43DFBF1CF2187
- md5sums = 390bbd889c7e8e8a7041564cb6b27cca
- md5sums = SKIP
- md5sums = 07ac979b6ab5eeb778d55f041529d623
- md5sums = 476e9113489f93b348b21e144b6a8fcf
- md5sums = 6e052f1cb693d5d3203f50f9d4e8c33b
- md5sums = 91fec3b7e75510ae2ac42533aa2e695e
- md5sums = 680df504c683640b02ed4a805797c0b2
- md5sums = cfe57018d06bf748b8ca1779980fef33
- md5sums = 78f041fc66fee4ee372f13b00a99ff72
- md5sums = 9e418efa189c20053e887398df2253cf
- md5sums = 7a09f1693613897add1791e7aead19c9
- md5sums = 5974b86859dd65c7cfda756a8b2445c2
- md5sums = 26a619a810de7d296608cc78377bc27c
pkgname = glibc-dso
pkgdesc = GNU C Library - DSO patch
- install = glibc.install
- depends = linux-api-headers>=4.10
- depends = tzdata
- depends = filesystem
- optdepends = gd: for memusagestat
- provides = glibc=2.33
- conflicts = glibc
- backup = etc/gai.conf
- backup = etc/locale.gen
- backup = etc/nscd.conf
+ depends = glibc
pkgname = lib32-glibc-dso
pkgdesc = GNU C Library (32-bit) - DSO patch
- depends = glibc=2.33
- provides = lib32-glibc=2.33
- conflicts = lib32-glibc
- options = !strip
- options = staticlibs
- options = !emptydirs
+ depends = lib32-glibc
diff --git a/0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch b/0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch
deleted file mode 100644
index 0b9c2efd4fe1..000000000000
--- a/0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch
+++ /dev/null
@@ -1,308 +0,0 @@
-From a64afc225240b2b27129ccfb0516d7c958b98040 Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Wed, 21 Apr 2021 11:50:43 +0200
-Subject: [PATCH 364/576] nptl_db: Support different libpthread/ld.so load
- orders (bug 27744)
-
-libthread_db is loaded once GDB encounters libpthread, and at this
-point, ld.so may not have been processed by GDB yet. As a result,
-_rtld_global cannot be accessed by regular means from libthread_db.
-To make this work until GDB can be fixed, acess _rtld_global through
-a pointer stored in libpthread.
-
-The new test does not reproduce bug 27744 with
---disable-hardcoded-path-in-tests, but is still a valid smoke test.
-With --enable-hardcoded-path-in-tests, it is necessary to avoid
-add-symbol-file because this can tickle a GDB bug.
-
-Fixes commit 1daccf403b1bd86370eb94edca794dc106d02039 ("nptl: Move
-stack list variables into _rtld_global").
-
-Tested-by: Emil Velikov <emil.velikov@collabora.com>
----
- nptl/Makefile | 19 +++-
- nptl/pthread_create.c | 8 ++
- nptl/tst-pthread-gdb-attach-static.c | 1 +
- nptl/tst-pthread-gdb-attach.c | 143 +++++++++++++++++++++++++++
- nptl_db/structs.def | 3 +-
- nptl_db/td_init.c | 15 +--
- nptl_db/thread_dbP.h | 2 +
- 7 files changed, 180 insertions(+), 11 deletions(-)
- create mode 100644 nptl/tst-pthread-gdb-attach-static.c
- create mode 100644 nptl/tst-pthread-gdb-attach.c
-
-diff --git a/nptl/Makefile b/nptl/Makefile
-index 8fe92d43fa..e665d37e52 100644
---- a/nptl/Makefile
-+++ b/nptl/Makefile
-@@ -313,7 +313,8 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
- tst-thread-affinity-sched \
- tst-pthread-defaultattr-free \
- tst-pthread-attr-sigmask \
-- tst-pthread-timedlock-lockloop
-+ tst-pthread-timedlock-lockloop \
-+ tst-pthread-gdb-attach tst-pthread-gdb-attach-static
-
- tests-container = tst-pthread-getattr
-
-@@ -359,6 +360,19 @@ CPPFLAGS-test-cond-printers.c := $(CFLAGS-printers-tests)
- CPPFLAGS-test-rwlockattr-printers.c := $(CFLAGS-printers-tests)
- CPPFLAGS-test-rwlock-printers.c := $(CFLAGS-printers-tests)
-
-+# Reuse the CFLAGS setting for the GDB attaching test. It needs
-+# debugging information.
-+CFLAGS-tst-pthread-gdb-attach.c := $(CFLAGS-printers-tests)
-+CPPFLAGS-tst-pthread-gdb-attach.c := $(CFLAGS-printers-tests)
-+ifeq ($(build-shared)$(build-hardcoded-path-in-tests),yesno)
-+CPPFLAGS-tst-pthread-gdb-attach.c += -DDO_ADD_SYMBOL_FILE=1
-+else
-+CPPFLAGS-tst-pthread-gdb-attach.c += -DDO_ADD_SYMBOL_FILE=0
-+endif
-+CFLAGS-tst-pthread-gdb-attach-static.c := $(CFLAGS-printers-tests)
-+CPPFLAGS-tst-pthread-gdb-attach-static.c := \
-+ $(CFLAGS-printers-tests) -DDO_ADD_SYMBOL_FILE=0
-+
- ifeq ($(build-shared),yes)
- tests-printers-libs := $(shared-thread-library)
- else
-@@ -430,7 +444,8 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \
- tests-static += tst-stackguard1-static \
- tst-cancel24-static \
- tst-mutex8-static tst-mutexpi8-static tst-sem11-static \
-- tst-sem12-static tst-cond11-static
-+ tst-sem12-static tst-cond11-static \
-+ tst-pthread-gdb-attach-static
-
- tests += tst-cancel24-static
-
-diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
-index 6c645aff48..f13d8e44a4 100644
---- a/nptl/pthread_create.c
-+++ b/nptl/pthread_create.c
-@@ -51,6 +51,14 @@ static td_thr_events_t __nptl_threads_events __attribute_used__;
- /* Pointer to descriptor with the last event. */
- static struct pthread *__nptl_last_event __attribute_used__;
-
-+#ifdef SHARED
-+/* This variable is used to access _rtld_global from libthread_db. If
-+ GDB loads libpthread before ld.so, it is not possible to resolve
-+ _rtld_global directly during libpthread initialization. */
-+static struct rtld_global *__nptl_rtld_global __attribute_used__
-+ = &_rtld_global;
-+#endif
-+
- /* Number of threads running. */
- unsigned int __nptl_nthreads = 1;
-
-diff --git a/nptl/tst-pthread-gdb-attach-static.c b/nptl/tst-pthread-gdb-attach-static.c
-new file mode 100644
-index 0000000000..e159632cac
---- /dev/null
-+++ b/nptl/tst-pthread-gdb-attach-static.c
-@@ -0,0 +1 @@
-+#include "tst-pthread-gdb-attach.c"
-diff --git a/nptl/tst-pthread-gdb-attach.c b/nptl/tst-pthread-gdb-attach.c
-new file mode 100644
-index 0000000000..0603ad844d
---- /dev/null
-+++ b/nptl/tst-pthread-gdb-attach.c
-@@ -0,0 +1,143 @@
-+/* Smoke testing GDB process attach with thread-local variable access.
-+ Copyright (C) 2021 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
-+ <https://www.gnu.org/licenses/>. */
-+
-+/* This test runs GDB against a forked copy of itself, to check
-+ whether libthread_db can be loaded, and that access to thread-local
-+ variables works. */
-+
-+#include <errno.h>
-+#include <stdlib.h>
-+#include <support/check.h>
-+#include <support/support.h>
-+#include <support/temp_file.h>
-+#include <support/test-driver.h>
-+#include <support/xstdio.h>
-+#include <support/xthread.h>
-+#include <support/xunistd.h>
-+#include <unistd.h>
-+
-+/* Starts out as zero, changed to 1 or 2 by the debugger, depending on
-+ the thread. */
-+__thread volatile int altered_by_debugger;
-+
-+/* Writes the GDB script to run the test to PATH. */
-+static void
-+write_gdbscript (const char *path, int tested_pid)
-+{
-+ FILE *fp = xfopen (path, "w");
-+ fprintf (fp,
-+ "set trace-commands on\n"
-+ "set debug libthread-db 1\n"
-+#if DO_ADD_SYMBOL_FILE
-+ /* Do not do this unconditionally to work around a GDB
-+ assertion failure: ../../gdb/symtab.c:6404:
-+ internal-error: CORE_ADDR get_msymbol_address(objfile*,
-+ const minimal_symbol*): Assertion `(objf->flags &
-+ OBJF_MAINLINE) == 0' failed. */
-+ "add-symbol-file %1$s/nptl/tst-pthread-gdb-attach\n"
-+#endif
-+ "set auto-load safe-path %1$s/nptl_db\n"
-+ "set libthread-db-search-path %1$s/nptl_db\n"
-+ "attach %2$d\n",
-+ support_objdir_root, tested_pid);
-+ fputs ("break debugger_inspection_point\n"
-+ "continue\n"
-+ "thread 1\n"
-+ "print altered_by_debugger\n"
-+ "print altered_by_debugger = 1\n"
-+ "thread 2\n"
-+ "print altered_by_debugger\n"
-+ "print altered_by_debugger = 2\n"
-+ "continue\n",
-+ fp);
-+ xfclose (fp);
-+}
-+
-+/* The test sets a breakpoint on this function and alters the
-+ altered_by_debugger thread-local variable. */
-+void __attribute__ ((weak))
-+debugger_inspection_point (void)
-+{
-+}
-+
-+/* Thread function for the test thread in the subprocess. */
-+static void *
-+subprocess_thread (void *closure)
-+{
-+ /* Wait until altered_by_debugger changes the value away from 0. */
-+ while (altered_by_debugger == 0)
-+ {
-+ usleep (100 * 1000);
-+ debugger_inspection_point ();
-+ }
-+
-+ TEST_COMPARE (altered_by_debugger, 2);
-+ return NULL;
-+}
-+
-+/* This function implements the subprocess under test. It creates a
-+ second thread, waiting for its value to change to 2, and checks
-+ that the main thread also changed its value to 1. */
-+static void
-+in_subprocess (void)
-+{
-+ pthread_t thr = xpthread_create (NULL, subprocess_thread, NULL);
-+ TEST_VERIFY (xpthread_join (thr) == NULL);
-+ TEST_COMPARE (altered_by_debugger, 1);
-+ _exit (0);
-+}
-+
-+static int
-+do_test (void)
-+{
-+ pid_t tested_pid = xfork ();
-+ if (tested_pid == 0)
-+ in_subprocess ();
-+ char *tested_pid_string = xasprintf ("%d", tested_pid);
-+
-+ char *gdbscript;
-+ xclose (create_temp_file ("tst-pthread-gdb-attach-", &gdbscript));
-+ write_gdbscript (gdbscript, tested_pid);
-+
-+ pid_t gdb_pid = xfork ();
-+ if (gdb_pid == 0)
-+ {
-+ clearenv ();
-+ xdup2 (STDOUT_FILENO, STDERR_FILENO);
-+ execlp ("gdb", "gdb", "-nx", "-batch", "-x", gdbscript, NULL);
-+ if (errno == ENOENT)
-+ _exit (EXIT_UNSUPPORTED);
-+ else
-+ _exit (1);
-+ }
-+
-+ int status;
-+ TEST_COMPARE (xwaitpid (gdb_pid, &status, 0), gdb_pid);
-+ if (WIFEXITED (status) && WEXITSTATUS (status) == EXIT_UNSUPPORTED)
-+ /* gdb is not installed. */
-+ return EXIT_UNSUPPORTED;
-+ TEST_COMPARE (status, 0);
-+ TEST_COMPARE (xwaitpid (tested_pid, &status, 0), tested_pid);
-+ TEST_COMPARE (status, 0);
-+
-+ free (tested_pid_string);
-+ free (gdbscript);
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/nptl_db/structs.def b/nptl_db/structs.def
-index 999a9fc35a..8a613dd2f5 100644
---- a/nptl_db/structs.def
-+++ b/nptl_db/structs.def
-@@ -100,8 +100,7 @@ DB_STRUCT_FIELD (pthread, dtvp)
- #endif
-
- #if !(IS_IN (libpthread) && !defined SHARED)
--DB_STRUCT (rtld_global)
--DB_RTLD_VARIABLE (_rtld_global)
-+DB_VARIABLE (__nptl_rtld_global)
- #endif
- DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list)
- DB_RTLD_GLOBAL_FIELD (dl_stack_user)
-diff --git a/nptl_db/td_init.c b/nptl_db/td_init.c
-index 1d15681228..06b5adc5c2 100644
---- a/nptl_db/td_init.c
-+++ b/nptl_db/td_init.c
-@@ -33,13 +33,14 @@ td_init (void)
- bool
- __td_ta_rtld_global (td_thragent_t *ta)
- {
-- if (ta->ta_addr__rtld_global == 0
-- && td_mod_lookup (ta->ph, LD_SO, SYM__rtld_global,
-- &ta->ta_addr__rtld_global) != PS_OK)
-+ if (ta->ta_addr__rtld_global == 0)
- {
-- ta->ta_addr__rtld_global = (void*)-1;
-- return false;
-+ psaddr_t rtldglobalp;
-+ if (DB_GET_VALUE (rtldglobalp, ta, __nptl_rtld_global, 0) == TD_OK)
-+ ta->ta_addr__rtld_global = rtldglobalp;
-+ else
-+ ta->ta_addr__rtld_global = (void *) -1;
- }
-- else
-- return ta->ta_addr__rtld_global != (void*)-1;
-+
-+ return ta->ta_addr__rtld_global != (void *)-1;
- }
-diff --git a/nptl_db/thread_dbP.h b/nptl_db/thread_dbP.h
-index 580a70c471..712fa3aeb6 100644
---- a/nptl_db/thread_dbP.h
-+++ b/nptl_db/thread_dbP.h
-@@ -108,6 +108,8 @@ struct td_thragent
- # undef DB_SYMBOL
- # undef DB_VARIABLE
-
-+ psaddr_t ta_addr__rtld_global;
-+
- /* The method of locating a thread's th_unique value. */
- enum
- {
---
-2.31.1
-
diff --git a/0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch b/0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch
deleted file mode 100644
index d3846d654ca7..000000000000
--- a/0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From f553dc066071a4465321fbc122bed8a75afd996b Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Thu, 22 Apr 2021 11:07:43 +0200
-Subject: [PATCH 405/576] nptl: Check for compatible GDB in
- nptl/tst-pthread-gdb-attach
-
-Also do not clear the subprocess environment, in case running
-GDB needs certain environment variables.
----
- nptl/tst-pthread-gdb-attach.c | 78 ++++++++++++++++++++++++++++++++++-
- 1 file changed, 76 insertions(+), 2 deletions(-)
-
-diff --git a/nptl/tst-pthread-gdb-attach.c b/nptl/tst-pthread-gdb-attach.c
-index 0603ad844d..901a120034 100644
---- a/nptl/tst-pthread-gdb-attach.c
-+++ b/nptl/tst-pthread-gdb-attach.c
-@@ -20,8 +20,12 @@
- whether libthread_db can be loaded, and that access to thread-local
- variables works. */
-
-+#include <elf.h>
- #include <errno.h>
-+#include <fcntl.h>
-+#include <stdbool.h>
- #include <stdlib.h>
-+#include <string.h>
- #include <support/check.h>
- #include <support/support.h>
- #include <support/temp_file.h>
-@@ -35,6 +39,49 @@
- the thread. */
- __thread volatile int altered_by_debugger;
-
-+/* Common prefix between 32-bit and 64-bit ELF. */
-+struct elf_prefix
-+{
-+ unsigned char e_ident[EI_NIDENT];
-+ uint16_t e_type;
-+ uint16_t e_machine;
-+ uint32_t e_version;
-+};
-+_Static_assert (sizeof (struct elf_prefix) == EI_NIDENT + 8,
-+ "padding in struct elf_prefix");
-+
-+/* Reads the ELF header from PATH. Returns true if the header can be
-+ read, false if the file is too short. */
-+static bool
-+read_elf_header (const char *path, struct elf_prefix *elf)
-+{
-+ int fd = xopen (path, O_RDONLY, 0);
-+ bool result = read (fd, elf, sizeof (*elf)) == sizeof (*elf);
-+ xclose (fd);
-+ return result;
-+}
-+
-+/* Searches for "gdb" alongside the path variable. See execvpe. */
-+static char *
-+find_gdb (void)
-+{
-+ const char *path = getenv ("PATH");
-+ if (path == NULL)
-+ return NULL;
-+ while (true)
-+ {
-+ const char *colon = strchrnul (path, ':');
-+ char *candidate = xasprintf ("%.*s/gdb", (int) (colon - path), path);
-+ if (access (candidate, X_OK) == 0)
-+ return candidate;
-+ free (candidate);
-+ if (*colon == '\0')
-+ break;
-+ path = colon + 1;
-+ }
-+ return NULL;
-+}
-+
- /* Writes the GDB script to run the test to PATH. */
- static void
- write_gdbscript (const char *path, int tested_pid)
-@@ -105,6 +152,33 @@ in_subprocess (void)
- static int
- do_test (void)
- {
-+ char *gdb_path = find_gdb ();
-+ if (gdb_path == NULL)
-+ FAIL_UNSUPPORTED ("gdb command not found in PATH: %s", getenv ("PATH"));
-+
-+ /* Check that libthread_db is compatible with the gdb architecture
-+ because gdb loads it via dlopen. */
-+ {
-+ char *threaddb_path = xasprintf ("%s/nptl_db/libthread_db.so",
-+ support_objdir_root);
-+ struct elf_prefix elf_threaddb;
-+ TEST_VERIFY_EXIT (read_elf_header (threaddb_path, &elf_threaddb));
-+ struct elf_prefix elf_gdb;
-+ /* If the ELF header cannot be read or "gdb" is not an ELF file,
-+ assume this is a wrapper script that can run. */
-+ if (read_elf_header (gdb_path, &elf_gdb)
-+ && memcmp (&elf_gdb, ELFMAG, SELFMAG) == 0)
-+ {
-+ if (elf_gdb.e_ident[EI_CLASS] != elf_threaddb.e_ident[EI_CLASS])
-+ FAIL_UNSUPPORTED ("GDB at %s has wrong class", gdb_path);
-+ if (elf_gdb.e_ident[EI_DATA] != elf_threaddb.e_ident[EI_DATA])
-+ FAIL_UNSUPPORTED ("GDB at %s has wrong data", gdb_path);
-+ if (elf_gdb.e_machine != elf_threaddb.e_machine)
-+ FAIL_UNSUPPORTED ("GDB at %s has wrong machine", gdb_path);
-+ }
-+ free (threaddb_path);
-+ }
-+
- pid_t tested_pid = xfork ();
- if (tested_pid == 0)
- in_subprocess ();
-@@ -117,9 +191,8 @@ do_test (void)
- pid_t gdb_pid = xfork ();
- if (gdb_pid == 0)
- {
-- clearenv ();
- xdup2 (STDOUT_FILENO, STDERR_FILENO);
-- execlp ("gdb", "gdb", "-nx", "-batch", "-x", gdbscript, NULL);
-+ execl (gdb_path, "gdb", "-nx", "-batch", "-x", gdbscript, NULL);
- if (errno == ENOENT)
- _exit (EXIT_UNSUPPORTED);
- else
-@@ -137,6 +210,7 @@ do_test (void)
-
- free (tested_pid_string);
- free (gdbscript);
-+ free (gdb_path);
- return 0;
- }
-
---
-2.31.1
-
diff --git a/0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch b/0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch
deleted file mode 100644
index 1ba043d0233c..000000000000
--- a/0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 6f3e54d404cfe1ba7d1444e6dfcfd77b102d9287 Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Thu, 22 Apr 2021 19:53:15 +0200
-Subject: [PATCH 409/576] nptl: Do not build nptl/tst-pthread-gdb-attach as PIE
-
----
- nptl/Makefile | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/nptl/Makefile b/nptl/Makefile
-index a3d1ef8d66..294bb2faa4 100644
---- a/nptl/Makefile
-+++ b/nptl/Makefile
-@@ -377,6 +377,9 @@ endif
- CFLAGS-tst-pthread-gdb-attach-static.c := $(CFLAGS-printers-tests)
- CPPFLAGS-tst-pthread-gdb-attach-static.c := \
- $(CFLAGS-printers-tests) -DDO_ADD_SYMBOL_FILE=0
-+# As of version 9.2, GDB cannot attach properly to PIE programs that
-+# were launched with an explicit ld.so invocation.
-+tst-pthread-gdb-attach-no-pie = yes
-
- ifeq ($(build-shared),yes)
- tests-printers-libs := $(shared-thread-library)
---
-2.31.1
-
diff --git a/PKGBUILD b/PKGBUILD
index 30d009469db6..6fd444f718fb 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -6,258 +6,21 @@
pkgbase=glibc-dso
pkgname=(glibc-dso lib32-glibc-dso)
pkgver=2.33
-pkgrel=10
+pkgrel=11
arch=(x86_64)
url='https://www.gnu.org/software/libc'
license=(GPL LGPL)
-makedepends=(git gd lib32-gcc-libs python cpio)
-optdepends=('perl: for mtrace')
-options=(!strip staticlibs)
-#_commit=3de512be7ea6053255afed6154db9ee31d4e557a
-#source=(git+https://sourceware.org/git/glibc.git#commit=$_commit
-source=(https://ftp.gnu.org/gnu/glibc/glibc-$pkgver.tar.xz{,.sig}
- locale.gen.txt
- locale-gen
- lib32-glibc.conf
- sdt.h sdt-config.h
- bz27343.patch
- 0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch
- 0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch
- 0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch
- v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch
- v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch)
-validpgpkeys=(7273542B39962DF7B299931416792B4EA25340F8 # Carlos O'Donell
- BC7C7372637EC10C57D7AA6579C43DFBF1CF2187) # Siddhesh Poyarekar
-md5sums=('390bbd889c7e8e8a7041564cb6b27cca'
- 'SKIP'
- '07ac979b6ab5eeb778d55f041529d623'
- '476e9113489f93b348b21e144b6a8fcf'
- '6e052f1cb693d5d3203f50f9d4e8c33b'
- '91fec3b7e75510ae2ac42533aa2e695e'
- '680df504c683640b02ed4a805797c0b2'
- 'cfe57018d06bf748b8ca1779980fef33'
- '78f041fc66fee4ee372f13b00a99ff72'
- '9e418efa189c20053e887398df2253cf'
- '7a09f1693613897add1791e7aead19c9'
- '5974b86859dd65c7cfda756a8b2445c2'
- '26a619a810de7d296608cc78377bc27c')
prepare() {
- echo "THIS PACKAGE IS NO LONGER WORKING DO NOT INSTALL IT"
- exit 1
-
- mkdir -p glibc-build lib32-glibc-build
-
- [[ -d glibc-$pkgver ]] && ln -s glibc-$pkgver glibc
- cd glibc
-
- # commit c3479fb7939898ec22c655c383454d6e8b982a67
- patch -p1 -i "$srcdir"/bz27343.patch
-
- # nptl_db: Support different libpthread/ld.so load orders (bug 27744)
- patch -p1 -i "$srcdir"/0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch
-
- # nptl: Check for compatible GDB in nptl/tst-pthread-gdb-attach
- patch -p1 -i "$srcdir"/0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch
-
- # nptl: Do not build nptl/tst-pthread-gdb-attach as PIE
- patch -p1 -i "$srcdir"/0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch
- patch -p1 -i "$srcdir"/v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch
- patch -p1 -i "$srcdir"/v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch
-}
-
-build() {
- local _configure_flags=(
- --prefix=/usr
- --with-headers=/usr/include
- --with-bugurl=https://bugs.archlinux.org/
- --enable-add-ons
- --enable-bind-now
- --enable-cet
- --enable-kernel=4.4
- --enable-lock-elision
- --enable-multi-arch
- --enable-stack-protector=strong
- --enable-stackguard-randomization
- --enable-static-pie
- --enable-systemtap
- --disable-profile
- --disable-werror
- )
-
- cd "$srcdir/glibc-build"
-
- echo "slibdir=/usr/lib" >> configparms
- echo "rtlddir=/usr/lib" >> configparms
- echo "sbindir=/usr/bin" >> configparms
- echo "rootsbindir=/usr/bin" >> configparms
-
- # remove fortify for building libraries
- CPPFLAGS=${CPPFLAGS/-D_FORTIFY_SOURCE=2/}
- CFLAGS=${CFLAGS/-Wp,-D_FORTIFY_SOURCE=2/}
-
- #
- CFLAGS=${CFLAGS/-fno-plt/}
- CXXFLAGS=${CXXFLAGS/-fno-plt/}
- LDFLAGS=${LDFLAGS/,-z,now/}
-
- "$srcdir/glibc/configure" \
- --libdir=/usr/lib \
- --libexecdir=/usr/lib \
- ${_configure_flags[@]}
-
- # build libraries with fortify disabled
- echo "build-programs=no" >> configparms
- make
-
- # re-enable fortify for programs
- sed -i "/build-programs=/s#no#yes#" configparms
-
- echo "CC += -D_FORTIFY_SOURCE=2" >> configparms
- echo "CXX += -D_FORTIFY_SOURCE=2" >> configparms
- make
-
- # build info pages manually for reprducibility
- make info
-
- cd "$srcdir/lib32-glibc-build"
- export CC="gcc -m32 -mstackrealign"
- export CXX="g++ -m32 -mstackrealign"
-
- echo "slibdir=/usr/lib32" >> configparms
- echo "rtlddir=/usr/lib32" >> configparms
- echo "sbindir=/usr/bin" >> configparms
- echo "rootsbindir=/usr/bin" >> configparms
-
- # remove fortify for building libraries
- CPPFLAGS=${CPPFLAGS/-D_FORTIFY_SOURCE=2/}
- CFLAGS=${CFLAGS/-Wp,-D_FORTIFY_SOURCE=2/}
- CFLAGS=${CFLAGS/-fno-plt/}
- CXXFLAGS=${CXXFLAGS/-fno-plt/}
-
- "$srcdir/glibc/configure" \
- --host=i686-pc-linux-gnu \
- --libdir=/usr/lib32 \
- --libexecdir=/usr/lib32 \
- ${_configure_flags[@]}
-
- # build libraries with fortify disabled
- echo "build-programs=no" >> configparms
- make
-
- # re-enable fortify for programs
- sed -i "/build-programs=/s#no#yes#" configparms
-
- echo "CC += -D_FORTIFY_SOURCE=2" >> configparms
- echo "CXX += -D_FORTIFY_SOURCE=2" >> configparms
- make
-
-}
-
-check() {
- cd glibc-build
-
- # remove fortify in preparation to run test-suite
- sed -i '/FORTIFY/d' configparms
-
- # some failures are "expected"
- make check || true
+ echo "This package is decomisioned, installing this update will revert to your mainline glibc and should be installed ASAP"
}
package_glibc-dso() {
pkgdesc='GNU C Library - DSO patch'
- depends=('linux-api-headers>=4.10' tzdata filesystem)
- optdepends=('gd: for memusagestat')
- install=glibc.install
- backup=(etc/gai.conf
- etc/locale.gen
- etc/nscd.conf)
- provides=("glibc=${pkgver%%.r*}")
- conflicts=('glibc')
-
- install -dm755 "$pkgdir/etc"
- touch "$pkgdir/etc/ld.so.conf"
-
- make -C glibc-build install_root="$pkgdir" install
- rm -f "$pkgdir"/etc/ld.so.{cache,conf}
-
- # Shipped in tzdata
- rm -f "$pkgdir"/usr/bin/{tzselect,zdump,zic}
-
- cd glibc
-
- install -dm755 "$pkgdir"/usr/lib/{locale,systemd/system,tmpfiles.d}
- install -m644 nscd/nscd.conf "$pkgdir/etc/nscd.conf"
- install -m644 nscd/nscd.service "$pkgdir/usr/lib/systemd/system"
- install -m644 nscd/nscd.tmpfiles "$pkgdir/usr/lib/tmpfiles.d/nscd.conf"
- install -dm755 "$pkgdir/var/db/nscd"
-
- install -m644 posix/gai.conf "$pkgdir"/etc/gai.conf
-
- install -m755 "$srcdir/locale-gen" "$pkgdir/usr/bin"
-
- # Create /etc/locale.gen
- install -m644 "$srcdir/locale.gen.txt" "$pkgdir/etc/locale.gen"
- sed -e '1,3d' -e 's|/| |g' -e 's|\\| |g' -e 's|^|#|g' \
- "$srcdir/glibc/localedata/SUPPORTED" >> "$pkgdir/etc/locale.gen"
-
- if check_option 'debug' n; then
- find "$pkgdir"/usr/bin -type f -executable -exec strip $STRIP_BINARIES {} + 2> /dev/null || true
- find "$pkgdir"/usr/lib -name '*.a' -type f -exec strip $STRIP_STATIC {} + 2> /dev/null || true
-
- # Do not strip these for gdb and valgrind functionality, but strip the rest
- find "$pkgdir"/usr/lib \
- -not -name 'ld-*.so' \
- -not -name 'libc-*.so' \
- -not -name 'libpthread-*.so' \
- -not -name 'libthread_db-*.so' \
- -name '*-*.so' -type f -exec strip $STRIP_SHARED {} + 2> /dev/null || true
- fi
-
- # Provide tracing probes to libstdc++ for exceptions, possibly for other
- # libraries too. Useful for gdb's catch command.
- install -Dm644 "$srcdir/sdt.h" "$pkgdir/usr/include/sys/sdt.h"
- install -Dm644 "$srcdir/sdt-config.h" "$pkgdir/usr/include/sys/sdt-config.h"
-
- # Provided by libxcrypt; keep the old shared library for backwards compatibility
- rm -f "$pkgdir"/usr/include/crypt.h "$pkgdir"/usr/lib/libcrypt.{a,so}
+ depends=('glibc')
}
package_lib32-glibc-dso() {
pkgdesc='GNU C Library (32-bit) - DSO patch'
- depends=("glibc=$pkgver")
- options+=('!emptydirs')
- provides=("lib32-glibc=${pkgver%%.r*}")
- conflicts=('lib32-glibc')
-
- cd lib32-glibc-build
-
- make install_root="$pkgdir" install
- rm -rf "$pkgdir"/{etc,sbin,usr/{bin,sbin,share},var}
-
- # We need to keep 32 bit specific header files
- find "$pkgdir/usr/include" -type f -not -name '*-32.h' -delete
-
- # Dynamic linker
- install -d "$pkgdir/usr/lib"
- ln -s ../lib32/ld-linux.so.2 "$pkgdir/usr/lib/"
-
- # Add lib32 paths to the default library search path
- install -Dm644 "$srcdir/lib32-glibc.conf" "$pkgdir/etc/ld.so.conf.d/lib32-glibc.conf"
-
- # Symlink /usr/lib32/locale to /usr/lib/locale
- ln -s ../lib/locale "$pkgdir/usr/lib32/locale"
-
- if check_option 'debug' n; then
- find "$pkgdir"/usr/lib32 -name '*.a' -type f -exec strip $STRIP_STATIC {} + 2> /dev/null || true
- find "$pkgdir"/usr/lib32 \
- -not -name 'ld-*.so' \
- -not -name 'libc-*.so' \
- -not -name 'libpthread-*.so' \
- -not -name 'libthread_db-*.so' \
- -name '*-*.so' -type f -exec strip $STRIP_SHARED {} + 2> /dev/null || true
- fi
-
- # Provided by lib32-libxcrypt; keep the old shared library for backwards compatibility
- rm -f "$pkgdir"/usr/lib32/libcrypt.{a,so}
+ depends=("lib32-glibc")
}
diff --git a/bz27343.patch b/bz27343.patch
deleted file mode 100644
index 3db6a9440eb2..000000000000
--- a/bz27343.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From c3479fb7939898ec22c655c383454d6e8b982a67 Mon Sep 17 00:00:00 2001
-From: Sergei Trofimovich <slyfox@gentoo.org>
-Date: Fri, 5 Feb 2021 07:32:18 +0000
-Subject: [PATCH] nsswitch: return result when nss database is locked [BZ
- #27343]
-
-Before the change nss_database_check_reload_and_get() did not populate
-the '*result' value when it returned success in a case of chroot
-detection. This caused initgroups() to use garage pointer in the
-following test (extracted from unbound):
-
-```
-
-int main() {
- // load some NSS modules
- struct passwd * pw = getpwnam("root");
-
- chdir("/tmp");
- chroot("/tmp");
- chdir("/");
- // access nsswitch.conf in a chroot
- initgroups("root", 0);
-}
-```
-
-Reviewed-by: DJ Delorie <dj@redhat.com>
----
- nss/nss_database.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/nss/nss_database.c b/nss/nss_database.c
-index cf0306adc4..e1bef6bd75 100644
---- a/nss/nss_database.c
-+++ b/nss/nss_database.c
-@@ -398,8 +398,9 @@ nss_database_check_reload_and_get (struct nss_database_state *local,
- && (str.st_ino != local->root_ino
- || str.st_dev != local->root_dev)))
- {
-- /* Change detected; disable reloading. */
-+ /* Change detected; disable reloading and return current state. */
- atomic_store_release (&local->data.reload_disabled, 1);
-+ *result = local->data.services[database_index];
- __libc_lock_unlock (local->lock);
- __nss_module_disable_loading ();
- return true;
---
-2.27.0
-
diff --git a/glibc.install b/glibc.install
deleted file mode 100644
index 351f05b263cb..000000000000
--- a/glibc.install
+++ /dev/null
@@ -1,5 +0,0 @@
-post_upgrade() {
- locale-gen
-
- ldconfig -r .
-}
diff --git a/lib32-glibc.conf b/lib32-glibc.conf
deleted file mode 100644
index 9b08c3f43a78..000000000000
--- a/lib32-glibc.conf
+++ /dev/null
@@ -1 +0,0 @@
-/usr/lib32
diff --git a/locale-gen b/locale-gen
deleted file mode 100755
index 5aff344c4e91..000000000000
--- a/locale-gen
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-
-set -e
-
-LOCALEGEN=/etc/locale.gen
-LOCALES=/usr/share/i18n/locales
-if [ -n "$POSIXLY_CORRECT" ]; then
- unset POSIXLY_CORRECT
-fi
-
-
-[ -f $LOCALEGEN -a -s $LOCALEGEN ] || exit 0;
-
-# Remove all old locale dir and locale-archive before generating new
-# locale data.
-rm -rf /usr/lib/locale/* || true
-
-umask 022
-
-is_entry_ok() {
- if [ -n "$locale" -a -n "$charset" ] ; then
- true
- else
- echo "error: Bad entry '$locale $charset'"
- false
- fi
-}
-
-echo "Generating locales..."
-while read locale charset; do \
- case $locale in \#*) continue;; "") continue;; esac; \
- is_entry_ok || continue
- echo -n " `echo $locale | sed 's/\([^.\@]*\).*/\1/'`"; \
- echo -n ".$charset"; \
- echo -n `echo $locale | sed 's/\([^\@]*\)\(\@.*\)*/\2/'`; \
- echo -n '...'; \
- if [ -f $LOCALES/$locale ]; then input=$locale; else \
- input=`echo $locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; fi; \
- localedef -i $input -c -f $charset -A /usr/share/locale/locale.alias $locale; \
- echo ' done'; \
-done < $LOCALEGEN
-echo "Generation complete."
diff --git a/locale.gen.txt b/locale.gen.txt
deleted file mode 100644
index ccdd817342c7..000000000000
--- a/locale.gen.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-# Configuration file for locale-gen
-#
-# lists of locales that are to be generated by the locale-gen command.
-#
-# Each line is of the form:
-#
-# <locale> <charset>
-#
-# where <locale> is one of the locales given in /usr/share/i18n/locales
-# and <charset> is one of the character sets listed in /usr/share/i18n/charmaps
-#
-# Examples:
-# en_US ISO-8859-1
-# en_US.UTF-8 UTF-8
-# de_DE ISO-8859-1
-# de_DE@euro ISO-8859-15
-#
-# The locale-gen command will generate all the locales,
-# placing them in /usr/lib/locale.
-#
-# A list of supported locales is included in this file.
-# Uncomment the ones you need.
-#
diff --git a/sdt-config.h b/sdt-config.h
deleted file mode 100644
index 733045a52771..000000000000
--- a/sdt-config.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* includes/sys/sdt-config.h. Generated from sdt-config.h.in by configure.
-
- This file just defines _SDT_ASM_SECTION_AUTOGROUP_SUPPORT to 0 or 1 to
- indicate whether the assembler supports "?" in .pushsection directives. */
-
-#define _SDT_ASM_SECTION_AUTOGROUP_SUPPORT 1
diff --git a/sdt.h b/sdt.h
deleted file mode 100644
index c0c5a492cb9c..000000000000
--- a/sdt.h
+++ /dev/null
@@ -1,430 +0,0 @@
-/* <sys/sdt.h> - Systemtap static probe definition macros.
-
- This file is dedicated to the public domain, pursuant to CC0
- (https://creativecommons.org/publicdomain/zero/1.0/)
-*/
-
-#ifndef _SYS_SDT_H
-#define _SYS_SDT_H 1
-
-/*
- This file defines a family of macros
-
- STAP_PROBEn(op1, ..., opn)
-
- that emit a nop into the instruction stream, and some data into an auxiliary
- note section. The data in the note section describes the operands, in terms
- of size and location. Each location is encoded as assembler operand string.
- Consumer tools such as gdb or systemtap insert breakpoints on top of
- the nop, and decode the location operand-strings, like an assembler,
- to find the values being passed.
-
- The operand strings are selected by the compiler for each operand.
- They are constrained by gcc inline-assembler codes. The default is:
-
- #define STAP_SDT_ARG_CONSTRAINT nor
-
- This is a good default if the operands tend to be integral and
- moderate in number (smaller than number of registers). In other
- cases, the compiler may report "'asm' requires impossible reload" or
- similar. In this case, consider simplifying the macro call (fewer
- and simpler operands), reduce optimization, or override the default
- constraints string via:
-
- #define STAP_SDT_ARG_CONSTRAINT g
- #include <sys/sdt.h>
-
- See also:
- https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation
- https://gcc.gnu.org/onlinedocs/gcc/Constraints.html
- */
-
-
-
-#ifdef __ASSEMBLER__
-# define _SDT_PROBE(provider, name, n, arglist) \
- _SDT_ASM_BODY(provider, name, _SDT_ASM_STRING_1, (_SDT_DEPAREN_##n arglist)) \
- _SDT_ASM_BASE
-# define _SDT_ASM_1(x) x;
-# define _SDT_ASM_2(a, b) a,b;
-# define _SDT_ASM_3(a, b, c) a,b,c;
-# define _SDT_ASM_5(a, b, c, d, e) a,b,c,d,e;
-# define _SDT_ASM_STRING_1(x) .asciz #x;
-# define _SDT_DEPAREN_0() /* empty */
-# define _SDT_DEPAREN_1(a) a
-# define _SDT_DEPAREN_2(a,b) a b
-# define _SDT_DEPAREN_3(a,b,c) a b c
-# define _SDT_DEPAREN_4(a,b,c,d) a b c d
-# define _SDT_DEPAREN_5(a,b,c,d,e) a b c d e
-# define _SDT_DEPAREN_6(a,b,c,d,e,f) a b c d e f
-# define _SDT_DEPAREN_7(a,b,c,d,e,f,g) a b c d e f g
-# define _SDT_DEPAREN_8(a,b,c,d,e,f,g,h) a b c d e f g h
-# define _SDT_DEPAREN_9(a,b,c,d,e,f,g,h,i) a b c d e f g h i
-# define _SDT_DEPAREN_10(a,b,c,d,e,f,g,h,i,j) a b c d e f g h i j
-# define _SDT_DEPAREN_11(a,b,c,d,e,f,g,h,i,j,k) a b c d e f g h i j k
-# define _SDT_DEPAREN_12(a,b,c,d,e,f,g,h,i,j,k,l) a b c d e f g h i j k l
-#else
-# define _SDT_PROBE(provider, name, n, arglist) \
- do { \
- __asm__ __volatile__ (_SDT_ASM_BODY(provider, name, _SDT_ASM_ARGS, (n)) \
- :: _SDT_ASM_OPERANDS_##n arglist); \
- __asm__ __volatile__ (_SDT_ASM_BASE); \
- } while (0)
-# define _SDT_S(x) #x
-# define _SDT_ASM_1(x) _SDT_S(x) "\n"
-# define _SDT_ASM_2(a, b) _SDT_S(a) "," _SDT_S(b) "\n"
-# define _SDT_ASM_3(a, b, c) _SDT_S(a) "," _SDT_S(b) "," \
- _SDT_S(c) "\n"
-# define _SDT_ASM_5(a, b, c, d, e) _SDT_S(a) "," _SDT_S(b) "," \
- _SDT_S(c) "," _SDT_S(d) "," \
- _SDT_S(e) "\n"
-# define _SDT_ASM_ARGS(n) _SDT_ASM_STRING(_SDT_ASM_TEMPLATE_##n)
-# define _SDT_ASM_STRING_1(x) _SDT_ASM_1(.asciz #x)
-
-# define _SDT_ARGFMT(no) %n[_SDT_S##no]@_SDT_ARGTMPL(_SDT_A##no)
-
-# ifndef STAP_SDT_ARG_CONSTRAINT
-# if defined __powerpc__
-# define STAP_SDT_ARG_CONSTRAINT nZr
-# else
-# define STAP_SDT_ARG_CONSTRAINT nor
-# endif
-# endif
-
-# define _SDT_STRINGIFY(x) #x
-# define _SDT_ARG_CONSTRAINT_STRING(x) _SDT_STRINGIFY(x)
-# define _SDT_ARG(n, x) \
- [_SDT_S##n] "n" ((_SDT_ARGSIGNED (x) ? 1 : -1) * (int) _SDT_ARGSIZE (x)), \
- [_SDT_A##n] _SDT_ARG_CONSTRAINT_STRING (STAP_SDT_ARG_CONSTRAINT) (_SDT_ARGVAL (x))
-#endif
-#define _SDT_ASM_STRING(x) _SDT_ASM_STRING_1(x)
-
-#define _SDT_ARGARRAY(x) (__builtin_classify_type (x) == 14 \
- || __builtin_classify_type (x) == 5)
-
-#ifdef __cplusplus
-# define _SDT_ARGSIGNED(x) (!_SDT_ARGARRAY (x) \
- && __sdt_type<__typeof (x)>::__sdt_signed)
-# define _SDT_ARGSIZE(x) (_SDT_ARGARRAY (x) \
- ? sizeof (void *) : sizeof (x))
-# define _SDT_ARGVAL(x) (x)
-
-# include <cstddef>
-
-template<typename __sdt_T>
-struct __sdt_type
-{
- static const bool __sdt_signed = false;
-};
-
-#define __SDT_ALWAYS_SIGNED(T) \
-template<> struct __sdt_type<T> { static const bool __sdt_signed = true; };
-#define __SDT_COND_SIGNED(T,CT) \
-template<> struct __sdt_type<T> { static const bool __sdt_signed = ((CT)(-1) < 1); };
-__SDT_ALWAYS_SIGNED(signed char)
-__SDT_ALWAYS_SIGNED(short)
-__SDT_ALWAYS_SIGNED(int)
-__SDT_ALWAYS_SIGNED(long)
-__SDT_ALWAYS_SIGNED(long long)
-__SDT_ALWAYS_SIGNED(volatile signed char)
-__SDT_ALWAYS_SIGNED(volatile short)
-__SDT_ALWAYS_SIGNED(volatile int)
-__SDT_ALWAYS_SIGNED(volatile long)
-__SDT_ALWAYS_SIGNED(volatile long long)
-__SDT_ALWAYS_SIGNED(const signed char)
-__SDT_ALWAYS_SIGNED(const short)
-__SDT_ALWAYS_SIGNED(const int)
-__SDT_ALWAYS_SIGNED(const long)
-__SDT_ALWAYS_SIGNED(const long long)
-__SDT_ALWAYS_SIGNED(const volatile signed char)
-__SDT_ALWAYS_SIGNED(const volatile short)
-__SDT_ALWAYS_SIGNED(const volatile int)
-__SDT_ALWAYS_SIGNED(const volatile long)
-__SDT_ALWAYS_SIGNED(const volatile long long)
-__SDT_COND_SIGNED(char, char)
-__SDT_COND_SIGNED(wchar_t, wchar_t)
-__SDT_COND_SIGNED(volatile char, char)
-__SDT_COND_SIGNED(volatile wchar_t, wchar_t)
-__SDT_COND_SIGNED(const char, char)
-__SDT_COND_SIGNED(const wchar_t, wchar_t)
-__SDT_COND_SIGNED(const volatile char, char)
-__SDT_COND_SIGNED(const volatile wchar_t, wchar_t)
-#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
-/* __SDT_COND_SIGNED(char16_t) */
-/* __SDT_COND_SIGNED(char32_t) */
-#endif
-
-template<typename __sdt_E>
-struct __sdt_type<__sdt_E[]> : public __sdt_type<__sdt_E *> {};
-
-template<typename __sdt_E, size_t __sdt_N>
-struct __sdt_type<__sdt_E[__sdt_N]> : public __sdt_type<__sdt_E *> {};
-
-#elif !defined(__ASSEMBLER__)
-__extension__ extern unsigned long long __sdt_unsp;
-# define _SDT_ARGINTTYPE(x) \
- __typeof (__builtin_choose_expr (((__builtin_classify_type (x) \
- + 3) & -4) == 4, (x), 0U))
-# define _SDT_ARGSIGNED(x) \
- (!__extension__ \
- (__builtin_constant_p ((((unsigned long long) \
- (_SDT_ARGINTTYPE (x)) __sdt_unsp) \
- & ((unsigned long long)1 << (sizeof (unsigned long long) \
- * __CHAR_BIT__ - 1))) == 0) \
- || (_SDT_ARGINTTYPE (x)) -1 > (_SDT_ARGINTTYPE (x)) 0))
-# define _SDT_ARGSIZE(x) \
- (_SDT_ARGARRAY (x) ? sizeof (void *) : sizeof (x))
-# define _SDT_ARGVAL(x) (x)
-#endif
-
-#if defined __powerpc__ || defined __powerpc64__
-# define _SDT_ARGTMPL(id) %I[id]%[id]
-#elif defined __i386__
-# define _SDT_ARGTMPL(id) %w[id] /* gcc.gnu.org/PR80115 */
-#else
-# define _SDT_ARGTMPL(id) %[id]
-#endif
-
-#ifdef __LP64__
-# define _SDT_ASM_ADDR .8byte
-#else
-# define _SDT_ASM_ADDR .4byte
-#endif
-
-/* The ia64 and s390 nop instructions take an argument. */
-#if defined(__ia64__) || defined(__s390__) || defined(__s390x__)
-#define _SDT_NOP nop 0
-#else
-#define _SDT_NOP nop
-#endif
-
-#define _SDT_NOTE_NAME "stapsdt"
-#define _SDT_NOTE_TYPE 3
-
-/* If the assembler supports the necessary feature, then we can play
- nice with code in COMDAT sections, which comes up in C++ code.
- Without that assembler support, some combinations of probe placements
- in certain kinds of C++ code may produce link-time errors. */
-#include "sdt-config.h"
-#if _SDT_ASM_SECTION_AUTOGROUP_SUPPORT
-# define _SDT_ASM_AUTOGROUP "?"
-#else
-# define _SDT_ASM_AUTOGROUP ""
-#endif
-
-#define _SDT_ASM_BODY(provider, name, pack_args, args) \
- _SDT_ASM_1(990: _SDT_NOP) \
- _SDT_ASM_3( .pushsection .note.stapsdt,_SDT_ASM_AUTOGROUP,"note") \
- _SDT_ASM_1( .balign 4) \
- _SDT_ASM_3( .4byte 992f-991f, 994f-993f, _SDT_NOTE_TYPE) \
- _SDT_ASM_1(991: .asciz _SDT_NOTE_NAME) \
- _SDT_ASM_1(992: .balign 4) \
- _SDT_ASM_1(993: _SDT_ASM_ADDR 990b) \
- _SDT_ASM_1( _SDT_ASM_ADDR _.stapsdt.base) \
- _SDT_SEMAPHORE(provider,name) \
- _SDT_ASM_STRING(provider) \
- _SDT_ASM_STRING(name) \
- pack_args args \
- _SDT_ASM_1(994: .balign 4) \
- _SDT_ASM_1( .popsection)
-
-#define _SDT_ASM_BASE \
- _SDT_ASM_1(.ifndef _.stapsdt.base) \
- _SDT_ASM_5( .pushsection .stapsdt.base,"aG","progbits", \
- .stapsdt.base,comdat) \
- _SDT_ASM_1( .weak _.stapsdt.base) \
- _SDT_ASM_1( .hidden _.stapsdt.base) \
- _SDT_ASM_1( _.stapsdt.base: .space 1) \
- _SDT_ASM_2( .size _.stapsdt.base, 1) \
- _SDT_ASM_1( .popsection) \
- _SDT_ASM_1(.endif)
-
-#if defined _SDT_HAS_SEMAPHORES
-#define _SDT_SEMAPHORE(p,n) _SDT_ASM_1( _SDT_ASM_ADDR p##_##n##_semaphore)
-#else
-#define _SDT_SEMAPHORE(p,n) _SDT_ASM_1( _SDT_ASM_ADDR 0)
-#endif
-
-#define _SDT_ASM_TEMPLATE_0 /* no arguments */
-#define _SDT_ASM_TEMPLATE_1 _SDT_ARGFMT(1)
-#define _SDT_ASM_TEMPLATE_2 _SDT_ASM_TEMPLATE_1 _SDT_ARGFMT(2)
-#define _SDT_ASM_TEMPLATE_3 _SDT_ASM_TEMPLATE_2 _SDT_ARGFMT(3)
-#define _SDT_ASM_TEMPLATE_4 _SDT_ASM_TEMPLATE_3 _SDT_ARGFMT(4)
-#define _SDT_ASM_TEMPLATE_5 _SDT_ASM_TEMPLATE_4 _SDT_ARGFMT(5)
-#define _SDT_ASM_TEMPLATE_6 _SDT_ASM_TEMPLATE_5 _SDT_ARGFMT(6)
-#define _SDT_ASM_TEMPLATE_7 _SDT_ASM_TEMPLATE_6 _SDT_ARGFMT(7)
-#define _SDT_ASM_TEMPLATE_8 _SDT_ASM_TEMPLATE_7 _SDT_ARGFMT(8)
-#define _SDT_ASM_TEMPLATE_9 _SDT_ASM_TEMPLATE_8 _SDT_ARGFMT(9)
-#define _SDT_ASM_TEMPLATE_10 _SDT_ASM_TEMPLATE_9 _SDT_ARGFMT(10)
-#define _SDT_ASM_TEMPLATE_11 _SDT_ASM_TEMPLATE_10 _SDT_ARGFMT(11)
-#define _SDT_ASM_TEMPLATE_12 _SDT_ASM_TEMPLATE_11 _SDT_ARGFMT(12)
-#define _SDT_ASM_OPERANDS_0() [__sdt_dummy] "g" (0)
-#define _SDT_ASM_OPERANDS_1(arg1) _SDT_ARG(1, arg1)
-#define _SDT_ASM_OPERANDS_2(arg1, arg2) \
- _SDT_ASM_OPERANDS_1(arg1), _SDT_ARG(2, arg2)
-#define _SDT_ASM_OPERANDS_3(arg1, arg2, arg3) \
- _SDT_ASM_OPERANDS_2(arg1, arg2), _SDT_ARG(3, arg3)
-#define _SDT_ASM_OPERANDS_4(arg1, arg2, arg3, arg4) \
- _SDT_ASM_OPERANDS_3(arg1, arg2, arg3), _SDT_ARG(4, arg4)
-#define _SDT_ASM_OPERANDS_5(arg1, arg2, arg3, arg4, arg5) \
- _SDT_ASM_OPERANDS_4(arg1, arg2, arg3, arg4), _SDT_ARG(5, arg5)
-#define _SDT_ASM_OPERANDS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
- _SDT_ASM_OPERANDS_5(arg1, arg2, arg3, arg4, arg5), _SDT_ARG(6, arg6)
-#define _SDT_ASM_OPERANDS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
- _SDT_ASM_OPERANDS_6(arg1, arg2, arg3, arg4, arg5, arg6), _SDT_ARG(7, arg7)
-#define _SDT_ASM_OPERANDS_8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
- _SDT_ASM_OPERANDS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7), \
- _SDT_ARG(8, arg8)
-#define _SDT_ASM_OPERANDS_9(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) \
- _SDT_ASM_OPERANDS_8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), \
- _SDT_ARG(9, arg9)
-#define _SDT_ASM_OPERANDS_10(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) \
- _SDT_ASM_OPERANDS_9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), \
- _SDT_ARG(10, arg10)
-#define _SDT_ASM_OPERANDS_11(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11) \
- _SDT_ASM_OPERANDS_10(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), \
- _SDT_ARG(11, arg11)
-#define _SDT_ASM_OPERANDS_12(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12) \
- _SDT_ASM_OPERANDS_11(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11), \
- _SDT_ARG(12, arg12)
-
-/* These macros can be used in C, C++, or assembly code.
- In assembly code the arguments should use normal assembly operand syntax. */
-
-#define STAP_PROBE(provider, name) \
- _SDT_PROBE(provider, name, 0, ())
-#define STAP_PROBE1(provider, name, arg1) \
- _SDT_PROBE(provider, name, 1, (arg1))
-#define STAP_PROBE2(provider, name, arg1, arg2) \
- _SDT_PROBE(provider, name, 2, (arg1, arg2))
-#define STAP_PROBE3(provider, name, arg1, arg2, arg3) \
- _SDT_PROBE(provider, name, 3, (arg1, arg2, arg3))
-#define STAP_PROBE4(provider, name, arg1, arg2, arg3, arg4) \
- _SDT_PROBE(provider, name, 4, (arg1, arg2, arg3, arg4))
-#define STAP_PROBE5(provider, name, arg1, arg2, arg3, arg4, arg5) \
- _SDT_PROBE(provider, name, 5, (arg1, arg2, arg3, arg4, arg5))
-#define STAP_PROBE6(provider, name, arg1, arg2, arg3, arg4, arg5, arg6) \
- _SDT_PROBE(provider, name, 6, (arg1, arg2, arg3, arg4, arg5, arg6))
-#define STAP_PROBE7(provider, name, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
- _SDT_PROBE(provider, name, 7, (arg1, arg2, arg3, arg4, arg5, arg6, arg7))
-#define STAP_PROBE8(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \
- _SDT_PROBE(provider, name, 8, (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8))
-#define STAP_PROBE9(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)\
- _SDT_PROBE(provider, name, 9, (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9))
-#define STAP_PROBE10(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) \
- _SDT_PROBE(provider, name, 10, \
- (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10))
-#define STAP_PROBE11(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11) \
- _SDT_PROBE(provider, name, 11, \
- (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11))
-#define STAP_PROBE12(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12) \
- _SDT_PROBE(provider, name, 12, \
- (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12))
-
-/* This STAP_PROBEV macro can be used in variadic scenarios, where the
- number of probe arguments is not known until compile time. Since
- variadic macro support may vary with compiler options, you must
- pre-#define SDT_USE_VARIADIC to enable this type of probe.
-
- The trick to count __VA_ARGS__ was inspired by this post by
- Laurent Deniau <laurent.deniau@cern.ch>:
- http://groups.google.com/group/comp.std.c/msg/346fc464319b1ee5
-
- Note that our _SDT_NARG is called with an extra 0 arg that's not
- counted, so we don't have to worry about the behavior of macros
- called without any arguments. */
-
-#ifdef SDT_USE_VARIADIC
-#define _SDT_NARG(...) __SDT_NARG(__VA_ARGS__, 12,11,10,9,8,7,6,5,4,3,2,1,0)
-#define __SDT_NARG(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, N, ...) N
-#define _SDT_PROBE_N(provider, name, N, ...) \
- _SDT_PROBE(provider, name, N, (__VA_ARGS__))
-#define STAP_PROBEV(provider, name, ...) \
- _SDT_PROBE_N(provider, name, _SDT_NARG(0, ##__VA_ARGS__), ##__VA_ARGS__)
-#endif
-
-/* These macros are for use in asm statements. You must compile
- with -std=gnu99 or -std=c99 to use the STAP_PROBE_ASM macro.
-
- The STAP_PROBE_ASM macro generates a quoted string to be used in the
- template portion of the asm statement, concatenated with strings that
- contain the actual assembly code around the probe site.
-
- For example:
-
- asm ("before\n"
- STAP_PROBE_ASM(provider, fooprobe, %eax 4(%esi))
- "after");
-
- emits the assembly code for "before\nafter", with a probe in between.
- The probe arguments are the %eax register, and the value of the memory
- word located 4 bytes past the address in the %esi register. Note that
- because this is a simple asm, not a GNU C extended asm statement, these
- % characters do not need to be doubled to generate literal %reg names.
-
- In a GNU C extended asm statement, the probe arguments can be specified
- using the macro STAP_PROBE_ASM_TEMPLATE(n) for n arguments. The paired
- macro STAP_PROBE_ASM_OPERANDS gives the C values of these probe arguments,
- and appears in the input operand list of the asm statement. For example:
-
- asm ("someinsn %0,%1\n" // %0 is output operand, %1 is input operand
- STAP_PROBE_ASM(provider, fooprobe, STAP_PROBE_ASM_TEMPLATE(3))
- "otherinsn %[namedarg]"
- : "r" (outvar)
- : "g" (some_value), [namedarg] "i" (1234),
- STAP_PROBE_ASM_OPERANDS(3, some_value, some_ptr->field, 1234));
-
- This is just like writing:
-
- STAP_PROBE3(provider, fooprobe, some_value, some_ptr->field, 1234));
-
- but the probe site is right between "someinsn" and "otherinsn".
-
- The probe arguments in STAP_PROBE_ASM can be given as assembly
- operands instead, even inside a GNU C extended asm statement.
- Note that these can use operand templates like %0 or %[name],
- and likewise they must write %%reg for a literal operand of %reg. */
-
-#if __STDC_VERSION__ >= 199901L
-# define STAP_PROBE_ASM(provider, name, ...) \
- _SDT_ASM_BODY(provider, name, _SDT_ASM_STRING, (__VA_ARGS__)) \
- _SDT_ASM_BASE
-# define STAP_PROBE_ASM_OPERANDS(n, ...) _SDT_ASM_OPERANDS_##n(__VA_ARGS__)
-#else
-# define STAP_PROBE_ASM(provider, name, args) \
- _SDT_ASM_BODY(provider, name, _SDT_ASM_STRING, (args)) \
- _SDT_ASM_BASE
-#endif
-#define STAP_PROBE_ASM_TEMPLATE(n) _SDT_ASM_TEMPLATE_##n
-
-
-/* DTrace compatible macro names. */
-#define DTRACE_PROBE(provider,probe) \
- STAP_PROBE(provider,probe)
-#define DTRACE_PROBE1(provider,probe,parm1) \
- STAP_PROBE1(provider,probe,parm1)
-#define DTRACE_PROBE2(provider,probe,parm1,parm2) \
- STAP_PROBE2(provider,probe,parm1,parm2)
-#define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \
- STAP_PROBE3(provider,probe,parm1,parm2,parm3)
-#define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \
- STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4)
-#define DTRACE_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \
- STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5)
-#define DTRACE_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \
- STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6)
-#define DTRACE_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \
- STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7)
-#define DTRACE_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \
- STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8)
-#define DTRACE_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \
- STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9)
-#define DTRACE_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \
- STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10)
-#define DTRACE_PROBE11(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11) \
- STAP_PROBE11(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11)
-#define DTRACE_PROBE12(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11,parm12) \
- STAP_PROBE12(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11,parm12)
-
-
-#endif /* sys/sdt.h */
diff --git a/v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch b/v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch
deleted file mode 100644
index 82431bea85a3..000000000000
--- a/v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch
+++ /dev/null
@@ -1,1974 +0,0 @@
-diff --git a/elf/Makefile b/elf/Makefile
-index bf45d8ee24..bdcf4cb885 100644
---- a/elf/Makefile
-+++ b/elf/Makefile
-@@ -477,6 +477,21 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \
- $(objpfx)tst-unused-dep-cmp.out
- endif
-
-+# DSO sorting tests:
-+# The dso-ordering-test.py script generates testcase source files in $(objpfx),
-+# creating a $(objpfx)<testcase-name>-dir for each testcase, and creates a
-+# Makefile fragment to be included.
-+define include_dsosort_tests
-+$(objpfx)$(1).generated-makefile: $(1)
-+ $(PYTHON) $(..)scripts/dso-ordering-test.py \
-+ --description-file $$< --objpfx $(objpfx) --output-makefile $$@
-+include $(objpfx)$(1).generated-makefile
-+endef
-+
-+# Generate from each testcase description file
-+$(eval $(call include_dsosort_tests,dso-sort-tests-1.def))
-+$(eval $(call include_dsosort_tests,dso-sort-tests-2.def))
-+
- check-abi: $(objpfx)check-abi-ld.out
- tests-special += $(objpfx)check-abi-ld.out
- update-abi: update-abi-ld
-diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
-new file mode 100644
-index 0000000000..873ddf55d9
---- /dev/null
-+++ b/elf/dso-sort-tests-1.def
-@@ -0,0 +1,66 @@
-+# DSO sorting test descriptions.
-+# This file is to be processed by ../scripts/dso-ordering-test.py, see usage
-+# in elf/Makefile for how it is executed.
-+
-+# We test both dynamic loader sorting algorithms
-+tunable_option: glibc.rtld.dynamic_sort=1
-+tunable_option: glibc.rtld.dynamic_sort=2
-+
-+# Sequence of single dependencies with no cycles.
-+tst-dso-ordering1: a->b->c
-+output: c>b>a>{}<a<b<c
-+
-+# Sequence including 2 dependent DSOs not at the end of the graph.
-+tst-dso-ordering2: a->b->[cd]->e
-+output: e>d>c>b>a>{}<a<b<c<d<e
-+
-+# Complex order with 3 "layers" of full dependencies
-+tst-dso-ordering3: a->[bc]->[def]->[gh]->i
-+output: i>h>g>f>e>d>c>b>a>{}<a<b<c<d<e<f<g<h<i
-+
-+# Sequence including 2 dependent DSOs at the end of the graph.
-+# Additionally the same dependencies appear in two paths.
-+tst-dso-ordering4: a->b->[de];a->c->d->e
-+output: e>d>c>b>a>{}<a<b<c<d<e
-+
-+# Test that b->c cross link is respected correctly
-+tst-dso-ordering5: a!->[bc]->d;b->c
-+output: d>c>b>a>{}<a<b<c<d
-+
-+# First DSO fully dependent on 4 DSOs, with another DSO at the end of chain.
-+tst-dso-ordering6: a->[bcde]->f
-+output: f>e>d>c>b>a>{}<a<b<c<d<e<f
-+
-+# Sequence including 2 dependent and 3 dependent DSOs, and one of the
-+# dependent DSOs is dependent on an earlier DSO.
-+tst-dso-ordering7: a->[bc];b->[cde];e->f
-+output: f>e>d>c>b>a>{}<a<b<c<d<e<f
-+
-+# Sequence where the DSO c is unerlinked and calls a function in DSO a which
-+# is technically a cycle. The main executable depends on the first two DSOs.
-+# Note: This test has unspecified behavior.
-+tst-dso-ordering8: a->b->c=>a;{}->[ba]
-+output: c>b>a>{}<a<b<c
-+
-+# Generate the permutation of DT_NEEDED order between the main binary and
-+# all 5 DSOs; all link orders should produce exact same init/fini ordering
-+tst-dso-ordering9: a->b->c->d->e;{}!->[abcde]
-+output: e>d>c>b>a>{}<a<b<c<d<e
-+
-+# Test if init/fini ordering behavior is proper, despite main program with
-+# an soname that may cause confusion
-+tst-dso-ordering10: {}->a->b->c;soname({})=c
-+output: b>a>{}<a<b
-+
-+# Complex example from Bugzilla #15311, under-linked and with circular
-+# relocation(dynamic) dependencies. While this is technically unspecified, the
-+# presumed reasonable practical behavior is for the destructor order to respect
-+# the static DT_NEEDED links (here this means the a->b->c->d order).
-+# The older dynamic_sort=1 algorithm does not achieve this, while the DFS-based
-+# dynamic_sort=2 algorithm does, although it is still arguable whether going
-+# beyond spec to do this is the right thing to do.
-+# The below expected outputs are what the two algorithms currently produce
-+# respectively, for regression testing purposes.
-+tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
-+xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
-+output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
-diff --git a/elf/dso-sort-tests-2.def b/elf/dso-sort-tests-2.def
-new file mode 100644
-index 0000000000..b79e79ecb7
---- /dev/null
-+++ b/elf/dso-sort-tests-2.def
-@@ -0,0 +1,614 @@
-+# Large DSO sorting testcase adapted from Red Hat Bugzilla 1162810
-+#
-+# Note that below we specify different expected outputs between dynamic_sort=1
-+# and dynamic_sort=2 algorithms, due to circular dependencies in the testcase
-+# causing different sorting behavior. These expected outputs are what the two
-+# algorithms currently produce, and are used for regression comparison tests.
-+# They are not "definitively" correct outputs, for circular dependencies
-+# inherently have unspecified behavior.
-+
-+xtest(tst-redhat-1162810):
-+{}->A101
-+{}->*
-+A101->(B101 B163 B122 B181)
-+A102->(B102 B140 B199 B158)
-+A103->(B103 B117 B176 B135)
-+A104->(B104 B194 B153 B112)
-+A105->(B105 B171 B130 B189)
-+A106->(B106 B148 B107 B166)
-+A107->(B107 B125 B184 B143)
-+A108->(B108 B102 B161 B120)
-+A109->(B109 B179 B138 B197)
-+A110->(B110 B156 B115 B174)
-+A111->(B111 B133 B192 B151)
-+A112->(B112 B110 B169 B128)
-+A113->(B113 B187 B146 B105)
-+A114->(B114 B164 B123 B182)
-+A115->(B115 B141 B200 B159)
-+A116->(B116 B118 B177 B136)
-+A117->(B117 B195 B154 B113)
-+A118->(B118 B172 B131 B190)
-+A119->(B119 B149 B108 B167)
-+A120->(B120 B126 B185 B144)
-+A121->(B121 B103 B162)
-+A122->(B122 B180 B139 B198)
-+A123->(B123 B157 B116 B175)
-+A124->(B124 B134 B193 B152)
-+A125->(B125 B111 B170 B129)
-+A126->(B126 B188 B147 B106)
-+A127->(B127 B165 B124 B183)
-+A128->(B128 B142 B101 B160)
-+A129->(B129 B119 B178 B137)
-+A130->(B130 B196 B155 B114)
-+A131->(B131 B173 B132 B191)
-+A132->(B132 B150 B109 B168)
-+A133->(B133 B127 B186 B145)
-+A134->(B134 B104 B163 B122)
-+A135->(B135 B181 B140 B199)
-+A136->(B136 B158 B117 B176)
-+A137->(B137 B135 B194 B153)
-+A138->(B138 B112 B171 B130)
-+A139->(B139 B189 B148 B107)
-+A140->(B140 B166 B125 B184)
-+A141->(B141 B143 B102 B161)
-+A142->(B142 B120 B179 B138)
-+A143->(B143 B197 B156 B115)
-+A144->(B144 B174 B133 B192)
-+A145->(B145 B151 B110 B169)
-+A146->(B146 B128 B187)
-+A147->(B147 B105 B164 B123)
-+A148->(B148 B182 B141 B200)
-+A149->(B149 B159 B118 B177)
-+A150->(B150 B136 B195 B154)
-+A151->(B151 B113 B172 B131)
-+A152->(B152 B190 B149 B108)
-+A153->(B153 B167 B126 B185)
-+A154->(B154 B144 B103 B162)
-+A155->(B155 B121 B180 B139)
-+A156->(B156 B198 B157 B116)
-+A157->(B157 B175 B134 B193)
-+A158->(B158 B152 B111 B170)
-+A159->(B159 B129 B188 B147)
-+A160->(B160 B106 B165 B124)
-+A161->(B161 B183 B142 B101)
-+A162->(B162 B160 B119 B178)
-+A163->(B163 B137 B196 B155)
-+A164->(B164 B114 B173 B132)
-+A165->(B165 B191 B150 B109)
-+A166->(B166 B168 B127 B186)
-+A167->(B167 B145 B104 B163)
-+A168->(B168 B122 B181 B140)
-+A169->(B169 B199 B158 B117)
-+A170->(B170 B176 B135 B194)
-+A171->(B171 B153 B112)
-+A172->(B172 B130 B189 B148)
-+A173->(B173 B107 B166 B125)
-+A174->(B174 B184 B143 B102)
-+A175->(B175 B161 B120 B179)
-+A176->(B176 B138 B197 B156)
-+A177->(B177 B115 B174 B133)
-+A178->(B178 B192 B151 B110)
-+A179->(B179 B169 B128 B187)
-+A180->(B180 B146 B105 B164)
-+A181->(B181 B123 B182 B141)
-+A182->(B182 B200 B159 B118)
-+A183->(B183 B177 B136 B195)
-+A184->(B184 B154 B113 B172)
-+A185->(B185 B131 B190 B149)
-+A186->(B186 B108 B167 B126)
-+A187->(B187 B185 B144 B103)
-+A188->(B188 B162 B121 B180)
-+A189->(B189 B139 B198 B157)
-+A190->(B190 B116 B175 B134)
-+A191->(B191 B193 B152 B111)
-+A192->(B192 B170 B129 B188)
-+A193->(B193 B147 B106 B165)
-+A194->(B194 B124 B183 B142)
-+A195->(B195 B101 B160 B119)
-+A196->(B196 B178 B137)
-+A197->(B197 B155 B114 B173)
-+A198->(B198 B132 B191 B150)
-+A199->(B199 B109 B168 B127)
-+A200->(B200 B186 B145 B104)
-+B101->(C101 C164 C123 C182)
-+B102->(C102 C141 C200 C159)
-+B103->(C103 C118 C177 C136)
-+B104->(C104 C195 C154 C113)
-+B105->(C105 C172 C131 C190)
-+B106->(C106 C149 C108 C167)
-+B107->(C107 C126 C185 C144)
-+B108->(C108 C103 C162 C121)
-+B109->(C109 C180 C139 C198)
-+B110->(C110 C157 C116 C175)
-+B111->(C111 C134 C193 C152)
-+B112->(C112 C111 C170 C129)
-+B113->(C113 C188 C147 C106)
-+B114->(C114 C165 C124 C183)
-+B115->(C115 C142 C101 C160)
-+B116->(C116 C119 C178 C137)
-+B117->(C117 C196 C155 C114)
-+B118->(C118 C173 C132 C191)
-+B119->(C119 C150 C109 C168)
-+B120->(C120 C127 C186 C145)
-+B121->(C121 C104 C163 C122)
-+B122->(C122 C181 C140 C199)
-+B123->(C123 C158 C117 C176)
-+B124->(C124 C135 C194 C153)
-+B125->(C125 C112 C171 C130)
-+B126->(C126 C189 C148 C107)
-+B127->(C127 C166 C125 C184)
-+B128->(C128 C143 C102 C161)
-+B129->(C129 C120 C179 C138)
-+B130->(C130 C197 C156 C115)
-+B131->(C131 C174 C133 C192)
-+B132->(C132 C151 C110 C169)
-+B133->(C133 C128 C187 C146)
-+B134->(C134 C105 C164 C123)
-+B135->(C135 C182 C141 C200)
-+B136->(C136 C159 C118 C177)
-+B137->(C137 C136 C195 C154)
-+B138->(C138 C113 C172 C131)
-+B139->(C139 C190 C149 C108)
-+B140->(C140 C167 C126 C185)
-+B141->(C141 C144 C103 C162)
-+B142->(C142 C121 C180 C139)
-+B143->(C143 C198 C157 C116)
-+B144->(C144 C175 C134 C193)
-+B145->(C145 C152 C111 C170)
-+B146->(C146 C129 C188 C147)
-+B147->(C147 C106 C165 C124)
-+B148->(C148 C183 C142 C101)
-+B149->(C149 C160 C119 C178)
-+B150->(C150 C137 C196 C155)
-+B151->(C151 C114 C173 C132)
-+B152->(C152 C191 C150 C109)
-+B153->(C153 C168 C127 C186)
-+B154->(C154 C145 C104 C163)
-+B155->(C155 C122 C181 C140)
-+B156->(C156 C199 C158 C117)
-+B157->(C157 C176 C135 C194)
-+B158->(C158 C153 C112 C171)
-+B159->(C159 C130 C189 C148)
-+B160->(C160 C107 C166 C125)
-+B161->(C161 C184 C143 C102)
-+B162->(C162 C161 C120 C179)
-+B163->(C163 C138 C197 C156)
-+B164->(C164 C115 C174 C133)
-+B165->(C165 C192 C151 C110)
-+B166->(C166 C169 C128 C187)
-+B167->(C167 C146 C105 C164)
-+B168->(C168 C123 C182 C141)
-+B169->(C169 C200 C159 C118)
-+B170->(C170 C177 C136 C195)
-+B171->(C171 C154 C113 C172)
-+B172->(C172 C131 C190 C149)
-+B173->(C173 C108 C167 C126)
-+B174->(C174 C185 C144 C103)
-+B175->(C175 C162 C121 C180)
-+B176->(C176 C139 C198 C157)
-+B177->(C177 C116 C175 C134)
-+B178->(C178 C193 C152 C111)
-+B179->(C179 C170 C129 C188)
-+B180->(C180 C147 C106 C165)
-+B181->(C181 C124 C183 C142)
-+B182->(C182 C101 C160 C119)
-+B183->(C183 C178 C137 C196)
-+B184->(C184 C155 C114 C173)
-+B185->(C185 C132 C191 C150)
-+B186->(C186 C109 C168 C127)
-+B187->(C187 C186 C145 C104)
-+B188->(C188 C163 C122 C181)
-+B189->(C189 C140 C199 C158)
-+B190->(C190 C117 C176 C135)
-+B191->(C191 C194 C153 C112)
-+B192->(C192 C171 C130 C189)
-+B193->(C193 C148 C107 C166)
-+B194->(C194 C125 C184 C143)
-+B195->(C195 C102 C161 C120)
-+B196->(C196 C179 C138 C197)
-+B197->(C197 C156 C115 C174)
-+B198->(C198 C133 C192 C151)
-+B199->(C199 C110 C169 C128)
-+B200->(C200 C187 C146 C105)
-+C101->(A165 A124)
-+C102->(A183 A142)
-+C103->(A101 A160)
-+C104->(A119 A178)
-+C105->(A137 A196)
-+C106->(A155 A114)
-+C107->(A173 A132)
-+C108->(A191 A150)
-+C109->(A109 A168)
-+C110->(A127 A186)
-+C111->(A145 A104)
-+C112->(A163 A122)
-+C113->(A181 A140)
-+C114->(A199 A158)
-+C115->(A117 A176)
-+C116->(A135 A194)
-+C117->(A153 A112)
-+C118->(A171 A130)
-+C119->(A189 A148)
-+C120->(A107 A166)
-+C121->(A125 A184)
-+C122->(A143 A102)
-+C123->(A161 A120)
-+C124->(A179 A138)
-+C125->(A197 A156)
-+C126->(A115 A174)
-+C127->(A133 A192)
-+C128->(A151 A110)
-+C129->(A169 A128)
-+C130->(A187 A146)
-+C131->(A105 A164)
-+C132->(A123 A182)
-+C133->(A141 A200)
-+C134->(A159 A118)
-+C135->(A177 A136)
-+C136->(A195 A154)
-+C137->(A113 A172)
-+C138->(A131 A190)
-+C139->(A149 A108)
-+C140->(A167 A126)
-+C141->(A185 A144)
-+C142->(A103 A162)
-+C143->(A121 A180)
-+C144->(A139 A198)
-+C145->(A157 A116)
-+C146->(A175 A134)
-+C147->(A193 A152)
-+C148->(A111 A170)
-+C149->(A129 A188)
-+C150->(A147 A106)
-+C151->(A165 A124)
-+C152->(A183 A142)
-+C153->(A101 A160)
-+C154->(A119 A178)
-+C155->(A137 A196)
-+C156->(A155 A114)
-+C157->(A173 A132)
-+C158->(A191 A150)
-+C159->(A109 A168)
-+C160->(A127 A186)
-+C161->(A145 A104)
-+C162->(A163 A122)
-+C163->(A181 A140)
-+C164->(A199 A158)
-+C165->(A117 A176)
-+C166->(A135 A194)
-+C167->(A153 A112)
-+C168->(A171 A130)
-+C169->(A189 A148)
-+C170->(A107 A166)
-+C171->(A125 A184)
-+C172->(A143 A102)
-+C173->(A161 A120)
-+C174->(A179 A138)
-+C175->(A197 A156)
-+C176->(A115 A174)
-+C177->(A133 A192)
-+C178->(A151 A110)
-+C179->(A169 A128)
-+C180->(A187 A146)
-+C181->(A105 A164)
-+C182->(A123 A182)
-+C183->(A141 A200)
-+C184->(A159 A118)
-+C185->(A177 A136)
-+C186->(A195 A154)
-+C187->(A113 A172)
-+C188->(A131 A190)
-+C189->(A149 A108)
-+C190->(A167 A126)
-+C191->(A185 A144)
-+C192->(A103 A162)
-+C193->(A121 A180)
-+C194->(A139 A198)
-+C195->(A157 A116)
-+C196->(A175 A134)
-+C197->(A193 A152)
-+C198->(A111 A170)
-+C199->(A129 A188)
-+C200->(A147 A106)
-+M11X11->(M13X14 M12X13 M12X12 M12X11)
-+M11X12->(M13X25 M12X24 M12X23 M12X22)
-+M11X13->(M13X21 M12X20 M12X19 M12X18)
-+M11X14->(M13X17 M12X16 M12X15 M12X14)
-+M11X15->(M13X13 M12X12 M12X11 M12X25)
-+M11X16->(M13X24 M12X23 M12X22 M12X21)
-+M11X17->(M13X20 M12X19 M12X18 M12X17)
-+M11X18->(M13X16 M12X15 M12X14 M12X13)
-+M11X19->(M13X12 M12X11 M12X25 M12X24)
-+M11X20->(M13X23 M12X22 M12X21 M12X20)
-+M11X21->(M13X19 M12X18 M12X17 M12X16)
-+M11X22->(M13X15 M12X14 M12X13 M12X12)
-+M11X23->(M13X11 M12X25 M12X24 M12X23)
-+M11X24->(M13X22 M12X21 M12X20 M12X19)
-+M11X25->(M13X18 M12X17 M12X16 M12X15)
-+M12X11->(M14X14 M13X13 M13X12 M13X11)
-+M12X12->(M14X25 M13X24 M13X23 M13X22)
-+M12X13->(M14X21 M13X20 M13X19 M13X18)
-+M12X14->(M14X17 M13X16 M13X15 M13X14)
-+M12X15->(M14X13 M13X12 M13X11 M13X25)
-+M12X16->(M14X24 M13X23 M13X22 M13X21)
-+M12X17->(M14X20 M13X19 M13X18 M13X17)
-+M12X18->(M14X16 M13X15 M13X14 M13X13)
-+M12X19->(M14X12 M13X11 M13X25 M13X24)
-+M12X20->(M14X23 M13X22 M13X21 M13X20)
-+M12X21->(M14X19 M13X18 M13X17 M13X16)
-+M12X22->(M14X15 M13X14 M13X13 M13X12)
-+M12X23->(M14X11 M13X25 M13X24 M13X23)
-+M12X24->(M14X22 M13X21 M13X20 M13X19)
-+M12X25->(M14X18 M13X17 M13X16 M13X15)
-+M13X11->(M15X14 M14X13 M14X12 M14X11)
-+M13X12->(M15X25 M14X24 M14X23 M14X22)
-+M13X13->(M15X21 M14X20 M14X19 M14X18)
-+M13X14->(M15X17 M14X16 M14X15 M14X14)
-+M13X15->(M15X13 M14X12 M14X11 M14X25)
-+M13X16->(M15X24 M14X23 M14X22 M14X21)
-+M13X17->(M15X20 M14X19 M14X18 M14X17)
-+M13X18->(M15X16 M14X15 M14X14 M14X13)
-+M13X19->(M15X12 M14X11 M14X25 M14X24)
-+M13X20->(M15X23 M14X22 M14X21 M14X20)
-+M13X21->(M15X19 M14X18 M14X17 M14X16)
-+M13X22->(M15X15 M14X14 M14X13 M14X12)
-+M13X23->(M15X11 M14X25 M14X24 M14X23)
-+M13X24->(M15X22 M14X21 M14X20 M14X19)
-+M13X25->(M15X18 M14X17 M14X16 M14X15)
-+M14X11->(M16X14 M15X13 M15X12 M15X11)
-+M14X12->(M16X25 M15X24 M15X23 M15X22)
-+M14X13->(M16X21 M15X20 M15X19 M15X18)
-+M14X14->(M16X17 M15X16 M15X15 M15X14)
-+M14X15->(M16X13 M15X12 M15X11 M15X25)
-+M14X16->(M16X24 M15X23 M15X22 M15X21)
-+M14X17->(M16X20 M15X19 M15X18 M15X17)
-+M14X18->(M16X16 M15X15 M15X14 M15X13)
-+M14X19->(M16X12 M15X11 M15X25 M15X24)
-+M14X20->(M16X23 M15X22 M15X21 M15X20)
-+M14X21->(M16X19 M15X18 M15X17 M15X16)
-+M14X22->(M16X15 M15X14 M15X13 M15X12)
-+M14X23->(M16X11 M15X25 M15X24 M15X23)
-+M14X24->(M16X22 M15X21 M15X20 M15X19)
-+M14X25->(M16X18 M15X17 M15X16 M15X15)
-+M15X11->(M17X14 M16X13 M16X12 M16X11)
-+M15X12->(M17X25 M16X24 M16X23 M16X22)
-+M15X13->(M17X21 M16X20 M16X19 M16X18)
-+M15X14->(M17X17 M16X16 M16X15 M16X14)
-+M15X15->(M17X13 M16X12 M16X11 M16X25)
-+M15X16->(M17X24 M16X23 M16X22 M16X21)
-+M15X17->(M17X20 M16X19 M16X18 M16X17)
-+M15X18->(M17X16 M16X15 M16X14 M16X13)
-+M15X19->(M17X12 M16X11 M16X25 M16X24)
-+M15X20->(M17X23 M16X22 M16X21 M16X20)
-+M15X21->(M17X19 M16X18 M16X17 M16X16)
-+M15X22->(M17X15 M16X14 M16X13 M16X12)
-+M15X23->(M17X11 M16X25 M16X24 M16X23)
-+M15X24->(M17X22 M16X21 M16X20 M16X19)
-+M15X25->(M17X18 M16X17 M16X16 M16X15)
-+M16X11->(M18X14 M17X13 M17X12 M17X11)
-+M16X12->(M18X25 M17X24 M17X23 M17X22)
-+M16X13->(M18X21 M17X20 M17X19 M17X18)
-+M16X14->(M18X17 M17X16 M17X15 M17X14)
-+M16X15->(M18X13 M17X12 M17X11 M17X25)
-+M16X16->(M18X24 M17X23 M17X22 M17X21)
-+M16X17->(M18X20 M17X19 M17X18 M17X17)
-+M16X18->(M18X16 M17X15 M17X14 M17X13)
-+M16X19->(M18X12 M17X11 M17X25 M17X24)
-+M16X20->(M18X23 M17X22 M17X21 M17X20)
-+M16X21->(M18X19 M17X18 M17X17 M17X16)
-+M16X22->(M18X15 M17X14 M17X13 M17X12)
-+M16X23->(M18X11 M17X25 M17X24 M17X23)
-+M16X24->(M18X22 M17X21 M17X20 M17X19)
-+M16X25->(M18X18 M17X17 M17X16 M17X15)
-+M17X11->(M19X14 M18X13 M18X12 M18X11)
-+M17X12->(M19X25 M18X24 M18X23 M18X22)
-+M17X13->(M19X21 M18X20 M18X19 M18X18)
-+M17X14->(M19X17 M18X16 M18X15 M18X14)
-+M17X15->(M19X13 M18X12 M18X11 M18X25)
-+M17X16->(M19X24 M18X23 M18X22 M18X21)
-+M17X17->(M19X20 M18X19 M18X18 M18X17)
-+M17X18->(M19X16 M18X15 M18X14 M18X13)
-+M17X19->(M19X12 M18X11 M18X25 M18X24)
-+M17X20->(M19X23 M18X22 M18X21 M18X20)
-+M17X21->(M19X19 M18X18 M18X17 M18X16)
-+M17X22->(M19X15 M18X14 M18X13 M18X12)
-+M17X23->(M19X11 M18X25 M18X24 M18X23)
-+M17X24->(M19X22 M18X21 M18X20 M18X19)
-+M17X25->(M19X18 M18X17 M18X16 M18X15)
-+M18X11->(M20X14 M19X13 M19X12 M19X11)
-+M18X12->(M20X25 M19X24 M19X23 M19X22)
-+M18X13->(M20X21 M19X20 M19X19 M19X18)
-+M18X14->(M20X17 M19X16 M19X15 M19X14)
-+M18X15->(M20X13 M19X12 M19X11 M19X25)
-+M18X16->(M20X24 M19X23 M19X22 M19X21)
-+M18X17->(M20X20 M19X19 M19X18 M19X17)
-+M18X18->(M20X16 M19X15 M19X14 M19X13)
-+M18X19->(M20X12 M19X11 M19X25 M19X24)
-+M18X20->(M20X23 M19X22 M19X21 M19X20)
-+M18X21->(M20X19 M19X18 M19X17 M19X16)
-+M18X22->(M20X15 M19X14 M19X13 M19X12)
-+M18X23->(M20X11 M19X25 M19X24 M19X23)
-+M18X24->(M20X22 M19X21 M19X20 M19X19)
-+M18X25->(M20X18 M19X17 M19X16 M19X15)
-+M19X11->(M21X14 M20X13 M20X12 M20X11)
-+M19X12->(M21X25 M20X24 M20X23 M20X22)
-+M19X13->(M21X21 M20X20 M20X19 M20X18)
-+M19X14->(M21X17 M20X16 M20X15 M20X14)
-+M19X15->(M21X13 M20X12 M20X11 M20X25)
-+M19X16->(M21X24 M20X23 M20X22 M20X21)
-+M19X17->(M21X20 M20X19 M20X18 M20X17)
-+M19X18->(M21X16 M20X15 M20X14 M20X13)
-+M19X19->(M21X12 M20X11 M20X25 M20X24)
-+M19X20->(M21X23 M20X22 M20X21 M20X20)
-+M19X21->(M21X19 M20X18 M20X17 M20X16)
-+M19X22->(M21X15 M20X14 M20X13 M20X12)
-+M19X23->(M21X11 M20X25 M20X24 M20X23)
-+M19X24->(M21X22 M20X21 M20X20 M20X19)
-+M19X25->(M21X18 M20X17 M20X16 M20X15)
-+M20X11->(M22X14 M21X13 M21X12 M21X11)
-+M20X12->(M22X25 M21X24 M21X23 M21X22)
-+M20X13->(M22X21 M21X20 M21X19 M21X18)
-+M20X14->(M22X17 M21X16 M21X15 M21X14)
-+M20X15->(M22X13 M21X12 M21X11 M21X25)
-+M20X16->(M22X24 M21X23 M21X22 M21X21)
-+M20X17->(M22X20 M21X19 M21X18 M21X17)
-+M20X18->(M22X16 M21X15 M21X14 M21X13)
-+M20X19->(M22X12 M21X11 M21X25 M21X24)
-+M20X20->(M22X23 M21X22 M21X21 M21X20)
-+M20X21->(M22X19 M21X18 M21X17 M21X16)
-+M20X22->(M22X15 M21X14 M21X13 M21X12)
-+M20X23->(M22X11 M21X25 M21X24 M21X23)
-+M20X24->(M22X22 M21X21 M21X20 M21X19)
-+M20X25->(M22X18 M21X17 M21X16 M21X15)
-+M21X11->(M23X15 M22X14 M22X13 M22X12)
-+M21X12->(M11X11 M23X25 M22X24 M22X23 M22X22)
-+M21X13->(M23X21 M22X20 M22X19 M22X18)
-+M21X14->(M23X17 M22X16 M22X15 M22X14)
-+M21X15->(M23X13 M22X12 M22X11 M22X25)
-+M21X16->(M23X24 M22X23 M22X22 M22X21)
-+M21X17->(M23X20 M22X19 M22X18 M22X17)
-+M21X18->(M23X16 M22X15 M22X14 M22X13)
-+M21X19->(M23X12 M22X11 M22X25 M22X24)
-+M21X20->(M23X23 M22X22 M22X21 M22X20)
-+M21X21->(M23X19 M22X18 M22X17 M22X16)
-+M21X22->(M23X15 M22X14 M22X13 M22X12)
-+M21X23->(M23X11 M22X25 M22X24 M22X23)
-+M21X24->(M23X22 M22X21 M22X20 M22X19)
-+M21X25->(M23X18 M22X17 M22X16 M22X15)
-+M22X11->(M24X16 M23X15 M23X14 M23X13)
-+M22X12->(M12X12 M24X11 M23X25 M23X24 M23X23)
-+M22X13->(M24X22 M23X21 M23X20 M23X19)
-+M22X14->(M24X18 M23X17 M23X16 M23X15)
-+M22X15->(M24X14 M23X13 M23X12 M23X11)
-+M22X16->(M24X25 M23X24 M23X23 M23X22)
-+M22X17->(M24X21 M23X20 M23X19 M23X18)
-+M22X18->(M24X17 M23X16 M23X15 M23X14)
-+M22X19->(M24X13 M23X12 M23X11 M23X25)
-+M22X20->(M24X24 M23X23 M23X22 M23X21)
-+M22X21->(M24X20 M23X19 M23X18 M23X17)
-+M22X22->(M24X16 M23X15 M23X14 M23X13)
-+M22X23->(M24X12 M23X11 M23X25 M23X24)
-+M22X24->(M24X23 M23X22 M23X21 M23X20)
-+M22X25->(M24X19 M23X18 M23X17 M23X16)
-+M23X11->(M25X17 M24X16 M24X15 M24X14)
-+M23X12->(M13X13 M25X12 M24X11 M24X25 M24X24)
-+M23X13->(M25X23 M24X22 M24X21 M24X20)
-+M23X14->(M25X19 M24X18 M24X17 M24X16)
-+M23X15->(M25X15 M24X14 M24X13 M24X12)
-+M23X16->(M25X11 M24X25 M24X24 M24X23)
-+M23X17->(M25X22 M24X21 M24X20 M24X19)
-+M23X18->(M25X18 M24X17 M24X16 M24X15)
-+M23X19->(M25X14 M24X13 M24X12 M24X11)
-+M23X20->(M25X25 M24X24 M24X23 M24X22)
-+M23X21->(M25X21 M24X20 M24X19 M24X18)
-+M23X22->(M25X17 M24X16 M24X15 M24X14)
-+M23X23->(M25X13 M24X12 M24X11 M24X25)
-+M23X24->(M25X24 M24X23 M24X22 M24X21)
-+M23X25->(M25X20 M24X19 M24X18 M24X17)
-+M24X11->(M26X18 M25X17 M25X16 M25X15)
-+M24X12->(M14X14 M26X13 M25X12 M25X11 M25X25)
-+M24X13->(M26X24 M25X23 M25X22 M25X21)
-+M24X14->(M26X20 M25X19 M25X18 M25X17)
-+M24X15->(M26X16 M25X15 M25X14 M25X13)
-+M24X16->(M26X12 M25X11 M25X25 M25X24)
-+M24X17->(M26X23 M25X22 M25X21 M25X20)
-+M24X18->(M26X19 M25X18 M25X17 M25X16)
-+M24X19->(M26X15 M25X14 M25X13 M25X12)
-+M24X20->(M26X11 M25X25 M25X24 M25X23)
-+M24X21->(M26X22 M25X21 M25X20 M25X19)
-+M24X22->(M26X18 M25X17 M25X16 M25X15)
-+M24X23->(M26X14 M25X13 M25X12 M25X11)
-+M24X24->(M26X25 M25X24 M25X23 M25X22)
-+M24X25->(M26X21 M25X20 M25X19 M25X18)
-+M25X11->(M27X19 M26X18 M26X17 M26X16)
-+M25X12->(M15X15 M27X14 M26X13 M26X12 M26X11)
-+M25X13->(M27X25 M26X24 M26X23 M26X22)
-+M25X14->(M27X21 M26X20 M26X19 M26X18)
-+M25X15->(M27X17 M26X16 M26X15 M26X14)
-+M25X16->(M27X13 M26X12 M26X11 M26X25)
-+M25X17->(M27X24 M26X23 M26X22 M26X21)
-+M25X18->(M27X20 M26X19 M26X18 M26X17)
-+M25X19->(M27X16 M26X15 M26X14 M26X13)
-+M25X20->(M27X12 M26X11 M26X25 M26X24)
-+M25X21->(M27X23 M26X22 M26X21 M26X20)
-+M25X22->(M27X19 M26X18 M26X17 M26X16)
-+M25X23->(M27X15 M26X14 M26X13 M26X12)
-+M25X24->(M27X11 M26X25 M26X24 M26X23)
-+M25X25->(M27X22 M26X21 M26X20 M26X19)
-+M26X11->(M28X20 M27X19 M27X18 M27X17)
-+M26X12->(M16X16 M28X15 M27X14 M27X13 M27X12)
-+M26X13->(M28X11 M27X25 M27X24 M27X23)
-+M26X14->(M28X22 M27X21 M27X20 M27X19)
-+M26X15->(M28X18 M27X17 M27X16 M27X15)
-+M26X16->(M28X14 M27X13 M27X12 M27X11)
-+M26X17->(M28X25 M27X24 M27X23 M27X22)
-+M26X18->(M28X21 M27X20 M27X19 M27X18)
-+M26X19->(M28X17 M27X16 M27X15 M27X14)
-+M26X20->(M28X13 M27X12 M27X11 M27X25)
-+M26X21->(M28X24 M27X23 M27X22 M27X21)
-+M26X22->(M28X20 M27X19 M27X18 M27X17)
-+M26X23->(M28X16 M27X15 M27X14 M27X13)
-+M26X24->(M28X12 M27X11 M27X25 M27X24)
-+M26X25->(M28X23 M27X22 M27X21 M27X20)
-+M27X11->(M29X21 M28X20 M28X19 M28X18)
-+M27X12->(M17X17 M29X16 M28X15 M28X14 M28X13)
-+M27X13->(M29X12 M28X11 M28X25 M28X24)
-+M27X14->(M29X23 M28X22 M28X21 M28X20)
-+M27X15->(M29X19 M28X18 M28X17 M28X16)
-+M27X16->(M29X15 M28X14 M28X13 M28X12)
-+M27X17->(M29X11 M28X25 M28X24 M28X23)
-+M27X18->(M29X22 M28X21 M28X20 M28X19)
-+M27X19->(M29X18 M28X17 M28X16 M28X15)
-+M27X20->(M29X14 M28X13 M28X12 M28X11)
-+M27X21->(M29X25 M28X24 M28X23 M28X22)
-+M27X22->(M29X21 M28X20 M28X19 M28X18)
-+M27X23->(M29X17 M28X16 M28X15 M28X14)
-+M27X24->(M29X13 M28X12 M28X11 M28X25)
-+M27X25->(M29X24 M28X23 M28X22 M28X21)
-+M28X11->(M30X22 M29X21 M29X20 M29X19)
-+M28X12->(M18X18 M30X17 M29X16 M29X15 M29X14)
-+M28X13->(M30X13 M29X12 M29X11 M29X25)
-+M28X14->(M30X24 M29X23 M29X22 M29X21)
-+M28X15->(M30X20 M29X19 M29X18 M29X17)
-+M28X16->(M30X16 M29X15 M29X14 M29X13)
-+M28X17->(M30X12 M29X11 M29X25 M29X24)
-+M28X18->(M30X23 M29X22 M29X21 M29X20)
-+M28X19->(M30X19 M29X18 M29X17 M29X16)
-+M28X20->(M30X15 M29X14 M29X13 M29X12)
-+M28X21->(M30X11 M29X25 M29X24 M29X23)
-+M28X22->(M30X22 M29X21 M29X20 M29X19)
-+M28X23->(M30X18 M29X17 M29X16 M29X15)
-+M28X24->(M30X14 M29X13 M29X12 M29X11)
-+M28X25->(M30X25 M29X24 M29X23 M29X22)
-+M29X11->(M30X22 M30X21 M30X20)
-+M29X12->(M30X17 M30X16 M30X15)
-+M29X13->(M30X13 M30X12 M30X11)
-+M29X14->(M30X24 M30X23 M30X22)
-+M29X15->(M30X20 M30X19 M30X18)
-+M29X16->(M30X16 M30X15 M30X14)
-+M29X17->(M30X12 M30X11 M30X25)
-+M29X18->(M30X23 M30X22 M30X21)
-+M29X19->(M30X19 M30X18 M30X17)
-+M29X20->(M30X15 M30X14 M30X13)
-+M29X21->(M30X11 M30X25 M30X24)
-+M29X22->(M30X22 M30X21 M30X20)
-+M29X23->(M30X18 M30X17 M30X16)
-+M29X24->(M30X14 M30X13 M30X12)
-+M29X25->(M30X25 M30X24 M30X23)
-+M30X11
-+M30X12
-+M30X13
-+M30X14
-+M30X15
-+M30X16
-+M30X17
-+M30X18
-+M30X19
-+M30X20
-+M30X21
-+M30X22
-+M30X23
-+M30X24
-+M30X25
-+xfail_output(glibc.rtld.dynamic_sort=1): M30X19>M30X15>M30X16>M30X11>M30X12>M30X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X19>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28X11>M28X22>M27X14>M28X18>M27X15>M28X13>M27X11>M28X23>M27X25>M28X14>M28X25>M27X23>M27X22>M28X24>M27X21>M27X13>M27X19>M27X17>M26X11>M26X23>M26X21>M26X22>M26X20>M26X16>M25X21>M17X22>M15X15>M20X14>M20X16>M18X18>M28X12>M27X24>M25X17>M27X20>M26X18>M26X17>M27X16>M26X19>M25X18>M26X24>M25X20>M24X17>M23X18>M25X13>M26X13>M17X23>M16X16>M26X12>M25X12>M26X15>M24X19>M25X23>M25X24>M25X25>M24X20>M25X19>M24X21>M23X17>M22X21>M24X14>M23X22>M24X24>M22X20>M24X13>M25X11>M24X12>M25X15>M23X15>M25X16>M24X22>M23X13>M24X18>M23X14>M22X22>M21X20>M24X25>M23X16>M22X25>M21X19>M22X14>M23X11>M22X15>M21X18>M22X19>M21X17>M20X17>M19X17>M21X24>M21X12>M20X22>M19X16>M18X25>M19X21>M19X20>M18X24>M20X12>M19X11>M23X20>M22X24>M22X16>M21X21>M25X14>M23X19>M23X24>M20X24>M19X12>M18X15>M17X14>M16X18>M14X25>M16X22>M16X20>M17X17>M22X12>M21X11>M20X15>M18X22>M19X24>M19X18>M18X21>M17X16>M17X18>M16X21>M15X20>M19X22>M18X20>M18X11>M17X19>M16X17>M15X21>M16X14>M16X13>M15X22>M14X20>M17X25>M16X19>M14X21>M13X24>M12X12>M16X24>M15X23>M14X16>M16X15>M15X25>M15X11>M15X12>M14X15>M13X14>M14X22>M13X20>M12X13>M11X11>M22X23>M21X15>M21X16>M20X21>M20X20>M18X17>M19X25>M18X23>M21X13>M15X17>M15X18>M18X19>M17X24>M16X12>M17X13>M20X25>M19X23>M15X19>M14X13>M13X18>M15X13>M17X12>M16X11>M18X13>M18X12>M14X11>M14X24>M13X19>M15X14>M17X20>M20X11>M20X13>M21X14>M15X24>M14X12>M13X22>M14X23>M13X23>M14X19>M17X15>M16X25>M17X11>M18X14>M19X19>M21X25>M13X12>M13X11>M14X18>M13X13>M12X11>M15X16>M14X14>M27X12>M17X21>M20X23>M22X13>M21X22>M24X16>M24X15>M26X25>M23X25>M26X14>M23X12>M22X18>M24X11>M16X23>M19X14>M19X13>M21X23>M22X17>M23X23>M23X21>M25X22>M18X16>M19X15>M20X18>M20X19>M22X11>M24X23>C156>C118>C143>C137>C147>C106>C168>C113>C163>C155>C105>C146>C187>A150>C139>C180>C164>C193>C157>A191>C158>B188>A159>C184>C121>C154>B171>A105>C131>C104>B104>C161>C111>B145>C160>B155>A163>C112>C142>B148>C133>B198>A198>A115>C114>B157>A156>C175>B144>A120>C173>B184>A174>C126>B107>A139>C194>B194>A194>C116>B116>C166>B160>B110>A110>C128>B128>A128>C179>B162>A154>C186>B187>A179>C124>B181>A101>C153>B158>A136>C135>C176>A192>B133>A133>C177>B177>A177>C185>C103>B141>A141>C183>A162>C192>C129>B179>C144>B124>B183>C127>B127>A127>B108>A112>B153>A153>C167>B167>A186>A122>C162>A144>B149>C174>B131>A185>C141>B106>A126>A167>C140>B122>A170>C198>B143>C117>C123>B123>A147>A106>C200>B169>C191>B175>A123>B118>A182>C132>B151>A145>A104>A109>C159>C150>B119>A119>A178>B164>B114>A164>C181>A102>C122>B134>A157>A116>C195>B191>B111>C172>B172>A118>B129>A129>C149>A107>C170>B197>A197>A173>B168>A132>C107>B165>A160>A131>C188>A168>B109>C178>A189>A148>C119>C190>C120>B166>B176>C108>B135>B139>A103>B178>A169>B132>C125>C138>B163>A111>B170>C110>A165>C151>C169>C199>A138>C182>A135>B101>B142>C101>C148>B193>B152>A158>A199>C136>B137>A161>B120>A108>A149>A125>B113>A184>C171>A134>A175>A124>B150>B161>B102>A146>A187>C130>B192>B200>A200>A142>A183>C102>B105>B156>A176>C165>B147>A137>A196>B190>A190>B125>C134>C189>B126>B186>A166>B136>B195>A195>B154>B138>B112>B173>A117>B159>B182>A181>A140>C145>B117>A152>A193>C197>B130>A172>A113>A151>B115>A143>B140>B185>B103>A121>A180>A130>A171>B199>C196>B146>B180>C115>B174>B121>A188>B196>B189>C152>C109>A155>A114>M14X17>M13X15>M13X16>M13X17>M12X17>M12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22>M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X17>M11X16>M11X15>M11X14>M11X13>M11X12>{}<M11X12<M11X13<M11X14<M11X15<M11X16<M11X17<M11X18<M11X19<M11X20<M11X21<M11X22<M11X23<M11X24<M11X25<M12X24<M12X23<M12X22<M12X20<M12X19<M12X18<M12X16<M13X21<M12X15<M13X25<M12X14<M12X25<M12X21<M12X17<M13X17<M13X16<M13X15<M14X17<A114<A155<C109<C152<B189<B196<A188<B121<B174<C115<B180<B146<C196<B199<A171<A130<A180<A121<B103<B185<B140<A143<B115<A151<A113<A172<B130<C197<A193<A152<B117<C145<A140<A181<B182<B159<A117<B173<B112<B138<B154<A195<B195<B136<A166<B186<B126<C189<C134<B125<A190<B190<A196<A137<B147<C165<A176<B156<B105<C102<A183<A142<A200<B200<B192<C130<A187<A146<B102<B161<B150<A124<A175<A134<C171<A184<B113<A125<A149<A108<B120<A161<B137<C136<A199<A158<B152<B193<C148<C101<B142<B101<A135<C182<A138<C199<C169<C151<A165<C110<B170<A111<B163<C138<C125<B132<A169<B178<A103<B139<B135<C108<B176<B166<C120<C190<C119<A148<A189<C178<B109<A168<C188<A131<A160<B165<C107<A132<B168<A173<A197<B197<C170<A107<C149<A129<B129<A118<B172<C172<B111<B191<C195<A116<A157<B134<C122<A102<C181<A164<B114<B164<A178<A119<B119<C150<C159<A109<A104<A145<B151<C132<A182<B118<A123<B175<C191<B169<C200<A106<A147<B123<C123<C117<B143<C198<A170<B122<C140<A167<A126<B106<C141<A185<B131<C174<B149<A144<C162<A122<A186<B167<C167<A153<B153<A112<B108<A127<B127<C127<B183<B124<C144<B179<C129<C192<A162<C183<A141<B141<C103<C185<A177<B177<C177<A133<B133<A192<C176<C135<A136<B158<C153<A101<B181<C124<A179<B187<C186<A154<B162<C179<A128<B128<C128<A110<B110<B160<C166<B116<C116<A194<B194<C194<A139<B107<C126<A174<B184<C173<A120<B144<C175<A156<B157<C114<A115<A198<B198<C133<B148<C142<C112<A163<B155<C160<B145<C111<C161<B104<C104<C131<A105<B171<C154<C121<C184<A159<B188<C158<A191<C157<C193<C164<C180<C139<A150<C187<C146<C105<C155<C163<C113<C168<C106<C147<C137<C143<C118<C156<M24X23<M22X11<M20X19<M20X18<M19X15<M18X16<M25X22<M23X21<M23X23<M22X17<M21X23<M19X13<M19X14<M16X23<M24X11<M22X18<M23X12<M26X14<M23X25<M26X25<M24X15<M24X16<M21X22<M22X13<M20X23<M17X21<M27X12<M14X14<M15X16<M12X11<M13X13<M14X18<M13X11<M13X12<M21X25<M19X19<M18X14<M17X11<M16X25<M17X15<M14X19<M13X23<M14X23<M13X22<M14X12<M15X24<M21X14<M20X13<M20X11<M17X20<M15X14<M13X19<M14X24<M14X11<M18X12<M18X13<M16X11<M17X12<M15X13<M13X18<M14X13<M15X19<M19X23<M20X25<M17X13<M16X12<M17X24<M18X19<M15X18<M15X17<M21X13<M18X23<M19X25<M18X17<M20X20<M20X21<M21X16<M21X15<M22X23<M11X11<M12X13<M13X20<M14X22<M13X14<M14X15<M15X12<M15X11<M15X25<M16X15<M14X16<M15X23<M16X24<M12X12<M13X24<M14X21<M16X19<M17X25<M14X20<M15X22<M16X13<M16X14<M15X21<M16X17<M17X19<M18X11<M18X20<M19X22<M15X20<M16X21<M17X18<M17X16<M18X21<M19X18<M19X24<M18X22<M20X15<M21X11<M22X12<M17X17<M16X20<M16X22<M14X25<M16X18<M17X14<M18X15<M19X12<M20X24<M23X24<M23X19<M25X14<M21X21<M22X16<M22X24<M23X20<M19X11<M20X12<M18X24<M19X20<M19X21<M18X25<M19X16<M20X22<M21X12<M21X24<M19X17<M20X17<M21X17<M22X19<M21X18<M22X15<M23X11<M22X14<M21X19<M22X25<M23X16<M24X25<M21X20<M22X22<M23X14<M24X18<M23X13<M24X22<M25X16<M23X15<M25X15<M24X12<M25X11<M24X13<M22X20<M24X24<M23X22<M24X14<M22X21<M23X17<M24X21<M25X19<M24X20<M25X25<M25X24<M25X23<M24X19<M26X15<M25X12<M26X12<M16X16<M17X23<M26X13<M25X13<M23X18<M24X17<M25X20<M26X24<M25X18<M26X19<M27X16<M26X17<M26X18<M27X20<M25X17<M27X24<M28X12<M18X18<M20X16<M20X14<M15X15<M17X22<M25X21<M26X16<M26X20<M26X22<M26X21<M26X23<M26X11<M27X17<M27X19<M27X13<M27X21<M28X24<M27X22<M27X23<M28X25<M28X14<M27X25<M28X23<M27X11<M28X13<M27X15<M28X18<M27X14<M28X22<M28X11<M28X17<M29X11<M27X18<M28X21<M28X16<M28X15<M28X20<M29X14<M29X25<M29X21<M28X19<M29X18<M29X17<M29X13<M29X24<M29X16<M29X23<M29X19<M30X25<M29X22<M30X21<M30X22<M29X12<M29X15<M30X18<M30X20<M30X24<M30X23<M29X20<M30X14<M30X13<M30X17<M30X12<M30X11<M30X16<M30X15<M30X19
-+output(glibc.rtld.dynamic_sort=2): M30X19>M30X15>M30X16>M30X11>M30X12>M30X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X19>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28X11>M28X22>M28X24>M28X23>M27X21>M28X13>M27X20>M27X19>M26X14>M27X25>M28X18>M27X11>M28X25>M27X24>M26X24>M27X15>M27X14>M27X13>M26X23>M27X17>M26X22>M25X13>M28X14>M27X16>M26X19>M26X18>M27X23>M27X22>M26X17>M25X18>M26X21>M25X17>M26X20>M26X15>M26X13>M25X19>M24X14>M25X23>M26X11>M26X25>M25X16>M25X15>M24X22>M25X21>M25X20>M24X21>M25X25>M25X24>M24X20>M23X13>M22X15>M25X14>M24X19>M23X17>M24X25>M23X24>M24X13>M23X15>M24X18>M23X14>M22X11>M24X15>M23X22>M24X11>M23X19>M22X21>M24X24>M23X21>M22X20>M23X25>M22X19>M21X24>M20X23>M22X22>M25X11>M23X16>M22X18>M23X20>M22X17>M21X21>M21X20>M20X24>M22X14>M22X13>M21X11>M21X17>M22X23>M21X16>M20X25>M19X23>M18X16>M21X22>M20X20>M20X19>M21X13>M20X18>M19X13>M21X18>M20X21>M19X24>M18X12>M20X14>M20X13>M22X25>M20X12>M20X15>M19X14>M18X22>M19X18>M20X17>M19X17>M19X16>M18X21>M17X20>M19X19>M18X13>M17X11>M18X17>M19X25>M18X15>M17X25>M18X19>M17X24>M16X19>M15X17>M17X21>M16X24>M18X23>M17X16>M16X25>M19X15>M18X25>M17X23>M16X23>M15X23>M18X14>M17X14>M16X14>M17X18>M16X13>M17X22>M16X12>M15X22>M14X16>M17X12>M16X22>M15X12>M16X11>M15X11>M16X15>M15X25>M14X15>M13X14>M15X18>M16X21>M15X16>M14X21>M15X14>M16X20>M15X13>M14X22>M15X20>M14X20>M13X20>M14X11>M15X19>M14X24>M13X19>M14X13>M13X18>M12X13>M15X24>M14X23>M13X12>M14X12>M13X11>M12X11>M11X11>M21X12>M20X11>M19X11>M18X11>M17X15>M16X18>M14X25>M14X19>M13X24>M13X23>M13X22>M12X12>M22X12>M21X15>M19X22>M18X20>M16X17>M14X14>M24X12>M23X23>M22X16>M21X14>M20X22>M18X24>M16X16>M26X12>M24X16>M23X11>M21X23>M19X20>M17X17>M27X12>M26X16>M25X22>M24X17>M23X18>M21X25>M19X12>M17X19>M15X21>M14X18>M13X13>M23X12>M21X19>M19X21>M17X13>M15X15>M25X12>M24X23>M22X24>M20X16>M18X18>M28X12>A150>C158>B112>A112>C167>B146>A146>C180>B180>A180>C143>B143>A115>C126>B126>A126>C190>B190>A190>C138>B138>A138>C174>B174>A102>C122>B122>A122>C162>B162>A162>C142>B142>A142>C102>B102>A174>C176>B176>A176>C115>B115>A143>C172>B172>A172>C187>B187>A187>C130>B130>A130>C118>B118>A118>C184>B184>A184>C171>B171>A171>C168>B182>A182>C182>B168>A168>C109>B109>A109>C159>B159>A159>C134>B134>A134>C146>B167>A167>C140>B140>A140>C163>B163>A163>C112>B158>A158>C164>B164>A164>C131>B131>A131>C188>B188>A188>C199>B199>A199>C114>B114>A114>C106>B106>A106>C200>B200>A200>C183>B183>A183>C152>B152>A152>C147>B147>A147>C150>B150>A198>C144>B144>A144>C191>B191>A191>C108>B108>A108>C139>B139>A139>C194>B194>A194>C166>B166>A166>C120>B120>A120>C123>B123>A123>C132>B132>A132>C107>B107>A107>C170>B170>A170>C198>B198>A156>C125>B125>A125>C121>B121>A121>C193>B193>A193>C197>B197>A197>C175>B175>A175>C196>B196>A196>C105>B105>A105>C181>B181>A181>C113>B113>A113>C137>B137>A137>C155>B155>A155>C156>B156>A110>C128>B128>A128>C179>B179>A179>C124>B124>A124>C151>B151>A151>C178>B178>A178>C104>B104>A104>C111>B111>A111>C148>B148>A148>C169>B169>A169>C129>B129>A129>C149>B149>A149>C189>B189>A189>C119>B119>A119>C154>B154>A154>C136>B136>A136>C135>B135>A135>C116>B116>A116>C145>B145>A145>C161>B161>A161>C173>B173>A173>C157>B157>A157>C195>B195>A195>C186>B186>A186>C160>B160>A160>C153>B153>A153>C117>B117>A117>C165>B165>A165>C101>B101>A101>C103>B103>A103>C192>B192>A192>C177>B177>A177>C185>B185>A185>C141>B141>A141>C133>B133>A133>C127>B127>A127>C110>B110>M14X17>M13X15>M13X16>M13X17>M12X17>M12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22>M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X17>M11X16>M11X15>M11X14>M11X13>M11X12>{}<M11X12<M11X13<M11X14<M11X15<M11X16<M11X17<M11X18<M11X19<M11X20<M11X21<M11X22<M11X23<M11X24<M11X25<M12X24<M12X23<M12X22<M12X20<M12X19<M12X18<M12X16<M13X21<M12X15<M13X25<M12X14<M12X25<M12X21<M12X17<M13X17<M13X16<M13X15<M14X17<B110<C110<A127<B127<C127<A133<B133<C133<A141<B141<C141<A185<B185<C185<A177<B177<C177<A192<B192<C192<A103<B103<C103<A101<B101<C101<A165<B165<C165<A117<B117<C117<A153<B153<C153<A160<B160<C160<A186<B186<C186<A195<B195<C195<A157<B157<C157<A173<B173<C173<A161<B161<C161<A145<B145<C145<A116<B116<C116<A135<B135<C135<A136<B136<C136<A154<B154<C154<A119<B119<C119<A189<B189<C189<A149<B149<C149<A129<B129<C129<A169<B169<C169<A148<B148<C148<A111<B111<C111<A104<B104<C104<A178<B178<C178<A151<B151<C151<A124<B124<C124<A179<B179<C179<A128<B128<C128<A110<B156<C156<A155<B155<C155<A137<B137<C137<A113<B113<C113<A181<B181<C181<A105<B105<C105<A196<B196<C196<A175<B175<C175<A197<B197<C197<A193<B193<C193<A121<B121<C121<A125<B125<C125<A156<B198<C198<A170<B170<C170<A107<B107<C107<A132<B132<C132<A123<B123<C123<A120<B120<C120<A166<B166<C166<A194<B194<C194<A139<B139<C139<A108<B108<C108<A191<B191<C191<A144<B144<C144<A198<B150<C150<A147<B147<C147<A152<B152<C152<A183<B183<C183<A200<B200<C200<A106<B106<C106<A114<B114<C114<A199<B199<C199<A188<B188<C188<A131<B131<C131<A164<B164<C164<A158<B158<C112<A163<B163<C163<A140<B140<C140<A167<B167<C146<A134<B134<C134<A159<B159<C159<A109<B109<C109<A168<B168<C182<A182<B182<C168<A171<B171<C171<A184<B184<C184<A118<B118<C118<A130<B130<C130<A187<B187<C187<A172<B172<C172<A143<B115<C115<A176<B176<C176<A174<B102<C102<A142<B142<C142<A162<B162<C162<A122<B122<C122<A102<B174<C174<A138<B138<C138<A190<B190<C190<A126<B126<C126<A115<B143<C143<A180<B180<C180<A146<B146<C167<A112<B112<C158<A150<M28X12<M18X18<M20X16<M22X24<M24X23<M25X12<M15X15<M17X13<M19X21<M21X19<M23X12<M13X13<M14X18<M15X21<M17X19<M19X12<M21X25<M23X18<M24X17<M25X22<M26X16<M27X12<M17X17<M19X20<M21X23<M23X11<M24X16<M26X12<M16X16<M18X24<M20X22<M21X14<M22X16<M23X23<M24X12<M14X14<M16X17<M18X20<M19X22<M21X15<M22X12<M12X12<M13X22<M13X23<M13X24<M14X19<M14X25<M16X18<M17X15<M18X11<M19X11<M20X11<M21X12<M11X11<M12X11<M13X11<M14X12<M13X12<M14X23<M15X24<M12X13<M13X18<M14X13<M13X19<M14X24<M15X19<M14X11<M13X20<M14X20<M15X20<M14X22<M15X13<M16X20<M15X14<M14X21<M15X16<M16X21<M15X18<M13X14<M14X15<M15X25<M16X15<M15X11<M16X11<M15X12<M16X22<M17X12<M14X16<M15X22<M16X12<M17X22<M16X13<M17X18<M16X14<M17X14<M18X14<M15X23<M16X23<M17X23<M18X25<M19X15<M16X25<M17X16<M18X23<M16X24<M17X21<M15X17<M16X19<M17X24<M18X19<M17X25<M18X15<M19X25<M18X17<M17X11<M18X13<M19X19<M17X20<M18X21<M19X16<M19X17<M20X17<M19X18<M18X22<M19X14<M20X15<M20X12<M22X25<M20X13<M20X14<M18X12<M19X24<M20X21<M21X18<M19X13<M20X18<M21X13<M20X19<M20X20<M21X22<M18X16<M19X23<M20X25<M21X16<M22X23<M21X17<M21X11<M22X13<M22X14<M20X24<M21X20<M21X21<M22X17<M23X20<M22X18<M23X16<M25X11<M22X22<M20X23<M21X24<M22X19<M23X25<M22X20<M23X21<M24X24<M22X21<M23X19<M24X11<M23X22<M24X15<M22X11<M23X14<M24X18<M23X15<M24X13<M23X24<M24X25<M23X17<M24X19<M25X14<M22X15<M23X13<M24X20<M25X24<M25X25<M24X21<M25X20<M25X21<M24X22<M25X15<M25X16<M26X25<M26X11<M25X23<M24X14<M25X19<M26X13<M26X15<M26X20<M25X17<M26X21<M25X18<M26X17<M27X22<M27X23<M26X18<M26X19<M27X16<M28X14<M25X13<M26X22<M27X17<M26X23<M27X13<M27X14<M27X15<M26X24<M27X24<M28X25<M27X11<M28X18<M27X25<M26X14<M27X19<M27X20<M28X13<M27X21<M28X23<M28X24<M28X22<M28X11<M28X17<M29X11<M27X18<M28X21<M28X16<M28X15<M28X20<M29X14<M29X25<M29X21<M28X19<M29X18<M29X17<M29X13<M29X24<M29X16<M29X23<M29X19<M30X25<M29X22<M30X21<M30X22<M29X12<M29X15<M30X18<M30X20<M30X24<M30X23<M29X20<M30X14<M30X13<M30X17<M30X12<M30X11<M30X16<M30X15<M30X19
-diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
-new file mode 100644
-index 0000000000..944ee74052
---- /dev/null
-+++ b/scripts/dso-ordering-test.py
-@@ -0,0 +1,1144 @@
-+#!/usr/bin/python3
-+# Generate testcase files and Makefile fragments for DSO sorting test
-+# Copyright (C) 2021 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
-+# <http://www.gnu.org/licenses/>.
-+
-+"""Generate testcase files and Makefile fragments for DSO sorting test
-+
-+This script takes a small description string language, and generates
-+testcases for displaying the ELF dynamic linker's dependency sorting
-+behavior, allowing verification.
-+
-+Testcase descriptions are semicolon-separated description strings, and
-+this tool generates a testcase from the description, including main program,
-+associated modules, and Makefile fragments for including into elf/Makefile.
-+
-+This allows automation of what otherwise would be very laborous manual
-+construction of complex dependency cases, however it must be noted that this
-+is only a tool to speed up testcase construction, and thus the generation
-+features are largely mechanical in nature; inconsistencies or errors may occur
-+if the input description was itself erroneous or have unforeseen interactions.
-+
-+The format of the input test description files are:
-+
-+ # Each test description has a name, lines of description,
-+ # and an expected output specification. Comments use '#'.
-+ testname1: <test-description-line>
-+ output: <expected-output-string>
-+
-+ # Tests can be marked to be XFAIL by using 'xfail_output' instead
-+ testname2: <test-description-line>
-+ xfail_output: <expected-output-string>
-+
-+ # A default set of GLIBC_TUNABLES tunables can be specified, for which
-+ # all following tests will run multiple times, once for each of the
-+ # GLIBC_TUNABLES=... strings set by the 'tunable_option' command.
-+ tunable_option: <glibc-tunable-string1>
-+ tunable_option: <glibc-tunable-string2>
-+
-+ # Test descriptions can use multiple lines, which will all be merged
-+ # together, so order is not important.
-+ testname3: <test-description-line>
-+ <test-description-line>
-+ <test-description-line>
-+ ...
-+ output: <expected-output-string>
-+
-+ # 'testname3' will be run and compared two times, for both
-+ # GLIBC_TUNABLES=<glibc-tunable-string1> and
-+ # GLIBC_TUNABLES=<glibc-tunable-string2>. This can be cleared and reset by the
-+ # 'clear_tunables' command:
-+ clear_tunables
-+
-+ # Multiple expected outputs can also be specified, with an associated
-+ # tunable option in (), which multiple tests will be run with each
-+ # GLIBC_TUNABLES=... option tried.
-+ testname4:
-+ <test-description-line>
-+ ...
-+ output(<glibc-tunable-string1>): <expected-output-string-1>
-+ output(<glibc-tunable-string2>): <expected-output-string-2>
-+ # Individual tunable output cases can be XFAILed, though note that
-+ # this will have the effect of XFAILing the entire 'testname4' test
-+ # in the final top-level tests.sum summary.
-+ xfail_output(<glibc-tunable-string3>): <expected-output-string-3>
-+
-+ # When multiple outputs (with specific tunable strings) are specified,
-+ # these take priority over any active 'tunable_option' settings.
-+
-+ # When a test is meant to be placed under 'xtests' (not run under
-+ # "make check", but only when "make xtests" is used), the testcase name can be
-+ # declared using 'xtest(<test-name>)':
-+ ...
-+ xtest(test-too-big1): <test-description>
-+ output: <expected-output-string>
-+ ...
-+
-+ # Do note that under current elf/Makefile organization, for such a xtest case,
-+ # while the test execution is only run under 'make xtests', the associated
-+ # DSOs are always built even under 'make check'.
-+
-+On the description language used, an example description line string:
-+
-+ a->b!->[cdef];c=>g=>h;{+c;%c;-c}->a
-+
-+Each identifier represents a shared object module, currently sequences of
-+letters/digits are allowed, case-sensitive.
-+
-+All such shared objects have a constructor/destructor generated for them
-+that emits its name followed by a '>' for constructors, and '<' followed by
-+its name for destructors, e.g. if the name is 'obj1', then "obj1>" and "<obj1"
-+is printed by its constructor/destructor respectively.
-+
-+The -> operator specifies a link time dependency, these can be chained for
-+convenience (e.g. a->b->c->d).
-+
-+The => operator creates a call-reference, e.g. for a=>b, an fn_a() function
-+is created inside module 'a', which calls fn_b() in module 'b'.
-+These module functions emit 'name()' output in nested form,
-+e.g. a=>b emits 'a(b())'
-+
-+For single character object names, square brackets [] in the description
-+allows specifying multiple objects; e.g. a->[bcd]->e is equivalent to
-+ a->b->e;a->c->e;a->d->e
-+
-+The () parenthesis construct with space separated names is also allowed for
-+specifying objects. For names with integer suffixes a range can also be used,
-+e.g. (foo1 bar2-5), specifies DSOs foo1, bar2, bar2, bar3, bar4, bar5.
-+
-+A {} construct specifies the main test program, and its link dependencies
-+are also specified using ->. Inside {}, a few ;-separated constructs are
-+allowed:
-+ +a Loads module a using dlopen(RTLD_LAZY|RTLD_GLOBAL)
-+ ^a Loads module a using dlopen(RTLD_LAZY)
-+ %a Use dlsym() to load and call fn_a()
-+ @a Calls fn_a() directly.
-+ -a Unloads module a using dlclose()
-+
-+The generated main program outputs '{' '}' with all output from above
-+constructs in between. The other output before/after {} are the ordered
-+constructor/destructor output.
-+
-+If no {} construct is present, a default empty main program is linked
-+against all objects which have no dependency linked to it. e.g. for
-+'[ab]->c;d->e', the default main program is equivalent to '{}->[abd]'
-+
-+Sometimes for very complex or large testcases, besides specifying a
-+few explicit dependencies from main{}, the above default dependency
-+behavior is still useful to automatically have, but is turned off
-+upon specifying a single explicit {}->dso_name.
-+In this case, add {}->* to explicitly add this generation behavior:
-+
-+ # Main program links to 'foo', and all other objects which have no
-+ # dependency linked to it.
-+ {}->foo,{}->*
-+
-+Note that '*' works not only on main{}, but can be used as the
-+dependency target of any object. Note that it only works as a target,
-+not a dependency source.
-+
-+The '!' operator after object names turns on permutation of its
-+dependencies, e.g. while a->[bcd] only generates one set of objects,
-+with 'a.so' built with a link line of "b.so c.so d.so", for a!->[bcd]
-+permutations of a's dependencies creates multiple testcases with
-+different link line orders: "b.so c.so d.so", "c.so b.so d.so",
-+"b.so d.so c.so", etc. Note that for a <test-name> specified on
-+the script command-line, multiple <test-name_1>, <test-name_2>, etc.
-+tests will be generated (e.g. for a!->[bc]!->[de], eight tests with
-+different link orders for a, b, and c will be generated)
-+
-+It is possible to specify the ELF soname field for an object or the
-+main program:
-+ # DSO 'a' will be linked with the appropriate -Wl,-soname=x setting
-+ a->b->c;soname(a)=x
-+ # The the main program can also have a soname specified
-+ soname({})=y
-+
-+This can be used to test how ld.so behaves when objects and/or the
-+main program have such a field set.
-+
-+
-+Strings Output by Generated Testcase Programs
-+
-+The text output produced by a generated testcase consists of three main
-+parts:
-+ 1. The constructors' output
-+ 2. Output from the main program
-+ 3. Destructors' output
-+
-+To see by example, a simple test description "a->b->c" generates a testcase
-+that when run, outputs: "c>b>a>{}<a<b<c"
-+
-+Each generated DSO constructor prints its name followed by a '>' character,
-+and the "c>b>a" part above is the full constructor output by all DSOs, the
-+order indicating that DSO 'c', which does not depend on any other DSO, has
-+its constructor run first, followed by 'b' and then 'a'.
-+
-+Destructor output for each DSO is a '<' character followed by its name,
-+reflecting its reverse nature of constructors. In the above example, the
-+destructor output part is "<a<b<c".
-+
-+The middle "{}" part is the main program. In this simple example, nothing
-+was specified for the main program, so by default it is implicitly linked
-+to the DSO 'a' (with no other DSOs depending on it) and only prints the
-+brackets {} with no actions inside.
-+
-+To see an example with actions inside the main program, lets see an example
-+description: c->g=>h;{+c;%c;-c}->a->h
-+
-+This produces a testcase, that when executed outputs:
-+ h>a>{+c[g>c>];%c();-c[<c<g];}<a<h
-+
-+The constructor and destructor parts display the a->h dependency as expected.
-+Inside the main program, the "+c" action triggers a dlopen() of DSO 'c',
-+causing another chain of constructors "g>c>" to be triggered. Here it is
-+displayed inside [] brackets for each dlopen call. The same is done for "-c",
-+a dlclose() of 'c'.
-+
-+The "%c" output is due to calling to fn_c() inside DSO 'c', this comprises
-+of two parts: the '%' character is printed by the caller, here it is the main
-+program. The 'c' character is printed from inside fn_c(). The '%' character
-+indicates that this is called by a dlsym() of "fn_c". A '@' character would
-+mean a direct call (with a symbol reference). These can all be controlled
-+by the main test program constructs documented earlier.
-+
-+The output strings described here is the exact same form placed in
-+test description files' "output: <expected output>" line.
-+"""
-+
-+import sys
-+import re
-+import os
-+import subprocess
-+import argparse
-+from collections import OrderedDict
-+import itertools
-+
-+# BUILD_GCC is only used under the --build option,
-+# which builds the generated testcase, including DSOs using BUILD_GCC.
-+# Mainly for testing purposes, especially debugging of this script,
-+# and can be changed here to another toolchain path if needed.
-+build_gcc = "gcc"
-+
-+def get_parser():
-+ parser = argparse.ArgumentParser("")
-+ parser.add_argument("description",
-+ help="Description string of DSO dependency test to be "
-+ "generated (see script source for documentation of "
-+ "description language), either specified here as "
-+ "command line argument, or by input file using "
-+ "-f/--description-file option",
-+ nargs="?", default="")
-+ parser.add_argument("test_name",
-+ help="Identifier for testcase being generated",
-+ nargs="?", default="")
-+ parser.add_argument("--objpfx",
-+ help="Path to place generated files, defaults to "
-+ "current directory if none specified",
-+ nargs="?", default="./")
-+ parser.add_argument("-m", "--output-makefile",
-+ help="File to write Makefile fragment to, defaults to "
-+ "stdout when option not present",
-+ nargs="?", default="")
-+ parser.add_argument("-f", "--description-file",
-+ help="Input file containing testcase descriptions",
-+ nargs="?", default="")
-+ parser.add_argument("--build", help="After C testcase generated, build it "
-+ "using gcc (for manual testing purposes)",
-+ action="store_true")
-+ parser.add_argument("--debug-output",
-+ help="Prints some internal data "
-+ "structures; used for debugging of this script",
-+ action="store_true")
-+ return parser
-+
-+# Main script starts here.
-+cmdlineargs = get_parser().parse_args()
-+test_name = cmdlineargs.test_name
-+description = cmdlineargs.description
-+objpfx = cmdlineargs.objpfx
-+description_file = cmdlineargs.description_file
-+output_makefile = cmdlineargs.output_makefile
-+makefile = ""
-+default_tunable_options = []
-+
-+current_input_lineno = 0
-+def error(msg):
-+ global current_input_lineno
-+ print("Error: %s%s" % ((("Line %d, " % current_input_lineno)
-+ if current_input_lineno != 0 else ""),
-+ msg))
-+ exit(1)
-+
-+if(test_name or description) and description_file:
-+ error("both command-line testcase and input file specified")
-+if test_name and not description:
-+ error("command-line testcase name without description string")
-+
-+# Main class type describing a testcase.
-+class TestDescr:
-+ def __init__(self):
-+ self.objs = [] # list of all DSO objects
-+ self.deps = OrderedDict() # map of DSO object -> list of dependencies
-+
-+ # map of DSO object -> list of call refs
-+ self.callrefs = OrderedDict()
-+
-+ # map of DSO object -> list of permutations of dependencies
-+ self.dep_permutations = OrderedDict()
-+
-+ # map of DSO object -> SONAME of object (if one is specified)
-+ self.soname_map = OrderedDict()
-+
-+ # list of main program operations
-+ self.main_program = []
-+ # set if default dependencies added to main
-+ self.main_program_default_deps = True
-+
-+ self.test_name = "" # name of testcase
-+ self.expected_outputs = OrderedDict() # expected outputs of testcase
-+ self.xfail = False # set if this is a XFAIL testcase
-+ self.xtest = False # set if this is put under 'xtests'
-+
-+ # Add 'object -> [object, object, ...]' relations to CURR_MAP
-+ def __add_deps_internal(self, src_objs, dst_objs, curr_map):
-+ for src in src_objs:
-+ for dst in dst_objs:
-+ if not src in curr_map:
-+ curr_map[src] = []
-+ if not dst in curr_map[src]:
-+ curr_map[src].append(dst)
-+ def add_deps(self, src_objs, dst_objs):
-+ self.__add_deps_internal(src_objs, dst_objs, self.deps)
-+ def add_callrefs(self, src_objs, dst_objs):
-+ self.__add_deps_internal(src_objs, dst_objs, self.callrefs)
-+
-+# Process commands inside the {} construct.
-+# Note that throughout this script, the main program object is represented
-+# by the '#' string.
-+def process_main_program(test_descr, mainprog_str):
-+ if mainprog_str:
-+ test_descr.main_program = mainprog_str.split(';')
-+ for s in test_descr.main_program:
-+ m = re.match(r"^([+\-%^@])([0-9a-zA-Z]+)$", s)
-+ if not m:
-+ error("'%s' is not recognized main program operation" % (s))
-+ opr = m.group(1)
-+ obj = m.group(2)
-+ if not obj in test_descr.objs:
-+ test_descr.objs.append(obj)
-+ if opr == '%' or opr == '@':
-+ test_descr.add_callrefs(['#'], [obj])
-+ # We have a main program specified, turn this off
-+ test_descr.main_program_default_deps = False
-+
-+# For(a1 a2 b1-12) object set descriptions, expand into an object list
-+def expand_object_set_string(descr_str):
-+ obj_list = []
-+ descr_list = descr_str.split()
-+ for descr in descr_list:
-+ m = re.match(r"^([a-zA-Z][0-9a-zA-Z]*)(-[0-9]+)?$", descr)
-+ if not m:
-+ error("'%s' is not a valid object set description" % (descr))
-+ obj = m.group(1)
-+ idx_end = m.group(2)
-+ if not idx_end:
-+ if not obj in obj_list:
-+ obj_list.append(obj)
-+ else:
-+ idx_end = int(idx_end[1:])
-+ m = re.match(r"^([0-9a-zA-Z][a-zA-Z]*)([0-9]+)$", obj)
-+ if not m:
-+ error("object description '%s' is malformed" % (obj))
-+ obj_name = m.group(1)
-+ idx_start = int(m.group (2))
-+ if idx_start > idx_end:
-+ error("index range %s-%s invalid" % (idx_start, idx_end))
-+ for i in range(idx_start, idx_end + 1):
-+ o = obj_name + str(i)
-+ if not o in obj_list:
-+ obj_list.append(o)
-+ return obj_list
-+
-+# Lexer for tokens
-+tokenspec = [ ("SONAME", r"soname\(([0-9a-zA-Z{}]+)\)=([0-9a-zA-Z]+)"),
-+ ("OBJ", r"([0-9a-zA-Z]+)"),
-+ ("DEP", r"->"),
-+ ("CALLREF", r"=>"),
-+ ("OBJSET", r"\[([0-9a-zA-Z]+)\]"),
-+ ("OBJSET2", r"\(([0-9a-zA-Z \-]+)\)"),
-+ ("OBJSET3", r"\*"),
-+ ("PROG", r"{([0-9a-zA-Z;+^\-%@]*)}"),
-+ ("PERMUTE", r"!"),
-+ ("SEMICOL", r";"),
-+ ("ERROR", r".") ]
-+tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tokenspec)
-+
-+# Main line parser of description language
-+def parse_description_string(t, descr_str):
-+ # State used when parsing dependencies
-+ curr_objs = []
-+ in_dep = False
-+ in_callref = False
-+ def clear_dep_state():
-+ nonlocal in_dep, in_callref
-+ in_dep = in_callref = False
-+
-+ for m in re.finditer(tok_re, descr_str):
-+ kind = m.lastgroup
-+ value = m.group()
-+ if kind == "SONAME":
-+ s = re.match(r"soname\(([0-9a-zA-Z{}]+)\)=([0-9a-zA-Z]+)", value)
-+ obj = s.group(1)
-+ val = s.group(2)
-+ if obj == "{}":
-+ if '#' in t.soname_map:
-+ error("soname of main program already set")
-+ # Adjust to internal name
-+ obj = '#'
-+ else:
-+ if re.match(r"[{}]", obj):
-+ error("invalid object name '%s'" % (obj))
-+ if not obj in t.objs:
-+ error("'%s' is not name of already defined object" % (obj))
-+ if obj in t.soname_map:
-+ error("'%s' already has soname of '%s' set"
-+ % (obj, t.soname_map[obj]))
-+ t.soname_map[obj] = val
-+
-+ elif kind == "OBJ":
-+ if in_dep:
-+ t.add_deps(curr_objs, [value])
-+ elif in_callref:
-+ t.add_callrefs(curr_objs, [value])
-+ clear_dep_state()
-+ curr_objs = [value]
-+ if not value in t.objs:
-+ t.objs.append(value)
-+
-+ elif kind == "OBJSET":
-+ objset = value[1:len(value)-1]
-+ if in_dep:
-+ t.add_deps(curr_objs, list (objset))
-+ elif in_callref:
-+ t.add_callrefs(curr_objs, list (objset))
-+ clear_dep_state()
-+ curr_objs = list(objset)
-+ for o in list(objset):
-+ if not o in t.objs:
-+ t.objs.append(o)
-+
-+ elif kind == "OBJSET2":
-+ descr_str = value[1:len(value)-1]
-+ descr_str.strip()
-+ objs = expand_object_set_string(descr_str)
-+ if not objs:
-+ error("empty object set '%s'" % (value))
-+ if in_dep:
-+ t.add_deps(curr_objs, objs)
-+ elif in_callref:
-+ t.add_callrefs(curr_objs, objs)
-+ clear_dep_state()
-+ curr_objs = objs
-+ for o in objs:
-+ if not o in t.objs:
-+ t.objs.append(o)
-+
-+ elif kind == "OBJSET3":
-+ if in_dep:
-+ t.add_deps(curr_objs, ['*'])
-+ elif in_callref:
-+ t.add_callrefs(curr_objs, ['*'])
-+ else:
-+ error("non-dependence target set '*' can only be used "
-+ "as target of ->/=> operations")
-+ clear_dep_state()
-+ curr_objs = ['*']
-+
-+ elif kind == "PERMUTE":
-+ if in_dep or in_callref:
-+ error("syntax error, permute operation invalid here")
-+ if not curr_objs:
-+ error("syntax error, no objects to permute here")
-+
-+ for obj in curr_objs:
-+ if not obj in t.dep_permutations:
-+ # Signal this object has permuted dependencies
-+ t.dep_permutations[obj] = []
-+
-+ elif kind == "PROG":
-+ if t.main_program:
-+ error("cannot have more than one main program")
-+ if in_dep:
-+ error("objects cannot have dependency on main program")
-+ if in_callref:
-+ # TODO: A DSO can resolve to a symbol in the main binary,
-+ # which we syntactically allow here, but haven't yet
-+ # implemented.
-+ t.add_callrefs(curr_objs, ["#"])
-+ process_main_program(t, value[1:len(value)-1])
-+ clear_dep_state()
-+ curr_objs = ["#"]
-+
-+ elif kind == "DEP":
-+ if in_dep or in_callref:
-+ error("syntax error, multiple contiguous ->,=> operations")
-+ if '*' in curr_objs:
-+ error("non-dependence target set '*' can only be used "
-+ "as target of ->/=> operations")
-+ in_dep = True
-+
-+ elif kind == "CALLREF":
-+ if in_dep or in_callref:
-+ error("syntax error, multiple contiguous ->,=> operations")
-+ if '*' in curr_objs:
-+ error("non-dependence target set '*' can only be used "
-+ "as target of ->/=> operations")
-+ in_callref = True
-+
-+ elif kind == "SEMICOL":
-+ curr_objs = []
-+ clear_dep_state()
-+
-+ else:
-+ error("unknown token '%s'" % (value))
-+ return t
-+
-+# Main routine to process each testcase description
-+def process_testcase(t):
-+ global objpfx
-+ assert t.test_name
-+
-+ base_test_name = t.test_name
-+ test_subdir = base_test_name + "-dir"
-+ testpfx = objpfx + test_subdir + "/"
-+
-+ if not os.path.exists(testpfx):
-+ os.mkdir(testpfx)
-+
-+ def find_objs_not_depended_on(t):
-+ objs_not_depended_on = []
-+ for obj in t.objs:
-+ skip = False
-+ for r in t.deps.items():
-+ if obj in r[1]:
-+ skip = True
-+ break
-+ if not skip:
-+ objs_not_depended_on.append(obj)
-+ return objs_not_depended_on
-+
-+ non_dep_tgt_objs = find_objs_not_depended_on(t)
-+ for obj in t.objs:
-+ if obj in t.deps:
-+ deps = t.deps[obj]
-+ if '*' in deps:
-+ t.deps[obj].remove('*')
-+ t.add_deps([obj], non_dep_tgt_objs)
-+ if obj in t.callrefs:
-+ deps = t.callrefs[obj]
-+ if '*' in deps:
-+ t.deps[obj].remove('*')
-+ t.add_callrefs([obj], non_dep_tgt_objs)
-+ if "#" in t.deps:
-+ deps = t.deps["#"]
-+ if '*' in deps:
-+ t.deps["#"].remove('*')
-+ t.add_deps(["#"], non_dep_tgt_objs)
-+
-+ # If no main program was specified in dependency description, make a
-+ # default main program with deps pointing to all DSOs which are not
-+ # depended by another DSO.
-+ if t.main_program_default_deps:
-+ main_deps = non_dep_tgt_objs
-+ if not main_deps:
-+ error("no objects for default main program to point "
-+ "dependency to(all objects strongly connected?)")
-+ t.add_deps(["#"], main_deps)
-+
-+ # Some debug output
-+ if cmdlineargs.debug_output:
-+ print("Testcase: %s" % (t.test_name))
-+ print("All objects: %s" % (t.objs))
-+ print("--- Static link dependencies ---")
-+ for r in t.deps.items():
-+ print("%s -> %s" % (r[0], r[1]))
-+ print("--- Objects whose dependencies are to be permuted ---")
-+ for r in t.dep_permutations.items():
-+ print("%s" % (r[0]))
-+ print("--- Call reference dependencies ---")
-+ for r in t.callrefs.items():
-+ print("%s => %s" % (r[0], r[1]))
-+ print("--- main program ---")
-+ print(t.main_program)
-+
-+ # Main testcase generation routine, does Makefile fragment generation,
-+ # testcase source generation, and if --build specified builds testcase.
-+ def generate_testcase(test_descr, test_suffix):
-+
-+ test_name = test_descr.test_name + test_suffix
-+
-+ # Print out needed Makefile fragments for use in glibc/elf/Makefile.
-+ module_names = ""
-+ for o in test_descr.objs:
-+ module_names += " " + test_subdir + "/" + test_name + "-" + o
-+ makefile.write("modules-names +=%s\n" % (module_names))
-+
-+ # Depth-first traversal, executing FN(OBJ) in post-order
-+ def dfs(t, fn):
-+ def dfs_rec(obj, fn, obj_visited):
-+ if obj in obj_visited:
-+ return
-+ obj_visited[obj] = True
-+ if obj in t.deps:
-+ for dep in t.deps[obj]:
-+ dfs_rec(dep, fn, obj_visited)
-+ fn(obj)
-+
-+ obj_visited = {}
-+ for obj in t.objs:
-+ dfs_rec(obj, fn, obj_visited)
-+
-+ # Generate link dependencies for all DSOs, done in a DFS fashion.
-+ # Usually this doesn't need to be this complex, just listing the direct
-+ # dependencies is enough. However to support creating circular
-+ # dependency situations, traversing it by DFS and tracking processing
-+ # status is the natural way to do it.
-+ obj_processed = {}
-+ fake_created = {}
-+ def gen_link_deps(obj):
-+ if obj in test_descr.deps:
-+ dso = test_subdir + "/" + test_name + "-" + obj + ".so"
-+ dependencies = ""
-+ for dep in test_descr.deps[obj]:
-+ if dep in obj_processed:
-+ depstr = (" $(objpfx)" + test_subdir + "/"
-+ + test_name + "-" + dep + ".so")
-+ else:
-+ # A circular dependency is satisfied by making a
-+ # fake DSO tagged with the correct SONAME
-+ depstr = (" $(objpfx)" + test_subdir + "/"
-+ + test_name + "-" + dep + ".FAKE.so")
-+ # Create empty C file and Makefile fragments for fake
-+ # object. This only needs to be done at most once for
-+ # an object name.
-+ if not dep in fake_created:
-+ f = open(testpfx + test_name + "-" + dep
-+ + ".FAKE.c", "w")
-+ f.write(" \n")
-+ f.close()
-+ # Generate rule to create fake object
-+ makefile.write \
-+ ("LDFLAGS-%s = -Wl,--no-as-needed "
-+ "-Wl,-soname=%s\n"
-+ % (test_name + "-" + dep + ".FAKE.so",
-+ ("$(objpfx)" + test_subdir + "/"
-+ + test_name + "-" + dep + ".so")))
-+ makefile.write \
-+ ("modules-names += %s\n"
-+ % (test_subdir + "/"
-+ + test_name + "-" + dep + ".FAKE"))
-+ fake_created[dep] = True
-+ dependencies += depstr
-+ makefile.write("$(objpfx)%s:%s\n" % (dso, dependencies))
-+ # Mark obj as processed
-+ obj_processed[obj] = True
-+
-+ dfs(test_descr, gen_link_deps)
-+
-+ # Print LDFLAGS-* and *-no-z-defs
-+ for o in test_descr.objs:
-+ dso = test_name + "-" + o + ".so"
-+ ldflags = "-Wl,--no-as-needed"
-+ if o in test_descr.soname_map:
-+ soname = ("$(objpfx)" + test_subdir + "/"
-+ + test_name + "-"
-+ + test_descr.soname_map[o] + ".so")
-+ ldflags += (" -Wl,-soname=" + soname)
-+ makefile.write("LDFLAGS-%s = %s\n" % (dso, ldflags))
-+ if o in test_descr.callrefs:
-+ makefile.write("%s-no-z-defs = yes\n" % (dso))
-+
-+ # Print dependencies for main test program.
-+ depstr = ""
-+ if '#' in test_descr.deps:
-+ for o in test_descr.deps['#']:
-+ depstr += (" $(objpfx)" + test_subdir + "/"
-+ + test_name + "-" + o + ".so")
-+ makefile.write("$(objpfx)%s/%s:%s\n" % (test_subdir, test_name, depstr))
-+ ldflags = "-Wl,--no-as-needed"
-+ if '#' in test_descr.soname_map:
-+ soname = ("$(objpfx)" + test_subdir + "/"
-+ + test_name + "-"
-+ + test_descr.soname_map['#'] + ".so")
-+ ldflags += (" -Wl,-soname=" + soname)
-+ makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags))
-+
-+ not_depended_objs = find_objs_not_depended_on(test_descr)
-+ if not_depended_objs:
-+ depstr = ""
-+ for dep in not_depended_objs:
-+ depstr += (" $(objpfx)" + test_subdir + "/"
-+ + test_name + "-" + dep + ".so")
-+ makefile.write("$(objpfx)%s.out:%s\n" % (base_test_name, depstr))
-+
-+ # Add main executable to test-srcs
-+ makefile.write("test-srcs += %s/%s\n" % (test_subdir, test_name))
-+ # Add dependency on main executable of test
-+ makefile.write("$(objpfx)%s.out: $(objpfx)%s/%s\n"
-+ % (base_test_name, test_subdir, test_name))
-+
-+ for r in test_descr.expected_outputs.items():
-+ tunable_options = []
-+ specific_tunable = r[0]
-+ xfail = r[1][1]
-+ if specific_tunable != "":
-+ tunable_options = [specific_tunable]
-+ else:
-+ tunable_options = default_tunable_options
-+ if not tunable_options:
-+ tunable_options = [""]
-+
-+ for tunable in tunable_options:
-+ tunable_env = ""
-+ tunable_sfx = ""
-+ exp_tunable_sfx = ""
-+ if tunable:
-+ tunable_env = "GLIBC_TUNABLES=%s " % tunable
-+ tunable_sfx = "-" + tunable.replace("=","_")
-+ if specific_tunable:
-+ tunable_sfx = "-" + specific_tunable.replace("=","_")
-+ exp_tunable_sfx = tunable_sfx
-+ tunable_descr = ("(%s)" % tunable_env.strip()
-+ if tunable_env else "")
-+ # Write out fragment of shell script for this single test.
-+ test_descr.sh.write \
-+ ("%s${test_wrapper_env} ${run_program_env} \\\n"
-+ "${common_objpfx}support/test-run-command \\\n"
-+ "${common_objpfx}elf/ld.so \\\n"
-+ "--library-path ${common_objpfx}elf/%s:"
-+ "${common_objpfx}elf:${common_objpfx}.:"
-+ "${common_objpfx}dlfcn \\\n"
-+ "${common_objpfx}elf/%s/%s > \\\n"
-+ " ${common_objpfx}elf/%s/%s%s.output\n"
-+ % (tunable_env ,test_subdir,
-+ test_subdir, test_name, test_subdir, test_name,
-+ tunable_sfx))
-+ # Generate a run of each test and compare with expected out
-+ test_descr.sh.write \
-+ ("if [ $? -ne 0 ]; then\n"
-+ " echo '%sFAIL: %s%s execution test'\n"
-+ " something_failed=true\n"
-+ "else\n"
-+ " diff -wu ${common_objpfx}elf/%s/%s%s.output \\\n"
-+ " ${common_objpfx}elf/%s/%s%s.exp\n"
-+ " if [ $? -ne 0 ]; then\n"
-+ " echo '%sFAIL: %s%s expected output comparison'\n"
-+ " something_failed=true\n"
-+ " fi\n"
-+ "fi\n"
-+ % (("X" if xfail else ""), test_name, tunable_descr,
-+ test_subdir, test_name, tunable_sfx,
-+ test_subdir, base_test_name, exp_tunable_sfx,
-+ ("X" if xfail else ""), test_name, tunable_descr))
-+
-+ # Generate C files according to dependency and calling relations from
-+ # description string.
-+ for obj in test_descr.objs:
-+ src_name = test_name + "-" + obj + ".c"
-+ f = open(testpfx + src_name, "w")
-+ if obj in test_descr.callrefs:
-+ called_objs = test_descr.callrefs[obj]
-+ for callee in called_objs:
-+ f.write("extern void fn_%s (void);\n" % (callee))
-+ if len(obj) == 1:
-+ f.write("extern int putchar(int);\n")
-+ f.write("static void __attribute__((constructor)) " +
-+ "init(void){putchar('%s');putchar('>');}\n" % (obj))
-+ f.write("static void __attribute__((destructor)) " +
-+ "fini(void){putchar('<');putchar('%s');}\n" % (obj))
-+ else:
-+ f.write('extern int printf(const char *, ...);\n')
-+ f.write('static void __attribute__((constructor)) ' +
-+ 'init(void){printf("%s>");}\n' % (obj))
-+ f.write('static void __attribute__((destructor)) ' +
-+ 'fini(void){printf("<%s");}\n' % (obj))
-+ if obj in test_descr.callrefs:
-+ called_objs = test_descr.callrefs[obj]
-+ if len(obj) != 1:
-+ f.write("extern int putchar(int);\n")
-+ f.write("void fn_%s (void) {\n" % (obj))
-+ if len(obj) == 1:
-+ f.write(" putchar ('%s');\n" % (obj));
-+ f.write(" putchar ('(');\n");
-+ else:
-+ f.write(' printf ("%s(");\n' % (obj));
-+ for callee in called_objs:
-+ f.write(" fn_%s ();\n" % (callee))
-+ f.write(" putchar (')');\n");
-+ f.write("}\n")
-+ else:
-+ for callref in test_descr.callrefs.items():
-+ if obj in callref[1]:
-+ if len(obj) == 1:
-+ # We need to declare printf here in this case.
-+ f.write('extern int printf(const char *, ...);\n')
-+ f.write("void fn_%s (void) {\n" % (obj))
-+ f.write(' printf ("%s()");\n' % (obj))
-+ f.write("}\n")
-+ break
-+ f.close()
-+
-+ # Open C file for writing main program
-+ f = open(testpfx + test_name + ".c", "w")
-+
-+ # if there are some operations in main(), it means we need -ldl
-+ f.write("#include <stdio.h>\n")
-+ f.write("#include <stdlib.h>\n")
-+ f.write("#include <dlfcn.h>\n")
-+ for s in test_descr.main_program:
-+ if s[0] == '@':
-+ f.write("extern void fn_%s (void);\n" % (s[1:]));
-+ f.write("int main (void) {\n")
-+ f.write(" putchar('{');\n")
-+
-+ # Helper routine for generating sanity checking code.
-+ def put_fail_check(fail_cond, action_desc):
-+ f.write(' if (%s) { printf ("\\n%s failed: %%s\\n", '
-+ 'dlerror()); exit (1);}\n' % (fail_cond, action_desc))
-+ i = 0
-+ while i < len(test_descr.main_program):
-+ s = test_descr.main_program[i]
-+ obj = s[1:]
-+ dso = test_name + "-" + obj
-+ if s[0] == '+' or s[0] == '^':
-+ if s[0] == '+':
-+ dlopen_flags = "RTLD_LAZY|RTLD_GLOBAL"
-+ f.write(" putchar('+');\n");
-+ else:
-+ dlopen_flags = "RTLD_LAZY"
-+ f.write(" putchar(':');\n");
-+ if len(obj) == 1:
-+ f.write(" putchar('%s');\n" % (obj));
-+ else:
-+ f.write(' printf("%s");\n' % (obj));
-+ f.write(" putchar('[');\n");
-+ f.write(' void *%s = dlopen ("%s.so", %s);\n'
-+ % (obj, dso, dlopen_flags))
-+ put_fail_check("!%s" % (obj),
-+ "%s.so dlopen" % (dso))
-+ f.write(" putchar(']');\n");
-+ elif s[0] == '-':
-+ f.write(" putchar('-');\n");
-+ if len(obj) == 1:
-+ f.write(" putchar('%s');\n" % (obj));
-+ else:
-+ f.write(' printf("%s");\n' % (obj));
-+ f.write(" putchar('[');\n");
-+ put_fail_check("dlclose (%s) != 0" % (obj),
-+ "%s.so dlclose" % (dso))
-+ f.write(" putchar(']');\n");
-+ elif s[0] == '%':
-+ f.write(" putchar('%');\n");
-+ f.write(' void (*fn_%s)(void) = dlsym (%s, "fn_%s");\n'
-+ % (obj, obj, obj))
-+ put_fail_check("!fn_%s" % (obj),
-+ "dlsym(fn_%s) from %s.so" % (obj, dso))
-+ f.write(" fn_%s ();\n" % (obj))
-+ elif s[0] == '@':
-+ f.write(" putchar('@');\n");
-+ f.write(" fn_%s ();\n" % (obj))
-+ f.write(" putchar(';');\n");
-+ i += 1
-+ f.write(" putchar('}');\n")
-+ f.write(" return 0;\n")
-+ f.write("}\n")
-+ f.close()
-+
-+ # --build option processing: build generated sources using 'build_gcc'
-+ if cmdlineargs.build:
-+ # Helper routine to run a shell command, for running GCC below
-+ def run_cmd(args):
-+ cmd = str.join(' ', args)
-+ if cmdlineargs.debug_output:
-+ print(cmd)
-+ p = subprocess.Popen(args)
-+ p.wait()
-+ if p.returncode != 0:
-+ error("error running command: %s" % (cmd))
-+
-+ # Compile individual .os files
-+ for obj in test_descr.objs:
-+ src_name = test_name + "-" + obj + ".c"
-+ obj_name = test_name + "-" + obj + ".os"
-+ run_cmd([build_gcc, "-c", "-fPIC", testpfx + src_name,
-+ "-o", testpfx + obj_name])
-+
-+ obj_processed = {}
-+ fake_created = {}
-+ # Function to create <test_name>-<obj>.so
-+ def build_dso(obj):
-+ obj_name = test_name + "-" + obj + ".os"
-+ dso_name = test_name + "-" + obj + ".so"
-+ deps = []
-+ if obj in test_descr.deps:
-+ for dep in test_descr.deps[obj]:
-+ if dep in obj_processed:
-+ deps.append(dep)
-+ else:
-+ deps.append(dep + ".FAKE")
-+ if not dep in fake_created:
-+ base_name = testpfx + test_name + "-" + dep
-+ cmd = [build_gcc, "-Wl,--no-as-needed",
-+ ("-Wl,-soname=" + base_name + ".so"),
-+ "-shared", base_name + ".FAKE.c",
-+ "-o", base_name + ".FAKE.so"]
-+ run_cmd(cmd)
-+ fake_created[dep] = True
-+ dso_deps = map(lambda d: testpfx + test_name + "-" + d + ".so",
-+ deps)
-+ cmd = [build_gcc, "-shared", "-o", testpfx + dso_name,
-+ testpfx + obj_name, "-Wl,--no-as-needed"]
-+ if obj in test_descr.soname_map:
-+ soname = ("-Wl,-soname=" + testpfx + test_name + "-"
-+ + test_descr.soname_map[obj] + ".so")
-+ cmd += [soname]
-+ cmd += list(dso_deps)
-+ run_cmd(cmd)
-+ obj_processed[obj] = True
-+
-+ # Build all DSOs, this needs to be in topological dependency order,
-+ # or link will fail
-+ dfs(test_descr, build_dso)
-+
-+ # Build main program
-+ deps = []
-+ if '#' in test_descr.deps:
-+ deps = test_descr.deps['#']
-+ main_deps = map(lambda d: testpfx + test_name + "-" + d + ".so",
-+ deps)
-+ cmd = [build_gcc, "-Wl,--no-as-needed", "-o", testpfx + test_name,
-+ testpfx + test_name + ".c", "-L%s" % (os.getcwd()),
-+ "-Wl,-rpath-link=%s" % (os.getcwd())]
-+ if '#' in test_descr.soname_map:
-+ soname = ("-Wl,-soname=" + testpfx + test_name + "-"
-+ + test_descr.soname_map['#'] + ".so")
-+ cmd += [soname]
-+ cmd += list(main_deps)
-+ run_cmd(cmd)
-+
-+ # Check if we need to enumerate permutations of dependencies
-+ need_permutation_processing = False
-+ if t.dep_permutations:
-+ # Adjust dep_permutations into map of object -> dependency permutations
-+ for r in t.dep_permutations.items():
-+ obj = r[0]
-+ if obj in t.deps and len(t.deps[obj]) > 1:
-+ deps = t.deps[obj]
-+ t.dep_permutations[obj] = list(itertools.permutations (deps))
-+ need_permutation_processing = True
-+
-+ def enum_permutations(t, perm_list):
-+ test_subindex = 1
-+ curr_perms = []
-+ def enum_permutations_rec(t, perm_list):
-+ nonlocal test_subindex, curr_perms
-+ if len(perm_list) >= 1:
-+ curr = perm_list[0]
-+ obj = curr[0]
-+ perms = curr[1]
-+ if not perms:
-+ # This may be an empty list if no multiple dependencies to
-+ # permute were found, skip to next in this case
-+ enum_permutations_rec(t, perm_list[1:])
-+ else:
-+ for deps in perms:
-+ t.deps[obj] = deps
-+ permstr = "" if obj == "#" else obj + "_"
-+ permstr += str.join('', deps)
-+ curr_perms.append(permstr)
-+ enum_permutations_rec(t, perm_list[1:])
-+ curr_perms = curr_perms[0:len(curr_perms)-1]
-+ else:
-+ # t.deps is now instantiated with one dependency order
-+ # permutation(across all objects that have multiple
-+ # permutations), now process a testcase
-+ generate_testcase(t, ("_" + str (test_subindex)
-+ + "-" + str.join('-', curr_perms)))
-+ test_subindex += 1
-+ enum_permutations_rec(t, perm_list)
-+
-+ # Create *.exp files with expected outputs
-+ for r in t.expected_outputs.items():
-+ sfx = ""
-+ if r[0] != "":
-+ sfx = "-" + r[0].replace("=","_")
-+ f = open(testpfx + t.test_name + sfx + ".exp", "w")
-+ (output, xfail) = r[1]
-+ f.write('%s' % output)
-+ f.close()
-+
-+ # Create header part of top-level testcase shell script, to wrap execution
-+ # and output comparison together.
-+ t.sh = open(testpfx + t.test_name + ".sh", "w")
-+ t.sh.write("#!/bin/sh\n")
-+ t.sh.write("# Test driver for %s, generated by "
-+ "dso-ordering-test.py\n" % (t.test_name))
-+ t.sh.write("common_objpfx=$1\n")
-+ t.sh.write("test_wrapper_env=$2\n")
-+ t.sh.write("run_program_env=$3\n")
-+ t.sh.write("something_failed=false\n")
-+
-+ # Starting part of Makefile fragment
-+ makefile.write("ifeq (yes,$(build-shared))\n")
-+
-+ if need_permutation_processing:
-+ enum_permutations(t, list (t.dep_permutations.items()))
-+ else:
-+ # We have no permutations to enumerate, just process testcase normally
-+ generate_testcase(t, "")
-+
-+ # If testcase is XFAIL, indicate so
-+ if t.xfail:
-+ makefile.write("test-xfail-%s = yes\n" % t.test_name)
-+
-+ # Output end part of Makefile fragment
-+ expected_output_files = ""
-+ for r in t.expected_outputs.items():
-+ sfx = ""
-+ if r[0] != "":
-+ sfx = "-" + r[0].replace("=","_")
-+ expected_output_files += " $(objpfx)%s/%s%s.exp" % (test_subdir,
-+ t.test_name, sfx)
-+ makefile.write \
-+ ("$(objpfx)%s.out: $(objpfx)%s/%s.sh%s "
-+ "$(common-objpfx)support/test-run-command\n"
-+ % (t.test_name, test_subdir, t.test_name,
-+ expected_output_files))
-+ makefile.write("\t$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' "
-+ "'$(run-program-env)' > $@; $(evaluate-test)\n")
-+ makefile.write("ifeq ($(run-built-tests),yes)\n")
-+ if t.xtest:
-+ makefile.write("xtests-special += $(objpfx)%s.out\n" % (t.test_name))
-+ else:
-+ makefile.write("tests-special += $(objpfx)%s.out\n" % (t.test_name))
-+ makefile.write("endif\n")
-+ makefile.write("endif\n")
-+
-+ # Write ending part of shell script generation
-+ t.sh.write("if $something_failed; then\n"
-+ " exit 1\n"
-+ "else\n"
-+ " echo '%sPASS: all tests for %s succeeded'\n"
-+ " exit 0\n"
-+ "fi\n" % (("X" if t.xfail else ""),
-+ t.test_name))
-+ t.sh.close()
-+
-+# Decription file parsing
-+def parse_description_file(filename):
-+ global default_tunable_options
-+ global current_input_lineno
-+ f = open(filename)
-+ if not f:
-+ error("cannot open description file %s" % (filename))
-+ descrfile_lines = f.readlines()
-+ t = None
-+ for line in descrfile_lines:
-+ p = re.compile(r"#.*$")
-+ line = p.sub("", line) # Filter out comments
-+ line = line.strip() # Remove excess whitespace
-+ current_input_lineno += 1
-+
-+ m = re.match(r"^tunable_option:\s*(.*)$", line)
-+ if m:
-+ if m.group(1) == "":
-+ error("tunable option cannot be empty")
-+ default_tunable_options.append(m.group (1))
-+ continue
-+
-+ m = re.match(r"^clear_tunables$", line)
-+ if m:
-+ default_tunable_options = []
-+ continue
-+
-+ m = re.match(r"^([^:]+):\s*(.*)$", line)
-+ if m:
-+ lhs = m.group(1)
-+ o = re.match(r"^output(.*)$", lhs)
-+ xfail = False
-+ if not o:
-+ o = re.match(r"^xfail_output(.*)$", lhs)
-+ if o:
-+ xfail = True;
-+ if o:
-+ if not t:
-+ error("output specification without testcase description")
-+ tsstr = ""
-+ if o.group(1):
-+ ts = re.match(r"^\(([a-zA-Z0-9_.=]*)\)$", o.group (1))
-+ if not ts:
-+ error("tunable option malformed '%s'" % o.group(1))
-+ tsstr = ts.group(1)
-+ t.expected_outputs[tsstr] = (m.group(2), xfail)
-+ # Any tunable option XFAILed means entire testcase
-+ # is XFAIL/XPASS
-+ t.xfail |= xfail
-+ else:
-+ if t:
-+ # Starting a new test description, end and process
-+ # current one.
-+ process_testcase(t)
-+ t = TestDescr()
-+ x = re.match(r"^xtest\((.*)\)$", lhs)
-+ if x:
-+ t.xtest = True
-+ t.test_name = x.group(1)
-+ else:
-+ t.test_name = lhs
-+ descr_string = m.group(2)
-+ parse_description_string(t, descr_string)
-+ continue
-+ else:
-+ if line:
-+ if not t:
-+ error("no active testcase description")
-+ parse_description_string(t, line)
-+ # Process last completed test description
-+ if t:
-+ process_testcase(t)
-+
-+# Setup Makefile output to file or stdout as selected
-+if output_makefile:
-+ output_makefile_dir = os.path.dirname(output_makefile)
-+ if output_makefile_dir:
-+ os.makedirs(output_makefile_dir, exist_ok = True)
-+ makefile = open(output_makefile, "w")
-+else:
-+ makefile = open(sys.stdout.fileno (), "w")
-+
-+# Finally, the main top-level calling of above parsing routines.
-+if description_file:
-+ parse_description_file(description_file)
-+else:
-+ t = TestDescr()
-+ t.test_name = test_name
-+ parse_description_string(t, description)
-+ process_testcase(t)
-+
-+# Close Makefile fragment output
-+makefile.close()
-diff --git a/support/Depend b/support/Depend
-new file mode 100644
-index 0000000000..7e7d5dc67c
---- /dev/null
-+++ b/support/Depend
-@@ -0,0 +1 @@
-+elf
-diff --git a/support/Makefile b/support/Makefile
-index 7f03950914..984ec02dfe 100644
---- a/support/Makefile
-+++ b/support/Makefile
-@@ -257,10 +257,16 @@ others-noinstall += shell-container echo-container true-container
- others += $(LINKS_DSO_PROGRAM)
- others-noinstall += $(LINKS_DSO_PROGRAM)
-
-+others += test-run-command
-+others-static += test-run-command
-+others-noinstall += test-run-command
-+LDLIBS-test-run-command = $(libsupport)
-+
- $(objpfx)test-container : $(libsupport)
- $(objpfx)shell-container : $(libsupport)
- $(objpfx)echo-container : $(libsupport)
- $(objpfx)true-container : $(libsupport)
-+$(objpfx)test-run-command : $(libsupport) $(common-objpfx)elf/static-stubs.o
-
- tests = \
- README-testing \
-diff --git a/support/support_test_main.c b/support/support_test_main.c
-index 07e3cdd173..66a754b84f 100644
---- a/support/support_test_main.c
-+++ b/support/support_test_main.c
-@@ -228,6 +228,18 @@ run_test_function (int argc, char **argv, const struct test_config *config)
- while (wait_for_debugger)
- usleep (1000);
-
-+ if (config->run_command_mode)
-+ {
-+ /* In run-command-mode, the child process executes the command line
-+ arguments as a new program. */
-+ char **argv_ = xmalloc (sizeof (char *) * argc);
-+ memcpy (argv_, &argv[1], sizeof (char *) * (argc - 1));
-+ argv_[argc - 1] = NULL;
-+ execv (argv_[0], argv_);
-+ printf ("error: should not return here\n");
-+ exit (1);
-+ }
-+
- if (config->test_function != NULL)
- return config->test_function ();
- else if (config->test_function_argv != NULL)
-diff --git a/support/test-driver.c b/support/test-driver.c
-index b0bea46dee..1552f62c9b 100644
---- a/support/test-driver.c
-+++ b/support/test-driver.c
-@@ -116,7 +116,9 @@ main (int argc, char **argv)
- #if defined (TEST_FUNCTION) && defined (TEST_FUNCTON_ARGV)
- # error TEST_FUNCTION and TEST_FUNCTION_ARGV cannot be defined at the same time
- #endif
--#if defined (TEST_FUNCTION)
-+#ifdef RUN_COMMAND_MODE
-+ test_config.run_command_mode = 1;
-+#elif defined (TEST_FUNCTION)
- test_config.test_function = TEST_FUNCTION;
- #elif defined (TEST_FUNCTION_ARGV)
- test_config.test_function_argv = TEST_FUNCTION_ARGV;
-diff --git a/support/test-driver.h b/support/test-driver.h
-index 8d4f38275d..b44c0ff033 100644
---- a/support/test-driver.h
-+++ b/support/test-driver.h
-@@ -36,6 +36,7 @@ struct test_config
- int expected_signal; /* If non-zero, expect termination by signal. */
- char no_mallopt; /* Boolean flag to disable mallopt. */
- char no_setvbuf; /* Boolean flag to disable setvbuf. */
-+ char run_command_mode; /* Boolean flag to indicate run-command-mode. */
- const char *optstring; /* Short command line options. */
- };
-
-diff --git a/support/test-run-command.c b/support/test-run-command.c
-new file mode 100644
-index 0000000000..61560d7bfb
---- /dev/null
-+++ b/support/test-run-command.c
-@@ -0,0 +1,22 @@
-+/* Main program for test-run-command support utility.
-+ Copyright (C) 2021 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
-+ <https://www.gnu.org/licenses/>. */
-+
-+/* This is basically a configuration of test-driver.c into a general
-+ command-line program runner. */
-+#define RUN_COMMAND_MODE
-+#include <test-driver.c>
diff --git a/v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch b/v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch
deleted file mode 100644
index 8dae228961e2..000000000000
--- a/v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch
+++ /dev/null
@@ -1,569 +0,0 @@
-diff --git a/NEWS b/NEWS
-index 220d327071..b39b1e5e33 100644
---- a/NEWS
-+++ b/NEWS
-@@ -51,6 +51,15 @@ Major new features:
-
- * The ISO C2X macro _PRINTF_NAN_LEN_MAX has been added to <stdio.h>.
-
-+* A new DSO sorting algorithm has been added in the dynamic linker that uses
-+ topological sorting by depth-first search (DFS), solving performance issues
-+ of the existing sorting algorithm when encountering particular circular
-+ object dependency cases.
-+
-+* A new tunable, glibc.rtld.dynamic_sort, can be used to select between the two
-+ DSO sorting algorithms. The default setting of '1' uses the current existing
-+ algorithm, while a value of '2' selects the new DFS-based algorithm.
-+
- Deprecated and removed features, and other changes affecting compatibility:
-
- * The r_version update in the debugger interface makes the glibc binary
-diff --git a/elf/dl-close.c b/elf/dl-close.c
-index cfe0f1c0c9..4f5cfcc1c3 100644
---- a/elf/dl-close.c
-+++ b/elf/dl-close.c
-@@ -167,8 +167,6 @@ _dl_close_worker (struct link_map *map, bool force)
-
- bool any_tls = false;
- const unsigned int nloaded = ns->_ns_nloaded;
-- char used[nloaded];
-- char done[nloaded];
- struct link_map *maps[nloaded];
-
- /* Run over the list and assign indexes to the link maps and enter
-@@ -176,24 +174,21 @@ _dl_close_worker (struct link_map *map, bool force)
- int idx = 0;
- for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next)
- {
-+ l->l_map_used = 0;
-+ l->l_map_done = 0;
- l->l_idx = idx;
- maps[idx] = l;
- ++idx;
--
- }
- assert (idx == nloaded);
-
-- /* Prepare the bitmaps. */
-- memset (used, '\0', sizeof (used));
-- memset (done, '\0', sizeof (done));
--
- /* Keep track of the lowest index link map we have covered already. */
- int done_index = -1;
- while (++done_index < nloaded)
- {
- struct link_map *l = maps[done_index];
-
-- if (done[done_index])
-+ if (l->l_map_done)
- /* Already handled. */
- continue;
-
-@@ -204,12 +199,12 @@ _dl_close_worker (struct link_map *map, bool force)
- /* 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
-- && !used[done_index])
-+ && !l->l_map_used)
- continue;
-
- /* We need this object and we handle it now. */
-- done[done_index] = 1;
-- used[done_index] = 1;
-+ l->l_map_used = 1;
-+ l->l_map_done = 1;
- /* Signal the object is still needed. */
- l->l_idx = IDX_STILL_USED;
-
-@@ -225,9 +220,9 @@ _dl_close_worker (struct link_map *map, bool force)
- {
- assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded);
-
-- if (!used[(*lp)->l_idx])
-+ if (!(*lp)->l_map_used)
- {
-- used[(*lp)->l_idx] = 1;
-+ (*lp)->l_map_used = 1;
- /* If we marked a new object as used, and we've
- already processed it, then we need to go back
- and process again from that point forward to
-@@ -250,9 +245,9 @@ _dl_close_worker (struct link_map *map, bool force)
- {
- assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded);
-
-- if (!used[jmap->l_idx])
-+ if (!jmap->l_map_used)
- {
-- used[jmap->l_idx] = 1;
-+ jmap->l_map_used = 1;
- if (jmap->l_idx - 1 < done_index)
- done_index = jmap->l_idx - 1;
- }
-@@ -262,8 +257,7 @@ _dl_close_worker (struct link_map *map, bool force)
-
- /* Sort the entries. We can skip looking for the binary itself which is
- at the front of the search list for the main namespace. */
-- _dl_sort_maps (maps + (nsid == LM_ID_BASE), nloaded - (nsid == LM_ID_BASE),
-- used + (nsid == LM_ID_BASE), true);
-+ _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
-
- /* Call all termination functions at once. */
- #ifdef SHARED
-@@ -280,7 +274,7 @@ _dl_close_worker (struct link_map *map, bool force)
- /* All elements must be in the same namespace. */
- assert (imap->l_ns == nsid);
-
-- if (!used[i])
-+ if (!imap->l_map_used)
- {
- assert (imap->l_type == lt_loaded && !imap->l_nodelete_active);
-
-@@ -333,7 +327,7 @@ _dl_close_worker (struct link_map *map, bool force)
- if (i < first_loaded)
- first_loaded = i;
- }
-- /* Else used[i]. */
-+ /* Else imap->l_map_used. */
- else if (imap->l_type == lt_loaded)
- {
- struct r_scope_elem *new_list = NULL;
-@@ -560,7 +554,7 @@ _dl_close_worker (struct link_map *map, bool force)
- for (unsigned int i = first_loaded; i < nloaded; ++i)
- {
- struct link_map *imap = maps[i];
-- if (!used[i])
-+ if (!imap->l_map_used)
- {
- assert (imap->l_type == lt_loaded);
-
-diff --git a/elf/dl-deps.c b/elf/dl-deps.c
-index 087a49b212..237d9636c5 100644
---- a/elf/dl-deps.c
-+++ b/elf/dl-deps.c
-@@ -613,10 +613,9 @@ Filters not supported with LD_TRACE_PRELINKING"));
-
- /* If libc.so.6 is the main map, it participates in the sort, so
- that the relocation order is correct regarding libc.so.6. */
-- if (l_initfini[0] == GL (dl_ns)[l_initfini[0]->l_ns].libc_map)
-- _dl_sort_maps (l_initfini, nlist, NULL, false);
-- else
-- _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
-+ _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;
-diff --git a/elf/dl-fini.c b/elf/dl-fini.c
-index 6dbdfe4b3e..c683884c35 100644
---- a/elf/dl-fini.c
-+++ b/elf/dl-fini.c
-@@ -92,8 +92,7 @@ _dl_fini (void)
- /* Now we have to do the sorting. We can skip looking for the
- binary itself which is at the front of the search list for
- the main namespace. */
-- _dl_sort_maps (maps + (ns == LM_ID_BASE), nmaps - (ns == LM_ID_BASE),
-- NULL, true);
-+ _dl_sort_maps (maps, nmaps, (ns == LM_ID_BASE), true);
-
- /* We do not rely on the linked list of loaded object anymore
- from this point on. We have our own list here (maps). The
-diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
-index d21770267a..a274ed66cc 100644
---- a/elf/dl-sort-maps.c
-+++ b/elf/dl-sort-maps.c
-@@ -16,16 +16,24 @@
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-+#include <assert.h>
- #include <ldsodefs.h>
-+#include <elf/dl-tunables.h>
-
-+/* Note: this is the older, "original" sorting algorithm, being used as
-+ default up to 2.35.
-
--/* Sort array MAPS according to dependencies of the contained objects.
-- Array USED, if non-NULL, is permutated along MAPS. If FOR_FINI this is
-- called for finishing an object. */
--void
--_dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
-- bool for_fini)
-+ Sort array MAPS according to dependencies of the contained objects.
-+ If FOR_FINI is true, this is called for finishing an object. */
-+static void
-+_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
-+ unsigned int skip, bool for_fini)
- {
-+ /* Allows caller to do the common optimization of skipping the first map,
-+ usually the main binary. */
-+ maps += skip;
-+ nmaps -= skip;
-+
- /* A list of one element need not be sorted. */
- if (nmaps <= 1)
- return;
-@@ -66,14 +74,6 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
- (k - i) * sizeof (maps[0]));
- maps[k] = thisp;
-
-- if (used != NULL)
-- {
-- char here_used = used[i];
-- memmove (&used[i], &used[i + 1],
-- (k - i) * sizeof (used[0]));
-- used[k] = here_used;
-- }
--
- if (seen[i + 1] > nmaps - i)
- {
- ++i;
-@@ -120,3 +120,183 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
- next:;
- }
- }
-+
-+#if !HAVE_TUNABLES
-+/* In this case, just default to the original algorithm. */
-+strong_alias (_dl_sort_maps_original, _dl_sort_maps);
-+#else
-+
-+/* We use a recursive function due to its better clarity and ease of
-+ implementation, as well as faster execution speed. We already use
-+ alloca() for list allocation during the breadth-first search of
-+ dependencies in _dl_map_object_deps(), and this should be on the
-+ same order of worst-case stack usage.
-+
-+ Note: the '*rpo' parameter is supposed to point to one past the
-+ last element of the array where we save the sort results, and is
-+ decremented before storing the current map at each level. */
-+
-+static void
-+dfs_traversal (struct link_map ***rpo, struct link_map *map,
-+ bool *do_reldeps)
-+{
-+ if (map->l_visited)
-+ return;
-+
-+ map->l_visited = 1;
-+
-+ if (map->l_initfini)
-+ {
-+ for (int i = 0; map->l_initfini[i] != NULL; i++)
-+ {
-+ struct link_map *dep = map->l_initfini[i];
-+ if (dep->l_visited == 0
-+ && dep->l_main_map == 0)
-+ dfs_traversal (rpo, dep, do_reldeps);
-+ }
-+ }
-+
-+ if (__glibc_unlikely (do_reldeps != NULL && map->l_reldeps != NULL))
-+ {
-+ /* Indicate that we encountered relocation dependencies during
-+ traversal. */
-+ *do_reldeps = true;
-+
-+ for (int m = map->l_reldeps->act - 1; m >= 0; m--)
-+ {
-+ struct link_map *dep = map->l_reldeps->list[m];
-+ if (dep->l_visited == 0
-+ && dep->l_main_map == 0)
-+ dfs_traversal (rpo, dep, do_reldeps);
-+ }
-+ }
-+
-+ *rpo -= 1;
-+ **rpo = map;
-+}
-+
-+/* Topologically sort array MAPS according to dependencies of the contained
-+ objects. */
-+
-+static void
-+_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
-+ unsigned int skip __attribute__ ((unused)), bool for_fini)
-+{
-+ for (int i = nmaps - 1; i >= 0; i--)
-+ maps[i]->l_visited = 0;
-+
-+ /* We apply DFS traversal for each of maps[i] until the whole total order
-+ is found and we're at the start of the Reverse-Postorder (RPO) sequence,
-+ which is a topological sort.
-+
-+ We go from maps[nmaps - 1] backwards towards maps[0] at this level.
-+ Due to the breadth-first search (BFS) ordering we receive, going
-+ backwards usually gives a more shallow depth-first recursion depth,
-+ adding more stack usage safety. Also, combined with the natural
-+ processing order of l_initfini[] at each node during DFS, this maintains
-+ an ordering closer to the original link ordering in the sorting results
-+ under most simpler cases.
-+
-+ Another reason we order the top level backwards, it that maps[0] is
-+ usually exactly the main object of which we're in the midst of
-+ _dl_map_object_deps() processing, and maps[0]->l_initfini[] is still
-+ blank. If we start the traversal from maps[0], since having no
-+ dependencies yet filled in, maps[0] will always be immediately
-+ incorrectly placed at the last place in the order (first in reverse).
-+ Adjusting the order so that maps[0] is last traversed naturally avoids
-+ this problem.
-+
-+ Further, the old "optimization" of skipping the main object at maps[0]
-+ from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general
-+ no longer valid, since traversing along object dependency-links
-+ may "find" the main object even when it is not included in the initial
-+ order (e.g. a dlopen()'ed shared object can have circular dependencies
-+ linked back to itself). In such a case, traversing N-1 objects will
-+ create a N-object result, and raise problems.
-+
-+ To summarize, just passing in the full list, and iterating from back
-+ to front makes things much more straightforward. */
-+
-+ /* Array to hold RPO sorting results, before we copy back to maps[]. */
-+ struct link_map *rpo[nmaps];
-+
-+ /* The 'head' position during each DFS iteration. Note that we start at
-+ one past the last element due to first-decrement-then-store (see the
-+ bottom of above dfs_traversal() routine). */
-+ struct link_map **rpo_head = &rpo[nmaps];
-+
-+ bool do_reldeps = false;
-+ bool *do_reldeps_ref = (for_fini ? &do_reldeps : NULL);
-+
-+ for (int i = nmaps - 1; i >= 0; i--)
-+ {
-+ dfs_traversal (&rpo_head, maps[i], do_reldeps_ref);
-+
-+ /* We can break early if all objects are already placed. */
-+ if (rpo_head == rpo)
-+ goto end;
-+ }
-+ assert (rpo_head == rpo);
-+
-+ end:
-+ /* Here we may do a second pass of sorting, using only l_initfini[]
-+ static dependency links. This is avoided if !FOR_FINI or if we didn't
-+ find any reldeps in the first DFS traversal.
-+
-+ The reason we do this is: while it is unspecified how circular
-+ dependencies should be handled, the presumed reasonable behavior is to
-+ have destructors to respect static dependency links as much as possible,
-+ overriding reldeps if needed. And the first sorting pass, which takes
-+ l_initfini/l_reldeps links equally, may not preserve this priority.
-+
-+ Hence we do a 2nd sorting pass, taking only DT_NEEDED links into account
-+ (see how the do_reldeps argument to dfs_traversal() is NULL below). */
-+ if (do_reldeps)
-+ {
-+ for (int i = nmaps - 1; i >= 0; i--)
-+ rpo[i]->l_visited = 0;
-+
-+ struct link_map **maps_head = &maps[nmaps];
-+ for (int i = nmaps - 1; i >= 0; i--)
-+ {
-+ dfs_traversal (&maps_head, rpo[i], NULL);
-+
-+ /* We can break early if all objects are already placed.
-+ The below memcpy is not needed in the do_reldeps case here,
-+ since we wrote back to maps[] during DFS traversal. */
-+ if (maps_head == maps)
-+ return;
-+ }
-+ assert (maps_head == maps);
-+ return;
-+ }
-+
-+ memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
-+}
-+
-+void
-+_dl_sort_maps_init (void)
-+{
-+ int32_t algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, NULL);
-+ GLRO(dl_dso_sort_algo) = algorithm == 1 ? dso_sort_algorithm_original
-+ : dso_sort_algorithm_dfs;
-+}
-+
-+void
-+_dl_sort_maps (struct link_map **maps, unsigned int nmaps,
-+ unsigned int skip, bool for_fini)
-+{
-+ /* It can be tempting to use a static function pointer to store and call
-+ the current selected sorting algorithm routine, but experimentation
-+ shows that current processors still do not handle indirect branches
-+ that efficiently, plus a static function pointer will involve
-+ PTR_MANGLE/DEMANGLE, further impairing performance of small, common
-+ input cases. A simple if-case with direct function calls appears to
-+ be the fastest. */
-+ if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original))
-+ _dl_sort_maps_original (maps, nmaps, skip, for_fini);
-+ else
-+ _dl_sort_maps_dfs (maps, nmaps, skip, for_fini);
-+}
-+
-+#endif /* HAVE_TUNABLES. */
-diff --git a/elf/dl-support.c b/elf/dl-support.c
-index d99c1f1d62..98d5d8db5c 100644
---- a/elf/dl-support.c
-+++ b/elf/dl-support.c
-@@ -166,6 +166,8 @@ size_t _dl_phnum;
- uint64_t _dl_hwcap;
- uint64_t _dl_hwcap2;
-
-+enum dso_sort_algorithm _dl_dso_sort_algo;
-+
- /* The value of the FPU control word the kernel will preset in hardware. */
- fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
-
-diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
-index 2c684c2db2..4dc366eea4 100644
---- a/elf/dl-sysdep.c
-+++ b/elf/dl-sysdep.c
-@@ -231,6 +231,9 @@ _dl_sysdep_start (void **start_argptr,
-
- __tunables_init (_environ);
-
-+ /* Initialize DSO sorting algorithm after tunables. */
-+ _dl_sort_maps_init ();
-+
- #ifdef DL_SYSDEP_INIT
- DL_SYSDEP_INIT;
- #endif
-diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
-index 8ddd4a2314..46ffb23784 100644
---- a/elf/dl-tunables.list
-+++ b/elf/dl-tunables.list
-@@ -156,4 +156,13 @@ glibc {
- security_level: SXID_IGNORE
- }
- }
-+
-+ rtld {
-+ dynamic_sort {
-+ type: INT_32
-+ minval: 1
-+ maxval: 2
-+ default: 1
-+ }
-+ }
- }
-diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
-index 873ddf55d9..5f7f18ef27 100644
---- a/elf/dso-sort-tests-1.def
-+++ b/elf/dso-sort-tests-1.def
-@@ -62,5 +62,5 @@ output: b>a>{}<a<b
- # The below expected outputs are what the two algorithms currently produce
- # respectively, for regression testing purposes.
- tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
--xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
-+output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
- output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
-diff --git a/elf/rtld.c b/elf/rtld.c
-index b8ba2d8836..be2d5d8e74 100644
---- a/elf/rtld.c
-+++ b/elf/rtld.c
-@@ -1391,6 +1391,9 @@ dl_main (const ElfW(Phdr) *phdr,
- main_map->l_name = (char *) "";
- *user_entry = main_map->l_entry;
-
-+ /* Set bit indicating this is the main program map. */
-+ main_map->l_main_map = 1;
-+
- #ifdef HAVE_AUX_VECTOR
- /* Adjust the on-stack auxiliary vector so that it looks like the
- binary was executed directly. */
-diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
-index 9f66c52885..9bf572715f 100644
---- a/elf/tst-rtld-list-tunables.exp
-+++ b/elf/tst-rtld-list-tunables.exp
-@@ -10,5 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
- glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
- glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+)
- glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
-+glibc.rtld.dynamic_sort: 1 (min: 1, max: 2)
- glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
- glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
-diff --git a/include/link.h b/include/link.h
-index 484ee6cb1b..c1c382ccfa 100644
---- a/include/link.h
-+++ b/include/link.h
-@@ -181,6 +181,11 @@ struct link_map
- unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
- unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
- unsigned int l_reserved:2; /* Reserved for internal use. */
-+ unsigned int l_main_map:1; /* Nonzero for the map of the main program. */
-+ unsigned int l_visited:1; /* Used internally for map dependency
-+ graph traversal. */
-+ unsigned int l_map_used:1; /* These two bits are used during traversal */
-+ unsigned int l_map_done:1; /* of maps in _dl_close_worker. */
- unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
- to by `l_phdr' is allocated. */
- unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in
-diff --git a/manual/tunables.texi b/manual/tunables.texi
-index 658547c613..10f4d75993 100644
---- a/manual/tunables.texi
-+++ b/manual/tunables.texi
-@@ -309,6 +309,17 @@ changed once allocated at process startup. The default allocation of
- optional static TLS is 512 bytes and is allocated in every thread.
- @end deftp
-
-+@deftp Tunable glibc.rtld.dynamic_sort
-+Sets the algorithm to use for DSO sorting, valid values are @samp{1} and
-+@samp{2}. For value of @samp{1}, an older O(n^3) algorithm is used, which is
-+long time tested, but may have performance issues when dependencies between
-+shared objects contain cycles due to circular dependencies. When set to the
-+value of @samp{2}, a different algorithm is used, which implements a
-+topological sort through depth-first search, and does not exhibit the
-+performance issues of @samp{1}.
-+
-+The default value of this tunable is @samp{1}.
-+@end deftp
-
- @node Elision Tunables
- @section Elision Tunables
-diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
-index 0410f777a6..65a6a51633 100644
---- a/sysdeps/generic/ldsodefs.h
-+++ b/sysdeps/generic/ldsodefs.h
-@@ -245,6 +245,13 @@ enum allowmask
- };
-
-
-+/* DSO sort algorithm to use (check dl-sort-maps.c). */
-+enum dso_sort_algorithm
-+ {
-+ dso_sort_algorithm_original,
-+ dso_sort_algorithm_dfs
-+ };
-+
- struct audit_ifaces
- {
- void (*activity) (uintptr_t *, unsigned int);
-@@ -678,6 +685,8 @@ struct rtld_global_ro
- platforms. */
- EXTERN uint64_t _dl_hwcap2;
-
-+ EXTERN enum dso_sort_algorithm _dl_dso_sort_algo;
-+
- #ifdef SHARED
- /* We add a function table to _rtld_global which is then used to
- call the function instead of going through the PLT. The result
-@@ -1104,7 +1113,7 @@ extern void _dl_fini (void) attribute_hidden;
-
- /* Sort array MAPS according to dependencies of the contained objects. */
- extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
-- char *used, bool for_fini) attribute_hidden;
-+ unsigned int skip, bool for_fini) attribute_hidden;
-
- /* The dynamic linker calls this function before and having changing
- any shared object mappings. The `r_state' member of `struct r_debug'
-@@ -1235,6 +1244,9 @@ extern struct link_map * _dl_get_dl_main_map (void)
- # endif
- #endif
-
-+/* Initialize the DSO sort algorithm to use. */
-+extern void _dl_sort_maps_init (void) attribute_hidden;
-+
- /* Initialization of libpthread for statically linked applications.
- If libpthread is not linked in, this is an empty function. */
- void __pthread_initialize_minimal (void) weak_function;