Bug#943425: Use of $v10 register (was Re: klibc: [s390x] SIGSEGV in mksh testcase funsub-2)

Thorsten Glaser <[email protected]>
Newsgroups gmane.linux.debian.devel.bugs.general,gmane.linux.debian.ports.s390
Message-ID <[email protected]>
retitle 943425 klibc: [s390x] setjmp/longjmp do not save/restore all registers in use
# because this affects a release architecture
severity 943425 serious
thanks

Recapping for the benefit of [email protected]:

> The code in question (where it crashes) is thus:

>    1607                  */
>    1608                 valsub(t, NULL);
>    1609                 subst_exstat = exstat & 0xFF;
>    1610                 /* rewind the tempfile and restore regular stdout */
>    1611                 lseek(shf_fileno(shf), (off_t)0, SEEK_SET);

> The crash occurs in line 1611 because shf (a local variable) is nil.
>
> The really interesting part, though, is in line 1608, a call to valsub():

[…]
>    2104         if (!kshsetjmp(e->jbuf))
>    2105                 execute(t, XXCOM | XERROK, NULL);
[…]

kshsetjmp(x) is sigsetjmp(x,0) (though klibc ignores the 0).

execute() calls siglongjmp().

> - it appears as if the combination of sigsetjmp/siglongjmp does not restore
>   all callee-saved variables correctly on s390x; comparing with glibc shows
>   that the wrong FPU registers seem to be saved but mksh does not use the
>   FPU anyway
>
> Setting breakpoints to lines 1608 (valsub call) and 1609:

[…]
> 1608                    valsub(t, NULL);
> (gdb) print shf
> $5 = (struct shf *) 0x3fffdfe5de8
> (gdb) print &shf
> Address requested for identifier "shf" which is in register $v10
> (gdb) print $v10
> $6 = {v4_float = {1.43352833e-42, -4.22639375e+37, 0, 0}, v2_double = {2.1729070589754877e-311, 0}, v16_int8 = {
>     0, 0, 3, -1, -3, -2, 93, -24, 0, 0, 0, 0, 0, 0, 0, 0}, v8_int16 = {0, 1023, -514, 24040, 0, 0, 0, 0},
>   v4_int32 = {1023, -33661464, 0, 0}, v2_int64 = {4398012849640, 0}, uint128 = 81129017470195127308370827018240}
>
> 0x3FFFDFE5DE8 is 4398012849640 which is in v2_int64, found.
[…]
> Breakpoint 2, comsub (fn=14, cp=0x0, xp=<synthetic pointer>) at ../../eval.c:1609
> 1609                    subst_exstat = exstat & 0xFF;
[…]
> (gdb) print $v10
> $7 = {v4_float = {0, 0, 0, 0}, v2_double = {0, 0}, v16_int8 = {0 <repeats 16 times>}, v8_int16 = {0, 0, 0, 0,
>     0, 0, 0, 0}, v4_int32 = {0, 0, 0, 0}, v2_int64 = {0, 0}, uint128 = 0}

------------------------------------------------------------------

So, setjmp/longjmp in klibc save f1/f3/f5/f7 (as shown on Wikipedia
https://en.wikipedia.org/wiki/Calling_convention#IBM_System/360_and_successors
“the z/Architecture ABI,[11] used in Linux” a page down), while
glibc’s save f8–f15 instead.

https://share.confex.com/share/124/webprogram/Handout/Session16897/SHARE_Seattle_2015_SIMD.pdf
shows that the vector registers overlap and extend the FPU registers.

(gdb) info float
[…]
f10            2.172907066248134e-311 (raw 0x000003fffdfe9768)
(gdb) print shf
$2 = (struct shf *) 0x3fffdfe9768

The real questions here are:

• is register v10 (vector extension) even supposed to be used?
• klibc does not really support the FPU anyway
• the half of v10 that equals f10 just HAPPENS to be saved by
  glibc, but what if the upper half, that is outside of the FPU,
  is used?
• where *is* the s390x̲ ABI documented anyway? syscall(2) has the
  kernel side only

Building with -mno-vx does not seem to help, %f* are still in
the .s files generated by gcc.

So I assume klibc should save registers f8–15 on s390x but what
happened to f1/f3/f5/f7?

Thanks,
//mirabilos
-- 
[17:15:07] Lukas Degener: Kleines Asterix-Latinum für Softwaretechniker:
	   veni, vidi, fixi(t) ;-)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.