[klibc] Bug#943425: Debian #943425: klibc: [s390x] setjmp/longjmp do not save/restore all registers in use
Thorsten Glaser
tg at mirbsd.de
Wed May 5 12:56:30 PDT 2021
Ben Hutchings dixit:
>> > hpa, maks, bwh: any of you taking these two or should I send patches
>> > and possibly NMU klibc in Debian?
>>
>> Please send patches. If you have a test base that could catch bugs
>
>test *case*
>
>> like this (without writing lists of registers in the test itself), that
>> would be really useful.
Unfortunately, I do not, other than, “run mksh’s testsuite”. This
seems to highly depend on compiler decisions (what to spill where
and when).
Patches for klibc upstream git attched; I’m currently trying to test
them, will report.
bye,
//mirabilos
--
Solange man keine schmutzigen Tricks macht, und ich meine *wirklich*
schmutzige Tricks, wie bei einer doppelt verketteten Liste beide
Pointer XORen und in nur einem Word speichern, funktioniert Boehm ganz
hervorragend. -- Andreas Bogk über boehm-gc in d.a.s.r
-------------- next part --------------
From ba9cce08553cb49fe077485b13ae99548bb2da5c Mon Sep 17 00:00:00 2001
From: mirabilos <tg at debian.org>
Date: Wed, 5 May 2021 21:02:37 +0200
Subject: [PATCH 1/2] [klibc] sig{set,long}jmp: do not ignore sigsetjmp's
second argument
Save and restore the signal mask only if that argument is nonzero,
as required by the standards. (Closes: Debian #988027)
Signed-off-by: mirabilos <tg at debian.org>
---
usr/include/setjmp.h | 7 ++++++-
usr/klibc/CAVEATS | 3 +--
usr/klibc/siglongjmp.c | 3 ++-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/usr/include/setjmp.h b/usr/include/setjmp.h
index abebccde..5916cd8a 100644
--- a/usr/include/setjmp.h
+++ b/usr/include/setjmp.h
@@ -27,6 +27,7 @@ __extern __noreturn longjmp(jmp_buf, int);
struct __sigjmp_buf {
jmp_buf __jmpbuf;
sigset_t __sigs;
+ unsigned char __sigs_saved;
};
typedef struct __sigjmp_buf sigjmp_buf[1];
@@ -34,7 +35,11 @@ typedef struct __sigjmp_buf sigjmp_buf[1];
#define sigsetjmp(__env, __save) \
({ \
struct __sigjmp_buf *__e = (__env); \
- sigprocmask(0, NULL, &__e->__sigs); \
+ if (__save) { \
+ sigprocmask(0, NULL, &__e->__sigs); \
+ __e->__sigs_saved = 1; \
+ } else \
+ __e->__sigs_saved = 0; \
setjmp(__e->__jmpbuf); \
})
diff --git a/usr/klibc/CAVEATS b/usr/klibc/CAVEATS
index 5e991cb7..39949c28 100644
--- a/usr/klibc/CAVEATS
+++ b/usr/klibc/CAVEATS
@@ -13,8 +13,7 @@ Compiling with -O0 is more likely to work on gcc 3.
setjmp()/longjmp():
-------------------
setjmp() and longjmp() *do not* save signal state. sigsetjmp() and
-siglongjmp() *do* save the signal mask -- regardless of the value of
-the extra argument.
+siglongjmp() *do* save the signal mask if the extra argument is nonzero.
The standards actually state that if you pass longjmp() a final value
of zero the library should change that to a 1! Presumably the reason
diff --git a/usr/klibc/siglongjmp.c b/usr/klibc/siglongjmp.c
index 31042cbd..45f4e400 100644
--- a/usr/klibc/siglongjmp.c
+++ b/usr/klibc/siglongjmp.c
@@ -10,6 +10,7 @@
__noreturn siglongjmp(sigjmp_buf buf, int retval)
{
- sigprocmask(SIG_SETMASK, &buf->__sigs, NULL);
+ if (buf->__sigs_saved)
+ sigprocmask(SIG_SETMASK, &buf->__sigs, NULL);
longjmp(buf->__jmpbuf, retval);
}
--
2.31.1
-------------- next part --------------
From fc5a53932ee56d61a9fd8db75784e9f39ca474a3 Mon Sep 17 00:00:00 2001
From: mirabilos <tg at debian.org>
Date: Wed, 5 May 2021 21:26:33 +0200
Subject: [PATCH 2/2] [klibc] {set,long}jmp [s390x]: save/restore the correct
registers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The s390x ABI actually has FPU registers f8‥f15, not f1/f3/f5/f7,
to be saved. (Closes: Debian #943425)
Signed-off-by: mirabilos <tg at debian.org>
---
usr/include/arch/s390/klibc/archsetjmp.h | 2 +-
usr/klibc/arch/s390/setjmp.S | 24 ++++++++++++++++--------
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/usr/include/arch/s390/klibc/archsetjmp.h b/usr/include/arch/s390/klibc/archsetjmp.h
index 728780ad..1167c8b6 100644
--- a/usr/include/arch/s390/klibc/archsetjmp.h
+++ b/usr/include/arch/s390/klibc/archsetjmp.h
@@ -16,7 +16,7 @@ struct __jmp_buf {
struct __jmp_buf {
uint64_t __gregs[10]; /* general registers r6-r15 */
- uint64_t __fpregs[4]; /* fp registers f1, f3, f5, f7 */
+ uint64_t __fpregs[8]; /* fp registers f8-f15 */
};
#endif /* __s390x__ */
diff --git a/usr/klibc/arch/s390/setjmp.S b/usr/klibc/arch/s390/setjmp.S
index c36a0517..1386419a 100644
--- a/usr/klibc/arch/s390/setjmp.S
+++ b/usr/klibc/arch/s390/setjmp.S
@@ -38,10 +38,14 @@ longjmp:
setjmp:
stmg %r6,%r15,0(%r2) # save all general registers
- std %f1,80(%r2) # save fp registers f4 and f6
- std %f3,88(%r2)
- std %f5,96(%r2)
- std %f7,104(%r2)
+ std %f8,80(%r2) # save fp registers f8 to f15
+ std %f9,88(%r2)
+ std %f10,96(%r2)
+ std %f11,104(%r2)
+ std %f12,112(%r2)
+ std %f13,120(%r2)
+ std %f14,128(%r2)
+ std %f15,136(%r2)
lghi %r2,0 # return 0
br %r14
@@ -54,10 +58,14 @@ setjmp:
longjmp:
lgr %r1,%r2 # jmp_buf
lgr %r2,%r3 # return value
- ld %f7,104(%r1) # restore all saved registers
- ld %f5,96(%r1)
- ld %f3,88(%r1)
- ld %f1,80(%r1)
+ ld %f15,136(%r1) # restore all saved registers
+ ld %f14,128(%r1)
+ ld %f13,120(%r1)
+ ld %f12,112(%r1)
+ ld %f11,104(%r1)
+ ld %f10,96(%r1)
+ ld %f9,88(%r1)
+ ld %f8,80(%r1)
lmg %r6,%r15,0(%r1)
br %r14 # return to restored address
--
2.31.1
More information about the klibc
mailing list