From 3c30afc8625c680257b91638c3d9bee01e1fe778 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 22 Jun 2009 15:07:40 -0700 Subject: Add more IFUNC tests. Mostly tests around not-exported IFUNC functions, IFUNC in statically linked binaries and PIEs, etc. --- elf/Makefile | 82 ++++++++++++++++++++++++++++++++++++++++++++--- elf/ifuncdep5.c | 3 ++ elf/ifuncdep5pic.c | 3 ++ elf/ifuncmain1staticpie.c | 3 ++ elf/ifuncmain5.c | 40 +++++++++++++++++++++++ elf/ifuncmain5pic.c | 3 ++ elf/ifuncmain5picstatic.c | 3 ++ elf/ifuncmain5pie.c | 3 ++ elf/ifuncmain5static.c | 3 ++ elf/ifuncmain5staticpic.c | 3 ++ elf/ifuncmain6pie.c | 63 ++++++++++++++++++++++++++++++++++++ elf/ifuncmain7.c | 70 ++++++++++++++++++++++++++++++++++++++++ elf/ifuncmain7pic.c | 7 ++++ elf/ifuncmain7picstatic.c | 7 ++++ elf/ifuncmain7pie.c | 7 ++++ elf/ifuncmain7static.c | 7 ++++ elf/ifuncmod5.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ elf/ifuncmod6.c | 19 +++++++++++ 18 files changed, 399 insertions(+), 5 deletions(-) create mode 100644 elf/ifuncdep5.c create mode 100644 elf/ifuncdep5pic.c create mode 100644 elf/ifuncmain1staticpie.c create mode 100644 elf/ifuncmain5.c create mode 100644 elf/ifuncmain5pic.c create mode 100644 elf/ifuncmain5picstatic.c create mode 100644 elf/ifuncmain5pie.c create mode 100644 elf/ifuncmain5static.c create mode 100644 elf/ifuncmain5staticpic.c create mode 100644 elf/ifuncmain6pie.c create mode 100644 elf/ifuncmain7.c create mode 100644 elf/ifuncmain7pic.c create mode 100644 elf/ifuncmain7picstatic.c create mode 100644 elf/ifuncmain7pie.c create mode 100644 elf/ifuncmain7static.c create mode 100644 elf/ifuncmod5.c create mode 100644 elf/ifuncmod6.c (limited to 'elf') 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 + +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 + +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 + +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; +} -- cgit v1.2.1