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 epilogue.

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.march...@oracle.com>.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmansk...@oracle.com>
---
 include/lapi/rt_sigaction.h |   20 ++++++++++++--------
 1 files changed, 12 insertions(+), 8 deletions(-)

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 @@ static inline int sig_initial(int sig)
 # 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 @@ static void __rt_sigreturn_stub(void)
 # 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 __rt_sigreturn_stub(void)
 
 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 @@ static int ltp_rt_sigaction(int signum, const struct 
sigaction *act,
 #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
 
-- 
1.7.1


------------------------------------------------------------------------------
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to