aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2009-06-22 15:07:40 -0700
committerUlrich Drepper <drepper@redhat.com>2009-06-22 15:07:40 -0700
commit3c30afc8625c680257b91638c3d9bee01e1fe778 (patch)
tree46b73bd4a4ca129ce8818c14c83657a9d3018f02 /elf
parentccab6d8f73a17346862b681250de6f73a6940144 (diff)
downloadglibc-3c30afc8625c680257b91638c3d9bee01e1fe778.zip
glibc-3c30afc8625c680257b91638c3d9bee01e1fe778.tar.gz
glibc-3c30afc8625c680257b91638c3d9bee01e1fe778.tar.bz2
Add more IFUNC tests.
Mostly tests around not-exported IFUNC functions, IFUNC in statically linked binaries and PIEs, etc.
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 2aa5b71..8059117 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 0000000..f262343
--- /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 0000000..3edb3a0
--- /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 0000000..4891114
--- /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 0000000..819a443
--- /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 0000000..e9144fb
--- /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 0000000..a0afe90
--- /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 0000000..669f31e
--- /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 0000000..7250440
--- /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 0000000..9e8bac2
--- /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 0000000..7e757e3
--- /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 0000000..8832c7f
--- /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 0000000..fc37bf4
--- /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 0000000..baf8934
--- /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 0000000..254d453
--- /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 0000000..e470d57
--- /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 0000000..4838896
--- /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 0000000..2e16c1d
--- /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;
+}