mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 01:33:36 +08:00
Uglify IFUNC tests for PPC.
This commit is contained in:
parent
51a71cf063
commit
31c759bf37
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
||||
2009-10-28 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf/ifuncdep2.c: Include ifunc-sel.h.
|
||||
(global): Delete.
|
||||
(foo1_ifunc, foo2_ifunc, foo3_ifunc): Use ifunc_sel.
|
||||
* elf/ifuncmain1.c (global): Delete.
|
||||
* elf/ifuncmain1vis.c: Likewise.
|
||||
* elf/ifuncmain2.c: Likewise.
|
||||
* elf/ifuncmain5.c: Likewise.
|
||||
* elf/ifuncmod3.c: Likewise.
|
||||
* elf/ifuncmain6pie.c: Include ifunc-sel.h.
|
||||
(foo_ifunc): Use ifunc_one.
|
||||
* elf/ifuncmain7.c: Likewise.
|
||||
* elf/ifuncmod1.c: Include ifunc-sel.h.
|
||||
(global): Define protected var.
|
||||
(foo_ifunc, foo_hidden_ifunc, foo_protected_ifunc): Use ifunc_sel.
|
||||
* elf/ifuncmod5.c: Likewise.
|
||||
* sysdeps/generic/elf/ifunc-sel.h: New file.
|
||||
* sysdeps/powerpc/elf/ifunc-sel.h: New file.
|
||||
|
||||
2009-07-30 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf/elf.h (R_PPC_NUM, R_PPC64_NUM): Delete unused and incorrect.
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* Test 3 STT_GNU_IFUNC symbols. */
|
||||
|
||||
extern int global;
|
||||
#include "ifunc-sel.h"
|
||||
|
||||
int global __attribute__ ((visibility ("protected"))) = -1;
|
||||
|
||||
static int
|
||||
one (void)
|
||||
@ -26,15 +28,7 @@ __asm__(".type foo1, %gnu_indirect_function");
|
||||
void *
|
||||
foo1_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return one;
|
||||
case -1:
|
||||
return minus_one;
|
||||
default:
|
||||
return zero;
|
||||
}
|
||||
return ifunc_sel (one, minus_one, zero);
|
||||
}
|
||||
|
||||
void * foo2_ifunc (void) __asm__ ("foo2");
|
||||
@ -43,15 +37,7 @@ __asm__(".type foo2, %gnu_indirect_function");
|
||||
void *
|
||||
foo2_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return minus_one;
|
||||
case -1:
|
||||
return one;
|
||||
default:
|
||||
return zero;
|
||||
}
|
||||
return ifunc_sel (minus_one, one, zero);
|
||||
}
|
||||
|
||||
void * foo3_ifunc (void) __asm__ ("foo3");
|
||||
@ -60,13 +46,5 @@ __asm__(".type foo3, %gnu_indirect_function");
|
||||
void *
|
||||
foo3_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return one;
|
||||
case -1:
|
||||
return zero;
|
||||
default:
|
||||
return minus_one;
|
||||
}
|
||||
return ifunc_sel (one, zero, minus_one);
|
||||
}
|
||||
|
@ -7,8 +7,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int global = -1;
|
||||
|
||||
int ret_foo;
|
||||
int ret_foo_hidden;
|
||||
int ret_foo_protected;
|
||||
|
@ -7,8 +7,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int global = -1;
|
||||
|
||||
int ret_foo;
|
||||
int ret_foo_hidden;
|
||||
int ret_foo_protected;
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int global = -1;
|
||||
|
||||
extern int foo1 (void);
|
||||
|
||||
int
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int global = -1;
|
||||
|
||||
extern int foo (void);
|
||||
extern int foo_protected (void);
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "ifunc-sel.h"
|
||||
|
||||
typedef int (*foo_p) (void);
|
||||
extern foo_p foo_ptr;
|
||||
@ -22,7 +23,7 @@ __asm__(".type foo, %gnu_indirect_function");
|
||||
void *
|
||||
foo_ifunc (void)
|
||||
{
|
||||
return one;
|
||||
return ifunc_one (one);
|
||||
}
|
||||
|
||||
extern int foo (void);
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "ifunc-sel.h"
|
||||
|
||||
extern int foo (void);
|
||||
|
||||
@ -21,7 +22,7 @@ static void *
|
||||
__attribute__ ((used))
|
||||
foo_ifunc (void)
|
||||
{
|
||||
return one;
|
||||
return ifunc_one (one);
|
||||
}
|
||||
|
||||
typedef int (*foo_p) (void);
|
||||
|
@ -4,8 +4,9 @@
|
||||
2. Function pointer.
|
||||
3. Visibility.
|
||||
*/
|
||||
#include "ifunc-sel.h"
|
||||
|
||||
extern int global;
|
||||
int global __attribute__ ((visibility ("protected"))) = -1;
|
||||
|
||||
static int
|
||||
one (void)
|
||||
@ -20,7 +21,7 @@ minus_one (void)
|
||||
}
|
||||
|
||||
static int
|
||||
zero (void)
|
||||
zero (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -28,52 +29,28 @@ zero (void)
|
||||
void * foo_ifunc (void) __asm__ ("foo");
|
||||
__asm__(".type foo, %gnu_indirect_function");
|
||||
|
||||
void *
|
||||
void *
|
||||
foo_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return one;
|
||||
case -1:
|
||||
return minus_one;
|
||||
default:
|
||||
return zero;
|
||||
}
|
||||
return ifunc_sel (one, minus_one, zero);
|
||||
}
|
||||
|
||||
void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
|
||||
__asm__(".type foo_hidden, %gnu_indirect_function");
|
||||
|
||||
void *
|
||||
void *
|
||||
foo_hidden_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return minus_one;
|
||||
case -1:
|
||||
return one;
|
||||
default:
|
||||
return zero;
|
||||
}
|
||||
return ifunc_sel (minus_one, one, zero);
|
||||
}
|
||||
|
||||
void * foo_protected_ifunc (void) __asm__ ("foo_protected");
|
||||
__asm__(".type foo_protected, %gnu_indirect_function");
|
||||
|
||||
void *
|
||||
void *
|
||||
foo_protected_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return one;
|
||||
case -1:
|
||||
return zero;
|
||||
default:
|
||||
return minus_one;
|
||||
}
|
||||
return ifunc_sel (one, zero, minus_one);
|
||||
}
|
||||
|
||||
/* Test hidden indirect function. */
|
||||
|
@ -5,4 +5,3 @@
|
||||
int ret_foo;
|
||||
int ret_foo_hidden;
|
||||
int ret_foo_protected;
|
||||
int global = -1;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Test STT_GNU_IFUNC symbols without direct function call. */
|
||||
#include "ifunc-sel.h"
|
||||
|
||||
extern int global;
|
||||
int global __attribute__ ((visibility ("protected"))) = -1;
|
||||
|
||||
static int
|
||||
one (void)
|
||||
@ -26,15 +27,7 @@ __asm__(".type foo, %gnu_indirect_function");
|
||||
void *
|
||||
foo_ifunc (void)
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return one;
|
||||
case -1:
|
||||
return minus_one;
|
||||
default:
|
||||
return zero;
|
||||
}
|
||||
return ifunc_sel (one, minus_one, zero);
|
||||
}
|
||||
|
||||
void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
|
||||
@ -43,15 +36,7 @@ __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;
|
||||
}
|
||||
return ifunc_sel (minus_one, one, zero);
|
||||
}
|
||||
|
||||
void * foo_protected_ifunc (void) __asm__ ("foo_protected");
|
||||
@ -60,15 +45,7 @@ __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;
|
||||
}
|
||||
return ifunc_sel (one, zero, minus_one);
|
||||
}
|
||||
|
||||
/* Test hidden indirect function. */
|
||||
|
26
sysdeps/generic/elf/ifunc-sel.h
Normal file
26
sysdeps/generic/elf/ifunc-sel.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* Used by the elf ifunc tests. */
|
||||
#ifndef ELF_IFUNC_SEL_H
|
||||
#define ELF_IFUNC_SEL_H 1
|
||||
|
||||
extern int global;
|
||||
|
||||
static inline void *
|
||||
ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
|
||||
{
|
||||
switch (global)
|
||||
{
|
||||
case 1:
|
||||
return f1;
|
||||
case -1:
|
||||
return f2;
|
||||
default:
|
||||
return f3;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void *
|
||||
ifunc_one (int (*f1) (void))
|
||||
{
|
||||
return f1;
|
||||
}
|
||||
#endif
|
46
sysdeps/powerpc/elf/ifunc-sel.h
Normal file
46
sysdeps/powerpc/elf/ifunc-sel.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* Used by the elf ifunc tests. */
|
||||
#ifndef ELF_IFUNC_SEL_H
|
||||
#define ELF_IFUNC_SEL_H 1
|
||||
|
||||
extern int global;
|
||||
|
||||
static inline void *
|
||||
ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
|
||||
{
|
||||
register void *ret __asm__ ("r3");
|
||||
__asm__ ("mflr 12\n\t"
|
||||
"bcl 20,31,1f\n"
|
||||
"1:\tmflr 11\n\t"
|
||||
"mtlr 12\n\t"
|
||||
"addis 12,11,global-1b@ha\n\t"
|
||||
"lwz 12,global-1b@l(12)\n\t"
|
||||
"addis %0,11,%2-1b@ha\n\t"
|
||||
"addi %0,%0,%2-1b@l\n\t"
|
||||
"cmpwi 12,1\n\t"
|
||||
"beqlr\n\t"
|
||||
"addis %0,11,%3-1b@ha\n\t"
|
||||
"addi %0,%0,%3-1b@l\n\t"
|
||||
"cmpwi 12,-1\n\t"
|
||||
"beqlr\n\t"
|
||||
"addis %0,11,%4-1b@ha\n\t"
|
||||
"addi %0,%0,%4-1b@l"
|
||||
: "=r" (ret)
|
||||
: "X" (&global), "X" (f1), "X" (f2), "X" (f3));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
ifunc_one (int (*f1) (void))
|
||||
{
|
||||
register void *ret __asm__ ("r3");
|
||||
__asm__ ("mflr 12\n\t"
|
||||
"bcl 20,31,1f\n"
|
||||
"1:\tmflr %0\n\t"
|
||||
"mtlr 12\n\t"
|
||||
"addis %0,%0,%1-1b@ha\n\t"
|
||||
"addi %0,%0,%1-1b@l"
|
||||
: "=r" (ret)
|
||||
: "X" (f1));
|
||||
return ret;
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user