public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v12 0/4] Multiple rtld-audit fixes
@ 2022-01-25 18:36 Adhemerval Zanella
  2022-01-25 18:36 ` [PATCH v12 1/4] elf: Add la_activity during application exit Adhemerval Zanella
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2022-01-25 18:36 UTC (permalink / raw)
  To: libc-alpha, jma14, Carlos O'Donell; +Cc: John Mellor-Crummey, Ben Woodard

This patches fixes some of remaining issues brought by John
Mellor-Crummey [1] while trying to use it along with the HPCToolkit.
This should cover all the issues listed as 'Tier 1' [2] (the aarch64
SVE requires additional work, so it is postpone to 2.36) and also
most of the 'Tier2' issue (BZ#28096 inclusive) which prevents the use
of some glibc function that uses TLS internally on the audit module.

I have checked the patches on x86_64, i686, aarch64, armv7, powerpc64,
powerpc64le, and powerpc.

[1] https://sourceware.org/pipermail/libc-alpha/2021-June/127636.html
[2] https://docs.google.com/document/d/1dVaDBdzySecxQqD6hLLzDrEF18M1UtjDna9gL5BWWI0/edit#
[3] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/ld-audit-fixes

Changes from v11:
  - Fixed tst-audit23.

Changes from v10:
  - Removed l_auditing usage on initial-exec TLS access fix.
  - Fixed aarch64 comments about the _dl_runtime_profile stack layout.
  - Added some more argumet checking on some tests.
  - Fixed copyright years.

Changes from v9:
  - Fixed aarch64 comments about the _dl_runtime_profile stack layout.
  - Rebased against master.

Changes from v8:
  - Improved la_activity test coverage.
  - Fixed BZ#28096 regression.

Changes from v7:
  - Added la_activity tests during application exit.
  - Refactor _dl_allocate_tls_init to not initialize static TLS.
  - Changed sotruss to warn instead of error for bind-now.
  - Added NEWS and changed commit message for aarch64.

Changes from v6:
  - Dropped SVE, main application on main_map l_name, and Run
    constructors if executable has a soname of a dependency patches.
  - Bumped LAV_VERSION to 2 on la_symbind bind-now support.
  - Added extension pointer on aarch64 fix.
  - Moved the refactor patch at the start of the set.
  - Changed _dl_audit_objsearch interface.

Changes from v5:
  - Fixed build with --enable-profiling=yes.
  - Moved la_activity (LA_ACT_ADD) *after* _dl_add_to_namespace_list()
    for BZ#28062 fix.
  - Fixed powerpc64 ELFv1 OPD toc setup for bind-now.
  - Fixed testsuite issues for ia64.
  - Removed LA_SYMB_BINDNOW now that LA_SYMB_NOPLTENTER and
    LA_SYMB_NOPLTEXIT is passed for bind-now.

Changes from v4:
  - Added a fix for constructors if executable has a soname of a
    dependency
  - Rebased against master.

Changes from v3
  - Added a aarch64 SVE RFC patch.
  - Fixed an issue with bind-now fix on powerpc64 ELFv1.
  - Rebased against master.

Changes from v2
  - Refactored rtld-audit code to move common come to dl-audit.c.
  - Issue audit la_objopen() for vDSO.
  - Isseu la_activity during application exit.
  - Issue la_symbind() for bind-now (BZ #23734).
  - Fix runtime linker auditing on aarch64 (BZ #26643)

Changes from v1
  - Fixed -fstack-protector-all tst-auditmod17.
  - Simplify the _dl_call_libc_early_init call the 'Fix audit
    regression' patch.
  - Remove symbind check fr BZ#15333.
  - Added the BZ#28096 fix.

--

Adhemerval Zanella (3):
  elf: Add la_activity during application exit
  elf: Fix initial-exec TLS access on audit modules (BZ #28096)
  elf: Issue la_symbind for bind-now (BZ #23734)

Ben Woodard (1):
  elf: Fix runtime linker auditing on aarch64 (BZ #26643)

 NEWS                             |   8 ++
 bits/link_lavcurrent.h           |   2 +-
 elf/Makefile                     | 104 +++++++++++++-
 elf/dl-audit.c                   |  58 +++++---
 elf/dl-fini.c                    |   8 ++
 elf/dl-tls.c                     |  13 +-
 elf/do-rel.h                     |  57 ++++++--
 elf/rtld.c                       |   5 +-
 elf/sotruss-lib.c                |   7 +
 elf/tst-audit21.c                |  42 ++++++
 elf/tst-audit23.c                | 239 +++++++++++++++++++++++++++++++
 elf/tst-audit23mod.c             |  23 +++
 elf/tst-audit24a.c               |  36 +++++
 elf/tst-audit24amod1.c           |  31 ++++
 elf/tst-audit24amod2.c           |  25 ++++
 elf/tst-audit24b.c               |  37 +++++
 elf/tst-audit24bmod1.c           |  31 ++++
 elf/tst-audit24bmod2.c           |  23 +++
 elf/tst-audit24c.c               |   2 +
 elf/tst-audit24d.c               |  36 +++++
 elf/tst-audit24dmod1.c           |  33 +++++
 elf/tst-audit24dmod2.c           |  28 ++++
 elf/tst-audit24dmod3.c           |  31 ++++
 elf/tst-audit24dmod4.c           |  25 ++++
 elf/tst-audit25a.c               | 129 +++++++++++++++++
 elf/tst-audit25b.c               | 128 +++++++++++++++++
 elf/tst-audit25mod1.c            |  30 ++++
 elf/tst-audit25mod2.c            |  30 ++++
 elf/tst-audit25mod3.c            |  22 +++
 elf/tst-audit25mod4.c            |  22 +++
 elf/tst-auditmod21a.c            |  80 +++++++++++
 elf/tst-auditmod21b.c            |  22 +++
 elf/tst-auditmod23.c             |  74 ++++++++++
 elf/tst-auditmod24.h             |  29 ++++
 elf/tst-auditmod24a.c            | 114 +++++++++++++++
 elf/tst-auditmod24b.c            | 104 ++++++++++++++
 elf/tst-auditmod24c.c            |   3 +
 elf/tst-auditmod24d.c            | 120 ++++++++++++++++
 elf/tst-auditmod25.c             |  79 ++++++++++
 nptl/allocatestack.c             |   2 +-
 sysdeps/aarch64/Makefile         |  20 +++
 sysdeps/aarch64/bits/link.h      |  26 ++--
 sysdeps/aarch64/dl-audit-check.h |  28 ++++
 sysdeps/aarch64/dl-link.sym      |   6 +-
 sysdeps/aarch64/dl-trampoline.S  |  81 +++++++----
 sysdeps/aarch64/tst-audit26.c    |  37 +++++
 sysdeps/aarch64/tst-audit26mod.c |  33 +++++
 sysdeps/aarch64/tst-audit26mod.h |  50 +++++++
 sysdeps/aarch64/tst-audit27.c    |  64 +++++++++
 sysdeps/aarch64/tst-audit27mod.c |  95 ++++++++++++
 sysdeps/aarch64/tst-audit27mod.h |  67 +++++++++
 sysdeps/aarch64/tst-auditmod26.c | 103 +++++++++++++
 sysdeps/aarch64/tst-auditmod27.c | 180 +++++++++++++++++++++++
 sysdeps/generic/dl-audit-check.h |  23 +++
 sysdeps/generic/dl-lookupcfg.h   |   3 +
 sysdeps/generic/ldsodefs.h       |   7 +-
 sysdeps/hppa/dl-lookupcfg.h      |   3 +
 sysdeps/ia64/dl-lookupcfg.h      |   3 +
 sysdeps/powerpc/dl-lookupcfg.h   |  39 +++++
 59 files changed, 2674 insertions(+), 86 deletions(-)
 create mode 100644 elf/tst-audit21.c
 create mode 100644 elf/tst-audit23.c
 create mode 100644 elf/tst-audit23mod.c
 create mode 100644 elf/tst-audit24a.c
 create mode 100644 elf/tst-audit24amod1.c
 create mode 100644 elf/tst-audit24amod2.c
 create mode 100644 elf/tst-audit24b.c
 create mode 100644 elf/tst-audit24bmod1.c
 create mode 100644 elf/tst-audit24bmod2.c
 create mode 100644 elf/tst-audit24c.c
 create mode 100644 elf/tst-audit24d.c
 create mode 100644 elf/tst-audit24dmod1.c
 create mode 100644 elf/tst-audit24dmod2.c
 create mode 100644 elf/tst-audit24dmod3.c
 create mode 100644 elf/tst-audit24dmod4.c
 create mode 100644 elf/tst-audit25a.c
 create mode 100644 elf/tst-audit25b.c
 create mode 100644 elf/tst-audit25mod1.c
 create mode 100644 elf/tst-audit25mod2.c
 create mode 100644 elf/tst-audit25mod3.c
 create mode 100644 elf/tst-audit25mod4.c
 create mode 100644 elf/tst-auditmod21a.c
 create mode 100644 elf/tst-auditmod21b.c
 create mode 100644 elf/tst-auditmod23.c
 create mode 100644 elf/tst-auditmod24.h
 create mode 100644 elf/tst-auditmod24a.c
 create mode 100644 elf/tst-auditmod24b.c
 create mode 100644 elf/tst-auditmod24c.c
 create mode 100644 elf/tst-auditmod24d.c
 create mode 100644 elf/tst-auditmod25.c
 create mode 100644 sysdeps/aarch64/dl-audit-check.h
 create mode 100644 sysdeps/aarch64/tst-audit26.c
 create mode 100644 sysdeps/aarch64/tst-audit26mod.c
 create mode 100644 sysdeps/aarch64/tst-audit26mod.h
 create mode 100644 sysdeps/aarch64/tst-audit27.c
 create mode 100644 sysdeps/aarch64/tst-audit27mod.c
 create mode 100644 sysdeps/aarch64/tst-audit27mod.h
 create mode 100644 sysdeps/aarch64/tst-auditmod26.c
 create mode 100644 sysdeps/aarch64/tst-auditmod27.c
 create mode 100644 sysdeps/generic/dl-audit-check.h
 create mode 100644 sysdeps/powerpc/dl-lookupcfg.h

-- 
2.32.0


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v12 1/4] elf: Add la_activity during application exit
  2022-01-25 18:36 [PATCH v12 0/4] Multiple rtld-audit fixes Adhemerval Zanella
@ 2022-01-25 18:36 ` Adhemerval Zanella
  2022-01-26 11:42   ` Florian Weimer
  2022-02-01  4:21   ` Carlos O'Donell
  2022-01-25 18:36 ` [PATCH v12 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Adhemerval Zanella
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2022-01-25 18:36 UTC (permalink / raw)
  To: libc-alpha, jma14, Carlos O'Donell; +Cc: John Mellor-Crummey, Ben Woodard

la_activity is not called during application exit, even though
la_objclose is.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
---
 elf/Makefile         |   7 ++
 elf/dl-fini.c        |   8 ++
 elf/tst-audit23.c    | 239 +++++++++++++++++++++++++++++++++++++++++++
 elf/tst-audit23mod.c |  23 +++++
 elf/tst-auditmod23.c |  74 ++++++++++++++
 5 files changed, 351 insertions(+)
 create mode 100644 elf/tst-audit23.c
 create mode 100644 elf/tst-audit23mod.c
 create mode 100644 elf/tst-auditmod23.c

diff --git a/elf/Makefile b/elf/Makefile
index 41e0f2e8c4..a3b4468593 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -377,6 +377,7 @@ tests += \
   tst-audit19b \
   tst-audit20 \
   tst-audit22 \
+  tst-audit23 \
   tst-auditmany \
   tst-auxobj \
   tst-auxobj-dlopen \
@@ -673,6 +674,7 @@ modules-names = \
   tst-audit13mod1 \
   tst-audit18mod \
   tst-audit19bmod \
+  tst-audit23mod \
   tst-auditlogmod-1 \
   tst-auditlogmod-2 \
   tst-auditlogmod-3 \
@@ -695,6 +697,7 @@ modules-names = \
   tst-auditmod19b \
   tst-auditmod20 \
   tst-auditmod22 \
+  tst-auditmod23 \
   tst-auxvalmod \
   tst-big-note-lib \
   tst-deep1mod1 \
@@ -2136,6 +2139,10 @@ tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
 $(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
 tst-audit22-ARGS = -- $(host-test-program-cmd)
 
+$(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
+			  $(objpfx)tst-audit23mod.so
+tst-audit23-ARGS = -- $(host-test-program-cmd)
+
 # tst-sonamemove links against an older implementation of the library.
 LDFLAGS-tst-sonamemove-linkmod1.so = \
   -Wl,--version-script=tst-sonamemove-linkmod1.map \
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index de8eb1b3c9..030b1fcbcd 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -64,6 +64,10 @@ _dl_fini (void)
 	__rtld_lock_unlock_recursive (GL(dl_load_lock));
       else
 	{
+#ifdef SHARED
+	  _dl_audit_activity_nsid (ns, LA_ACT_DELETE);
+#endif
+
 	  /* Now we can allocate an array to hold all the pointers and
 	     copy the pointers in.  */
 	  struct link_map *maps[nloaded];
@@ -153,6 +157,10 @@ _dl_fini (void)
 	      /* Correct the previous increment.  */
 	      --l->l_direct_opencount;
 	    }
+
+#ifdef SHARED
+	  _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
+#endif
 	}
     }
 
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
new file mode 100644
index 0000000000..3eea322051
--- /dev/null
+++ b/elf/tst-audit23.c
@@ -0,0 +1,239 @@
+/* Check DT_AUDIT la_objopen and la_objclose for all objects.
+   Copyright (C) 2022 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/>.  */
+
+#include <array_length.h>
+#include <errno.h>
+#include <getopt.h>
+#include <link.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <gnu/lib-names.h>
+#include <string.h>
+#include <stdlib.h>
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/xstdio.h>
+#include <support/xdlfcn.h>
+#include <support/support.h>
+
+static int restart;
+#define CMDLINE_OPTIONS \
+  { "restart", no_argument, &restart, 1 },
+
+static int
+handle_restart (void)
+{
+  xdlopen ("tst-audit23mod.so", RTLD_NOW);
+  xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
+
+  return 0;
+}
+
+static inline bool
+startswith (const char *str, const char *pre)
+{
+  size_t lenpre = strlen (pre);
+  size_t lenstr = strlen (str);
+  return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
+}
+
+static inline bool
+is_vdso (const char *str)
+{
+  return startswith (str, "linux-gate")
+	 || startswith (str, "linux-vdso");
+}
+
+static int
+do_test (int argc, char *argv[])
+{
+  /* We must have either:
+     - One our fource parameters left if called initially:
+       + path to ld.so         optional
+       + "--library-path"      optional
+       + the library path      optional
+       + the application name  */
+  if (restart)
+    return handle_restart ();
+
+  char *spargv[9];
+  int i = 0;
+  for (; i < argc - 1; i++)
+    spargv[i] = argv[i + 1];
+  spargv[i++] = (char *) "--direct";
+  spargv[i++] = (char *) "--restart";
+  spargv[i] = NULL;
+  TEST_VERIFY_EXIT (i < array_length (spargv));
+
+  setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
+  struct support_capture_subprocess result
+    = support_capture_subprogram (spargv[0], spargv);
+  support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
+
+  /* The expected la_objopen/la_objclose:
+     1. executable
+     2. loader
+     3. libc.so
+     4. tst-audit23mod.so
+     5. libc.so (LM_ID_NEWLM).
+     6. vdso (optional and ignored).  */
+  enum { max_objs = 6 };
+  struct la_obj_t
+  {
+    char *lname;
+    uintptr_t laddr;
+    Lmid_t lmid;
+    bool closed;
+  } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
+  size_t nobjs = 0;
+
+  /* The expected namespaces are one for the audit module, one for the
+     application, and another for the dlmopen on handle_restart.  */
+  enum { max_ns = 3 };
+  uintptr_t acts[max_ns] = { 0 };
+  size_t nacts = 0;
+  int last_act = -1;
+  uintptr_t last_act_cookie = -1;
+  bool seen_first_objclose = false;
+
+  FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
+  TEST_VERIFY (out != NULL);
+  char *buffer = NULL;
+  size_t buffer_length = 0;
+  while (xgetline (&buffer, &buffer_length, out))
+    {
+      if (startswith (buffer, "la_activity: "))
+	{
+	  uintptr_t cookie;
+	  int this_act;
+	  int r = sscanf (buffer, "la_activity: %d %"SCNxPTR"", &this_act,
+			  &cookie);
+	  TEST_COMPARE (r, 2);
+
+	  /* The cookie identifies the object at the head of the link map,
+	     so we only add a new namespace if it changes from previous
+	     one.  This work since dlmopen is the last in the test body.  */
+	  if (cookie != last_act_cookie && last_act_cookie != -1)
+	    TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
+
+	  if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
+	    {
+	      acts[nacts++] = cookie;
+	      last_act_cookie = cookie;
+	    }
+	  /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
+	     at program termination (if the tests adds a dlclose or a library
+	     with extra dependencies this require to be adapted).  */
+	  else if (this_act == LA_ACT_DELETE)
+	    {
+	      last_act_cookie = acts[--nacts];
+	      TEST_COMPARE (acts[nacts], cookie);
+	      acts[nacts] = 0;
+	    }
+	  else if (this_act == LA_ACT_CONSISTENT)
+	    {
+	      TEST_COMPARE (cookie, last_act_cookie);
+
+	      /* LA_ACT_DELETE must always be followed by an la_objclose.  */
+	      if (last_act == LA_ACT_DELETE)
+		TEST_COMPARE (seen_first_objclose, true);
+	      else
+		TEST_COMPARE (last_act, LA_ACT_ADD);
+	    }
+
+	  last_act = this_act;
+	  seen_first_objclose = false;
+	}
+      else if (startswith (buffer, "la_objopen: "))
+	{
+	  char *lname;
+	  uintptr_t laddr;
+	  Lmid_t lmid;
+	  uintptr_t cookie;
+	  int r = sscanf (buffer, "la_objopen: %"SCNxPTR"  %ms %"SCNxPTR" %ld",
+			  &cookie, &lname, &laddr, &lmid);
+	  TEST_COMPARE (r, 4);
+
+	  /* la_objclose is not triggered by vDSO because glibc does not
+	     unload it.  */
+	  if (is_vdso (lname))
+	    continue;
+	  if (nobjs == max_objs)
+	    FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
+			lname, laddr, lmid);
+	  objs[nobjs].lname = lname;
+	  objs[nobjs].laddr = laddr;
+	  objs[nobjs].lmid = lmid;
+	  objs[nobjs].closed = false;
+	  nobjs++;
+
+	  /* This indirectly checks that la_objopen always come before
+	     la_objclose btween la_activity calls.  */
+	  seen_first_objclose = false;
+	}
+      else if (startswith (buffer, "la_objclose: "))
+	{
+	  char *lname;
+	  uintptr_t laddr;
+	  Lmid_t lmid;
+	  uintptr_t cookie;
+	  int r = sscanf (buffer, "la_objclose: %"SCNxPTR" %ms %"SCNxPTR" %ld",
+			  &cookie, &lname, &laddr, &lmid);
+	  TEST_COMPARE (r, 4);
+
+	  for (size_t i = 0; i < nobjs; i++)
+	    {
+	      if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
+		{
+		  TEST_COMPARE (objs[i].closed, false);
+		  objs[i].closed = true;
+		  break;
+		}
+	    }
+
+	  /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
+	     the closed object's namespace.  */
+	  TEST_COMPARE (last_act, LA_ACT_DELETE);
+	  if (!seen_first_objclose)
+	    {
+	      TEST_COMPARE (last_act_cookie, cookie);
+	      seen_first_objclose = true;
+	    }
+	}
+    }
+
+  for (size_t i = 0; i < nobjs; i++)
+    {
+      TEST_COMPARE (objs[i].closed, true);
+      free (objs[i].lname);
+    }
+
+  /* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
+     Since only one link map may be not-CONSISTENT at a time, this also
+     ensures la_activity(LA_ACT_CONSISTENT) is the last callback received
+     for every namespace.  */
+  TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
+
+  free (buffer);
+  xfclose (out);
+
+  return 0;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
diff --git a/elf/tst-audit23mod.c b/elf/tst-audit23mod.c
new file mode 100644
index 0000000000..9a116ff682
--- /dev/null
+++ b/elf/tst-audit23mod.c
@@ -0,0 +1,23 @@
+/* Extra modules for tst-audit23
+   Copyright (C) 2022 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/>.  */
+
+int
+foo (void)
+{
+  return 0;
+}
diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c
new file mode 100644
index 0000000000..42eccae11b
--- /dev/null
+++ b/elf/tst-auditmod23.c
@@ -0,0 +1,74 @@
+/* Audit modules loaded by tst-audit23.
+   Copyright (C) 2022 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/>.  */
+
+#include <link.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/auxv.h>
+
+unsigned int
+la_version (unsigned int version)
+{
+  return LAV_CURRENT;
+}
+
+struct map_desc_t
+{
+  char *lname;
+  uintptr_t laddr;
+  Lmid_t lmid;
+};
+
+void
+la_activity (uintptr_t *cookie, unsigned int flag)
+{
+  fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie);
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+  const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name;
+  fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
+	   (uintptr_t) cookie, l_name, map->l_addr, lmid);
+
+  struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t));
+  if (map_desc == NULL)
+    abort ();
+
+  map_desc->lname = strdup (l_name);
+  map_desc->laddr = map->l_addr;
+  map_desc->lmid = lmid;
+
+  *cookie = (uintptr_t) map_desc;
+
+  return 0;
+}
+
+unsigned int
+la_objclose (uintptr_t *cookie)
+{
+  struct map_desc_t *map_desc = (struct map_desc_t *) *cookie;
+  fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
+	   (uintptr_t) cookie, map_desc->lname, map_desc->laddr,
+	   map_desc->lmid);
+
+  return 0;
+}
-- 
2.32.0


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v12 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096)
  2022-01-25 18:36 [PATCH v12 0/4] Multiple rtld-audit fixes Adhemerval Zanella
  2022-01-25 18:36 ` [PATCH v12 1/4] elf: Add la_activity during application exit Adhemerval Zanella
@ 2022-01-25 18:36 ` Adhemerval Zanella
  2022-02-01  5:29   ` Carlos O'Donell
  2022-01-25 18:36 ` [PATCH v12 3/4] elf: Issue la_symbind for bind-now (BZ #23734) Adhemerval Zanella
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2022-01-25 18:36 UTC (permalink / raw)
  To: libc-alpha, jma14, Carlos O'Donell; +Cc: John Mellor-Crummey, Ben Woodard

For audit modules and dependencies with initial-exec TLS, we can not
set the initial TLS image on default loader initialization because it
would already be set by the audit setup.  However, subsequent thread
creation would need to follow the default behaviour.

This patch fixes it by setting l_auditing link_map field not only
for the audit modules, but also for all its dependencies.  This is
used on _dl_allocate_tls_init to avoid the static TLS initialization
only at loading time.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
---
 elf/Makefile               |  8 ++++
 elf/dl-tls.c               | 13 +++++--
 elf/rtld.c                 |  2 +-
 elf/tst-audit21.c          | 42 ++++++++++++++++++++
 elf/tst-auditmod21a.c      | 80 ++++++++++++++++++++++++++++++++++++++
 elf/tst-auditmod21b.c      | 22 +++++++++++
 nptl/allocatestack.c       |  2 +-
 sysdeps/generic/ldsodefs.h |  2 +-
 8 files changed, 165 insertions(+), 6 deletions(-)
 create mode 100644 elf/tst-audit21.c
 create mode 100644 elf/tst-auditmod21a.c
 create mode 100644 elf/tst-auditmod21b.c

diff --git a/elf/Makefile b/elf/Makefile
index a3b4468593..7d01b71f6a 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -376,6 +376,7 @@ tests += \
   tst-audit18 \
   tst-audit19b \
   tst-audit20 \
+  tst-audit21 \
   tst-audit22 \
   tst-audit23 \
   tst-auditmany \
@@ -696,6 +697,8 @@ modules-names = \
   tst-auditmod19a \
   tst-auditmod19b \
   tst-auditmod20 \
+  tst-auditmod21a \
+  tst-auditmod21b \
   tst-auditmod22 \
   tst-auditmod23 \
   tst-auxvalmod \
@@ -2136,6 +2139,11 @@ tst-audit19b-ARGS = -- $(host-test-program-cmd)
 $(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
 tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
 
+$(objpfx)tst-audit21: $(shared-thread-library)
+$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so
+$(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so
+tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so
+
 $(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
 tst-audit22-ARGS = -- $(host-test-program-cmd)
 
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 8ba70c9a9d..ccbe39660b 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -520,7 +520,7 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
 
 
 void *
-_dl_allocate_tls_init (void *result)
+_dl_allocate_tls_init (void *result, bool init_tls)
 {
   if (result == NULL)
     /* The memory allocation failed.  */
@@ -593,7 +593,14 @@ _dl_allocate_tls_init (void *result)
 	     some platforms use in static programs requires it.  */
 	  dtv[map->l_tls_modid].pointer.val = dest;
 
-	  /* Copy the initialization image and clear the BSS part.  */
+	  /* Copy the initialization image and clear the BSS part.  For
+	     audit modules or depedencies with initial-exec TLS, we can not
+	     set the initial TLS image on default loader initialization
+	     because it would already be set by the audit setup.  However,
+	     subsequent thread creation would need to follow the default
+	     behaviour.   */
+	  if (map->l_ns != LM_ID_BASE && !init_tls)
+	    continue;
 	  memset (__mempcpy (dest, map->l_tls_initimage,
 			     map->l_tls_initimage_size), '\0',
 		  map->l_tls_blocksize - map->l_tls_initimage_size);
@@ -620,7 +627,7 @@ _dl_allocate_tls (void *mem)
 {
   return _dl_allocate_tls_init (mem == NULL
 				? _dl_allocate_tls_storage ()
-				: allocate_dtv (mem));
+				: allocate_dtv (mem), true);
 }
 rtld_hidden_def (_dl_allocate_tls)
 
diff --git a/elf/rtld.c b/elf/rtld.c
index 8d233f77be..10436f7034 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2462,7 +2462,7 @@ dl_main (const ElfW(Phdr) *phdr,
      into the main thread's TLS area, which we allocated above.
      Note: thread-local variables must only be accessed after completing
      the next step.  */
-  _dl_allocate_tls_init (tcbp);
+  _dl_allocate_tls_init (tcbp, false);
 
   /* And finally install it for the main thread.  */
   if (! tls_init_tp_called)
diff --git a/elf/tst-audit21.c b/elf/tst-audit21.c
new file mode 100644
index 0000000000..41446a2107
--- /dev/null
+++ b/elf/tst-audit21.c
@@ -0,0 +1,42 @@
+/* Check DT_AUDIT with static TLS.
+   Copyright (C) 2022 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/>.  */
+
+#include <ctype.h>
+#include <support/xthread.h>
+#include <support/check.h>
+
+static volatile __thread int out __attribute__ ((tls_model ("initial-exec")));
+
+static void *
+tf (void *arg)
+{
+  TEST_COMPARE (out, 0);
+  out = isspace (' ');
+  return NULL;
+}
+
+int main (int argc, char *argv[])
+{
+  TEST_COMPARE (out, 0);
+  out = isspace (' ');
+
+  pthread_t t = xpthread_create (NULL, tf, NULL);
+  xpthread_join (t);
+
+  return 0;
+}
diff --git a/elf/tst-auditmod21a.c b/elf/tst-auditmod21a.c
new file mode 100644
index 0000000000..4c0f256969
--- /dev/null
+++ b/elf/tst-auditmod21a.c
@@ -0,0 +1,80 @@
+/* Check DT_AUDIT with static TLS.
+   Copyright (C) 2022 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/>.  */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <link.h>
+
+#define tls_ie __attribute__ ((tls_model ("initial-exec")))
+
+__thread int tls_var0 tls_ie;
+__thread int tls_var1 tls_ie = 0x10;
+
+/* Defined at tst-auditmod21b.so  */
+extern __thread int tls_var2;
+extern __thread int tls_var3;
+
+static volatile int out;
+
+static void
+call_libc (void)
+{
+  /* isspace access the initial-exec glibc TLS variables, which are
+     setup in glibc initialization.  */
+  out = isspace (' ');
+}
+
+unsigned int
+la_version (unsigned int v)
+{
+  tls_var0 = 0x1;
+  if (tls_var1 != 0x10)
+    abort ();
+  tls_var1 = 0x20;
+
+  tls_var2 = 0x2;
+  if (tls_var3 != 0x20)
+    abort ();
+  tls_var3 = 0x40;
+
+  call_libc ();
+
+  return LAV_CURRENT;
+}
+
+unsigned int
+la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie)
+{
+  call_libc ();
+  *cookie = (uintptr_t) map;
+  return 0;
+}
+
+void
+la_activity (uintptr_t* cookie, unsigned int flag)
+{
+  if (tls_var0 != 0x1 || tls_var1 != 0x20)
+    abort ();
+  call_libc ();
+}
+
+void
+la_preinit (uintptr_t* cookie)
+{
+  call_libc ();
+}
diff --git a/elf/tst-auditmod21b.c b/elf/tst-auditmod21b.c
new file mode 100644
index 0000000000..69705cf75a
--- /dev/null
+++ b/elf/tst-auditmod21b.c
@@ -0,0 +1,22 @@
+/* Check DT_AUDIT with static TLS.
+   Copyright (C) 2022 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/>.  */
+
+#define tls_ie __attribute__ ((tls_model ("initial-exec")))
+
+__thread int tls_var2 tls_ie;
+__thread int tls_var3 tls_ie = 0x20;
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 3fb085f9a1..34a33164ff 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -138,7 +138,7 @@ get_cached_stack (size_t *sizep, void **memp)
   memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
 
   /* Re-initialize the TLS.  */
-  _dl_allocate_tls_init (TLS_TPADJ (result));
+  _dl_allocate_tls_init (TLS_TPADJ (result), true);
 
   return result;
 }
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index f6b2b415a6..97061bdf9f 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1282,7 +1282,7 @@ extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
 /* These are internal entry points to the two halves of _dl_allocate_tls,
    only used within rtld.c itself at startup time.  */
 extern void *_dl_allocate_tls_storage (void) attribute_hidden;
-extern void *_dl_allocate_tls_init (void *);
+extern void *_dl_allocate_tls_init (void *, bool);
 rtld_hidden_proto (_dl_allocate_tls_init)
 
 /* Deallocate memory allocated with _dl_allocate_tls.  */
-- 
2.32.0


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v12 3/4] elf: Issue la_symbind for bind-now (BZ #23734)
  2022-01-25 18:36 [PATCH v12 0/4] Multiple rtld-audit fixes Adhemerval Zanella
  2022-01-25 18:36 ` [PATCH v12 1/4] elf: Add la_activity during application exit Adhemerval Zanella
  2022-01-25 18:36 ` [PATCH v12 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Adhemerval Zanella
@ 2022-01-25 18:36 ` Adhemerval Zanella
  2022-02-01  6:06   ` Carlos O'Donell
  2022-01-25 18:37 ` [PATCH v12 4/4] elf: Fix runtime linker auditing on aarch64 (BZ #26643) Adhemerval Zanella
  2022-02-01  6:45 ` [PATCH v12 0/4] Multiple rtld-audit fixes Carlos O'Donell
  4 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2022-01-25 18:36 UTC (permalink / raw)
  To: libc-alpha, jma14, Carlos O'Donell; +Cc: John Mellor-Crummey, Ben Woodard

The audit symbind callback is not called for binaries built with
-Wl,-z,now or when LD_BIND_NOW=1 is used, nor the PLT tracking callbacks
(plt_enter and plt_exit) since this will would change the expected
program semantic (where no PTL is expected) and would incur in
performance implications (such as for BZ#15533).

LAV_CURRENT is also bumped to indicate the audit ABI change (where
la_symbind flags are set by the loader to indicate no possible PTL
trace).

To handle powerpc64 ELFv1 function descriptor, _dl_audit_symbind
requires to know whether bind-now is used so the symbol value is
updated to function text segment instead of the OPD (for lazy binding
this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve).

Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
powerpc64-linux-gnu.
---
 NEWS                           |   4 +
 bits/link_lavcurrent.h         |   2 +-
 elf/Makefile                   |  89 ++++++++++++++++++++++-
 elf/dl-audit.c                 |  58 +++++++++------
 elf/do-rel.h                   |  57 +++++++++++----
 elf/sotruss-lib.c              |   7 ++
 elf/tst-audit24a.c             |  36 +++++++++
 elf/tst-audit24amod1.c         |  31 ++++++++
 elf/tst-audit24amod2.c         |  25 +++++++
 elf/tst-audit24b.c             |  37 ++++++++++
 elf/tst-audit24bmod1.c         |  31 ++++++++
 elf/tst-audit24bmod2.c         |  23 ++++++
 elf/tst-audit24c.c             |   2 +
 elf/tst-audit24d.c             |  36 +++++++++
 elf/tst-audit24dmod1.c         |  33 +++++++++
 elf/tst-audit24dmod2.c         |  28 +++++++
 elf/tst-audit24dmod3.c         |  31 ++++++++
 elf/tst-audit24dmod4.c         |  25 +++++++
 elf/tst-audit25a.c             | 129 +++++++++++++++++++++++++++++++++
 elf/tst-audit25b.c             | 128 ++++++++++++++++++++++++++++++++
 elf/tst-audit25mod1.c          |  30 ++++++++
 elf/tst-audit25mod2.c          |  30 ++++++++
 elf/tst-audit25mod3.c          |  22 ++++++
 elf/tst-audit25mod4.c          |  22 ++++++
 elf/tst-auditmod24.h           |  29 ++++++++
 elf/tst-auditmod24a.c          | 114 +++++++++++++++++++++++++++++
 elf/tst-auditmod24b.c          | 104 ++++++++++++++++++++++++++
 elf/tst-auditmod24c.c          |   3 +
 elf/tst-auditmod24d.c          | 120 ++++++++++++++++++++++++++++++
 elf/tst-auditmod25.c           |  79 ++++++++++++++++++++
 sysdeps/generic/dl-lookupcfg.h |   3 +
 sysdeps/generic/ldsodefs.h     |   5 +-
 sysdeps/hppa/dl-lookupcfg.h    |   3 +
 sysdeps/ia64/dl-lookupcfg.h    |   3 +
 sysdeps/powerpc/dl-lookupcfg.h |  39 ++++++++++
 35 files changed, 1379 insertions(+), 39 deletions(-)
 create mode 100644 elf/tst-audit24a.c
 create mode 100644 elf/tst-audit24amod1.c
 create mode 100644 elf/tst-audit24amod2.c
 create mode 100644 elf/tst-audit24b.c
 create mode 100644 elf/tst-audit24bmod1.c
 create mode 100644 elf/tst-audit24bmod2.c
 create mode 100644 elf/tst-audit24c.c
 create mode 100644 elf/tst-audit24d.c
 create mode 100644 elf/tst-audit24dmod1.c
 create mode 100644 elf/tst-audit24dmod2.c
 create mode 100644 elf/tst-audit24dmod3.c
 create mode 100644 elf/tst-audit24dmod4.c
 create mode 100644 elf/tst-audit25a.c
 create mode 100644 elf/tst-audit25b.c
 create mode 100644 elf/tst-audit25mod1.c
 create mode 100644 elf/tst-audit25mod2.c
 create mode 100644 elf/tst-audit25mod3.c
 create mode 100644 elf/tst-audit25mod4.c
 create mode 100644 elf/tst-auditmod24.h
 create mode 100644 elf/tst-auditmod24a.c
 create mode 100644 elf/tst-auditmod24b.c
 create mode 100644 elf/tst-auditmod24c.c
 create mode 100644 elf/tst-auditmod24d.c
 create mode 100644 elf/tst-auditmod25.c
 create mode 100644 sysdeps/powerpc/dl-lookupcfg.h

diff --git a/NEWS b/NEWS
index a9f25d3225..c0f8932f84 100644
--- a/NEWS
+++ b/NEWS
@@ -158,6 +158,10 @@ Deprecated and removed features, and other changes affecting compatibility:
   been removed.  There are widely-deployed out-of-process alternatives for
   catching coredumps and backtraces.
 
+* The audit module interface version LAV_CURRENT is increased to enable
+  proper bind-now support.  The loader now advertises on the la_symbind
+  flags that PLT trace is not possible.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h
index 7bfa4b9f4e..a852d41302 100644
--- a/bits/link_lavcurrent.h
+++ b/bits/link_lavcurrent.h
@@ -22,4 +22,4 @@
 #endif
 
 /* Version numbers for la_version handshake interface.  */
-#define LAV_CURRENT	1
+#define LAV_CURRENT	2
diff --git a/elf/Makefile b/elf/Makefile
index 7d01b71f6a..b9edcccb82 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -379,6 +379,12 @@ tests += \
   tst-audit21 \
   tst-audit22 \
   tst-audit23 \
+  tst-audit24a \
+  tst-audit24b \
+  tst-audit24c \
+  tst-audit24d \
+  tst-audit25a \
+  tst-audit25b \
   tst-auditmany \
   tst-auxobj \
   tst-auxobj-dlopen \
@@ -676,6 +682,18 @@ modules-names = \
   tst-audit18mod \
   tst-audit19bmod \
   tst-audit23mod \
+  tst-audit24amod1 \
+  tst-audit24amod2 \
+  tst-audit24bmod1 \
+  tst-audit24bmod2 \
+  tst-audit24dmod1 \
+  tst-audit24dmod2 \
+  tst-audit24dmod3 \
+  tst-audit24dmod4 \
+  tst-audit25mod1 \
+  tst-audit25mod2 \
+  tst-audit25mod3 \
+  tst-audit25mod4 \
   tst-auditlogmod-1 \
   tst-auditlogmod-2 \
   tst-auditlogmod-3 \
@@ -701,6 +719,11 @@ modules-names = \
   tst-auditmod21b \
   tst-auditmod22 \
   tst-auditmod23 \
+  tst-auditmod24a \
+  tst-auditmod24b \
+  tst-auditmod24c \
+  tst-auditmod24d \
+  tst-auditmod25 \
   tst-auxvalmod \
   tst-big-note-lib \
   tst-deep1mod1 \
@@ -918,7 +941,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
 
 # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
 # rules.
-modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod
+modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
+			 tst-audit24bmod1 tst-audit24bmod2.so
 
 tests += $(tests-static)
 
@@ -2151,6 +2175,69 @@ $(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
 			  $(objpfx)tst-audit23mod.so
 tst-audit23-ARGS = -- $(host-test-program-cmd)
 
+$(objpfx)tst-audit24a.out: $(objpfx)tst-auditmod24a.so
+$(objpfx)tst-audit24a: $(objpfx)tst-audit24amod1.so \
+		       $(objpfx)tst-audit24amod2.so
+tst-audit24a-ENV = LD_AUDIT=$(objpfx)tst-auditmod24a.so
+LDFLAGS-tst-audit24a = -Wl,-z,now
+
+$(objpfx)tst-audit24b.out: $(objpfx)tst-auditmod24b.so
+$(objpfx)tst-audit24b: $(objpfx)tst-audit24bmod1.so \
+		       $(objpfx)tst-audit24bmod2.so
+$(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so
+# The test check if a library without .gnu.version correctly calls the
+# audit callbacks.  So it uses an explicit link rule to avoid linking
+# against libc.so.
+$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os
+	$(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \
+	  -Wl,-z,now
+	$(call after-link,$@.new)
+	mv -f $@.new $@
+CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1)
+$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os
+	$(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os
+	$(call after-link,$@.new)
+	mv -f $@.new $@
+CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2)
+tst-audit24b-ENV = LD_AUDIT=$(objpfx)tst-auditmod24b.so
+LDFLAGS-tst-audit24b = -Wl,-z,now
+
+# Same as tst-audit24a, but tests LD_BIND_NOW
+$(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so
+$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \
+		       $(objpfx)tst-audit24amod2.so
+tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so
+LDFLAGS-tst-audit24b = -Wl,-z,lazy
+
+$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so
+$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \
+		       $(objpfx)tst-audit24dmod2.so
+$(objpfx)tst-audit24dmod1.so: $(objpfx)tst-audit24dmod3.so
+LDFLAGS-tst-audit24dmod1.so = -Wl,-z,now
+$(objpfx)tst-audit24dmod2.so: $(objpfx)tst-audit24dmod4.so
+LDFLAGS-tst-audit24dmod2.so = -Wl,-z,lazy
+tst-audit24d-ENV = LD_AUDIT=$(objpfx)tst-auditmod24d.so
+LDFLAGS-tst-audit24d = -Wl,-z,lazy
+
+$(objpfx)tst-audit25a.out: $(objpfx)tst-auditmod25.so
+$(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \
+		       $(objpfx)tst-audit25mod2.so \
+		       $(objpfx)tst-audit25mod3.so \
+		       $(objpfx)tst-audit25mod4.so
+$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so
+LDFLAGS-tst-audit25mod1.so = -Wl,-z,now
+$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so
+LDFLAGS-tst-audit25mod2.so = -Wl,-z,lazy
+tst-audit25a-ARGS = -- $(host-test-program-cmd)
+
+$(objpfx)tst-audit25b.out: $(objpfx)tst-auditmod25.so
+$(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \
+		       $(objpfx)tst-audit25mod2.so \
+		       $(objpfx)tst-audit25mod3.so \
+		       $(objpfx)tst-audit25mod4.so
+LDFLAGS-tst-audit25b = -Wl,-z,now
+tst-audit25b-ARGS = -- $(host-test-program-cmd)
+
 # tst-sonamemove links against an older implementation of the library.
 LDFLAGS-tst-sonamemove-linkmod1.so = \
   -Wl,--version-script=tst-sonamemove-linkmod1.map \
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
index 715de53272..794bfd45cd 100644
--- a/elf/dl-audit.c
+++ b/elf/dl-audit.c
@@ -178,16 +178,23 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
 		   const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
 		   lookup_t result)
 {
-  reloc_result->bound = result;
-  /* Compute index of the symbol entry in the symbol table of the DSO with the
-     definition.  */
-  reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result,
-							  l_info[DT_SYMTAB]));
+  bool for_jmp_slot = reloc_result == NULL;
+
+  /* Compute index of the symbol entry in the symbol table of the DSO
+     with the definition.  */
+  unsigned int boundndx = defsym - (ElfW(Sym) *) D_PTR (result,
+							l_info[DT_SYMTAB]);
+  if (!for_jmp_slot)
+    {
+      reloc_result->bound = result;
+      reloc_result->boundndx = boundndx;
+    }
 
   if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
     {
       /* Set all bits since this symbol binding is not interesting.  */
-      reloc_result->enterexit = (1u << DL_NNS) - 1;
+      if (!for_jmp_slot)
+	reloc_result->enterexit = (1u << DL_NNS) - 1;
       return;
     }
 
@@ -199,12 +206,13 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
      two bits.  */
   assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
   assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
-  reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
+  uint32_t enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
 
   const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]);
 
   unsigned int flags = 0;
   struct audit_ifaces *afct = GLRO(dl_audit);
+  uintptr_t new_value = (uintptr_t) sym.st_value;
   for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
     {
       /* XXX Check whether both DSOs must request action or only one */
@@ -215,37 +223,41 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
 	{
 	  if (afct->symbind != NULL)
 	    {
-	      uintptr_t new_value = afct->symbind (&sym,
-						   reloc_result->boundndx,
-						   &l_state->cookie,
-						   &result_state->cookie,
-						   &flags,
-						   strtab2 + defsym->st_name);
+	      flags |= for_jmp_slot ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT
+				    : 0;
+	      new_value = afct->symbind (&sym, boundndx,
+					 &l_state->cookie,
+					 &result_state->cookie, &flags,
+					 strtab2 + defsym->st_name);
 	      if (new_value != (uintptr_t) sym.st_value)
 		{
 		  flags |= LA_SYMB_ALTVALUE;
-		  sym.st_value = new_value;
+		  sym.st_value = for_jmp_slot
+		    ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value;
 		}
 	    }
 
 	  /* Remember the results for every audit library and store a summary
 	     in the first two bits.  */
-	  reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER
-					      | LA_SYMB_NOPLTEXIT);
-	  reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
-						| LA_SYMB_NOPLTEXIT))
-				      << ((cnt + 1) * 2));
+	  enterexit &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
+	  enterexit |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
+			<< ((cnt + 1) * 2));
 	}
       else
 	/* If the bind flags say this auditor is not interested, set the bits
 	   manually.  */
-	reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
-				    << ((cnt + 1) * 2));
+	enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
+		      << ((cnt + 1) * 2));
       afct = afct->next;
     }
 
-  reloc_result->flags = flags;
-  *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
+  if (!for_jmp_slot)
+    {
+      reloc_result->enterexit = enterexit;
+      reloc_result->flags = flags;
+    }
+
+  DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
 }
 
 void
diff --git a/elf/do-rel.h b/elf/do-rel.h
index 0718badf83..60d5dce8f2 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -16,6 +16,8 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <ldsodefs.h>
+
 /* This file may be included twice, to define both
    `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.  */
 
@@ -123,6 +125,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 
 	  for (; r < end; ++r)
 	    {
+	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
+	      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
+	      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
+	      const struct r_found_version *rversion = &map->l_versions[ndx];
 #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
 	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
 		{
@@ -133,10 +139,19 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 		}
 #endif
 
-	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
-	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
-			       &map->l_versions[ndx],
-			       (void *) (l_addr + r->r_offset), skip_ifunc);
+	      elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg,
+			       skip_ifunc);
+#if defined SHARED && !defined RTLD_BOOTSTRAP
+	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
+		  && GLRO(dl_naudit) > 0)
+		{
+		  struct link_map *sym_map
+		    = RESOLVE_MAP (map, scope, &sym, rversion,
+				   ELF_MACHINE_JMP_SLOT);
+		  if (sym != NULL)
+		    _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map);
+		}
+#endif
 	    }
 
 #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
@@ -158,17 +173,33 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
       else
 	{
 	  for (; r < end; ++r)
+	    {
+	      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
+	      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
 # ifdef ELF_MACHINE_IRELATIVE
-	    if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
-	      {
-		if (r2 == NULL)
-		  r2 = r;
-		end2 = r;
-	      }
-	    else
+	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
+		{
+		  if (r2 == NULL)
+		    r2 = r;
+		  end2 = r;
+		  continue;
+		}
 # endif
-	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
-			       (void *) (l_addr + r->r_offset), skip_ifunc);
+	      elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg,
+			       skip_ifunc);
+# if defined SHARED && !defined RTLD_BOOTSTRAP
+	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
+		  && GLRO(dl_naudit) > 0)
+		{
+		  struct link_map *sym_map
+		    = RESOLVE_MAP (map, scope, &sym,
+				   (struct r_found_version *) NULL,
+				   ELF_MACHINE_JMP_SLOT);
+		  if (sym != NULL)
+		    _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map);
+		}
+# endif
+	    }
 
 # ifdef ELF_MACHINE_IRELATIVE
 	  if (r2 != NULL)
diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c
index 1077458c9d..a5edd438f9 100644
--- a/elf/sotruss-lib.c
+++ b/elf/sotruss-lib.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <err.h>
 #include <error.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -231,6 +232,12 @@ uintptr_t
 la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook,
 	    uintptr_t *defcook, unsigned int *flags, const char *symname)
 {
+  if (*flags & LA_SYMB_NOPLTENTER)
+    warnx ("cannot trace PLT enter (bind-now enabled)");
+
+  if (do_exit && *flags & LA_SYMB_NOPLTEXIT)
+    warnx ("cannot trace PLT exit (bind-now enabled)");
+
   if (!do_exit)
     *flags = LA_SYMB_NOPLTEXIT;
 
diff --git a/elf/tst-audit24a.c b/elf/tst-audit24a.c
new file mode 100644
index 0000000000..2cdd3fb98b
--- /dev/null
+++ b/elf/tst-audit24a.c
@@ -0,0 +1,36 @@
+/* DL_AUDIT test for la_symbind and bind-now.
+   Copyright (C) 2022 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/>.  */
+
+#include <support/check.h>
+#include <support/support.h>
+
+int tst_audit24amod1_func1 (void);
+int tst_audit24amod1_func2 (void);
+int tst_audit24amod2_func1 (void);
+
+int
+do_test (void)
+{
+  TEST_COMPARE (tst_audit24amod1_func1 (), 1);
+  TEST_COMPARE (tst_audit24amod1_func2 (), 2);
+  TEST_COMPARE (tst_audit24amod2_func1 (), 10);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/elf/tst-audit24amod1.c b/elf/tst-audit24amod1.c
new file mode 100644
index 0000000000..c287372e32
--- /dev/null
+++ b/elf/tst-audit24amod1.c
@@ -0,0 +1,31 @@
+/* Modules used by tst-audit24a.
+   Copyright (C) 2022 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/>.  */
+
+#include <stdlib.h>
+
+_Noreturn int
+tst_audit24amod1_func1 (void)
+{
+  abort ();
+}
+
+int
+tst_audit24amod1_func2 (void)
+{
+  return 2;
+}
diff --git a/elf/tst-audit24amod2.c b/elf/tst-audit24amod2.c
new file mode 100644
index 0000000000..938c71dc29
--- /dev/null
+++ b/elf/tst-audit24amod2.c
@@ -0,0 +1,25 @@
+/* Modules used by tst-audit24a.
+   Copyright (C) 2022 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/>.  */
+
+#include <stdlib.h>
+
+_Noreturn int
+tst_audit24amod2_func1 (void)
+{
+  abort ();
+}
diff --git a/elf/tst-audit24b.c b/elf/tst-audit24b.c
new file mode 100644
index 0000000000..82478ed8f9
--- /dev/null
+++ b/elf/tst-audit24b.c
@@ -0,0 +1,37 @@
+/* DL_AUDIT test for la_symbind and bind-now.
+   Copyright (C) 2022 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 similar to tst-audit24a, with the difference this modules
+   does not have the .gnu.version section header.  */
+
+#include <support/check.h>
+#include <support/support.h>
+
+int tst_audit24bmod1_func1 (void);
+int tst_audit24bmod1_func2 (void);
+
+int
+do_test (void)
+{
+  TEST_COMPARE (tst_audit24bmod1_func1 (), 1);
+  TEST_COMPARE (tst_audit24bmod1_func2 (), 2);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/elf/tst-audit24bmod1.c b/elf/tst-audit24bmod1.c
new file mode 100644
index 0000000000..5fa4611918
--- /dev/null
+++ b/elf/tst-audit24bmod1.c
@@ -0,0 +1,31 @@
+/* Modules used by tst-audit24c.
+   Copyright (C) 2022 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/>.  */
+
+int tst_audit24bmod2_func1 (void);
+
+int
+tst_audit24bmod1_func1 (void)
+{
+  return -1;
+}
+
+int
+tst_audit24bmod1_func2 (void)
+{
+  return tst_audit24bmod2_func1 ();
+}
diff --git a/elf/tst-audit24bmod2.c b/elf/tst-audit24bmod2.c
new file mode 100644
index 0000000000..d469e70a41
--- /dev/null
+++ b/elf/tst-audit24bmod2.c
@@ -0,0 +1,23 @@
+/* Modules used by tst-audit24b.
+   Copyright (C) 2022 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/>.  */
+
+int
+tst_audit24bmod2_func1 (void)
+{
+  return -1;
+}
diff --git a/elf/tst-audit24c.c b/elf/tst-audit24c.c
new file mode 100644
index 0000000000..46ed328756
--- /dev/null
+++ b/elf/tst-audit24c.c
@@ -0,0 +1,2 @@
+/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now  */
+#include "tst-audit24a.c"
diff --git a/elf/tst-audit24d.c b/elf/tst-audit24d.c
new file mode 100644
index 0000000000..1c89e4cb83
--- /dev/null
+++ b/elf/tst-audit24d.c
@@ -0,0 +1,36 @@
+/* DL_AUDIT test for la_symbind and bind-now.
+   Copyright (C) 2022 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/>.  */
+
+#include <support/check.h>
+#include <support/support.h>
+
+int tst_audit24dmod1_func1 (void);
+int tst_audit24dmod1_func2 (void);
+int tst_audit24dmod2_func1 (void);
+
+int
+do_test (void)
+{
+  TEST_COMPARE (tst_audit24dmod1_func1 (), 1);
+  TEST_COMPARE (tst_audit24dmod1_func2 (), 32);
+  TEST_COMPARE (tst_audit24dmod2_func1 (), 10);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/elf/tst-audit24dmod1.c b/elf/tst-audit24dmod1.c
new file mode 100644
index 0000000000..3ff2218c96
--- /dev/null
+++ b/elf/tst-audit24dmod1.c
@@ -0,0 +1,33 @@
+/* Modules used by tst-audit24d.
+   Copyright (C) 2022 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/>.  */
+
+#include <stdlib.h>
+
+int tst_audit24dmod3_func1 (void);
+
+_Noreturn int
+tst_audit24dmod1_func1 (void)
+{
+  abort ();
+}
+
+int
+tst_audit24dmod1_func2 (void)
+{
+  return 2 + tst_audit24dmod3_func1 ();;
+}
diff --git a/elf/tst-audit24dmod2.c b/elf/tst-audit24dmod2.c
new file mode 100644
index 0000000000..03fe938128
--- /dev/null
+++ b/elf/tst-audit24dmod2.c
@@ -0,0 +1,28 @@
+/* Module for tst-audit24d.
+   Copyright (C) 2022 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/>.  */
+
+#include <stdlib.h>
+
+int tst_audit24dmod4_func1 (void);
+
+_Noreturn int
+tst_audit24dmod2_func1 (void)
+{
+  tst_audit24dmod4_func1 ();
+  abort ();
+}
diff --git a/elf/tst-audit24dmod3.c b/elf/tst-audit24dmod3.c
new file mode 100644
index 0000000000..106d517d28
--- /dev/null
+++ b/elf/tst-audit24dmod3.c
@@ -0,0 +1,31 @@
+/* Module for tst-audit24d.
+   Copyright (C) 2022 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/>.  */
+
+#include <stdlib.h>
+
+_Noreturn int
+tst_audit24dmod3_func1 (void)
+{
+  abort ();
+}
+
+int
+tst_audit24dmod3_func2 (void)
+{
+  return 4;
+}
diff --git a/elf/tst-audit24dmod4.c b/elf/tst-audit24dmod4.c
new file mode 100644
index 0000000000..1da3b46917
--- /dev/null
+++ b/elf/tst-audit24dmod4.c
@@ -0,0 +1,25 @@
+/* Module for tst-audit24d.
+   Copyright (C) 2022 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/>.  */
+
+#include <stdlib.h>
+
+_Noreturn int
+tst_audit24dmod4_func1 (void)
+{
+  abort ();
+}
diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c
new file mode 100644
index 0000000000..3476069353
--- /dev/null
+++ b/elf/tst-audit25a.c
@@ -0,0 +1,129 @@
+/* Check DT_AUDIT and LD_BIND_NOW.
+   Copyright (C) 2022 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/>.  */
+
+#include <array_length.h>
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdlib.h>
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/xstdio.h>
+#include <support/support.h>
+#include <sys/auxv.h>
+
+static int restart;
+#define CMDLINE_OPTIONS \
+  { "restart", no_argument, &restart, 1 },
+
+void tst_audit25mod1_func1 (void);
+void tst_audit25mod1_func2 (void);
+void tst_audit25mod2_func1 (void);
+void tst_audit25mod2_func2 (void);
+
+static int
+handle_restart (void)
+{
+  tst_audit25mod1_func1 ();
+  tst_audit25mod1_func2 ();
+  tst_audit25mod2_func1 ();
+  tst_audit25mod2_func2 ();
+
+  return 0;
+}
+
+static inline bool
+startswith (const char *str, const char *pre)
+{
+  size_t lenpre = strlen (pre);
+  size_t lenstr = strlen (str);
+  return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
+}
+
+static int
+do_test (int argc, char *argv[])
+{
+  /* We must have either:
+     - One our fource parameters left if called initially:
+       + path to ld.so         optional
+       + "--library-path"      optional
+       + the library path      optional
+       + the application name  */
+
+  if (restart)
+    return handle_restart ();
+
+  setenv ("LD_AUDIT", "tst-auditmod25.so", 0);
+
+  char *spargv[9];
+  int i = 0;
+  for (; i < argc - 1; i++)
+    spargv[i] = argv[i + 1];
+  spargv[i++] = (char *) "--direct";
+  spargv[i++] = (char *) "--restart";
+  spargv[i] = NULL;
+  TEST_VERIFY_EXIT (i < array_length (spargv));
+
+  {
+    struct support_capture_subprocess result
+      = support_capture_subprogram (spargv[0], spargv);
+    support_capture_subprocess_check (&result, "tst-audit25a", 0,
+				      sc_allow_stderr);
+
+    /* tst-audit25a is build with -Wl,-z,lazy and tst-audit25mod1 with
+       -Wl,-z,now; so only tst_audit25mod3_func1 should be expected to
+       have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  */
+    TEST_COMPARE_STRING (result.err.buffer,
+			 "la_symbind: tst_audit25mod3_func1 1\n"
+			 "la_symbind: tst_audit25mod1_func1 0\n"
+			 "la_symbind: tst_audit25mod1_func2 0\n"
+			 "la_symbind: tst_audit25mod2_func1 0\n"
+			 "la_symbind: tst_audit25mod4_func1 0\n"
+			 "la_symbind: tst_audit25mod2_func2 0\n");
+
+    support_capture_subprocess_free (&result);
+  }
+
+  {
+    setenv ("LD_BIND_NOW", "1", 0);
+    struct support_capture_subprocess result
+      = support_capture_subprogram (spargv[0], spargv);
+    support_capture_subprocess_check (&result, "tst-audit25a", 0,
+				      sc_allow_stderr);
+
+    /* With LD_BIND_NOW all symbols are expected to have
+       LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  Also the resolution
+       order is done in breadth-first order.  */
+    TEST_COMPARE_STRING (result.err.buffer,
+			 "la_symbind: tst_audit25mod4_func1 1\n"
+			 "la_symbind: tst_audit25mod3_func1 1\n"
+			 "la_symbind: tst_audit25mod1_func1 1\n"
+			 "la_symbind: tst_audit25mod2_func1 1\n"
+			 "la_symbind: tst_audit25mod1_func2 1\n"
+			 "la_symbind: tst_audit25mod2_func2 1\n");
+
+    support_capture_subprocess_free (&result);
+  }
+
+  return 0;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c
new file mode 100644
index 0000000000..8bf98bc7fd
--- /dev/null
+++ b/elf/tst-audit25b.c
@@ -0,0 +1,128 @@
+/* Check DT_AUDIT and LD_BIND_NOW.
+   Copyright (C) 2022 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/>.  */
+
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdlib.h>
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/xstdio.h>
+#include <support/support.h>
+#include <sys/auxv.h>
+
+static int restart;
+#define CMDLINE_OPTIONS \
+  { "restart", no_argument, &restart, 1 },
+
+void tst_audit25mod1_func1 (void);
+void tst_audit25mod1_func2 (void);
+void tst_audit25mod2_func1 (void);
+void tst_audit25mod2_func2 (void);
+
+static int
+handle_restart (void)
+{
+  tst_audit25mod1_func1 ();
+  tst_audit25mod1_func2 ();
+  tst_audit25mod2_func1 ();
+  tst_audit25mod2_func2 ();
+
+  return 0;
+}
+
+static inline bool
+startswith (const char *str, const char *pre)
+{
+  size_t lenpre = strlen (pre);
+  size_t lenstr = strlen (str);
+  return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
+}
+
+static int
+do_test (int argc, char *argv[])
+{
+  /* We must have either:
+     - One our fource parameters left if called initially:
+       + path to ld.so         optional
+       + "--library-path"      optional
+       + the library path      optional
+       + the application name  */
+
+  if (restart)
+    return handle_restart ();
+
+  setenv ("LD_AUDIT", "tst-auditmod25.so", 0);
+
+  char *spargv[9];
+  int i = 0;
+  for (; i < argc - 1; i++)
+    spargv[i] = argv[i + 1];
+  spargv[i++] = (char *) "--direct";
+  spargv[i++] = (char *) "--restart";
+  spargv[i] = NULL;
+
+  {
+    struct support_capture_subprocess result
+      = support_capture_subprogram (spargv[0], spargv);
+    support_capture_subprocess_check (&result, "tst-audit25a", 0,
+				      sc_allow_stderr);
+
+    /* tst-audit25a and tst-audit25mod1 are built with -Wl,-z,now, but
+       tst-audit25mod2 is built with -Wl,z,lazy.  So only
+       tst_audit25mod4_func1 (called by tst_audit25mod2_func1) should not
+       have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  */
+    TEST_COMPARE_STRING (result.err.buffer,
+			 "la_symbind: tst_audit25mod3_func1 1\n"
+			 "la_symbind: tst_audit25mod1_func1 1\n"
+			 "la_symbind: tst_audit25mod2_func1 1\n"
+			 "la_symbind: tst_audit25mod1_func2 1\n"
+			 "la_symbind: tst_audit25mod2_func2 1\n"
+			 "la_symbind: tst_audit25mod4_func1 0\n");
+
+    support_capture_subprocess_free (&result);
+  }
+
+  {
+    setenv ("LD_BIND_NOW", "1", 0);
+    struct support_capture_subprocess result
+      = support_capture_subprogram (spargv[0], spargv);
+    support_capture_subprocess_check (&result, "tst-audit25a", 0,
+				      sc_allow_stderr);
+
+    /* With LD_BIND_NOW all symbols are expected to have
+       LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  Also the resolution
+       order is done in breadth-first order.  */
+    TEST_COMPARE_STRING (result.err.buffer,
+			 "la_symbind: tst_audit25mod4_func1 1\n"
+			 "la_symbind: tst_audit25mod3_func1 1\n"
+			 "la_symbind: tst_audit25mod1_func1 1\n"
+			 "la_symbind: tst_audit25mod2_func1 1\n"
+			 "la_symbind: tst_audit25mod1_func2 1\n"
+			 "la_symbind: tst_audit25mod2_func2 1\n");
+
+    support_capture_subprocess_free (&result);
+  }
+
+  return 0;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
diff --git a/elf/tst-audit25mod1.c b/elf/tst-audit25mod1.c
new file mode 100644
index 0000000000..3cff8cc688
--- /dev/null
+++ b/elf/tst-audit25mod1.c
@@ -0,0 +1,30 @@
+/* Modules used by tst-audit25.
+   Copyright (C) 2022 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/>.  */
+
+void tst_audit25mod3_func1 (void);
+
+void
+tst_audit25mod1_func1 (void)
+{
+  tst_audit25mod3_func1 ();
+}
+
+void
+tst_audit25mod1_func2 (void)
+{
+}
diff --git a/elf/tst-audit25mod2.c b/elf/tst-audit25mod2.c
new file mode 100644
index 0000000000..5e40555fa9
--- /dev/null
+++ b/elf/tst-audit25mod2.c
@@ -0,0 +1,30 @@
+/* Modules used by tst-audit25.
+   Copyright (C) 2022 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/>.  */
+
+void tst_audit25mod4_func1 (void);
+
+void
+tst_audit25mod2_func1 (void)
+{
+  tst_audit25mod4_func1 ();
+}
+
+void
+tst_audit25mod2_func2 (void)
+{
+}
diff --git a/elf/tst-audit25mod3.c b/elf/tst-audit25mod3.c
new file mode 100644
index 0000000000..e35ed6a1da
--- /dev/null
+++ b/elf/tst-audit25mod3.c
@@ -0,0 +1,22 @@
+/* Modules used by tst-audit25.
+   Copyright (C) 2022 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/>.  */
+
+void
+tst_audit25mod3_func1 (void)
+{
+}
diff --git a/elf/tst-audit25mod4.c b/elf/tst-audit25mod4.c
new file mode 100644
index 0000000000..c3118b6368
--- /dev/null
+++ b/elf/tst-audit25mod4.c
@@ -0,0 +1,22 @@
+/* Modules used by tst-audit25.
+   Copyright (C) 2022 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/>.  */
+
+void
+tst_audit25mod4_func1 (void)
+{
+}
diff --git a/elf/tst-auditmod24.h b/elf/tst-auditmod24.h
new file mode 100644
index 0000000000..e34c53df5e
--- /dev/null
+++ b/elf/tst-auditmod24.h
@@ -0,0 +1,29 @@
+/* Auxiliary functions for tst-audit24x.
+   Copyright (C) 2022 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/>.  */
+
+#ifndef _TST_AUDITMOD24_H
+#define _TST_AUDITMOD24_H
+
+static void
+check_symbind_flags (unsigned int flags)
+{
+  if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0)
+    abort ();
+}
+
+#endif
diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c
new file mode 100644
index 0000000000..a4838b3e05
--- /dev/null
+++ b/elf/tst-auditmod24a.c
@@ -0,0 +1,114 @@
+/* Audit modules for tst-audit24a.
+   Copyright (C) 2022 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/>.  */
+
+#include <link.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tst-auditmod24.h>
+
+#define AUDIT24_COOKIE     0x1
+#define AUDIT24MOD1_COOKIE 0x2
+#define AUDIT24MOD2_COOKIE 0x3
+
+#ifndef TEST_NAME
+# define TEST_NAME "tst-audit24a"
+#endif
+#ifndef TEST_MOD
+# define TEST_MOD TEST_NAME
+#endif
+#ifndef TEST_FUNC
+# define TEST_FUNC "tst_audit24a"
+#endif
+
+unsigned int
+la_version (unsigned int version)
+{
+  return LAV_CURRENT;
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+  const char *p = strrchr (map->l_name, '/');
+  const char *l_name = p == NULL ? TEST_NAME : p + 1;
+
+  uintptr_t ck = -1;
+  if (strcmp (l_name, TEST_MOD "mod1.so") == 0)
+    ck = AUDIT24MOD1_COOKIE;
+  else if (strcmp (l_name, TEST_MOD "mod2.so") == 0)
+    ck = AUDIT24MOD2_COOKIE;
+  else if (strcmp (l_name, TEST_NAME) == 0)
+    ck = AUDIT24_COOKIE;
+
+  *cookie = ck;
+  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
+}
+
+static int
+tst_func1 (void)
+{
+  return 1;
+}
+
+static int
+tst_func2 (void)
+{
+  return 10;
+}
+
+#if __ELF_NATIVE_CLASS == 64
+uintptr_t
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
+	      uintptr_t *refcook, uintptr_t *defcook,
+	      unsigned int *flags, const char *symname)
+#else
+uintptr_t
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
+	      uintptr_t *refcook, uintptr_t *defcook,
+	      unsigned int *flags, const char *symname)
+#endif
+{
+  if (*refcook == AUDIT24_COOKIE)
+    {
+      if (*defcook == AUDIT24MOD1_COOKIE)
+	{
+	  /* Check if bind-now symbols are advertised to not call the PLT
+	     hooks.  */
+	  check_symbind_flags (*flags);
+
+	  if (strcmp (symname, TEST_FUNC "mod1_func1") == 0)
+	    return (uintptr_t) tst_func1;
+	  else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0)
+	    return sym->st_value;
+	  abort ();
+	}
+      if (*defcook == AUDIT24MOD2_COOKIE
+	  && (strcmp (symname, TEST_FUNC "mod2_func1") == 0))
+	{
+	  check_symbind_flags (*flags);
+
+	  return (uintptr_t) tst_func2;
+	}
+
+      /* malloc functions.  */
+      return sym->st_value;
+    }
+
+  abort ();
+}
diff --git a/elf/tst-auditmod24b.c b/elf/tst-auditmod24b.c
new file mode 100644
index 0000000000..aefac8ced4
--- /dev/null
+++ b/elf/tst-auditmod24b.c
@@ -0,0 +1,104 @@
+/* Audit modules for tst-audit24b.
+   Copyright (C) 2022 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/>.  */
+
+#include <link.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tst-auditmod24.h>
+
+#define TEST_NAME "tst-audit24b"
+#define TEST_FUNC "tst_audit24b"
+
+#define AUDIT24_COOKIE     0x1
+#define AUDIT24MOD1_COOKIE 0x2
+#define AUDIT24MOD2_COOKIE 0x3
+
+unsigned int
+la_version (unsigned int version)
+{
+  return LAV_CURRENT;
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+  const char *p = strrchr (map->l_name, '/');
+  const char *l_name = p == NULL ? TEST_NAME : p + 1;
+
+  uintptr_t ck = -1;
+  if (strcmp (l_name, TEST_NAME "mod1.so") == 0)
+    ck = AUDIT24MOD1_COOKIE;
+  else if (strcmp (l_name, TEST_NAME "mod2.so") == 0)
+    ck = AUDIT24MOD2_COOKIE;
+  else if (strcmp (l_name, TEST_NAME) == 0)
+    ck = AUDIT24_COOKIE;
+
+  *cookie = ck;
+  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
+}
+
+static int
+tst_func1 (void)
+{
+  return 1;
+}
+
+static int
+tst_func2 (void)
+{
+  return 2;
+}
+
+#if __ELF_NATIVE_CLASS == 64
+uintptr_t
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
+	      uintptr_t *refcook, uintptr_t *defcook,
+	      unsigned int *flags, const char *symname)
+#else
+uintptr_t
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
+	      uintptr_t *refcook, uintptr_t *defcook,
+	      unsigned int *flags, const char *symname)
+#endif
+{
+  if (*refcook == AUDIT24_COOKIE)
+    {
+      if (*defcook == AUDIT24MOD1_COOKIE)
+	  {
+	    if (strcmp (symname, TEST_FUNC "mod1_func1") == 0)
+	      return (uintptr_t) tst_func1;
+	    else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0)
+	      return sym->st_value;
+	    abort ();
+	  }
+      /* malloc functions.  */
+      return sym->st_value;
+    }
+  else if (*refcook == AUDIT24MOD1_COOKIE)
+    {
+      if (*defcook == AUDIT24MOD2_COOKIE
+	  && (strcmp (symname, TEST_FUNC "mod2_func1") == 0))
+	{
+	  check_symbind_flags (*flags);
+	  return (uintptr_t) tst_func2;
+	}
+    }
+
+  abort ();
+}
diff --git a/elf/tst-auditmod24c.c b/elf/tst-auditmod24c.c
new file mode 100644
index 0000000000..67e62c9d33
--- /dev/null
+++ b/elf/tst-auditmod24c.c
@@ -0,0 +1,3 @@
+#define TEST_NAME "tst-audit24c"
+#define TEST_MOD  "tst-audit24a"
+#include "tst-auditmod24a.c"
diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c
new file mode 100644
index 0000000000..a49f00ef17
--- /dev/null
+++ b/elf/tst-auditmod24d.c
@@ -0,0 +1,120 @@
+/* Audit module for tst-audit24d.
+   Copyright (C) 2022 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/>.  */
+
+#include <link.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tst-auditmod24.h>
+
+#define AUDIT24_COOKIE     0x0
+#define AUDIT24MOD1_COOKIE 0x1
+#define AUDIT24MOD2_COOKIE 0x2
+#define AUDIT24MOD3_COOKIE 0x3
+#define AUDIT24MOD4_COOKIE 0x4
+
+unsigned int
+la_version (unsigned int version)
+{
+  return LAV_CURRENT;
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+  const char *p = strrchr (map->l_name, '/');
+  const char *l_name = p == NULL ? "tst-audit24d" : p + 1;
+
+  uintptr_t ck = -1;
+  if (strcmp (l_name, "tst-audit24dmod1.so") == 0)
+    ck = AUDIT24MOD1_COOKIE;
+  else if (strcmp (l_name, "tst-audit24dmod2.so") == 0)
+    ck = AUDIT24MOD2_COOKIE;
+  else if (strcmp (l_name, "tst-audit24dmod3.so") == 0)
+    ck = AUDIT24MOD3_COOKIE;
+  else if (strcmp (l_name, "tst-audit24dmod.so") == 0)
+    ck = AUDIT24MOD4_COOKIE;
+  else if (strcmp (l_name, "tst-audit24d") == 0)
+    ck = AUDIT24_COOKIE;
+
+  *cookie = ck;
+  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
+}
+
+static int
+tst_audit24dmod1_func1 (void)
+{
+  return 1;
+}
+
+static int
+tst_audit24dmod2_func1 (void)
+{
+  return 10;
+}
+
+static int
+tst_audit24dmod3_func1 (void)
+{
+  return 30;
+}
+
+#include <stdio.h>
+
+#if __ELF_NATIVE_CLASS == 64
+uintptr_t
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
+	      uintptr_t *refcook, uintptr_t *defcook,
+	      unsigned int *flags, const char *symname)
+#else
+uintptr_t
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
+	      uintptr_t *refcook, uintptr_t *defcook,
+	      unsigned int *flags, const char *symname)
+#endif
+{
+  if (*refcook == AUDIT24_COOKIE)
+    {
+      if (*defcook == AUDIT24MOD1_COOKIE)
+	  {
+	    if (strcmp (symname, "tst_audit24dmod1_func1") == 0)
+	      return (uintptr_t) tst_audit24dmod1_func1;
+	    else if (strcmp (symname, "tst_audit24dmod1_func2") == 0)
+	      return sym->st_value;
+	    abort ();
+	  }
+      if (*defcook == AUDIT24MOD2_COOKIE
+	  && (strcmp (symname, "tst_audit24dmod2_func1") == 0))
+	return (uintptr_t) tst_audit24dmod2_func1;
+
+      /* malloc functions.  */
+      return sym->st_value;
+    }
+  else if (*refcook == AUDIT24MOD1_COOKIE)
+    {
+      if (*defcook == AUDIT24MOD3_COOKIE
+	  && strcmp (symname, "tst_audit24dmod3_func1") == 0)
+	{
+	  check_symbind_flags (*flags);
+
+	  return (uintptr_t) tst_audit24dmod3_func1;
+	}
+    }
+
+  abort ();
+}
diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c
new file mode 100644
index 0000000000..526f5c54bc
--- /dev/null
+++ b/elf/tst-auditmod25.c
@@ -0,0 +1,79 @@
+/* Audit modules for tst-audit25a.
+   Copyright (C) 2022 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/>.  */
+
+#include <link.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#define AUDIT25_COOKIE     0x1
+#define AUDIT25MOD1_COOKIE 0x2
+#define AUDIT25MOD2_COOKIE 0x3
+#define AUDIT25MOD3_COOKIE 0x2
+#define AUDIT25MOD4_COOKIE 0x3
+
+#define TEST_NAME "tst-audit25"
+#define TEST_MOD  "tst-audit25"
+#define TEST_FUNC "tst_audit25"
+
+unsigned int
+la_version (unsigned int version)
+{
+  return LAV_CURRENT;
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+  const char *p = strrchr (map->l_name, '/');
+  const char *l_name = p == NULL ? TEST_NAME : p + 1;
+
+  uintptr_t ck = -1;
+  if (strcmp (l_name, TEST_MOD "mod1.so") == 0)
+    ck = AUDIT25MOD1_COOKIE;
+  else if (strcmp (l_name, TEST_MOD "mod2.so") == 0)
+    ck = AUDIT25MOD2_COOKIE;
+  else if (strcmp (l_name, TEST_MOD "mod3.so") == 0)
+    ck = AUDIT25MOD3_COOKIE;
+  else if (strcmp (l_name, TEST_MOD "mod4.so") == 0)
+    ck = AUDIT25MOD4_COOKIE;
+  else if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
+    ck = AUDIT25_COOKIE;
+
+  *cookie = ck;
+  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
+}
+
+#if __ELF_NATIVE_CLASS == 64
+uintptr_t
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
+	      uintptr_t *refcook, uintptr_t *defcook,
+	      unsigned int *flags, const char *symname)
+#else
+uintptr_t
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
+	      uintptr_t *refcook, uintptr_t *defcook,
+	      unsigned int *flags, const char *symname)
+#endif
+{
+  if (*refcook != -1 && *defcook != -1)
+    fprintf (stderr, "la_symbind: %s %u\n", symname,
+	     *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);
+  return sym->st_value;
+}
diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h
index 7460c0596a..95bcfc1cc1 100644
--- a/sysdeps/generic/dl-lookupcfg.h
+++ b/sysdeps/generic/dl-lookupcfg.h
@@ -26,3 +26,6 @@
 #define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
 #define DL_FIXUP_VALUE_ADDR(value) (value)
 #define DL_FIXUP_ADDR_VALUE(addr) (addr)
+#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
+#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
+  (*value) = st_value;
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 97061bdf9f..2ebe7901c0 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1431,7 +1431,10 @@ void _dl_audit_objclose (struct link_map *l)
 /* Call the la_preinit from the audit modules for the link_map L.  */
 void _dl_audit_preinit (struct link_map *l);
 
-/* Call the la_symbind{32,64} from the audit modules for the link_map L.  */
+/* Call the la_symbind{32,64} from the audit modules for the link_map L.  If
+   RELOC_RESULT is NULL it assumes the symbol to be bind-now and will set
+   the flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT prior calling
+   la_symbind{32,64}.  */
 void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
 			const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
 			lookup_t result)
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
index 5d381147c0..8da2412fea 100644
--- a/sysdeps/hppa/dl-lookupcfg.h
+++ b/sysdeps/hppa/dl-lookupcfg.h
@@ -80,3 +80,6 @@ void attribute_hidden _dl_unmap (struct link_map *map);
 #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
 #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
 #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
+#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
+#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
+  (*value) = *(struct fdesc *) (st_value)
diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h
index b8ab1bba15..3df3116b31 100644
--- a/sysdeps/ia64/dl-lookupcfg.h
+++ b/sysdeps/ia64/dl-lookupcfg.h
@@ -74,3 +74,6 @@ extern void attribute_hidden _dl_unmap (struct link_map *map);
 
 #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
 #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
+#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
+#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
+  (*value) = *(struct fdesc *) (st_value)
diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h
new file mode 100644
index 0000000000..25abcc1d12
--- /dev/null
+++ b/sysdeps/powerpc/dl-lookupcfg.h
@@ -0,0 +1,39 @@
+/* Configuration of lookup functions.  PowerPC version.
+   Copyright (C) 2022 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/>.  */
+
+#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
+#define DL_FIXUP_MAKE_VALUE(map, addr) (addr)
+#define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
+#define DL_FIXUP_VALUE_ADDR(value) (value)
+#define DL_FIXUP_ADDR_VALUE(addr) (addr)
+#if __WORDSIZE == 64 && _CALL_ELF == 1
+/* We need to correctly set the audit modules value for bind-now.  */
+# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \
+ (((Elf64_FuncDesc *)(addr))->fd_func)
+# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value)	\
+ ({								\
+    Elf64_FuncDesc *opd = (Elf64_FuncDesc *) (value);		\
+    opd->fd_func = (st_value);					\
+    if ((new_value) != (uintptr_t) (st_value))			\
+     opd->fd_toc = ((Elf64_FuncDesc *)(new_value))->fd_toc;	\
+  })
+#else
+# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
+# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value)	\
+  (*value) = st_value;
+#endif
-- 
2.32.0


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v12 4/4] elf: Fix runtime linker auditing on aarch64 (BZ #26643)
  2022-01-25 18:36 [PATCH v12 0/4] Multiple rtld-audit fixes Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2022-01-25 18:36 ` [PATCH v12 3/4] elf: Issue la_symbind for bind-now (BZ #23734) Adhemerval Zanella
@ 2022-01-25 18:37 ` Adhemerval Zanella
  2022-02-01  6:19   ` Carlos O'Donell
  2022-02-01  6:45 ` [PATCH v12 0/4] Multiple rtld-audit fixes Carlos O'Donell
  4 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2022-01-25 18:37 UTC (permalink / raw)
  To: libc-alpha, jma14, Carlos O'Donell
  Cc: John Mellor-Crummey, Ben Woodard, Szabolcs Nagy

From: Ben Woodard <woodard@redhat.com>

The rtld audit support show two problems on aarch64:

  1. _dl_runtime_resolve does not preserve x8, the indirect result
      location register, which might generate wrong result calls
      depending of the function signature.

  2. The NEON Q registers pushed onto the stack by _dl_runtime_resolve
     were twice the size of D registers extracted from the stack frame by
     _dl_runtime_profile.

While 2. might result in wrong information passed on the PLT tracing,
1. generates wrong runtime behaviour.

The aarch64 rtld audit support is change to:

  * Both La_aarch64_regs and La_aarch64_retval are expanded to include
    both x8 and the full sized NEON V registers, as defined by the
    ABI.

  * dl_runtime_profile needed to extract registers saved by
    _dl_runtime_resolve and put them into the new correctly sized
    La_aarch64_regs structure.

  * The LAV_CURRENT check is change to only accept new audit modules
    to avoid the undefined behavior of not save/restore x8.

  * Different than other architectures, audit modules older than
    LAV_CURRENT are rejected (both La_aarch64_regs and La_aarch64_retval
    changed their layout and the it does worth the to support multiple
    audit interface with the inherent aarch64 issues).

  * A new field is also reserved on both La_aarch64_regs and
    La_aarch64_retval to support variant pcs symbols.

Similar to x86, a new La_aarch64_vector type to represent the NEON
register is added on the La_aarch64_regs (so each type can be accessed
directly).

Since LAV_CURRENT was already bumped to support bind-now, there is
no need to increase it again.

Checked on aarch64-linux-gnu.

Co-authored-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
---
 NEWS                             |   4 +
 elf/rtld.c                       |   3 +-
 sysdeps/aarch64/Makefile         |  20 ++++
 sysdeps/aarch64/bits/link.h      |  26 +++--
 sysdeps/aarch64/dl-audit-check.h |  28 +++++
 sysdeps/aarch64/dl-link.sym      |   6 +-
 sysdeps/aarch64/dl-trampoline.S  |  81 +++++++++-----
 sysdeps/aarch64/tst-audit26.c    |  37 +++++++
 sysdeps/aarch64/tst-audit26mod.c |  33 ++++++
 sysdeps/aarch64/tst-audit26mod.h |  50 +++++++++
 sysdeps/aarch64/tst-audit27.c    |  64 +++++++++++
 sysdeps/aarch64/tst-audit27mod.c |  95 ++++++++++++++++
 sysdeps/aarch64/tst-audit27mod.h |  67 ++++++++++++
 sysdeps/aarch64/tst-auditmod26.c | 103 ++++++++++++++++++
 sysdeps/aarch64/tst-auditmod27.c | 180 +++++++++++++++++++++++++++++++
 sysdeps/generic/dl-audit-check.h |  23 ++++
 16 files changed, 779 insertions(+), 41 deletions(-)
 create mode 100644 sysdeps/aarch64/dl-audit-check.h
 create mode 100644 sysdeps/aarch64/tst-audit26.c
 create mode 100644 sysdeps/aarch64/tst-audit26mod.c
 create mode 100644 sysdeps/aarch64/tst-audit26mod.h
 create mode 100644 sysdeps/aarch64/tst-audit27.c
 create mode 100644 sysdeps/aarch64/tst-audit27mod.c
 create mode 100644 sysdeps/aarch64/tst-audit27mod.h
 create mode 100644 sysdeps/aarch64/tst-auditmod26.c
 create mode 100644 sysdeps/aarch64/tst-auditmod27.c
 create mode 100644 sysdeps/generic/dl-audit-check.h

diff --git a/NEWS b/NEWS
index c0f8932f84..40623d01c0 100644
--- a/NEWS
+++ b/NEWS
@@ -162,6 +162,10 @@ Deprecated and removed features, and other changes affecting compatibility:
   proper bind-now support.  The loader now advertises on the la_symbind
   flags that PLT trace is not possible.
 
+* The audit interface on aarch64 is extended to support both the indirect
+  result location register (x8) and NEON Q register.  Old audit modules are
+  rejected by the loader.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/elf/rtld.c b/elf/rtld.c
index 10436f7034..8dafaf61f4 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -52,6 +52,7 @@
 #include <get-dynamic-info.h>
 #include <dl-execve.h>
 #include <dl-find_object.h>
+#include <dl-audit-check.h>
 
 #include <assert.h>
 
@@ -1000,7 +1001,7 @@ file=%s [%lu]; audit interface function la_version returned zero; ignored.\n",
       return;
     }
 
-  if (lav > LAV_CURRENT)
+  if (!_dl_audit_check_version (lav))
     {
       _dl_debug_printf ("\
 ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n",
diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
index 7c66fb97aa..7183895d04 100644
--- a/sysdeps/aarch64/Makefile
+++ b/sysdeps/aarch64/Makefile
@@ -10,6 +10,26 @@ endif
 
 ifeq ($(subdir),elf)
 sysdep-dl-routines += dl-bti
+
+tests += tst-audit26 \
+	 tst-audit27
+
+modules-names += \
+    tst-audit26mod \
+    tst-auditmod26 \
+    tst-audit27mod \
+    tst-auditmod27
+
+$(objpfx)tst-audit26: $(objpfx)tst-audit26mod.so \
+		      $(objpfx)tst-auditmod26.so
+LDFLAGS-tst-audit26 += -Wl,-z,lazy
+tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so
+
+$(objpfx)tst-audit27: $(objpfx)tst-audit27mod.so \
+		      $(objpfx)tst-auditmod27.so
+$(objpfx)tst-audit27mod.so: $(libsupport)
+LDFLAGS-tst-audit27 += -Wl,-z,lazy
+tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so
 endif
 
 ifeq ($(subdir),elf)
diff --git a/sysdeps/aarch64/bits/link.h b/sysdeps/aarch64/bits/link.h
index e64f36d3f3..2479abc4fb 100644
--- a/sysdeps/aarch64/bits/link.h
+++ b/sysdeps/aarch64/bits/link.h
@@ -20,23 +20,31 @@
 # error "Never include <bits/link.h> directly; use <link.h> instead."
 #endif
 
+typedef union
+{
+  float s;
+  double d;
+  long double q;
+} La_aarch64_vector;
+
 /* Registers for entry into PLT on AArch64.  */
 typedef struct La_aarch64_regs
 {
-  uint64_t lr_xreg[8];
-  uint64_t lr_dreg[8];
-  uint64_t lr_sp;
-  uint64_t lr_lr;
+  uint64_t          lr_xreg[9];
+  La_aarch64_vector lr_vreg[8];
+  uint64_t          lr_sp;
+  uint64_t          lr_lr;
+  void              *lr_vpcs;
 } La_aarch64_regs;
 
 /* Return values for calls from PLT on AArch64.  */
 typedef struct La_aarch64_retval
 {
-  /* Up to two integer registers can be used for a return value.  */
-  uint64_t lrv_xreg[2];
-  /* Up to four D registers can be used for a return value.  */
-  uint64_t lrv_dreg[4];
-
+  /* Up to eight integer registers can be used for a return value.  */
+  uint64_t          lrv_xreg[8];
+  /* Up to eight V registers can be used for a return value.  */
+  La_aarch64_vector lrv_vreg[8];
+  void              *lrv_vpcs;
 } La_aarch64_retval;
 __BEGIN_DECLS
 
diff --git a/sysdeps/aarch64/dl-audit-check.h b/sysdeps/aarch64/dl-audit-check.h
new file mode 100644
index 0000000000..181eba0e8e
--- /dev/null
+++ b/sysdeps/aarch64/dl-audit-check.h
@@ -0,0 +1,28 @@
+/* rtld-audit version check.  AArch64 version.
+   Copyright (C) 2022 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/>.  */
+
+static inline bool
+_dl_audit_check_version (unsigned int lav)
+{
+  /* Audit version 1 do not save neither x8 nor NEON register, which required
+     change La_aarch64_regs and La_aarch64_retval layout (BZ#26643).  The
+     missing indirect result save/restore makes _dl_runtime_profile
+     potentially trigger undefined behavior if function returns a large
+     struct (even when PLT trace is not requested).  */
+  return lav == LAV_CURRENT;
+}
diff --git a/sysdeps/aarch64/dl-link.sym b/sysdeps/aarch64/dl-link.sym
index d67d28b40c..cb4dcdcbed 100644
--- a/sysdeps/aarch64/dl-link.sym
+++ b/sysdeps/aarch64/dl-link.sym
@@ -7,9 +7,11 @@ DL_SIZEOF_RG		sizeof(struct La_aarch64_regs)
 DL_SIZEOF_RV		sizeof(struct La_aarch64_retval)
 
 DL_OFFSET_RG_X0		offsetof(struct La_aarch64_regs, lr_xreg)
-DL_OFFSET_RG_D0		offsetof(struct La_aarch64_regs, lr_dreg)
+DL_OFFSET_RG_V0		offsetof(struct La_aarch64_regs, lr_vreg)
 DL_OFFSET_RG_SP		offsetof(struct La_aarch64_regs, lr_sp)
 DL_OFFSET_RG_LR		offsetof(struct La_aarch64_regs, lr_lr)
+DL_OFFSET_RG_VPCS       offsetof(struct La_aarch64_regs, lr_vpcs)
 
 DL_OFFSET_RV_X0		offsetof(struct La_aarch64_retval, lrv_xreg)
-DL_OFFSET_RV_D0		offsetof(struct La_aarch64_retval, lrv_dreg)
+DL_OFFSET_RV_V0		offsetof(struct La_aarch64_retval, lrv_vreg)
+DL_OFFSET_RV_VPCS       offsetof(struct La_aarch64_retval, lrv_vpcs)
diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
index a403863ef9..a7fc34639b 100644
--- a/sysdeps/aarch64/dl-trampoline.S
+++ b/sysdeps/aarch64/dl-trampoline.S
@@ -45,7 +45,8 @@ _dl_runtime_resolve:
 
 	cfi_rel_offset (lr, 8)
 
-	/* Save arguments.  */
+	/* Note: Saving x9 is not required by the ABI but the assember requires
+	   the immediate values of operand 3 to be a multiple of 16 */
 	stp	x8, x9, [sp, #-(80+8*16)]!
 	cfi_adjust_cfa_offset (80+8*16)
 	cfi_rel_offset (x8, 0)
@@ -142,7 +143,7 @@ _dl_runtime_profile:
 	   Stack frame layout:
 	   [sp,   #...] lr
 	   [sp,   #...] &PLTGOT[n]
-	   [sp,    #96] La_aarch64_regs
+	   [sp,   #256] La_aarch64_regs
 	   [sp,    #48] La_aarch64_retval
 	   [sp,    #40] frame size return from pltenter
 	   [sp,    #32] dl_profile_call saved x1
@@ -183,19 +184,25 @@ _dl_runtime_profile:
 	stp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
 	cfi_rel_offset (x6, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 0)
 	cfi_rel_offset (x7, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 8)
-
-	stp	d0, d1, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
-	cfi_rel_offset (d0, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0)
-	cfi_rel_offset (d1, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0 + 8)
-	stp	d2, d3, [X29, #OFFSET_RG+ DL_OFFSET_RG_D0 + 16*1]
-	cfi_rel_offset (d2, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 0)
-	cfi_rel_offset (d3, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 8)
-	stp	d4, d5, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
-	cfi_rel_offset (d4, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 0)
-	cfi_rel_offset (d5, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 8)
-	stp	d6, d7, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
-	cfi_rel_offset (d6, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 0)
-	cfi_rel_offset (d7, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 8)
+	str	x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0]
+	cfi_rel_offset (x8, OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0)
+	/* Note 8 bytes of padding is in the stack frame for alignment */
+
+	stp	q0, q1, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
+	cfi_rel_offset (q0, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0)
+	cfi_rel_offset (q1, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0 + 16)
+	stp	q2, q3, [X29, #OFFSET_RG+ DL_OFFSET_RG_V0 + 32*1]
+	cfi_rel_offset (q2, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 0)
+	cfi_rel_offset (q3, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 16)
+	stp	q4, q5, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
+	cfi_rel_offset (q4, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 0)
+	cfi_rel_offset (q5, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 16)
+	stp	q6, q7, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]
+	cfi_rel_offset (q6, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 0)
+	cfi_rel_offset (q7, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 16)
+
+	/* No APCS extension supported.  */
+	str	xzr,    [X29, #OFFSET_RG + DL_OFFSET_RG_VPCS]
 
 	add     x0, x29, #SF_SIZE + 16
 	ldr	x1, [x29, #OFFSET_LR]
@@ -234,10 +241,11 @@ _dl_runtime_profile:
 	ldp	x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
 	ldp	x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
 	ldp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
-	ldp	d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
-	ldp	d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
-	ldp	d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
-	ldp	d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
+	ldr	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
+	ldp	q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
+	ldp	q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1]
+	ldp	q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
+	ldp	q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]
 
 	cfi_def_cfa_register (sp)
 	ldp	x29, x30, [x29, #0]
@@ -280,14 +288,22 @@ _dl_runtime_profile:
 	ldp	x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
 	ldp	x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
 	ldp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
-	ldp	d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
-	ldp	d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
-	ldp	d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
-	ldp	d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
+	ldr	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
+	ldp	q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
+	ldp	q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1]
+	ldp	q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
+	ldp	q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]
 	blr	ip0
-	stp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
-	stp	d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
-	stp	d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
+	stp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0]
+	stp	x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
+	stp	x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
+	stp	x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
+	str	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
+	stp	q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
+	stp	q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
+	stp	q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
+	stp	q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3]
+	str	xzr,    [X29, #OFFSET_RV + DL_OFFSET_RG_VPCS]
 
 	/* Setup call to pltexit  */
 	ldp	x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
@@ -295,9 +311,16 @@ _dl_runtime_profile:
 	add	x3, x29, #OFFSET_RV
 	bl	_dl_audit_pltexit
 
-	ldp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
-	ldp	d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
-	ldp	d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
+	ldp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0]
+	ldp	x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
+	ldp	x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
+	ldp	x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
+	ldr	x8,     [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*4]
+	ldp	q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
+	ldp	q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
+	ldp	q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
+	ldp	q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3]
+
 	/* LR from within La_aarch64_reg */
 	ldr	lr, [x29, #OFFSET_RG + DL_OFFSET_RG_LR]
 	cfi_restore(lr)
diff --git a/sysdeps/aarch64/tst-audit26.c b/sysdeps/aarch64/tst-audit26.c
new file mode 100644
index 0000000000..8772958541
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit26.c
@@ -0,0 +1,37 @@
+/* Check DT_AUDIT for aarch64 ABI specifics.
+   Copyright (C) 2022 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/>.  */
+
+#include <array_length.h>
+#include <string.h>
+#include <support/check.h>
+#include "tst-audit26mod.h"
+
+int
+do_test (void)
+{
+  /* Returning a large struct uses 'x8' as indirect result location.  */
+  struct large_struct r = tst_audit26_func (ARG1, ARG2, ARG3);
+
+  struct large_struct e = set_large_struct (ARG1, ARG2, ARG3);
+
+  TEST_COMPARE_BLOB (r.a, sizeof (r.a), e.a, sizeof (e.a));
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/aarch64/tst-audit26mod.c b/sysdeps/aarch64/tst-audit26mod.c
new file mode 100644
index 0000000000..8d309be575
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit26mod.c
@@ -0,0 +1,33 @@
+/* Check DT_AUDIT for aarch64 ABI specifics.
+   Copyright (C) 2022 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/>.  */
+
+#include <stdlib.h>
+#include "tst-audit26mod.h"
+
+struct large_struct
+tst_audit26_func (char a, short b, long int c)
+{
+  if (a != ARG1)
+    abort ();
+  if (b != ARG2)
+    abort ();
+  if (c != ARG3)
+    abort ();
+
+  return set_large_struct (a, b, c);
+}
diff --git a/sysdeps/aarch64/tst-audit26mod.h b/sysdeps/aarch64/tst-audit26mod.h
new file mode 100644
index 0000000000..4226fad8cd
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit26mod.h
@@ -0,0 +1,50 @@
+/* Check DT_AUDIT for aarch64 specific ABI.
+   Copyright (C) 2022 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/>.  */
+
+#ifndef _TST_AUDIT27MOD_H
+#define _TST_AUDIT27MOD_H 1
+
+#include <array_length.h>
+
+struct large_struct
+{
+  char a[16];
+  short b[8];
+  long int c[4];
+};
+
+static inline struct large_struct
+set_large_struct (char a, short b, long int c)
+{
+  struct large_struct r;
+  for (int i = 0; i < array_length (r.a); i++)
+    r.a[i] = a;
+  for (int i = 0; i < array_length (r.b); i++)
+    r.b[i] = b;
+  for (int i = 0; i < array_length (r.c); i++)
+    r.c[i] = c;
+  return r;
+}
+
+#define ARG1 0x12
+#define ARG2 0x1234
+#define ARG3 0x12345678
+
+struct large_struct tst_audit26_func (char a, short b, long int c);
+
+#endif
diff --git a/sysdeps/aarch64/tst-audit27.c b/sysdeps/aarch64/tst-audit27.c
new file mode 100644
index 0000000000..f5017ce0f1
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit27.c
@@ -0,0 +1,64 @@
+/* Check DT_AUDIT for aarch64 ABI specifics.
+   Copyright (C) 2022 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/>.  */
+
+#include <array_length.h>
+#include <string.h>
+#include <support/check.h>
+#include "tst-audit27mod.h"
+
+int
+do_test (void)
+{
+  {
+    float r = tst_audit27_func_float (FUNC_FLOAT_ARG0, FUNC_FLOAT_ARG1,
+				      FUNC_FLOAT_ARG2, FUNC_FLOAT_ARG3,
+				      FUNC_FLOAT_ARG4, FUNC_FLOAT_ARG5,
+				      FUNC_FLOAT_ARG6, FUNC_FLOAT_ARG7);
+    if (r != FUNC_FLOAT_RET)
+      FAIL_EXIT1 ("tst_audit27_func_float() returned %a, expected %a",
+		  r, FUNC_FLOAT_RET);
+  }
+
+  {
+    double r = tst_audit27_func_double (FUNC_DOUBLE_ARG0, FUNC_DOUBLE_ARG1,
+					FUNC_DOUBLE_ARG2, FUNC_DOUBLE_ARG3,
+					FUNC_DOUBLE_ARG4, FUNC_DOUBLE_ARG5,
+					FUNC_DOUBLE_ARG6, FUNC_DOUBLE_ARG7);
+    if (r != FUNC_DOUBLE_RET)
+      FAIL_EXIT1 ("tst_audit27_func_double() returned %la, expected %la",
+		  r, FUNC_DOUBLE_RET);
+  }
+
+  {
+    long double r = tst_audit27_func_ldouble (FUNC_LDOUBLE_ARG0,
+					      FUNC_LDOUBLE_ARG1,
+					      FUNC_LDOUBLE_ARG2,
+					      FUNC_LDOUBLE_ARG3,
+					      FUNC_LDOUBLE_ARG4,
+					      FUNC_LDOUBLE_ARG5,
+					      FUNC_LDOUBLE_ARG6,
+					      FUNC_LDOUBLE_ARG7);
+    if (r != FUNC_LDOUBLE_RET)
+      FAIL_EXIT1 ("tst_audit27_func_ldouble() returned %La, expected %La",
+		  r, FUNC_LDOUBLE_RET);
+  }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/aarch64/tst-audit27mod.c b/sysdeps/aarch64/tst-audit27mod.c
new file mode 100644
index 0000000000..69f1d672b3
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit27mod.c
@@ -0,0 +1,95 @@
+/* Check DT_AUDIT for aarch64 ABI specifics.
+   Copyright (C) 2022 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/>.  */
+
+#include <array_length.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include "tst-audit27mod.h"
+
+float
+tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4,
+			float a5, float a6, float a7)
+{
+  if (a0 != FUNC_FLOAT_ARG0)
+    FAIL_EXIT1 ("a0: %a != %a", a0, FUNC_FLOAT_ARG0);
+  if (a1 != FUNC_FLOAT_ARG1)
+    FAIL_EXIT1 ("a1: %a != %a", a1, FUNC_FLOAT_ARG1);
+  if (a2 != FUNC_FLOAT_ARG2)
+    FAIL_EXIT1 ("a2: %a != %a", a2, FUNC_FLOAT_ARG2);
+  if (a3 != FUNC_FLOAT_ARG3)
+    FAIL_EXIT1 ("a3: %a != %a", a3, FUNC_FLOAT_ARG3);
+  if (a4 != FUNC_FLOAT_ARG4)
+    FAIL_EXIT1 ("a4: %a != %a", a4, FUNC_FLOAT_ARG4);
+  if (a5 != FUNC_FLOAT_ARG5)
+    FAIL_EXIT1 ("a5: %a != %a", a5, FUNC_FLOAT_ARG5);
+  if (a6 != FUNC_FLOAT_ARG6)
+    FAIL_EXIT1 ("a6: %a != %a", a6, FUNC_FLOAT_ARG6);
+  if (a7 != FUNC_FLOAT_ARG7)
+    FAIL_EXIT1 ("a7: %a != %a", a7, FUNC_FLOAT_ARG7);
+
+  return FUNC_FLOAT_RET;
+}
+
+double
+tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4,
+			 double a5, double a6, double a7)
+{
+  if (a0 != FUNC_DOUBLE_ARG0)
+    FAIL_EXIT1 ("a0: %la != %la", a0, FUNC_DOUBLE_ARG0);
+  if (a1 != FUNC_DOUBLE_ARG1)
+    FAIL_EXIT1 ("a1: %la != %la", a1, FUNC_DOUBLE_ARG1);
+  if (a2 != FUNC_DOUBLE_ARG2)
+    FAIL_EXIT1 ("a2: %la != %la", a2, FUNC_DOUBLE_ARG2);
+  if (a3 != FUNC_DOUBLE_ARG3)
+    FAIL_EXIT1 ("a3: %la != %la", a3, FUNC_DOUBLE_ARG3);
+  if (a4 != FUNC_DOUBLE_ARG4)
+    FAIL_EXIT1 ("a4: %la != %la", a4, FUNC_DOUBLE_ARG4);
+  if (a5 != FUNC_DOUBLE_ARG5)
+    FAIL_EXIT1 ("a5: %la != %la", a5, FUNC_DOUBLE_ARG5);
+  if (a6 != FUNC_DOUBLE_ARG6)
+    FAIL_EXIT1 ("a6: %la != %la", a6, FUNC_DOUBLE_ARG6);
+  if (a7 != FUNC_DOUBLE_ARG7)
+    FAIL_EXIT1 ("a7: %la != %la", a7, FUNC_DOUBLE_ARG7);
+
+  return FUNC_DOUBLE_RET;
+}
+
+long double
+tst_audit27_func_ldouble (long double a0, long double a1, long double a2,
+			  long double a3, long double a4, long double a5,
+			  long double a6, long double a7)
+{
+  if (a0 != FUNC_LDOUBLE_ARG0)
+    FAIL_EXIT1 ("a0: %La != %La", a0, FUNC_LDOUBLE_ARG0);
+  if (a1 != FUNC_LDOUBLE_ARG1)
+    FAIL_EXIT1 ("a1: %La != %La", a1, FUNC_LDOUBLE_ARG1);
+  if (a2 != FUNC_LDOUBLE_ARG2)
+    FAIL_EXIT1 ("a2: %La != %La", a2, FUNC_LDOUBLE_ARG2);
+  if (a3 != FUNC_LDOUBLE_ARG3)
+    FAIL_EXIT1 ("a3: %La != %La", a3, FUNC_LDOUBLE_ARG3);
+  if (a4 != FUNC_LDOUBLE_ARG4)
+    FAIL_EXIT1 ("a4: %La != %La", a4, FUNC_LDOUBLE_ARG4);
+  if (a5 != FUNC_LDOUBLE_ARG5)
+    FAIL_EXIT1 ("a5: %La != %La", a5, FUNC_LDOUBLE_ARG5);
+  if (a6 != FUNC_LDOUBLE_ARG6)
+    FAIL_EXIT1 ("a6: %La != %La", a6, FUNC_LDOUBLE_ARG6);
+  if (a7 != FUNC_LDOUBLE_ARG7)
+    FAIL_EXIT1 ("a7: %La != %La", a7, FUNC_LDOUBLE_ARG7);
+
+  return FUNC_LDOUBLE_RET;
+}
diff --git a/sysdeps/aarch64/tst-audit27mod.h b/sysdeps/aarch64/tst-audit27mod.h
new file mode 100644
index 0000000000..698df4d44f
--- /dev/null
+++ b/sysdeps/aarch64/tst-audit27mod.h
@@ -0,0 +1,67 @@
+/* Check DT_AUDIT for aarch64 specific ABI.
+   Copyright (C) 2022 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/>.  */
+
+#ifndef _TST_AUDIT27MOD_H
+#define _TST_AUDIT27MOD_H 1
+
+#include <float.h>
+
+#define FUNC_FLOAT_ARG0 FLT_MIN
+#define FUNC_FLOAT_ARG1 FLT_MAX
+#define FUNC_FLOAT_ARG2 FLT_EPSILON
+#define FUNC_FLOAT_ARG3 FLT_TRUE_MIN
+#define FUNC_FLOAT_ARG4 0.0f
+#define FUNC_FLOAT_ARG5 1.0f
+#define FUNC_FLOAT_ARG6 2.0f
+#define FUNC_FLOAT_ARG7 3.0f
+#define FUNC_FLOAT_RET  4.0f
+
+float
+tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4,
+			float a5, float a6, float a7);
+
+#define FUNC_DOUBLE_ARG0 DBL_MIN
+#define FUNC_DOUBLE_ARG1 DBL_MAX
+#define FUNC_DOUBLE_ARG2 DBL_EPSILON
+#define FUNC_DOUBLE_ARG3 DBL_TRUE_MIN
+#define FUNC_DOUBLE_ARG4 0.0
+#define FUNC_DOUBLE_ARG5 1.0
+#define FUNC_DOUBLE_ARG6 2.0
+#define FUNC_DOUBLE_ARG7 3.0
+#define FUNC_DOUBLE_RET  0x1.fffffe0000001p+127
+
+double
+tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4,
+			 double a5, double a6, double a7);
+
+#define FUNC_LDOUBLE_ARG0 DBL_MAX + 1.0L
+#define FUNC_LDOUBLE_ARG1 DBL_MAX + 2.0L
+#define FUNC_LDOUBLE_ARG2 DBL_MAX + 3.0L
+#define FUNC_LDOUBLE_ARG3 DBL_MAX + 4.0L
+#define FUNC_LDOUBLE_ARG4 DBL_MAX + 5.0L
+#define FUNC_LDOUBLE_ARG5 DBL_MAX + 6.0L
+#define FUNC_LDOUBLE_ARG6 DBL_MAX + 7.0L
+#define FUNC_LDOUBLE_ARG7 DBL_MAX + 8.0L
+#define FUNC_LDOUBLE_RET  0x1.fffffffffffff000000000000001p+1023L
+
+long double
+tst_audit27_func_ldouble (long double a0, long double a1, long double a2,
+			  long double a3, long double a4, long double a5,
+			  long double a6, long double a7);
+
+#endif
diff --git a/sysdeps/aarch64/tst-auditmod26.c b/sysdeps/aarch64/tst-auditmod26.c
new file mode 100644
index 0000000000..91d224dfbe
--- /dev/null
+++ b/sysdeps/aarch64/tst-auditmod26.c
@@ -0,0 +1,103 @@
+/* Check DT_AUDIT for aarch64 specific ABI.
+   Copyright (C) 2022 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/>.  */
+
+#include <assert.h>
+#include <link.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "tst-audit26mod.h"
+
+#define TEST_NAME  "tst-audit26"
+
+#define AUDIT26_COOKIE 0
+
+unsigned int
+la_version (unsigned int v)
+{
+  return v;
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+  const char *p = strrchr (map->l_name, '/');
+  const char *l_name = p == NULL ? map->l_name : p + 1;
+  uintptr_t ck = -1;
+  if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
+    ck = AUDIT26_COOKIE;
+  *cookie = ck;
+  printf ("objopen: %ld, %s [cookie=%ld]\n", lmid, l_name, ck);
+  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
+}
+
+ElfW(Addr)
+la_aarch64_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)),
+                         unsigned int ndx __attribute__ ((unused)),
+                         uintptr_t *refcook, uintptr_t *defcook,
+                         La_aarch64_regs *regs, unsigned int *flags,
+                         const char *symname, long int *framesizep)
+{
+  printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
+	  symname, (long int) sym->st_value, ndx, *flags);
+
+  if (strcmp (symname, "tst_audit26_func") == 0)
+    {
+      assert (regs->lr_xreg[0] == ARG1);
+      assert (regs->lr_xreg[1] == ARG2);
+      assert (regs->lr_xreg[2] == ARG3);
+    }
+  else
+    abort ();
+
+  assert (regs->lr_vpcs == 0);
+
+  /* Clobber 'x8'.  */
+  asm volatile ("mov x8, -1" : : : "x8");
+
+  *framesizep = 1024;
+
+  return sym->st_value;
+}
+
+unsigned int
+la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+                        uintptr_t *defcook,
+                        const struct La_aarch64_regs *inregs,
+                        struct La_aarch64_retval *outregs, const char *symname)
+{
+  printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n",
+	  symname, (long int) sym->st_value, ndx);
+
+  if (strcmp (symname, "tst_audit26_func") == 0)
+    {
+      assert (inregs->lr_xreg[0] == ARG1);
+      assert (inregs->lr_xreg[1] == ARG2);
+      assert (inregs->lr_xreg[2] == ARG3);
+    }
+  else
+    abort ();
+
+  assert (inregs->lr_vpcs == 0);
+  assert (outregs->lrv_vpcs == 0);
+
+  /* Clobber 'x8'.  */
+  asm volatile ("mov x8, -1" : : : "x8");
+
+  return 0;
+}
diff --git a/sysdeps/aarch64/tst-auditmod27.c b/sysdeps/aarch64/tst-auditmod27.c
new file mode 100644
index 0000000000..57936d7e70
--- /dev/null
+++ b/sysdeps/aarch64/tst-auditmod27.c
@@ -0,0 +1,180 @@
+/* Check DT_AUDIT for aarch64 specific ABI.
+   Copyright (C) 2022 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/>.  */
+
+#include <assert.h>
+#include <link.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "tst-audit27mod.h"
+
+#define TEST_NAME  "tst-audit27"
+
+#define AUDIT27_COOKIE 0
+
+unsigned int
+la_version (unsigned int v)
+{
+  return v;
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+  const char *p = strrchr (map->l_name, '/');
+  const char *l_name = p == NULL ? map->l_name : p + 1;
+  uintptr_t ck = -1;
+  if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
+    ck = AUDIT27_COOKIE;
+  *cookie = ck;
+  printf ("objopen: %ld, %s [%ld]\n", lmid, l_name, ck);
+  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
+}
+
+ElfW(Addr)
+la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+			 uintptr_t *defcook, La_aarch64_regs *regs,
+			 unsigned int *flags, const char *symname,
+			 long int *framesizep)
+{
+  printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
+	  symname, (long int) sym->st_value, ndx, *flags);
+
+  if (strcmp (symname, "tst_audit27_func_float") == 0)
+    {
+      assert (regs->lr_vreg[0].s == FUNC_FLOAT_ARG0);
+      assert (regs->lr_vreg[1].s == FUNC_FLOAT_ARG1);
+      assert (regs->lr_vreg[2].s == FUNC_FLOAT_ARG2);
+      assert (regs->lr_vreg[3].s == FUNC_FLOAT_ARG3);
+      assert (regs->lr_vreg[4].s == FUNC_FLOAT_ARG4);
+      assert (regs->lr_vreg[5].s == FUNC_FLOAT_ARG5);
+      assert (regs->lr_vreg[6].s == FUNC_FLOAT_ARG6);
+      assert (regs->lr_vreg[7].s == FUNC_FLOAT_ARG7);
+    }
+  else if (strcmp (symname, "tst_audit27_func_double") == 0)
+    {
+      assert (regs->lr_vreg[0].d == FUNC_DOUBLE_ARG0);
+      assert (regs->lr_vreg[1].d == FUNC_DOUBLE_ARG1);
+      assert (regs->lr_vreg[2].d == FUNC_DOUBLE_ARG2);
+      assert (regs->lr_vreg[3].d == FUNC_DOUBLE_ARG3);
+      assert (regs->lr_vreg[4].d == FUNC_DOUBLE_ARG4);
+      assert (regs->lr_vreg[5].d == FUNC_DOUBLE_ARG5);
+      assert (regs->lr_vreg[6].d == FUNC_DOUBLE_ARG6);
+      assert (regs->lr_vreg[7].d == FUNC_DOUBLE_ARG7);
+    }
+  else if (strcmp (symname, "tst_audit27_func_ldouble") == 0)
+    {
+      assert (regs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0);
+      assert (regs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1);
+      assert (regs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2);
+      assert (regs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3);
+      assert (regs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4);
+      assert (regs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5);
+      assert (regs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6);
+      assert (regs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7);
+    }
+  else
+    abort ();
+
+  assert (regs->lr_vpcs == 0);
+
+  /* Clobber the q registers on exit.  */
+  uint8_t v = 0xff;
+  asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0");
+  asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v1");
+  asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2");
+  asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3");
+  asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4");
+  asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5");
+  asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6");
+  asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7");
+
+  *framesizep = 1024;
+
+  return sym->st_value;
+}
+
+unsigned int
+la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+                        uintptr_t *defcook,
+			const struct La_aarch64_regs *inregs,
+                        struct La_aarch64_retval *outregs,
+			const char *symname)
+{
+  printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n",
+	  symname, (long int) sym->st_value, ndx);
+
+  if (strcmp (symname, "tst_audit27_func_float") == 0)
+    {
+      assert (inregs->lr_vreg[0].s == FUNC_FLOAT_ARG0);
+      assert (inregs->lr_vreg[1].s == FUNC_FLOAT_ARG1);
+      assert (inregs->lr_vreg[2].s == FUNC_FLOAT_ARG2);
+      assert (inregs->lr_vreg[3].s == FUNC_FLOAT_ARG3);
+      assert (inregs->lr_vreg[4].s == FUNC_FLOAT_ARG4);
+      assert (inregs->lr_vreg[5].s == FUNC_FLOAT_ARG5);
+      assert (inregs->lr_vreg[6].s == FUNC_FLOAT_ARG6);
+      assert (inregs->lr_vreg[7].s == FUNC_FLOAT_ARG7);
+
+      assert (outregs->lrv_vreg[0].s == FUNC_FLOAT_RET);
+    }
+  else if (strcmp (symname, "tst_audit27_func_double") == 0)
+    {
+      assert (inregs->lr_vreg[0].d == FUNC_DOUBLE_ARG0);
+      assert (inregs->lr_vreg[1].d == FUNC_DOUBLE_ARG1);
+      assert (inregs->lr_vreg[2].d == FUNC_DOUBLE_ARG2);
+      assert (inregs->lr_vreg[3].d == FUNC_DOUBLE_ARG3);
+      assert (inregs->lr_vreg[4].d == FUNC_DOUBLE_ARG4);
+      assert (inregs->lr_vreg[5].d == FUNC_DOUBLE_ARG5);
+      assert (inregs->lr_vreg[6].d == FUNC_DOUBLE_ARG6);
+      assert (inregs->lr_vreg[7].d == FUNC_DOUBLE_ARG7);
+
+      assert (outregs->lrv_vreg[0].d == FUNC_DOUBLE_RET);
+    }
+  else if (strcmp (symname, "tst_audit27_func_ldouble") == 0)
+    {
+      assert (inregs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0);
+      assert (inregs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1);
+      assert (inregs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2);
+      assert (inregs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3);
+      assert (inregs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4);
+      assert (inregs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5);
+      assert (inregs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6);
+      assert (inregs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7);
+
+      assert (outregs->lrv_vreg[0].q == FUNC_LDOUBLE_RET);
+    }
+  else
+    abort ();
+
+  assert (inregs->lr_vpcs == 0);
+  assert (outregs->lrv_vpcs == 0);
+
+  /* Clobber the q registers on exit.  */
+  uint8_t v = 0xff;
+  asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0");
+  asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v1");
+  asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2");
+  asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3");
+  asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4");
+  asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5");
+  asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6");
+  asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7");
+
+  return 0;
+}
diff --git a/sysdeps/generic/dl-audit-check.h b/sysdeps/generic/dl-audit-check.h
new file mode 100644
index 0000000000..3ab7653286
--- /dev/null
+++ b/sysdeps/generic/dl-audit-check.h
@@ -0,0 +1,23 @@
+/* rtld-audit version check.  Generic version.
+   Copyright (C) 2022 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/>.  */
+
+static inline bool
+_dl_audit_check_version (unsigned int lav)
+{
+  return lav <= LAV_CURRENT;
+}
-- 
2.32.0


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 1/4] elf: Add la_activity during application exit
  2022-01-25 18:36 ` [PATCH v12 1/4] elf: Add la_activity during application exit Adhemerval Zanella
@ 2022-01-26 11:42   ` Florian Weimer
  2022-01-26 12:18     ` Adhemerval Zanella
  2022-02-01  4:21   ` Carlos O'Donell
  1 sibling, 1 reply; 18+ messages in thread
From: Florian Weimer @ 2022-01-26 11:42 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha
  Cc: jma14, Carlos O'Donell, Adhemerval Zanella, John Mellor-Crummey

* Adhemerval Zanella via Libc-alpha:

> +static int
> +do_test (int argc, char *argv[])
> +{
> +  /* We must have either:
> +     - One our fource parameters left if called initially:
> +       + path to ld.so         optional
> +       + "--library-path"      optional
> +       + the library path      optional
> +       + the application name  */
> +  if (restart)
> +    return handle_restart ();
> +
> +  char *spargv[9];
> +  int i = 0;
> +  for (; i < argc - 1; i++)
> +    spargv[i] = argv[i + 1];
> +  spargv[i++] = (char *) "--direct";
> +  spargv[i++] = (char *) "--restart";
> +  spargv[i] = NULL;
> +  TEST_VERIFY_EXIT (i < array_length (spargv));

Sorry, I think this test is invalid because it happens after the
out-of-bounds write.  I expect that compilers will eventually warn about
that.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 1/4] elf: Add la_activity during application exit
  2022-01-26 11:42   ` Florian Weimer
@ 2022-01-26 12:18     ` Adhemerval Zanella
  2022-01-26 12:25       ` Florian Weimer
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2022-01-26 12:18 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha
  Cc: jma14, Carlos O'Donell, John Mellor-Crummey



On 26/01/2022 08:42, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> +static int
>> +do_test (int argc, char *argv[])
>> +{
>> +  /* We must have either:
>> +     - One our fource parameters left if called initially:
>> +       + path to ld.so         optional
>> +       + "--library-path"      optional
>> +       + the library path      optional
>> +       + the application name  */
>> +  if (restart)
>> +    return handle_restart ();
>> +
>> +  char *spargv[9];
>> +  int i = 0;
>> +  for (; i < argc - 1; i++)
>> +    spargv[i] = argv[i + 1];
>> +  spargv[i++] = (char *) "--direct";
>> +  spargv[i++] = (char *) "--restart";
>> +  spargv[i] = NULL;
>> +  TEST_VERIFY_EXIT (i < array_length (spargv));
> 
> Sorry, I think this test is invalid because it happens after the
> out-of-bounds write.  I expect that compilers will eventually warn about
> that.

It seems that at least gcc 11 does not warn if the array is not large
enough.  Maybe this is better:

  char *spargv[9];
  TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv));
  int i = 0;
  for (; i < argc - 1; i++)
    spargv[i] = argv[i + 1];
  spargv[i++] = (char *) "--direct";
  spargv[i++] = (char *) "--restart";
  spargv[i] = NULL;

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 1/4] elf: Add la_activity during application exit
  2022-01-26 12:18     ` Adhemerval Zanella
@ 2022-01-26 12:25       ` Florian Weimer
  0 siblings, 0 replies; 18+ messages in thread
From: Florian Weimer @ 2022-01-26 12:25 UTC (permalink / raw)
  To: Adhemerval Zanella
  Cc: Adhemerval Zanella via Libc-alpha, jma14, Carlos O'Donell,
	John Mellor-Crummey

* Adhemerval Zanella:

> On 26/01/2022 08:42, Florian Weimer wrote:
>> * Adhemerval Zanella via Libc-alpha:
>> 
>>> +static int
>>> +do_test (int argc, char *argv[])
>>> +{
>>> +  /* We must have either:
>>> +     - One our fource parameters left if called initially:
>>> +       + path to ld.so         optional
>>> +       + "--library-path"      optional
>>> +       + the library path      optional
>>> +       + the application name  */
>>> +  if (restart)
>>> +    return handle_restart ();
>>> +
>>> +  char *spargv[9];
>>> +  int i = 0;
>>> +  for (; i < argc - 1; i++)
>>> +    spargv[i] = argv[i + 1];
>>> +  spargv[i++] = (char *) "--direct";
>>> +  spargv[i++] = (char *) "--restart";
>>> +  spargv[i] = NULL;
>>> +  TEST_VERIFY_EXIT (i < array_length (spargv));
>> 
>> Sorry, I think this test is invalid because it happens after the
>> out-of-bounds write.  I expect that compilers will eventually warn about
>> that.
>
> It seems that at least gcc 11 does not warn if the array is not large
> enough.  Maybe this is better:
>
>   char *spargv[9];
>   TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv));
>   int i = 0;
>   for (; i < argc - 1; i++)
>     spargv[i] = argv[i + 1];
>   spargv[i++] = (char *) "--direct";
>   spargv[i++] = (char *) "--restart";
>   spargv[i] = NULL;

Yes, it is.  Thanks.  It's a bit unfortunate that there is no succinct
way to express this.

Florian


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 1/4] elf: Add la_activity during application exit
  2022-01-25 18:36 ` [PATCH v12 1/4] elf: Add la_activity during application exit Adhemerval Zanella
  2022-01-26 11:42   ` Florian Weimer
@ 2022-02-01  4:21   ` Carlos O'Donell
  2022-02-01 13:30     ` Adhemerval Zanella
  1 sibling, 1 reply; 18+ messages in thread
From: Carlos O'Donell @ 2022-02-01  4:21 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard

On 1/25/22 13:36, Adhemerval Zanella wrote:
> la_activity is not called during application exit, even though
> la_objclose is.

Logically this does what I expected, and I think the dlfini pieces are in the
right place. I worked through the logic around re-running again: and making
sure that we have guards in place for all the called audit modules so we don't
call callbacks for modules are they are being finalized. This looks good to me.

OK for glibc 2.35 with comment corrections, but please post v13 and I'll ACK that
as release manager.
 
> Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
> ---
>  elf/Makefile         |   7 ++
>  elf/dl-fini.c        |   8 ++
>  elf/tst-audit23.c    | 239 +++++++++++++++++++++++++++++++++++++++++++
>  elf/tst-audit23mod.c |  23 +++++
>  elf/tst-auditmod23.c |  74 ++++++++++++++
>  5 files changed, 351 insertions(+)
>  create mode 100644 elf/tst-audit23.c
>  create mode 100644 elf/tst-audit23mod.c
>  create mode 100644 elf/tst-auditmod23.c
> 
> diff --git a/elf/Makefile b/elf/Makefile
> index 41e0f2e8c4..a3b4468593 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -377,6 +377,7 @@ tests += \
>    tst-audit19b \
>    tst-audit20 \
>    tst-audit22 \
> +  tst-audit23 \

OK. Test.

>    tst-auditmany \
>    tst-auxobj \
>    tst-auxobj-dlopen \
> @@ -673,6 +674,7 @@ modules-names = \
>    tst-audit13mod1 \
>    tst-audit18mod \
>    tst-audit19bmod \
> +  tst-audit23mod \

OK. And DSO.

>    tst-auditlogmod-1 \
>    tst-auditlogmod-2 \
>    tst-auditlogmod-3 \
> @@ -695,6 +697,7 @@ modules-names = \
>    tst-auditmod19b \
>    tst-auditmod20 \
>    tst-auditmod22 \
> +  tst-auditmod23 \

OK. And audit module.

>    tst-auxvalmod \
>    tst-big-note-lib \
>    tst-deep1mod1 \
> @@ -2136,6 +2139,10 @@ tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
>  $(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
>  tst-audit22-ARGS = -- $(host-test-program-cmd)
>  
> +$(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
> +			  $(objpfx)tst-audit23mod.so
> +tst-audit23-ARGS = -- $(host-test-program-cmd)

OK. Dep on the two DSOs.

> +
>  # tst-sonamemove links against an older implementation of the library.
>  LDFLAGS-tst-sonamemove-linkmod1.so = \
>    -Wl,--version-script=tst-sonamemove-linkmod1.map \
> diff --git a/elf/dl-fini.c b/elf/dl-fini.c
> index de8eb1b3c9..030b1fcbcd 100644
> --- a/elf/dl-fini.c
> +++ b/elf/dl-fini.c
> @@ -64,6 +64,10 @@ _dl_fini (void)

OK. In _dl_fini and winding down the object.

>  	__rtld_lock_unlock_recursive (GL(dl_load_lock));
>        else
>  	{
> +#ifdef SHARED
> +	  _dl_audit_activity_nsid (ns, LA_ACT_DELETE);

OK. This is the start of the operation for the namespace that isn't empty
or just used for auditing. We are calling LA_ACT_DELETE here to signal that
we are closing objects as part of exit. The only other place we call LA_ACT_DELETE
is in _dl_close_worker() which is only used for dlclose and others. We can choose
to place LA_ACT_DELETE at any point, but this is 

> +#endif
> +
>  	  /* Now we can allocate an array to hold all the pointers and
>  	     copy the pointers in.  */
>  	  struct link_map *maps[nloaded];
> @@ -153,6 +157,10 @@ _dl_fini (void)
>  	      /* Correct the previous increment.  */
>  	      --l->l_direct_opencount;
>  	    }
> +
> +#ifdef SHARED
> +	  _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
> +#endif

OK. Confirmed this is the closing set of braces from LA_ACT_DELETE, and so marks
that we are consistent. Nothing should ever call _dl_fini() again, but some
cases may jump to again:, like when we are unloading the auditors as the last
step in _dl_fini(). There is no harm in doing this unconditionally because all
of _dl_audit_activity_nsid and _dl_audit_objclose are guarded by l_auditing
being zero before actually calling the callback. That is to say that no auditor
can audit another auditor.

>  	}
>      }
>  
> diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
> new file mode 100644
> index 0000000000..3eea322051
> --- /dev/null
> +++ b/elf/tst-audit23.c
> @@ -0,0 +1,239 @@
> +/* Check DT_AUDIT la_objopen and la_objclose for all objects.

This does not check DT_AUDIT, which is set only by the static linker for --audit?

Suggest:
Check for expected la_objopen and la_objeclose for all objects.

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <array_length.h>
> +#include <errno.h>
> +#include <getopt.h>
> +#include <link.h>
> +#include <limits.h>
> +#include <inttypes.h>
> +#include <gnu/lib-names.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <support/capture_subprocess.h>
> +#include <support/check.h>
> +#include <support/xstdio.h>
> +#include <support/xdlfcn.h>
> +#include <support/support.h>
> +
> +static int restart;
> +#define CMDLINE_OPTIONS \
> +  { "restart", no_argument, &restart, 1 },
> +
> +static int
> +handle_restart (void)
> +{
> +  xdlopen ("tst-audit23mod.so", RTLD_NOW);
> +  xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
> +
> +  return 0;
> +}
> +
> +static inline bool
> +startswith (const char *str, const char *pre)
> +{
> +  size_t lenpre = strlen (pre);
> +  size_t lenstr = strlen (str);
> +  return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
> +}
> +
> +static inline bool
> +is_vdso (const char *str)
> +{
> +  return startswith (str, "linux-gate")
> +	 || startswith (str, "linux-vdso");
> +}
> +
> +static int
> +do_test (int argc, char *argv[])
> +{
> +  /* We must have either:
> +     - One our fource parameters left if called initially:

s/One our fource/One or four/g.

> +       + path to ld.so         optional
> +       + "--library-path"      optional
> +       + the library path      optional
> +       + the application name  */
> +  if (restart)
> +    return handle_restart ();
> +
> +  char *spargv[9];
> +  int i = 0;
> +  for (; i < argc - 1; i++)
> +    spargv[i] = argv[i + 1];
> +  spargv[i++] = (char *) "--direct";
> +  spargv[i++] = (char *) "--restart";
> +  spargv[i] = NULL;
> +  TEST_VERIFY_EXIT (i < array_length (spargv));
> +

OK. Prepare to re-run ourselves with auditor.

> +  setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
> +  struct support_capture_subprocess result
> +    = support_capture_subprogram (spargv[0], spargv);
> +  support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
> +
> +  /* The expected la_objopen/la_objclose:
> +     1. executable
> +     2. loader
> +     3. libc.so
> +     4. tst-audit23mod.so
> +     5. libc.so (LM_ID_NEWLM).
> +     6. vdso (optional and ignored).  */
> +  enum { max_objs = 6 };
> +  struct la_obj_t
> +  {
> +    char *lname;
> +    uintptr_t laddr;
> +    Lmid_t lmid;
> +    bool closed;
> +  } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
> +  size_t nobjs = 0;
> +
> +  /* The expected namespaces are one for the audit module, one for the
> +     application, and another for the dlmopen on handle_restart.  */
> +  enum { max_ns = 3 };
> +  uintptr_t acts[max_ns] = { 0 };
> +  size_t nacts = 0;
> +  int last_act = -1;
> +  uintptr_t last_act_cookie = -1;
> +  bool seen_first_objclose = false;
> +
> +  FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
> +  TEST_VERIFY (out != NULL);
> +  char *buffer = NULL;
> +  size_t buffer_length = 0;
> +  while (xgetline (&buffer, &buffer_length, out))
> +    {
> +      if (startswith (buffer, "la_activity: "))
> +	{
> +	  uintptr_t cookie;
> +	  int this_act;
> +	  int r = sscanf (buffer, "la_activity: %d %"SCNxPTR"", &this_act,
> +			  &cookie);
> +	  TEST_COMPARE (r, 2);
> +
> +	  /* The cookie identifies the object at the head of the link map,
> +	     so we only add a new namespace if it changes from previous

s/from/from the/g

> +	     one.  This work since dlmopen is the last in the test body.  */

s/work/works/g

> +	  if (cookie != last_act_cookie && last_act_cookie != -1)
> +	    TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
> +
> +	  if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
> +	    {
> +	      acts[nacts++] = cookie;
> +	      last_act_cookie = cookie;
> +	    }
> +	  /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
> +	     at program termination (if the tests adds a dlclose or a library
> +	     with extra dependencies this require to be adapted).  */

s/require/will need/g

Florian's fix to make dlclose order consistent will make this consistent too!

> +	  else if (this_act == LA_ACT_DELETE)
> +	    {
> +	      last_act_cookie = acts[--nacts];
> +	      TEST_COMPARE (acts[nacts], cookie);
> +	      acts[nacts] = 0;
> +	    }
> +	  else if (this_act == LA_ACT_CONSISTENT)
> +	    {
> +	      TEST_COMPARE (cookie, last_act_cookie);
> +
> +	      /* LA_ACT_DELETE must always be followed by an la_objclose.  */
> +	      if (last_act == LA_ACT_DELETE)
> +		TEST_COMPARE (seen_first_objclose, true);
> +	      else
> +		TEST_COMPARE (last_act, LA_ACT_ADD);
> +	    }
> +
> +	  last_act = this_act;
> +	  seen_first_objclose = false;
> +	}
> +      else if (startswith (buffer, "la_objopen: "))
> +	{
> +	  char *lname;
> +	  uintptr_t laddr;
> +	  Lmid_t lmid;
> +	  uintptr_t cookie;
> +	  int r = sscanf (buffer, "la_objopen: %"SCNxPTR"  %ms %"SCNxPTR" %ld",
> +			  &cookie, &lname, &laddr, &lmid);
> +	  TEST_COMPARE (r, 4);
> +
> +	  /* la_objclose is not triggered by vDSO because glibc does not
> +	     unload it.  */

OK.

> +	  if (is_vdso (lname))
> +	    continue;
> +	  if (nobjs == max_objs)
> +	    FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
> +			lname, laddr, lmid);
> +	  objs[nobjs].lname = lname;
> +	  objs[nobjs].laddr = laddr;
> +	  objs[nobjs].lmid = lmid;
> +	  objs[nobjs].closed = false;
> +	  nobjs++;
> +
> +	  /* This indirectly checks that la_objopen always come before

s/come/comes/g

> +	     la_objclose btween la_activity calls.  */
> +	  seen_first_objclose = false;
> +	}
> +      else if (startswith (buffer, "la_objclose: "))
> +	{
> +	  char *lname;
> +	  uintptr_t laddr;
> +	  Lmid_t lmid;
> +	  uintptr_t cookie;
> +	  int r = sscanf (buffer, "la_objclose: %"SCNxPTR" %ms %"SCNxPTR" %ld",
> +			  &cookie, &lname, &laddr, &lmid);
> +	  TEST_COMPARE (r, 4);
> +
> +	  for (size_t i = 0; i < nobjs; i++)
> +	    {
> +	      if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
> +		{
> +		  TEST_COMPARE (objs[i].closed, false);
> +		  objs[i].closed = true;
> +		  break;
> +		}
> +	    }
> +
> +	  /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
> +	     the closed object's namespace.  */

OK. Agreed.

> +	  TEST_COMPARE (last_act, LA_ACT_DELETE);
> +	  if (!seen_first_objclose)
> +	    {
> +	      TEST_COMPARE (last_act_cookie, cookie);
> +	      seen_first_objclose = true;
> +	    }
> +	}
> +    }
> +
> +  for (size_t i = 0; i < nobjs; i++)
> +    {
> +      TEST_COMPARE (objs[i].closed, true);
> +      free (objs[i].lname);
> +    }
> +
> +  /* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
> +     Since only one link map may be not-CONSISTENT at a time, this also
> +     ensures la_activity(LA_ACT_CONSISTENT) is the last callback received
> +     for every namespace.  */
> +  TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
> +
> +  free (buffer);
> +  xfclose (out);
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION_ARGV do_test
> +#include <support/test-driver.c>
> diff --git a/elf/tst-audit23mod.c b/elf/tst-audit23mod.c
> new file mode 100644
> index 0000000000..9a116ff682
> --- /dev/null
> +++ b/elf/tst-audit23mod.c
> @@ -0,0 +1,23 @@
> +/* Extra modules for tst-audit23

s/modules/module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +int
> +foo (void)
> +{
> +  return 0;
> +}

OK.

> diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c
> new file mode 100644
> index 0000000000..42eccae11b
> --- /dev/null
> +++ b/elf/tst-auditmod23.c
> @@ -0,0 +1,74 @@
> +/* Audit modules loaded by tst-audit23.

s/modules/module/g.

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <link.h>
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <sys/auxv.h>
> +
> +unsigned int
> +la_version (unsigned int version)
> +{
> +  return LAV_CURRENT;
> +}
> +
> +struct map_desc_t
> +{
> +  char *lname;
> +  uintptr_t laddr;
> +  Lmid_t lmid;
> +};
> +
> +void
> +la_activity (uintptr_t *cookie, unsigned int flag)
> +{
> +  fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie);
> +}
> +
> +unsigned int
> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
> +{
> +  const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name;
> +  fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
> +	   (uintptr_t) cookie, l_name, map->l_addr, lmid);
> +
> +  struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t));
> +  if (map_desc == NULL)
> +    abort ();
> +
> +  map_desc->lname = strdup (l_name);
> +  map_desc->laddr = map->l_addr;
> +  map_desc->lmid = lmid;
> +
> +  *cookie = (uintptr_t) map_desc;

OK.

> +
> +  return 0;
> +}
> +
> +unsigned int
> +la_objclose (uintptr_t *cookie)
> +{
> +  struct map_desc_t *map_desc = (struct map_desc_t *) *cookie;
> +  fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
> +	   (uintptr_t) cookie, map_desc->lname, map_desc->laddr,
> +	   map_desc->lmid);
> +
> +  return 0;
> +}


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096)
  2022-01-25 18:36 ` [PATCH v12 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Adhemerval Zanella
@ 2022-02-01  5:29   ` Carlos O'Donell
  2022-02-01 13:35     ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: Carlos O'Donell @ 2022-02-01  5:29 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard

On 1/25/22 13:36, Adhemerval Zanella wrote:
> For audit modules and dependencies with initial-exec TLS, we can not
> set the initial TLS image on default loader initialization because it
> would already be set by the audit setup.  However, subsequent thread
> creation would need to follow the default behaviour.

Correct, there is a circular dependency, we need the initial TLS image setup for
the auditor before the loader does the setup.

> This patch fixes it by setting l_auditing link_map field not only
> for the audit modules, but also for all its dependencies.  This is
> used on _dl_allocate_tls_init to avoid the static TLS initialization
> only at loading time.

s/only at loading/at load/g

> Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Tested on x86_64 and i686 and it looks good for glibc 2.35.

Please post v13 with fixes and I'll ACK that as release manager.


> ---
>  elf/Makefile               |  8 ++++
>  elf/dl-tls.c               | 13 +++++--
>  elf/rtld.c                 |  2 +-
>  elf/tst-audit21.c          | 42 ++++++++++++++++++++
>  elf/tst-auditmod21a.c      | 80 ++++++++++++++++++++++++++++++++++++++
>  elf/tst-auditmod21b.c      | 22 +++++++++++
>  nptl/allocatestack.c       |  2 +-
>  sysdeps/generic/ldsodefs.h |  2 +-
>  8 files changed, 165 insertions(+), 6 deletions(-)
>  create mode 100644 elf/tst-audit21.c
>  create mode 100644 elf/tst-auditmod21a.c
>  create mode 100644 elf/tst-auditmod21b.c
> 
> diff --git a/elf/Makefile b/elf/Makefile
> index a3b4468593..7d01b71f6a 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -376,6 +376,7 @@ tests += \
>    tst-audit18 \
>    tst-audit19b \
>    tst-audit20 \
> +  tst-audit21 \

OK. Test.

>    tst-audit22 \
>    tst-audit23 \
>    tst-auditmany \
> @@ -696,6 +697,8 @@ modules-names = \
>    tst-auditmod19a \
>    tst-auditmod19b \
>    tst-auditmod20 \
> +  tst-auditmod21a \
> +  tst-auditmod21b \

OK. Two audit modules.

>    tst-auditmod22 \
>    tst-auditmod23 \
>    tst-auxvalmod \
> @@ -2136,6 +2139,11 @@ tst-audit19b-ARGS = -- $(host-test-program-cmd)
>  $(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
>  tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
>  
> +$(objpfx)tst-audit21: $(shared-thread-library)
> +$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so
> +$(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so

OK. A deps B.

> +tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so

OK. New test is audited by A, which deps B.

> +
>  $(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
>  tst-audit22-ARGS = -- $(host-test-program-cmd)
>  
> diff --git a/elf/dl-tls.c b/elf/dl-tls.c
> index 8ba70c9a9d..ccbe39660b 100644
> --- a/elf/dl-tls.c
> +++ b/elf/dl-tls.c
> @@ -520,7 +520,7 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
>  
>  

This needs a comment explaining bool init_tls.

/* Allocate initial TLS.  RESULT should be a non-NULL pointer to storage
   for the TLS space.  The DTV may be resized, and so this function may
   call malloc to allocate that space.  The loader's GL(dl_load_tls_lock)
   is taken when manipulating global TLS-related data in the laoder.

>  void *
> -_dl_allocate_tls_init (void *result)
> +_dl_allocate_tls_init (void *result, bool init_tls)

OK. This is called by a reinitialization of re-used stacks. It is called
by normal _dl_allocate_tls, which is called when a thread allocates a DTV.

>  {
>    if (result == NULL)
>      /* The memory allocation failed.  */
> @@ -593,7 +593,14 @@ _dl_allocate_tls_init (void *result)
>  	     some platforms use in static programs requires it.  */
>  	  dtv[map->l_tls_modid].pointer.val = dest;
>  
> -	  /* Copy the initialization image and clear the BSS part.  */
> +	  /* Copy the initialization image and clear the BSS part.  For
> +	     audit modules or depedencies with initial-exec TLS, we can not

s/depedencies/dependencies/g

> +	     set the initial TLS image on default loader initialization
> +	     because it would already be set by the audit setup.  However,
> +	     subsequent thread creation would need to follow the default
> +	     behaviour.   */
> +	  if (map->l_ns != LM_ID_BASE && !init_tls)
> +	    continue;

OK. The tricky part here is that this works because GL(dl_tls_dtv_slotinfo_list)
is a *GLOBAL* list that is irrespective of linker namespace. So when we come to setup
the static TLS for the thread via rtld we will redo the already done setup for the libc
in the non-main-namespace.

>  	  memset (__mempcpy (dest, map->l_tls_initimage,
>  			     map->l_tls_initimage_size), '\0',
>  		  map->l_tls_blocksize - map->l_tls_initimage_size);
> @@ -620,7 +627,7 @@ _dl_allocate_tls (void *mem)
>  {
>    return _dl_allocate_tls_init (mem == NULL
>  				? _dl_allocate_tls_storage ()
> -				: allocate_dtv (mem));
> +				: allocate_dtv (mem), true);

OK. Correct, when calling via _dl_allocate_tls we always want to initialize TLS.

>  }
>  rtld_hidden_def (_dl_allocate_tls)
>  
> diff --git a/elf/rtld.c b/elf/rtld.c
> index 8d233f77be..10436f7034 100644
> --- a/elf/rtld.c
> +++ b/elf/rtld.c
> @@ -2462,7 +2462,7 @@ dl_main (const ElfW(Phdr) *phdr,
>       into the main thread's TLS area, which we allocated above.
>       Note: thread-local variables must only be accessed after completing
>       the next step.  */
> -  _dl_allocate_tls_init (tcbp);
> +  _dl_allocate_tls_init (tcbp, false);

OK. When doing this step we have already potentially initialized everything
via init_tls(naudit) earlier, but "false" is only useful if we are in the
non-base namespace.

>  
>    /* And finally install it for the main thread.  */
>    if (! tls_init_tp_called)
> diff --git a/elf/tst-audit21.c b/elf/tst-audit21.c
> new file mode 100644
> index 0000000000..41446a2107
> --- /dev/null
> +++ b/elf/tst-audit21.c
> @@ -0,0 +1,42 @@
> +/* Check DT_AUDIT with static TLS.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <ctype.h>
> +#include <support/xthread.h>
> +#include <support/check.h>
> +
> +static volatile __thread int out __attribute__ ((tls_model ("initial-exec")));

OK. out has size int.

> +
> +static void *
> +tf (void *arg)
> +{
> +  TEST_COMPARE (out, 0);
> +  out = isspace (' ');

OK. Uses ctype data, which uses tls also.

> +  return NULL;
> +}
> +
> +int main (int argc, char *argv[])
> +{
> +  TEST_COMPARE (out, 0);
> +  out = isspace (' ');
> +
> +  pthread_t t = xpthread_create (NULL, tf, NULL);

OK. In the new thread look at the value.

> +  xpthread_join (t);
> +
> +  return 0;
> +}
> diff --git a/elf/tst-auditmod21a.c b/elf/tst-auditmod21a.c
> new file mode 100644
> index 0000000000..4c0f256969
> --- /dev/null
> +++ b/elf/tst-auditmod21a.c
> @@ -0,0 +1,80 @@
> +/* Check DT_AUDIT with static TLS.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <ctype.h>
> +#include <stdlib.h>
> +#include <link.h>
> +
> +#define tls_ie __attribute__ ((tls_model ("initial-exec")))
> +
> +__thread int tls_var0 tls_ie;
> +__thread int tls_var1 tls_ie = 0x10;

OK. Two TLS IE mode vars one with a non-zero intializer.

> +
> +/* Defined at tst-auditmod21b.so  */
> +extern __thread int tls_var2;
> +extern __thread int tls_var3;
> +
> +static volatile int out;
> +
> +static void
> +call_libc (void)
> +{
> +  /* isspace access the initial-exec glibc TLS variables, which are

s/access/accesses/g

> +     setup in glibc initialization.  */
> +  out = isspace (' ');
> +}
> +
> +unsigned int
> +la_version (unsigned int v)
> +{

OK. la_version is called to initialize this module, so it's after all the
early tls initialization done by the loader.

> +  tls_var0 = 0x1;
> +  if (tls_var1 != 0x10)
> +    abort ();
> +  tls_var1 = 0x20;
> +
> +  tls_var2 = 0x2;
> +  if (tls_var3 != 0x20)
> +    abort ();
> +  tls_var3 = 0x40;
> +
> +  call_libc ();
> +
> +  return LAV_CURRENT;
> +}
> +
> +unsigned int
> +la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie)
> +{
> +  call_libc ();
> +  *cookie = (uintptr_t) map;
> +  return 0;
> +}
> +
> +void
> +la_activity (uintptr_t* cookie, unsigned int flag)
> +{

OK. By the time we have activity our TLS will have been overwritten.

> +  if (tls_var0 != 0x1 || tls_var1 != 0x20)
> +    abort ();
> +  call_libc ();
> +}
> +
> +void
> +la_preinit (uintptr_t* cookie)
> +{
> +  call_libc ();

OK. Trigger libc tls usage after all DSOs are loaded but before main.

> +}
> diff --git a/elf/tst-auditmod21b.c b/elf/tst-auditmod21b.c
> new file mode 100644
> index 0000000000..69705cf75a
> --- /dev/null
> +++ b/elf/tst-auditmod21b.c
> @@ -0,0 +1,22 @@
> +/* Check DT_AUDIT with static TLS.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#define tls_ie __attribute__ ((tls_model ("initial-exec")))
> +
> +__thread int tls_var2 tls_ie;
> +__thread int tls_var3 tls_ie = 0x20;

OK.

> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
> index 3fb085f9a1..34a33164ff 100644
> --- a/nptl/allocatestack.c
> +++ b/nptl/allocatestack.c
> @@ -138,7 +138,7 @@ get_cached_stack (size_t *sizep, void **memp)
>    memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
>  
>    /* Re-initialize the TLS.  */
> -  _dl_allocate_tls_init (TLS_TPADJ (result));
> +  _dl_allocate_tls_init (TLS_TPADJ (result), true);

OK. Yes, a thread needs to reinitialize this for the new stack.

>  
>    return result;
>  }
> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
> index f6b2b415a6..97061bdf9f 100644
> --- a/sysdeps/generic/ldsodefs.h
> +++ b/sysdeps/generic/ldsodefs.h
> @@ -1282,7 +1282,7 @@ extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
>  /* These are internal entry points to the two halves of _dl_allocate_tls,
>     only used within rtld.c itself at startup time.  */
>  extern void *_dl_allocate_tls_storage (void) attribute_hidden;
> -extern void *_dl_allocate_tls_init (void *);
> +extern void *_dl_allocate_tls_init (void *, bool);

OK.

>  rtld_hidden_proto (_dl_allocate_tls_init)
>  
>  /* Deallocate memory allocated with _dl_allocate_tls.  */


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 3/4] elf: Issue la_symbind for bind-now (BZ #23734)
  2022-01-25 18:36 ` [PATCH v12 3/4] elf: Issue la_symbind for bind-now (BZ #23734) Adhemerval Zanella
@ 2022-02-01  6:06   ` Carlos O'Donell
  2022-02-01 13:47     ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: Carlos O'Donell @ 2022-02-01  6:06 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard

On 1/25/22 13:36, Adhemerval Zanella wrote:
> The audit symbind callback is not called for binaries built with
> -Wl,-z,now or when LD_BIND_NOW=1 is used, nor the PLT tracking callbacks
> (plt_enter and plt_exit) since this will would change the expected

s/will would/would/g

> program semantic (where no PTL is expected) and would incur in

s/semantic/semantics/g
s/PTL/PLT/g
s/incur in/have/g

> performance implications (such as for BZ#15533).
> 
> LAV_CURRENT is also bumped to indicate the audit ABI change (where
> la_symbind flags are set by the loader to indicate no possible PTL

s/PTL/PLT/g

> trace).
> 
> To handle powerpc64 ELFv1 function descriptor, _dl_audit_symbind
> requires to know whether bind-now is used so the symbol value is
> updated to function text segment instead of the OPD (for lazy binding
> this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve).
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
> powerpc64-linux-gnu.

Please post v13 and I'll ack that for glibc 2.35.

> ---
>  NEWS                           |   4 +
>  bits/link_lavcurrent.h         |   2 +-
>  elf/Makefile                   |  89 ++++++++++++++++++++++-
>  elf/dl-audit.c                 |  58 +++++++++------
>  elf/do-rel.h                   |  57 +++++++++++----
>  elf/sotruss-lib.c              |   7 ++
>  elf/tst-audit24a.c             |  36 +++++++++
>  elf/tst-audit24amod1.c         |  31 ++++++++
>  elf/tst-audit24amod2.c         |  25 +++++++
>  elf/tst-audit24b.c             |  37 ++++++++++
>  elf/tst-audit24bmod1.c         |  31 ++++++++
>  elf/tst-audit24bmod2.c         |  23 ++++++
>  elf/tst-audit24c.c             |   2 +
>  elf/tst-audit24d.c             |  36 +++++++++
>  elf/tst-audit24dmod1.c         |  33 +++++++++
>  elf/tst-audit24dmod2.c         |  28 +++++++
>  elf/tst-audit24dmod3.c         |  31 ++++++++
>  elf/tst-audit24dmod4.c         |  25 +++++++
>  elf/tst-audit25a.c             | 129 +++++++++++++++++++++++++++++++++
>  elf/tst-audit25b.c             | 128 ++++++++++++++++++++++++++++++++
>  elf/tst-audit25mod1.c          |  30 ++++++++
>  elf/tst-audit25mod2.c          |  30 ++++++++
>  elf/tst-audit25mod3.c          |  22 ++++++
>  elf/tst-audit25mod4.c          |  22 ++++++
>  elf/tst-auditmod24.h           |  29 ++++++++
>  elf/tst-auditmod24a.c          | 114 +++++++++++++++++++++++++++++
>  elf/tst-auditmod24b.c          | 104 ++++++++++++++++++++++++++
>  elf/tst-auditmod24c.c          |   3 +
>  elf/tst-auditmod24d.c          | 120 ++++++++++++++++++++++++++++++
>  elf/tst-auditmod25.c           |  79 ++++++++++++++++++++
>  sysdeps/generic/dl-lookupcfg.h |   3 +
>  sysdeps/generic/ldsodefs.h     |   5 +-
>  sysdeps/hppa/dl-lookupcfg.h    |   3 +
>  sysdeps/ia64/dl-lookupcfg.h    |   3 +
>  sysdeps/powerpc/dl-lookupcfg.h |  39 ++++++++++
>  35 files changed, 1379 insertions(+), 39 deletions(-)
>  create mode 100644 elf/tst-audit24a.c
>  create mode 100644 elf/tst-audit24amod1.c
>  create mode 100644 elf/tst-audit24amod2.c
>  create mode 100644 elf/tst-audit24b.c
>  create mode 100644 elf/tst-audit24bmod1.c
>  create mode 100644 elf/tst-audit24bmod2.c
>  create mode 100644 elf/tst-audit24c.c
>  create mode 100644 elf/tst-audit24d.c
>  create mode 100644 elf/tst-audit24dmod1.c
>  create mode 100644 elf/tst-audit24dmod2.c
>  create mode 100644 elf/tst-audit24dmod3.c
>  create mode 100644 elf/tst-audit24dmod4.c
>  create mode 100644 elf/tst-audit25a.c
>  create mode 100644 elf/tst-audit25b.c
>  create mode 100644 elf/tst-audit25mod1.c
>  create mode 100644 elf/tst-audit25mod2.c
>  create mode 100644 elf/tst-audit25mod3.c
>  create mode 100644 elf/tst-audit25mod4.c
>  create mode 100644 elf/tst-auditmod24.h
>  create mode 100644 elf/tst-auditmod24a.c
>  create mode 100644 elf/tst-auditmod24b.c
>  create mode 100644 elf/tst-auditmod24c.c
>  create mode 100644 elf/tst-auditmod24d.c
>  create mode 100644 elf/tst-auditmod25.c
>  create mode 100644 sysdeps/powerpc/dl-lookupcfg.h
> 
> diff --git a/NEWS b/NEWS
> index a9f25d3225..c0f8932f84 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -158,6 +158,10 @@ Deprecated and removed features, and other changes affecting compatibility:
>    been removed.  There are widely-deployed out-of-process alternatives for
>    catching coredumps and backtraces.
>  
> +* The audit module interface version LAV_CURRENT is increased to enable
> +  proper bind-now support.  The loader now advertises on the la_symbind

s/on/via/g

> +  flags that PLT trace is not possible.
> +
>  Changes to build and runtime requirements:
>  
>    [Add changes to build and runtime requirements here]
> diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h
> index 7bfa4b9f4e..a852d41302 100644
> --- a/bits/link_lavcurrent.h
> +++ b/bits/link_lavcurrent.h
> @@ -22,4 +22,4 @@
>  #endif
>  
>  /* Version numbers for la_version handshake interface.  */
> -#define LAV_CURRENT	1
> +#define LAV_CURRENT	2

OK. New version.

> diff --git a/elf/Makefile b/elf/Makefile
> index 7d01b71f6a..b9edcccb82 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -379,6 +379,12 @@ tests += \
>    tst-audit21 \
>    tst-audit22 \
>    tst-audit23 \
> +  tst-audit24a \
> +  tst-audit24b \
> +  tst-audit24c \
> +  tst-audit24d \
> +  tst-audit25a \
> +  tst-audit25b \

OK. New tests.

>    tst-auditmany \
>    tst-auxobj \
>    tst-auxobj-dlopen \
> @@ -676,6 +682,18 @@ modules-names = \
>    tst-audit18mod \
>    tst-audit19bmod \
>    tst-audit23mod \
> +  tst-audit24amod1 \
> +  tst-audit24amod2 \
> +  tst-audit24bmod1 \
> +  tst-audit24bmod2 \
> +  tst-audit24dmod1 \
> +  tst-audit24dmod2 \
> +  tst-audit24dmod3 \
> +  tst-audit24dmod4 \
> +  tst-audit25mod1 \
> +  tst-audit25mod2 \
> +  tst-audit25mod3 \
> +  tst-audit25mod4 \

OK. New DSOs.

>    tst-auditlogmod-1 \
>    tst-auditlogmod-2 \
>    tst-auditlogmod-3 \
> @@ -701,6 +719,11 @@ modules-names = \
>    tst-auditmod21b \
>    tst-auditmod22 \
>    tst-auditmod23 \
> +  tst-auditmod24a \
> +  tst-auditmod24b \
> +  tst-auditmod24c \
> +  tst-auditmod24d \
> +  tst-auditmod25 \

OK. New audit modules.

>    tst-auxvalmod \
>    tst-big-note-lib \
>    tst-deep1mod1 \
> @@ -918,7 +941,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
>  
>  # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
>  # rules.
> -modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod
> +modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
> +			 tst-audit24bmod1 tst-audit24bmod2.so

OK. Build them differently.

>  
>  tests += $(tests-static)
>  
> @@ -2151,6 +2175,69 @@ $(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
>  			  $(objpfx)tst-audit23mod.so
>  tst-audit23-ARGS = -- $(host-test-program-cmd)
>  
> +$(objpfx)tst-audit24a.out: $(objpfx)tst-auditmod24a.so
> +$(objpfx)tst-audit24a: $(objpfx)tst-audit24amod1.so \
> +		       $(objpfx)tst-audit24amod2.so
> +tst-audit24a-ENV = LD_AUDIT=$(objpfx)tst-auditmod24a.so
> +LDFLAGS-tst-audit24a = -Wl,-z,now

OK. Ensure immmediate binding.

> +
> +$(objpfx)tst-audit24b.out: $(objpfx)tst-auditmod24b.so
> +$(objpfx)tst-audit24b: $(objpfx)tst-audit24bmod1.so \
> +		       $(objpfx)tst-audit24bmod2.so
> +$(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so
> +# The test check if a library without .gnu.version correctly calls the

s/check/checks/g

> +# audit callbacks.  So it uses an explicit link rule to avoid linking
> +# against libc.so.
> +$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os
> +	$(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \
> +	  -Wl,-z,now
> +	$(call after-link,$@.new)
> +	mv -f $@.new $@

OK.

> +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1)
> +$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os
> +	$(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os
> +	$(call after-link,$@.new)
> +	mv -f $@.new $@
> +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2)
> +tst-audit24b-ENV = LD_AUDIT=$(objpfx)tst-auditmod24b.so
> +LDFLAGS-tst-audit24b = -Wl,-z,now

OK.

> +
> +# Same as tst-audit24a, but tests LD_BIND_NOW
> +$(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so
> +$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \
> +		       $(objpfx)tst-audit24amod2.so
> +tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so

OK. Immediate binding via env var.

> +LDFLAGS-tst-audit24b = -Wl,-z,lazy

OK. Testing lazy binding.

> +
> +$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so
> +$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \
> +		       $(objpfx)tst-audit24dmod2.so
> +$(objpfx)tst-audit24dmod1.so: $(objpfx)tst-audit24dmod3.so
> +LDFLAGS-tst-audit24dmod1.so = -Wl,-z,now
> +$(objpfx)tst-audit24dmod2.so: $(objpfx)tst-audit24dmod4.so
> +LDFLAGS-tst-audit24dmod2.so = -Wl,-z,lazy
> +tst-audit24d-ENV = LD_AUDIT=$(objpfx)tst-auditmod24d.so
> +LDFLAGS-tst-audit24d = -Wl,-z,lazy
> +
> +$(objpfx)tst-audit25a.out: $(objpfx)tst-auditmod25.so
> +$(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \
> +		       $(objpfx)tst-audit25mod2.so \
> +		       $(objpfx)tst-audit25mod3.so \
> +		       $(objpfx)tst-audit25mod4.so
> +$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so
> +LDFLAGS-tst-audit25mod1.so = -Wl,-z,now
> +$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so
> +LDFLAGS-tst-audit25mod2.so = -Wl,-z,lazy
> +tst-audit25a-ARGS = -- $(host-test-program-cmd)
> +
> +$(objpfx)tst-audit25b.out: $(objpfx)tst-auditmod25.so
> +$(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \
> +		       $(objpfx)tst-audit25mod2.so \
> +		       $(objpfx)tst-audit25mod3.so \
> +		       $(objpfx)tst-audit25mod4.so
> +LDFLAGS-tst-audit25b = -Wl,-z,now
> +tst-audit25b-ARGS = -- $(host-test-program-cmd)
> +
>  # tst-sonamemove links against an older implementation of the library.
>  LDFLAGS-tst-sonamemove-linkmod1.so = \
>    -Wl,--version-script=tst-sonamemove-linkmod1.map \
> diff --git a/elf/dl-audit.c b/elf/dl-audit.c
> index 715de53272..794bfd45cd 100644
> --- a/elf/dl-audit.c
> +++ b/elf/dl-audit.c
> @@ -178,16 +178,23 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>  		   const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
>  		   lookup_t result)
>  {
> -  reloc_result->bound = result;
> -  /* Compute index of the symbol entry in the symbol table of the DSO with the
> -     definition.  */
> -  reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result,
> -							  l_info[DT_SYMTAB]));
> +  bool for_jmp_slot = reloc_result == NULL;

OK. Check if we have relocation result.

> +
> +  /* Compute index of the symbol entry in the symbol table of the DSO
> +     with the definition.  */
> +  unsigned int boundndx = defsym - (ElfW(Sym) *) D_PTR (result,
> +							l_info[DT_SYMTAB]);
> +  if (!for_jmp_slot)
> +    {
> +      reloc_result->bound = result;
> +      reloc_result->boundndx = boundndx;
> +    }


OK. Need to guard reloc_result around !for_jmp_slot.

>  
>    if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
>      {
>        /* Set all bits since this symbol binding is not interesting.  */
> -      reloc_result->enterexit = (1u << DL_NNS) - 1;
> +      if (!for_jmp_slot)
> +	reloc_result->enterexit = (1u << DL_NNS) - 1;

OK.

>        return;
>      }
>  
> @@ -199,12 +206,13 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>       two bits.  */
>    assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
>    assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
> -  reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
> +  uint32_t enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;

OK.

>  
>    const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]);
>  
>    unsigned int flags = 0;
>    struct audit_ifaces *afct = GLRO(dl_audit);
> +  uintptr_t new_value = (uintptr_t) sym.st_value;
>    for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
>      {
>        /* XXX Check whether both DSOs must request action or only one */
> @@ -215,37 +223,41 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>  	{
>  	  if (afct->symbind != NULL)
>  	    {

OK. We have an auditor function to call.

> -	      uintptr_t new_value = afct->symbind (&sym,
> -						   reloc_result->boundndx,
> -						   &l_state->cookie,
> -						   &result_state->cookie,
> -						   &flags,
> -						   strtab2 + defsym->st_name);
> +	      flags |= for_jmp_slot ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT
> +				    : 0;

OK. Set incoming flags depending on for_jmp_slot.

> +	      new_value = afct->symbind (&sym, boundndx,
> +					 &l_state->cookie,
> +					 &result_state->cookie, &flags,
> +					 strtab2 + defsym->st_name);
>  	      if (new_value != (uintptr_t) sym.st_value)
>  		{
>  		  flags |= LA_SYMB_ALTVALUE;
> -		  sym.st_value = new_value;
> +		  sym.st_value = for_jmp_slot
> +		    ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value;

OK.

>  		}
>  	    }
>  
>  	  /* Remember the results for every audit library and store a summary
>  	     in the first two bits.  */
> -	  reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER
> -					      | LA_SYMB_NOPLTEXIT);
> -	  reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
> -						| LA_SYMB_NOPLTEXIT))
> -				      << ((cnt + 1) * 2));
> +	  enterexit &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
> +	  enterexit |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
> +			<< ((cnt + 1) * 2));

OK.

>  	}
>        else
>  	/* If the bind flags say this auditor is not interested, set the bits
>  	   manually.  */
> -	reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
> -				    << ((cnt + 1) * 2));
> +	enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
> +		      << ((cnt + 1) * 2));

OK.

>        afct = afct->next;
>      }
>  
> -  reloc_result->flags = flags;
> -  *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
> +  if (!for_jmp_slot)
> +    {
> +      reloc_result->enterexit = enterexit;
> +      reloc_result->flags = flags;
> +    }
> +
> +  DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);

OK.

>  }
>  
>  void
> diff --git a/elf/do-rel.h b/elf/do-rel.h
> index 0718badf83..60d5dce8f2 100644
> --- a/elf/do-rel.h
> +++ b/elf/do-rel.h
> @@ -16,6 +16,8 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> +#include <ldsodefs.h>
> +
>  /* This file may be included twice, to define both
>     `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.  */
>  
> @@ -123,6 +125,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
>  
>  	  for (; r < end; ++r)
>  	    {
> +	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
> +	      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
> +	      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
> +	      const struct r_found_version *rversion = &map->l_versions[ndx];
>  #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
>  	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
>  		{
> @@ -133,10 +139,19 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
>  		}
>  #endif
>  
> -	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
> -	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
> -			       &map->l_versions[ndx],
> -			       (void *) (l_addr + r->r_offset), skip_ifunc);
> +	      elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg,
> +			       skip_ifunc);

OK. We are in the non-lazy case.

> +#if defined SHARED && !defined RTLD_BOOTSTRAP
> +	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
> +		  && GLRO(dl_naudit) > 0)
> +		{
> +		  struct link_map *sym_map
> +		    = RESOLVE_MAP (map, scope, &sym, rversion,
> +				   ELF_MACHINE_JMP_SLOT);

OK. Do the extra check at startup.


> +		  if (sym != NULL)
> +		    _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map);

OK. Early immeidate binding for symbol.

> +		}
> +#endif
>  	    }
>  
>  #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
> @@ -158,17 +173,33 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
>        else
>  	{
>  	  for (; r < end; ++r)
> +	    {
> +	      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
> +	      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
>  # ifdef ELF_MACHINE_IRELATIVE
> -	    if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
> -	      {
> -		if (r2 == NULL)
> -		  r2 = r;
> -		end2 = r;
> -	      }
> -	    else
> +	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
> +		{
> +		  if (r2 == NULL)
> +		    r2 = r;
> +		  end2 = r;
> +		  continue;
> +		}
>  # endif
> -	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
> -			       (void *) (l_addr + r->r_offset), skip_ifunc);
> +	      elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg,
> +			       skip_ifunc);

OK. We are in the non-lazy case as expected.

> +# if defined SHARED && !defined RTLD_BOOTSTRAP
> +	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
> +		  && GLRO(dl_naudit) > 0)
> +		{
> +		  struct link_map *sym_map
> +		    = RESOLVE_MAP (map, scope, &sym,
> +				   (struct r_found_version *) NULL,
> +				   ELF_MACHINE_JMP_SLOT);
> +		  if (sym != NULL)
> +		    _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map);

OK. Again do the symbol binding auditing for immediate binding.


> +		}
> +# endif
> +	    }
>  
>  # ifdef ELF_MACHINE_IRELATIVE
>  	  if (r2 != NULL)
> diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c
> index 1077458c9d..a5edd438f9 100644
> --- a/elf/sotruss-lib.c
> +++ b/elf/sotruss-lib.c
> @@ -16,6 +16,7 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> +#include <err.h>
>  #include <error.h>
>  #include <fcntl.h>
>  #include <stdio.h>
> @@ -231,6 +232,12 @@ uintptr_t
>  la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook,
>  	    uintptr_t *defcook, unsigned int *flags, const char *symname)
>  {
> +  if (*flags & LA_SYMB_NOPLTENTER)
> +    warnx ("cannot trace PLT enter (bind-now enabled)");

OK. Awesome! :-)

> +
> +  if (do_exit && *flags & LA_SYMB_NOPLTEXIT)
> +    warnx ("cannot trace PLT exit (bind-now enabled)");

OK.

> +
>    if (!do_exit)
>      *flags = LA_SYMB_NOPLTEXIT;
>  
> diff --git a/elf/tst-audit24a.c b/elf/tst-audit24a.c
> new file mode 100644
> index 0000000000..2cdd3fb98b
> --- /dev/null
> +++ b/elf/tst-audit24a.c
> @@ -0,0 +1,36 @@
> +/* DL_AUDIT test for la_symbind and bind-now.

s/DL_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <support/check.h>
> +#include <support/support.h>
> +
> +int tst_audit24amod1_func1 (void);
> +int tst_audit24amod1_func2 (void);
> +int tst_audit24amod2_func1 (void);

OK. Calling 3 DSO functions with args.

> +
> +int
> +do_test (void)
> +{
> +  TEST_COMPARE (tst_audit24amod1_func1 (), 1);
> +  TEST_COMPARE (tst_audit24amod1_func2 (), 2);
> +  TEST_COMPARE (tst_audit24amod2_func1 (), 10);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/elf/tst-audit24amod1.c b/elf/tst-audit24amod1.c
> new file mode 100644
> index 0000000000..c287372e32
> --- /dev/null
> +++ b/elf/tst-audit24amod1.c
> @@ -0,0 +1,31 @@
> +/* Modules used by tst-audit24a.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <stdlib.h>
> +
> +_Noreturn int
> +tst_audit24amod1_func1 (void)
> +{
> +  abort ();

OK. Calls abort. Needs redirecting.

> +}
> +
> +int
> +tst_audit24amod1_func2 (void)
> +{
> +  return 2;

OK.

> +}
> diff --git a/elf/tst-audit24amod2.c b/elf/tst-audit24amod2.c
> new file mode 100644
> index 0000000000..938c71dc29
> --- /dev/null
> +++ b/elf/tst-audit24amod2.c
> @@ -0,0 +1,25 @@
> +/* Modules used by tst-audit24a.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <stdlib.h>
> +
> +_Noreturn int
> +tst_audit24amod2_func1 (void)
> +{
> +  abort ();

OK. Function aborts. Needs redirecting.

> +}
> diff --git a/elf/tst-audit24b.c b/elf/tst-audit24b.c
> new file mode 100644
> index 0000000000..82478ed8f9
> --- /dev/null
> +++ b/elf/tst-audit24b.c
> @@ -0,0 +1,37 @@
> +/* DL_AUDIT test for la_symbind and bind-now.

s/DL_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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 similar to tst-audit24a, with the difference this modules
> +   does not have the .gnu.version section header.  */
> +
> +#include <support/check.h>
> +#include <support/support.h>
> +
> +int tst_audit24bmod1_func1 (void);
> +int tst_audit24bmod1_func2 (void);
> +
> +int
> +do_test (void)
> +{
> +  TEST_COMPARE (tst_audit24bmod1_func1 (), 1);
> +  TEST_COMPARE (tst_audit24bmod1_func2 (), 2);

OK. Second test. Call two DSO functions.

> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/elf/tst-audit24bmod1.c b/elf/tst-audit24bmod1.c
> new file mode 100644
> index 0000000000..5fa4611918
> --- /dev/null
> +++ b/elf/tst-audit24bmod1.c
> @@ -0,0 +1,31 @@
> +/* Modules used by tst-audit24c.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +int tst_audit24bmod2_func1 (void);
> +
> +int
> +tst_audit24bmod1_func1 (void)
> +{
> +  return -1;
> +}
> +
> +int
> +tst_audit24bmod1_func2 (void)
> +{
> +  return tst_audit24bmod2_func1 ();

OK. fun2 calls func1 in dependent DSO.

> +}
> diff --git a/elf/tst-audit24bmod2.c b/elf/tst-audit24bmod2.c
> new file mode 100644
> index 0000000000..d469e70a41
> --- /dev/null
> +++ b/elf/tst-audit24bmod2.c
> @@ -0,0 +1,23 @@
> +/* Modules used by tst-audit24b.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +int
> +tst_audit24bmod2_func1 (void)
> +{
> +  return -1;

OK.

> +}
> diff --git a/elf/tst-audit24c.c b/elf/tst-audit24c.c
> new file mode 100644
> index 0000000000..46ed328756
> --- /dev/null
> +++ b/elf/tst-audit24c.c
> @@ -0,0 +1,2 @@
> +/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now  */
> +#include "tst-audit24a.c"

OK.

> diff --git a/elf/tst-audit24d.c b/elf/tst-audit24d.c
> new file mode 100644
> index 0000000000..1c89e4cb83
> --- /dev/null
> +++ b/elf/tst-audit24d.c
> @@ -0,0 +1,36 @@
> +/* DL_AUDIT test for la_symbind and bind-now.

s/DL_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <support/check.h>
> +#include <support/support.h>
> +
> +int tst_audit24dmod1_func1 (void);
> +int tst_audit24dmod1_func2 (void);
> +int tst_audit24dmod2_func1 (void);
> +
> +int
> +do_test (void)
> +{
> +  TEST_COMPARE (tst_audit24dmod1_func1 (), 1);
> +  TEST_COMPARE (tst_audit24dmod1_func2 (), 32);
> +  TEST_COMPARE (tst_audit24dmod2_func1 (), 10);

OK. Call functions in 2 DSOs.

> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/elf/tst-audit24dmod1.c b/elf/tst-audit24dmod1.c
> new file mode 100644
> index 0000000000..3ff2218c96
> --- /dev/null
> +++ b/elf/tst-audit24dmod1.c
> @@ -0,0 +1,33 @@
> +/* Modules used by tst-audit24d.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <stdlib.h>
> +
> +int tst_audit24dmod3_func1 (void);
> +
> +_Noreturn int
> +tst_audit24dmod1_func1 (void)
> +{
> +  abort ();

OK. Function aborts. Needs redirection.

> +}
> +
> +int
> +tst_audit24dmod1_func2 (void)
> +{
> +  return 2 + tst_audit24dmod3_func1 ();;

s/;;/;/g

OK. Calls 3rd DSO.

> +}
> diff --git a/elf/tst-audit24dmod2.c b/elf/tst-audit24dmod2.c
> new file mode 100644
> index 0000000000..03fe938128
> --- /dev/null
> +++ b/elf/tst-audit24dmod2.c
> @@ -0,0 +1,28 @@
> +/* Module for tst-audit24d.
> +   Copyright (C) 2022 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/>.  */
> +
> +#include <stdlib.h>
> +
> +int tst_audit24dmod4_func1 (void);
> +
> +_Noreturn int
> +tst_audit24dmod2_func1 (void)
> +{
> +  tst_audit24dmod4_func1 ();
> +  abort ();

OK. Calls 4th DSO and *then* aborts.

> +}
> diff --git a/elf/tst-audit24dmod3.c b/elf/tst-audit24dmod3.c
> new file mode 100644
> index 0000000000..106d517d28
> --- /dev/null
> +++ b/elf/tst-audit24dmod3.c
> @@ -0,0 +1,31 @@
> +/* Module for tst-audit24d.
> +   Copyright (C) 2022 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/>.  */
> +
> +#include <stdlib.h>
> +
> +_Noreturn int
> +tst_audit24dmod3_func1 (void)
> +{
> +  abort ();
> +}
> +
> +int
> +tst_audit24dmod3_func2 (void)
> +{
> +  return 4;
> +}

OK.

> diff --git a/elf/tst-audit24dmod4.c b/elf/tst-audit24dmod4.c
> new file mode 100644
> index 0000000000..1da3b46917
> --- /dev/null
> +++ b/elf/tst-audit24dmod4.c
> @@ -0,0 +1,25 @@
> +/* Module for tst-audit24d.
> +   Copyright (C) 2022 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/>.  */
> +
> +#include <stdlib.h>
> +
> +_Noreturn int
> +tst_audit24dmod4_func1 (void)
> +{
> +  abort ();
> +}

OK.

> diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c
> new file mode 100644
> index 0000000000..3476069353
> --- /dev/null
> +++ b/elf/tst-audit25a.c
> @@ -0,0 +1,129 @@
> +/* Check DT_AUDIT and LD_BIND_NOW.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <array_length.h>
> +#include <errno.h>
> +#include <getopt.h>
> +#include <limits.h>
> +#include <inttypes.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <support/capture_subprocess.h>
> +#include <support/check.h>
> +#include <support/xstdio.h>
> +#include <support/support.h>
> +#include <sys/auxv.h>
> +
> +static int restart;
> +#define CMDLINE_OPTIONS \
> +  { "restart", no_argument, &restart, 1 },
> +
> +void tst_audit25mod1_func1 (void);
> +void tst_audit25mod1_func2 (void);
> +void tst_audit25mod2_func1 (void);
> +void tst_audit25mod2_func2 (void);
> +
> +static int
> +handle_restart (void)
> +{
> +  tst_audit25mod1_func1 ();
> +  tst_audit25mod1_func2 ();
> +  tst_audit25mod2_func1 ();
> +  tst_audit25mod2_func2 ();
> +
> +  return 0;
> +}
> +
> +static inline bool
> +startswith (const char *str, const char *pre)
> +{
> +  size_t lenpre = strlen (pre);
> +  size_t lenstr = strlen (str);
> +  return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
> +}
> +
> +static int
> +do_test (int argc, char *argv[])
> +{
> +  /* We must have either:
> +     - One our fource parameters left if called initially:

s/One our fource/One or four/g

> +       + path to ld.so         optional
> +       + "--library-path"      optional
> +       + the library path      optional
> +       + the application name  */
> +
> +  if (restart)
> +    return handle_restart ();
> +
> +  setenv ("LD_AUDIT", "tst-auditmod25.so", 0);
> +
> +  char *spargv[9];
> +  int i = 0;
> +  for (; i < argc - 1; i++)
> +    spargv[i] = argv[i + 1];
> +  spargv[i++] = (char *) "--direct";
> +  spargv[i++] = (char *) "--restart";
> +  spargv[i] = NULL;
> +  TEST_VERIFY_EXIT (i < array_length (spargv));
> +
> +  {
> +    struct support_capture_subprocess result
> +      = support_capture_subprogram (spargv[0], spargv);
> +    support_capture_subprocess_check (&result, "tst-audit25a", 0,
> +				      sc_allow_stderr);

OK. Call ourselves again.

> +
> +    /* tst-audit25a is build with -Wl,-z,lazy and tst-audit25mod1 with
> +       -Wl,-z,now; so only tst_audit25mod3_func1 should be expected to
> +       have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  */
> +    TEST_COMPARE_STRING (result.err.buffer,
> +			 "la_symbind: tst_audit25mod3_func1 1\n"
> +			 "la_symbind: tst_audit25mod1_func1 0\n"
> +			 "la_symbind: tst_audit25mod1_func2 0\n"
> +			 "la_symbind: tst_audit25mod2_func1 0\n"
> +			 "la_symbind: tst_audit25mod4_func1 0\n"
> +			 "la_symbind: tst_audit25mod2_func2 0\n");
> +
> +    support_capture_subprocess_free (&result);
> +  }
> +
> +  {
> +    setenv ("LD_BIND_NOW", "1", 0);
> +    struct support_capture_subprocess result
> +      = support_capture_subprogram (spargv[0], spargv);
> +    support_capture_subprocess_check (&result, "tst-audit25a", 0,
> +				      sc_allow_stderr);

OK.

> +
> +    /* With LD_BIND_NOW all symbols are expected to have
> +       LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  Also the resolution
> +       order is done in breadth-first order.  */
> +    TEST_COMPARE_STRING (result.err.buffer,
> +			 "la_symbind: tst_audit25mod4_func1 1\n"
> +			 "la_symbind: tst_audit25mod3_func1 1\n"
> +			 "la_symbind: tst_audit25mod1_func1 1\n"
> +			 "la_symbind: tst_audit25mod2_func1 1\n"
> +			 "la_symbind: tst_audit25mod1_func2 1\n"
> +			 "la_symbind: tst_audit25mod2_func2 1\n");
> +
> +    support_capture_subprocess_free (&result);
> +  }
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION_ARGV do_test
> +#include <support/test-driver.c>
> diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c
> new file mode 100644
> index 0000000000..8bf98bc7fd
> --- /dev/null
> +++ b/elf/tst-audit25b.c
> @@ -0,0 +1,128 @@
> +/* Check DT_AUDIT and LD_BIND_NOW.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <errno.h>
> +#include <getopt.h>
> +#include <limits.h>
> +#include <inttypes.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <support/capture_subprocess.h>
> +#include <support/check.h>
> +#include <support/xstdio.h>
> +#include <support/support.h>
> +#include <sys/auxv.h>
> +
> +static int restart;
> +#define CMDLINE_OPTIONS \
> +  { "restart", no_argument, &restart, 1 },
> +
> +void tst_audit25mod1_func1 (void);
> +void tst_audit25mod1_func2 (void);
> +void tst_audit25mod2_func1 (void);
> +void tst_audit25mod2_func2 (void);
> +
> +static int
> +handle_restart (void)
> +{
> +  tst_audit25mod1_func1 ();
> +  tst_audit25mod1_func2 ();
> +  tst_audit25mod2_func1 ();
> +  tst_audit25mod2_func2 ();
> +
> +  return 0;
> +}
> +
> +static inline bool
> +startswith (const char *str, const char *pre)
> +{
> +  size_t lenpre = strlen (pre);
> +  size_t lenstr = strlen (str);
> +  return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
> +}
> +
> +static int
> +do_test (int argc, char *argv[])
> +{
> +  /* We must have either:
> +     - One our fource parameters left if called initially:

s/One our fource/One or four/g

> +       + path to ld.so         optional
> +       + "--library-path"      optional
> +       + the library path      optional
> +       + the application name  */
> +
> +  if (restart)
> +    return handle_restart ();
> +
> +  setenv ("LD_AUDIT", "tst-auditmod25.so", 0);
> +
> +  char *spargv[9];
> +  int i = 0;
> +  for (; i < argc - 1; i++)
> +    spargv[i] = argv[i + 1];
> +  spargv[i++] = (char *) "--direct";
> +  spargv[i++] = (char *) "--restart";
> +  spargv[i] = NULL;
> +
> +  {
> +    struct support_capture_subprocess result
> +      = support_capture_subprogram (spargv[0], spargv);
> +    support_capture_subprocess_check (&result, "tst-audit25a", 0,
> +				      sc_allow_stderr);

OK.

> +
> +    /* tst-audit25a and tst-audit25mod1 are built with -Wl,-z,now, but
> +       tst-audit25mod2 is built with -Wl,z,lazy.  So only

s/,z,/,-z,/g

> +       tst_audit25mod4_func1 (called by tst_audit25mod2_func1) should not
> +       have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  */
> +    TEST_COMPARE_STRING (result.err.buffer,
> +			 "la_symbind: tst_audit25mod3_func1 1\n"
> +			 "la_symbind: tst_audit25mod1_func1 1\n"
> +			 "la_symbind: tst_audit25mod2_func1 1\n"
> +			 "la_symbind: tst_audit25mod1_func2 1\n"
> +			 "la_symbind: tst_audit25mod2_func2 1\n"
> +			 "la_symbind: tst_audit25mod4_func1 0\n");
> +
> +    support_capture_subprocess_free (&result);
> +  }
> +
> +  {
> +    setenv ("LD_BIND_NOW", "1", 0);
> +    struct support_capture_subprocess result
> +      = support_capture_subprogram (spargv[0], spargv);
> +    support_capture_subprocess_check (&result, "tst-audit25a", 0,
> +				      sc_allow_stderr);
> +
> +    /* With LD_BIND_NOW all symbols are expected to have
> +       LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  Also the resolution
> +       order is done in breadth-first order.  */

OK.

> +    TEST_COMPARE_STRING (result.err.buffer,
> +			 "la_symbind: tst_audit25mod4_func1 1\n"
> +			 "la_symbind: tst_audit25mod3_func1 1\n"
> +			 "la_symbind: tst_audit25mod1_func1 1\n"
> +			 "la_symbind: tst_audit25mod2_func1 1\n"
> +			 "la_symbind: tst_audit25mod1_func2 1\n"
> +			 "la_symbind: tst_audit25mod2_func2 1\n");
> +
> +    support_capture_subprocess_free (&result);
> +  }
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION_ARGV do_test
> +#include <support/test-driver.c>
> diff --git a/elf/tst-audit25mod1.c b/elf/tst-audit25mod1.c
> new file mode 100644
> index 0000000000..3cff8cc688
> --- /dev/null
> +++ b/elf/tst-audit25mod1.c
> @@ -0,0 +1,30 @@
> +/* Modules used by tst-audit25.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +void tst_audit25mod3_func1 (void);
> +
> +void
> +tst_audit25mod1_func1 (void)
> +{
> +  tst_audit25mod3_func1 ();
> +}
> +
> +void
> +tst_audit25mod1_func2 (void)
> +{
> +}

OK.

> diff --git a/elf/tst-audit25mod2.c b/elf/tst-audit25mod2.c
> new file mode 100644
> index 0000000000..5e40555fa9
> --- /dev/null
> +++ b/elf/tst-audit25mod2.c
> @@ -0,0 +1,30 @@
> +/* Modules used by tst-audit25.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +void tst_audit25mod4_func1 (void);
> +
> +void
> +tst_audit25mod2_func1 (void)
> +{
> +  tst_audit25mod4_func1 ();
> +}
> +
> +void
> +tst_audit25mod2_func2 (void)
> +{
> +}

OK.

> diff --git a/elf/tst-audit25mod3.c b/elf/tst-audit25mod3.c
> new file mode 100644
> index 0000000000..e35ed6a1da
> --- /dev/null
> +++ b/elf/tst-audit25mod3.c
> @@ -0,0 +1,22 @@
> +/* Modules used by tst-audit25.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +void
> +tst_audit25mod3_func1 (void)
> +{
> +}

OK.

> diff --git a/elf/tst-audit25mod4.c b/elf/tst-audit25mod4.c
> new file mode 100644
> index 0000000000..c3118b6368
> --- /dev/null
> +++ b/elf/tst-audit25mod4.c
> @@ -0,0 +1,22 @@
> +/* Modules used by tst-audit25.

s/Modules/Module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +void
> +tst_audit25mod4_func1 (void)
> +{
> +}

OK.

> diff --git a/elf/tst-auditmod24.h b/elf/tst-auditmod24.h
> new file mode 100644
> index 0000000000..e34c53df5e
> --- /dev/null
> +++ b/elf/tst-auditmod24.h
> @@ -0,0 +1,29 @@
> +/* Auxiliary functions for tst-audit24x.
> +   Copyright (C) 2022 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/>.  */
> +
> +#ifndef _TST_AUDITMOD24_H
> +#define _TST_AUDITMOD24_H
> +
> +static void
> +check_symbind_flags (unsigned int flags)

Would suggest calling it "test_symbind_flags" since this is testing a specific
condition of the test and aborting if not met.

> +{
> +  if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0)
> +    abort ();

OK. Abort if none of the flags are set.

> +}
> +
> +#endif
> diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c
> new file mode 100644
> index 0000000000..a4838b3e05
> --- /dev/null
> +++ b/elf/tst-auditmod24a.c
> @@ -0,0 +1,114 @@
> +/* Audit modules for tst-audit24a.

s/modules/module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <link.h>
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <tst-auditmod24.h>
> +
> +#define AUDIT24_COOKIE     0x1
> +#define AUDIT24MOD1_COOKIE 0x2
> +#define AUDIT24MOD2_COOKIE 0x3
> +
> +#ifndef TEST_NAME
> +# define TEST_NAME "tst-audit24a"
> +#endif
> +#ifndef TEST_MOD
> +# define TEST_MOD TEST_NAME
> +#endif
> +#ifndef TEST_FUNC
> +# define TEST_FUNC "tst_audit24a"
> +#endif
> +
> +unsigned int
> +la_version (unsigned int version)
> +{
> +  return LAV_CURRENT;
> +}
> +
> +unsigned int
> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
> +{
> +  const char *p = strrchr (map->l_name, '/');
> +  const char *l_name = p == NULL ? TEST_NAME : p + 1;
> +
> +  uintptr_t ck = -1;
> +  if (strcmp (l_name, TEST_MOD "mod1.so") == 0)
> +    ck = AUDIT24MOD1_COOKIE;
> +  else if (strcmp (l_name, TEST_MOD "mod2.so") == 0)
> +    ck = AUDIT24MOD2_COOKIE;
> +  else if (strcmp (l_name, TEST_NAME) == 0)
> +    ck = AUDIT24_COOKIE;
> +
> +  *cookie = ck;
> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;

OK.

> +}
> +
> +static int
> +tst_func1 (void)
> +{
> +  return 1;
> +}
> +
> +static int
> +tst_func2 (void)
> +{
> +  return 10;
> +}

OK. Define two safety functions to use to avoid abort()s in the actual
implementations.

> +
> +#if __ELF_NATIVE_CLASS == 64
> +uintptr_t
> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
> +	      uintptr_t *refcook, uintptr_t *defcook,
> +	      unsigned int *flags, const char *symname)
> +#else
> +uintptr_t
> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
> +	      uintptr_t *refcook, uintptr_t *defcook,
> +	      unsigned int *flags, const char *symname)
> +#endif
> +{
> +  if (*refcook == AUDIT24_COOKIE)
> +    {
> +      if (*defcook == AUDIT24MOD1_COOKIE)
> +	{
> +	  /* Check if bind-now symbols are advertised to not call the PLT
> +	     hooks.  */
> +	  check_symbind_flags (*flags);
> +
> +	  if (strcmp (symname, TEST_FUNC "mod1_func1") == 0)
> +	    return (uintptr_t) tst_func1;
> +	  else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0)
> +	    return sym->st_value;
> +	  abort ();
> +	}
> +      if (*defcook == AUDIT24MOD2_COOKIE
> +	  && (strcmp (symname, TEST_FUNC "mod2_func1") == 0))
> +	{
> +	  check_symbind_flags (*flags);
> +
> +	  return (uintptr_t) tst_func2;
> +	}
> +
> +      /* malloc functions.  */
> +      return sym->st_value;
> +    }
> +
> +  abort ();

OK.

> +}
> diff --git a/elf/tst-auditmod24b.c b/elf/tst-auditmod24b.c
> new file mode 100644
> index 0000000000..aefac8ced4
> --- /dev/null
> +++ b/elf/tst-auditmod24b.c
> @@ -0,0 +1,104 @@
> +/* Audit modules for tst-audit24b.

s/modules/module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <link.h>
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <tst-auditmod24.h>
> +
> +#define TEST_NAME "tst-audit24b"
> +#define TEST_FUNC "tst_audit24b"
> +
> +#define AUDIT24_COOKIE     0x1
> +#define AUDIT24MOD1_COOKIE 0x2
> +#define AUDIT24MOD2_COOKIE 0x3
> +
> +unsigned int
> +la_version (unsigned int version)
> +{
> +  return LAV_CURRENT;
> +}
> +
> +unsigned int
> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
> +{
> +  const char *p = strrchr (map->l_name, '/');
> +  const char *l_name = p == NULL ? TEST_NAME : p + 1;
> +
> +  uintptr_t ck = -1;
> +  if (strcmp (l_name, TEST_NAME "mod1.so") == 0)
> +    ck = AUDIT24MOD1_COOKIE;
> +  else if (strcmp (l_name, TEST_NAME "mod2.so") == 0)
> +    ck = AUDIT24MOD2_COOKIE;
> +  else if (strcmp (l_name, TEST_NAME) == 0)
> +    ck = AUDIT24_COOKIE;
> +
> +  *cookie = ck;
> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;

OK.

> +}
> +
> +static int
> +tst_func1 (void)
> +{
> +  return 1;
> +}
> +
> +static int
> +tst_func2 (void)
> +{
> +  return 2;
> +}

OK. Define two safe functions.

> +
> +#if __ELF_NATIVE_CLASS == 64
> +uintptr_t
> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
> +	      uintptr_t *refcook, uintptr_t *defcook,
> +	      unsigned int *flags, const char *symname)
> +#else
> +uintptr_t
> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
> +	      uintptr_t *refcook, uintptr_t *defcook,
> +	      unsigned int *flags, const char *symname)
> +#endif
> +{
> +  if (*refcook == AUDIT24_COOKIE)
> +    {
> +      if (*defcook == AUDIT24MOD1_COOKIE)
> +	  {
> +	    if (strcmp (symname, TEST_FUNC "mod1_func1") == 0)
> +	      return (uintptr_t) tst_func1;

OK.

> +	    else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0)
> +	      return sym->st_value;
> +	    abort ();
> +	  }
> +      /* malloc functions.  */
> +      return sym->st_value;
> +    }
> +  else if (*refcook == AUDIT24MOD1_COOKIE)
> +    {
> +      if (*defcook == AUDIT24MOD2_COOKIE
> +	  && (strcmp (symname, TEST_FUNC "mod2_func1") == 0))
> +	{
> +	  check_symbind_flags (*flags);
> +	  return (uintptr_t) tst_func2;

OK.

> +	}
> +    }
> +
> +  abort ();
> +}
> diff --git a/elf/tst-auditmod24c.c b/elf/tst-auditmod24c.c
> new file mode 100644
> index 0000000000..67e62c9d33
> --- /dev/null
> +++ b/elf/tst-auditmod24c.c
> @@ -0,0 +1,3 @@
> +#define TEST_NAME "tst-audit24c"
> +#define TEST_MOD  "tst-audit24a"
> +#include "tst-auditmod24a.c"

OK.

> diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c
> new file mode 100644
> index 0000000000..a49f00ef17
> --- /dev/null
> +++ b/elf/tst-auditmod24d.c
> @@ -0,0 +1,120 @@
> +/* Audit module for tst-audit24d.
> +   Copyright (C) 2022 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/>.  */
> +
> +#include <link.h>
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <tst-auditmod24.h>
> +
> +#define AUDIT24_COOKIE     0x0
> +#define AUDIT24MOD1_COOKIE 0x1
> +#define AUDIT24MOD2_COOKIE 0x2
> +#define AUDIT24MOD3_COOKIE 0x3
> +#define AUDIT24MOD4_COOKIE 0x4
> +
> +unsigned int
> +la_version (unsigned int version)
> +{
> +  return LAV_CURRENT;

OK.

> +}
> +
> +unsigned int
> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
> +{
> +  const char *p = strrchr (map->l_name, '/');
> +  const char *l_name = p == NULL ? "tst-audit24d" : p + 1;
> +
> +  uintptr_t ck = -1;
> +  if (strcmp (l_name, "tst-audit24dmod1.so") == 0)
> +    ck = AUDIT24MOD1_COOKIE;
> +  else if (strcmp (l_name, "tst-audit24dmod2.so") == 0)
> +    ck = AUDIT24MOD2_COOKIE;
> +  else if (strcmp (l_name, "tst-audit24dmod3.so") == 0)
> +    ck = AUDIT24MOD3_COOKIE;
> +  else if (strcmp (l_name, "tst-audit24dmod.so") == 0)
> +    ck = AUDIT24MOD4_COOKIE;
> +  else if (strcmp (l_name, "tst-audit24d") == 0)
> +    ck = AUDIT24_COOKIE;
> +
> +  *cookie = ck;
> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;

OK.

> +}
> +
> +static int
> +tst_audit24dmod1_func1 (void)
> +{
> +  return 1;
> +}
> +
> +static int
> +tst_audit24dmod2_func1 (void)
> +{
> +  return 10;
> +}
> +
> +static int
> +tst_audit24dmod3_func1 (void)
> +{
> +  return 30;
> +}

OK.

> +
> +#include <stdio.h>
> +
> +#if __ELF_NATIVE_CLASS == 64
> +uintptr_t
> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
> +	      uintptr_t *refcook, uintptr_t *defcook,
> +	      unsigned int *flags, const char *symname)
> +#else
> +uintptr_t
> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
> +	      uintptr_t *refcook, uintptr_t *defcook,
> +	      unsigned int *flags, const char *symname)
> +#endif
> +{
> +  if (*refcook == AUDIT24_COOKIE)
> +    {
> +      if (*defcook == AUDIT24MOD1_COOKIE)
> +	  {
> +	    if (strcmp (symname, "tst_audit24dmod1_func1") == 0)
> +	      return (uintptr_t) tst_audit24dmod1_func1;
> +	    else if (strcmp (symname, "tst_audit24dmod1_func2") == 0)
> +	      return sym->st_value;
> +	    abort ();
> +	  }
> +      if (*defcook == AUDIT24MOD2_COOKIE
> +	  && (strcmp (symname, "tst_audit24dmod2_func1") == 0))
> +	return (uintptr_t) tst_audit24dmod2_func1;
> +
> +      /* malloc functions.  */
> +      return sym->st_value;
> +    }
> +  else if (*refcook == AUDIT24MOD1_COOKIE)
> +    {
> +      if (*defcook == AUDIT24MOD3_COOKIE
> +	  && strcmp (symname, "tst_audit24dmod3_func1") == 0)
> +	{
> +	  check_symbind_flags (*flags);
> +
> +	  return (uintptr_t) tst_audit24dmod3_func1;
> +	}
> +    }
> +
> +  abort ();
> +}

OK.

> diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c
> new file mode 100644
> index 0000000000..526f5c54bc
> --- /dev/null
> +++ b/elf/tst-auditmod25.c
> @@ -0,0 +1,79 @@
> +/* Audit modules for tst-audit25a.

s/modules/module/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <link.h>
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <stdio.h>
> +
> +#define AUDIT25_COOKIE     0x1
> +#define AUDIT25MOD1_COOKIE 0x2
> +#define AUDIT25MOD2_COOKIE 0x3
> +#define AUDIT25MOD3_COOKIE 0x2
> +#define AUDIT25MOD4_COOKIE 0x3
> +
> +#define TEST_NAME "tst-audit25"
> +#define TEST_MOD  "tst-audit25"
> +#define TEST_FUNC "tst_audit25"
> +
> +unsigned int
> +la_version (unsigned int version)
> +{
> +  return LAV_CURRENT;
> +}
> +
> +unsigned int
> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
> +{
> +  const char *p = strrchr (map->l_name, '/');
> +  const char *l_name = p == NULL ? TEST_NAME : p + 1;
> +
> +  uintptr_t ck = -1;
> +  if (strcmp (l_name, TEST_MOD "mod1.so") == 0)
> +    ck = AUDIT25MOD1_COOKIE;
> +  else if (strcmp (l_name, TEST_MOD "mod2.so") == 0)
> +    ck = AUDIT25MOD2_COOKIE;
> +  else if (strcmp (l_name, TEST_MOD "mod3.so") == 0)
> +    ck = AUDIT25MOD3_COOKIE;
> +  else if (strcmp (l_name, TEST_MOD "mod4.so") == 0)
> +    ck = AUDIT25MOD4_COOKIE;
> +  else if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
> +    ck = AUDIT25_COOKIE;
> +
> +  *cookie = ck;
> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;

OK.

> +}
> +
> +#if __ELF_NATIVE_CLASS == 64
> +uintptr_t
> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
> +	      uintptr_t *refcook, uintptr_t *defcook,
> +	      unsigned int *flags, const char *symname)
> +#else
> +uintptr_t
> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
> +	      uintptr_t *refcook, uintptr_t *defcook,
> +	      unsigned int *flags, const char *symname)
> +#endif
> +{
> +  if (*refcook != -1 && *defcook != -1)
> +    fprintf (stderr, "la_symbind: %s %u\n", symname,
> +	     *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);

OK.

> +  return sym->st_value;
> +}
> diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h
> index 7460c0596a..95bcfc1cc1 100644
> --- a/sysdeps/generic/dl-lookupcfg.h
> +++ b/sysdeps/generic/dl-lookupcfg.h
> @@ -26,3 +26,6 @@
>  #define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
>  #define DL_FIXUP_VALUE_ADDR(value) (value)
>  #define DL_FIXUP_ADDR_VALUE(addr) (addr)
> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
> +  (*value) = st_value;

OK.

> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
> index 97061bdf9f..2ebe7901c0 100644
> --- a/sysdeps/generic/ldsodefs.h
> +++ b/sysdeps/generic/ldsodefs.h
> @@ -1431,7 +1431,10 @@ void _dl_audit_objclose (struct link_map *l)
>  /* Call the la_preinit from the audit modules for the link_map L.  */
>  void _dl_audit_preinit (struct link_map *l);
>  
> -/* Call the la_symbind{32,64} from the audit modules for the link_map L.  */
> +/* Call the la_symbind{32,64} from the audit modules for the link_map L.  If
> +   RELOC_RESULT is NULL it assumes the symbol to be bind-now and will set
> +   the flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT prior calling
> +   la_symbind{32,64}.  */

OK.

>  void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>  			const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
>  			lookup_t result)
> diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
> index 5d381147c0..8da2412fea 100644
> --- a/sysdeps/hppa/dl-lookupcfg.h
> +++ b/sysdeps/hppa/dl-lookupcfg.h
> @@ -80,3 +80,6 @@ void attribute_hidden _dl_unmap (struct link_map *map);
>  #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
>  #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
>  #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
> +  (*value) = *(struct fdesc *) (st_value)

OK.

> diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h
> index b8ab1bba15..3df3116b31 100644
> --- a/sysdeps/ia64/dl-lookupcfg.h
> +++ b/sysdeps/ia64/dl-lookupcfg.h
> @@ -74,3 +74,6 @@ extern void attribute_hidden _dl_unmap (struct link_map *map);
>  
>  #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
>  #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
> +  (*value) = *(struct fdesc *) (st_value)

OK.

> diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h
> new file mode 100644
> index 0000000000..25abcc1d12
> --- /dev/null
> +++ b/sysdeps/powerpc/dl-lookupcfg.h
> @@ -0,0 +1,39 @@
> +/* Configuration of lookup functions.  PowerPC version.
> +   Copyright (C) 2022 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/>.  */
> +
> +#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
> +#define DL_FIXUP_MAKE_VALUE(map, addr) (addr)
> +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
> +#define DL_FIXUP_VALUE_ADDR(value) (value)
> +#define DL_FIXUP_ADDR_VALUE(addr) (addr)
> +#if __WORDSIZE == 64 && _CALL_ELF == 1
> +/* We need to correctly set the audit modules value for bind-now.  */
> +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \
> + (((Elf64_FuncDesc *)(addr))->fd_func)
> +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value)	\
> + ({								\
> +    Elf64_FuncDesc *opd = (Elf64_FuncDesc *) (value);		\
> +    opd->fd_func = (st_value);					\
> +    if ((new_value) != (uintptr_t) (st_value))			\
> +     opd->fd_toc = ((Elf64_FuncDesc *)(new_value))->fd_toc;	\

OK.

> +  })
> +#else
> +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
> +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value)	\
> +  (*value) = st_value;

OK.

> +#endif


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 4/4] elf: Fix runtime linker auditing on aarch64 (BZ #26643)
  2022-01-25 18:37 ` [PATCH v12 4/4] elf: Fix runtime linker auditing on aarch64 (BZ #26643) Adhemerval Zanella
@ 2022-02-01  6:19   ` Carlos O'Donell
  2022-02-01 14:11     ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: Carlos O'Donell @ 2022-02-01  6:19 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha, jma14
  Cc: John Mellor-Crummey, Ben Woodard, Szabolcs Nagy

On 1/25/22 13:37, Adhemerval Zanella wrote:
> From: Ben Woodard <woodard@redhat.com>
> 
> The rtld audit support show two problems on aarch64:
> 
>   1. _dl_runtime_resolve does not preserve x8, the indirect result
>       location register, which might generate wrong result calls
>       depending of the function signature.
> 
>   2. The NEON Q registers pushed onto the stack by _dl_runtime_resolve
>      were twice the size of D registers extracted from the stack frame by
>      _dl_runtime_profile.
> 
> While 2. might result in wrong information passed on the PLT tracing,
> 1. generates wrong runtime behaviour.
> 
> The aarch64 rtld audit support is change to:

s/change/changed/g

> 
>   * Both La_aarch64_regs and La_aarch64_retval are expanded to include
>     both x8 and the full sized NEON V registers, as defined by the
>     ABI.
> 
>   * dl_runtime_profile needed to extract registers saved by
>     _dl_runtime_resolve and put them into the new correctly sized
>     La_aarch64_regs structure.
> 
>   * The LAV_CURRENT check is change to only accept new audit modules
>     to avoid the undefined behavior of not save/restore x8.

OK.

> 
>   * Different than other architectures, audit modules older than
>     LAV_CURRENT are rejected (both La_aarch64_regs and La_aarch64_retval
>     changed their layout and the it does worth the to support multiple

s/and the it does worth the/and there are no requirements/g

>     audit interface with the inherent aarch64 issues).
> 
>   * A new field is also reserved on both La_aarch64_regs and
>     La_aarch64_retval to support variant pcs symbols.
> 
> Similar to x86, a new La_aarch64_vector type to represent the NEON
> register is added on the La_aarch64_regs (so each type can be accessed
> directly).
> 
> Since LAV_CURRENT was already bumped to support bind-now, there is
> no need to increase it again.

OK.

> 
> Checked on aarch64-linux-gnu.

Please send v13 and I'll ACK that for glibc 2.35.

> 
> Co-authored-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
> Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
> ---
>  NEWS                             |   4 +
>  elf/rtld.c                       |   3 +-
>  sysdeps/aarch64/Makefile         |  20 ++++
>  sysdeps/aarch64/bits/link.h      |  26 +++--
>  sysdeps/aarch64/dl-audit-check.h |  28 +++++
>  sysdeps/aarch64/dl-link.sym      |   6 +-
>  sysdeps/aarch64/dl-trampoline.S  |  81 +++++++++-----
>  sysdeps/aarch64/tst-audit26.c    |  37 +++++++
>  sysdeps/aarch64/tst-audit26mod.c |  33 ++++++
>  sysdeps/aarch64/tst-audit26mod.h |  50 +++++++++
>  sysdeps/aarch64/tst-audit27.c    |  64 +++++++++++
>  sysdeps/aarch64/tst-audit27mod.c |  95 ++++++++++++++++
>  sysdeps/aarch64/tst-audit27mod.h |  67 ++++++++++++
>  sysdeps/aarch64/tst-auditmod26.c | 103 ++++++++++++++++++
>  sysdeps/aarch64/tst-auditmod27.c | 180 +++++++++++++++++++++++++++++++
>  sysdeps/generic/dl-audit-check.h |  23 ++++
>  16 files changed, 779 insertions(+), 41 deletions(-)
>  create mode 100644 sysdeps/aarch64/dl-audit-check.h
>  create mode 100644 sysdeps/aarch64/tst-audit26.c
>  create mode 100644 sysdeps/aarch64/tst-audit26mod.c
>  create mode 100644 sysdeps/aarch64/tst-audit26mod.h
>  create mode 100644 sysdeps/aarch64/tst-audit27.c
>  create mode 100644 sysdeps/aarch64/tst-audit27mod.c
>  create mode 100644 sysdeps/aarch64/tst-audit27mod.h
>  create mode 100644 sysdeps/aarch64/tst-auditmod26.c
>  create mode 100644 sysdeps/aarch64/tst-auditmod27.c
>  create mode 100644 sysdeps/generic/dl-audit-check.h
> 
> diff --git a/NEWS b/NEWS
> index c0f8932f84..40623d01c0 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -162,6 +162,10 @@ Deprecated and removed features, and other changes affecting compatibility:
>    proper bind-now support.  The loader now advertises on the la_symbind
>    flags that PLT trace is not possible.
>  
> +* The audit interface on aarch64 is extended to support both the indirect
> +  result location register (x8) and NEON Q register.  Old audit modules are
> +  rejected by the loader.

OK. Thanks for the NEWS update.

> +
>  Changes to build and runtime requirements:
>  
>    [Add changes to build and runtime requirements here]
> diff --git a/elf/rtld.c b/elf/rtld.c
> index 10436f7034..8dafaf61f4 100644
> --- a/elf/rtld.c
> +++ b/elf/rtld.c
> @@ -52,6 +52,7 @@
>  #include <get-dynamic-info.h>
>  #include <dl-execve.h>
>  #include <dl-find_object.h>
> +#include <dl-audit-check.h>
>  
>  #include <assert.h>
>  
> @@ -1000,7 +1001,7 @@ file=%s [%lu]; audit interface function la_version returned zero; ignored.\n",
>        return;
>      }
>  
> -  if (lav > LAV_CURRENT)
> +  if (!_dl_audit_check_version (lav))
>      {
>        _dl_debug_printf ("\
>  ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n",
> diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
> index 7c66fb97aa..7183895d04 100644
> --- a/sysdeps/aarch64/Makefile
> +++ b/sysdeps/aarch64/Makefile
> @@ -10,6 +10,26 @@ endif
>  
>  ifeq ($(subdir),elf)
>  sysdep-dl-routines += dl-bti
> +
> +tests += tst-audit26 \
> +	 tst-audit27

OK.

> +
> +modules-names += \
> +    tst-audit26mod \
> +    tst-auditmod26 \
> +    tst-audit27mod \
> +    tst-auditmod27
> +
> +$(objpfx)tst-audit26: $(objpfx)tst-audit26mod.so \
> +		      $(objpfx)tst-auditmod26.so
> +LDFLAGS-tst-audit26 += -Wl,-z,lazy
> +tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so
> +
> +$(objpfx)tst-audit27: $(objpfx)tst-audit27mod.so \
> +		      $(objpfx)tst-auditmod27.so
> +$(objpfx)tst-audit27mod.so: $(libsupport)
> +LDFLAGS-tst-audit27 += -Wl,-z,lazy
> +tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so
>  endif

OK.

>  
>  ifeq ($(subdir),elf)
> diff --git a/sysdeps/aarch64/bits/link.h b/sysdeps/aarch64/bits/link.h
> index e64f36d3f3..2479abc4fb 100644
> --- a/sysdeps/aarch64/bits/link.h
> +++ b/sysdeps/aarch64/bits/link.h
> @@ -20,23 +20,31 @@
>  # error "Never include <bits/link.h> directly; use <link.h> instead."
>  #endif
>  
> +typedef union
> +{
> +  float s;
> +  double d;
> +  long double q;
> +} La_aarch64_vector;

OK.

> +
>  /* Registers for entry into PLT on AArch64.  */
>  typedef struct La_aarch64_regs
>  {
> -  uint64_t lr_xreg[8];
> -  uint64_t lr_dreg[8];
> -  uint64_t lr_sp;
> -  uint64_t lr_lr;
> +  uint64_t          lr_xreg[9];

OK, add new lr_xreg.

> +  La_aarch64_vector lr_vreg[8];

OK, add lr_vreg's.

> +  uint64_t          lr_sp;
> +  uint64_t          lr_lr;
> +  void              *lr_vpcs;
>  } La_aarch64_regs;
>  
>  /* Return values for calls from PLT on AArch64.  */
>  typedef struct La_aarch64_retval
>  {
> -  /* Up to two integer registers can be used for a return value.  */
> -  uint64_t lrv_xreg[2];
> -  /* Up to four D registers can be used for a return value.  */
> -  uint64_t lrv_dreg[4];
> -
> +  /* Up to eight integer registers can be used for a return value.  */
> +  uint64_t          lrv_xreg[8];
> +  /* Up to eight V registers can be used for a return value.  */
> +  La_aarch64_vector lrv_vreg[8];
> +  void              *lrv_vpcs;

OK.

>  } La_aarch64_retval;
>  __BEGIN_DECLS
>  
> diff --git a/sysdeps/aarch64/dl-audit-check.h b/sysdeps/aarch64/dl-audit-check.h
> new file mode 100644
> index 0000000000..181eba0e8e
> --- /dev/null
> +++ b/sysdeps/aarch64/dl-audit-check.h
> @@ -0,0 +1,28 @@
> +/* rtld-audit version check.  AArch64 version.
> +   Copyright (C) 2022 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/>.  */
> +
> +static inline bool
> +_dl_audit_check_version (unsigned int lav)
> +{
> +  /* Audit version 1 do not save neither x8 nor NEON register, which required

s/neither x86 nor NEON register/x8 or NEON registers/g

> +     change La_aarch64_regs and La_aarch64_retval layout (BZ#26643).  The

s/change/changing/g

> +     missing indirect result save/restore makes _dl_runtime_profile
> +     potentially trigger undefined behavior if function returns a large

s/if/if the/g

> +     struct (even when PLT trace is not requested).  */
> +  return lav == LAV_CURRENT;
> +}
> diff --git a/sysdeps/aarch64/dl-link.sym b/sysdeps/aarch64/dl-link.sym
> index d67d28b40c..cb4dcdcbed 100644
> --- a/sysdeps/aarch64/dl-link.sym
> +++ b/sysdeps/aarch64/dl-link.sym
> @@ -7,9 +7,11 @@ DL_SIZEOF_RG		sizeof(struct La_aarch64_regs)
>  DL_SIZEOF_RV		sizeof(struct La_aarch64_retval)
>  
>  DL_OFFSET_RG_X0		offsetof(struct La_aarch64_regs, lr_xreg)
> -DL_OFFSET_RG_D0		offsetof(struct La_aarch64_regs, lr_dreg)
> +DL_OFFSET_RG_V0		offsetof(struct La_aarch64_regs, lr_vreg)

OK.

>  DL_OFFSET_RG_SP		offsetof(struct La_aarch64_regs, lr_sp)
>  DL_OFFSET_RG_LR		offsetof(struct La_aarch64_regs, lr_lr)
> +DL_OFFSET_RG_VPCS       offsetof(struct La_aarch64_regs, lr_vpcs)

OK.

>  
>  DL_OFFSET_RV_X0		offsetof(struct La_aarch64_retval, lrv_xreg)
> -DL_OFFSET_RV_D0		offsetof(struct La_aarch64_retval, lrv_dreg)
> +DL_OFFSET_RV_V0		offsetof(struct La_aarch64_retval, lrv_vreg)
> +DL_OFFSET_RV_VPCS       offsetof(struct La_aarch64_retval, lrv_vpcs)

OK.

> diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
> index a403863ef9..a7fc34639b 100644
> --- a/sysdeps/aarch64/dl-trampoline.S
> +++ b/sysdeps/aarch64/dl-trampoline.S
> @@ -45,7 +45,8 @@ _dl_runtime_resolve:
>  
>  	cfi_rel_offset (lr, 8)
>  
> -	/* Save arguments.  */
> +	/* Note: Saving x9 is not required by the ABI but the assember requires

s/assember/assembler/g

> +	   the immediate values of operand 3 to be a multiple of 16 */
>  	stp	x8, x9, [sp, #-(80+8*16)]!
>  	cfi_adjust_cfa_offset (80+8*16)
>  	cfi_rel_offset (x8, 0)
> @@ -142,7 +143,7 @@ _dl_runtime_profile:
>  	   Stack frame layout:
>  	   [sp,   #...] lr
>  	   [sp,   #...] &PLTGOT[n]
> -	   [sp,    #96] La_aarch64_regs
> +	   [sp,   #256] La_aarch64_regs

OK.

>  	   [sp,    #48] La_aarch64_retval
>  	   [sp,    #40] frame size return from pltenter
>  	   [sp,    #32] dl_profile_call saved x1
> @@ -183,19 +184,25 @@ _dl_runtime_profile:
>  	stp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
>  	cfi_rel_offset (x6, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 0)
>  	cfi_rel_offset (x7, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 8)
> -
> -	stp	d0, d1, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
> -	cfi_rel_offset (d0, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0)
> -	cfi_rel_offset (d1, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0 + 8)
> -	stp	d2, d3, [X29, #OFFSET_RG+ DL_OFFSET_RG_D0 + 16*1]
> -	cfi_rel_offset (d2, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 0)
> -	cfi_rel_offset (d3, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 8)
> -	stp	d4, d5, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
> -	cfi_rel_offset (d4, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 0)
> -	cfi_rel_offset (d5, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 8)
> -	stp	d6, d7, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
> -	cfi_rel_offset (d6, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 0)
> -	cfi_rel_offset (d7, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 8)
> +	str	x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0]
> +	cfi_rel_offset (x8, OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0)
> +	/* Note 8 bytes of padding is in the stack frame for alignment */
> +
> +	stp	q0, q1, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
> +	cfi_rel_offset (q0, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0)
> +	cfi_rel_offset (q1, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0 + 16)
> +	stp	q2, q3, [X29, #OFFSET_RG+ DL_OFFSET_RG_V0 + 32*1]
> +	cfi_rel_offset (q2, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 0)
> +	cfi_rel_offset (q3, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 16)
> +	stp	q4, q5, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
> +	cfi_rel_offset (q4, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 0)
> +	cfi_rel_offset (q5, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 16)
> +	stp	q6, q7, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]
> +	cfi_rel_offset (q6, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 0)
> +	cfi_rel_offset (q7, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 16)

OK.

> +
> +	/* No APCS extension supported.  */
> +	str	xzr,    [X29, #OFFSET_RG + DL_OFFSET_RG_VPCS]

OK.

>  
>  	add     x0, x29, #SF_SIZE + 16
>  	ldr	x1, [x29, #OFFSET_LR]
> @@ -234,10 +241,11 @@ _dl_runtime_profile:
>  	ldp	x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
>  	ldp	x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
>  	ldp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
> -	ldp	d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
> -	ldp	d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
> -	ldp	d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
> -	ldp	d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
> +	ldr	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
> +	ldp	q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
> +	ldp	q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1]
> +	ldp	q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
> +	ldp	q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]

OK.

>  
>  	cfi_def_cfa_register (sp)
>  	ldp	x29, x30, [x29, #0]
> @@ -280,14 +288,22 @@ _dl_runtime_profile:
>  	ldp	x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
>  	ldp	x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
>  	ldp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
> -	ldp	d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
> -	ldp	d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
> -	ldp	d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
> -	ldp	d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
> +	ldr	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
> +	ldp	q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
> +	ldp	q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1]
> +	ldp	q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
> +	ldp	q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]

OK.

>  	blr	ip0
> -	stp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
> -	stp	d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
> -	stp	d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
> +	stp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0]
> +	stp	x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
> +	stp	x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
> +	stp	x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
> +	str	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
> +	stp	q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
> +	stp	q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
> +	stp	q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
> +	stp	q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3]
> +	str	xzr,    [X29, #OFFSET_RV + DL_OFFSET_RG_VPCS]

OK.

>  
>  	/* Setup call to pltexit  */
>  	ldp	x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
> @@ -295,9 +311,16 @@ _dl_runtime_profile:
>  	add	x3, x29, #OFFSET_RV
>  	bl	_dl_audit_pltexit
>  
> -	ldp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
> -	ldp	d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
> -	ldp	d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
> +	ldp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0]
> +	ldp	x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
> +	ldp	x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
> +	ldp	x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
> +	ldr	x8,     [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*4]
> +	ldp	q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
> +	ldp	q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
> +	ldp	q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
> +	ldp	q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3]

OK.

> +
>  	/* LR from within La_aarch64_reg */
>  	ldr	lr, [x29, #OFFSET_RG + DL_OFFSET_RG_LR]
>  	cfi_restore(lr)
> diff --git a/sysdeps/aarch64/tst-audit26.c b/sysdeps/aarch64/tst-audit26.c
> new file mode 100644
> index 0000000000..8772958541
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-audit26.c
> @@ -0,0 +1,37 @@
> +/* Check DT_AUDIT for aarch64 ABI specifics.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <array_length.h>
> +#include <string.h>
> +#include <support/check.h>
> +#include "tst-audit26mod.h"
> +
> +int
> +do_test (void)
> +{
> +  /* Returning a large struct uses 'x8' as indirect result location.  */
> +  struct large_struct r = tst_audit26_func (ARG1, ARG2, ARG3);
> +
> +  struct large_struct e = set_large_struct (ARG1, ARG2, ARG3);
> +
> +  TEST_COMPARE_BLOB (r.a, sizeof (r.a), e.a, sizeof (e.a));
> +
> +  return 0;
> +}

OK.

> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/aarch64/tst-audit26mod.c b/sysdeps/aarch64/tst-audit26mod.c
> new file mode 100644
> index 0000000000..8d309be575
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-audit26mod.c
> @@ -0,0 +1,33 @@
> +/* Check DT_AUDIT for aarch64 ABI specifics.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <stdlib.h>
> +#include "tst-audit26mod.h"
> +
> +struct large_struct
> +tst_audit26_func (char a, short b, long int c)
> +{
> +  if (a != ARG1)
> +    abort ();
> +  if (b != ARG2)
> +    abort ();
> +  if (c != ARG3)
> +    abort ();
> +
> +  return set_large_struct (a, b, c);
> +}

OK.

> diff --git a/sysdeps/aarch64/tst-audit26mod.h b/sysdeps/aarch64/tst-audit26mod.h
> new file mode 100644
> index 0000000000..4226fad8cd
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-audit26mod.h
> @@ -0,0 +1,50 @@
> +/* Check DT_AUDIT for aarch64 specific ABI.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#ifndef _TST_AUDIT27MOD_H
> +#define _TST_AUDIT27MOD_H 1
> +
> +#include <array_length.h>
> +
> +struct large_struct
> +{
> +  char a[16];
> +  short b[8];
> +  long int c[4];
> +};


OK.

> +
> +static inline struct large_struct
> +set_large_struct (char a, short b, long int c)
> +{
> +  struct large_struct r;
> +  for (int i = 0; i < array_length (r.a); i++)
> +    r.a[i] = a;
> +  for (int i = 0; i < array_length (r.b); i++)
> +    r.b[i] = b;
> +  for (int i = 0; i < array_length (r.c); i++)
> +    r.c[i] = c;
> +  return r;

OK.

> +}
> +
> +#define ARG1 0x12
> +#define ARG2 0x1234
> +#define ARG3 0x12345678

OK.

> +
> +struct large_struct tst_audit26_func (char a, short b, long int c);

OK.

> +
> +#endif
> diff --git a/sysdeps/aarch64/tst-audit27.c b/sysdeps/aarch64/tst-audit27.c
> new file mode 100644
> index 0000000000..f5017ce0f1
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-audit27.c
> @@ -0,0 +1,64 @@
> +/* Check DT_AUDIT for aarch64 ABI specifics.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <array_length.h>
> +#include <string.h>
> +#include <support/check.h>
> +#include "tst-audit27mod.h"
> +
> +int
> +do_test (void)
> +{
> +  {
> +    float r = tst_audit27_func_float (FUNC_FLOAT_ARG0, FUNC_FLOAT_ARG1,
> +				      FUNC_FLOAT_ARG2, FUNC_FLOAT_ARG3,
> +				      FUNC_FLOAT_ARG4, FUNC_FLOAT_ARG5,
> +				      FUNC_FLOAT_ARG6, FUNC_FLOAT_ARG7);
> +    if (r != FUNC_FLOAT_RET)
> +      FAIL_EXIT1 ("tst_audit27_func_float() returned %a, expected %a",
> +		  r, FUNC_FLOAT_RET);
> +  }
> +
> +  {
> +    double r = tst_audit27_func_double (FUNC_DOUBLE_ARG0, FUNC_DOUBLE_ARG1,
> +					FUNC_DOUBLE_ARG2, FUNC_DOUBLE_ARG3,
> +					FUNC_DOUBLE_ARG4, FUNC_DOUBLE_ARG5,
> +					FUNC_DOUBLE_ARG6, FUNC_DOUBLE_ARG7);
> +    if (r != FUNC_DOUBLE_RET)
> +      FAIL_EXIT1 ("tst_audit27_func_double() returned %la, expected %la",
> +		  r, FUNC_DOUBLE_RET);
> +  }
> +
> +  {
> +    long double r = tst_audit27_func_ldouble (FUNC_LDOUBLE_ARG0,
> +					      FUNC_LDOUBLE_ARG1,
> +					      FUNC_LDOUBLE_ARG2,
> +					      FUNC_LDOUBLE_ARG3,
> +					      FUNC_LDOUBLE_ARG4,
> +					      FUNC_LDOUBLE_ARG5,
> +					      FUNC_LDOUBLE_ARG6,
> +					      FUNC_LDOUBLE_ARG7);
> +    if (r != FUNC_LDOUBLE_RET)
> +      FAIL_EXIT1 ("tst_audit27_func_ldouble() returned %La, expected %La",
> +		  r, FUNC_LDOUBLE_RET);
> +  }
> +
> +  return 0;

OK. Test float, double, and long double.

> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/aarch64/tst-audit27mod.c b/sysdeps/aarch64/tst-audit27mod.c
> new file mode 100644
> index 0000000000..69f1d672b3
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-audit27mod.c
> @@ -0,0 +1,95 @@
> +/* Check DT_AUDIT for aarch64 ABI specifics.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <array_length.h>
> +#include <stdlib.h>
> +#include <support/check.h>
> +#include "tst-audit27mod.h"
> +
> +float
> +tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4,
> +			float a5, float a6, float a7)
> +{
> +  if (a0 != FUNC_FLOAT_ARG0)
> +    FAIL_EXIT1 ("a0: %a != %a", a0, FUNC_FLOAT_ARG0);
> +  if (a1 != FUNC_FLOAT_ARG1)
> +    FAIL_EXIT1 ("a1: %a != %a", a1, FUNC_FLOAT_ARG1);
> +  if (a2 != FUNC_FLOAT_ARG2)
> +    FAIL_EXIT1 ("a2: %a != %a", a2, FUNC_FLOAT_ARG2);
> +  if (a3 != FUNC_FLOAT_ARG3)
> +    FAIL_EXIT1 ("a3: %a != %a", a3, FUNC_FLOAT_ARG3);
> +  if (a4 != FUNC_FLOAT_ARG4)
> +    FAIL_EXIT1 ("a4: %a != %a", a4, FUNC_FLOAT_ARG4);
> +  if (a5 != FUNC_FLOAT_ARG5)
> +    FAIL_EXIT1 ("a5: %a != %a", a5, FUNC_FLOAT_ARG5);
> +  if (a6 != FUNC_FLOAT_ARG6)
> +    FAIL_EXIT1 ("a6: %a != %a", a6, FUNC_FLOAT_ARG6);
> +  if (a7 != FUNC_FLOAT_ARG7)
> +    FAIL_EXIT1 ("a7: %a != %a", a7, FUNC_FLOAT_ARG7);
> +
> +  return FUNC_FLOAT_RET;
> +}
> +
> +double
> +tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4,
> +			 double a5, double a6, double a7)
> +{
> +  if (a0 != FUNC_DOUBLE_ARG0)
> +    FAIL_EXIT1 ("a0: %la != %la", a0, FUNC_DOUBLE_ARG0);
> +  if (a1 != FUNC_DOUBLE_ARG1)
> +    FAIL_EXIT1 ("a1: %la != %la", a1, FUNC_DOUBLE_ARG1);
> +  if (a2 != FUNC_DOUBLE_ARG2)
> +    FAIL_EXIT1 ("a2: %la != %la", a2, FUNC_DOUBLE_ARG2);
> +  if (a3 != FUNC_DOUBLE_ARG3)
> +    FAIL_EXIT1 ("a3: %la != %la", a3, FUNC_DOUBLE_ARG3);
> +  if (a4 != FUNC_DOUBLE_ARG4)
> +    FAIL_EXIT1 ("a4: %la != %la", a4, FUNC_DOUBLE_ARG4);
> +  if (a5 != FUNC_DOUBLE_ARG5)
> +    FAIL_EXIT1 ("a5: %la != %la", a5, FUNC_DOUBLE_ARG5);
> +  if (a6 != FUNC_DOUBLE_ARG6)
> +    FAIL_EXIT1 ("a6: %la != %la", a6, FUNC_DOUBLE_ARG6);
> +  if (a7 != FUNC_DOUBLE_ARG7)
> +    FAIL_EXIT1 ("a7: %la != %la", a7, FUNC_DOUBLE_ARG7);
> +
> +  return FUNC_DOUBLE_RET;
> +}
> +
> +long double
> +tst_audit27_func_ldouble (long double a0, long double a1, long double a2,
> +			  long double a3, long double a4, long double a5,
> +			  long double a6, long double a7)
> +{
> +  if (a0 != FUNC_LDOUBLE_ARG0)
> +    FAIL_EXIT1 ("a0: %La != %La", a0, FUNC_LDOUBLE_ARG0);
> +  if (a1 != FUNC_LDOUBLE_ARG1)
> +    FAIL_EXIT1 ("a1: %La != %La", a1, FUNC_LDOUBLE_ARG1);
> +  if (a2 != FUNC_LDOUBLE_ARG2)
> +    FAIL_EXIT1 ("a2: %La != %La", a2, FUNC_LDOUBLE_ARG2);
> +  if (a3 != FUNC_LDOUBLE_ARG3)
> +    FAIL_EXIT1 ("a3: %La != %La", a3, FUNC_LDOUBLE_ARG3);
> +  if (a4 != FUNC_LDOUBLE_ARG4)
> +    FAIL_EXIT1 ("a4: %La != %La", a4, FUNC_LDOUBLE_ARG4);
> +  if (a5 != FUNC_LDOUBLE_ARG5)
> +    FAIL_EXIT1 ("a5: %La != %La", a5, FUNC_LDOUBLE_ARG5);
> +  if (a6 != FUNC_LDOUBLE_ARG6)
> +    FAIL_EXIT1 ("a6: %La != %La", a6, FUNC_LDOUBLE_ARG6);
> +  if (a7 != FUNC_LDOUBLE_ARG7)
> +    FAIL_EXIT1 ("a7: %La != %La", a7, FUNC_LDOUBLE_ARG7);
> +
> +  return FUNC_LDOUBLE_RET;
> +}

OK.

> diff --git a/sysdeps/aarch64/tst-audit27mod.h b/sysdeps/aarch64/tst-audit27mod.h
> new file mode 100644
> index 0000000000..698df4d44f
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-audit27mod.h
> @@ -0,0 +1,67 @@
> +/* Check DT_AUDIT for aarch64 specific ABI.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#ifndef _TST_AUDIT27MOD_H
> +#define _TST_AUDIT27MOD_H 1
> +
> +#include <float.h>
> +
> +#define FUNC_FLOAT_ARG0 FLT_MIN
> +#define FUNC_FLOAT_ARG1 FLT_MAX
> +#define FUNC_FLOAT_ARG2 FLT_EPSILON
> +#define FUNC_FLOAT_ARG3 FLT_TRUE_MIN
> +#define FUNC_FLOAT_ARG4 0.0f
> +#define FUNC_FLOAT_ARG5 1.0f
> +#define FUNC_FLOAT_ARG6 2.0f
> +#define FUNC_FLOAT_ARG7 3.0f
> +#define FUNC_FLOAT_RET  4.0f
> +
> +float
> +tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4,
> +			float a5, float a6, float a7);
> +
> +#define FUNC_DOUBLE_ARG0 DBL_MIN
> +#define FUNC_DOUBLE_ARG1 DBL_MAX
> +#define FUNC_DOUBLE_ARG2 DBL_EPSILON
> +#define FUNC_DOUBLE_ARG3 DBL_TRUE_MIN
> +#define FUNC_DOUBLE_ARG4 0.0
> +#define FUNC_DOUBLE_ARG5 1.0
> +#define FUNC_DOUBLE_ARG6 2.0
> +#define FUNC_DOUBLE_ARG7 3.0
> +#define FUNC_DOUBLE_RET  0x1.fffffe0000001p+127
> +
> +double
> +tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4,
> +			 double a5, double a6, double a7);
> +
> +#define FUNC_LDOUBLE_ARG0 DBL_MAX + 1.0L
> +#define FUNC_LDOUBLE_ARG1 DBL_MAX + 2.0L
> +#define FUNC_LDOUBLE_ARG2 DBL_MAX + 3.0L
> +#define FUNC_LDOUBLE_ARG3 DBL_MAX + 4.0L
> +#define FUNC_LDOUBLE_ARG4 DBL_MAX + 5.0L
> +#define FUNC_LDOUBLE_ARG5 DBL_MAX + 6.0L
> +#define FUNC_LDOUBLE_ARG6 DBL_MAX + 7.0L
> +#define FUNC_LDOUBLE_ARG7 DBL_MAX + 8.0L
> +#define FUNC_LDOUBLE_RET  0x1.fffffffffffff000000000000001p+1023L
> +
> +long double
> +tst_audit27_func_ldouble (long double a0, long double a1, long double a2,
> +			  long double a3, long double a4, long double a5,
> +			  long double a6, long double a7);
> +
> +#endif

OK.

> diff --git a/sysdeps/aarch64/tst-auditmod26.c b/sysdeps/aarch64/tst-auditmod26.c
> new file mode 100644
> index 0000000000..91d224dfbe
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-auditmod26.c
> @@ -0,0 +1,103 @@
> +/* Check DT_AUDIT for aarch64 specific ABI.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <assert.h>
> +#include <link.h>
> +#include <string.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include "tst-audit26mod.h"
> +
> +#define TEST_NAME  "tst-audit26"
> +
> +#define AUDIT26_COOKIE 0
> +
> +unsigned int
> +la_version (unsigned int v)
> +{
> +  return v;

OK. Always works :}

> +}
> +
> +unsigned int
> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
> +{
> +  const char *p = strrchr (map->l_name, '/');
> +  const char *l_name = p == NULL ? map->l_name : p + 1;
> +  uintptr_t ck = -1;
> +  if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
> +    ck = AUDIT26_COOKIE;
> +  *cookie = ck;
> +  printf ("objopen: %ld, %s [cookie=%ld]\n", lmid, l_name, ck);
> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
> +}
> +
> +ElfW(Addr)
> +la_aarch64_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)),
> +                         unsigned int ndx __attribute__ ((unused)),
> +                         uintptr_t *refcook, uintptr_t *defcook,
> +                         La_aarch64_regs *regs, unsigned int *flags,
> +                         const char *symname, long int *framesizep)
> +{
> +  printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
> +	  symname, (long int) sym->st_value, ndx, *flags);
> +
> +  if (strcmp (symname, "tst_audit26_func") == 0)
> +    {
> +      assert (regs->lr_xreg[0] == ARG1);
> +      assert (regs->lr_xreg[1] == ARG2);
> +      assert (regs->lr_xreg[2] == ARG3);

OK.

> +    }
> +  else
> +    abort ();
> +
> +  assert (regs->lr_vpcs == 0);
> +
> +  /* Clobber 'x8'.  */
> +  asm volatile ("mov x8, -1" : : : "x8");
> +
> +  *framesizep = 1024;
> +
> +  return sym->st_value;
> +}
> +
> +unsigned int
> +la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
> +                        uintptr_t *defcook,
> +                        const struct La_aarch64_regs *inregs,
> +                        struct La_aarch64_retval *outregs, const char *symname)
> +{
> +  printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n",
> +	  symname, (long int) sym->st_value, ndx);
> +
> +  if (strcmp (symname, "tst_audit26_func") == 0)
> +    {
> +      assert (inregs->lr_xreg[0] == ARG1);
> +      assert (inregs->lr_xreg[1] == ARG2);
> +      assert (inregs->lr_xreg[2] == ARG3);

OK.

> +    }
> +  else
> +    abort ();
> +
> +  assert (inregs->lr_vpcs == 0);
> +  assert (outregs->lrv_vpcs == 0);
> +
> +  /* Clobber 'x8'.  */
> +  asm volatile ("mov x8, -1" : : : "x8");

OK.

> +
> +  return 0;
> +}
> diff --git a/sysdeps/aarch64/tst-auditmod27.c b/sysdeps/aarch64/tst-auditmod27.c
> new file mode 100644
> index 0000000000..57936d7e70
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-auditmod27.c
> @@ -0,0 +1,180 @@
> +/* Check DT_AUDIT for aarch64 specific ABI.

s/DT_AUDIT/LD_AUDIT/g

> +   Copyright (C) 2022 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/>.  */
> +
> +#include <assert.h>
> +#include <link.h>
> +#include <string.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include "tst-audit27mod.h"
> +
> +#define TEST_NAME  "tst-audit27"
> +
> +#define AUDIT27_COOKIE 0
> +
> +unsigned int
> +la_version (unsigned int v)
> +{
> +  return v;

OK.

> +}
> +
> +unsigned int
> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
> +{
> +  const char *p = strrchr (map->l_name, '/');
> +  const char *l_name = p == NULL ? map->l_name : p + 1;
> +  uintptr_t ck = -1;
> +  if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
> +    ck = AUDIT27_COOKIE;
> +  *cookie = ck;
> +  printf ("objopen: %ld, %s [%ld]\n", lmid, l_name, ck);
> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
> +}
> +
> +ElfW(Addr)
> +la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
> +			 uintptr_t *defcook, La_aarch64_regs *regs,
> +			 unsigned int *flags, const char *symname,
> +			 long int *framesizep)
> +{
> +  printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
> +	  symname, (long int) sym->st_value, ndx, *flags);
> +
> +  if (strcmp (symname, "tst_audit27_func_float") == 0)
> +    {
> +      assert (regs->lr_vreg[0].s == FUNC_FLOAT_ARG0);
> +      assert (regs->lr_vreg[1].s == FUNC_FLOAT_ARG1);
> +      assert (regs->lr_vreg[2].s == FUNC_FLOAT_ARG2);
> +      assert (regs->lr_vreg[3].s == FUNC_FLOAT_ARG3);
> +      assert (regs->lr_vreg[4].s == FUNC_FLOAT_ARG4);
> +      assert (regs->lr_vreg[5].s == FUNC_FLOAT_ARG5);
> +      assert (regs->lr_vreg[6].s == FUNC_FLOAT_ARG6);
> +      assert (regs->lr_vreg[7].s == FUNC_FLOAT_ARG7);

OK.

> +    }
> +  else if (strcmp (symname, "tst_audit27_func_double") == 0)
> +    {
> +      assert (regs->lr_vreg[0].d == FUNC_DOUBLE_ARG0);
> +      assert (regs->lr_vreg[1].d == FUNC_DOUBLE_ARG1);
> +      assert (regs->lr_vreg[2].d == FUNC_DOUBLE_ARG2);
> +      assert (regs->lr_vreg[3].d == FUNC_DOUBLE_ARG3);
> +      assert (regs->lr_vreg[4].d == FUNC_DOUBLE_ARG4);
> +      assert (regs->lr_vreg[5].d == FUNC_DOUBLE_ARG5);
> +      assert (regs->lr_vreg[6].d == FUNC_DOUBLE_ARG6);
> +      assert (regs->lr_vreg[7].d == FUNC_DOUBLE_ARG7);

OK.

> +    }
> +  else if (strcmp (symname, "tst_audit27_func_ldouble") == 0)
> +    {
> +      assert (regs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0);
> +      assert (regs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1);
> +      assert (regs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2);
> +      assert (regs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3);
> +      assert (regs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4);
> +      assert (regs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5);
> +      assert (regs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6);
> +      assert (regs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7);

OK.

> +    }
> +  else
> +    abort ();
> +
> +  assert (regs->lr_vpcs == 0);
> +
> +  /* Clobber the q registers on exit.  */
> +  uint8_t v = 0xff;
> +  asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0");
> +  asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v1");
> +  asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2");
> +  asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3");
> +  asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4");
> +  asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5");
> +  asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6");
> +  asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7");

OK.

> +
> +  *framesizep = 1024;
> +
> +  return sym->st_value;
> +}
> +
> +unsigned int
> +la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
> +                        uintptr_t *defcook,
> +			const struct La_aarch64_regs *inregs,
> +                        struct La_aarch64_retval *outregs,
> +			const char *symname)
> +{
> +  printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n",
> +	  symname, (long int) sym->st_value, ndx);
> +
> +  if (strcmp (symname, "tst_audit27_func_float") == 0)
> +    {
> +      assert (inregs->lr_vreg[0].s == FUNC_FLOAT_ARG0);
> +      assert (inregs->lr_vreg[1].s == FUNC_FLOAT_ARG1);
> +      assert (inregs->lr_vreg[2].s == FUNC_FLOAT_ARG2);
> +      assert (inregs->lr_vreg[3].s == FUNC_FLOAT_ARG3);
> +      assert (inregs->lr_vreg[4].s == FUNC_FLOAT_ARG4);
> +      assert (inregs->lr_vreg[5].s == FUNC_FLOAT_ARG5);
> +      assert (inregs->lr_vreg[6].s == FUNC_FLOAT_ARG6);
> +      assert (inregs->lr_vreg[7].s == FUNC_FLOAT_ARG7);
> +
> +      assert (outregs->lrv_vreg[0].s == FUNC_FLOAT_RET);
> +    }
> +  else if (strcmp (symname, "tst_audit27_func_double") == 0)
> +    {
> +      assert (inregs->lr_vreg[0].d == FUNC_DOUBLE_ARG0);
> +      assert (inregs->lr_vreg[1].d == FUNC_DOUBLE_ARG1);
> +      assert (inregs->lr_vreg[2].d == FUNC_DOUBLE_ARG2);
> +      assert (inregs->lr_vreg[3].d == FUNC_DOUBLE_ARG3);
> +      assert (inregs->lr_vreg[4].d == FUNC_DOUBLE_ARG4);
> +      assert (inregs->lr_vreg[5].d == FUNC_DOUBLE_ARG5);
> +      assert (inregs->lr_vreg[6].d == FUNC_DOUBLE_ARG6);
> +      assert (inregs->lr_vreg[7].d == FUNC_DOUBLE_ARG7);
> +
> +      assert (outregs->lrv_vreg[0].d == FUNC_DOUBLE_RET);
> +    }
> +  else if (strcmp (symname, "tst_audit27_func_ldouble") == 0)
> +    {
> +      assert (inregs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0);
> +      assert (inregs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1);
> +      assert (inregs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2);
> +      assert (inregs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3);
> +      assert (inregs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4);
> +      assert (inregs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5);
> +      assert (inregs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6);
> +      assert (inregs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7);
> +
> +      assert (outregs->lrv_vreg[0].q == FUNC_LDOUBLE_RET);
> +    }
> +  else
> +    abort ();
> +
> +  assert (inregs->lr_vpcs == 0);
> +  assert (outregs->lrv_vpcs == 0);
> +
> +  /* Clobber the q registers on exit.  */
> +  uint8_t v = 0xff;
> +  asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0");
> +  asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v1");
> +  asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2");
> +  asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3");
> +  asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4");
> +  asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5");
> +  asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6");
> +  asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7");

OK.

> +
> +  return 0;
> +}
> diff --git a/sysdeps/generic/dl-audit-check.h b/sysdeps/generic/dl-audit-check.h
> new file mode 100644
> index 0000000000..3ab7653286
> --- /dev/null
> +++ b/sysdeps/generic/dl-audit-check.h
> @@ -0,0 +1,23 @@
> +/* rtld-audit version check.  Generic version.
> +   Copyright (C) 2022 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/>.  */
> +
> +static inline bool
> +_dl_audit_check_version (unsigned int lav)
> +{
> +  return lav <= LAV_CURRENT;
> +}

OK. For non-aarch64 the older versions are compatible.

-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 0/4] Multiple rtld-audit fixes
  2022-01-25 18:36 [PATCH v12 0/4] Multiple rtld-audit fixes Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2022-01-25 18:37 ` [PATCH v12 4/4] elf: Fix runtime linker auditing on aarch64 (BZ #26643) Adhemerval Zanella
@ 2022-02-01  6:45 ` Carlos O'Donell
  2022-02-01  7:53   ` John Mellor-Crummey
  4 siblings, 1 reply; 18+ messages in thread
From: Carlos O'Donell @ 2022-02-01  6:45 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard

On 1/25/22 13:36, Adhemerval Zanella wrote:
> This patches fixes some of remaining issues brought by John
> Mellor-Crummey [1] while trying to use it along with the HPCToolkit.
> This should cover all the issues listed as 'Tier 1' [2] (the aarch64
> SVE requires additional work, so it is postpone to 2.36) and also
> most of the 'Tier2' issue (BZ#28096 inclusive) which prevents the use
> of some glibc function that uses TLS internally on the audit module.

These changes look good to me. I've reviewed all 4 patches and I don't have any
logical changes, just minor cleanups. Please post v13 and I'll ACK that for inclusion
in glibc 2.35.

> I have checked the patches on x86_64, i686, aarch64, armv7, powerpc64,
> powerpc64le, and powerpc.

I have tested on x86_64 and i686. Thanks for working on this. I would like to include
this in glibc 2.35. The only external public data change is the LAV_VERSION bump,
otherwise we can change the internal implementation at will. The LAV_VERSION bump
will mean pre-glibc-2.35 audit modules need to be recompiled.

Thank you for working through these issues for the users who presented their
requirements to the community.

I tested these changes in a Fedora Rawhide desktop environment to catch any potential
issues like the DTV gap reuse problem. I didn't see any problems and ran GNOME,
the full desktop, Firefox, and sandboxed content (youtube), all without problems.

I also tested the downgrade errors:
LD_AUDIT=./audit.so ./main 
      4124:	ERROR: audit interface './audit.so' requires version 2 (maximum supported version 1); ignored.

Which shows a new audit module trying to be loaded by an old glibc.

The test passes with your changes, but segfaults without them.
 
> [1] https://sourceware.org/pipermail/libc-alpha/2021-June/127636.html
> [2] https://docs.google.com/document/d/1dVaDBdzySecxQqD6hLLzDrEF18M1UtjDna9gL5BWWI0/edit#
> [3] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/ld-audit-fixes
> 
> Changes from v11:
>   - Fixed tst-audit23.
> 
> Changes from v10:
>   - Removed l_auditing usage on initial-exec TLS access fix.
>   - Fixed aarch64 comments about the _dl_runtime_profile stack layout.
>   - Added some more argumet checking on some tests.
>   - Fixed copyright years.
> 
> Changes from v9:
>   - Fixed aarch64 comments about the _dl_runtime_profile stack layout.
>   - Rebased against master.
> 
> Changes from v8:
>   - Improved la_activity test coverage.
>   - Fixed BZ#28096 regression.
> 
> Changes from v7:
>   - Added la_activity tests during application exit.
>   - Refactor _dl_allocate_tls_init to not initialize static TLS.
>   - Changed sotruss to warn instead of error for bind-now.
>   - Added NEWS and changed commit message for aarch64.
> 
> Changes from v6:
>   - Dropped SVE, main application on main_map l_name, and Run
>     constructors if executable has a soname of a dependency patches.
>   - Bumped LAV_VERSION to 2 on la_symbind bind-now support.
>   - Added extension pointer on aarch64 fix.
>   - Moved the refactor patch at the start of the set.
>   - Changed _dl_audit_objsearch interface.
> 
> Changes from v5:
>   - Fixed build with --enable-profiling=yes.
>   - Moved la_activity (LA_ACT_ADD) *after* _dl_add_to_namespace_list()
>     for BZ#28062 fix.
>   - Fixed powerpc64 ELFv1 OPD toc setup for bind-now.
>   - Fixed testsuite issues for ia64.
>   - Removed LA_SYMB_BINDNOW now that LA_SYMB_NOPLTENTER and
>     LA_SYMB_NOPLTEXIT is passed for bind-now.
> 
> Changes from v4:
>   - Added a fix for constructors if executable has a soname of a
>     dependency
>   - Rebased against master.
> 
> Changes from v3
>   - Added a aarch64 SVE RFC patch.
>   - Fixed an issue with bind-now fix on powerpc64 ELFv1.
>   - Rebased against master.
> 
> Changes from v2
>   - Refactored rtld-audit code to move common come to dl-audit.c.
>   - Issue audit la_objopen() for vDSO.
>   - Isseu la_activity during application exit.
>   - Issue la_symbind() for bind-now (BZ #23734).
>   - Fix runtime linker auditing on aarch64 (BZ #26643)
> 
> Changes from v1
>   - Fixed -fstack-protector-all tst-auditmod17.
>   - Simplify the _dl_call_libc_early_init call the 'Fix audit
>     regression' patch.
>   - Remove symbind check fr BZ#15333.
>   - Added the BZ#28096 fix.
> 
> --
> 
> Adhemerval Zanella (3):
>   elf: Add la_activity during application exit
>   elf: Fix initial-exec TLS access on audit modules (BZ #28096)
>   elf: Issue la_symbind for bind-now (BZ #23734)
> 
> Ben Woodard (1):
>   elf: Fix runtime linker auditing on aarch64 (BZ #26643)
> 
>  NEWS                             |   8 ++
>  bits/link_lavcurrent.h           |   2 +-
>  elf/Makefile                     | 104 +++++++++++++-
>  elf/dl-audit.c                   |  58 +++++---
>  elf/dl-fini.c                    |   8 ++
>  elf/dl-tls.c                     |  13 +-
>  elf/do-rel.h                     |  57 ++++++--
>  elf/rtld.c                       |   5 +-
>  elf/sotruss-lib.c                |   7 +
>  elf/tst-audit21.c                |  42 ++++++
>  elf/tst-audit23.c                | 239 +++++++++++++++++++++++++++++++
>  elf/tst-audit23mod.c             |  23 +++
>  elf/tst-audit24a.c               |  36 +++++
>  elf/tst-audit24amod1.c           |  31 ++++
>  elf/tst-audit24amod2.c           |  25 ++++
>  elf/tst-audit24b.c               |  37 +++++
>  elf/tst-audit24bmod1.c           |  31 ++++
>  elf/tst-audit24bmod2.c           |  23 +++
>  elf/tst-audit24c.c               |   2 +
>  elf/tst-audit24d.c               |  36 +++++
>  elf/tst-audit24dmod1.c           |  33 +++++
>  elf/tst-audit24dmod2.c           |  28 ++++
>  elf/tst-audit24dmod3.c           |  31 ++++
>  elf/tst-audit24dmod4.c           |  25 ++++
>  elf/tst-audit25a.c               | 129 +++++++++++++++++
>  elf/tst-audit25b.c               | 128 +++++++++++++++++
>  elf/tst-audit25mod1.c            |  30 ++++
>  elf/tst-audit25mod2.c            |  30 ++++
>  elf/tst-audit25mod3.c            |  22 +++
>  elf/tst-audit25mod4.c            |  22 +++
>  elf/tst-auditmod21a.c            |  80 +++++++++++
>  elf/tst-auditmod21b.c            |  22 +++
>  elf/tst-auditmod23.c             |  74 ++++++++++
>  elf/tst-auditmod24.h             |  29 ++++
>  elf/tst-auditmod24a.c            | 114 +++++++++++++++
>  elf/tst-auditmod24b.c            | 104 ++++++++++++++
>  elf/tst-auditmod24c.c            |   3 +
>  elf/tst-auditmod24d.c            | 120 ++++++++++++++++
>  elf/tst-auditmod25.c             |  79 ++++++++++
>  nptl/allocatestack.c             |   2 +-
>  sysdeps/aarch64/Makefile         |  20 +++
>  sysdeps/aarch64/bits/link.h      |  26 ++--
>  sysdeps/aarch64/dl-audit-check.h |  28 ++++
>  sysdeps/aarch64/dl-link.sym      |   6 +-
>  sysdeps/aarch64/dl-trampoline.S  |  81 +++++++----
>  sysdeps/aarch64/tst-audit26.c    |  37 +++++
>  sysdeps/aarch64/tst-audit26mod.c |  33 +++++
>  sysdeps/aarch64/tst-audit26mod.h |  50 +++++++
>  sysdeps/aarch64/tst-audit27.c    |  64 +++++++++
>  sysdeps/aarch64/tst-audit27mod.c |  95 ++++++++++++
>  sysdeps/aarch64/tst-audit27mod.h |  67 +++++++++
>  sysdeps/aarch64/tst-auditmod26.c | 103 +++++++++++++
>  sysdeps/aarch64/tst-auditmod27.c | 180 +++++++++++++++++++++++
>  sysdeps/generic/dl-audit-check.h |  23 +++
>  sysdeps/generic/dl-lookupcfg.h   |   3 +
>  sysdeps/generic/ldsodefs.h       |   7 +-
>  sysdeps/hppa/dl-lookupcfg.h      |   3 +
>  sysdeps/ia64/dl-lookupcfg.h      |   3 +
>  sysdeps/powerpc/dl-lookupcfg.h   |  39 +++++
>  59 files changed, 2674 insertions(+), 86 deletions(-)
>  create mode 100644 elf/tst-audit21.c
>  create mode 100644 elf/tst-audit23.c
>  create mode 100644 elf/tst-audit23mod.c
>  create mode 100644 elf/tst-audit24a.c
>  create mode 100644 elf/tst-audit24amod1.c
>  create mode 100644 elf/tst-audit24amod2.c
>  create mode 100644 elf/tst-audit24b.c
>  create mode 100644 elf/tst-audit24bmod1.c
>  create mode 100644 elf/tst-audit24bmod2.c
>  create mode 100644 elf/tst-audit24c.c
>  create mode 100644 elf/tst-audit24d.c
>  create mode 100644 elf/tst-audit24dmod1.c
>  create mode 100644 elf/tst-audit24dmod2.c
>  create mode 100644 elf/tst-audit24dmod3.c
>  create mode 100644 elf/tst-audit24dmod4.c
>  create mode 100644 elf/tst-audit25a.c
>  create mode 100644 elf/tst-audit25b.c
>  create mode 100644 elf/tst-audit25mod1.c
>  create mode 100644 elf/tst-audit25mod2.c
>  create mode 100644 elf/tst-audit25mod3.c
>  create mode 100644 elf/tst-audit25mod4.c
>  create mode 100644 elf/tst-auditmod21a.c
>  create mode 100644 elf/tst-auditmod21b.c
>  create mode 100644 elf/tst-auditmod23.c
>  create mode 100644 elf/tst-auditmod24.h
>  create mode 100644 elf/tst-auditmod24a.c
>  create mode 100644 elf/tst-auditmod24b.c
>  create mode 100644 elf/tst-auditmod24c.c
>  create mode 100644 elf/tst-auditmod24d.c
>  create mode 100644 elf/tst-auditmod25.c
>  create mode 100644 sysdeps/aarch64/dl-audit-check.h
>  create mode 100644 sysdeps/aarch64/tst-audit26.c
>  create mode 100644 sysdeps/aarch64/tst-audit26mod.c
>  create mode 100644 sysdeps/aarch64/tst-audit26mod.h
>  create mode 100644 sysdeps/aarch64/tst-audit27.c
>  create mode 100644 sysdeps/aarch64/tst-audit27mod.c
>  create mode 100644 sysdeps/aarch64/tst-audit27mod.h
>  create mode 100644 sysdeps/aarch64/tst-auditmod26.c
>  create mode 100644 sysdeps/aarch64/tst-auditmod27.c
>  create mode 100644 sysdeps/generic/dl-audit-check.h
>  create mode 100644 sysdeps/powerpc/dl-lookupcfg.h
> 


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 0/4] Multiple rtld-audit fixes
  2022-02-01  6:45 ` [PATCH v12 0/4] Multiple rtld-audit fixes Carlos O'Donell
@ 2022-02-01  7:53   ` John Mellor-Crummey
  0 siblings, 0 replies; 18+ messages in thread
From: John Mellor-Crummey @ 2022-02-01  7:53 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: Adhemerval Zanella, libc-alpha, jma14, Ben Woodard

Thanks to Adhemerval, Florian, Szabolcs, and Carlos for all of the work it took to develop, test, and land these changes. My team really appreciates it! 

These fixes will provide the firm foundation we need for reliable tools.

John Mellor-Crummey

(sent from my phone)

> On Feb 1, 2022, at 12:45 AM, Carlos O'Donell <carlos@redhat.com> wrote:
> 
> On 1/25/22 13:36, Adhemerval Zanella wrote:
>> This patches fixes some of remaining issues brought by John
>> Mellor-Crummey [1] while trying to use it along with the HPCToolkit.
>> This should cover all the issues listed as 'Tier 1' [2] (the aarch64
>> SVE requires additional work, so it is postpone to 2.36) and also
>> most of the 'Tier2' issue (BZ#28096 inclusive) which prevents the use
>> of some glibc function that uses TLS internally on the audit module.
> 
> These changes look good to me. I've reviewed all 4 patches and I don't have any
> logical changes, just minor cleanups. Please post v13 and I'll ACK that for inclusion
> in glibc 2.35.
> 
>> I have checked the patches on x86_64, i686, aarch64, armv7, powerpc64,
>> powerpc64le, and powerpc.
> 
> I have tested on x86_64 and i686. Thanks for working on this. I would like to include
> this in glibc 2.35. The only external public data change is the LAV_VERSION bump,
> otherwise we can change the internal implementation at will. The LAV_VERSION bump
> will mean pre-glibc-2.35 audit modules need to be recompiled.
> 
> Thank you for working through these issues for the users who presented their
> requirements to the community.
> 
> I tested these changes in a Fedora Rawhide desktop environment to catch any potential
> issues like the DTV gap reuse problem. I didn't see any problems and ran GNOME,
> the full desktop, Firefox, and sandboxed content (youtube), all without problems.
> 
> I also tested the downgrade errors:
> LD_AUDIT=./audit.so ./main 
>      4124:    ERROR: audit interface './audit.so' requires version 2 (maximum supported version 1); ignored.
> 
> Which shows a new audit module trying to be loaded by an old glibc.
> 
> The test passes with your changes, but segfaults without them.
> 
>> [1] https://sourceware.org/pipermail/libc-alpha/2021-June/127636.html
>> [2] https://docs.google.com/document/d/1dVaDBdzySecxQqD6hLLzDrEF18M1UtjDna9gL5BWWI0/edit#
>> [3] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/ld-audit-fixes
>> 
>> Changes from v11:
>>  - Fixed tst-audit23.
>> 
>> Changes from v10:
>>  - Removed l_auditing usage on initial-exec TLS access fix.
>>  - Fixed aarch64 comments about the _dl_runtime_profile stack layout.
>>  - Added some more argumet checking on some tests.
>>  - Fixed copyright years.
>> 
>> Changes from v9:
>>  - Fixed aarch64 comments about the _dl_runtime_profile stack layout.
>>  - Rebased against master.
>> 
>> Changes from v8:
>>  - Improved la_activity test coverage.
>>  - Fixed BZ#28096 regression.
>> 
>> Changes from v7:
>>  - Added la_activity tests during application exit.
>>  - Refactor _dl_allocate_tls_init to not initialize static TLS.
>>  - Changed sotruss to warn instead of error for bind-now.
>>  - Added NEWS and changed commit message for aarch64.
>> 
>> Changes from v6:
>>  - Dropped SVE, main application on main_map l_name, and Run
>>    constructors if executable has a soname of a dependency patches.
>>  - Bumped LAV_VERSION to 2 on la_symbind bind-now support.
>>  - Added extension pointer on aarch64 fix.
>>  - Moved the refactor patch at the start of the set.
>>  - Changed _dl_audit_objsearch interface.
>> 
>> Changes from v5:
>>  - Fixed build with --enable-profiling=yes.
>>  - Moved la_activity (LA_ACT_ADD) *after* _dl_add_to_namespace_list()
>>    for BZ#28062 fix.
>>  - Fixed powerpc64 ELFv1 OPD toc setup for bind-now.
>>  - Fixed testsuite issues for ia64.
>>  - Removed LA_SYMB_BINDNOW now that LA_SYMB_NOPLTENTER and
>>    LA_SYMB_NOPLTEXIT is passed for bind-now.
>> 
>> Changes from v4:
>>  - Added a fix for constructors if executable has a soname of a
>>    dependency
>>  - Rebased against master.
>> 
>> Changes from v3
>>  - Added a aarch64 SVE RFC patch.
>>  - Fixed an issue with bind-now fix on powerpc64 ELFv1.
>>  - Rebased against master.
>> 
>> Changes from v2
>>  - Refactored rtld-audit code to move common come to dl-audit.c.
>>  - Issue audit la_objopen() for vDSO.
>>  - Isseu la_activity during application exit.
>>  - Issue la_symbind() for bind-now (BZ #23734).
>>  - Fix runtime linker auditing on aarch64 (BZ #26643)
>> 
>> Changes from v1
>>  - Fixed -fstack-protector-all tst-auditmod17.
>>  - Simplify the _dl_call_libc_early_init call the 'Fix audit
>>    regression' patch.
>>  - Remove symbind check fr BZ#15333.
>>  - Added the BZ#28096 fix.
>> 
>> --
>> 
>> Adhemerval Zanella (3):
>>  elf: Add la_activity during application exit
>>  elf: Fix initial-exec TLS access on audit modules (BZ #28096)
>>  elf: Issue la_symbind for bind-now (BZ #23734)
>> 
>> Ben Woodard (1):
>>  elf: Fix runtime linker auditing on aarch64 (BZ #26643)
>> 
>> NEWS                             |   8 ++
>> bits/link_lavcurrent.h           |   2 +-
>> elf/Makefile                     | 104 +++++++++++++-
>> elf/dl-audit.c                   |  58 +++++---
>> elf/dl-fini.c                    |   8 ++
>> elf/dl-tls.c                     |  13 +-
>> elf/do-rel.h                     |  57 ++++++--
>> elf/rtld.c                       |   5 +-
>> elf/sotruss-lib.c                |   7 +
>> elf/tst-audit21.c                |  42 ++++++
>> elf/tst-audit23.c                | 239 +++++++++++++++++++++++++++++++
>> elf/tst-audit23mod.c             |  23 +++
>> elf/tst-audit24a.c               |  36 +++++
>> elf/tst-audit24amod1.c           |  31 ++++
>> elf/tst-audit24amod2.c           |  25 ++++
>> elf/tst-audit24b.c               |  37 +++++
>> elf/tst-audit24bmod1.c           |  31 ++++
>> elf/tst-audit24bmod2.c           |  23 +++
>> elf/tst-audit24c.c               |   2 +
>> elf/tst-audit24d.c               |  36 +++++
>> elf/tst-audit24dmod1.c           |  33 +++++
>> elf/tst-audit24dmod2.c           |  28 ++++
>> elf/tst-audit24dmod3.c           |  31 ++++
>> elf/tst-audit24dmod4.c           |  25 ++++
>> elf/tst-audit25a.c               | 129 +++++++++++++++++
>> elf/tst-audit25b.c               | 128 +++++++++++++++++
>> elf/tst-audit25mod1.c            |  30 ++++
>> elf/tst-audit25mod2.c            |  30 ++++
>> elf/tst-audit25mod3.c            |  22 +++
>> elf/tst-audit25mod4.c            |  22 +++
>> elf/tst-auditmod21a.c            |  80 +++++++++++
>> elf/tst-auditmod21b.c            |  22 +++
>> elf/tst-auditmod23.c             |  74 ++++++++++
>> elf/tst-auditmod24.h             |  29 ++++
>> elf/tst-auditmod24a.c            | 114 +++++++++++++++
>> elf/tst-auditmod24b.c            | 104 ++++++++++++++
>> elf/tst-auditmod24c.c            |   3 +
>> elf/tst-auditmod24d.c            | 120 ++++++++++++++++
>> elf/tst-auditmod25.c             |  79 ++++++++++
>> nptl/allocatestack.c             |   2 +-
>> sysdeps/aarch64/Makefile         |  20 +++
>> sysdeps/aarch64/bits/link.h      |  26 ++--
>> sysdeps/aarch64/dl-audit-check.h |  28 ++++
>> sysdeps/aarch64/dl-link.sym      |   6 +-
>> sysdeps/aarch64/dl-trampoline.S  |  81 +++++++----
>> sysdeps/aarch64/tst-audit26.c    |  37 +++++
>> sysdeps/aarch64/tst-audit26mod.c |  33 +++++
>> sysdeps/aarch64/tst-audit26mod.h |  50 +++++++
>> sysdeps/aarch64/tst-audit27.c    |  64 +++++++++
>> sysdeps/aarch64/tst-audit27mod.c |  95 ++++++++++++
>> sysdeps/aarch64/tst-audit27mod.h |  67 +++++++++
>> sysdeps/aarch64/tst-auditmod26.c | 103 +++++++++++++
>> sysdeps/aarch64/tst-auditmod27.c | 180 +++++++++++++++++++++++
>> sysdeps/generic/dl-audit-check.h |  23 +++
>> sysdeps/generic/dl-lookupcfg.h   |   3 +
>> sysdeps/generic/ldsodefs.h       |   7 +-
>> sysdeps/hppa/dl-lookupcfg.h      |   3 +
>> sysdeps/ia64/dl-lookupcfg.h      |   3 +
>> sysdeps/powerpc/dl-lookupcfg.h   |  39 +++++
>> 59 files changed, 2674 insertions(+), 86 deletions(-)
>> create mode 100644 elf/tst-audit21.c
>> create mode 100644 elf/tst-audit23.c
>> create mode 100644 elf/tst-audit23mod.c
>> create mode 100644 elf/tst-audit24a.c
>> create mode 100644 elf/tst-audit24amod1.c
>> create mode 100644 elf/tst-audit24amod2.c
>> create mode 100644 elf/tst-audit24b.c
>> create mode 100644 elf/tst-audit24bmod1.c
>> create mode 100644 elf/tst-audit24bmod2.c
>> create mode 100644 elf/tst-audit24c.c
>> create mode 100644 elf/tst-audit24d.c
>> create mode 100644 elf/tst-audit24dmod1.c
>> create mode 100644 elf/tst-audit24dmod2.c
>> create mode 100644 elf/tst-audit24dmod3.c
>> create mode 100644 elf/tst-audit24dmod4.c
>> create mode 100644 elf/tst-audit25a.c
>> create mode 100644 elf/tst-audit25b.c
>> create mode 100644 elf/tst-audit25mod1.c
>> create mode 100644 elf/tst-audit25mod2.c
>> create mode 100644 elf/tst-audit25mod3.c
>> create mode 100644 elf/tst-audit25mod4.c
>> create mode 100644 elf/tst-auditmod21a.c
>> create mode 100644 elf/tst-auditmod21b.c
>> create mode 100644 elf/tst-auditmod23.c
>> create mode 100644 elf/tst-auditmod24.h
>> create mode 100644 elf/tst-auditmod24a.c
>> create mode 100644 elf/tst-auditmod24b.c
>> create mode 100644 elf/tst-auditmod24c.c
>> create mode 100644 elf/tst-auditmod24d.c
>> create mode 100644 elf/tst-auditmod25.c
>> create mode 100644 sysdeps/aarch64/dl-audit-check.h
>> create mode 100644 sysdeps/aarch64/tst-audit26.c
>> create mode 100644 sysdeps/aarch64/tst-audit26mod.c
>> create mode 100644 sysdeps/aarch64/tst-audit26mod.h
>> create mode 100644 sysdeps/aarch64/tst-audit27.c
>> create mode 100644 sysdeps/aarch64/tst-audit27mod.c
>> create mode 100644 sysdeps/aarch64/tst-audit27mod.h
>> create mode 100644 sysdeps/aarch64/tst-auditmod26.c
>> create mode 100644 sysdeps/aarch64/tst-auditmod27.c
>> create mode 100644 sysdeps/generic/dl-audit-check.h
>> create mode 100644 sysdeps/powerpc/dl-lookupcfg.h
>> 
> 
> 
> -- 
> Cheers,
> Carlos.
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 1/4] elf: Add la_activity during application exit
  2022-02-01  4:21   ` Carlos O'Donell
@ 2022-02-01 13:30     ` Adhemerval Zanella
  0 siblings, 0 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2022-02-01 13:30 UTC (permalink / raw)
  To: Carlos O'Donell, libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard



On 01/02/2022 01:21, Carlos O'Donell wrote:
> On 1/25/22 13:36, Adhemerval Zanella wrote:
>> diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
>> new file mode 100644
>> index 0000000000..3eea322051
>> --- /dev/null
>> +++ b/elf/tst-audit23.c
>> @@ -0,0 +1,239 @@
>> +/* Check DT_AUDIT la_objopen and la_objclose for all objects.
> 
> This does not check DT_AUDIT, which is set only by the static linker for --audit?
> 
> Suggest:
> Check for expected la_objopen and la_objeclose for all objects.
> 

Ack.

>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <array_length.h>
>> +#include <errno.h>
>> +#include <getopt.h>
>> +#include <link.h>
>> +#include <limits.h>
>> +#include <inttypes.h>
>> +#include <gnu/lib-names.h>
>> +#include <string.h>
>> +#include <stdlib.h>
>> +#include <support/capture_subprocess.h>
>> +#include <support/check.h>
>> +#include <support/xstdio.h>
>> +#include <support/xdlfcn.h>
>> +#include <support/support.h>
>> +
>> +static int restart;
>> +#define CMDLINE_OPTIONS \
>> +  { "restart", no_argument, &restart, 1 },
>> +
>> +static int
>> +handle_restart (void)
>> +{
>> +  xdlopen ("tst-audit23mod.so", RTLD_NOW);
>> +  xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
>> +
>> +  return 0;
>> +}
>> +
>> +static inline bool
>> +startswith (const char *str, const char *pre)
>> +{
>> +  size_t lenpre = strlen (pre);
>> +  size_t lenstr = strlen (str);
>> +  return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
>> +}
>> +
>> +static inline bool
>> +is_vdso (const char *str)
>> +{
>> +  return startswith (str, "linux-gate")
>> +	 || startswith (str, "linux-vdso");
>> +}
>> +
>> +static int
>> +do_test (int argc, char *argv[])
>> +{
>> +  /* We must have either:
>> +     - One our fource parameters left if called initially:
> 
> s/One our fource/One or four/g.
> 

Ack.

>> +       + path to ld.so         optional
>> +       + "--library-path"      optional
>> +       + the library path      optional
>> +       + the application name  */
>> +  if (restart)
>> +    return handle_restart ();
>> +
>> +  char *spargv[9];
>> +  int i = 0;
>> +  for (; i < argc - 1; i++)
>> +    spargv[i] = argv[i + 1];
>> +  spargv[i++] = (char *) "--direct";
>> +  spargv[i++] = (char *) "--restart";
>> +  spargv[i] = NULL;
>> +  TEST_VERIFY_EXIT (i < array_length (spargv));
>> +
> 
> OK. Prepare to re-run ourselves with auditor.
> 
>> +  setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
>> +  struct support_capture_subprocess result
>> +    = support_capture_subprogram (spargv[0], spargv);
>> +  support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
>> +
>> +  /* The expected la_objopen/la_objclose:
>> +     1. executable
>> +     2. loader
>> +     3. libc.so
>> +     4. tst-audit23mod.so
>> +     5. libc.so (LM_ID_NEWLM).
>> +     6. vdso (optional and ignored).  */
>> +  enum { max_objs = 6 };
>> +  struct la_obj_t
>> +  {
>> +    char *lname;
>> +    uintptr_t laddr;
>> +    Lmid_t lmid;
>> +    bool closed;
>> +  } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
>> +  size_t nobjs = 0;
>> +
>> +  /* The expected namespaces are one for the audit module, one for the
>> +     application, and another for the dlmopen on handle_restart.  */
>> +  enum { max_ns = 3 };
>> +  uintptr_t acts[max_ns] = { 0 };
>> +  size_t nacts = 0;
>> +  int last_act = -1;
>> +  uintptr_t last_act_cookie = -1;
>> +  bool seen_first_objclose = false;
>> +
>> +  FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
>> +  TEST_VERIFY (out != NULL);
>> +  char *buffer = NULL;
>> +  size_t buffer_length = 0;
>> +  while (xgetline (&buffer, &buffer_length, out))
>> +    {
>> +      if (startswith (buffer, "la_activity: "))
>> +	{
>> +	  uintptr_t cookie;
>> +	  int this_act;
>> +	  int r = sscanf (buffer, "la_activity: %d %"SCNxPTR"", &this_act,
>> +			  &cookie);
>> +	  TEST_COMPARE (r, 2);
>> +
>> +	  /* The cookie identifies the object at the head of the link map,
>> +	     so we only add a new namespace if it changes from previous
> 
> s/from/from the/g
> 

Ack.

>> +	     one.  This work since dlmopen is the last in the test body.  */
> 
> s/work/works/g

Ack.

> 
>> +	  if (cookie != last_act_cookie && last_act_cookie != -1)
>> +	    TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
>> +
>> +	  if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
>> +	    {
>> +	      acts[nacts++] = cookie;
>> +	      last_act_cookie = cookie;
>> +	    }
>> +	  /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
>> +	     at program termination (if the tests adds a dlclose or a library
>> +	     with extra dependencies this require to be adapted).  */
> 
> s/require/will need/g

Ack.

> 
> Florian's fix to make dlclose order consistent will make this consistent too!
> 
>> +	  else if (this_act == LA_ACT_DELETE)
>> +	    {
>> +	      last_act_cookie = acts[--nacts];
>> +	      TEST_COMPARE (acts[nacts], cookie);
>> +	      acts[nacts] = 0;
>> +	    }
>> +	  else if (this_act == LA_ACT_CONSISTENT)
>> +	    {
>> +	      TEST_COMPARE (cookie, last_act_cookie);
>> +
>> +	      /* LA_ACT_DELETE must always be followed by an la_objclose.  */
>> +	      if (last_act == LA_ACT_DELETE)
>> +		TEST_COMPARE (seen_first_objclose, true);
>> +	      else
>> +		TEST_COMPARE (last_act, LA_ACT_ADD);
>> +	    }
>> +
>> +	  last_act = this_act;
>> +	  seen_first_objclose = false;
>> +	}
>> +      else if (startswith (buffer, "la_objopen: "))
>> +	{
>> +	  char *lname;
>> +	  uintptr_t laddr;
>> +	  Lmid_t lmid;
>> +	  uintptr_t cookie;
>> +	  int r = sscanf (buffer, "la_objopen: %"SCNxPTR"  %ms %"SCNxPTR" %ld",
>> +			  &cookie, &lname, &laddr, &lmid);
>> +	  TEST_COMPARE (r, 4);
>> +
>> +	  /* la_objclose is not triggered by vDSO because glibc does not
>> +	     unload it.  */
> 
> OK.
> 
>> +	  if (is_vdso (lname))
>> +	    continue;
>> +	  if (nobjs == max_objs)
>> +	    FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
>> +			lname, laddr, lmid);
>> +	  objs[nobjs].lname = lname;
>> +	  objs[nobjs].laddr = laddr;
>> +	  objs[nobjs].lmid = lmid;
>> +	  objs[nobjs].closed = false;
>> +	  nobjs++;
>> +
>> +	  /* This indirectly checks that la_objopen always come before
> 
> s/come/comes/g

Ack.

> 
>> +	     la_objclose btween la_activity calls.  */
>> +	  seen_first_objclose = false;
>> +	}
>> +      else if (startswith (buffer, "la_objclose: "))
>> +	{
>> +	  char *lname;
>> +	  uintptr_t laddr;
>> +	  Lmid_t lmid;
>> +	  uintptr_t cookie;
>> +	  int r = sscanf (buffer, "la_objclose: %"SCNxPTR" %ms %"SCNxPTR" %ld",
>> +			  &cookie, &lname, &laddr, &lmid);
>> +	  TEST_COMPARE (r, 4);
>> +
>> +	  for (size_t i = 0; i < nobjs; i++)
>> +	    {
>> +	      if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
>> +		{
>> +		  TEST_COMPARE (objs[i].closed, false);
>> +		  objs[i].closed = true;
>> +		  break;
>> +		}
>> +	    }
>> +
>> +	  /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
>> +	     the closed object's namespace.  */
> 
> OK. Agreed.
> 
>> +	  TEST_COMPARE (last_act, LA_ACT_DELETE);
>> +	  if (!seen_first_objclose)
>> +	    {
>> +	      TEST_COMPARE (last_act_cookie, cookie);
>> +	      seen_first_objclose = true;
>> +	    }
>> +	}
>> +    }
>> +
>> +  for (size_t i = 0; i < nobjs; i++)
>> +    {
>> +      TEST_COMPARE (objs[i].closed, true);
>> +      free (objs[i].lname);
>> +    }
>> +
>> +  /* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
>> +     Since only one link map may be not-CONSISTENT at a time, this also
>> +     ensures la_activity(LA_ACT_CONSISTENT) is the last callback received
>> +     for every namespace.  */
>> +  TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
>> +
>> +  free (buffer);
>> +  xfclose (out);
>> +
>> +  return 0;
>> +}
>> +
>> +#define TEST_FUNCTION_ARGV do_test
>> +#include <support/test-driver.c>
>> diff --git a/elf/tst-audit23mod.c b/elf/tst-audit23mod.c
>> new file mode 100644
>> index 0000000000..9a116ff682
>> --- /dev/null
>> +++ b/elf/tst-audit23mod.c
>> @@ -0,0 +1,23 @@
>> +/* Extra modules for tst-audit23
> 
> s/modules/module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +int
>> +foo (void)
>> +{
>> +  return 0;
>> +}
> 
> OK.
> 
>> diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c
>> new file mode 100644
>> index 0000000000..42eccae11b
>> --- /dev/null
>> +++ b/elf/tst-auditmod23.c
>> @@ -0,0 +1,74 @@
>> +/* Audit modules loaded by tst-audit23.
> 
> s/modules/module/g.

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <link.h>
>> +#include <inttypes.h>
>> +#include <stdlib.h>
>> +#include <stdio.h>
>> +#include <string.h>
>> +#include <sys/auxv.h>
>> +
>> +unsigned int
>> +la_version (unsigned int version)
>> +{
>> +  return LAV_CURRENT;
>> +}
>> +
>> +struct map_desc_t
>> +{
>> +  char *lname;
>> +  uintptr_t laddr;
>> +  Lmid_t lmid;
>> +};
>> +
>> +void
>> +la_activity (uintptr_t *cookie, unsigned int flag)
>> +{
>> +  fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie);
>> +}
>> +
>> +unsigned int
>> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
>> +{
>> +  const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name;
>> +  fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
>> +	   (uintptr_t) cookie, l_name, map->l_addr, lmid);
>> +
>> +  struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t));
>> +  if (map_desc == NULL)
>> +    abort ();
>> +
>> +  map_desc->lname = strdup (l_name);
>> +  map_desc->laddr = map->l_addr;
>> +  map_desc->lmid = lmid;
>> +
>> +  *cookie = (uintptr_t) map_desc;
> 
> OK.
> 
>> +
>> +  return 0;
>> +}
>> +
>> +unsigned int
>> +la_objclose (uintptr_t *cookie)
>> +{
>> +  struct map_desc_t *map_desc = (struct map_desc_t *) *cookie;
>> +  fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
>> +	   (uintptr_t) cookie, map_desc->lname, map_desc->laddr,
>> +	   map_desc->lmid);
>> +
>> +  return 0;
>> +}
> 
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096)
  2022-02-01  5:29   ` Carlos O'Donell
@ 2022-02-01 13:35     ` Adhemerval Zanella
  0 siblings, 0 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2022-02-01 13:35 UTC (permalink / raw)
  To: Carlos O'Donell, libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard



On 01/02/2022 02:29, Carlos O'Donell wrote:
> On 1/25/22 13:36, Adhemerval Zanella wrote:
>> For audit modules and dependencies with initial-exec TLS, we can not
>> set the initial TLS image on default loader initialization because it
>> would already be set by the audit setup.  However, subsequent thread
>> creation would need to follow the default behaviour.
> 
> Correct, there is a circular dependency, we need the initial TLS image setup for
> the auditor before the loader does the setup.
> 
>> This patch fixes it by setting l_auditing link_map field not only
>> for the audit modules, but also for all its dependencies.  This is
>> used on _dl_allocate_tls_init to avoid the static TLS initialization
>> only at loading time.
> 
> s/only at loading/at load/g

Ack.

> 
>> Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
> 
> Tested on x86_64 and i686 and it looks good for glibc 2.35.
> 
> Please post v13 with fixes and I'll ACK that as release manager.
> 
> 
>> ---
>>  elf/Makefile               |  8 ++++
>>  elf/dl-tls.c               | 13 +++++--
>>  elf/rtld.c                 |  2 +-
>>  elf/tst-audit21.c          | 42 ++++++++++++++++++++
>>  elf/tst-auditmod21a.c      | 80 ++++++++++++++++++++++++++++++++++++++
>>  elf/tst-auditmod21b.c      | 22 +++++++++++
>>  nptl/allocatestack.c       |  2 +-
>>  sysdeps/generic/ldsodefs.h |  2 +-
>>  8 files changed, 165 insertions(+), 6 deletions(-)
>>  create mode 100644 elf/tst-audit21.c
>>  create mode 100644 elf/tst-auditmod21a.c
>>  create mode 100644 elf/tst-auditmod21b.c
>>
>> diff --git a/elf/Makefile b/elf/Makefile
>> index a3b4468593..7d01b71f6a 100644
>> --- a/elf/Makefile
>> +++ b/elf/Makefile
>> @@ -376,6 +376,7 @@ tests += \
>>    tst-audit18 \
>>    tst-audit19b \
>>    tst-audit20 \
>> +  tst-audit21 \
> 
> OK. Test.
> 
>>    tst-audit22 \
>>    tst-audit23 \
>>    tst-auditmany \
>> @@ -696,6 +697,8 @@ modules-names = \
>>    tst-auditmod19a \
>>    tst-auditmod19b \
>>    tst-auditmod20 \
>> +  tst-auditmod21a \
>> +  tst-auditmod21b \
> 
> OK. Two audit modules.
> 
>>    tst-auditmod22 \
>>    tst-auditmod23 \
>>    tst-auxvalmod \
>> @@ -2136,6 +2139,11 @@ tst-audit19b-ARGS = -- $(host-test-program-cmd)
>>  $(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
>>  tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
>>  
>> +$(objpfx)tst-audit21: $(shared-thread-library)
>> +$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so
>> +$(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so
> 
> OK. A deps B.
> 
>> +tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so
> 
> OK. New test is audited by A, which deps B.
> 
>> +
>>  $(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
>>  tst-audit22-ARGS = -- $(host-test-program-cmd)
>>  
>> diff --git a/elf/dl-tls.c b/elf/dl-tls.c
>> index 8ba70c9a9d..ccbe39660b 100644
>> --- a/elf/dl-tls.c
>> +++ b/elf/dl-tls.c
>> @@ -520,7 +520,7 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
>>  
>>  
> 
> This needs a comment explaining bool init_tls.
> 
> /* Allocate initial TLS.  RESULT should be a non-NULL pointer to storage
>    for the TLS space.  The DTV may be resized, and so this function may
>    call malloc to allocate that space.  The loader's GL(dl_load_tls_lock)
>    is taken when manipulating global TLS-related data in the laoder.

Ack.

> 
>>  void *
>> -_dl_allocate_tls_init (void *result)
>> +_dl_allocate_tls_init (void *result, bool init_tls)
> 
> OK. This is called by a reinitialization of re-used stacks. It is called
> by normal _dl_allocate_tls, which is called when a thread allocates a DTV.
> 
>>  {
>>    if (result == NULL)
>>      /* The memory allocation failed.  */
>> @@ -593,7 +593,14 @@ _dl_allocate_tls_init (void *result)
>>  	     some platforms use in static programs requires it.  */
>>  	  dtv[map->l_tls_modid].pointer.val = dest;
>>  
>> -	  /* Copy the initialization image and clear the BSS part.  */
>> +	  /* Copy the initialization image and clear the BSS part.  For
>> +	     audit modules or depedencies with initial-exec TLS, we can not
> 
> s/depedencies/dependencies/g

Ack.

> 
>> +	     set the initial TLS image on default loader initialization
>> +	     because it would already be set by the audit setup.  However,
>> +	     subsequent thread creation would need to follow the default
>> +	     behaviour.   */
>> +	  if (map->l_ns != LM_ID_BASE && !init_tls)
>> +	    continue;
> 
> OK. The tricky part here is that this works because GL(dl_tls_dtv_slotinfo_list)
> is a *GLOBAL* list that is irrespective of linker namespace. So when we come to setup
> the static TLS for the thread via rtld we will redo the already done setup for the libc
> in the non-main-namespace.

Yeap, that is the main issue indeed.

> 
>>  	  memset (__mempcpy (dest, map->l_tls_initimage,
>>  			     map->l_tls_initimage_size), '\0',
>>  		  map->l_tls_blocksize - map->l_tls_initimage_size);
>> @@ -620,7 +627,7 @@ _dl_allocate_tls (void *mem)
>>  {
>>    return _dl_allocate_tls_init (mem == NULL
>>  				? _dl_allocate_tls_storage ()
>> -				: allocate_dtv (mem));
>> +				: allocate_dtv (mem), true);
> 
> OK. Correct, when calling via _dl_allocate_tls we always want to initialize TLS.
> 
>>  }
>>  rtld_hidden_def (_dl_allocate_tls)
>>  
>> diff --git a/elf/rtld.c b/elf/rtld.c
>> index 8d233f77be..10436f7034 100644
>> --- a/elf/rtld.c
>> +++ b/elf/rtld.c
>> @@ -2462,7 +2462,7 @@ dl_main (const ElfW(Phdr) *phdr,
>>       into the main thread's TLS area, which we allocated above.
>>       Note: thread-local variables must only be accessed after completing
>>       the next step.  */
>> -  _dl_allocate_tls_init (tcbp);
>> +  _dl_allocate_tls_init (tcbp, false);
> 
> OK. When doing this step we have already potentially initialized everything
> via init_tls(naudit) earlier, but "false" is only useful if we are in the
> non-base namespace.
> 
>>  
>>    /* And finally install it for the main thread.  */
>>    if (! tls_init_tp_called)
>> diff --git a/elf/tst-audit21.c b/elf/tst-audit21.c
>> new file mode 100644
>> index 0000000000..41446a2107
>> --- /dev/null
>> +++ b/elf/tst-audit21.c
>> @@ -0,0 +1,42 @@
>> +/* Check DT_AUDIT with static TLS.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <ctype.h>
>> +#include <support/xthread.h>
>> +#include <support/check.h>
>> +
>> +static volatile __thread int out __attribute__ ((tls_model ("initial-exec")));
> 
> OK. out has size int.
> 
>> +
>> +static void *
>> +tf (void *arg)
>> +{
>> +  TEST_COMPARE (out, 0);
>> +  out = isspace (' ');
> 
> OK. Uses ctype data, which uses tls also.
> 
>> +  return NULL;
>> +}
>> +
>> +int main (int argc, char *argv[])
>> +{
>> +  TEST_COMPARE (out, 0);
>> +  out = isspace (' ');
>> +
>> +  pthread_t t = xpthread_create (NULL, tf, NULL);
> 
> OK. In the new thread look at the value.
> 
>> +  xpthread_join (t);
>> +
>> +  return 0;
>> +}
>> diff --git a/elf/tst-auditmod21a.c b/elf/tst-auditmod21a.c
>> new file mode 100644
>> index 0000000000..4c0f256969
>> --- /dev/null
>> +++ b/elf/tst-auditmod21a.c
>> @@ -0,0 +1,80 @@
>> +/* Check DT_AUDIT with static TLS.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <ctype.h>
>> +#include <stdlib.h>
>> +#include <link.h>
>> +
>> +#define tls_ie __attribute__ ((tls_model ("initial-exec")))
>> +
>> +__thread int tls_var0 tls_ie;
>> +__thread int tls_var1 tls_ie = 0x10;
> 
> OK. Two TLS IE mode vars one with a non-zero intializer.
> 
>> +
>> +/* Defined at tst-auditmod21b.so  */
>> +extern __thread int tls_var2;
>> +extern __thread int tls_var3;
>> +
>> +static volatile int out;
>> +
>> +static void
>> +call_libc (void)
>> +{
>> +  /* isspace access the initial-exec glibc TLS variables, which are
> 
> s/access/accesses/g

Ack.

> 
>> +     setup in glibc initialization.  */
>> +  out = isspace (' ');
>> +}
>> +
>> +unsigned int
>> +la_version (unsigned int v)
>> +{
> 
> OK. la_version is called to initialize this module, so it's after all the
> early tls initialization done by the loader.
> 
>> +  tls_var0 = 0x1;
>> +  if (tls_var1 != 0x10)
>> +    abort ();
>> +  tls_var1 = 0x20;
>> +
>> +  tls_var2 = 0x2;
>> +  if (tls_var3 != 0x20)
>> +    abort ();
>> +  tls_var3 = 0x40;
>> +
>> +  call_libc ();
>> +
>> +  return LAV_CURRENT;
>> +}
>> +
>> +unsigned int
>> +la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie)
>> +{
>> +  call_libc ();
>> +  *cookie = (uintptr_t) map;
>> +  return 0;
>> +}
>> +
>> +void
>> +la_activity (uintptr_t* cookie, unsigned int flag)
>> +{
> 
> OK. By the time we have activity our TLS will have been overwritten.
> 
>> +  if (tls_var0 != 0x1 || tls_var1 != 0x20)
>> +    abort ();
>> +  call_libc ();
>> +}
>> +
>> +void
>> +la_preinit (uintptr_t* cookie)
>> +{
>> +  call_libc ();
> 
> OK. Trigger libc tls usage after all DSOs are loaded but before main.
> 
>> +}
>> diff --git a/elf/tst-auditmod21b.c b/elf/tst-auditmod21b.c
>> new file mode 100644
>> index 0000000000..69705cf75a
>> --- /dev/null
>> +++ b/elf/tst-auditmod21b.c
>> @@ -0,0 +1,22 @@
>> +/* Check DT_AUDIT with static TLS.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#define tls_ie __attribute__ ((tls_model ("initial-exec")))
>> +
>> +__thread int tls_var2 tls_ie;
>> +__thread int tls_var3 tls_ie = 0x20;
> 
> OK.
> 
>> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
>> index 3fb085f9a1..34a33164ff 100644
>> --- a/nptl/allocatestack.c
>> +++ b/nptl/allocatestack.c
>> @@ -138,7 +138,7 @@ get_cached_stack (size_t *sizep, void **memp)
>>    memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
>>  
>>    /* Re-initialize the TLS.  */
>> -  _dl_allocate_tls_init (TLS_TPADJ (result));
>> +  _dl_allocate_tls_init (TLS_TPADJ (result), true);
> 
> OK. Yes, a thread needs to reinitialize this for the new stack.
> 
>>  
>>    return result;
>>  }
>> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
>> index f6b2b415a6..97061bdf9f 100644
>> --- a/sysdeps/generic/ldsodefs.h
>> +++ b/sysdeps/generic/ldsodefs.h
>> @@ -1282,7 +1282,7 @@ extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
>>  /* These are internal entry points to the two halves of _dl_allocate_tls,
>>     only used within rtld.c itself at startup time.  */
>>  extern void *_dl_allocate_tls_storage (void) attribute_hidden;
>> -extern void *_dl_allocate_tls_init (void *);
>> +extern void *_dl_allocate_tls_init (void *, bool);
> 
> OK.
> 
>>  rtld_hidden_proto (_dl_allocate_tls_init)
>>  
>>  /* Deallocate memory allocated with _dl_allocate_tls.  */
> 
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 3/4] elf: Issue la_symbind for bind-now (BZ #23734)
  2022-02-01  6:06   ` Carlos O'Donell
@ 2022-02-01 13:47     ` Adhemerval Zanella
  0 siblings, 0 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2022-02-01 13:47 UTC (permalink / raw)
  To: Carlos O'Donell, libc-alpha, jma14; +Cc: John Mellor-Crummey, Ben Woodard



On 01/02/2022 03:06, Carlos O'Donell wrote:
> On 1/25/22 13:36, Adhemerval Zanella wrote:
>> The audit symbind callback is not called for binaries built with
>> -Wl,-z,now or when LD_BIND_NOW=1 is used, nor the PLT tracking callbacks
>> (plt_enter and plt_exit) since this will would change the expected
> 
> s/will would/would/g

Ack.

> 
>> program semantic (where no PTL is expected) and would incur in
> 
> s/semantic/semantics/g
> s/PTL/PLT/g
> s/incur in/have/g
> 

Ack.

>> performance implications (such as for BZ#15533).
>>
>> LAV_CURRENT is also bumped to indicate the audit ABI change (where
>> la_symbind flags are set by the loader to indicate no possible PTL
> 
> s/PTL/PLT/g

Ack.

> 
>> trace).
>>
>> To handle powerpc64 ELFv1 function descriptor, _dl_audit_symbind
>> requires to know whether bind-now is used so the symbol value is
>> updated to function text segment instead of the OPD (for lazy binding
>> this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve).
>>
>> Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
>> powerpc64-linux-gnu.
> 
> Please post v13 and I'll ack that for glibc 2.35.
> 
>> ---
>>  NEWS                           |   4 +
>>  bits/link_lavcurrent.h         |   2 +-
>>  elf/Makefile                   |  89 ++++++++++++++++++++++-
>>  elf/dl-audit.c                 |  58 +++++++++------
>>  elf/do-rel.h                   |  57 +++++++++++----
>>  elf/sotruss-lib.c              |   7 ++
>>  elf/tst-audit24a.c             |  36 +++++++++
>>  elf/tst-audit24amod1.c         |  31 ++++++++
>>  elf/tst-audit24amod2.c         |  25 +++++++
>>  elf/tst-audit24b.c             |  37 ++++++++++
>>  elf/tst-audit24bmod1.c         |  31 ++++++++
>>  elf/tst-audit24bmod2.c         |  23 ++++++
>>  elf/tst-audit24c.c             |   2 +
>>  elf/tst-audit24d.c             |  36 +++++++++
>>  elf/tst-audit24dmod1.c         |  33 +++++++++
>>  elf/tst-audit24dmod2.c         |  28 +++++++
>>  elf/tst-audit24dmod3.c         |  31 ++++++++
>>  elf/tst-audit24dmod4.c         |  25 +++++++
>>  elf/tst-audit25a.c             | 129 +++++++++++++++++++++++++++++++++
>>  elf/tst-audit25b.c             | 128 ++++++++++++++++++++++++++++++++
>>  elf/tst-audit25mod1.c          |  30 ++++++++
>>  elf/tst-audit25mod2.c          |  30 ++++++++
>>  elf/tst-audit25mod3.c          |  22 ++++++
>>  elf/tst-audit25mod4.c          |  22 ++++++
>>  elf/tst-auditmod24.h           |  29 ++++++++
>>  elf/tst-auditmod24a.c          | 114 +++++++++++++++++++++++++++++
>>  elf/tst-auditmod24b.c          | 104 ++++++++++++++++++++++++++
>>  elf/tst-auditmod24c.c          |   3 +
>>  elf/tst-auditmod24d.c          | 120 ++++++++++++++++++++++++++++++
>>  elf/tst-auditmod25.c           |  79 ++++++++++++++++++++
>>  sysdeps/generic/dl-lookupcfg.h |   3 +
>>  sysdeps/generic/ldsodefs.h     |   5 +-
>>  sysdeps/hppa/dl-lookupcfg.h    |   3 +
>>  sysdeps/ia64/dl-lookupcfg.h    |   3 +
>>  sysdeps/powerpc/dl-lookupcfg.h |  39 ++++++++++
>>  35 files changed, 1379 insertions(+), 39 deletions(-)
>>  create mode 100644 elf/tst-audit24a.c
>>  create mode 100644 elf/tst-audit24amod1.c
>>  create mode 100644 elf/tst-audit24amod2.c
>>  create mode 100644 elf/tst-audit24b.c
>>  create mode 100644 elf/tst-audit24bmod1.c
>>  create mode 100644 elf/tst-audit24bmod2.c
>>  create mode 100644 elf/tst-audit24c.c
>>  create mode 100644 elf/tst-audit24d.c
>>  create mode 100644 elf/tst-audit24dmod1.c
>>  create mode 100644 elf/tst-audit24dmod2.c
>>  create mode 100644 elf/tst-audit24dmod3.c
>>  create mode 100644 elf/tst-audit24dmod4.c
>>  create mode 100644 elf/tst-audit25a.c
>>  create mode 100644 elf/tst-audit25b.c
>>  create mode 100644 elf/tst-audit25mod1.c
>>  create mode 100644 elf/tst-audit25mod2.c
>>  create mode 100644 elf/tst-audit25mod3.c
>>  create mode 100644 elf/tst-audit25mod4.c
>>  create mode 100644 elf/tst-auditmod24.h
>>  create mode 100644 elf/tst-auditmod24a.c
>>  create mode 100644 elf/tst-auditmod24b.c
>>  create mode 100644 elf/tst-auditmod24c.c
>>  create mode 100644 elf/tst-auditmod24d.c
>>  create mode 100644 elf/tst-auditmod25.c
>>  create mode 100644 sysdeps/powerpc/dl-lookupcfg.h
>>
>> diff --git a/NEWS b/NEWS
>> index a9f25d3225..c0f8932f84 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -158,6 +158,10 @@ Deprecated and removed features, and other changes affecting compatibility:
>>    been removed.  There are widely-deployed out-of-process alternatives for
>>    catching coredumps and backtraces.
>>  
>> +* The audit module interface version LAV_CURRENT is increased to enable
>> +  proper bind-now support.  The loader now advertises on the la_symbind
> 
> s/on/via/g

Ack.

> 
>> +  flags that PLT trace is not possible.
>> +
>>  Changes to build and runtime requirements:
>>  
>>    [Add changes to build and runtime requirements here]
>> diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h
>> index 7bfa4b9f4e..a852d41302 100644
>> --- a/bits/link_lavcurrent.h
>> +++ b/bits/link_lavcurrent.h
>> @@ -22,4 +22,4 @@
>>  #endif
>>  
>>  /* Version numbers for la_version handshake interface.  */
>> -#define LAV_CURRENT	1
>> +#define LAV_CURRENT	2
> 
> OK. New version.
> 
>> diff --git a/elf/Makefile b/elf/Makefile
>> index 7d01b71f6a..b9edcccb82 100644
>> --- a/elf/Makefile
>> +++ b/elf/Makefile
>> @@ -379,6 +379,12 @@ tests += \
>>    tst-audit21 \
>>    tst-audit22 \
>>    tst-audit23 \
>> +  tst-audit24a \
>> +  tst-audit24b \
>> +  tst-audit24c \
>> +  tst-audit24d \
>> +  tst-audit25a \
>> +  tst-audit25b \
> 
> OK. New tests.
> 
>>    tst-auditmany \
>>    tst-auxobj \
>>    tst-auxobj-dlopen \
>> @@ -676,6 +682,18 @@ modules-names = \
>>    tst-audit18mod \
>>    tst-audit19bmod \
>>    tst-audit23mod \
>> +  tst-audit24amod1 \
>> +  tst-audit24amod2 \
>> +  tst-audit24bmod1 \
>> +  tst-audit24bmod2 \
>> +  tst-audit24dmod1 \
>> +  tst-audit24dmod2 \
>> +  tst-audit24dmod3 \
>> +  tst-audit24dmod4 \
>> +  tst-audit25mod1 \
>> +  tst-audit25mod2 \
>> +  tst-audit25mod3 \
>> +  tst-audit25mod4 \
> 
> OK. New DSOs.
> 
>>    tst-auditlogmod-1 \
>>    tst-auditlogmod-2 \
>>    tst-auditlogmod-3 \
>> @@ -701,6 +719,11 @@ modules-names = \
>>    tst-auditmod21b \
>>    tst-auditmod22 \
>>    tst-auditmod23 \
>> +  tst-auditmod24a \
>> +  tst-auditmod24b \
>> +  tst-auditmod24c \
>> +  tst-auditmod24d \
>> +  tst-auditmod25 \
> 
> OK. New audit modules.
> 
>>    tst-auxvalmod \
>>    tst-big-note-lib \
>>    tst-deep1mod1 \
>> @@ -918,7 +941,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
>>  
>>  # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
>>  # rules.
>> -modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod
>> +modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
>> +			 tst-audit24bmod1 tst-audit24bmod2.so
> 
> OK. Build them differently.
> 
>>  
>>  tests += $(tests-static)
>>  
>> @@ -2151,6 +2175,69 @@ $(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
>>  			  $(objpfx)tst-audit23mod.so
>>  tst-audit23-ARGS = -- $(host-test-program-cmd)
>>  
>> +$(objpfx)tst-audit24a.out: $(objpfx)tst-auditmod24a.so
>> +$(objpfx)tst-audit24a: $(objpfx)tst-audit24amod1.so \
>> +		       $(objpfx)tst-audit24amod2.so
>> +tst-audit24a-ENV = LD_AUDIT=$(objpfx)tst-auditmod24a.so
>> +LDFLAGS-tst-audit24a = -Wl,-z,now
> 
> OK. Ensure immmediate binding.
> 
>> +
>> +$(objpfx)tst-audit24b.out: $(objpfx)tst-auditmod24b.so
>> +$(objpfx)tst-audit24b: $(objpfx)tst-audit24bmod1.so \
>> +		       $(objpfx)tst-audit24bmod2.so
>> +$(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so
>> +# The test check if a library without .gnu.version correctly calls the
> 
> s/check/checks/g

Ack.

> 
>> +# audit callbacks.  So it uses an explicit link rule to avoid linking
>> +# against libc.so.
>> +$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os
>> +	$(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \
>> +	  -Wl,-z,now
>> +	$(call after-link,$@.new)
>> +	mv -f $@.new $@
> 
> OK.
> 
>> +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1)
>> +$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os
>> +	$(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os
>> +	$(call after-link,$@.new)
>> +	mv -f $@.new $@
>> +CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2)
>> +tst-audit24b-ENV = LD_AUDIT=$(objpfx)tst-auditmod24b.so
>> +LDFLAGS-tst-audit24b = -Wl,-z,now
> 
> OK.
> 
>> +
>> +# Same as tst-audit24a, but tests LD_BIND_NOW
>> +$(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so
>> +$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \
>> +		       $(objpfx)tst-audit24amod2.so
>> +tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so
> 
> OK. Immediate binding via env var.
> 
>> +LDFLAGS-tst-audit24b = -Wl,-z,lazy
> 
> OK. Testing lazy binding.
> 
>> +
>> +$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so
>> +$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \
>> +		       $(objpfx)tst-audit24dmod2.so
>> +$(objpfx)tst-audit24dmod1.so: $(objpfx)tst-audit24dmod3.so
>> +LDFLAGS-tst-audit24dmod1.so = -Wl,-z,now
>> +$(objpfx)tst-audit24dmod2.so: $(objpfx)tst-audit24dmod4.so
>> +LDFLAGS-tst-audit24dmod2.so = -Wl,-z,lazy
>> +tst-audit24d-ENV = LD_AUDIT=$(objpfx)tst-auditmod24d.so
>> +LDFLAGS-tst-audit24d = -Wl,-z,lazy
>> +
>> +$(objpfx)tst-audit25a.out: $(objpfx)tst-auditmod25.so
>> +$(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \
>> +		       $(objpfx)tst-audit25mod2.so \
>> +		       $(objpfx)tst-audit25mod3.so \
>> +		       $(objpfx)tst-audit25mod4.so
>> +$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so
>> +LDFLAGS-tst-audit25mod1.so = -Wl,-z,now
>> +$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so
>> +LDFLAGS-tst-audit25mod2.so = -Wl,-z,lazy
>> +tst-audit25a-ARGS = -- $(host-test-program-cmd)
>> +
>> +$(objpfx)tst-audit25b.out: $(objpfx)tst-auditmod25.so
>> +$(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \
>> +		       $(objpfx)tst-audit25mod2.so \
>> +		       $(objpfx)tst-audit25mod3.so \
>> +		       $(objpfx)tst-audit25mod4.so
>> +LDFLAGS-tst-audit25b = -Wl,-z,now
>> +tst-audit25b-ARGS = -- $(host-test-program-cmd)
>> +
>>  # tst-sonamemove links against an older implementation of the library.
>>  LDFLAGS-tst-sonamemove-linkmod1.so = \
>>    -Wl,--version-script=tst-sonamemove-linkmod1.map \
>> diff --git a/elf/dl-audit.c b/elf/dl-audit.c
>> index 715de53272..794bfd45cd 100644
>> --- a/elf/dl-audit.c
>> +++ b/elf/dl-audit.c
>> @@ -178,16 +178,23 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>>  		   const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
>>  		   lookup_t result)
>>  {
>> -  reloc_result->bound = result;
>> -  /* Compute index of the symbol entry in the symbol table of the DSO with the
>> -     definition.  */
>> -  reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result,
>> -							  l_info[DT_SYMTAB]));
>> +  bool for_jmp_slot = reloc_result == NULL;
> 
> OK. Check if we have relocation result.
> 
>> +
>> +  /* Compute index of the symbol entry in the symbol table of the DSO
>> +     with the definition.  */
>> +  unsigned int boundndx = defsym - (ElfW(Sym) *) D_PTR (result,
>> +							l_info[DT_SYMTAB]);
>> +  if (!for_jmp_slot)
>> +    {
>> +      reloc_result->bound = result;
>> +      reloc_result->boundndx = boundndx;
>> +    }
> 
> 
> OK. Need to guard reloc_result around !for_jmp_slot.
> 
>>  
>>    if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
>>      {
>>        /* Set all bits since this symbol binding is not interesting.  */
>> -      reloc_result->enterexit = (1u << DL_NNS) - 1;
>> +      if (!for_jmp_slot)
>> +	reloc_result->enterexit = (1u << DL_NNS) - 1;
> 
> OK.
> 
>>        return;
>>      }
>>  
>> @@ -199,12 +206,13 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>>       two bits.  */
>>    assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
>>    assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
>> -  reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
>> +  uint32_t enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
> 
> OK.
> 
>>  
>>    const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]);
>>  
>>    unsigned int flags = 0;
>>    struct audit_ifaces *afct = GLRO(dl_audit);
>> +  uintptr_t new_value = (uintptr_t) sym.st_value;
>>    for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
>>      {
>>        /* XXX Check whether both DSOs must request action or only one */
>> @@ -215,37 +223,41 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>>  	{
>>  	  if (afct->symbind != NULL)
>>  	    {
> 
> OK. We have an auditor function to call.
> 
>> -	      uintptr_t new_value = afct->symbind (&sym,
>> -						   reloc_result->boundndx,
>> -						   &l_state->cookie,
>> -						   &result_state->cookie,
>> -						   &flags,
>> -						   strtab2 + defsym->st_name);
>> +	      flags |= for_jmp_slot ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT
>> +				    : 0;
> 
> OK. Set incoming flags depending on for_jmp_slot.
> 
>> +	      new_value = afct->symbind (&sym, boundndx,
>> +					 &l_state->cookie,
>> +					 &result_state->cookie, &flags,
>> +					 strtab2 + defsym->st_name);
>>  	      if (new_value != (uintptr_t) sym.st_value)
>>  		{
>>  		  flags |= LA_SYMB_ALTVALUE;
>> -		  sym.st_value = new_value;
>> +		  sym.st_value = for_jmp_slot
>> +		    ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value;
> 
> OK.
> 
>>  		}
>>  	    }
>>  
>>  	  /* Remember the results for every audit library and store a summary
>>  	     in the first two bits.  */
>> -	  reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER
>> -					      | LA_SYMB_NOPLTEXIT);
>> -	  reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
>> -						| LA_SYMB_NOPLTEXIT))
>> -				      << ((cnt + 1) * 2));
>> +	  enterexit &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
>> +	  enterexit |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
>> +			<< ((cnt + 1) * 2));
> 
> OK.
> 
>>  	}
>>        else
>>  	/* If the bind flags say this auditor is not interested, set the bits
>>  	   manually.  */
>> -	reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
>> -				    << ((cnt + 1) * 2));
>> +	enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
>> +		      << ((cnt + 1) * 2));
> 
> OK.
> 
>>        afct = afct->next;
>>      }
>>  
>> -  reloc_result->flags = flags;
>> -  *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
>> +  if (!for_jmp_slot)
>> +    {
>> +      reloc_result->enterexit = enterexit;
>> +      reloc_result->flags = flags;
>> +    }
>> +
>> +  DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
> 
> OK.
> 
>>  }
>>  
>>  void
>> diff --git a/elf/do-rel.h b/elf/do-rel.h
>> index 0718badf83..60d5dce8f2 100644
>> --- a/elf/do-rel.h
>> +++ b/elf/do-rel.h
>> @@ -16,6 +16,8 @@
>>     License along with the GNU C Library; if not, see
>>     <https://www.gnu.org/licenses/>.  */
>>  
>> +#include <ldsodefs.h>
>> +
>>  /* This file may be included twice, to define both
>>     `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.  */
>>  
>> @@ -123,6 +125,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
>>  
>>  	  for (; r < end; ++r)
>>  	    {
>> +	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
>> +	      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
>> +	      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
>> +	      const struct r_found_version *rversion = &map->l_versions[ndx];
>>  #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
>>  	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
>>  		{
>> @@ -133,10 +139,19 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
>>  		}
>>  #endif
>>  
>> -	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
>> -	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
>> -			       &map->l_versions[ndx],
>> -			       (void *) (l_addr + r->r_offset), skip_ifunc);
>> +	      elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg,
>> +			       skip_ifunc);
> 
> OK. We are in the non-lazy case.
> 
>> +#if defined SHARED && !defined RTLD_BOOTSTRAP
>> +	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
>> +		  && GLRO(dl_naudit) > 0)
>> +		{
>> +		  struct link_map *sym_map
>> +		    = RESOLVE_MAP (map, scope, &sym, rversion,
>> +				   ELF_MACHINE_JMP_SLOT);
> 
> OK. Do the extra check at startup.
> 
> 
>> +		  if (sym != NULL)
>> +		    _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map);
> 
> OK. Early immeidate binding for symbol.
> 
>> +		}
>> +#endif
>>  	    }
>>  
>>  #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
>> @@ -158,17 +173,33 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
>>        else
>>  	{
>>  	  for (; r < end; ++r)
>> +	    {
>> +	      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
>> +	      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
>>  # ifdef ELF_MACHINE_IRELATIVE
>> -	    if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
>> -	      {
>> -		if (r2 == NULL)
>> -		  r2 = r;
>> -		end2 = r;
>> -	      }
>> -	    else
>> +	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
>> +		{
>> +		  if (r2 == NULL)
>> +		    r2 = r;
>> +		  end2 = r;
>> +		  continue;
>> +		}
>>  # endif
>> -	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
>> -			       (void *) (l_addr + r->r_offset), skip_ifunc);
>> +	      elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg,
>> +			       skip_ifunc);
> 
> OK. We are in the non-lazy case as expected.
> 
>> +# if defined SHARED && !defined RTLD_BOOTSTRAP
>> +	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
>> +		  && GLRO(dl_naudit) > 0)
>> +		{
>> +		  struct link_map *sym_map
>> +		    = RESOLVE_MAP (map, scope, &sym,
>> +				   (struct r_found_version *) NULL,
>> +				   ELF_MACHINE_JMP_SLOT);
>> +		  if (sym != NULL)
>> +		    _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map);
> 
> OK. Again do the symbol binding auditing for immediate binding.
> 
> 
>> +		}
>> +# endif
>> +	    }
>>  
>>  # ifdef ELF_MACHINE_IRELATIVE
>>  	  if (r2 != NULL)
>> diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c
>> index 1077458c9d..a5edd438f9 100644
>> --- a/elf/sotruss-lib.c
>> +++ b/elf/sotruss-lib.c
>> @@ -16,6 +16,7 @@
>>     License along with the GNU C Library; if not, see
>>     <https://www.gnu.org/licenses/>.  */
>>  
>> +#include <err.h>
>>  #include <error.h>
>>  #include <fcntl.h>
>>  #include <stdio.h>
>> @@ -231,6 +232,12 @@ uintptr_t
>>  la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook,
>>  	    uintptr_t *defcook, unsigned int *flags, const char *symname)
>>  {
>> +  if (*flags & LA_SYMB_NOPLTENTER)
>> +    warnx ("cannot trace PLT enter (bind-now enabled)");
> 
> OK. Awesome! :-)
> 
>> +
>> +  if (do_exit && *flags & LA_SYMB_NOPLTEXIT)
>> +    warnx ("cannot trace PLT exit (bind-now enabled)");
> 
> OK.
> 
>> +
>>    if (!do_exit)
>>      *flags = LA_SYMB_NOPLTEXIT;
>>  
>> diff --git a/elf/tst-audit24a.c b/elf/tst-audit24a.c
>> new file mode 100644
>> index 0000000000..2cdd3fb98b
>> --- /dev/null
>> +++ b/elf/tst-audit24a.c
>> @@ -0,0 +1,36 @@
>> +/* DL_AUDIT test for la_symbind and bind-now.
> 
> s/DL_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <support/check.h>
>> +#include <support/support.h>
>> +
>> +int tst_audit24amod1_func1 (void);
>> +int tst_audit24amod1_func2 (void);
>> +int tst_audit24amod2_func1 (void);
> 
> OK. Calling 3 DSO functions with args.
> 
>> +
>> +int
>> +do_test (void)
>> +{
>> +  TEST_COMPARE (tst_audit24amod1_func1 (), 1);
>> +  TEST_COMPARE (tst_audit24amod1_func2 (), 2);
>> +  TEST_COMPARE (tst_audit24amod2_func1 (), 10);
>> +
>> +  return 0;
>> +}
>> +
>> +#include <support/test-driver.c>
>> diff --git a/elf/tst-audit24amod1.c b/elf/tst-audit24amod1.c
>> new file mode 100644
>> index 0000000000..c287372e32
>> --- /dev/null
>> +++ b/elf/tst-audit24amod1.c
>> @@ -0,0 +1,31 @@
>> +/* Modules used by tst-audit24a.
> 
> s/Modules/Module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <stdlib.h>
>> +
>> +_Noreturn int
>> +tst_audit24amod1_func1 (void)
>> +{
>> +  abort ();
> 
> OK. Calls abort. Needs redirecting.
> 
>> +}
>> +
>> +int
>> +tst_audit24amod1_func2 (void)
>> +{
>> +  return 2;
> 
> OK.
> 
>> +}
>> diff --git a/elf/tst-audit24amod2.c b/elf/tst-audit24amod2.c
>> new file mode 100644
>> index 0000000000..938c71dc29
>> --- /dev/null
>> +++ b/elf/tst-audit24amod2.c
>> @@ -0,0 +1,25 @@
>> +/* Modules used by tst-audit24a.
> 
> s/Modules/Module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <stdlib.h>
>> +
>> +_Noreturn int
>> +tst_audit24amod2_func1 (void)
>> +{
>> +  abort ();
> 
> OK. Function aborts. Needs redirecting.
> 
>> +}
>> diff --git a/elf/tst-audit24b.c b/elf/tst-audit24b.c
>> new file mode 100644
>> index 0000000000..82478ed8f9
>> --- /dev/null
>> +++ b/elf/tst-audit24b.c
>> @@ -0,0 +1,37 @@
>> +/* DL_AUDIT test for la_symbind and bind-now.
> 
> s/DL_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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 similar to tst-audit24a, with the difference this modules
>> +   does not have the .gnu.version section header.  */
>> +
>> +#include <support/check.h>
>> +#include <support/support.h>
>> +
>> +int tst_audit24bmod1_func1 (void);
>> +int tst_audit24bmod1_func2 (void);
>> +
>> +int
>> +do_test (void)
>> +{
>> +  TEST_COMPARE (tst_audit24bmod1_func1 (), 1);
>> +  TEST_COMPARE (tst_audit24bmod1_func2 (), 2);
> 
> OK. Second test. Call two DSO functions.
> 
>> +
>> +  return 0;
>> +}
>> +
>> +#include <support/test-driver.c>
>> diff --git a/elf/tst-audit24bmod1.c b/elf/tst-audit24bmod1.c
>> new file mode 100644
>> index 0000000000..5fa4611918
>> --- /dev/null
>> +++ b/elf/tst-audit24bmod1.c
>> @@ -0,0 +1,31 @@
>> +/* Modules used by tst-audit24c.
> 
> s/Modules/Module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +int tst_audit24bmod2_func1 (void);
>> +
>> +int
>> +tst_audit24bmod1_func1 (void)
>> +{
>> +  return -1;
>> +}
>> +
>> +int
>> +tst_audit24bmod1_func2 (void)
>> +{
>> +  return tst_audit24bmod2_func1 ();
> 
> OK. fun2 calls func1 in dependent DSO.
> 
>> +}
>> diff --git a/elf/tst-audit24bmod2.c b/elf/tst-audit24bmod2.c
>> new file mode 100644
>> index 0000000000..d469e70a41
>> --- /dev/null
>> +++ b/elf/tst-audit24bmod2.c
>> @@ -0,0 +1,23 @@
>> +/* Modules used by tst-audit24b.
> 
> s/Modules/Module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +int
>> +tst_audit24bmod2_func1 (void)
>> +{
>> +  return -1;
> 
> OK.
> 
>> +}
>> diff --git a/elf/tst-audit24c.c b/elf/tst-audit24c.c
>> new file mode 100644
>> index 0000000000..46ed328756
>> --- /dev/null
>> +++ b/elf/tst-audit24c.c
>> @@ -0,0 +1,2 @@
>> +/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now  */
>> +#include "tst-audit24a.c"
> 
> OK.
> 
>> diff --git a/elf/tst-audit24d.c b/elf/tst-audit24d.c
>> new file mode 100644
>> index 0000000000..1c89e4cb83
>> --- /dev/null
>> +++ b/elf/tst-audit24d.c
>> @@ -0,0 +1,36 @@
>> +/* DL_AUDIT test for la_symbind and bind-now.
> 
> s/DL_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <support/check.h>
>> +#include <support/support.h>
>> +
>> +int tst_audit24dmod1_func1 (void);
>> +int tst_audit24dmod1_func2 (void);
>> +int tst_audit24dmod2_func1 (void);
>> +
>> +int
>> +do_test (void)
>> +{
>> +  TEST_COMPARE (tst_audit24dmod1_func1 (), 1);
>> +  TEST_COMPARE (tst_audit24dmod1_func2 (), 32);
>> +  TEST_COMPARE (tst_audit24dmod2_func1 (), 10);
> 
> OK. Call functions in 2 DSOs.
> 
>> +
>> +  return 0;
>> +}
>> +
>> +#include <support/test-driver.c>
>> diff --git a/elf/tst-audit24dmod1.c b/elf/tst-audit24dmod1.c
>> new file mode 100644
>> index 0000000000..3ff2218c96
>> --- /dev/null
>> +++ b/elf/tst-audit24dmod1.c
>> @@ -0,0 +1,33 @@
>> +/* Modules used by tst-audit24d.
> 
> s/Modules/Module/g

Ack.


> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <stdlib.h>
>> +
>> +int tst_audit24dmod3_func1 (void);
>> +
>> +_Noreturn int
>> +tst_audit24dmod1_func1 (void)
>> +{
>> +  abort ();
> 
> OK. Function aborts. Needs redirection.
> 
>> +}
>> +
>> +int
>> +tst_audit24dmod1_func2 (void)
>> +{
>> +  return 2 + tst_audit24dmod3_func1 ();;
> 
> s/;;/;/g
> 
> OK. Calls 3rd DSO.
> 
>> +}
>> diff --git a/elf/tst-audit24dmod2.c b/elf/tst-audit24dmod2.c
>> new file mode 100644
>> index 0000000000..03fe938128
>> --- /dev/null
>> +++ b/elf/tst-audit24dmod2.c
>> @@ -0,0 +1,28 @@
>> +/* Module for tst-audit24d.
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <stdlib.h>
>> +
>> +int tst_audit24dmod4_func1 (void);
>> +
>> +_Noreturn int
>> +tst_audit24dmod2_func1 (void)
>> +{
>> +  tst_audit24dmod4_func1 ();
>> +  abort ();
> 
> OK. Calls 4th DSO and *then* aborts.
> 
>> +}
>> diff --git a/elf/tst-audit24dmod3.c b/elf/tst-audit24dmod3.c
>> new file mode 100644
>> index 0000000000..106d517d28
>> --- /dev/null
>> +++ b/elf/tst-audit24dmod3.c
>> @@ -0,0 +1,31 @@
>> +/* Module for tst-audit24d.
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <stdlib.h>
>> +
>> +_Noreturn int
>> +tst_audit24dmod3_func1 (void)
>> +{
>> +  abort ();
>> +}
>> +
>> +int
>> +tst_audit24dmod3_func2 (void)
>> +{
>> +  return 4;
>> +}
> 
> OK.
> 
>> diff --git a/elf/tst-audit24dmod4.c b/elf/tst-audit24dmod4.c
>> new file mode 100644
>> index 0000000000..1da3b46917
>> --- /dev/null
>> +++ b/elf/tst-audit24dmod4.c
>> @@ -0,0 +1,25 @@
>> +/* Module for tst-audit24d.
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <stdlib.h>
>> +
>> +_Noreturn int
>> +tst_audit24dmod4_func1 (void)
>> +{
>> +  abort ();
>> +}
> 
> OK.
> 
>> diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c
>> new file mode 100644
>> index 0000000000..3476069353
>> --- /dev/null
>> +++ b/elf/tst-audit25a.c
>> @@ -0,0 +1,129 @@
>> +/* Check DT_AUDIT and LD_BIND_NOW.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <array_length.h>
>> +#include <errno.h>
>> +#include <getopt.h>
>> +#include <limits.h>
>> +#include <inttypes.h>
>> +#include <string.h>
>> +#include <stdlib.h>
>> +#include <support/capture_subprocess.h>
>> +#include <support/check.h>
>> +#include <support/xstdio.h>
>> +#include <support/support.h>
>> +#include <sys/auxv.h>
>> +
>> +static int restart;
>> +#define CMDLINE_OPTIONS \
>> +  { "restart", no_argument, &restart, 1 },
>> +
>> +void tst_audit25mod1_func1 (void);
>> +void tst_audit25mod1_func2 (void);
>> +void tst_audit25mod2_func1 (void);
>> +void tst_audit25mod2_func2 (void);
>> +
>> +static int
>> +handle_restart (void)
>> +{
>> +  tst_audit25mod1_func1 ();
>> +  tst_audit25mod1_func2 ();
>> +  tst_audit25mod2_func1 ();
>> +  tst_audit25mod2_func2 ();
>> +
>> +  return 0;
>> +}
>> +
>> +static inline bool
>> +startswith (const char *str, const char *pre)
>> +{
>> +  size_t lenpre = strlen (pre);
>> +  size_t lenstr = strlen (str);
>> +  return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
>> +}
>> +
>> +static int
>> +do_test (int argc, char *argv[])
>> +{
>> +  /* We must have either:
>> +     - One our fource parameters left if called initially:
> 
> s/One our fource/One or four/g

Ack.


> 
>> +       + path to ld.so         optional
>> +       + "--library-path"      optional
>> +       + the library path      optional
>> +       + the application name  */
>> +
>> +  if (restart)
>> +    return handle_restart ();
>> +
>> +  setenv ("LD_AUDIT", "tst-auditmod25.so", 0);
>> +
>> +  char *spargv[9];
>> +  int i = 0;
>> +  for (; i < argc - 1; i++)
>> +    spargv[i] = argv[i + 1];
>> +  spargv[i++] = (char *) "--direct";
>> +  spargv[i++] = (char *) "--restart";
>> +  spargv[i] = NULL;
>> +  TEST_VERIFY_EXIT (i < array_length (spargv));
>> +
>> +  {
>> +    struct support_capture_subprocess result
>> +      = support_capture_subprogram (spargv[0], spargv);
>> +    support_capture_subprocess_check (&result, "tst-audit25a", 0,
>> +				      sc_allow_stderr);
> 
> OK. Call ourselves again.
> 
>> +
>> +    /* tst-audit25a is build with -Wl,-z,lazy and tst-audit25mod1 with
>> +       -Wl,-z,now; so only tst_audit25mod3_func1 should be expected to
>> +       have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  */
>> +    TEST_COMPARE_STRING (result.err.buffer,
>> +			 "la_symbind: tst_audit25mod3_func1 1\n"
>> +			 "la_symbind: tst_audit25mod1_func1 0\n"
>> +			 "la_symbind: tst_audit25mod1_func2 0\n"
>> +			 "la_symbind: tst_audit25mod2_func1 0\n"
>> +			 "la_symbind: tst_audit25mod4_func1 0\n"
>> +			 "la_symbind: tst_audit25mod2_func2 0\n");
>> +
>> +    support_capture_subprocess_free (&result);
>> +  }
>> +
>> +  {
>> +    setenv ("LD_BIND_NOW", "1", 0);
>> +    struct support_capture_subprocess result
>> +      = support_capture_subprogram (spargv[0], spargv);
>> +    support_capture_subprocess_check (&result, "tst-audit25a", 0,
>> +				      sc_allow_stderr);
> 
> OK.
> 
>> +
>> +    /* With LD_BIND_NOW all symbols are expected to have
>> +       LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  Also the resolution
>> +       order is done in breadth-first order.  */
>> +    TEST_COMPARE_STRING (result.err.buffer,
>> +			 "la_symbind: tst_audit25mod4_func1 1\n"
>> +			 "la_symbind: tst_audit25mod3_func1 1\n"
>> +			 "la_symbind: tst_audit25mod1_func1 1\n"
>> +			 "la_symbind: tst_audit25mod2_func1 1\n"
>> +			 "la_symbind: tst_audit25mod1_func2 1\n"
>> +			 "la_symbind: tst_audit25mod2_func2 1\n");
>> +
>> +    support_capture_subprocess_free (&result);
>> +  }
>> +
>> +  return 0;
>> +}
>> +
>> +#define TEST_FUNCTION_ARGV do_test
>> +#include <support/test-driver.c>
>> diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c
>> new file mode 100644
>> index 0000000000..8bf98bc7fd
>> --- /dev/null
>> +++ b/elf/tst-audit25b.c
>> @@ -0,0 +1,128 @@
>> +/* Check DT_AUDIT and LD_BIND_NOW.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.


> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <errno.h>
>> +#include <getopt.h>
>> +#include <limits.h>
>> +#include <inttypes.h>
>> +#include <string.h>
>> +#include <stdlib.h>
>> +#include <support/capture_subprocess.h>
>> +#include <support/check.h>
>> +#include <support/xstdio.h>
>> +#include <support/support.h>
>> +#include <sys/auxv.h>
>> +
>> +static int restart;
>> +#define CMDLINE_OPTIONS \
>> +  { "restart", no_argument, &restart, 1 },
>> +
>> +void tst_audit25mod1_func1 (void);
>> +void tst_audit25mod1_func2 (void);
>> +void tst_audit25mod2_func1 (void);
>> +void tst_audit25mod2_func2 (void);
>> +
>> +static int
>> +handle_restart (void)
>> +{
>> +  tst_audit25mod1_func1 ();
>> +  tst_audit25mod1_func2 ();
>> +  tst_audit25mod2_func1 ();
>> +  tst_audit25mod2_func2 ();
>> +
>> +  return 0;
>> +}
>> +
>> +static inline bool
>> +startswith (const char *str, const char *pre)
>> +{
>> +  size_t lenpre = strlen (pre);
>> +  size_t lenstr = strlen (str);
>> +  return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
>> +}
>> +
>> +static int
>> +do_test (int argc, char *argv[])
>> +{
>> +  /* We must have either:
>> +     - One our fource parameters left if called initially:
> 
> s/One our fource/One or four/g

Ack.

> 
>> +       + path to ld.so         optional
>> +       + "--library-path"      optional
>> +       + the library path      optional
>> +       + the application name  */
>> +
>> +  if (restart)
>> +    return handle_restart ();
>> +
>> +  setenv ("LD_AUDIT", "tst-auditmod25.so", 0);
>> +
>> +  char *spargv[9];
>> +  int i = 0;
>> +  for (; i < argc - 1; i++)
>> +    spargv[i] = argv[i + 1];
>> +  spargv[i++] = (char *) "--direct";
>> +  spargv[i++] = (char *) "--restart";
>> +  spargv[i] = NULL;
>> +
>> +  {
>> +    struct support_capture_subprocess result
>> +      = support_capture_subprogram (spargv[0], spargv);
>> +    support_capture_subprocess_check (&result, "tst-audit25a", 0,
>> +				      sc_allow_stderr);
> 
> OK.
> 
>> +
>> +    /* tst-audit25a and tst-audit25mod1 are built with -Wl,-z,now, but
>> +       tst-audit25mod2 is built with -Wl,z,lazy.  So only
> 
> s/,z,/,-z,/g

Ack.

> 
>> +       tst_audit25mod4_func1 (called by tst_audit25mod2_func1) should not
>> +       have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  */
>> +    TEST_COMPARE_STRING (result.err.buffer,
>> +			 "la_symbind: tst_audit25mod3_func1 1\n"
>> +			 "la_symbind: tst_audit25mod1_func1 1\n"
>> +			 "la_symbind: tst_audit25mod2_func1 1\n"
>> +			 "la_symbind: tst_audit25mod1_func2 1\n"
>> +			 "la_symbind: tst_audit25mod2_func2 1\n"
>> +			 "la_symbind: tst_audit25mod4_func1 0\n");
>> +
>> +    support_capture_subprocess_free (&result);
>> +  }
>> +
>> +  {
>> +    setenv ("LD_BIND_NOW", "1", 0);
>> +    struct support_capture_subprocess result
>> +      = support_capture_subprogram (spargv[0], spargv);
>> +    support_capture_subprocess_check (&result, "tst-audit25a", 0,
>> +				      sc_allow_stderr);
>> +
>> +    /* With LD_BIND_NOW all symbols are expected to have
>> +       LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT.  Also the resolution
>> +       order is done in breadth-first order.  */
> 
> OK.
> 
>> +    TEST_COMPARE_STRING (result.err.buffer,
>> +			 "la_symbind: tst_audit25mod4_func1 1\n"
>> +			 "la_symbind: tst_audit25mod3_func1 1\n"
>> +			 "la_symbind: tst_audit25mod1_func1 1\n"
>> +			 "la_symbind: tst_audit25mod2_func1 1\n"
>> +			 "la_symbind: tst_audit25mod1_func2 1\n"
>> +			 "la_symbind: tst_audit25mod2_func2 1\n");
>> +
>> +    support_capture_subprocess_free (&result);
>> +  }
>> +
>> +  return 0;
>> +}
>> +
>> +#define TEST_FUNCTION_ARGV do_test
>> +#include <support/test-driver.c>
>> diff --git a/elf/tst-audit25mod1.c b/elf/tst-audit25mod1.c
>> new file mode 100644
>> index 0000000000..3cff8cc688
>> --- /dev/null
>> +++ b/elf/tst-audit25mod1.c
>> @@ -0,0 +1,30 @@
>> +/* Modules used by tst-audit25.
> 
> s/Modules/Module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +void tst_audit25mod3_func1 (void);
>> +
>> +void
>> +tst_audit25mod1_func1 (void)
>> +{
>> +  tst_audit25mod3_func1 ();
>> +}
>> +
>> +void
>> +tst_audit25mod1_func2 (void)
>> +{
>> +}
> 
> OK.
> 
>> diff --git a/elf/tst-audit25mod2.c b/elf/tst-audit25mod2.c
>> new file mode 100644
>> index 0000000000..5e40555fa9
>> --- /dev/null
>> +++ b/elf/tst-audit25mod2.c
>> @@ -0,0 +1,30 @@
>> +/* Modules used by tst-audit25.
> 
> s/Modules/Module/g


Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +void tst_audit25mod4_func1 (void);
>> +
>> +void
>> +tst_audit25mod2_func1 (void)
>> +{
>> +  tst_audit25mod4_func1 ();
>> +}
>> +
>> +void
>> +tst_audit25mod2_func2 (void)
>> +{
>> +}
> 
> OK.
> 
>> diff --git a/elf/tst-audit25mod3.c b/elf/tst-audit25mod3.c
>> new file mode 100644
>> index 0000000000..e35ed6a1da
>> --- /dev/null
>> +++ b/elf/tst-audit25mod3.c
>> @@ -0,0 +1,22 @@
>> +/* Modules used by tst-audit25.
> 
> s/Modules/Module/g


Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +void
>> +tst_audit25mod3_func1 (void)
>> +{
>> +}
> 
> OK.
> 
>> diff --git a/elf/tst-audit25mod4.c b/elf/tst-audit25mod4.c
>> new file mode 100644
>> index 0000000000..c3118b6368
>> --- /dev/null
>> +++ b/elf/tst-audit25mod4.c
>> @@ -0,0 +1,22 @@
>> +/* Modules used by tst-audit25.
> 
> s/Modules/Module/g


Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +void
>> +tst_audit25mod4_func1 (void)
>> +{
>> +}
> 
> OK.
> 
>> diff --git a/elf/tst-auditmod24.h b/elf/tst-auditmod24.h
>> new file mode 100644
>> index 0000000000..e34c53df5e
>> --- /dev/null
>> +++ b/elf/tst-auditmod24.h
>> @@ -0,0 +1,29 @@
>> +/* Auxiliary functions for tst-audit24x.
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#ifndef _TST_AUDITMOD24_H
>> +#define _TST_AUDITMOD24_H
>> +
>> +static void
>> +check_symbind_flags (unsigned int flags)
> 
> Would suggest calling it "test_symbind_flags" since this is testing a specific
> condition of the test and aborting if not met.

Ack.

> 
>> +{
>> +  if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0)
>> +    abort ();
> 
> OK. Abort if none of the flags are set.
> 
>> +}
>> +
>> +#endif
>> diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c
>> new file mode 100644
>> index 0000000000..a4838b3e05
>> --- /dev/null
>> +++ b/elf/tst-auditmod24a.c
>> @@ -0,0 +1,114 @@
>> +/* Audit modules for tst-audit24a.
> 
> s/modules/module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <link.h>
>> +#include <inttypes.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <tst-auditmod24.h>
>> +
>> +#define AUDIT24_COOKIE     0x1
>> +#define AUDIT24MOD1_COOKIE 0x2
>> +#define AUDIT24MOD2_COOKIE 0x3
>> +
>> +#ifndef TEST_NAME
>> +# define TEST_NAME "tst-audit24a"
>> +#endif
>> +#ifndef TEST_MOD
>> +# define TEST_MOD TEST_NAME
>> +#endif
>> +#ifndef TEST_FUNC
>> +# define TEST_FUNC "tst_audit24a"
>> +#endif
>> +
>> +unsigned int
>> +la_version (unsigned int version)
>> +{
>> +  return LAV_CURRENT;
>> +}
>> +
>> +unsigned int
>> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
>> +{
>> +  const char *p = strrchr (map->l_name, '/');
>> +  const char *l_name = p == NULL ? TEST_NAME : p + 1;
>> +
>> +  uintptr_t ck = -1;
>> +  if (strcmp (l_name, TEST_MOD "mod1.so") == 0)
>> +    ck = AUDIT24MOD1_COOKIE;
>> +  else if (strcmp (l_name, TEST_MOD "mod2.so") == 0)
>> +    ck = AUDIT24MOD2_COOKIE;
>> +  else if (strcmp (l_name, TEST_NAME) == 0)
>> +    ck = AUDIT24_COOKIE;
>> +
>> +  *cookie = ck;
>> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
> 
> OK.
> 
>> +}
>> +
>> +static int
>> +tst_func1 (void)
>> +{
>> +  return 1;
>> +}
>> +
>> +static int
>> +tst_func2 (void)
>> +{
>> +  return 10;
>> +}
> 
> OK. Define two safety functions to use to avoid abort()s in the actual
> implementations.
> 
>> +
>> +#if __ELF_NATIVE_CLASS == 64
>> +uintptr_t
>> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
>> +	      uintptr_t *refcook, uintptr_t *defcook,
>> +	      unsigned int *flags, const char *symname)
>> +#else
>> +uintptr_t
>> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
>> +	      uintptr_t *refcook, uintptr_t *defcook,
>> +	      unsigned int *flags, const char *symname)
>> +#endif
>> +{
>> +  if (*refcook == AUDIT24_COOKIE)
>> +    {
>> +      if (*defcook == AUDIT24MOD1_COOKIE)
>> +	{
>> +	  /* Check if bind-now symbols are advertised to not call the PLT
>> +	     hooks.  */
>> +	  check_symbind_flags (*flags);
>> +
>> +	  if (strcmp (symname, TEST_FUNC "mod1_func1") == 0)
>> +	    return (uintptr_t) tst_func1;
>> +	  else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0)
>> +	    return sym->st_value;
>> +	  abort ();
>> +	}
>> +      if (*defcook == AUDIT24MOD2_COOKIE
>> +	  && (strcmp (symname, TEST_FUNC "mod2_func1") == 0))
>> +	{
>> +	  check_symbind_flags (*flags);
>> +
>> +	  return (uintptr_t) tst_func2;
>> +	}
>> +
>> +      /* malloc functions.  */
>> +      return sym->st_value;
>> +    }
>> +
>> +  abort ();
> 
> OK.
> 
>> +}
>> diff --git a/elf/tst-auditmod24b.c b/elf/tst-auditmod24b.c
>> new file mode 100644
>> index 0000000000..aefac8ced4
>> --- /dev/null
>> +++ b/elf/tst-auditmod24b.c
>> @@ -0,0 +1,104 @@
>> +/* Audit modules for tst-audit24b.
> 
> s/modules/module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <link.h>
>> +#include <inttypes.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <tst-auditmod24.h>
>> +
>> +#define TEST_NAME "tst-audit24b"
>> +#define TEST_FUNC "tst_audit24b"
>> +
>> +#define AUDIT24_COOKIE     0x1
>> +#define AUDIT24MOD1_COOKIE 0x2
>> +#define AUDIT24MOD2_COOKIE 0x3
>> +
>> +unsigned int
>> +la_version (unsigned int version)
>> +{
>> +  return LAV_CURRENT;
>> +}
>> +
>> +unsigned int
>> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
>> +{
>> +  const char *p = strrchr (map->l_name, '/');
>> +  const char *l_name = p == NULL ? TEST_NAME : p + 1;
>> +
>> +  uintptr_t ck = -1;
>> +  if (strcmp (l_name, TEST_NAME "mod1.so") == 0)
>> +    ck = AUDIT24MOD1_COOKIE;
>> +  else if (strcmp (l_name, TEST_NAME "mod2.so") == 0)
>> +    ck = AUDIT24MOD2_COOKIE;
>> +  else if (strcmp (l_name, TEST_NAME) == 0)
>> +    ck = AUDIT24_COOKIE;
>> +
>> +  *cookie = ck;
>> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
> 
> OK.
> 
>> +}
>> +
>> +static int
>> +tst_func1 (void)
>> +{
>> +  return 1;
>> +}
>> +
>> +static int
>> +tst_func2 (void)
>> +{
>> +  return 2;
>> +}
> 
> OK. Define two safe functions.
> 
>> +
>> +#if __ELF_NATIVE_CLASS == 64
>> +uintptr_t
>> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
>> +	      uintptr_t *refcook, uintptr_t *defcook,
>> +	      unsigned int *flags, const char *symname)
>> +#else
>> +uintptr_t
>> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
>> +	      uintptr_t *refcook, uintptr_t *defcook,
>> +	      unsigned int *flags, const char *symname)
>> +#endif
>> +{
>> +  if (*refcook == AUDIT24_COOKIE)
>> +    {
>> +      if (*defcook == AUDIT24MOD1_COOKIE)
>> +	  {
>> +	    if (strcmp (symname, TEST_FUNC "mod1_func1") == 0)
>> +	      return (uintptr_t) tst_func1;
> 
> OK.
> 
>> +	    else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0)
>> +	      return sym->st_value;
>> +	    abort ();
>> +	  }
>> +      /* malloc functions.  */
>> +      return sym->st_value;
>> +    }
>> +  else if (*refcook == AUDIT24MOD1_COOKIE)
>> +    {
>> +      if (*defcook == AUDIT24MOD2_COOKIE
>> +	  && (strcmp (symname, TEST_FUNC "mod2_func1") == 0))
>> +	{
>> +	  check_symbind_flags (*flags);
>> +	  return (uintptr_t) tst_func2;
> 
> OK.
> 
>> +	}
>> +    }
>> +
>> +  abort ();
>> +}
>> diff --git a/elf/tst-auditmod24c.c b/elf/tst-auditmod24c.c
>> new file mode 100644
>> index 0000000000..67e62c9d33
>> --- /dev/null
>> +++ b/elf/tst-auditmod24c.c
>> @@ -0,0 +1,3 @@
>> +#define TEST_NAME "tst-audit24c"
>> +#define TEST_MOD  "tst-audit24a"
>> +#include "tst-auditmod24a.c"
> 
> OK.
> 
>> diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c
>> new file mode 100644
>> index 0000000000..a49f00ef17
>> --- /dev/null
>> +++ b/elf/tst-auditmod24d.c
>> @@ -0,0 +1,120 @@
>> +/* Audit module for tst-audit24d.
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <link.h>
>> +#include <inttypes.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <tst-auditmod24.h>
>> +
>> +#define AUDIT24_COOKIE     0x0
>> +#define AUDIT24MOD1_COOKIE 0x1
>> +#define AUDIT24MOD2_COOKIE 0x2
>> +#define AUDIT24MOD3_COOKIE 0x3
>> +#define AUDIT24MOD4_COOKIE 0x4
>> +
>> +unsigned int
>> +la_version (unsigned int version)
>> +{
>> +  return LAV_CURRENT;
> 
> OK.
> 
>> +}
>> +
>> +unsigned int
>> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
>> +{
>> +  const char *p = strrchr (map->l_name, '/');
>> +  const char *l_name = p == NULL ? "tst-audit24d" : p + 1;
>> +
>> +  uintptr_t ck = -1;
>> +  if (strcmp (l_name, "tst-audit24dmod1.so") == 0)
>> +    ck = AUDIT24MOD1_COOKIE;
>> +  else if (strcmp (l_name, "tst-audit24dmod2.so") == 0)
>> +    ck = AUDIT24MOD2_COOKIE;
>> +  else if (strcmp (l_name, "tst-audit24dmod3.so") == 0)
>> +    ck = AUDIT24MOD3_COOKIE;
>> +  else if (strcmp (l_name, "tst-audit24dmod.so") == 0)
>> +    ck = AUDIT24MOD4_COOKIE;
>> +  else if (strcmp (l_name, "tst-audit24d") == 0)
>> +    ck = AUDIT24_COOKIE;
>> +
>> +  *cookie = ck;
>> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
> 
> OK.
> 
>> +}
>> +
>> +static int
>> +tst_audit24dmod1_func1 (void)
>> +{
>> +  return 1;
>> +}
>> +
>> +static int
>> +tst_audit24dmod2_func1 (void)
>> +{
>> +  return 10;
>> +}
>> +
>> +static int
>> +tst_audit24dmod3_func1 (void)
>> +{
>> +  return 30;
>> +}
> 
> OK.
> 
>> +
>> +#include <stdio.h>
>> +
>> +#if __ELF_NATIVE_CLASS == 64
>> +uintptr_t
>> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
>> +	      uintptr_t *refcook, uintptr_t *defcook,
>> +	      unsigned int *flags, const char *symname)
>> +#else
>> +uintptr_t
>> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
>> +	      uintptr_t *refcook, uintptr_t *defcook,
>> +	      unsigned int *flags, const char *symname)
>> +#endif
>> +{
>> +  if (*refcook == AUDIT24_COOKIE)
>> +    {
>> +      if (*defcook == AUDIT24MOD1_COOKIE)
>> +	  {
>> +	    if (strcmp (symname, "tst_audit24dmod1_func1") == 0)
>> +	      return (uintptr_t) tst_audit24dmod1_func1;
>> +	    else if (strcmp (symname, "tst_audit24dmod1_func2") == 0)
>> +	      return sym->st_value;
>> +	    abort ();
>> +	  }
>> +      if (*defcook == AUDIT24MOD2_COOKIE
>> +	  && (strcmp (symname, "tst_audit24dmod2_func1") == 0))
>> +	return (uintptr_t) tst_audit24dmod2_func1;
>> +
>> +      /* malloc functions.  */
>> +      return sym->st_value;
>> +    }
>> +  else if (*refcook == AUDIT24MOD1_COOKIE)
>> +    {
>> +      if (*defcook == AUDIT24MOD3_COOKIE
>> +	  && strcmp (symname, "tst_audit24dmod3_func1") == 0)
>> +	{
>> +	  check_symbind_flags (*flags);
>> +
>> +	  return (uintptr_t) tst_audit24dmod3_func1;
>> +	}
>> +    }
>> +
>> +  abort ();
>> +}
> 
> OK.
> 
>> diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c
>> new file mode 100644
>> index 0000000000..526f5c54bc
>> --- /dev/null
>> +++ b/elf/tst-auditmod25.c
>> @@ -0,0 +1,79 @@
>> +/* Audit modules for tst-audit25a.
> 
> s/modules/module/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <link.h>
>> +#include <inttypes.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <stdio.h>
>> +
>> +#define AUDIT25_COOKIE     0x1
>> +#define AUDIT25MOD1_COOKIE 0x2
>> +#define AUDIT25MOD2_COOKIE 0x3
>> +#define AUDIT25MOD3_COOKIE 0x2
>> +#define AUDIT25MOD4_COOKIE 0x3
>> +
>> +#define TEST_NAME "tst-audit25"
>> +#define TEST_MOD  "tst-audit25"
>> +#define TEST_FUNC "tst_audit25"
>> +
>> +unsigned int
>> +la_version (unsigned int version)
>> +{
>> +  return LAV_CURRENT;
>> +}
>> +
>> +unsigned int
>> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
>> +{
>> +  const char *p = strrchr (map->l_name, '/');
>> +  const char *l_name = p == NULL ? TEST_NAME : p + 1;
>> +
>> +  uintptr_t ck = -1;
>> +  if (strcmp (l_name, TEST_MOD "mod1.so") == 0)
>> +    ck = AUDIT25MOD1_COOKIE;
>> +  else if (strcmp (l_name, TEST_MOD "mod2.so") == 0)
>> +    ck = AUDIT25MOD2_COOKIE;
>> +  else if (strcmp (l_name, TEST_MOD "mod3.so") == 0)
>> +    ck = AUDIT25MOD3_COOKIE;
>> +  else if (strcmp (l_name, TEST_MOD "mod4.so") == 0)
>> +    ck = AUDIT25MOD4_COOKIE;
>> +  else if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
>> +    ck = AUDIT25_COOKIE;
>> +
>> +  *cookie = ck;
>> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
> 
> OK.
> 
>> +}
>> +
>> +#if __ELF_NATIVE_CLASS == 64
>> +uintptr_t
>> +la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
>> +	      uintptr_t *refcook, uintptr_t *defcook,
>> +	      unsigned int *flags, const char *symname)
>> +#else
>> +uintptr_t
>> +la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
>> +	      uintptr_t *refcook, uintptr_t *defcook,
>> +	      unsigned int *flags, const char *symname)
>> +#endif
>> +{
>> +  if (*refcook != -1 && *defcook != -1)
>> +    fprintf (stderr, "la_symbind: %s %u\n", symname,
>> +	     *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);
> 
> OK.
> 
>> +  return sym->st_value;
>> +}
>> diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h
>> index 7460c0596a..95bcfc1cc1 100644
>> --- a/sysdeps/generic/dl-lookupcfg.h
>> +++ b/sysdeps/generic/dl-lookupcfg.h
>> @@ -26,3 +26,6 @@
>>  #define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
>>  #define DL_FIXUP_VALUE_ADDR(value) (value)
>>  #define DL_FIXUP_ADDR_VALUE(addr) (addr)
>> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
>> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
>> +  (*value) = st_value;
> 
> OK.
> 
>> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
>> index 97061bdf9f..2ebe7901c0 100644
>> --- a/sysdeps/generic/ldsodefs.h
>> +++ b/sysdeps/generic/ldsodefs.h
>> @@ -1431,7 +1431,10 @@ void _dl_audit_objclose (struct link_map *l)
>>  /* Call the la_preinit from the audit modules for the link_map L.  */
>>  void _dl_audit_preinit (struct link_map *l);
>>  
>> -/* Call the la_symbind{32,64} from the audit modules for the link_map L.  */
>> +/* Call the la_symbind{32,64} from the audit modules for the link_map L.  If
>> +   RELOC_RESULT is NULL it assumes the symbol to be bind-now and will set
>> +   the flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT prior calling
>> +   la_symbind{32,64}.  */
> 
> OK.
> 
>>  void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>>  			const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
>>  			lookup_t result)
>> diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
>> index 5d381147c0..8da2412fea 100644
>> --- a/sysdeps/hppa/dl-lookupcfg.h
>> +++ b/sysdeps/hppa/dl-lookupcfg.h
>> @@ -80,3 +80,6 @@ void attribute_hidden _dl_unmap (struct link_map *map);
>>  #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
>>  #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
>>  #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
>> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
>> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
>> +  (*value) = *(struct fdesc *) (st_value)
> 
> OK.
> 
>> diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h
>> index b8ab1bba15..3df3116b31 100644
>> --- a/sysdeps/ia64/dl-lookupcfg.h
>> +++ b/sysdeps/ia64/dl-lookupcfg.h
>> @@ -74,3 +74,6 @@ extern void attribute_hidden _dl_unmap (struct link_map *map);
>>  
>>  #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
>>  #define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
>> +#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
>> +#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
>> +  (*value) = *(struct fdesc *) (st_value)
> 
> OK.
> 
>> diff --git a/sysdeps/powerpc/dl-lookupcfg.h b/sysdeps/powerpc/dl-lookupcfg.h
>> new file mode 100644
>> index 0000000000..25abcc1d12
>> --- /dev/null
>> +++ b/sysdeps/powerpc/dl-lookupcfg.h
>> @@ -0,0 +1,39 @@
>> +/* Configuration of lookup functions.  PowerPC version.
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
>> +#define DL_FIXUP_MAKE_VALUE(map, addr) (addr)
>> +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
>> +#define DL_FIXUP_VALUE_ADDR(value) (value)
>> +#define DL_FIXUP_ADDR_VALUE(addr) (addr)
>> +#if __WORDSIZE == 64 && _CALL_ELF == 1
>> +/* We need to correctly set the audit modules value for bind-now.  */
>> +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) \
>> + (((Elf64_FuncDesc *)(addr))->fd_func)
>> +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value)	\
>> + ({								\
>> +    Elf64_FuncDesc *opd = (Elf64_FuncDesc *) (value);		\
>> +    opd->fd_func = (st_value);					\
>> +    if ((new_value) != (uintptr_t) (st_value))			\
>> +     opd->fd_toc = ((Elf64_FuncDesc *)(new_value))->fd_toc;	\
> 
> OK.
> 
>> +  })
>> +#else
>> +# define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
>> +# define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value)	\
>> +  (*value) = st_value;
> 
> OK.
> 
>> +#endif
> 
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v12 4/4] elf: Fix runtime linker auditing on aarch64 (BZ #26643)
  2022-02-01  6:19   ` Carlos O'Donell
@ 2022-02-01 14:11     ` Adhemerval Zanella
  0 siblings, 0 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2022-02-01 14:11 UTC (permalink / raw)
  To: Carlos O'Donell, libc-alpha, jma14
  Cc: John Mellor-Crummey, Ben Woodard, Szabolcs Nagy



On 01/02/2022 03:19, Carlos O'Donell wrote:
> On 1/25/22 13:37, Adhemerval Zanella wrote:
>> From: Ben Woodard <woodard@redhat.com>
>>
>> The rtld audit support show two problems on aarch64:
>>
>>   1. _dl_runtime_resolve does not preserve x8, the indirect result
>>       location register, which might generate wrong result calls
>>       depending of the function signature.
>>
>>   2. The NEON Q registers pushed onto the stack by _dl_runtime_resolve
>>      were twice the size of D registers extracted from the stack frame by
>>      _dl_runtime_profile.
>>
>> While 2. might result in wrong information passed on the PLT tracing,
>> 1. generates wrong runtime behaviour.
>>
>> The aarch64 rtld audit support is change to:
> 
> s/change/changed/g

Ack.

> 
>>
>>   * Both La_aarch64_regs and La_aarch64_retval are expanded to include
>>     both x8 and the full sized NEON V registers, as defined by the
>>     ABI.
>>
>>   * dl_runtime_profile needed to extract registers saved by
>>     _dl_runtime_resolve and put them into the new correctly sized
>>     La_aarch64_regs structure.
>>
>>   * The LAV_CURRENT check is change to only accept new audit modules
>>     to avoid the undefined behavior of not save/restore x8.
> 
> OK.
> 
>>
>>   * Different than other architectures, audit modules older than
>>     LAV_CURRENT are rejected (both La_aarch64_regs and La_aarch64_retval
>>     changed their layout and the it does worth the to support multiple
> 
> s/and the it does worth the/and there are no requirements/g

Ack.

> 
>>     audit interface with the inherent aarch64 issues).
>>
>>   * A new field is also reserved on both La_aarch64_regs and
>>     La_aarch64_retval to support variant pcs symbols.
>>
>> Similar to x86, a new La_aarch64_vector type to represent the NEON
>> register is added on the La_aarch64_regs (so each type can be accessed
>> directly).
>>
>> Since LAV_CURRENT was already bumped to support bind-now, there is
>> no need to increase it again.
> 
> OK.
> 
>>
>> Checked on aarch64-linux-gnu.
> 
> Please send v13 and I'll ACK that for glibc 2.35.

Ack.

> 
>>
>> Co-authored-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
>> Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
>> ---
>>  NEWS                             |   4 +
>>  elf/rtld.c                       |   3 +-
>>  sysdeps/aarch64/Makefile         |  20 ++++
>>  sysdeps/aarch64/bits/link.h      |  26 +++--
>>  sysdeps/aarch64/dl-audit-check.h |  28 +++++
>>  sysdeps/aarch64/dl-link.sym      |   6 +-
>>  sysdeps/aarch64/dl-trampoline.S  |  81 +++++++++-----
>>  sysdeps/aarch64/tst-audit26.c    |  37 +++++++
>>  sysdeps/aarch64/tst-audit26mod.c |  33 ++++++
>>  sysdeps/aarch64/tst-audit26mod.h |  50 +++++++++
>>  sysdeps/aarch64/tst-audit27.c    |  64 +++++++++++
>>  sysdeps/aarch64/tst-audit27mod.c |  95 ++++++++++++++++
>>  sysdeps/aarch64/tst-audit27mod.h |  67 ++++++++++++
>>  sysdeps/aarch64/tst-auditmod26.c | 103 ++++++++++++++++++
>>  sysdeps/aarch64/tst-auditmod27.c | 180 +++++++++++++++++++++++++++++++
>>  sysdeps/generic/dl-audit-check.h |  23 ++++
>>  16 files changed, 779 insertions(+), 41 deletions(-)
>>  create mode 100644 sysdeps/aarch64/dl-audit-check.h
>>  create mode 100644 sysdeps/aarch64/tst-audit26.c
>>  create mode 100644 sysdeps/aarch64/tst-audit26mod.c
>>  create mode 100644 sysdeps/aarch64/tst-audit26mod.h
>>  create mode 100644 sysdeps/aarch64/tst-audit27.c
>>  create mode 100644 sysdeps/aarch64/tst-audit27mod.c
>>  create mode 100644 sysdeps/aarch64/tst-audit27mod.h
>>  create mode 100644 sysdeps/aarch64/tst-auditmod26.c
>>  create mode 100644 sysdeps/aarch64/tst-auditmod27.c
>>  create mode 100644 sysdeps/generic/dl-audit-check.h
>>
>> diff --git a/NEWS b/NEWS
>> index c0f8932f84..40623d01c0 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -162,6 +162,10 @@ Deprecated and removed features, and other changes affecting compatibility:
>>    proper bind-now support.  The loader now advertises on the la_symbind
>>    flags that PLT trace is not possible.
>>  
>> +* The audit interface on aarch64 is extended to support both the indirect
>> +  result location register (x8) and NEON Q register.  Old audit modules are
>> +  rejected by the loader.
> 
> OK. Thanks for the NEWS update.
> 
>> +
>>  Changes to build and runtime requirements:
>>  
>>    [Add changes to build and runtime requirements here]
>> diff --git a/elf/rtld.c b/elf/rtld.c
>> index 10436f7034..8dafaf61f4 100644
>> --- a/elf/rtld.c
>> +++ b/elf/rtld.c
>> @@ -52,6 +52,7 @@
>>  #include <get-dynamic-info.h>
>>  #include <dl-execve.h>
>>  #include <dl-find_object.h>
>> +#include <dl-audit-check.h>
>>  
>>  #include <assert.h>
>>  
>> @@ -1000,7 +1001,7 @@ file=%s [%lu]; audit interface function la_version returned zero; ignored.\n",
>>        return;
>>      }
>>  
>> -  if (lav > LAV_CURRENT)
>> +  if (!_dl_audit_check_version (lav))
>>      {
>>        _dl_debug_printf ("\
>>  ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n",
>> diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
>> index 7c66fb97aa..7183895d04 100644
>> --- a/sysdeps/aarch64/Makefile
>> +++ b/sysdeps/aarch64/Makefile
>> @@ -10,6 +10,26 @@ endif
>>  
>>  ifeq ($(subdir),elf)
>>  sysdep-dl-routines += dl-bti
>> +
>> +tests += tst-audit26 \
>> +	 tst-audit27
> 
> OK.
> 
>> +
>> +modules-names += \
>> +    tst-audit26mod \
>> +    tst-auditmod26 \
>> +    tst-audit27mod \
>> +    tst-auditmod27
>> +
>> +$(objpfx)tst-audit26: $(objpfx)tst-audit26mod.so \
>> +		      $(objpfx)tst-auditmod26.so
>> +LDFLAGS-tst-audit26 += -Wl,-z,lazy
>> +tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so
>> +
>> +$(objpfx)tst-audit27: $(objpfx)tst-audit27mod.so \
>> +		      $(objpfx)tst-auditmod27.so
>> +$(objpfx)tst-audit27mod.so: $(libsupport)
>> +LDFLAGS-tst-audit27 += -Wl,-z,lazy
>> +tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so
>>  endif
> 
> OK.
> 
>>  
>>  ifeq ($(subdir),elf)
>> diff --git a/sysdeps/aarch64/bits/link.h b/sysdeps/aarch64/bits/link.h
>> index e64f36d3f3..2479abc4fb 100644
>> --- a/sysdeps/aarch64/bits/link.h
>> +++ b/sysdeps/aarch64/bits/link.h
>> @@ -20,23 +20,31 @@
>>  # error "Never include <bits/link.h> directly; use <link.h> instead."
>>  #endif
>>  
>> +typedef union
>> +{
>> +  float s;
>> +  double d;
>> +  long double q;
>> +} La_aarch64_vector;
> 
> OK.
> 
>> +
>>  /* Registers for entry into PLT on AArch64.  */
>>  typedef struct La_aarch64_regs
>>  {
>> -  uint64_t lr_xreg[8];
>> -  uint64_t lr_dreg[8];
>> -  uint64_t lr_sp;
>> -  uint64_t lr_lr;
>> +  uint64_t          lr_xreg[9];
> 
> OK, add new lr_xreg.
> 
>> +  La_aarch64_vector lr_vreg[8];
> 
> OK, add lr_vreg's.
> 
>> +  uint64_t          lr_sp;
>> +  uint64_t          lr_lr;
>> +  void              *lr_vpcs;
>>  } La_aarch64_regs;
>>  
>>  /* Return values for calls from PLT on AArch64.  */
>>  typedef struct La_aarch64_retval
>>  {
>> -  /* Up to two integer registers can be used for a return value.  */
>> -  uint64_t lrv_xreg[2];
>> -  /* Up to four D registers can be used for a return value.  */
>> -  uint64_t lrv_dreg[4];
>> -
>> +  /* Up to eight integer registers can be used for a return value.  */
>> +  uint64_t          lrv_xreg[8];
>> +  /* Up to eight V registers can be used for a return value.  */
>> +  La_aarch64_vector lrv_vreg[8];
>> +  void              *lrv_vpcs;
> 
> OK.
> 
>>  } La_aarch64_retval;
>>  __BEGIN_DECLS
>>  
>> diff --git a/sysdeps/aarch64/dl-audit-check.h b/sysdeps/aarch64/dl-audit-check.h
>> new file mode 100644
>> index 0000000000..181eba0e8e
>> --- /dev/null
>> +++ b/sysdeps/aarch64/dl-audit-check.h
>> @@ -0,0 +1,28 @@
>> +/* rtld-audit version check.  AArch64 version.
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +static inline bool
>> +_dl_audit_check_version (unsigned int lav)
>> +{
>> +  /* Audit version 1 do not save neither x8 nor NEON register, which required
> 
> s/neither x86 nor NEON register/x8 or NEON registers/g

Ack.

> 
>> +     change La_aarch64_regs and La_aarch64_retval layout (BZ#26643).  The
> 
> s/change/changing/g

Ack.

> 
>> +     missing indirect result save/restore makes _dl_runtime_profile
>> +     potentially trigger undefined behavior if function returns a large
> 
> s/if/if the/g

Ack.

> 
>> +     struct (even when PLT trace is not requested).  */
>> +  return lav == LAV_CURRENT;
>> +}
>> diff --git a/sysdeps/aarch64/dl-link.sym b/sysdeps/aarch64/dl-link.sym
>> index d67d28b40c..cb4dcdcbed 100644
>> --- a/sysdeps/aarch64/dl-link.sym
>> +++ b/sysdeps/aarch64/dl-link.sym
>> @@ -7,9 +7,11 @@ DL_SIZEOF_RG		sizeof(struct La_aarch64_regs)
>>  DL_SIZEOF_RV		sizeof(struct La_aarch64_retval)
>>  
>>  DL_OFFSET_RG_X0		offsetof(struct La_aarch64_regs, lr_xreg)
>> -DL_OFFSET_RG_D0		offsetof(struct La_aarch64_regs, lr_dreg)
>> +DL_OFFSET_RG_V0		offsetof(struct La_aarch64_regs, lr_vreg)
> 
> OK.
> 
>>  DL_OFFSET_RG_SP		offsetof(struct La_aarch64_regs, lr_sp)
>>  DL_OFFSET_RG_LR		offsetof(struct La_aarch64_regs, lr_lr)
>> +DL_OFFSET_RG_VPCS       offsetof(struct La_aarch64_regs, lr_vpcs)
> 
> OK.
> 
>>  
>>  DL_OFFSET_RV_X0		offsetof(struct La_aarch64_retval, lrv_xreg)
>> -DL_OFFSET_RV_D0		offsetof(struct La_aarch64_retval, lrv_dreg)
>> +DL_OFFSET_RV_V0		offsetof(struct La_aarch64_retval, lrv_vreg)
>> +DL_OFFSET_RV_VPCS       offsetof(struct La_aarch64_retval, lrv_vpcs)
> 
> OK.
> 
>> diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
>> index a403863ef9..a7fc34639b 100644
>> --- a/sysdeps/aarch64/dl-trampoline.S
>> +++ b/sysdeps/aarch64/dl-trampoline.S
>> @@ -45,7 +45,8 @@ _dl_runtime_resolve:
>>  
>>  	cfi_rel_offset (lr, 8)
>>  
>> -	/* Save arguments.  */
>> +	/* Note: Saving x9 is not required by the ABI but the assember requires
> 
> s/assember/assembler/g

Ack.

> 
>> +	   the immediate values of operand 3 to be a multiple of 16 */
>>  	stp	x8, x9, [sp, #-(80+8*16)]!
>>  	cfi_adjust_cfa_offset (80+8*16)
>>  	cfi_rel_offset (x8, 0)
>> @@ -142,7 +143,7 @@ _dl_runtime_profile:
>>  	   Stack frame layout:
>>  	   [sp,   #...] lr
>>  	   [sp,   #...] &PLTGOT[n]
>> -	   [sp,    #96] La_aarch64_regs
>> +	   [sp,   #256] La_aarch64_regs
> 
> OK.
> 
>>  	   [sp,    #48] La_aarch64_retval
>>  	   [sp,    #40] frame size return from pltenter
>>  	   [sp,    #32] dl_profile_call saved x1
>> @@ -183,19 +184,25 @@ _dl_runtime_profile:
>>  	stp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
>>  	cfi_rel_offset (x6, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 0)
>>  	cfi_rel_offset (x7, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 8)
>> -
>> -	stp	d0, d1, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
>> -	cfi_rel_offset (d0, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0)
>> -	cfi_rel_offset (d1, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0 + 8)
>> -	stp	d2, d3, [X29, #OFFSET_RG+ DL_OFFSET_RG_D0 + 16*1]
>> -	cfi_rel_offset (d2, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 0)
>> -	cfi_rel_offset (d3, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 8)
>> -	stp	d4, d5, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
>> -	cfi_rel_offset (d4, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 0)
>> -	cfi_rel_offset (d5, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 8)
>> -	stp	d6, d7, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
>> -	cfi_rel_offset (d6, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 0)
>> -	cfi_rel_offset (d7, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 8)
>> +	str	x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0]
>> +	cfi_rel_offset (x8, OFFSET_RG + DL_OFFSET_RG_X0 + 16*4 + 0)
>> +	/* Note 8 bytes of padding is in the stack frame for alignment */
>> +
>> +	stp	q0, q1, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
>> +	cfi_rel_offset (q0, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0)
>> +	cfi_rel_offset (q1, OFFSET_RG + DL_OFFSET_RG_V0 + 32*0 + 16)
>> +	stp	q2, q3, [X29, #OFFSET_RG+ DL_OFFSET_RG_V0 + 32*1]
>> +	cfi_rel_offset (q2, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 0)
>> +	cfi_rel_offset (q3, OFFSET_RG + DL_OFFSET_RG_V0 + 32*1 + 16)
>> +	stp	q4, q5, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
>> +	cfi_rel_offset (q4, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 0)
>> +	cfi_rel_offset (q5, OFFSET_RG + DL_OFFSET_RG_V0 + 32*2 + 16)
>> +	stp	q6, q7, [X29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]
>> +	cfi_rel_offset (q6, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 0)
>> +	cfi_rel_offset (q7, OFFSET_RG + DL_OFFSET_RG_V0 + 32*3 + 16)
> 
> OK.
> 
>> +
>> +	/* No APCS extension supported.  */
>> +	str	xzr,    [X29, #OFFSET_RG + DL_OFFSET_RG_VPCS]
> 
> OK.
> 
>>  
>>  	add     x0, x29, #SF_SIZE + 16
>>  	ldr	x1, [x29, #OFFSET_LR]
>> @@ -234,10 +241,11 @@ _dl_runtime_profile:
>>  	ldp	x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
>>  	ldp	x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
>>  	ldp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
>> -	ldp	d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
>> -	ldp	d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
>> -	ldp	d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
>> -	ldp	d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
>> +	ldr	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
>> +	ldp	q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
>> +	ldp	q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1]
>> +	ldp	q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
>> +	ldp	q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]
> 
> OK.
> 
>>  
>>  	cfi_def_cfa_register (sp)
>>  	ldp	x29, x30, [x29, #0]
>> @@ -280,14 +288,22 @@ _dl_runtime_profile:
>>  	ldp	x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
>>  	ldp	x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
>>  	ldp	x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
>> -	ldp	d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
>> -	ldp	d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
>> -	ldp	d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
>> -	ldp	d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
>> +	ldr	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
>> +	ldp	q0, q1, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*0]
>> +	ldp	q2, q3, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*1]
>> +	ldp	q4, q5, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*2]
>> +	ldp	q6, q7, [x29, #OFFSET_RG + DL_OFFSET_RG_V0 + 32*3]
> 
> OK.
> 
>>  	blr	ip0
>> -	stp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
>> -	stp	d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
>> -	stp	d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
>> +	stp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0]
>> +	stp	x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
>> +	stp	x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
>> +	stp	x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
>> +	str	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
>> +	stp	q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
>> +	stp	q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
>> +	stp	q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
>> +	stp	q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3]
>> +	str	xzr,    [X29, #OFFSET_RV + DL_OFFSET_RG_VPCS]
> 
> OK.
> 
>>  
>>  	/* Setup call to pltexit  */
>>  	ldp	x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
>> @@ -295,9 +311,16 @@ _dl_runtime_profile:
>>  	add	x3, x29, #OFFSET_RV
>>  	bl	_dl_audit_pltexit
>>  
>> -	ldp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
>> -	ldp	d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
>> -	ldp	d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
>> +	ldp	x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*0]
>> +	ldp	x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
>> +	ldp	x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
>> +	ldp	x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
>> +	ldr	x8,     [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*4]
>> +	ldp	q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
>> +	ldp	q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
>> +	ldp	q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
>> +	ldp	q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3]
> 
> OK.
> 
>> +
>>  	/* LR from within La_aarch64_reg */
>>  	ldr	lr, [x29, #OFFSET_RG + DL_OFFSET_RG_LR]
>>  	cfi_restore(lr)
>> diff --git a/sysdeps/aarch64/tst-audit26.c b/sysdeps/aarch64/tst-audit26.c
>> new file mode 100644
>> index 0000000000..8772958541
>> --- /dev/null
>> +++ b/sysdeps/aarch64/tst-audit26.c
>> @@ -0,0 +1,37 @@
>> +/* Check DT_AUDIT for aarch64 ABI specifics.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <array_length.h>
>> +#include <string.h>
>> +#include <support/check.h>
>> +#include "tst-audit26mod.h"
>> +
>> +int
>> +do_test (void)
>> +{
>> +  /* Returning a large struct uses 'x8' as indirect result location.  */
>> +  struct large_struct r = tst_audit26_func (ARG1, ARG2, ARG3);
>> +
>> +  struct large_struct e = set_large_struct (ARG1, ARG2, ARG3);
>> +
>> +  TEST_COMPARE_BLOB (r.a, sizeof (r.a), e.a, sizeof (e.a));
>> +
>> +  return 0;
>> +}
> 
> OK.
> 
>> +
>> +#include <support/test-driver.c>
>> diff --git a/sysdeps/aarch64/tst-audit26mod.c b/sysdeps/aarch64/tst-audit26mod.c
>> new file mode 100644
>> index 0000000000..8d309be575
>> --- /dev/null
>> +++ b/sysdeps/aarch64/tst-audit26mod.c
>> @@ -0,0 +1,33 @@
>> +/* Check DT_AUDIT for aarch64 ABI specifics.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <stdlib.h>
>> +#include "tst-audit26mod.h"
>> +
>> +struct large_struct
>> +tst_audit26_func (char a, short b, long int c)
>> +{
>> +  if (a != ARG1)
>> +    abort ();
>> +  if (b != ARG2)
>> +    abort ();
>> +  if (c != ARG3)
>> +    abort ();
>> +
>> +  return set_large_struct (a, b, c);
>> +}
> 
> OK.
> 
>> diff --git a/sysdeps/aarch64/tst-audit26mod.h b/sysdeps/aarch64/tst-audit26mod.h
>> new file mode 100644
>> index 0000000000..4226fad8cd
>> --- /dev/null
>> +++ b/sysdeps/aarch64/tst-audit26mod.h
>> @@ -0,0 +1,50 @@
>> +/* Check DT_AUDIT for aarch64 specific ABI.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#ifndef _TST_AUDIT27MOD_H
>> +#define _TST_AUDIT27MOD_H 1
>> +
>> +#include <array_length.h>
>> +
>> +struct large_struct
>> +{
>> +  char a[16];
>> +  short b[8];
>> +  long int c[4];
>> +};
> 
> 
> OK.
> 
>> +
>> +static inline struct large_struct
>> +set_large_struct (char a, short b, long int c)
>> +{
>> +  struct large_struct r;
>> +  for (int i = 0; i < array_length (r.a); i++)
>> +    r.a[i] = a;
>> +  for (int i = 0; i < array_length (r.b); i++)
>> +    r.b[i] = b;
>> +  for (int i = 0; i < array_length (r.c); i++)
>> +    r.c[i] = c;
>> +  return r;
> 
> OK.
> 
>> +}
>> +
>> +#define ARG1 0x12
>> +#define ARG2 0x1234
>> +#define ARG3 0x12345678
> 
> OK.
> 
>> +
>> +struct large_struct tst_audit26_func (char a, short b, long int c);
> 
> OK.
> 
>> +
>> +#endif
>> diff --git a/sysdeps/aarch64/tst-audit27.c b/sysdeps/aarch64/tst-audit27.c
>> new file mode 100644
>> index 0000000000..f5017ce0f1
>> --- /dev/null
>> +++ b/sysdeps/aarch64/tst-audit27.c
>> @@ -0,0 +1,64 @@
>> +/* Check DT_AUDIT for aarch64 ABI specifics.
> 
> s/DT_AUDIT/LD_AUDIT/g

ACk.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <array_length.h>
>> +#include <string.h>
>> +#include <support/check.h>
>> +#include "tst-audit27mod.h"
>> +
>> +int
>> +do_test (void)
>> +{
>> +  {
>> +    float r = tst_audit27_func_float (FUNC_FLOAT_ARG0, FUNC_FLOAT_ARG1,
>> +				      FUNC_FLOAT_ARG2, FUNC_FLOAT_ARG3,
>> +				      FUNC_FLOAT_ARG4, FUNC_FLOAT_ARG5,
>> +				      FUNC_FLOAT_ARG6, FUNC_FLOAT_ARG7);
>> +    if (r != FUNC_FLOAT_RET)
>> +      FAIL_EXIT1 ("tst_audit27_func_float() returned %a, expected %a",
>> +		  r, FUNC_FLOAT_RET);
>> +  }
>> +
>> +  {
>> +    double r = tst_audit27_func_double (FUNC_DOUBLE_ARG0, FUNC_DOUBLE_ARG1,
>> +					FUNC_DOUBLE_ARG2, FUNC_DOUBLE_ARG3,
>> +					FUNC_DOUBLE_ARG4, FUNC_DOUBLE_ARG5,
>> +					FUNC_DOUBLE_ARG6, FUNC_DOUBLE_ARG7);
>> +    if (r != FUNC_DOUBLE_RET)
>> +      FAIL_EXIT1 ("tst_audit27_func_double() returned %la, expected %la",
>> +		  r, FUNC_DOUBLE_RET);
>> +  }
>> +
>> +  {
>> +    long double r = tst_audit27_func_ldouble (FUNC_LDOUBLE_ARG0,
>> +					      FUNC_LDOUBLE_ARG1,
>> +					      FUNC_LDOUBLE_ARG2,
>> +					      FUNC_LDOUBLE_ARG3,
>> +					      FUNC_LDOUBLE_ARG4,
>> +					      FUNC_LDOUBLE_ARG5,
>> +					      FUNC_LDOUBLE_ARG6,
>> +					      FUNC_LDOUBLE_ARG7);
>> +    if (r != FUNC_LDOUBLE_RET)
>> +      FAIL_EXIT1 ("tst_audit27_func_ldouble() returned %La, expected %La",
>> +		  r, FUNC_LDOUBLE_RET);
>> +  }
>> +
>> +  return 0;
> 
> OK. Test float, double, and long double.
> 
>> +}
>> +
>> +#include <support/test-driver.c>
>> diff --git a/sysdeps/aarch64/tst-audit27mod.c b/sysdeps/aarch64/tst-audit27mod.c
>> new file mode 100644
>> index 0000000000..69f1d672b3
>> --- /dev/null
>> +++ b/sysdeps/aarch64/tst-audit27mod.c
>> @@ -0,0 +1,95 @@
>> +/* Check DT_AUDIT for aarch64 ABI specifics.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <array_length.h>
>> +#include <stdlib.h>
>> +#include <support/check.h>
>> +#include "tst-audit27mod.h"
>> +
>> +float
>> +tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4,
>> +			float a5, float a6, float a7)
>> +{
>> +  if (a0 != FUNC_FLOAT_ARG0)
>> +    FAIL_EXIT1 ("a0: %a != %a", a0, FUNC_FLOAT_ARG0);
>> +  if (a1 != FUNC_FLOAT_ARG1)
>> +    FAIL_EXIT1 ("a1: %a != %a", a1, FUNC_FLOAT_ARG1);
>> +  if (a2 != FUNC_FLOAT_ARG2)
>> +    FAIL_EXIT1 ("a2: %a != %a", a2, FUNC_FLOAT_ARG2);
>> +  if (a3 != FUNC_FLOAT_ARG3)
>> +    FAIL_EXIT1 ("a3: %a != %a", a3, FUNC_FLOAT_ARG3);
>> +  if (a4 != FUNC_FLOAT_ARG4)
>> +    FAIL_EXIT1 ("a4: %a != %a", a4, FUNC_FLOAT_ARG4);
>> +  if (a5 != FUNC_FLOAT_ARG5)
>> +    FAIL_EXIT1 ("a5: %a != %a", a5, FUNC_FLOAT_ARG5);
>> +  if (a6 != FUNC_FLOAT_ARG6)
>> +    FAIL_EXIT1 ("a6: %a != %a", a6, FUNC_FLOAT_ARG6);
>> +  if (a7 != FUNC_FLOAT_ARG7)
>> +    FAIL_EXIT1 ("a7: %a != %a", a7, FUNC_FLOAT_ARG7);
>> +
>> +  return FUNC_FLOAT_RET;
>> +}
>> +
>> +double
>> +tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4,
>> +			 double a5, double a6, double a7)
>> +{
>> +  if (a0 != FUNC_DOUBLE_ARG0)
>> +    FAIL_EXIT1 ("a0: %la != %la", a0, FUNC_DOUBLE_ARG0);
>> +  if (a1 != FUNC_DOUBLE_ARG1)
>> +    FAIL_EXIT1 ("a1: %la != %la", a1, FUNC_DOUBLE_ARG1);
>> +  if (a2 != FUNC_DOUBLE_ARG2)
>> +    FAIL_EXIT1 ("a2: %la != %la", a2, FUNC_DOUBLE_ARG2);
>> +  if (a3 != FUNC_DOUBLE_ARG3)
>> +    FAIL_EXIT1 ("a3: %la != %la", a3, FUNC_DOUBLE_ARG3);
>> +  if (a4 != FUNC_DOUBLE_ARG4)
>> +    FAIL_EXIT1 ("a4: %la != %la", a4, FUNC_DOUBLE_ARG4);
>> +  if (a5 != FUNC_DOUBLE_ARG5)
>> +    FAIL_EXIT1 ("a5: %la != %la", a5, FUNC_DOUBLE_ARG5);
>> +  if (a6 != FUNC_DOUBLE_ARG6)
>> +    FAIL_EXIT1 ("a6: %la != %la", a6, FUNC_DOUBLE_ARG6);
>> +  if (a7 != FUNC_DOUBLE_ARG7)
>> +    FAIL_EXIT1 ("a7: %la != %la", a7, FUNC_DOUBLE_ARG7);
>> +
>> +  return FUNC_DOUBLE_RET;
>> +}
>> +
>> +long double
>> +tst_audit27_func_ldouble (long double a0, long double a1, long double a2,
>> +			  long double a3, long double a4, long double a5,
>> +			  long double a6, long double a7)
>> +{
>> +  if (a0 != FUNC_LDOUBLE_ARG0)
>> +    FAIL_EXIT1 ("a0: %La != %La", a0, FUNC_LDOUBLE_ARG0);
>> +  if (a1 != FUNC_LDOUBLE_ARG1)
>> +    FAIL_EXIT1 ("a1: %La != %La", a1, FUNC_LDOUBLE_ARG1);
>> +  if (a2 != FUNC_LDOUBLE_ARG2)
>> +    FAIL_EXIT1 ("a2: %La != %La", a2, FUNC_LDOUBLE_ARG2);
>> +  if (a3 != FUNC_LDOUBLE_ARG3)
>> +    FAIL_EXIT1 ("a3: %La != %La", a3, FUNC_LDOUBLE_ARG3);
>> +  if (a4 != FUNC_LDOUBLE_ARG4)
>> +    FAIL_EXIT1 ("a4: %La != %La", a4, FUNC_LDOUBLE_ARG4);
>> +  if (a5 != FUNC_LDOUBLE_ARG5)
>> +    FAIL_EXIT1 ("a5: %La != %La", a5, FUNC_LDOUBLE_ARG5);
>> +  if (a6 != FUNC_LDOUBLE_ARG6)
>> +    FAIL_EXIT1 ("a6: %La != %La", a6, FUNC_LDOUBLE_ARG6);
>> +  if (a7 != FUNC_LDOUBLE_ARG7)
>> +    FAIL_EXIT1 ("a7: %La != %La", a7, FUNC_LDOUBLE_ARG7);
>> +
>> +  return FUNC_LDOUBLE_RET;
>> +}
> 
> OK.
> 
>> diff --git a/sysdeps/aarch64/tst-audit27mod.h b/sysdeps/aarch64/tst-audit27mod.h
>> new file mode 100644
>> index 0000000000..698df4d44f
>> --- /dev/null
>> +++ b/sysdeps/aarch64/tst-audit27mod.h
>> @@ -0,0 +1,67 @@
>> +/* Check DT_AUDIT for aarch64 specific ABI.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#ifndef _TST_AUDIT27MOD_H
>> +#define _TST_AUDIT27MOD_H 1
>> +
>> +#include <float.h>
>> +
>> +#define FUNC_FLOAT_ARG0 FLT_MIN
>> +#define FUNC_FLOAT_ARG1 FLT_MAX
>> +#define FUNC_FLOAT_ARG2 FLT_EPSILON
>> +#define FUNC_FLOAT_ARG3 FLT_TRUE_MIN
>> +#define FUNC_FLOAT_ARG4 0.0f
>> +#define FUNC_FLOAT_ARG5 1.0f
>> +#define FUNC_FLOAT_ARG6 2.0f
>> +#define FUNC_FLOAT_ARG7 3.0f
>> +#define FUNC_FLOAT_RET  4.0f
>> +
>> +float
>> +tst_audit27_func_float (float a0, float a1, float a2, float a3, float a4,
>> +			float a5, float a6, float a7);
>> +
>> +#define FUNC_DOUBLE_ARG0 DBL_MIN
>> +#define FUNC_DOUBLE_ARG1 DBL_MAX
>> +#define FUNC_DOUBLE_ARG2 DBL_EPSILON
>> +#define FUNC_DOUBLE_ARG3 DBL_TRUE_MIN
>> +#define FUNC_DOUBLE_ARG4 0.0
>> +#define FUNC_DOUBLE_ARG5 1.0
>> +#define FUNC_DOUBLE_ARG6 2.0
>> +#define FUNC_DOUBLE_ARG7 3.0
>> +#define FUNC_DOUBLE_RET  0x1.fffffe0000001p+127
>> +
>> +double
>> +tst_audit27_func_double (double a0, double a1, double a2, double a3, double a4,
>> +			 double a5, double a6, double a7);
>> +
>> +#define FUNC_LDOUBLE_ARG0 DBL_MAX + 1.0L
>> +#define FUNC_LDOUBLE_ARG1 DBL_MAX + 2.0L
>> +#define FUNC_LDOUBLE_ARG2 DBL_MAX + 3.0L
>> +#define FUNC_LDOUBLE_ARG3 DBL_MAX + 4.0L
>> +#define FUNC_LDOUBLE_ARG4 DBL_MAX + 5.0L
>> +#define FUNC_LDOUBLE_ARG5 DBL_MAX + 6.0L
>> +#define FUNC_LDOUBLE_ARG6 DBL_MAX + 7.0L
>> +#define FUNC_LDOUBLE_ARG7 DBL_MAX + 8.0L
>> +#define FUNC_LDOUBLE_RET  0x1.fffffffffffff000000000000001p+1023L
>> +
>> +long double
>> +tst_audit27_func_ldouble (long double a0, long double a1, long double a2,
>> +			  long double a3, long double a4, long double a5,
>> +			  long double a6, long double a7);
>> +
>> +#endif
> 
> OK.
> 
>> diff --git a/sysdeps/aarch64/tst-auditmod26.c b/sysdeps/aarch64/tst-auditmod26.c
>> new file mode 100644
>> index 0000000000..91d224dfbe
>> --- /dev/null
>> +++ b/sysdeps/aarch64/tst-auditmod26.c
>> @@ -0,0 +1,103 @@
>> +/* Check DT_AUDIT for aarch64 specific ABI.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ok.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <assert.h>
>> +#include <link.h>
>> +#include <string.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include "tst-audit26mod.h"
>> +
>> +#define TEST_NAME  "tst-audit26"
>> +
>> +#define AUDIT26_COOKIE 0
>> +
>> +unsigned int
>> +la_version (unsigned int v)
>> +{
>> +  return v;
> 
> OK. Always works :}
> 
>> +}
>> +
>> +unsigned int
>> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
>> +{
>> +  const char *p = strrchr (map->l_name, '/');
>> +  const char *l_name = p == NULL ? map->l_name : p + 1;
>> +  uintptr_t ck = -1;
>> +  if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
>> +    ck = AUDIT26_COOKIE;
>> +  *cookie = ck;
>> +  printf ("objopen: %ld, %s [cookie=%ld]\n", lmid, l_name, ck);
>> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
>> +}
>> +
>> +ElfW(Addr)
>> +la_aarch64_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)),
>> +                         unsigned int ndx __attribute__ ((unused)),
>> +                         uintptr_t *refcook, uintptr_t *defcook,
>> +                         La_aarch64_regs *regs, unsigned int *flags,
>> +                         const char *symname, long int *framesizep)
>> +{
>> +  printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
>> +	  symname, (long int) sym->st_value, ndx, *flags);
>> +
>> +  if (strcmp (symname, "tst_audit26_func") == 0)
>> +    {
>> +      assert (regs->lr_xreg[0] == ARG1);
>> +      assert (regs->lr_xreg[1] == ARG2);
>> +      assert (regs->lr_xreg[2] == ARG3);
> 
> OK.
> 
>> +    }
>> +  else
>> +    abort ();
>> +
>> +  assert (regs->lr_vpcs == 0);
>> +
>> +  /* Clobber 'x8'.  */
>> +  asm volatile ("mov x8, -1" : : : "x8");
>> +
>> +  *framesizep = 1024;
>> +
>> +  return sym->st_value;
>> +}
>> +
>> +unsigned int
>> +la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
>> +                        uintptr_t *defcook,
>> +                        const struct La_aarch64_regs *inregs,
>> +                        struct La_aarch64_retval *outregs, const char *symname)
>> +{
>> +  printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n",
>> +	  symname, (long int) sym->st_value, ndx);
>> +
>> +  if (strcmp (symname, "tst_audit26_func") == 0)
>> +    {
>> +      assert (inregs->lr_xreg[0] == ARG1);
>> +      assert (inregs->lr_xreg[1] == ARG2);
>> +      assert (inregs->lr_xreg[2] == ARG3);
> 
> OK.
> 
>> +    }
>> +  else
>> +    abort ();
>> +
>> +  assert (inregs->lr_vpcs == 0);
>> +  assert (outregs->lrv_vpcs == 0);
>> +
>> +  /* Clobber 'x8'.  */
>> +  asm volatile ("mov x8, -1" : : : "x8");
> 
> OK.
> 
>> +
>> +  return 0;
>> +}
>> diff --git a/sysdeps/aarch64/tst-auditmod27.c b/sysdeps/aarch64/tst-auditmod27.c
>> new file mode 100644
>> index 0000000000..57936d7e70
>> --- /dev/null
>> +++ b/sysdeps/aarch64/tst-auditmod27.c
>> @@ -0,0 +1,180 @@
>> +/* Check DT_AUDIT for aarch64 specific ABI.
> 
> s/DT_AUDIT/LD_AUDIT/g

Ack.

> 
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +#include <assert.h>
>> +#include <link.h>
>> +#include <string.h>
>> +#include <stddef.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include "tst-audit27mod.h"
>> +
>> +#define TEST_NAME  "tst-audit27"
>> +
>> +#define AUDIT27_COOKIE 0
>> +
>> +unsigned int
>> +la_version (unsigned int v)
>> +{
>> +  return v;
> 
> OK.
> 
>> +}
>> +
>> +unsigned int
>> +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
>> +{
>> +  const char *p = strrchr (map->l_name, '/');
>> +  const char *l_name = p == NULL ? map->l_name : p + 1;
>> +  uintptr_t ck = -1;
>> +  if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
>> +    ck = AUDIT27_COOKIE;
>> +  *cookie = ck;
>> +  printf ("objopen: %ld, %s [%ld]\n", lmid, l_name, ck);
>> +  return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
>> +}
>> +
>> +ElfW(Addr)
>> +la_aarch64_gnu_pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
>> +			 uintptr_t *defcook, La_aarch64_regs *regs,
>> +			 unsigned int *flags, const char *symname,
>> +			 long int *framesizep)
>> +{
>> +  printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
>> +	  symname, (long int) sym->st_value, ndx, *flags);
>> +
>> +  if (strcmp (symname, "tst_audit27_func_float") == 0)
>> +    {
>> +      assert (regs->lr_vreg[0].s == FUNC_FLOAT_ARG0);
>> +      assert (regs->lr_vreg[1].s == FUNC_FLOAT_ARG1);
>> +      assert (regs->lr_vreg[2].s == FUNC_FLOAT_ARG2);
>> +      assert (regs->lr_vreg[3].s == FUNC_FLOAT_ARG3);
>> +      assert (regs->lr_vreg[4].s == FUNC_FLOAT_ARG4);
>> +      assert (regs->lr_vreg[5].s == FUNC_FLOAT_ARG5);
>> +      assert (regs->lr_vreg[6].s == FUNC_FLOAT_ARG6);
>> +      assert (regs->lr_vreg[7].s == FUNC_FLOAT_ARG7);
> 
> OK.
> 
>> +    }
>> +  else if (strcmp (symname, "tst_audit27_func_double") == 0)
>> +    {
>> +      assert (regs->lr_vreg[0].d == FUNC_DOUBLE_ARG0);
>> +      assert (regs->lr_vreg[1].d == FUNC_DOUBLE_ARG1);
>> +      assert (regs->lr_vreg[2].d == FUNC_DOUBLE_ARG2);
>> +      assert (regs->lr_vreg[3].d == FUNC_DOUBLE_ARG3);
>> +      assert (regs->lr_vreg[4].d == FUNC_DOUBLE_ARG4);
>> +      assert (regs->lr_vreg[5].d == FUNC_DOUBLE_ARG5);
>> +      assert (regs->lr_vreg[6].d == FUNC_DOUBLE_ARG6);
>> +      assert (regs->lr_vreg[7].d == FUNC_DOUBLE_ARG7);
> 
> OK.
> 
>> +    }
>> +  else if (strcmp (symname, "tst_audit27_func_ldouble") == 0)
>> +    {
>> +      assert (regs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0);
>> +      assert (regs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1);
>> +      assert (regs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2);
>> +      assert (regs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3);
>> +      assert (regs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4);
>> +      assert (regs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5);
>> +      assert (regs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6);
>> +      assert (regs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7);
> 
> OK.
> 
>> +    }
>> +  else
>> +    abort ();
>> +
>> +  assert (regs->lr_vpcs == 0);
>> +
>> +  /* Clobber the q registers on exit.  */
>> +  uint8_t v = 0xff;
>> +  asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0");
>> +  asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v1");
>> +  asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2");
>> +  asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3");
>> +  asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4");
>> +  asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5");
>> +  asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6");
>> +  asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7");
> 
> OK.
> 
>> +
>> +  *framesizep = 1024;
>> +
>> +  return sym->st_value;
>> +}
>> +
>> +unsigned int
>> +la_aarch64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
>> +                        uintptr_t *defcook,
>> +			const struct La_aarch64_regs *inregs,
>> +                        struct La_aarch64_retval *outregs,
>> +			const char *symname)
>> +{
>> +  printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u\n",
>> +	  symname, (long int) sym->st_value, ndx);
>> +
>> +  if (strcmp (symname, "tst_audit27_func_float") == 0)
>> +    {
>> +      assert (inregs->lr_vreg[0].s == FUNC_FLOAT_ARG0);
>> +      assert (inregs->lr_vreg[1].s == FUNC_FLOAT_ARG1);
>> +      assert (inregs->lr_vreg[2].s == FUNC_FLOAT_ARG2);
>> +      assert (inregs->lr_vreg[3].s == FUNC_FLOAT_ARG3);
>> +      assert (inregs->lr_vreg[4].s == FUNC_FLOAT_ARG4);
>> +      assert (inregs->lr_vreg[5].s == FUNC_FLOAT_ARG5);
>> +      assert (inregs->lr_vreg[6].s == FUNC_FLOAT_ARG6);
>> +      assert (inregs->lr_vreg[7].s == FUNC_FLOAT_ARG7);
>> +
>> +      assert (outregs->lrv_vreg[0].s == FUNC_FLOAT_RET);
>> +    }
>> +  else if (strcmp (symname, "tst_audit27_func_double") == 0)
>> +    {
>> +      assert (inregs->lr_vreg[0].d == FUNC_DOUBLE_ARG0);
>> +      assert (inregs->lr_vreg[1].d == FUNC_DOUBLE_ARG1);
>> +      assert (inregs->lr_vreg[2].d == FUNC_DOUBLE_ARG2);
>> +      assert (inregs->lr_vreg[3].d == FUNC_DOUBLE_ARG3);
>> +      assert (inregs->lr_vreg[4].d == FUNC_DOUBLE_ARG4);
>> +      assert (inregs->lr_vreg[5].d == FUNC_DOUBLE_ARG5);
>> +      assert (inregs->lr_vreg[6].d == FUNC_DOUBLE_ARG6);
>> +      assert (inregs->lr_vreg[7].d == FUNC_DOUBLE_ARG7);
>> +
>> +      assert (outregs->lrv_vreg[0].d == FUNC_DOUBLE_RET);
>> +    }
>> +  else if (strcmp (symname, "tst_audit27_func_ldouble") == 0)
>> +    {
>> +      assert (inregs->lr_vreg[0].q == FUNC_LDOUBLE_ARG0);
>> +      assert (inregs->lr_vreg[1].q == FUNC_LDOUBLE_ARG1);
>> +      assert (inregs->lr_vreg[2].q == FUNC_LDOUBLE_ARG2);
>> +      assert (inregs->lr_vreg[3].q == FUNC_LDOUBLE_ARG3);
>> +      assert (inregs->lr_vreg[4].q == FUNC_LDOUBLE_ARG4);
>> +      assert (inregs->lr_vreg[5].q == FUNC_LDOUBLE_ARG5);
>> +      assert (inregs->lr_vreg[6].q == FUNC_LDOUBLE_ARG6);
>> +      assert (inregs->lr_vreg[7].q == FUNC_LDOUBLE_ARG7);
>> +
>> +      assert (outregs->lrv_vreg[0].q == FUNC_LDOUBLE_RET);
>> +    }
>> +  else
>> +    abort ();
>> +
>> +  assert (inregs->lr_vpcs == 0);
>> +  assert (outregs->lrv_vpcs == 0);
>> +
>> +  /* Clobber the q registers on exit.  */
>> +  uint8_t v = 0xff;
>> +  asm volatile ("dup v0.8b, %w0" : : "r" (v) : "v0");
>> +  asm volatile ("dup v1.8b, %w0" : : "r" (v) : "v1");
>> +  asm volatile ("dup v2.8b, %w0" : : "r" (v) : "v2");
>> +  asm volatile ("dup v3.8b, %w0" : : "r" (v) : "v3");
>> +  asm volatile ("dup v4.8b, %w0" : : "r" (v) : "v4");
>> +  asm volatile ("dup v5.8b, %w0" : : "r" (v) : "v5");
>> +  asm volatile ("dup v6.8b, %w0" : : "r" (v) : "v6");
>> +  asm volatile ("dup v7.8b, %w0" : : "r" (v) : "v7");
> 
> OK.
> 
>> +
>> +  return 0;
>> +}
>> diff --git a/sysdeps/generic/dl-audit-check.h b/sysdeps/generic/dl-audit-check.h
>> new file mode 100644
>> index 0000000000..3ab7653286
>> --- /dev/null
>> +++ b/sysdeps/generic/dl-audit-check.h
>> @@ -0,0 +1,23 @@
>> +/* rtld-audit version check.  Generic version.
>> +   Copyright (C) 2022 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/>.  */
>> +
>> +static inline bool
>> +_dl_audit_check_version (unsigned int lav)
>> +{
>> +  return lav <= LAV_CURRENT;
>> +}
> 
> OK. For non-aarch64 the older versions are compatible.
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2022-02-01 14:11 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-25 18:36 [PATCH v12 0/4] Multiple rtld-audit fixes Adhemerval Zanella
2022-01-25 18:36 ` [PATCH v12 1/4] elf: Add la_activity during application exit Adhemerval Zanella
2022-01-26 11:42   ` Florian Weimer
2022-01-26 12:18     ` Adhemerval Zanella
2022-01-26 12:25       ` Florian Weimer
2022-02-01  4:21   ` Carlos O'Donell
2022-02-01 13:30     ` Adhemerval Zanella
2022-01-25 18:36 ` [PATCH v12 2/4] elf: Fix initial-exec TLS access on audit modules (BZ #28096) Adhemerval Zanella
2022-02-01  5:29   ` Carlos O'Donell
2022-02-01 13:35     ` Adhemerval Zanella
2022-01-25 18:36 ` [PATCH v12 3/4] elf: Issue la_symbind for bind-now (BZ #23734) Adhemerval Zanella
2022-02-01  6:06   ` Carlos O'Donell
2022-02-01 13:47     ` Adhemerval Zanella
2022-01-25 18:37 ` [PATCH v12 4/4] elf: Fix runtime linker auditing on aarch64 (BZ #26643) Adhemerval Zanella
2022-02-01  6:19   ` Carlos O'Donell
2022-02-01 14:11     ` Adhemerval Zanella
2022-02-01  6:45 ` [PATCH v12 0/4] Multiple rtld-audit fixes Carlos O'Donell
2022-02-01  7:53   ` John Mellor-Crummey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).