ltp_rt_sigaction: SPARC fixes for -O0
The *sigreturn_stub functions are copied from glibc, and they
work only if optimization > 0, since they expect that the compiler
does not add an prologue.
For example, with -O > 0:
0000000000102140 <__rt_sigreturn_stub>:
102140: 82 10 20 65 mov 0x65, %g1 ! 65 <_init-0x101f23>
102144: 91 d0 20 6d ta 0x6d
102148: 81 c3 e0 08 retl
10214c: 01 00 00 00 nop
but without -O:
000000000010212c <__rt_sigreturn_stub>:
10212c: 9d e3 bf 50 save %sp, -176, %sp <--- this
102130: 82 10 20 65 mov 0x65, %g1
102134: 91 d0 20 6d ta 0x6d
102138: 81 cf e0 08 rett %i7 + 8
10213c: 01 00 00 00 nop
Therefore, if we build LTP with OPT_CFLAGS="", ltp_rt_sigaction() will
malfunction.
To avoid this, let's declare a new symbol pointing to the instruction we
need ('mov ...').
The trick was proposed by Jose E. Marchesi <jose.marchesi@oracle.com>.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
Acked-by: Jan Stancek <jstancek@redhat.com>
diff --git a/include/lapi/rt_sigaction.h b/include/lapi/rt_sigaction.h
index 46f6a50..f99c372 100644
--- a/include/lapi/rt_sigaction.h
+++ b/include/lapi/rt_sigaction.h
@@ -105,12 +105,14 @@
# if defined __arch64__ || defined __sparcv9
/*
- * From glibc/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c
+ * Based on glibc/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c
*/
+extern char *__rt_sig_stub;
+
static void __rt_sigreturn_stub(void)
{
- __asm__ ("mov %0, %%g1\n\t"
+ __asm__ ("__rt_sig_stub: mov %0, %%g1\n\t"
"ta 0x6d\n\t"
: /* no outputs */
: "i" (__NR_rt_sigreturn));
@@ -119,12 +121,14 @@
# else /* sparc32 */
/*
- * From glibc/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
+ * Based on glibc/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
*/
+extern char *__rt_sig_stub, *__sig_stub;
+
static void __rt_sigreturn_stub(void)
{
- __asm__ ("mov %0, %%g1\n\t"
+ __asm__ ("__rt_sig_stub: mov %0, %%g1\n\t"
"ta 0x10\n\t"
: /* no outputs */
: "i" (__NR_rt_sigreturn));
@@ -132,7 +136,7 @@
static void __sigreturn_stub(void)
{
- __asm__ ("mov %0, %%g1\n\t"
+ __asm__ ("__sig_stub: mov %0, %%g1\n\t"
"ta 0x10\n\t"
: /* no outputs */
: "i" (__NR_sigreturn));
@@ -181,12 +185,12 @@
#ifdef __sparc__
unsigned long stub = 0;
# if defined __arch64__ || defined __sparcv9
- stub = ((unsigned long) &__rt_sigreturn_stub) - 8;
+ stub = ((unsigned long) &__rt_sig_stub) - 8;
# else /* sparc32 */
if ((kact.sa_flags & SA_SIGINFO) != 0)
- stub = ((unsigned long) &__rt_sigreturn_stub) - 8;
+ stub = ((unsigned long) &__rt_sig_stub) - 8;
else
- stub = ((unsigned long) &__sigreturn_stub) - 8;
+ stub = ((unsigned long) &__sig_stub) - 8;
# endif
#endif