mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00: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>
|
2009-07-30 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* elf/elf.h (R_PPC_NUM, R_PPC64_NUM): Delete unused and incorrect.
|
* elf/elf.h (R_PPC_NUM, R_PPC64_NUM): Delete unused and incorrect.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/* Test 3 STT_GNU_IFUNC symbols. */
|
/* Test 3 STT_GNU_IFUNC symbols. */
|
||||||
|
|
||||||
extern int global;
|
#include "ifunc-sel.h"
|
||||||
|
|
||||||
|
int global __attribute__ ((visibility ("protected"))) = -1;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
one (void)
|
one (void)
|
||||||
@ -26,15 +28,7 @@ __asm__(".type foo1, %gnu_indirect_function");
|
|||||||
void *
|
void *
|
||||||
foo1_ifunc (void)
|
foo1_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (one, minus_one, zero);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return one;
|
|
||||||
case -1:
|
|
||||||
return minus_one;
|
|
||||||
default:
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void * foo2_ifunc (void) __asm__ ("foo2");
|
void * foo2_ifunc (void) __asm__ ("foo2");
|
||||||
@ -43,15 +37,7 @@ __asm__(".type foo2, %gnu_indirect_function");
|
|||||||
void *
|
void *
|
||||||
foo2_ifunc (void)
|
foo2_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (minus_one, one, zero);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return minus_one;
|
|
||||||
case -1:
|
|
||||||
return one;
|
|
||||||
default:
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void * foo3_ifunc (void) __asm__ ("foo3");
|
void * foo3_ifunc (void) __asm__ ("foo3");
|
||||||
@ -60,13 +46,5 @@ __asm__(".type foo3, %gnu_indirect_function");
|
|||||||
void *
|
void *
|
||||||
foo3_ifunc (void)
|
foo3_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (one, zero, minus_one);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return one;
|
|
||||||
case -1:
|
|
||||||
return zero;
|
|
||||||
default:
|
|
||||||
return minus_one;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int global = -1;
|
|
||||||
|
|
||||||
int ret_foo;
|
int ret_foo;
|
||||||
int ret_foo_hidden;
|
int ret_foo_hidden;
|
||||||
int ret_foo_protected;
|
int ret_foo_protected;
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int global = -1;
|
|
||||||
|
|
||||||
int ret_foo;
|
int ret_foo;
|
||||||
int ret_foo_hidden;
|
int ret_foo_hidden;
|
||||||
int ret_foo_protected;
|
int ret_foo_protected;
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int global = -1;
|
|
||||||
|
|
||||||
extern int foo1 (void);
|
extern int foo1 (void);
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int global = -1;
|
|
||||||
|
|
||||||
extern int foo (void);
|
extern int foo (void);
|
||||||
extern int foo_protected (void);
|
extern int foo_protected (void);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "ifunc-sel.h"
|
||||||
|
|
||||||
typedef int (*foo_p) (void);
|
typedef int (*foo_p) (void);
|
||||||
extern foo_p foo_ptr;
|
extern foo_p foo_ptr;
|
||||||
@ -22,7 +23,7 @@ __asm__(".type foo, %gnu_indirect_function");
|
|||||||
void *
|
void *
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
return one;
|
return ifunc_one (one);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int foo (void);
|
extern int foo (void);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "ifunc-sel.h"
|
||||||
|
|
||||||
extern int foo (void);
|
extern int foo (void);
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ static void *
|
|||||||
__attribute__ ((used))
|
__attribute__ ((used))
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
return one;
|
return ifunc_one (one);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*foo_p) (void);
|
typedef int (*foo_p) (void);
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
2. Function pointer.
|
2. Function pointer.
|
||||||
3. Visibility.
|
3. Visibility.
|
||||||
*/
|
*/
|
||||||
|
#include "ifunc-sel.h"
|
||||||
|
|
||||||
extern int global;
|
int global __attribute__ ((visibility ("protected"))) = -1;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
one (void)
|
one (void)
|
||||||
@ -20,7 +21,7 @@ minus_one (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zero (void)
|
zero (void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -28,52 +29,28 @@ zero (void)
|
|||||||
void * foo_ifunc (void) __asm__ ("foo");
|
void * foo_ifunc (void) __asm__ ("foo");
|
||||||
__asm__(".type foo, %gnu_indirect_function");
|
__asm__(".type foo, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (one, minus_one, zero);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return one;
|
|
||||||
case -1:
|
|
||||||
return minus_one;
|
|
||||||
default:
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
|
void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
|
||||||
__asm__(".type foo_hidden, %gnu_indirect_function");
|
__asm__(".type foo_hidden, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
foo_hidden_ifunc (void)
|
foo_hidden_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (minus_one, one, zero);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return minus_one;
|
|
||||||
case -1:
|
|
||||||
return one;
|
|
||||||
default:
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void * foo_protected_ifunc (void) __asm__ ("foo_protected");
|
void * foo_protected_ifunc (void) __asm__ ("foo_protected");
|
||||||
__asm__(".type foo_protected, %gnu_indirect_function");
|
__asm__(".type foo_protected, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
foo_protected_ifunc (void)
|
foo_protected_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (one, zero, minus_one);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return one;
|
|
||||||
case -1:
|
|
||||||
return zero;
|
|
||||||
default:
|
|
||||||
return minus_one;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test hidden indirect function. */
|
/* Test hidden indirect function. */
|
||||||
|
@ -5,4 +5,3 @@
|
|||||||
int ret_foo;
|
int ret_foo;
|
||||||
int ret_foo_hidden;
|
int ret_foo_hidden;
|
||||||
int ret_foo_protected;
|
int ret_foo_protected;
|
||||||
int global = -1;
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* Test STT_GNU_IFUNC symbols without direct function call. */
|
/* Test STT_GNU_IFUNC symbols without direct function call. */
|
||||||
|
#include "ifunc-sel.h"
|
||||||
|
|
||||||
extern int global;
|
int global __attribute__ ((visibility ("protected"))) = -1;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
one (void)
|
one (void)
|
||||||
@ -26,15 +27,7 @@ __asm__(".type foo, %gnu_indirect_function");
|
|||||||
void *
|
void *
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (one, minus_one, zero);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return one;
|
|
||||||
case -1:
|
|
||||||
return minus_one;
|
|
||||||
default:
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
|
void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
|
||||||
@ -43,15 +36,7 @@ __asm__(".type foo_hidden, %gnu_indirect_function");
|
|||||||
void *
|
void *
|
||||||
foo_hidden_ifunc (void)
|
foo_hidden_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (minus_one, one, zero);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return minus_one;
|
|
||||||
case -1:
|
|
||||||
return one;
|
|
||||||
default:
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void * foo_protected_ifunc (void) __asm__ ("foo_protected");
|
void * foo_protected_ifunc (void) __asm__ ("foo_protected");
|
||||||
@ -60,15 +45,7 @@ __asm__(".type foo_protected, %gnu_indirect_function");
|
|||||||
void *
|
void *
|
||||||
foo_protected_ifunc (void)
|
foo_protected_ifunc (void)
|
||||||
{
|
{
|
||||||
switch (global)
|
return ifunc_sel (one, zero, minus_one);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return one;
|
|
||||||
case -1:
|
|
||||||
return zero;
|
|
||||||
default:
|
|
||||||
return minus_one;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test hidden indirect function. */
|
/* 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