NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-sparc/59307: kernel longjmp(9) fails to make setjmp(9) return 1



>Number:         59307
>Category:       port-sparc
>Synopsis:       kernel longjmp(9) fails to make setjmp(9) return 1
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-sparc-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 17 05:25:00 +0000 2025
>Originator:     Taylor R Campbell
>Release:        current
>Organization:
I jumped because it sparced when I put a fork in the outlet Foundation
>Environment:
>Description:
Kernel longjmp(9) is supposed to make setjmp(9) return 1 -- it doesn't take a second argument for the return value.  But the sparc code does this:

   6044 ENTRY(longjmp)
   6045 	addcc	%o1, %g0, %g6	! compute v ? v : 1 in a global register
   6046 	be,a	0f
   6047 	 mov	1, %g6
   6048 0:

https://nxr.netbsd.org/xref/src/sys/arch/sparc/sparc/locore.s?r=1.285#6044

Here, because we have not executed `save' to cycle the register windows, %o0 is the first argument (label_t pointer), and %o1 -- normally the second argument register -- is garbage because longjmp(9) doesn't have a second argument.  Strictly speaking we have not documented that longjmp(9) make setjmp(9) return _exactly_ 1 -- it just has to return nonzero.  But, it's pretty weird to return register garbage!  So I think this should be changed to return exactly 1, unconditionally.

sparc64 has some similar logic, but with a conditional move instead, and after a `save' instruction so the second argument register is %i1 rather than %o1:

   7750 	movrz	%i1, %i1, %i2	! compute v ? v : 1

https://nxr.netbsd.org/xref/src/sys/arch/sparc64/sparc64/locore.s#7750
>How-To-Repeat:
code inspection
mess with ddb, probably
>Fix:
sparc: Change everything before the 0 label to: mov 1, %g6
sparc64: Change the movrz to: mov 1, %i2



Home | Main Index | Thread Index | Old Index