summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile82
-rw-r--r--elf/ifuncdep5.c3
-rw-r--r--elf/ifuncdep5pic.c3
-rw-r--r--elf/ifuncmain1staticpie.c3
-rw-r--r--elf/ifuncmain5.c40
-rw-r--r--elf/ifuncmain5pic.c3
-rw-r--r--elf/ifuncmain5picstatic.c3
-rw-r--r--elf/ifuncmain5pie.c3
-rw-r--r--elf/ifuncmain5static.c3
-rw-r--r--elf/ifuncmain5staticpic.c3
-rw-r--r--elf/ifuncmain6pie.c63
-rw-r--r--elf/ifuncmain7.c70
-rw-r--r--elf/ifuncmain7pic.c7
-rw-r--r--elf/ifuncmain7picstatic.c7
-rw-r--r--elf/ifuncmain7pie.c7
-rw-r--r--elf/ifuncmain7static.c7
-rw-r--r--elf/ifuncmod5.c78
-rw-r--r--elf/ifuncmod6.c19
18 files changed, 399 insertions, 5 deletions
diff --git a/elf/Makefile b/elf/Makefile
index 2aa5b7118f..80591178e0 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -99,10 +99,18 @@ distribute	:= rtld-Rules \
 		   ifuncmain1staticpic.c ifuncmain1picstatic.c \
 		   ifuncdep1.c ifuncdep1pic.c ifuncmod1.c \
 		   ifuncmain1pie.c ifuncmain1vispie.c \
+		   ifuncmain1staticpie.c \
 		   ifuncmain2.c ifuncmain2static.c ifuncdep2.c \
 		   ifuncmain2pic.c ifuncmain2picstatic.c ifuncdep2pic.c \
 		   ifuncmain3.c ifuncmod3.c \
-		   ifuncmain4.c ifuncmain4static.c ifuncmain4picstatic.c
+		   ifuncmain4.c ifuncmain4static.c ifuncmain4picstatic.c \
+		   ifuncmain5.c ifuncmain5pic.c ifuncmain5picstatic.c \
+		   ifuncmain5pie.c ifuncmain5static.c \
+		   ifuncmain5staticpic.c \
+		   ifuncdep5.c ifuncdep5pic.c ifuncmod5.c \
+		   ifuncmain6pie.c ifuncmod6.c \
+		   ifuncmain7.c ifuncmain7pic.c ifuncmain7picstatic.c \
+		   ifuncmain7pie.c ifuncmain7static.c
 
 CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
@@ -244,16 +252,22 @@ modules-names-nobuild := filtmod1
 ifeq (yes,$(multi-arch))
 tests-static += ifuncmain1static ifuncmain1picstatic \
 		ifuncmain2static ifuncmain2picstatic \
-		ifuncmain4static ifuncmain4picstatic
+		ifuncmain4static ifuncmain4picstatic \
+		ifuncmain5static ifuncmain5picstatic \
+		ifuncmain7static ifuncmain7picstatic
 
 ifeq (yes,$(build-shared))
 tests += ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
 	 ifuncmain1staticpic \
-	 ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4
+	 ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \
+	 ifuncmain5 ifuncmain5pic ifuncmain5staticpic \
+	 ifuncmain7 ifuncmain7pic
 ifeq (yes,$(have-fpie))
-tests: $(objpfx)ifuncmain1pie.out $(objpfx)ifuncmain1vispie.out
+tests: $(objpfx)ifuncmain1pie.out $(objpfx)ifuncmain1vispie.out \
+	$(objpfx)ifuncmain1staticpie.out $(objpfx)ifuncmain5pie.out \
+	$(objpfx)ifuncmain6pie.out $(objpfx)ifuncmain7pie.out
 endif
-modules-names += ifuncmod1 ifuncmod3
+modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6
 endif
 endif
 
@@ -530,6 +544,8 @@ reldep9mod1.so-no-z-defs = yes
 unload3mod4.so-no-z-defs = yes
 unload4mod1.so-no-z-defs = yes
 ifuncmod1.so-no-z-defs = yes
+ifuncmod5.so-no-z-defs = yes
+ifuncmod6.so-no-z-defs = yes
 
 ifeq ($(build-shared),yes)
 # Build all the modules even when not actually running test programs.
@@ -980,12 +996,22 @@ CFLAGS-ifuncmain2pic.c += $(pic-ccflag)
 CFLAGS-ifuncmain2picstatic.c += $(pic-ccflag)
 CFLAGS-ifuncdep2pic.c += $(pic-ccflag)
 CFLAGS-ifuncmain4picstatic.c += $(pic-ccflag)
+CFLAGS-ifuncmain5pic.c += $(pic-ccflag)
+CFLAGS-ifuncmain5picstatic.c += $(pic-ccflag)
+CFLAGS-ifuncmain5staticpic.c += $(pic-ccflag)
+CFLAGS-ifuncdep5pic.c += $(pic-ccflag)
+CFLAGS-ifuncmain7pic.c += $(pic-ccflag)
+CFLAGS-ifuncmain7picstatic.c += $(pic-ccflag)
 
 LDFLAGS-ifuncmain3 = -Wl,-export-dynamic
 
 ifeq (yesyes,$(have-fpie)$(build-shared))
 CFLAGS-ifuncmain1pie.c += $(pie-ccflag)
 CFLAGS-ifuncmain1vispie.c += $(pie-ccflag)
+CFLAGS-ifuncmain1staticpie.c += $(pie-ccflag)
+CFLAGS-ifuncmain5pie.c += $(pie-ccflag)
+CFLAGS-ifuncmain6pie.c += $(pie-ccflag)
+CFLAGS-ifuncmain7pie.c += $(pie-ccflag)
 
 $(objpfx)ifuncmain1pie.out: $(objpfx)ifuncmain1pie
 	$(elf-objpfx)$(rtld-installed-name) \
@@ -997,6 +1023,16 @@ $(objpfx)ifuncmain1pie: $(objpfx)ifuncmain1pie.o $(objpfx)ifuncmod1.so
 
 generated += ifuncmain1pie ifuncmain1pie.out
 
+$(objpfx)ifuncmain1staticpie.out: $(objpfx)ifuncmain1staticpie
+	$(elf-objpfx)$(rtld-installed-name) \
+	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
+	  $< > $@
+
+$(objpfx)ifuncmain1staticpie: $(objpfx)ifuncmain1staticpie.o $(objpfx)ifuncdep1pic.o
+	$(+link-pie)
+
+generated += ifuncmain1staticpie ifuncmain1staticpie.out
+
 $(objpfx)ifuncmain1vispie.out: $(objpfx)ifuncmain1vispie
 	$(elf-objpfx)$(rtld-installed-name) \
 	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
@@ -1006,6 +1042,36 @@ $(objpfx)ifuncmain1vispie: $(objpfx)ifuncmain1vispie.o $(objpfx)ifuncmod1.so
 	$(+link-pie)
 
 generated += ifuncmain1vispie ifuncmain1vispie.out
+
+$(objpfx)ifuncmain5pie.out: $(objpfx)ifuncmain5pie
+	$(elf-objpfx)$(rtld-installed-name) \
+	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
+	  $< > $@
+
+$(objpfx)ifuncmain5pie: $(objpfx)ifuncmain5pie.o $(objpfx)ifuncmod5.so
+	$(+link-pie)
+
+generated += ifuncmain5pie ifuncmain5pie.out
+
+$(objpfx)ifuncmain6pie.out: $(objpfx)ifuncmain6pie
+	$(elf-objpfx)$(rtld-installed-name) \
+	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
+	  $< > $@
+
+$(objpfx)ifuncmain6pie: $(objpfx)ifuncmain6pie.o $(objpfx)ifuncmod6.so
+	$(+link-pie)
+
+generated += ifuncmain6pie ifuncmain6pie.out
+
+$(objpfx)ifuncmain7pie.out: $(objpfx)ifuncmain7pie
+	$(elf-objpfx)$(rtld-installed-name) \
+	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
+	  $< > $@
+
+$(objpfx)ifuncmain7pie: $(objpfx)ifuncmain7pie.o 
+	$(+link-pie)
+
+generated += ifuncmain7pie ifuncmain7pie.out
 endif
 
 $(objpfx)ifuncmain1: $(addprefix $(objpfx),ifuncmod1.so)
@@ -1022,3 +1088,9 @@ $(objpfx)ifuncmain2picstatic: $(addprefix $(objpfx),ifuncdep2pic.o)
 
 $(objpfx)ifuncmain3: $(libdl)
 $(objpfx)ifuncmain3.out: $(objpfx)ifuncmod3.so
+
+$(objpfx)ifuncmain5: $(addprefix $(objpfx),ifuncmod5.so)
+$(objpfx)ifuncmain5pic: $(addprefix $(objpfx),ifuncmod5.so)
+$(objpfx)ifuncmain5static: $(addprefix $(objpfx),ifuncdep5.o)
+$(objpfx)ifuncmain5staticpic: $(addprefix $(objpfx),ifuncdep5pic.o)
+$(objpfx)ifuncmain5picstatic: $(addprefix $(objpfx),ifuncdep5pic.o)
diff --git a/elf/ifuncdep5.c b/elf/ifuncdep5.c
new file mode 100644
index 0000000000..f26234336e
--- /dev/null
+++ b/elf/ifuncdep5.c
@@ -0,0 +1,3 @@
+/* Test STT_GNU_IFUNC symbols without -fPIC.  */
+
+#include "ifuncmod5.c"
diff --git a/elf/ifuncdep5pic.c b/elf/ifuncdep5pic.c
new file mode 100644
index 0000000000..3edb3a07c6
--- /dev/null
+++ b/elf/ifuncdep5pic.c
@@ -0,0 +1,3 @@
+/* Test STT_GNU_IFUNC symbols with -fPIC.  */
+
+#include "ifuncmod5.c"
diff --git a/elf/ifuncmain1staticpie.c b/elf/ifuncmain1staticpie.c
new file mode 100644
index 0000000000..4891114260
--- /dev/null
+++ b/elf/ifuncmain1staticpie.c
@@ -0,0 +1,3 @@
+/* Test STT_GNU_IFUNC symbols with PIE and no DSO.  */
+
+#include "ifuncmain1.c"
diff --git a/elf/ifuncmain5.c b/elf/ifuncmain5.c
new file mode 100644
index 0000000000..819a443904
--- /dev/null
+++ b/elf/ifuncmain5.c
@@ -0,0 +1,40 @@
+/* Test STT_GNU_IFUNC symbols with dynamic function pointer only.  */
+
+#include <stdlib.h>
+
+int global = -1;
+
+extern int foo (void);
+extern int foo_protected (void);
+
+typedef int (*foo_p) (void);
+
+foo_p
+__attribute__ ((noinline))
+get_foo (void)
+{
+  return foo;
+}
+
+foo_p
+__attribute__ ((noinline))
+get_foo_protected (void)
+{
+  return foo_protected;
+}
+
+int
+main (void)
+{
+  foo_p p;
+  
+  p = get_foo ();
+  if ((*p) () != -1)
+    abort ();
+
+  p = get_foo_protected ();
+  if ((*p) () != 0)
+    abort ();
+
+  return 0;
+}
diff --git a/elf/ifuncmain5pic.c b/elf/ifuncmain5pic.c
new file mode 100644
index 0000000000..e9144fbb20
--- /dev/null
+++ b/elf/ifuncmain5pic.c
@@ -0,0 +1,3 @@
+/* Test STT_GNU_IFUNC symbols with -fPIC.  */
+
+#include "ifuncmain5.c"
diff --git a/elf/ifuncmain5picstatic.c b/elf/ifuncmain5picstatic.c
new file mode 100644
index 0000000000..a0afe905d7
--- /dev/null
+++ b/elf/ifuncmain5picstatic.c
@@ -0,0 +1,3 @@
+/* Test STT_GNU_IFUNC symbols with -fPIC and -static.  */
+
+#include "ifuncmain5.c"
diff --git a/elf/ifuncmain5pie.c b/elf/ifuncmain5pie.c
new file mode 100644
index 0000000000..669f31eeda
--- /dev/null
+++ b/elf/ifuncmain5pie.c
@@ -0,0 +1,3 @@
+/* Test STT_GNU_IFUNC symbols with PIE.  */
+
+#include "ifuncmain5.c"
diff --git a/elf/ifuncmain5static.c b/elf/ifuncmain5static.c
new file mode 100644
index 0000000000..72504404a5
--- /dev/null
+++ b/elf/ifuncmain5static.c
@@ -0,0 +1,3 @@
+/* Test STT_GNU_IFUNC symbols with -static.  */
+
+#include "ifuncmain5.c"
diff --git a/elf/ifuncmain5staticpic.c b/elf/ifuncmain5staticpic.c
new file mode 100644
index 0000000000..9e8bac254f
--- /dev/null
+++ b/elf/ifuncmain5staticpic.c
@@ -0,0 +1,3 @@
+/* Test STT_GNU_IFUNC symbols with -fPIC and no DSO.  */
+
+#include "ifuncmain5.c"
diff --git a/elf/ifuncmain6pie.c b/elf/ifuncmain6pie.c
new file mode 100644
index 0000000000..7e757e335f
--- /dev/null
+++ b/elf/ifuncmain6pie.c
@@ -0,0 +1,63 @@
+/* Test STT_GNU_IFUNC symbols in PIE:
+
+   1. Direct function call.
+   2. Function pointer.
+   3. Reference from a shared library.
+ */
+
+#include <stdlib.h>
+
+typedef int (*foo_p) (void);
+extern foo_p foo_ptr;
+
+static int
+one (void)
+{
+  return -30;
+}
+
+void * foo_ifunc (void) __asm__ ("foo");
+__asm__(".type foo, %gnu_indirect_function");
+
+void * 
+foo_ifunc (void)
+{
+  return one;
+}
+
+extern int foo (void);
+extern foo_p get_foo (void);
+extern foo_p get_foo_p (void);
+
+foo_p my_foo_ptr = foo;
+
+int
+main (void)
+{
+  foo_p p;
+
+  p = get_foo ();
+  if (p != foo)
+    abort ();
+  if ((*p) () != -30)
+    abort ();
+
+  p = get_foo_p ();
+  if (p != foo)
+    abort ();
+  if ((*p) () != -30)
+    abort ();
+
+  if (foo_ptr != foo)
+    abort ();
+  if (my_foo_ptr != foo)
+    abort ();
+  if ((*foo_ptr) () != -30)
+    abort ();
+  if ((*my_foo_ptr) () != -30)
+    abort ();
+  if (foo () != -30)
+    abort ();
+
+  return 0;
+}
diff --git a/elf/ifuncmain7.c b/elf/ifuncmain7.c
new file mode 100644
index 0000000000..8832c7fa1c
--- /dev/null
+++ b/elf/ifuncmain7.c
@@ -0,0 +1,70 @@
+/* Test local STT_GNU_IFUNC symbols:
+
+   1. Direct function call.
+   2. Function pointer.
+ */
+
+#include <stdlib.h>
+
+extern int foo (void);
+
+static int
+one (void)
+{
+  return -30;
+}
+
+static void * foo_ifunc (void) __asm__ ("foo");
+__asm__(".type foo, %gnu_indirect_function");
+
+static void * 
+__attribute__ ((used))
+foo_ifunc (void)
+{
+  return one;
+}
+
+typedef int (*foo_p) (void);
+
+foo_p foo_ptr = foo;
+
+foo_p
+__attribute__ ((noinline))
+get_foo_p (void)
+{
+  return foo_ptr;
+}
+
+foo_p
+__attribute__ ((noinline))
+get_foo (void)
+{
+  return foo;
+}
+
+int
+main (void)
+{
+  foo_p p;
+
+  p = get_foo ();
+  if (p != foo)
+    abort ();
+  if ((*p) () != -30)
+    abort ();
+
+  p = get_foo_p ();
+  if (p != foo)
+    abort ();
+  if ((*p) () != -30)
+    abort ();
+
+  if (foo_ptr != foo)
+    abort ();
+  if ((*foo_ptr) () != -30)
+    abort ();
+  if (foo () != -30)
+    abort ();
+
+  return 0;
+}
diff --git a/elf/ifuncmain7pic.c b/elf/ifuncmain7pic.c
new file mode 100644
index 0000000000..fc37bf4469
--- /dev/null
+++ b/elf/ifuncmain7pic.c
@@ -0,0 +1,7 @@
+/* Test local STT_GNU_IFUNC symbols with -fPIC:
+
+   1. Direct function call.
+   2. Function pointer.
+ */
+
+#include "ifuncmain7.c"
diff --git a/elf/ifuncmain7picstatic.c b/elf/ifuncmain7picstatic.c
new file mode 100644
index 0000000000..baf8934b95
--- /dev/null
+++ b/elf/ifuncmain7picstatic.c
@@ -0,0 +1,7 @@
+/* Test local STT_GNU_IFUNC symbols with -fPIC and -static:
+
+   1. Direct function call.
+   2. Function pointer.
+ */
+
+#include "ifuncmain7.c"
diff --git a/elf/ifuncmain7pie.c b/elf/ifuncmain7pie.c
new file mode 100644
index 0000000000..254d453f1e
--- /dev/null
+++ b/elf/ifuncmain7pie.c
@@ -0,0 +1,7 @@
+/* Test local STT_GNU_IFUNC symbols with PIE:
+
+   1. Direct function call.
+   2. Function pointer.
+ */
+
+#include "ifuncmain7.c"
diff --git a/elf/ifuncmain7static.c b/elf/ifuncmain7static.c
new file mode 100644
index 0000000000..e470d570ef
--- /dev/null
+++ b/elf/ifuncmain7static.c
@@ -0,0 +1,7 @@
+/* Test local STT_GNU_IFUNC symbols with -static:
+
+   1. Direct function call.
+   2. Function pointer.
+ */
+
+#include "ifuncmain7.c"
diff --git a/elf/ifuncmod5.c b/elf/ifuncmod5.c
new file mode 100644
index 0000000000..48388967b5
--- /dev/null
+++ b/elf/ifuncmod5.c
@@ -0,0 +1,78 @@
+/* Test STT_GNU_IFUNC symbols without direct function call.  */
+
+extern int global;
+
+static int
+one (void)
+{
+  return 1;
+}
+
+static int
+minus_one (void)
+{
+  return -1;
+}
+
+static int
+zero (void) 
+{
+  return 0;
+}
+
+void * foo_ifunc (void) __asm__ ("foo");
+__asm__(".type foo, %gnu_indirect_function");
+
+void * 
+foo_ifunc (void)
+{
+  switch (global)
+    {
+    case 1:
+      return one;
+    case -1:
+      return minus_one;
+    default:
+      return zero;
+    }
+}
+
+void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
+__asm__(".type foo_hidden, %gnu_indirect_function");
+
+void * 
+foo_hidden_ifunc (void)
+{
+  switch (global)
+    {
+    case 1:
+      return minus_one;
+    case -1:
+      return one;
+    default:
+      return zero;
+    }
+}
+
+void * foo_protected_ifunc (void) __asm__ ("foo_protected");
+__asm__(".type foo_protected, %gnu_indirect_function");
+
+void * 
+foo_protected_ifunc (void)
+{
+  switch (global)
+    {
+    case 1:
+      return one;
+    case -1:
+      return zero;
+    default:
+      return minus_one;
+    }
+}
+
+/* Test hidden indirect function.  */
+__asm__(".hidden foo_hidden");
+
+/* Test protected indirect function.  */
+__asm__(".protected foo_protected");
diff --git a/elf/ifuncmod6.c b/elf/ifuncmod6.c
new file mode 100644
index 0000000000..2e16c1d06d
--- /dev/null
+++ b/elf/ifuncmod6.c
@@ -0,0 +1,19 @@
+/* Test STT_GNU_IFUNC symbol reference in a shared library.  */
+
+extern int foo (void);
+
+typedef int (*foo_p) (void);
+
+foo_p foo_ptr = foo;
+
+foo_p
+get_foo_p (void)
+{
+  return foo_ptr;
+}
+
+foo_p
+get_foo (void)
+{
+  return foo;
+}