about summary refs log tree commit diff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-05-27 07:15:35 -0700
committerH.J. Lu <hjl.tools@gmail.com>2018-06-06 08:32:12 -0700
commit3bc6d308ef8ba549e0ef072692903ea2afa883d1 (patch)
tree22933829d15bdc05f258a7f7cb1e01af1209c8ed
parent3fe2b141c2d2bd2c7274f860cdf8a0aa061bb5bd (diff)
downloadglibc-hjl/pr23240/fw.tar.gz
glibc-hjl/pr23240/fw.tar.xz
glibc-hjl/pr23240/fw.zip
Check non-lazy binding with LD_PRELOAD and weak reference hjl/pr23240/fw
Check non-lazy binding with

1. Reference to unrelocated IFUNC function with LD_PRELOAD.
2. Weak reference.

	[BZ #23176]
	[BZ #23240]
	* elf/Makefile (tests): Add reldep6a.
	(tests-internal): Add ifuncpreload1
	(modules-names): Add ifuncpreloadmod1a and ifuncpreloadmod1b.
	($(objpfx)reldep6a): New.
	($(objpfx)reldep6a.out): Likewise.
	(reldep6a-ENV): Likewise.
	($(objpfx)ifuncpreload1): Likewise.
	($(objpfx)ifuncpreload1.out): Likewise.
	(ifuncpreload1-ENV): Likewise.
	* elf/ifuncpreload1.c: New file.
	* elf/ifuncpreloadmod1a.c: Likewise.
	* elf/ifuncpreloadmod1b.c: Likewise.
	* elf/reldep6a.c: Likewise.
-rw-r--r--elf/Makefile18
-rw-r--r--elf/ifuncpreload1.c39
-rw-r--r--elf/ifuncpreloadmod1a.c23
-rw-r--r--elf/ifuncpreloadmod1b.c49
-rw-r--r--elf/reldep6a.c1
5 files changed, 126 insertions, 4 deletions
diff --git a/elf/Makefile b/elf/Makefile
index f54c4657c7..08a090a1b3 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -170,8 +170,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
 	 constload1 order noload filter \
 	 reldep reldep2 reldep3 reldep4 nodelete nodelete2 \
 	 nodlopen nodlopen2 lateglobal initfirst global \
-	 restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
-	 tst-tls4 tst-tls5 \
+	 restest2 next dblload dblunload reldep5 reldep6 reldep6a \
+	 reldep7 reldep8 tst-tls4 tst-tls5 \
 	 tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \
 	 tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \
 	 tst-align tst-align2 \
@@ -328,7 +328,7 @@ tests-internal += \
 	 ifuncmain1staticpic \
 	 ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \
 	 ifuncmain5 ifuncmain5pic ifuncmain5staticpic \
-	 ifuncmain7 ifuncmain7pic
+	 ifuncmain7 ifuncmain7pic ifuncpreload1
 ifunc-test-modules = ifuncdep1 ifuncdep1pic ifuncdep2 ifuncdep2pic \
 		     ifuncdep5 ifuncdep5pic
 extra-test-objs += $(ifunc-test-modules:=.o)
@@ -339,7 +339,8 @@ ifunc-pie-tests = ifuncmain1pie ifuncmain1vispie ifuncmain1staticpie \
 tests-internal += $(ifunc-pie-tests)
 tests-pie += $(ifunc-pie-tests)
 endif
-modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6
+modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6 \
+		 ifuncpreloadmod1a ifuncpreloadmod1b
 endif
 endif
 
@@ -885,6 +886,10 @@ $(objpfx)reldep5.out: $(objpfx)reldepmod5.so $(objpfx)reldepmod6.so
 $(objpfx)reldep6: $(libdl)
 $(objpfx)reldep6.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so
 
+$(objpfx)reldep6a: $(libdl)
+$(objpfx)reldep6a.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so
+reldep6a-ENV = LD_BIND_NOW=1
+
 $(objpfx)reldep7: $(libdl)
 $(objpfx)reldep7.out: $(objpfx)reldep7mod1.so $(objpfx)reldep7mod2.so
 
@@ -1454,3 +1459,8 @@ tst-libc_dlvsym-static-ENV = \
 $(objpfx)tst-libc_dlvsym-static.out: $(objpfx)tst-libc_dlvsym-dso.so
 
 $(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
+
+$(objpfx)ifuncpreload1: $(objpfx)ifuncpreloadmod1a.so
+$(objpfx)ifuncpreload1.out: $(objpfx)ifuncpreloadmod1b.so
+ifuncpreload1-ENV = \
+  LD_PRELOAD=$(objpfx)ifuncpreloadmod1b.so LD_BIND_NOW=1
diff --git a/elf/ifuncpreload1.c b/elf/ifuncpreload1.c
new file mode 100644
index 0000000000..172df33ac3
--- /dev/null
+++ b/elf/ifuncpreload1.c
@@ -0,0 +1,39 @@
+/* Test for relocation over with IFUNC symbols.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+
+extern void bar (char *, const char *, unsigned int);
+
+static int
+do_test (void)
+{
+  char dst[50];
+  const char src[] =
+    {
+      "This is a test"
+    };
+  bar (dst, src, sizeof (src));
+  if (__builtin_memcmp (dst, src, sizeof (src)) != 0)
+    __builtin_abort ();
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/elf/ifuncpreloadmod1a.c b/elf/ifuncpreloadmod1a.c
new file mode 100644
index 0000000000..be9f8832b8
--- /dev/null
+++ b/elf/ifuncpreloadmod1a.c
@@ -0,0 +1,23 @@
+/* Shared module to test for relocation over with IFUNC symbols.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+void
+bar (char *dst, const char *src, unsigned int size)
+{
+  __builtin_memmove (dst, src, size);
+}
diff --git a/elf/ifuncpreloadmod1b.c b/elf/ifuncpreloadmod1b.c
new file mode 100644
index 0000000000..1194ae20e4
--- /dev/null
+++ b/elf/ifuncpreloadmod1b.c
@@ -0,0 +1,49 @@
+/* Shared module to test for relocation over with IFUNC symbols.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+
+void *
+my_memmove(void *dst_p, const void *src_p, size_t n)
+{
+  const char *src = src_p;
+  char *dst = dst_p;
+  char *ret = dst;
+  if (src < dst)
+    {
+      dst += n;
+      src += n;
+      while (n--)
+	*--dst = *--src;
+    }
+  else
+    while (n--)
+      *dst++ = *src++;
+  return ret;
+}
+
+void *memmove (void *, const void *, size_t)
+  __attribute__ ((ifunc ("resolve_memmove")));
+
+typedef void *(*memmove_t) (void *, const void *, size_t);
+
+static memmove_t
+resolve_memmove (void)
+{
+  return my_memmove;
+}
diff --git a/elf/reldep6a.c b/elf/reldep6a.c
new file mode 100644
index 0000000000..28ed7008fa
--- /dev/null
+++ b/elf/reldep6a.c
@@ -0,0 +1 @@
+#include "reldep6.c"