From: "Vivek Das Mohapatra" <vivek@collabora.com>
To: libc-alpha@sourceware.org
Subject: [RFC][PATCH v8 19/20] Add dlmopen / RTLD_SHARED tests
Date: Tue, 9 Feb 2021 17:18:38 +0000 [thread overview]
Message-ID: <20210209171839.7911-20-vivek@collabora.com> (raw)
In-Reply-To: <20210209171839.7911-1-vivek@collabora.com>
---
elf/Makefile | 97 ++-
elf/tst-dlmopen-auditmod.c | 23 +
elf/tst-dlmopen-common.h | 33 +
elf/tst-dlmopen-main.h | 1022 ++++++++++++++++++++++++++
elf/tst-dlmopen-modules.h | 20 +
elf/tst-dlmopen-rtld-audit-shared1.c | 11 +
elf/tst-dlmopen-rtld-audit-shared2.c | 11 +
elf/tst-dlmopen-rtld-audit-shared3.c | 11 +
elf/tst-dlmopen-rtld-audit-shared4.c | 11 +
elf/tst-dlmopen-rtld-audit-shared5.c | 11 +
elf/tst-dlmopen-rtld-audit-shared6.c | 11 +
elf/tst-dlmopen-rtld-audit-unique1.c | 11 +
elf/tst-dlmopen-rtld-audit-unique2.c | 11 +
elf/tst-dlmopen-rtld-audit-unique3.c | 11 +
elf/tst-dlmopen-rtld-audit-unique4.c | 11 +
elf/tst-dlmopen-rtld-audit-unique5.c | 11 +
elf/tst-dlmopen-rtld-audit-unique6.c | 11 +
elf/tst-dlmopen-rtld-shared1.c | 11 +
elf/tst-dlmopen-rtld-shared1.h | 65 ++
elf/tst-dlmopen-rtld-shared2.c | 11 +
elf/tst-dlmopen-rtld-shared2.h | 67 ++
elf/tst-dlmopen-rtld-shared3.c | 11 +
elf/tst-dlmopen-rtld-shared3.h | 44 ++
elf/tst-dlmopen-rtld-shared4.c | 11 +
elf/tst-dlmopen-rtld-shared4.h | 15 +
elf/tst-dlmopen-rtld-shared5.c | 11 +
elf/tst-dlmopen-rtld-shared5.h | 26 +
elf/tst-dlmopen-rtld-shared6.c | 11 +
elf/tst-dlmopen-rtld-shared6.h | 37 +
elf/tst-dlmopen-rtld-unique1.c | 11 +
elf/tst-dlmopen-rtld-unique1.h | 87 +++
elf/tst-dlmopen-rtld-unique2.c | 11 +
elf/tst-dlmopen-rtld-unique2.h | 26 +
elf/tst-dlmopen-rtld-unique3.c | 11 +
elf/tst-dlmopen-rtld-unique3.h | 14 +
elf/tst-dlmopen-rtld-unique4.c | 11 +
elf/tst-dlmopen-rtld-unique4.h | 15 +
elf/tst-dlmopen-rtld-unique5.c | 11 +
elf/tst-dlmopen-rtld-unique5.h | 59 ++
elf/tst-dlmopen-rtld-unique6.c | 11 +
elf/tst-dlmopen-rtld-unique6.h | 52 ++
elf/tst-dlmopen-sharedmod-norm.c | 11 +
elf/tst-dlmopen-sharedmod-uniq.c | 11 +
elf/tst-dlmopen-std-do-test.h | 11 +
44 files changed, 1998 insertions(+), 1 deletion(-)
create mode 100644 elf/tst-dlmopen-auditmod.c
create mode 100644 elf/tst-dlmopen-common.h
create mode 100644 elf/tst-dlmopen-main.h
create mode 100644 elf/tst-dlmopen-modules.h
create mode 100644 elf/tst-dlmopen-rtld-audit-shared1.c
create mode 100644 elf/tst-dlmopen-rtld-audit-shared2.c
create mode 100644 elf/tst-dlmopen-rtld-audit-shared3.c
create mode 100644 elf/tst-dlmopen-rtld-audit-shared4.c
create mode 100644 elf/tst-dlmopen-rtld-audit-shared5.c
create mode 100644 elf/tst-dlmopen-rtld-audit-shared6.c
create mode 100644 elf/tst-dlmopen-rtld-audit-unique1.c
create mode 100644 elf/tst-dlmopen-rtld-audit-unique2.c
create mode 100644 elf/tst-dlmopen-rtld-audit-unique3.c
create mode 100644 elf/tst-dlmopen-rtld-audit-unique4.c
create mode 100644 elf/tst-dlmopen-rtld-audit-unique5.c
create mode 100644 elf/tst-dlmopen-rtld-audit-unique6.c
create mode 100644 elf/tst-dlmopen-rtld-shared1.c
create mode 100644 elf/tst-dlmopen-rtld-shared1.h
create mode 100644 elf/tst-dlmopen-rtld-shared2.c
create mode 100644 elf/tst-dlmopen-rtld-shared2.h
create mode 100644 elf/tst-dlmopen-rtld-shared3.c
create mode 100644 elf/tst-dlmopen-rtld-shared3.h
create mode 100644 elf/tst-dlmopen-rtld-shared4.c
create mode 100644 elf/tst-dlmopen-rtld-shared4.h
create mode 100644 elf/tst-dlmopen-rtld-shared5.c
create mode 100644 elf/tst-dlmopen-rtld-shared5.h
create mode 100644 elf/tst-dlmopen-rtld-shared6.c
create mode 100644 elf/tst-dlmopen-rtld-shared6.h
create mode 100644 elf/tst-dlmopen-rtld-unique1.c
create mode 100644 elf/tst-dlmopen-rtld-unique1.h
create mode 100644 elf/tst-dlmopen-rtld-unique2.c
create mode 100644 elf/tst-dlmopen-rtld-unique2.h
create mode 100644 elf/tst-dlmopen-rtld-unique3.c
create mode 100644 elf/tst-dlmopen-rtld-unique3.h
create mode 100644 elf/tst-dlmopen-rtld-unique4.c
create mode 100644 elf/tst-dlmopen-rtld-unique4.h
create mode 100644 elf/tst-dlmopen-rtld-unique5.c
create mode 100644 elf/tst-dlmopen-rtld-unique5.h
create mode 100644 elf/tst-dlmopen-rtld-unique6.c
create mode 100644 elf/tst-dlmopen-rtld-unique6.h
create mode 100644 elf/tst-dlmopen-sharedmod-norm.c
create mode 100644 elf/tst-dlmopen-sharedmod-uniq.c
create mode 100644 elf/tst-dlmopen-std-do-test.h
diff --git a/elf/Makefile b/elf/Makefile
index 16c89b6d07..bccf31b1a9 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -196,6 +196,38 @@ static-dlopen-environment = \
tst-tls9-static-ENV = $(static-dlopen-environment)
tst-single_threaded-static-dlopen-ENV = $(static-dlopen-environment)
+dlmopen-rtld-tests-norm := \
+ tst-dlmopen-rtld-shared1 \
+ tst-dlmopen-rtld-shared2 \
+ tst-dlmopen-rtld-shared3 \
+ tst-dlmopen-rtld-shared4 \
+ tst-dlmopen-rtld-shared5 \
+ tst-dlmopen-rtld-shared6
+
+dlmopen-rtld-tests-uniq := \
+ tst-dlmopen-rtld-unique1 \
+ tst-dlmopen-rtld-unique2 \
+ tst-dlmopen-rtld-unique3 \
+ tst-dlmopen-rtld-unique4 \
+ tst-dlmopen-rtld-unique5 \
+ tst-dlmopen-rtld-unique6
+
+dlmopen-rtld-audit-tests-norm := \
+ tst-dlmopen-rtld-audit-shared1 \
+ tst-dlmopen-rtld-audit-shared2 \
+ tst-dlmopen-rtld-audit-shared3 \
+ tst-dlmopen-rtld-audit-shared4 \
+ tst-dlmopen-rtld-audit-shared5 \
+ tst-dlmopen-rtld-audit-shared6
+
+dlmopen-rtld-audit-tests-uniq := \
+ tst-dlmopen-rtld-audit-unique1 \
+ tst-dlmopen-rtld-audit-unique2 \
+ tst-dlmopen-rtld-audit-unique3 \
+ tst-dlmopen-rtld-audit-unique4 \
+ tst-dlmopen-rtld-audit-unique5 \
+ tst-dlmopen-rtld-audit-unique6
+
tests += restest1 preloadtest loadfail multiload origtest resolvfail \
constload1 order noload filter \
reldep reldep2 reldep3 reldep4 nodelete nodelete2 \
@@ -225,7 +257,11 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-audit14 tst-audit15 tst-audit16 \
tst-single_threaded tst-single_threaded-pthread \
tst-tls-ie tst-tls-ie-dlmopen argv0test \
- tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask
+ tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
+ $(dlmopen-rtld-tests-norm) \
+ $(dlmopen-rtld-tests-uniq) \
+ $(dlmopen-rtld-audit-tests-norm) \
+ $(dlmopen-rtld-audit-tests-uniq)
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -286,6 +322,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
$(modules-execstack-$(have-z-execstack)) \
tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
tst-dlmopen1mod tst-auditmod1 \
+ tst-dlmopen-sharedmod-norm \
+ tst-dlmopen-sharedmod-uniq \
+ tst-dlmopen-auditmod \
unload3mod1 unload3mod2 unload3mod3 unload3mod4 \
unload4mod1 unload4mod2 unload4mod3 unload4mod4 \
unload6mod1 unload6mod2 unload6mod3 \
@@ -325,6 +364,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \
tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
+ tst-dlmopen-auditmod \
tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \
@@ -823,6 +863,9 @@ tst-nodelete-uniquemod.so-no-z-defs = yes
tst-nodelete-rtldmod.so-no-z-defs = yes
tst-nodelete-zmod.so-no-z-defs = yes
tst-nodelete2mod.so-no-z-defs = yes
+tst-dlmopen-sharedmod-norm.so-no-z-defs = yes
+tst-dlmopen-sharedmod-uniq.so-no-z-defs = yes
+tst-dlmopen-auditmod.so-no-z-defs = yes
ifeq ($(build-shared),yes)
# Build all the modules even when not actually running test programs.
@@ -1301,6 +1344,58 @@ $(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so
$(objpfx)tst-dlmopen3: $(libdl)
$(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
+LDFLAGS-tst-dlmopen-sharedmod-uniq.so = -Wl,-z,unique
+$(objpfx)tst-dlmopen-sharedmod-norm.so: $(libdl)
+$(objpfx)tst-dlmopen-sharedmod-uniq.so: $(libdl)
+$(objpfx)tst-dlmopen-auditmod.so: $(libdl)
+
+dlmopen-rtld-tests-norm-executables := \
+ $(foreach x,$(dlmopen-rtld-tests-norm),$(objpfx)$(x))
+dlmopen-rtld-tests-norm-out := \
+ $(foreach x,$(dlmopen-rtld-tests-norm),$(objpfx)$(x).out)
+
+dlmopen-rtld-tests-uniq-executables := \
+ $(foreach x,$(dlmopen-rtld-tests-uniq),$(objpfx)$(x))
+dlmopen-rtld-tests-uniq-out := \
+ $(foreach x,$(dlmopen-rtld-tests-uniq),$(objpfx)$(x).out)
+
+dlmopen-rtld-audit-tests-norm-executables := \
+ $(foreach x,$(dlmopen-rtld-audit-tests-norm),$(objpfx)$(x))
+dlmopen-rtld-audit-tests-norm-out := \
+ $(foreach x,$(dlmopen-rtld-audit-tests-norm),$(objpfx)$(x).out)
+
+dlmopen-rtld-audit-tests-uniq-executables := \
+ $(foreach x,$(dlmopen-rtld-audit-tests-uniq),$(objpfx)$(x))
+dlmopen-rtld-audit-tests-uniq-out := \
+ $(foreach x,$(dlmopen-rtld-audit-tests-uniq),$(objpfx)$(x).out)
+
+$(dlmopen-rtld-tests-norm-executables): $(libdl)
+$(dlmopen-rtld-tests-norm-out): $(objpfx)tst-dlmopen-sharedmod-norm.so
+
+$(dlmopen-rtld-tests-uniq-executables): $(libdl)
+$(dlmopen-rtld-tests-uniq-out): $(objpfx)tst-dlmopen-sharedmod-uniq.so
+
+
+$(dlmopen-rtld-audit-tests-norm-executables): $(libdl)
+$(dlmopen-rtld-audit-tests-norm-out): $(objpfx)tst-dlmopen-sharedmod-norm.so
+$(dlmopen-rtld-audit-tests-norm-out): $(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-shared1-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-shared2-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-shared3-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-shared4-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-shared5-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-shared6-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+
+$(dlmopen-rtld-audit-tests-uniq-executables): $(libdl)
+$(dlmopen-rtld-audit-tests-uniq-out): $(objpfx)tst-dlmopen-sharedmod-uniq.so
+$(dlmopen-rtld-audit-tests-uniq-out): $(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-unique1-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-unique2-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-unique3-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-unique4-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-unique5-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+tst-dlmopen-rtld-audit-unique6-ENV = LD_AUDIT=$(objpfx)tst-dlmopen-auditmod.so
+
$(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so
tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
diff --git a/elf/tst-dlmopen-auditmod.c b/elf/tst-dlmopen-auditmod.c
new file mode 100644
index 0000000000..04457249d0
--- /dev/null
+++ b/elf/tst-dlmopen-auditmod.c
@@ -0,0 +1,23 @@
+/* Audit module for tst-dlmopen-rtld-audit-*
+ Copyright © 2020 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/>. */
+
+unsigned int
+la_version (unsigned int version)
+{
+ return version;
+}
diff --git a/elf/tst-dlmopen-common.h b/elf/tst-dlmopen-common.h
new file mode 100644
index 0000000000..5653c9c02c
--- /dev/null
+++ b/elf/tst-dlmopen-common.h
@@ -0,0 +1,33 @@
+#pragma once
+
+/* Common infrastructure for tst-dlmopen-rtld-*
+ Copyright © 2020 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 <stdio.h>
+#include <string.h>
+#include <gnu/lib-names.h>
+
+typedef struct
+{
+ const char *name;
+ void *free;
+} dlmopen_testresult;
+
+typedef dlmopen_testresult * (*dlmopen_testfunc) (void);
+
diff --git a/elf/tst-dlmopen-main.h b/elf/tst-dlmopen-main.h
new file mode 100644
index 0000000000..2e091e9b8d
--- /dev/null
+++ b/elf/tst-dlmopen-main.h
@@ -0,0 +1,1022 @@
+#pragma once
+
+/* Main infrastructure for tst-dlmopen-rtld-*
+ Copyright © 2020 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/>. */
+
+/* dlmopen ± RTLD_SHARED/RTLD_ISOLATE semantics:
+
+ RTLD_ISOLATE's purpose is to suppress all shared behaviour,
+ mainly used fir LD_AUDIT code paths but available to the user
+ and also useful for constructing test case preconditions.
+
+ dlmopen should have the following behaviour:
+
+ Notation:
+ Number of namespace (+ = make a new one in an empty NS)
+ |
+ [+]X[p] - p indicates a proxy
+ |
+ + → new enry after the dlmopen call
+
+ Need to be able to inspect:
+
+ list of dl handles before we start (base state)
+ list of dl handles after an action in each namespace
+ ns of a given dl handle
+ _real_ ns of a given handle (ie where does a proxy point)
+
+ Target is a normal DSO:
+ Before | Target NS | RTLD Flags | After | handle NS | libc NS
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-shared1:
+ -------+-----------+------------+--------+-----------+---------
+ - | 0 | - | +0 | 0 | 0
+ 0 | 0 | - | 0 | 0 | 0
+ 0 | 0 | SHARED | 0 | 0 | 0
+ 0 | + | - | 0,+1 | 1 | 0
+ 0,1 | 0 | - | 0,1 | 0 | 0
+ 0,1 | 0 | SHARED | 0,1 | 0 | 0
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-shared2:
+ -------+-----------+------------+--------+-----------+---------
+ - | 0 | SHARED | +0 | 0 | 0
+ 0 | + | SHARED | 0,+1p | 1p | 0
+ 0,1p | 0 | - | 0,1p | 0 | 0
+ 0,1p | 0 | SHARED | 0,1p | 0 | 0
+ 0,1p | 1 | - | 0,1p | 1p | 0
+ 0,1p | 1 | SHARED | 0,1p | 1p | 0
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-shared3
+ -------+-----------+------------+--------+-----------+---------
+ - | + | - | +1 | 1 | 0
+ 1 | 0 | - | +0,1 | 0 | 0
+ 0,1 | 1 | - | 0,1 | 1 | 0
+ 0,1 | 1 | SHARED | 0,1 | ERR | -
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-shared4
+ -------+-----------+------------+--------+-----------+---------
+ - | + | SHARED | +0,+1p | 1p | 0
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-shared5
+ -------+-----------+------------+--------+-----------+---------
+ 1 | 0 | SHARED | +0,1 | 0 | 0
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-shared6
+ -------+-----------+------------+--------+-----------+---------
+ 1 | 1 | - | 1 | 0 | 0
+ 1 | 1 | SHARED | 1 | ERR | -
+
+ Target is a DF_GNU_1_UNIQUE DSO:
+ Before | Target NS | RTLD Flags | After | handle NS | libc NS
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-unique1:
+ -------+-----------+------------+--------+-----------+---------
+ - | 0 | - | +0 | 0 | 0
+ 0 | 0 | - | 0 | 0 | 0
+ 0 | 0 | SHARED | 0 | 0 | 0
+ 0 | + | - | 0,+1p | 1p | 0
+ 0,1p | 0 | - | 0,1p | 0 | 0
+ 0,1p | 0 | SHARED | 0,1p | 0 | 0
+ 0,1p | 1 | - | 0,1p | 1p | 0
+ 0,1p | 1 | SHARED | 0,1p | 1p | 0
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-unique2:
+ -------+-----------+------------+--------+-----------+---------
+ - | 0 | SHARED | +0 | 0 | 0
+ 0 | + | SHARED | 0,+1p | 1p | 0
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-unique3:
+ -------+-----------+------------+--------+-----------+---------
+ - | + | - | +0,+1p | 1p | 0
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-unique4:
+ -------+-----------+------------+--------+-----------+---------
+ - | + | SHARED | +0,+1p | 1p | 0
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-unique5:
+ -------+-----------+------------+--------+-----------+---------
+ - | + | ISOLATE | +1 | 1 | 1
+ 1 | 0 | - | +0,1 | 0 | 0
+ 0,1 | 0 | - | 0,1 | 0 | 0
+ 0,1 | 0 | SHARED | 0,1 | 0 | 0
+ 0,1 | 1 | - | 0,1 | ERR | -
+ =======+===========+============+========+===========+=========
+ dlmopen-rtld-unique6:
+ -------+-----------+------------+--------+-----------+---------
+ - | +1 | ISOLATE | +1 | 1 | 1
+ 1 | 1 | - | 1 | ERR | -
+ 1 | 1 | SHARED | 1 | ERR | -
+ 1 | 0 | SHARED | +0,1 | 0 | 0
+ 0,1 | 1 | SHARED | 0,1 | ERR | -
+*/
+
+#include "tst-dlmopen-common.h"
+#include <dl-dtprocnum.h>
+#include <link.h>
+
+#define DSO_NORMAL "$ORIGIN/tst-dlmopen-sharedmod-norm.so"
+#define DSO_UNIQUE "$ORIGIN/tst-dlmopen-sharedmod-uniq.so"
+#define DSO_TESTFN "rtld_shared_testfunc"
+#define DSO_NAMESTUB "tst-dlmopen-sharedmod-"
+#define MAX_NS 16
+
+#define END_TESTS { .name = NULL },
+
+#define ERROR(test, fmt, ...) \
+ ({ if (last_test != test) \
+ printf ("FAILED: %s (%s):\n", test->name, test->desc); \
+ printf ("%s @ %d - " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
+ last_test = test; })
+
+static void *last_test;
+
+typedef enum
+ {
+ NONE = 0,
+ DSO = 1,
+ PROXY = 2,
+ NEW = 4,
+ } dso_type;
+
+typedef struct
+{
+ const char *name;
+ const char *desc;
+ int is_prep_stage;
+ const char *dso_name;
+ int failure;
+
+ struct
+ {
+ const char *dso_path;
+ Lmid_t ns;
+ int flags;
+ } args;
+
+ dso_type preloaded[MAX_NS];
+ dso_type loaded[MAX_NS];
+ dso_type handle_type;
+ Lmid_t handle_ns;
+ Lmid_t free_ns;
+} dlmopen_test_spec;
+
+struct r_scope_elem
+{
+ struct tst_lm **r_list;
+ unsigned int r_nlist;
+};
+
+/* This is a copy of the first part of the internal definition of
+ struct link_map from <include/link.h>. We use it to check some
+ expected internal state that's not readily accessible via public APIs.
+ */
+struct tst_lm
+ {
+ /* These first few members are part of the protocol with the debugger.
+ This is the same format used in SVR4. */
+
+ ElfW(Addr) l_addr; /* Difference between the address in the ELF
+ file and the addresses in memory. */
+ char *l_name; /* Absolute file name object was found in. */
+ ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */
+ struct tst_lm *l_next, *l_prev; /* Chain of loaded objects. */
+
+ /* All following members are internal to the dynamic linker.
+ They may change without notice. */
+
+ /* This is an element which is only ever different from a pointer to
+ the very same copy of this type when:
+ - A shallow copy of ld.so is placed in namespaces other than LM_ID_BASE.
+ - An object is proxied into a namespace by dlmopen with RTLD_SHARED. */
+ struct tst_lm *l_real;
+
+ /* Number of the namespace this link map belongs to. */
+ Lmid_t l_ns;
+
+ struct libname_list *l_libname;
+ /* Indexed pointers to dynamic section.
+ [0,DT_NUM) are indexed by the processor-independent tags.
+ [DT_NUM,DT_NUM+DT_THISPROCNUM) are indexed by the tag minus DT_LOPROC.
+ [DT_NUM+DT_THISPROCNUM,DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM) are
+ indexed by DT_VERSIONTAGIDX(tagvalue).
+ [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM,
+ DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM) are indexed by
+ DT_EXTRATAGIDX(tagvalue).
+ [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM,
+ DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM) are
+ indexed by DT_VALTAGIDX(tagvalue) and
+ [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM,
+ DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM+DT_ADDRNUM)
+ are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>. */
+
+ ElfW(Dyn) *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM
+ + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM];
+ const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */
+ ElfW(Addr) l_entry; /* Entry point location. */
+ ElfW(Half) l_phnum; /* Number of program header entries. */
+ ElfW(Half) l_ldnum; /* Number of dynamic segment entries. */
+
+ /* Array of DT_NEEDED dependencies and their dependencies, in
+ dependency order for symbol lookup (with and without
+ duplicates). There is no entry before the dependencies have
+ been loaded. */
+ struct r_scope_elem l_searchlist;
+
+ /* We need a special searchlist to process objects marked with
+ DT_SYMBOLIC. */
+ struct r_scope_elem l_symbolic_searchlist;
+
+ /* Dependent object that first caused this object to be loaded. */
+ struct link_map *l_loader;
+
+ /* Array with version names. */
+ struct r_found_version *l_versions;
+ unsigned int l_nversions;
+
+ /* Symbol hash table. */
+ Elf_Symndx l_nbuckets;
+ Elf32_Word l_gnu_bitmask_idxbits;
+ Elf32_Word l_gnu_shift;
+ const ElfW(Addr) *l_gnu_bitmask;
+ union
+ {
+ const Elf32_Word *l_gnu_buckets;
+ const Elf_Symndx *l_chain;
+ };
+ union
+ {
+ const Elf32_Word *l_gnu_chain_zero;
+ const Elf_Symndx *l_buckets;
+ };
+
+ unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose. */
+ enum /* Where this object came from. */
+ {
+ lt_executable, /* The main executable program. */
+ lt_library, /* Library needed by main executable. */
+ lt_loaded /* Extra run-time loaded shared object. */
+ } l_type:2;
+ unsigned int l_relocated:1; /* Nonzero if object's relocations done. */
+ unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
+ unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
+ unsigned int l_proxy:1; /* Nonzero if object is a shallow copy. */
+ unsigned int l_reserved:2; /* Reserved for internal use. */
+ unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
+ to by `l_phdr' is allocated. */
+ unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in
+ the l_libname list. */
+ unsigned int l_faked:1; /* Nonzero if this is a faked descriptor
+ without associated file. */
+ unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls)
+ should be called on this link map
+ when relocation finishes. */
+ unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing. */
+ unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module
+ is interested in the PLT interception.*/
+ unsigned int l_removed:1; /* Nozero if the object cannot be used anymore
+ since it is removed. */
+ unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
+ mprotected or if no holes are present at
+ all. */
+ unsigned int l_symbolic_in_local_scope:1; /* Nonzero if l_local_scope
+ during LD_TRACE_PRELINKING=1
+ contains any DT_SYMBOLIC
+ libraries. */
+ unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
+ freed, ie. not allocated with
+ the dummy malloc in ld.so. */
+ };
+
+typedef struct { void *handle; Lmid_t ns; } test_handle;
+static test_handle cached_handles[32];
+
+static void
+cache_test_handle (void *handle, Lmid_t ns)
+{
+ int i;
+
+ for (i = 0; i < sizeof(cached_handles)/sizeof(test_handle); i++)
+ if (cached_handles[i].handle == NULL)
+ {
+ cached_handles[i].handle = handle;
+ cached_handles[i].ns = ns;
+ break;
+ }
+}
+
+__attribute__((unused))
+static struct tst_lm *
+link_map_of_dl_handle (void *handle)
+{
+ struct tst_lm *lm = NULL;
+
+ if (dlinfo (handle, RTLD_DI_LINKMAP, &lm) == 0)
+ return lm;
+
+ printf ("dlinfo (LINKMAP) for %s in %s failed: %s\n",
+ LIBC_SO, __func__, dlerror ());
+
+ return NULL;
+}
+
+__attribute__((unused))
+static Lmid_t
+ns_of_dl_handle (void *handle)
+{
+ Lmid_t ns = 0;
+
+ if (dlinfo (handle, RTLD_DI_LMID, &ns) == 0)
+ return ns;
+
+ printf ("dlinfo (LMID) for %s in %s failed: %s\n",
+ LIBC_SO, __func__, dlerror ());
+
+ return -1;
+}
+
+__attribute__((unused))
+static Lmid_t real_ns_of_dl_handle (void *handle)
+{
+ Lmid_t ns = 0;
+ struct tst_lm *lm = link_map_of_dl_handle (handle);
+
+ if (lm == NULL)
+ return -1;
+
+ // printf ("DEBUG: handle %p; LM %p; proxy: %d / %p\n",
+ // handle, lm, lm->l_proxy, lm->l_real);
+
+ if (lm->l_proxy)
+ {
+ // printf ("DEBUG: proxy %p vs real %p\n", lm, lm->l_real);
+ ns = ns_of_dl_handle ((void *) lm->l_real);
+ }
+ else
+ ns = ns_of_dl_handle (handle);
+
+ return ns;
+}
+
+__attribute__((unused))
+static const char *str_soname (const char *name)
+{
+ char *slash = NULL;
+
+ if (name == NULL)
+ return NULL;
+
+ if ((slash = strrchr (name, '/')))
+ return ++slash;
+ else
+ return name;
+}
+
+__attribute__((unused))
+static const char *lm_name (struct tst_lm *lm)
+{
+ if (lm)
+ return lm->l_name;
+
+ return NULL;
+}
+
+
+static int dlm_dso_is_loaded (void *handle)
+{
+ if (handle != RTLD_DEFAULT)
+ {
+#ifdef DEBUG_DSO_LOADCHECK
+ Dl_info sinfo = {};
+#endif
+
+ if (((struct tst_lm *) handle)->l_type != lt_loaded)
+ return 0;
+
+#ifdef DEBUG_DSO_LOADCHECK
+ printf ("checking %p %s for %s\n",
+ handle, ((struct tst_lm *)handle)->l_name, DSO_TESTFN);
+#endif
+
+ void *symbol = dlsym (handle, DSO_TESTFN);
+
+#ifdef DEBUG_DSO_LOADCHECK
+ dladdr (symbol, &sinfo);
+ printf (" -> %s (in %s (%p))\n",
+ sinfo.dli_fname,
+ sinfo.dli_sname,
+ sinfo.dli_saddr);
+#endif
+
+ return symbol ? 1 : 0;
+ }
+
+ for (int i = 0; i < sizeof(cached_handles)/sizeof(test_handle); i++)
+ {
+ if (cached_handles[i].handle == NULL)
+ break;
+
+ if (((struct tst_lm *) cached_handles[i].handle)->l_type != lt_loaded)
+ continue;
+
+#ifdef DEBUG_DSO_LOADCHECK
+ printf ("checking %p %s for %s\n",
+ cached_handles[i].handle,
+ ((struct tst_lm *)cached_handles[i].handle)->l_name,
+ DSO_TESTFN);
+#endif
+
+ if (dlsym (cached_handles[i].handle, DSO_TESTFN) != NULL)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int call_testfunc (dlmopen_test_spec *test, void *handle)
+{
+ Dl_info dli = {};
+ struct tst_lm *lm = NULL;
+ dlmopen_testfunc func = NULL;
+ dlmopen_testresult *result = NULL;
+
+ if (handle != RTLD_DEFAULT)
+ func = dlsym (handle, DSO_TESTFN);
+
+ if (func == NULL)
+ {
+ ERROR (test, "test function %s not found\n", DSO_TESTFN);
+ return 0;
+ }
+
+ result = (func)();
+
+ if (result == NULL)
+ {
+ ERROR (test, "test function %s returned NULL\n", DSO_TESTFN);
+ return 0;
+ }
+
+ dladdr1 (result->free, &dli, (void **)&lm, RTLD_DL_LINKMAP);
+
+ if (lm == NULL)
+ {
+ ERROR (test, "free() implementation from test module is invalid\n");
+ return 0;
+ }
+
+ if (lm->l_ns != test->free_ns)
+ {
+ ERROR (test,
+ "free() function from test module was from ns %d, expected %d\n",
+ (int)lm->l_ns, (int)test->free_ns);
+ return 0;
+ }
+
+ printf ("%s: %s: %s in ns %d using free() from ns %d: OK\n",
+ test->name, test->args.dso_path, DSO_TESTFN,
+ (int)test->handle_ns, (int)lm->l_ns);
+
+ return 1;
+}
+
+static void *link_map_snapshot_array (void *handle, void *func, Lmid_t ns, size_t *len)
+{
+ struct tst_lm *lm = NULL;
+ struct tst_lm *start = NULL;
+
+ if (len)
+ *len = 0;
+
+ if (handle != NULL)
+ {
+ dlinfo (handle, RTLD_DI_LINKMAP, &lm);
+ }
+ else if (func != NULL)
+ {
+ Dl_info dli = {};
+
+ dladdr1 (func, &dli, (void **)&lm, RTLD_DL_LINKMAP);
+ }
+ else if (ns >= LM_ID_BASE)
+ {
+ for (int i = 0; i < sizeof(cached_handles)/sizeof(test_handle); i++)
+ {
+ if (cached_handles[i].handle == NULL)
+ break;
+
+ if (cached_handles[i].ns != ns)
+ continue;
+
+ dlinfo (cached_handles[i].handle, RTLD_DI_LINKMAP, &lm);
+ break;
+ }
+ }
+
+ if (lm == NULL)
+ return NULL;
+
+ start = lm;
+
+ while (start->l_prev)
+ start = start->l_prev;
+
+ size_t lm_size = 0;
+
+ for (lm = start; lm; lm = lm->l_next)
+ lm_size++;
+
+ struct tst_lm **lm_list = calloc (lm_size + 1, sizeof (struct tst_lm *));
+
+ if (len)
+ *len = lm_size;
+
+ int i = 0;
+
+ for (lm = start; lm; lm = lm->l_next)
+ lm_list[i++] = lm;
+ lm_list[i] = NULL;
+
+ return lm_list;
+}
+
+__attribute__((unused))
+static int search_link_map_array (struct tst_lm **lma, size_t len, void *handle)
+{
+ if (lma == NULL)
+ return 0;
+
+ if (len == 0)
+ return 0;
+
+ struct tst_lm *target = link_map_of_dl_handle (handle);
+
+ for (int i = 0; i < len; i++)
+ {
+ //printf ("searching for %p in <%p>[%d] == %p\n",
+ // handle, lma, i, lma[i]);
+ if (handle == (struct tst_lm *)(lma[i]))
+ return 1;
+
+ if (target->l_proxy)
+ if (target->l_real == (struct tst_lm *)(lma[i]))
+ return 1;
+ }
+
+ return 0;
+}
+
+#ifdef DEBUG_DSO_SEARCH
+#define TRACE2(fmt, ...) \
+ printf (" find-test-dso (%s @ %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
+#else
+#define TRACE2(fmt, ...)
+#endif
+
+static struct tst_lm *
+find_test_dso_in_link_map_array (struct tst_lm **lma, size_t len)
+{
+ if (lma == NULL)
+ return NULL;
+
+ if (len == 0)
+ return NULL;
+
+ for (int i = 0; i < len; i++)
+ {
+ if (!lma[i] || !lma[i]->l_name)
+ continue;
+
+ TRACE2 ("%p [%d/%d] %s", lma, i, (int)len - 1,
+ lma[i] ? (lma[i]->l_name ?: "???.so") : "NULL" );
+
+ if (lma[i] && lma[i]->l_name)
+ if (strstr (lma[i]->l_name, DSO_NAMESTUB))
+ if (dlsym (lma[i], DSO_TESTFN) != NULL)
+ return (struct tst_lm *)lma[i];
+ }
+
+ return NULL;
+}
+
+__attribute__((unused))
+static void *link_map_list (void *handle, void *func, int *len, Lmid_t *ns)
+{
+ struct tst_lm *lm = NULL;
+ struct tst_lm *start = NULL;
+
+ if (len)
+ *len = 0;
+
+ if (handle != NULL)
+ {
+ dlinfo (handle, RTLD_DI_LINKMAP, &lm);
+ }
+ else if (func != NULL)
+ {
+ Dl_info dli = {};
+
+ dladdr1 (func, &dli, (void **)&lm, RTLD_DL_LINKMAP);
+ }
+
+ if (lm == NULL)
+ return NULL;
+
+ if (ns)
+ *ns = lm->l_ns;
+
+ // rewind to start of link map list:
+ start = lm;
+
+ while (start->l_prev)
+ start = start->l_prev;
+
+ size_t lm_size = 0;
+
+ for (lm = start; lm; lm = lm->l_next)
+ lm_size++;
+
+ if (len)
+ *len = lm_size;
+
+ return start;
+}
+
+#ifdef DEBUG_DLMOPEN_TEST_WRAPPER
+#define TRACE(fmt, ...) \
+ printf ("%s (%s @ %d): " fmt "\n", test->name, __FILE__, __LINE__, ##__VA_ARGS__)
+#else
+#define TRACE(fmt, ...)
+#endif
+
+static int process_test_spec (dlmopen_test_spec *test)
+{
+ void *handle = NULL;
+ size_t lm_before_len[MAX_NS] = { 0 };
+ size_t lm_after_len[MAX_NS] = { 0 };
+ struct tst_lm **lm_before[MAX_NS] = { NULL };
+ struct tst_lm **lm_after[MAX_NS] = { NULL };
+ struct tst_lm *preloads[MAX_NS] = { NULL };
+ int want_preload = 0;
+ int test_status = 0;
+
+ memset (&lm_after[0], 0, sizeof (lm_after));
+ memset (&lm_before[0], 0, sizeof (lm_before));
+ memset (&preloads[0], 0, sizeof (preloads));
+
+ TRACE("LD_AUDIT = %s", getenv("LD_AUDIT") ?: "-");
+ TRACE("BEFORE SNAPSHOTS: %p", &lm_before[0]);
+ TRACE("AFTER SNAPSHOTS: %p", &lm_after[0]);
+ TRACE("preloads : %p", preloads);
+ TRACE("setup done");
+
+ if (test->args.dso_path && *test->args.dso_path && !test->dso_name)
+ test->dso_name = str_soname (test->args.dso_path);
+
+ TRACE("DSO short name: %s", test->dso_name);
+
+ // get the existing link map contents before the test runs:
+ lm_before[0] = link_map_snapshot_array (NULL, process_test_spec,
+ LM_ID_BASE, &lm_before_len[0]);
+ for (int i = 1; i < MAX_NS; i++)
+ lm_before[i] = link_map_snapshot_array (NULL, NULL, i, &lm_before_len[i]);
+
+ TRACE("link map snapshots cached");
+
+ for (int i = 0; i < MAX_NS; i++)
+ {
+ if (test->preloaded[i] & PROXY)
+ {
+ struct tst_lm **lm = lm_before[i];
+ want_preload++;
+
+ if (lm != NULL)
+ for (int j = 0; !preloads[i] && (j < lm_before_len[i]); j++)
+ if (dlm_dso_is_loaded (lm[j]) && lm[j]->l_proxy)
+ preloads[i] = lm[j];
+
+ if (!preloads[i])
+ {
+ ERROR (test,
+ "needed proxy for %s preloaded in NS %d, not found\n",
+ test->dso_name, i);
+ goto cleanup;
+ }
+ }
+ else if (test->preloaded[i] & DSO)
+ {
+ struct tst_lm **lm = lm_before[i];
+ int lm_max = lm_before_len[i];
+ want_preload++;
+
+ if (lm != NULL)
+ for (int j = 0; !preloads[i] && (j < lm_max); j++)
+ {
+ if (dlm_dso_is_loaded (lm[j]) && !lm[j]->l_proxy)
+ preloads[i] = lm[j];
+ }
+ if (!preloads[i])
+ {
+ ERROR (test,
+ "needed %s preloaded in NS %d, not found\n",
+ test->dso_name, i);
+ goto cleanup;
+ }
+ }
+ }
+ TRACE("preload checks (A)");
+
+ if (dlm_dso_is_loaded (RTLD_DEFAULT))
+ {
+ // test DSO module must _not_ be preloaded, and is:
+ if (!want_preload)
+ {
+ ERROR (test, "DSO %s unexpectedly loaded before test\n", test->dso_name);
+ goto cleanup;
+ }
+ }
+ else
+ {
+ // DSO is not loaded, and must be:
+ // In theory we can never see this error as it
+ // should be caught by the preceding preload loop:
+ if (want_preload)
+ {
+ ERROR (test, "DSO %s must be preloaded (and is not)\n", test->args.dso_path);
+ goto cleanup;
+ }
+ }
+ TRACE("preload checks (B) %s", test->name);
+
+ if (!(test->args.flags & (RTLD_NOW|RTLD_LAZY)))
+ test->args.flags |= RTLD_NOW;
+
+ handle = dlmopen (test->args.ns, test->args.dso_path, test->args.flags);
+ TRACE("dlmopen returned %p", handle);
+
+ if (handle == NULL)
+ {
+ const char *status = "failed";
+
+ if (test->failure)
+ {
+ status = "failed (EXPECTED)";
+ test_status = 1;
+
+ printf ("%s: dlmopen(%s, %d, 0x%0x) failed: OK\n",
+ test->name, test->args.dso_path,
+ (int)test->args.ns, (int)test->args.flags);
+ printf ("Returned: %p\n\n", handle);
+
+ goto cleanup;
+ }
+
+ ERROR (test, "");
+
+ if (test->is_prep_stage)
+ printf ("(during setup of preconditions): ");
+ else
+ printf (": ");
+
+ if (test->args.ns == LM_ID_BASE)
+ printf ("dlmopen (LM_ID_BASE, \"%s\", 0x%x) %s: %s\n",
+ test->args.dso_path, test->args.flags, status, dlerror ());
+ else
+ printf ("dlmopen (%d, \"%s\", 0x%x) %s: %s\n",
+ (int)test->args.ns, test->args.dso_path, test->args.flags, status, dlerror ());
+
+ goto cleanup;
+ }
+ else if (test->failure)
+ {
+ ERROR (test, "dlmopen() call should have failed, but did not\n");
+ goto cleanup;
+ }
+
+ TRACE("return status checked");
+
+ if (!dlm_dso_is_loaded (handle))
+ {
+ ERROR (test, "DSO %s (%p) missing function (%s)\n",
+ test->args.dso_path, handle, DSO_TESTFN);
+ goto cleanup;
+ }
+
+ TRACE ("loaded DSO sanity checked");
+
+ Lmid_t hns = ns_of_dl_handle (handle);
+ Lmid_t real_hns = real_ns_of_dl_handle (handle);
+ Lmid_t proxy_ns = 0;
+
+ call_testfunc (test, handle);
+ TRACE (DSO_TESTFN "called");
+
+ cache_test_handle (handle, hns);
+ TRACE ("handle %p cached (ns %d)", handle, (int)hns);
+
+ // if the real ns was different to the apparent one
+ // then we have a proxy and we need to shuffle the values,
+ // else leave the proxy ns as 0 as an expect.proxy_ns of 0
+ // means we weren't expecting a proxy:
+ if (real_hns != hns)
+ {
+ proxy_ns = hns;
+ hns = real_hns;
+ }
+
+ if (proxy_ns)
+ printf ("Returned: proxy ns:%d (real ns: %d)\n\n", (int)proxy_ns, (int)hns);
+ else
+ printf ("Returned: dso ns:%d\n\n", (int)hns);
+
+ Lmid_t expected;
+ if (test->handle_type & PROXY)
+ expected = proxy_ns;
+ else
+ expected = hns;
+
+ TRACE("check expected ns %d", (int)expected);
+
+ if (test->args.ns == LM_ID_NEWLM)
+ {
+ if (expected <= LM_ID_BASE)
+ {
+ ERROR (test, "DSO should have been in NS > %d, was in %d\n",
+ LM_ID_BASE, (int)expected);
+ goto cleanup;
+ }
+
+ // for any cases where we can't predict
+ // the namespace in advance:
+ if (test->handle_ns == LM_ID_NEWLM)
+ test->handle_ns = expected;
+ }
+ else
+ {
+ if (test->args.ns != expected)
+ {
+ ERROR (test, "DSO should have been in NS %d, was in %d\n",
+ (int)test->args.ns, (int)expected);
+ goto cleanup;
+ }
+ }
+
+ TRACE("ns %d Ok", (int)expected);
+
+ if (test->handle_type & PROXY) // expecting a proxy
+ {
+ if (proxy_ns != 0) // got a proxy
+ {
+ if (test->handle_ns != proxy_ns) // but not in the right place
+ {
+ ERROR (test, "DSO proxy should have been in ns %d, was in %d\n",
+ (int)test->handle_ns, (int)proxy_ns);
+ goto cleanup;
+ }
+ }
+ else // didn't get a proxy
+ {
+ ERROR (test,
+ "DSO should have been a proxy in ns %d,"
+ " was a non-proxy in ns %d\n",
+ (int)test->handle_ns, (int)hns);
+ goto cleanup;
+ }
+ }
+ else // not expecting a proxy
+ {
+ if (proxy_ns > 0)
+ {
+ ERROR (test,
+ "DSO should NOT have been a proxy,"
+ " was a proxy in ns %d (real ns %d)\n",
+ (int)proxy_ns, (int)hns);
+ goto cleanup;
+ }
+
+ if (test->handle_ns != hns)
+ {
+ ERROR (test,
+ "DSO should have been in ns %d,"
+ " was in ns %d\n",
+ (int)test->handle_ns, (int)hns);
+ goto cleanup;
+ }
+ }
+ TRACE ("proxy status Ok");
+
+ // get the new link map contents after the test has run:
+ lm_after[0] = link_map_snapshot_array (NULL, process_test_spec,
+ LM_ID_BASE, &lm_after_len[0]);
+ for (int i = 1; i < MAX_NS; i++)
+ lm_after[i] = link_map_snapshot_array (NULL, NULL, i, &lm_after_len[i]);
+
+ for (int i = 0; i < MAX_NS; i++)
+ {
+ TRACE("checking status of NS %d", i);
+ void *old_handle =
+ find_test_dso_in_link_map_array (lm_before[i], lm_before_len[i]);
+ TRACE ("old handle is %p", old_handle);
+
+ void *new_handle =
+ find_test_dso_in_link_map_array (lm_after[i], lm_after_len[i]);
+ TRACE ("new handle is %p", new_handle);
+
+ if (test->loaded[i] == NONE)
+ {
+ TRACE ("ns %d requirement is NONE", i);
+ if (old_handle != NULL)
+ {
+ ERROR (test,
+ "Unexpected preload DSO %s in ns %d\n",
+ lm_name (old_handle), i);
+ goto cleanup;
+ }
+ if (new_handle != NULL)
+ {
+ ERROR (test, "Unexpected new DSO %s in ns %d\n",
+ lm_name (new_handle), i);
+ goto cleanup;
+ }
+ continue;
+ }
+
+ if (test->loaded[i] & NEW)
+ {
+ TRACE("ns %d requirement is NEW", i);
+ if (old_handle != NULL)
+ {
+ ERROR (test,
+ "DSO in ns %d should have been a new load,"
+ " found to have been preloaded\n", i);
+ goto cleanup;
+ }
+ if (new_handle == NULL)
+ {
+ ERROR (test, "Expected DSO in ns %d, not found\n", i);
+ goto cleanup;
+ }
+ }
+ else
+ {
+ TRACE("ns %d requirement is OLD", i);
+ if (new_handle == NULL)
+ {
+ ERROR (test, "Expected new DSO in ns %d, not found\n", i);
+ goto cleanup;
+ }
+
+ if (old_handle != new_handle)
+ {
+ ERROR (test, "DSO in ns %d changed. This should be impossible, "
+ "sanity check the test code in %s\n", i, __FILE__);
+ goto cleanup;
+ }
+ }
+
+ if (test->loaded[i] & PROXY)
+ {
+ TRACE ("rechecking DSO status in ns %d", i);
+ if (!((struct tst_lm *)new_handle)->l_proxy)
+ {
+ ERROR (test, "DSO in ns %d should be a proxy but is not\n", i);
+ goto cleanup;
+ }
+ }
+ else
+ {
+ TRACE ("rechecking proxy status in ns %d", i);
+ if (((struct tst_lm *)new_handle)->l_proxy)
+ {
+ ERROR (test, "DSO in ns %d should NOT be a proxy but is\n", i);
+ goto cleanup;
+ }
+ }
+ }
+
+ test_status = 1;
+
+ cleanup:
+ for (int i = 0; i < MAX_NS; i++)
+ free (lm_after[i]);
+ for (int i = 0; i < MAX_NS; i++)
+ free (lm_before[i]);
+
+ return test_status;
+}
+
+
diff --git a/elf/tst-dlmopen-modules.h b/elf/tst-dlmopen-modules.h
new file mode 100644
index 0000000000..4bbf431ec3
--- /dev/null
+++ b/elf/tst-dlmopen-modules.h
@@ -0,0 +1,20 @@
+#pragma once
+/* Module-specific infrastructure for tst-dlmopen-rtld-*
+ Copyright © 2020 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 "tst-dlmopen-common.h"
diff --git a/elf/tst-dlmopen-rtld-audit-shared1.c b/elf/tst-dlmopen-rtld-audit-shared1.c
new file mode 100644
index 0000000000..1e9f604327
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-shared1.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-shared1.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-shared2.c b/elf/tst-dlmopen-rtld-audit-shared2.c
new file mode 100644
index 0000000000..53064dd345
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-shared2.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-shared2.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-shared3.c b/elf/tst-dlmopen-rtld-audit-shared3.c
new file mode 100644
index 0000000000..de90bc1258
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-shared3.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-shared3.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-shared4.c b/elf/tst-dlmopen-rtld-audit-shared4.c
new file mode 100644
index 0000000000..c600b2f4dc
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-shared4.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-shared4.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-shared5.c b/elf/tst-dlmopen-rtld-audit-shared5.c
new file mode 100644
index 0000000000..cd223d041b
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-shared5.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-shared5.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-shared6.c b/elf/tst-dlmopen-rtld-audit-shared6.c
new file mode 100644
index 0000000000..f84303b1b4
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-shared6.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-shared6.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-unique1.c b/elf/tst-dlmopen-rtld-audit-unique1.c
new file mode 100644
index 0000000000..f60b9c05d4
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-unique1.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-unique1.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-unique2.c b/elf/tst-dlmopen-rtld-audit-unique2.c
new file mode 100644
index 0000000000..199b1d3606
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-unique2.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-unique2.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-unique3.c b/elf/tst-dlmopen-rtld-audit-unique3.c
new file mode 100644
index 0000000000..f3ebe58828
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-unique3.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-unique3.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-unique4.c b/elf/tst-dlmopen-rtld-audit-unique4.c
new file mode 100644
index 0000000000..ef555672d2
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-unique4.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-unique4.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-unique5.c b/elf/tst-dlmopen-rtld-audit-unique5.c
new file mode 100644
index 0000000000..b7faa5d02c
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-unique5.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-unique5.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-audit-unique6.c b/elf/tst-dlmopen-rtld-audit-unique6.c
new file mode 100644
index 0000000000..d431e3a787
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-audit-unique6.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 2
+#include "tst-dlmopen-rtld-unique6.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-shared1.c b/elf/tst-dlmopen-rtld-shared1.c
new file mode 100644
index 0000000000..812d21e692
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared1.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-shared1.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-shared1.h b/elf/tst-dlmopen-rtld-shared1.h
new file mode 100644
index 0000000000..bd733cb3c4
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared1.h
@@ -0,0 +1,65 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen:0:none--ns0",
+ .desc = "dlmopen as dlopen",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .loaded = { [0] = DSO|NEW },
+ .handle_type = DSO,
+ .handle_ns = LM_ID_BASE,
+ },
+ {
+ .name = "dlmopen:0:ns0--ns0",
+ .desc = "dlmopen a preloaded DSO in the base NS",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .preloaded = { [0] = DSO },
+ .loaded = { [0] = DSO },
+ .handle_type = DSO,
+ .handle_ns = LM_ID_BASE,
+ },
+ {
+ .name = "dlmopen-shared:0:ns0--ns0",
+ .desc = "dlmopen a preloaded DSO in the base NS with RTLD_SHARED",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .preloaded = { [0] = DSO },
+ .loaded = { [0] = DSO },
+ .handle_type = DSO,
+ .handle_ns = LM_ID_BASE,
+ },
+ {
+ .name = "dlmopen:0:ns0--nsX",
+ .desc = "dlmopen a preloaded DSO in the base NS into a new NS",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_NEWLM,
+ .preloaded = { [0] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = DSO|NEW },
+ .handle_type = DSO,
+ .handle_ns = EXPECTED_NS,
+ },
+ {
+ .name = "dlmopen:0:ns0-nsX--ns0-nsX",
+ .desc = "dlmopen a preloaded DSO in the base & secondary NS into the base NS",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .handle_type = DSO,
+ .handle_ns = LM_ID_BASE,
+ },
+ {
+ .name = "dlmopen-shared:0:ns0-nsX--ns0-nsX",
+ .desc = "dlmopen a preloaded DSO in the base & secondary NS into the base NS",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .handle_type = DSO,
+ .handle_ns = LM_ID_BASE,
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-shared2.c b/elf/tst-dlmopen-rtld-shared2.c
new file mode 100644
index 0000000000..f830832a0a
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared2.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-shared2.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-shared2.h b/elf/tst-dlmopen-rtld-shared2.h
new file mode 100644
index 0000000000..9775619b9a
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared2.h
@@ -0,0 +1,67 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-shared:0:none--ns0",
+ .desc = "dlmopen as dlopen with RTLD_SHARED",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .loaded = { [0] = DSO|NEW },
+ .handle_ns = LM_ID_BASE,
+ .handle_type = DSO,
+ },
+ {
+ .name = "dlmopen-shared:X:ns0--ns0-nsXp",
+ .desc = "dlmopen into a new namespace with the target already in the base NS",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_NEWLM,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { [0] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY|NEW }
+ },
+ {
+ .name = "dlmopen:0:ns0-nsXp--ns0-nsXp",
+ .desc = "dlmopen into base NS while proxy already in nsX",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ },
+ {
+ .name = "dlmopen-shared:0:ns0-nsXp--ns0-nsXp",
+ .desc = "dlmopen with RTLD_SHARED into base NS while proxy already in nsX",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ },
+ {
+ .name = "dlmopen:X:ns0-nsXp--ns0-nsXp",
+ .desc = "dlmopen into NS X while proxy already in nsX",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = EXPECTED_NS,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ },
+ {
+ .name = "dlmopen-shared:X:ns0-nsXp--ns0-nsXp",
+ .desc = "dlmopen with RTLD_SHARED into NS X while proxy already in nsX",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = EXPECTED_NS,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-shared3.c b/elf/tst-dlmopen-rtld-shared3.c
new file mode 100644
index 0000000000..a63753eb84
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared3.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-shared3.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-shared3.h b/elf/tst-dlmopen-rtld-shared3.h
new file mode 100644
index 0000000000..23fce58bae
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared3.h
@@ -0,0 +1,44 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen:X:none--nsX",
+ .desc = "dlmopen into nsX, no copies preloaded",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_NEWLM,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { },
+ .loaded = { [EXPECTED_NS] = DSO|NEW },
+ },
+ {
+ .name = "dlmopen:0:nsX--ns0-nsX",
+ .desc = "dlmopen into ns 0, copy already loaded in ns X",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO|NEW, [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen:X:ns0-nsX--nsX",
+ .desc = "dlmopen into ns X, copies already in ns 0 and ns X",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = EXPECTED_NS,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen-shared:X:ns0-nsX--nsX",
+ .desc = "dlmopen RTLD_SHARED into nsX with a DSO already in NS0 and NSX",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = EXPECTED_NS,
+ .args.flags = RTLD_SHARED,
+ .failure = 1,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-shared4.c b/elf/tst-dlmopen-rtld-shared4.c
new file mode 100644
index 0000000000..7c3d92e37b
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared4.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-shared4.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-shared4.h b/elf/tst-dlmopen-rtld-shared4.h
new file mode 100644
index 0000000000..9ad29b9a6d
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared4.h
@@ -0,0 +1,15 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-shared:X:none--ns0-nsX",
+ .desc = "dlmopen a new proxy in nsX with no preexisting dso in ns0",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_NEWLM,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { },
+ .loaded = { [0] = DSO|NEW, [EXPECTED_NS] = PROXY|NEW },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-shared5.c b/elf/tst-dlmopen-rtld-shared5.c
new file mode 100644
index 0000000000..f59d14e7b6
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared5.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-shared5.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-shared5.h b/elf/tst-dlmopen-rtld-shared5.h
new file mode 100644
index 0000000000..220129a5cf
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared5.h
@@ -0,0 +1,26 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-preload:X:none--nsX",
+ .desc = "preload a DSO into ns1 to prepare for other tests",
+ .is_prep_stage = 1,
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_NEWLM,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { },
+ .loaded = { [EXPECTED_NS] = DSO|NEW },
+ },
+ {
+ .name = "dlmopen-shared:0:nsX--nsX-ns0",
+ .desc = "dlmopen RTLD_SHARED into ns0 when preloaded into nsX",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO|NEW, [EXPECTED_NS] = DSO },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-shared6.c b/elf/tst-dlmopen-rtld-shared6.c
new file mode 100644
index 0000000000..469fb3566d
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared6.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-shared6.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-shared6.h b/elf/tst-dlmopen-rtld-shared6.h
new file mode 100644
index 0000000000..116e53ea51
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-shared6.h
@@ -0,0 +1,37 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-preload:X:none--nsX",
+ .desc = "preload a DSO into nsX to prepare for other tests",
+ .is_prep_stage = 1,
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = LM_ID_NEWLM,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { },
+ .loaded = { [EXPECTED_NS] = DSO|NEW },
+ },
+ {
+ .name = "dlmopen:X:nsX--nsX",
+ .desc = "dlmopen a dso in nsX while already loaded there",
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = EXPECTED_NS,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { [EXPECTED_NS] = DSO },
+ .loaded = { [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen-shared:X:nsX--nsX",
+ .desc = "dlmopen RTLD_SHARED a dso in nsX while already loaded there",
+ .failure = 1,
+ .args.dso_path = DSO_NORMAL,
+ .args.ns = EXPECTED_NS,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { [EXPECTED_NS] = DSO },
+ .loaded = { [EXPECTED_NS] = DSO },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-unique1.c b/elf/tst-dlmopen-rtld-unique1.c
new file mode 100644
index 0000000000..867345582f
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique1.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-unique1.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-unique1.h b/elf/tst-dlmopen-rtld-unique1.h
new file mode 100644
index 0000000000..f7d32959c2
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique1.h
@@ -0,0 +1,87 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-unique:0:none--ns0",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso into ns0",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { },
+ .loaded = { [0] = DSO|NEW },
+ },
+ {
+ .name = "dlmopen-unique:0:ns0--ns0",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso into ns0 while already present",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO },
+ .loaded = { [0] = DSO },
+ },
+ {
+ .name = "dlmopen-unique-shared:0:ns0--ns0",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso into ns0 while already present",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO },
+ .loaded = { [0] = DSO },
+ },
+ {
+ .name = "dlmopen-unique:X:ns0--nsX",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso into nsX while present in ns0",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_NEWLM,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { [0] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY|NEW },
+ },
+ {
+ .name = "dlmopen-unique:0:ns0-nsXp--ns0--nsXp",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso already in ns0 proxied in nsX",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ },
+ {
+ .name = "dlmopen-shared-unique:0:ns0-nsXp--ns0-nsXp",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso into ns0 already in ns0 and proxied in nsX",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ },
+ {
+ .name = "dlmopen-unique:0:ns0-nsXp--ns0-nsXp",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso into ns0 already in ns0 and proxied in nsX",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = EXPECTED_NS,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ },
+ {
+ .name = "dlmopen-unique:0:ns0-nsXp--ns0-nsXp",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso into ns0 already in ns0 and proxied in nsX",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = EXPECTED_NS,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-unique2.c b/elf/tst-dlmopen-rtld-unique2.c
new file mode 100644
index 0000000000..dabb87b43f
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique2.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-unique2.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-unique2.h b/elf/tst-dlmopen-rtld-unique2.h
new file mode 100644
index 0000000000..911e0180ab
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique2.h
@@ -0,0 +1,26 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-shared-unique:0:none--ns0",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso in the base ns",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { },
+ .loaded = { [0] = DSO|NEW },
+ },
+ {
+ .name = "dlmopen-shared-unique:1:ns0--ns0-ns1p",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso into ns1 while present in ns0",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_NEWLM,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { [0] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = PROXY|NEW },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-unique3.c b/elf/tst-dlmopen-rtld-unique3.c
new file mode 100644
index 0000000000..db8a567a3f
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique3.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-unique3.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-unique3.h b/elf/tst-dlmopen-rtld-unique3.h
new file mode 100644
index 0000000000..b400bad07f
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique3.h
@@ -0,0 +1,14 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-unique:X:none--ns0-ns1p",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso into nsX",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_NEWLM,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { },
+ .loaded = { [0] = DSO|NEW, [EXPECTED_NS] = PROXY|NEW },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-unique4.c b/elf/tst-dlmopen-rtld-unique4.c
new file mode 100644
index 0000000000..58b8e017b4
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique4.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-unique4.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-unique4.h b/elf/tst-dlmopen-rtld-unique4.h
new file mode 100644
index 0000000000..36d5915172
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique4.h
@@ -0,0 +1,15 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-shared-unique:X:none--ns0-nsXp",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_NEWLM,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = PROXY,
+ .preloaded = { },
+ .loaded = { [0] = DSO|NEW, [EXPECTED_NS] = PROXY|NEW },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-unique5.c b/elf/tst-dlmopen-rtld-unique5.c
new file mode 100644
index 0000000000..b2e8329461
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique5.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-unique5.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-unique5.h b/elf/tst-dlmopen-rtld-unique5.h
new file mode 100644
index 0000000000..29882ea782
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique5.h
@@ -0,0 +1,59 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-isolate-unique:X:none--nsX",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso into NSX with RTLD_ISOLATE",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_NEWLM,
+ .args.flags = RTLD_ISOLATE,
+ .handle_ns = EXPECTED_NS,
+ .free_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { },
+ .loaded = { [EXPECTED_NS] = DSO|NEW },
+ },
+ {
+ .name = "dlmopen-unique:0:nsX--ns0-nsX",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso already present in NS X",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO|NEW, [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen-unique:0:ns0-nsX--ns0-nsX",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso already in the base NS and NS X",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen-shared-unique:0:ns0-nsX--ns0-nsX",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso already in the base NS and NS X",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen-shared-unique:X:ns0-nsX--ns0-nsX",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso already in the base NS and NS X into NS X",
+ .failure = 1,
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = EXPECTED_NS,
+ .args.flags = RTLD_SHARED,
+ .handle_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-rtld-unique6.c b/elf/tst-dlmopen-rtld-unique6.c
new file mode 100644
index 0000000000..fecaf559a3
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique6.c
@@ -0,0 +1,11 @@
+#include <dlfcn.h>
+#include "tst-dlmopen-main.h"
+
+#define EXPECTED_NS 1
+#include "tst-dlmopen-rtld-unique6.h"
+
+#include "tst-dlmopen-std-do-test.h"
+
+DEFINE_DLMOPEN_TEST(dltest)
+
+#include <support/test-driver.c>
diff --git a/elf/tst-dlmopen-rtld-unique6.h b/elf/tst-dlmopen-rtld-unique6.h
new file mode 100644
index 0000000000..3c25127fa1
--- /dev/null
+++ b/elf/tst-dlmopen-rtld-unique6.h
@@ -0,0 +1,52 @@
+static dlmopen_test_spec dltest[] =
+ {
+ {
+ .name = "dlmopen-isolate-unique:1:none--ns1--prep",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso into NS1 with RTLD_ISOLATE",
+ .is_prep_stage = 1,
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_NEWLM,
+ .args.flags = RTLD_ISOLATE,
+ .handle_ns = EXPECTED_NS,
+ .free_ns = EXPECTED_NS,
+ .handle_type = DSO,
+ .preloaded = { },
+ .loaded = { [EXPECTED_NS] = DSO|NEW },
+ },
+ {
+ .name = "dlmopen-unique:1:nsX--nsX--FAIL",
+ .desc = "dlmopen a DF_GNU_1_UNIQUE dso into NSX when already there",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = EXPECTED_NS,
+ .failure = 1,
+ .preloaded = { [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen-shared-unique:X:nsX--nsX--FAIL",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso into NSX when already there",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = EXPECTED_NS,
+ .args.flags = RTLD_SHARED,
+ .failure = 1,
+ .preloaded = { [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen-shared-unique:0:nsX--ns0-nsX",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso already present in NS X",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = LM_ID_BASE,
+ .handle_ns = 0,
+ .handle_type = DSO,
+ .preloaded = { [EXPECTED_NS] = DSO },
+ .loaded = { [0] = DSO|NEW, [EXPECTED_NS] = DSO },
+ },
+ {
+ .name = "dlmopen-shared-unique:X:ns0-nsX--ns0-nsX--FAIL",
+ .desc = "dlmopen RTLD_SHARED a DF_GNU_1_UNIQUE dso already in the base NS and NS 1",
+ .args.dso_path = DSO_UNIQUE,
+ .args.ns = EXPECTED_NS,
+ .failure = 1,
+ .preloaded = { [0] = DSO, [EXPECTED_NS] = DSO },
+ },
+ END_TESTS
+ };
diff --git a/elf/tst-dlmopen-sharedmod-norm.c b/elf/tst-dlmopen-sharedmod-norm.c
new file mode 100644
index 0000000000..fd049903f4
--- /dev/null
+++ b/elf/tst-dlmopen-sharedmod-norm.c
@@ -0,0 +1,11 @@
+#include "tst-dlmopen-modules.h"
+
+dlmopen_testresult *rtld_shared_testfunc (void)
+{
+ static dlmopen_testresult result;
+
+ result.name = "norm";
+ result.free = free;
+
+ return &result;
+}
diff --git a/elf/tst-dlmopen-sharedmod-uniq.c b/elf/tst-dlmopen-sharedmod-uniq.c
new file mode 100644
index 0000000000..5c9701da41
--- /dev/null
+++ b/elf/tst-dlmopen-sharedmod-uniq.c
@@ -0,0 +1,11 @@
+#include "tst-dlmopen-modules.h"
+
+dlmopen_testresult *rtld_shared_testfunc (void)
+{
+ static dlmopen_testresult result;
+
+ result.name = "noop";
+ result.free = free;
+
+ return &result;
+}
diff --git a/elf/tst-dlmopen-std-do-test.h b/elf/tst-dlmopen-std-do-test.h
new file mode 100644
index 0000000000..595f6f764d
--- /dev/null
+++ b/elf/tst-dlmopen-std-do-test.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#define DEFINE_DLMOPEN_TEST(x) \
+ static int \
+ do_test (void) \
+ { \
+ for (int i = 0; x[i].name; i++) \
+ if (!process_test_spec (&x[i])) \
+ return 1; \
+ return 0; \
+ }
--
2.20.1
next prev parent reply other threads:[~2021-02-09 17:18 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-09 17:18 [RFC][PATCH v8 00/20] Implementation of RTLD_SHARED for dlmopen Vivek Das Mohapatra
2021-02-09 17:18 ` [RFC][PATCH v8 01/20] Declare and describe the dlmopen RTLD_SHARED flag Vivek Das Mohapatra
2021-02-15 13:08 ` Adhemerval Zanella
2021-02-15 13:29 ` Andreas Schwab
2021-02-15 13:31 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 02/20] include/link.h: Update the link_map struct to allow proxies Vivek Das Mohapatra
2021-02-15 13:11 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 03/20] elf/dl-object.c: Implement a helper function to proxy link_map entries Vivek Das Mohapatra
2021-02-15 13:30 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 04/20] elf/dl-load.c, elf-dl-open.c: Implement RTLD_SHARED dlmopen proxying Vivek Das Mohapatra
2021-02-15 14:53 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 05/20] elf/dl-fini.c: Handle proxy link_map entries in the shutdown path Vivek Das Mohapatra
2021-02-15 17:08 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 06/20] elf/dl-init.c: Skip proxied link map entries in the dl init path Vivek Das Mohapatra
2021-02-15 17:52 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 07/20] elf/dl-open.c: Don't try libc linit in namespaces with no libc mapping Vivek Das Mohapatra
2021-02-15 17:54 ` Adhemerval Zanella
2021-02-17 15:39 ` Vivek Das Mohapatra
2021-02-17 16:17 ` Adhemerval Zanella
2021-02-17 18:32 ` Vivek Das Mohapatra
2021-02-17 20:52 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 08/20] elf/dl-open.c: when creating a proxy check the libc_map in NS 0 Vivek Das Mohapatra
2021-02-15 17:55 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 09/20] Define a new dynamic section tag - DT_GNU_FLAGS_1 Vivek Das Mohapatra
2021-02-15 18:42 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 10/20] Abstract the loaded-DSO search code into a private helper function Vivek Das Mohapatra
2021-02-15 19:25 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 11/20] Compare loaded DSOs by file ID and check for DF_GNU_1_UNIQUE Vivek Das Mohapatra
2021-02-18 20:45 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 12/20] Use the new DSO finder helper function since we have it Vivek Das Mohapatra
2021-02-19 14:39 ` Adhemerval Zanella
2021-02-19 19:50 ` Adhemerval Zanella
2021-02-22 18:44 ` Vivek Das Mohapatra
2021-02-22 18:51 ` Adhemerval Zanella
2021-02-22 23:50 ` Vivek Das Mohapatra
2021-02-09 17:18 ` [RFC][PATCH v8 13/20] Use the DSO search helper to check for preloaded DT_GNU_UNIQUE DSOs Vivek Das Mohapatra
2021-02-19 17:26 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 14/20] When loading DSOs into alternate namespaces check for DT_GNU_UNIQUE Vivek Das Mohapatra
2021-02-19 18:11 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 15/20] Suppress audit calls when a (new) namespace is empty Vivek Das Mohapatra
2021-02-19 19:45 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 16/20] Suppress inter-namespace DSO sharing for audit libraries Vivek Das Mohapatra
2021-02-19 20:39 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 17/20] dlsym, dlvsym should be able to look up symbols via DSO proxies Vivek Das Mohapatra
2021-02-22 18:51 ` Adhemerval Zanella
2021-02-09 17:18 ` [RFC][PATCH v8 18/20] Add DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE dynamic section+flag to glibc DSOs Vivek Das Mohapatra
2021-02-22 20:39 ` Adhemerval Zanella
2021-02-22 21:19 ` Florian Weimer
2021-02-22 21:53 ` Adhemerval Zanella
2021-02-23 3:26 ` Alan Modra
2021-02-23 11:57 ` Adhemerval Zanella
2021-02-23 10:00 ` Florian Weimer
2021-02-23 11:58 ` Adhemerval Zanella
2021-02-23 12:12 ` Florian Weimer
2021-02-23 0:17 ` Vivek Das Mohapatra
2021-02-23 12:02 ` Adhemerval Zanella
2021-02-23 13:24 ` Adhemerval Zanella
2021-02-23 18:46 ` Vivek Das Mohapatra
2021-02-23 18:48 ` Adhemerval Zanella
2021-02-23 19:01 ` Florian Weimer
2021-02-23 19:06 ` Adhemerval Zanella
2021-02-09 17:18 ` Vivek Das Mohapatra [this message]
2021-02-26 19:50 ` [RFC][PATCH v8 19/20] Add dlmopen / RTLD_SHARED tests Adhemerval Zanella
2021-02-26 20:26 ` Andreas Schwab
2021-02-09 17:18 ` [RFC][PATCH v8 20/20] Restore separate libc loading for the TLS/namespace storage test Vivek Das Mohapatra
2021-02-09 19:01 ` [RFC][PATCH v8 00/20] Implementation of RTLD_SHARED for dlmopen Joseph Myers
2021-02-10 12:25 ` Vivek Das Mohapatra
2021-02-10 18:32 ` Joseph Myers
2021-02-12 18:52 ` Adhemerval Zanella
2021-02-12 18:56 ` Florian Weimer
2021-02-12 19:01 ` Adhemerval Zanella
2021-02-12 19:29 ` Florian Weimer
2021-02-18 14:41 ` Vivek Das Mohapatra
2021-02-18 15:02 ` Florian Weimer
2021-02-18 15:05 ` Vivek Das Mohapatra
2021-02-19 8:57 ` Florian Weimer
2021-02-19 15:08 ` Vivek Das Mohapatra
2021-03-04 18:27 ` Adhemerval Zanella
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210209171839.7911-20-vivek@collabora.com \
--to=vivek@collabora.com \
--cc=libc-alpha@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).