mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 01:33:36 +08:00
Test for ELF IFUNC functionality.
This commit is contained in:
parent
fbb04b35e7
commit
2f083d7511
46
ChangeLog
46
ChangeLog
@ -1,3 +1,49 @@
|
||||
2009-06-02 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* elf/Makefile (distribute): Add ifuncmain1.c, ifuncmain1pic.c,
|
||||
ifuncmain1vis.c, ifuncmain1vispic.c, ifuncmain1static.c,
|
||||
ifuncmain1staticpic.c, ifuncmain1picstatic.c, ifuncdep1.c,
|
||||
ifuncdep1pic.c, ifuncmod1.c, ifuncmain1pie.c, ifuncmain1vispie.c,
|
||||
ifuncmain2.c, ifuncmain2static.c, ifuncdep2.c,
|
||||
funcmain2pic.c, ifuncmain2picstatic.c, ifuncdep2pic.c,
|
||||
ifuncmain3.c, ifuncmod3.c,.
|
||||
ifuncmain4.c, ifuncmain4static.c, ifuncmain4picstatic.c.
|
||||
(tests-static): Add ifuncmain1static, ifuncmain1picstatic,
|
||||
ifuncmain2static, ifuncmain2picstatic, ifuncmain4static,
|
||||
ifuncmain4picstatic.
|
||||
(tests): Add ifuncmain1, ifuncmain1pic, ifuncmain1vis,
|
||||
ifuncmain1vispic, ifuncmain1staticpic, ifuncmain2, ifuncmain2pic,
|
||||
ifuncmain3, ifuncmain4.
|
||||
(tests): Depend on $(objpfx)ifuncmain1pie.out and
|
||||
$(objpfx)ifuncmain1vispie.out.
|
||||
(modules-names): Add ifuncmod1 ifuncmod3.
|
||||
(generated): Add ifuncmain1pie ifuncmain1pie.out
|
||||
ifuncmain1vispie ifuncmain1vispie.out.
|
||||
Define rules to build and run the tests.
|
||||
* elf/ifuncdep1.c: New file.
|
||||
* elf/ifuncdep1pic.c: New file.
|
||||
* elf/ifuncdep2.c: New file.
|
||||
* elf/ifuncdep2pic.c: New file.
|
||||
* elf/ifuncmain1.c: New file.
|
||||
* elf/ifuncmain1pic.c: New file.
|
||||
* elf/ifuncmain1picstatic.c: New file.
|
||||
* elf/ifuncmain1pie.c: New file.
|
||||
* elf/ifuncmain1static.c: New file.
|
||||
* elf/ifuncmain1staticpic.c: New file.
|
||||
* elf/ifuncmain1vis.c: New file..
|
||||
* elf/ifuncmain1vispic.c: New file..
|
||||
* elf/ifuncmain1vispie.c: New file.
|
||||
* elf/ifuncmain2.c: New file.
|
||||
* elf/ifuncmain2pic.c: New file.
|
||||
* elf/ifuncmain2picstatic.c: New file.
|
||||
* elf/ifuncmain2static.c: New file.
|
||||
* elf/ifuncmain3.c: New file.
|
||||
* elf/ifuncmain4.c: New file.
|
||||
* elf/ifuncmain4picstatic.c: New file.
|
||||
* elf/ifuncmain4static.c: New file.
|
||||
* elf/ifuncmod1.c: New file.
|
||||
* elf/ifuncmod3.c: New file.
|
||||
|
||||
2009-06-03 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/dl-sysdep.c (_dl_show_auxv): Terminate correct string.
|
||||
|
94
elf/Makefile
94
elf/Makefile
@ -93,7 +93,16 @@ distribute := rtld-Rules \
|
||||
order2mod1.c order2mod2.c order2mod3.c order2mod4.c \
|
||||
tst-stackguard1.c tst-stackguard1-static.c \
|
||||
tst-array5.c tst-array5-static.c tst-array5dep.c \
|
||||
tst-array5.exp tst-leaks1.c check-execstack.c
|
||||
tst-array5.exp tst-leaks1.c check-execstack.c \
|
||||
ifuncmain1.c ifuncmain1pic.c ifuncmain1vis.c \
|
||||
ifuncmain1vispic.c ifuncmain1static.c \
|
||||
ifuncmain1staticpic.c ifuncmain1picstatic.c \
|
||||
ifuncdep1.c ifuncdep1pic.c ifuncmod1.c \
|
||||
ifuncmain1pie.c ifuncmain1vispie.c \
|
||||
ifuncmain2.c ifuncmain2static.c ifuncdep2.c \
|
||||
ifuncmain2pic.c ifuncmain2picstatic.c ifuncdep2pic.c \
|
||||
ifuncmain3.c ifuncmod3.c \
|
||||
ifuncmain4.c ifuncmain4static.c ifuncmain4picstatic.c
|
||||
|
||||
CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
|
||||
@ -232,6 +241,22 @@ test-extras += $(modules-names)
|
||||
# filtmod1.so has a special rule
|
||||
modules-names-nobuild := filtmod1
|
||||
|
||||
ifeq (yes,$(multi-arch))
|
||||
tests-static += ifuncmain1static ifuncmain1picstatic \
|
||||
ifuncmain2static ifuncmain2picstatic \
|
||||
ifuncmain4static ifuncmain4picstatic
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
tests += ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
|
||||
ifuncmain1staticpic \
|
||||
ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4
|
||||
ifeq (yes,$(have-fpie))
|
||||
tests: $(objpfx)ifuncmain1pie.out $(objpfx)ifuncmain1vispie.out
|
||||
endif
|
||||
modules-names += ifuncmod1 ifuncmod3
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
include ../Rules
|
||||
|
||||
@ -504,6 +529,7 @@ reldep8mod2.so-no-z-defs = yes
|
||||
reldep9mod1.so-no-z-defs = yes
|
||||
unload3mod4.so-no-z-defs = yes
|
||||
unload4mod1.so-no-z-defs = yes
|
||||
ifuncmod1.so-no-z-defs = yes
|
||||
|
||||
ifeq ($(build-shared),yes)
|
||||
# Build all the modules even when not actually running test programs.
|
||||
@ -951,3 +977,69 @@ tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace
|
||||
$(objpfx)tst-addr1: $(libdl)
|
||||
|
||||
$(objpfx)tst-thrlock: $(libdl) $(shared-thread-library)
|
||||
|
||||
CFLAGS-ifuncmain1pic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncmain1picstatic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncmain1staticpic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncdep1pic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncmain1vispic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncmain2pic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncmain2picstatic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncdep2pic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncmain4picstatic.c += $(pic-ccflag)
|
||||
|
||||
LDFLAGS-ifuncmain3 = -Wl,-export-dynamic
|
||||
|
||||
ifeq (yesyes,$(have-fpie)$(build-shared))
|
||||
CFLAGS-ifuncmain1pie.c += $(pie-ccflag)
|
||||
CFLAGS-ifuncmain1vispie.c += $(pie-ccflag)
|
||||
|
||||
$(objpfx)ifuncmain1pie.out: $(objpfx)ifuncmain1pie
|
||||
$(elf-objpfx)$(rtld-installed-name) \
|
||||
--library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
|
||||
$< > $@
|
||||
|
||||
$(objpfx)ifuncmain1pie: $(objpfx)ifuncmain1pie.o $(objpfx)ifuncmod1.so
|
||||
$(LINK.o) -pie -Wl,-O1 \
|
||||
$(sysdep-LDFLAGS) $(config-LDFLAGS) \
|
||||
$(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
|
||||
$(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
|
||||
$(LDFLAGS) $(LDFLAGS-$(@F)) \
|
||||
-L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \
|
||||
-o $@ $(objpfx)tst-pie1.o $(objpfx)tst-piemod1.so \
|
||||
$(common-objpfx)libc_nonshared.a
|
||||
|
||||
generated += ifuncmain1pie ifuncmain1pie.out
|
||||
|
||||
$(objpfx)ifuncmain1vispie.out: $(objpfx)ifuncmain1vispie
|
||||
$(elf-objpfx)$(rtld-installed-name) \
|
||||
--library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
|
||||
$< > $@
|
||||
|
||||
$(objpfx)ifuncmain1vispie: $(objpfx)ifuncmain1vispie.o $(objpfx)ifuncmod1.so
|
||||
$(LINK.o) -pie -Wl,-O1 \
|
||||
$(sysdep-LDFLAGS) $(config-LDFLAGS) \
|
||||
$(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
|
||||
$(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
|
||||
$(LDFLAGS) $(LDFLAGS-$(@F)) \
|
||||
-L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \
|
||||
-o $@ $(objpfx)tst-pie1.o $(objpfx)tst-piemod1.so \
|
||||
$(common-objpfx)libc_nonshared.a
|
||||
|
||||
generated += ifuncmain1vispie ifuncmain1vispie.out
|
||||
endif
|
||||
|
||||
$(objpfx)ifuncmain1: $(addprefix $(objpfx),ifuncmod1.so)
|
||||
$(objpfx)ifuncmain1pic: $(addprefix $(objpfx),ifuncmod1.so)
|
||||
$(objpfx)ifuncmain1staticpic: $(addprefix $(objpfx),ifuncdep1pic.o)
|
||||
$(objpfx)ifuncmain1static: $(addprefix $(objpfx),ifuncdep1.o)
|
||||
$(objpfx)ifuncmain1picstatic: $(addprefix $(objpfx),ifuncdep1pic.o)
|
||||
$(objpfx)ifuncmain1vis: $(addprefix $(objpfx),ifuncmod1.so)
|
||||
$(objpfx)ifuncmain1vispic: $(addprefix $(objpfx),ifuncmod1.so)
|
||||
$(objpfx)ifuncmain2: $(addprefix $(objpfx),ifuncdep2.o)
|
||||
$(objpfx)ifuncmain2pic: $(addprefix $(objpfx),ifuncdep2pic.o)
|
||||
$(objpfx)ifuncmain2static: $(addprefix $(objpfx),ifuncdep2.o)
|
||||
$(objpfx)ifuncmain2picstatic: $(addprefix $(objpfx),ifuncdep2pic.o)
|
||||
|
||||
$(objpfx)ifuncmain3: $(libdl)
|
||||
$(objpfx)ifuncmain3.out: $(objpfx)ifuncmod3.so
|
||||
|
3
elf/ifuncdep1.c
Normal file
3
elf/ifuncdep1.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols without -fPIC. */
|
||||
|
||||
#include "ifuncmod1.c"
|
3
elf/ifuncdep1pic.c
Normal file
3
elf/ifuncdep1pic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC. */
|
||||
|
||||
#include "ifuncmod1.c"
|
72
elf/ifuncdep2.c
Normal file
72
elf/ifuncdep2.c
Normal file
@ -0,0 +1,72 @@
|
||||
/* Test 3 STT_GNU_IFUNC symbols. */
|
||||
|
||||
extern int global;
|
||||
|
||||
static int
|
||||
one (void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
minus_one (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
zero (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void * foo1_ifunc (void) __asm__ ("foo1");
|
||||
__asm__(".type foo1, %gnu_indirect_function");
|
||||
|
||||
void *
|
||||
foo1_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return one;
|
||||
case -1:
|
||||
return minus_one;
|
||||
default:
|
||||
return zero;
|
||||
}
|
||||
}
|
||||
|
||||
void * foo2_ifunc (void) __asm__ ("foo2");
|
||||
__asm__(".type foo2, %gnu_indirect_function");
|
||||
|
||||
void *
|
||||
foo2_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return minus_one;
|
||||
case -1:
|
||||
return one;
|
||||
default:
|
||||
return zero;
|
||||
}
|
||||
}
|
||||
|
||||
void * foo3_ifunc (void) __asm__ ("foo3");
|
||||
__asm__(".type foo3, %gnu_indirect_function");
|
||||
|
||||
void *
|
||||
foo3_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return one;
|
||||
case -1:
|
||||
return zero;
|
||||
default:
|
||||
return minus_one;
|
||||
}
|
||||
}
|
3
elf/ifuncdep2pic.c
Normal file
3
elf/ifuncdep2pic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC. */
|
||||
|
||||
#include "ifuncdep2.c"
|
66
elf/ifuncmain1.c
Normal file
66
elf/ifuncmain1.c
Normal file
@ -0,0 +1,66 @@
|
||||
/* Test STT_GNU_IFUNC symbols:
|
||||
|
||||
1. Direct function call.
|
||||
2. Function pointer.
|
||||
3. Visibility without override.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int global = -1;
|
||||
|
||||
int ret_foo;
|
||||
int ret_foo_hidden;
|
||||
int ret_foo_protected;
|
||||
|
||||
extern int foo (void);
|
||||
extern int foo_protected (void);
|
||||
|
||||
#ifndef FOO_P
|
||||
typedef int (*foo_p) (void);
|
||||
#endif
|
||||
|
||||
foo_p foo_ptr = foo;
|
||||
foo_p foo_procted_ptr = foo_protected;
|
||||
|
||||
extern foo_p get_foo_p (void);
|
||||
extern foo_p get_foo_hidden_p (void);
|
||||
extern foo_p get_foo_protected_p (void);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
foo_p p;
|
||||
|
||||
if (foo_ptr != foo)
|
||||
abort ();
|
||||
if (foo () != -1)
|
||||
abort ();
|
||||
if ((*foo_ptr) () != -1)
|
||||
abort ();
|
||||
|
||||
if (foo_procted_ptr != foo_protected)
|
||||
abort ();
|
||||
if (foo_protected () != 0)
|
||||
abort ();
|
||||
if ((*foo_procted_ptr) () != 0)
|
||||
abort ();
|
||||
|
||||
p = get_foo_p ();
|
||||
if (p != foo)
|
||||
abort ();
|
||||
if (ret_foo != -1 || (*p) () != ret_foo)
|
||||
abort ();
|
||||
|
||||
p = get_foo_hidden_p ();
|
||||
if (ret_foo_hidden != 1 || (*p) () != ret_foo_hidden)
|
||||
abort ();
|
||||
|
||||
p = get_foo_protected_p ();
|
||||
if (p != foo_protected)
|
||||
abort ();
|
||||
if (ret_foo_protected != 0 || (*p) () != ret_foo_protected)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
3
elf/ifuncmain1pic.c
Normal file
3
elf/ifuncmain1pic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC. */
|
||||
|
||||
#include "ifuncmain1.c"
|
3
elf/ifuncmain1picstatic.c
Normal file
3
elf/ifuncmain1picstatic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC and -static. */
|
||||
|
||||
#include "ifuncmain1.c"
|
3
elf/ifuncmain1pie.c
Normal file
3
elf/ifuncmain1pie.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with PIE. */
|
||||
|
||||
#include "ifuncmain1.c"
|
3
elf/ifuncmain1static.c
Normal file
3
elf/ifuncmain1static.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -static. */
|
||||
|
||||
#include "ifuncmain1.c"
|
3
elf/ifuncmain1staticpic.c
Normal file
3
elf/ifuncmain1staticpic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC and no DSO. */
|
||||
|
||||
#include "ifuncmain1.c"
|
89
elf/ifuncmain1vis.c
Normal file
89
elf/ifuncmain1vis.c
Normal file
@ -0,0 +1,89 @@
|
||||
/* Test STT_GNU_IFUNC symbols:
|
||||
|
||||
1. Direct function call.
|
||||
2. Function pointer.
|
||||
3. Visibility with override.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int global = -1;
|
||||
|
||||
int ret_foo;
|
||||
int ret_foo_hidden;
|
||||
int ret_foo_protected;
|
||||
|
||||
extern int foo (void);
|
||||
extern int foo_protected (void);
|
||||
|
||||
#ifndef FOO_P
|
||||
typedef int (*foo_p) (void);
|
||||
#endif
|
||||
|
||||
foo_p foo_ptr = foo;
|
||||
foo_p foo_procted_ptr = foo_protected;
|
||||
|
||||
extern foo_p get_foo_p (void);
|
||||
extern foo_p get_foo_hidden_p (void);
|
||||
extern foo_p get_foo_protected_p (void);
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
foo (void)
|
||||
{
|
||||
return -30;
|
||||
}
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
foo_hidden (void)
|
||||
{
|
||||
return -20;
|
||||
}
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
foo_protected (void)
|
||||
{
|
||||
return -40;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
foo_p p;
|
||||
|
||||
if (foo_ptr != foo)
|
||||
abort ();
|
||||
if ((*foo_ptr) () != -30)
|
||||
abort ();
|
||||
|
||||
if (foo_procted_ptr != foo_protected)
|
||||
abort ();
|
||||
if ((*foo_procted_ptr) () != -40)
|
||||
abort ();
|
||||
|
||||
p = get_foo_p ();
|
||||
if (p != foo)
|
||||
abort ();
|
||||
if (foo () != -30)
|
||||
abort ();
|
||||
if (ret_foo != -30 || (*p) () != ret_foo)
|
||||
abort ();
|
||||
|
||||
p = get_foo_hidden_p ();
|
||||
if (foo_hidden () != -20)
|
||||
abort ();
|
||||
if (ret_foo_hidden != 1 || (*p) () != ret_foo_hidden)
|
||||
abort ();
|
||||
|
||||
p = get_foo_protected_p ();
|
||||
if (p == foo_protected)
|
||||
abort ();
|
||||
if (foo_protected () != -40)
|
||||
abort ();
|
||||
if (ret_foo_protected != 0 || (*p) () != ret_foo_protected)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
3
elf/ifuncmain1vispic.c
Normal file
3
elf/ifuncmain1vispic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC. */
|
||||
|
||||
#include "ifuncmain1vis.c"
|
3
elf/ifuncmain1vispie.c
Normal file
3
elf/ifuncmain1vispie.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with PIE. */
|
||||
|
||||
#include "ifuncmain1vis.c"
|
16
elf/ifuncmain2.c
Normal file
16
elf/ifuncmain2.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* Test calling one STT_GNU_IFUNC function with 3 different
|
||||
STT_GNU_IFUNC definitions. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int global = -1;
|
||||
|
||||
extern int foo1 (void);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
if (foo1 () != -1)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
3
elf/ifuncmain2pic.c
Normal file
3
elf/ifuncmain2pic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC. */
|
||||
|
||||
#include "ifuncmain2.c"
|
3
elf/ifuncmain2picstatic.c
Normal file
3
elf/ifuncmain2picstatic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC and -static. */
|
||||
|
||||
#include "ifuncmain2.c"
|
3
elf/ifuncmain2static.c
Normal file
3
elf/ifuncmain2static.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -static. */
|
||||
|
||||
#include "ifuncmain2.c"
|
120
elf/ifuncmain3.c
Normal file
120
elf/ifuncmain3.c
Normal file
@ -0,0 +1,120 @@
|
||||
/* Test STT_GNU_IFUNC symbols with dlopen:
|
||||
|
||||
1. Direct function call.
|
||||
2. Function pointer.
|
||||
3. Visibility with override.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef int (*foo_p) (void);
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
foo (void)
|
||||
{
|
||||
return -30;
|
||||
}
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
foo_hidden (void)
|
||||
{
|
||||
return -20;
|
||||
}
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
foo_protected (void)
|
||||
{
|
||||
return -40;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
foo_p p;
|
||||
foo_p (*f) (void);
|
||||
int *ret;
|
||||
|
||||
void *h = dlopen ("ifuncmod3.so", RTLD_LAZY);
|
||||
if (h == NULL)
|
||||
{
|
||||
printf ("cannot load: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = dlsym (h, "get_foo_p");
|
||||
if (f == NULL)
|
||||
{
|
||||
printf ("symbol not found: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = dlsym (h, "ret_foo");
|
||||
if (ret == NULL)
|
||||
{
|
||||
printf ("symbol not found: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = (*f) ();
|
||||
if (p != foo)
|
||||
abort ();
|
||||
if (foo () != -30)
|
||||
abort ();
|
||||
if (*ret != -30 || (*p) () != *ret)
|
||||
abort ();
|
||||
|
||||
f = dlsym (h, "get_foo_hidden_p");
|
||||
if (f == NULL)
|
||||
{
|
||||
printf ("symbol not found: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = dlsym (h, "ret_foo_hidden");
|
||||
if (ret == NULL)
|
||||
{
|
||||
printf ("symbol not found: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = (*f) ();
|
||||
if (foo_hidden () != -20)
|
||||
abort ();
|
||||
if (*ret != 1 || (*p) () != *ret)
|
||||
abort ();
|
||||
|
||||
f = dlsym (h, "get_foo_protected_p");
|
||||
if (f == NULL)
|
||||
{
|
||||
printf ("symbol not found: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = dlsym (h, "ret_foo_protected");
|
||||
if (ret == NULL)
|
||||
{
|
||||
printf ("symbol not found: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = (*f) ();
|
||||
if (p == foo_protected)
|
||||
abort ();
|
||||
if (foo_protected () != -40)
|
||||
abort ();
|
||||
if (*ret != 0 || (*p) () != *ret)
|
||||
abort ();
|
||||
|
||||
if (dlclose (h) != 0)
|
||||
{
|
||||
printf ("cannot close: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
4
elf/ifuncmain4.c
Normal file
4
elf/ifuncmain4.c
Normal file
@ -0,0 +1,4 @@
|
||||
/* Test STT_GNU_IFUNC symbols in a single source file. */
|
||||
|
||||
#include "ifuncmod1.c"
|
||||
#include "ifuncmain1.c"
|
3
elf/ifuncmain4picstatic.c
Normal file
3
elf/ifuncmain4picstatic.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -fPIC and -static. */
|
||||
|
||||
#include "ifuncmain4.c"
|
3
elf/ifuncmain4static.c
Normal file
3
elf/ifuncmain4static.c
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test STT_GNU_IFUNC symbols with -static. */
|
||||
|
||||
#include "ifuncmain4.c"
|
114
elf/ifuncmod1.c
Normal file
114
elf/ifuncmod1.c
Normal file
@ -0,0 +1,114 @@
|
||||
/* Test STT_GNU_IFUNC symbols:
|
||||
|
||||
1. Direct function call.
|
||||
2. Function pointer.
|
||||
3. Visibility.
|
||||
*/
|
||||
|
||||
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");
|
||||
|
||||
extern int foo (void);
|
||||
extern int foo_hidden (void);
|
||||
extern int foo_protected (void);
|
||||
extern int ret_foo;
|
||||
extern int ret_foo_hidden;
|
||||
extern int ret_foo_protected;
|
||||
|
||||
#define FOO_P
|
||||
typedef int (*foo_p) (void);
|
||||
|
||||
foo_p
|
||||
get_foo_p (void)
|
||||
{
|
||||
ret_foo = foo ();
|
||||
return foo;
|
||||
}
|
||||
|
||||
foo_p
|
||||
get_foo_hidden_p (void)
|
||||
{
|
||||
ret_foo_hidden = foo_hidden ();
|
||||
return foo_hidden;
|
||||
}
|
||||
|
||||
foo_p
|
||||
get_foo_protected_p (void)
|
||||
{
|
||||
ret_foo_protected = foo_protected ();
|
||||
return foo_protected;
|
||||
}
|
8
elf/ifuncmod3.c
Normal file
8
elf/ifuncmod3.c
Normal file
@ -0,0 +1,8 @@
|
||||
/* Test STT_GNU_IFUNC symbols with dlopen. */
|
||||
|
||||
#include "ifuncmod1.c"
|
||||
|
||||
int ret_foo;
|
||||
int ret_foo_hidden;
|
||||
int ret_foo_protected;
|
||||
int global = -1;
|
Loading…
Reference in New Issue
Block a user