summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authortmm <tmm@FreeBSD.org>2003-01-05 22:17:32 +0000
committertmm <tmm@FreeBSD.org>2003-01-05 22:17:32 +0000
commit6e68a2b1ca0c29fc620a29364a84c465b0d72314 (patch)
treedbc36e6b5ef3970407b2b897ad01b4c39a34d859 /lib/libc
parentd16b835650e0e0df5195fb36fc746a92ec47967f (diff)
downloadFreeBSD-src-6e68a2b1ca0c29fc620a29364a84c465b0d72314.zip
FreeBSD-src-6e68a2b1ca0c29fc620a29364a84c465b0d72314.tar.gz
Rewrite longjmp() and _longjmp() to directly restore the saved frame,
instead of unwinding the call stack. This makes them usable to switch stacks, e.g. for libc_r. Do not save the frame pointer in setjmp() and _setjmp(), it is not needed any more. Rename _longjmp() to ___longjmp(), with a weak alias to _longjmp(), like the other architectures did.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/sparc64/gen/_setjmp.S42
-rw-r--r--lib/libc/sparc64/gen/setjmp.S32
2 files changed, 19 insertions, 55 deletions
diff --git a/lib/libc/sparc64/gen/_setjmp.S b/lib/libc/sparc64/gen/_setjmp.S
index 645121b..c48876e 100644
--- a/lib/libc/sparc64/gen/_setjmp.S
+++ b/lib/libc/sparc64/gen/_setjmp.S
@@ -58,42 +58,26 @@ __FBSDID("$FreeBSD$");
* will generate a "return(v?v:1)" from
* the last call to
* _setjmp(a)
- * by unwinding the call stack.
+ * by restoring the previous context.
* The previous signal state is NOT restored.
*/
ENTRY(_setjmp)
stx %sp, [%o0 + _JB_SP]
stx %o7, [%o0 + _JB_PC]
- stx %fp, [%o0 + _JB_FP]
retl
clr %o0
END(_setjmp)
-ENTRY(_longjmp)
- mov 1, %g1
- movrnz %o1, %o1, %g1 ! compute v ? v : 1
- mov %o0, %g2
- ldx [%g2 + _JB_FP], %g3 ! fetch callers frame
-1: cmp %fp, %g3 ! compare against desired frame
- bl,a 1b ! if below,
- restore ! pop frame and loop
- be,a 2f ! if there,
- ldx [%g2 + _JB_SP], %o0 ! fetch return %sp
-
-.Lbotch:
- call CNAME(longjmperror)
- nop
- call CNAME(abort)
- nop
- illtrap
-
-2: cmp %o0, %sp ! %sp must not decrease
- bge,a 3f
- mov %o0, %sp ! it is OK, put it in place
- b,a .Lbotch
- nop
-3: ldx [%g2 + _JB_PC], %o7 ! fetch return address
- retl
- mov %g1, %o0 ! return v ? v : 1;
-END(_longjmp)
+ .weak CNAME(_longjmp)
+ .set CNAME(_longjmp),CNAME(___longjmp)
+ENTRY(___longjmp)
+ save %sp, -CCFSZ, %sp
+ flushw
+ ldx [%i0 + _JB_SP], %fp
+ ldx [%i0 + _JB_PC], %i7
+ mov 1, %i0
+ movrnz %i1, %i1, %i0
+ ret
+ restore
+END(___longjmp)
diff --git a/lib/libc/sparc64/gen/setjmp.S b/lib/libc/sparc64/gen/setjmp.S
index 201d8a6..5ad65a5 100644
--- a/lib/libc/sparc64/gen/setjmp.S
+++ b/lib/libc/sparc64/gen/setjmp.S
@@ -70,7 +70,6 @@ ENTRY(setjmp)
restore
stx %sp, [%o0 + _JB_SP]
stx %o7, [%o0 + _JB_PC]
- stx %fp, [%o0 + _JB_FP]
retl
clr %o0
END(setjmp)
@@ -79,34 +78,15 @@ END(setjmp)
.set CNAME(longjmp),CNAME(__longjmp)
ENTRY(__longjmp)
save %sp, -CCFSZ, %sp
+ flushw
mov SIG_SETMASK, %o0
add %i0, _JB_SIGMASK, %o1
call CNAME(sigprocmask)
clr %o2
- restore
- mov 1, %g1
- movrnz %o1, %o1, %g1
- mov %o0, %g2
- ldx [%g2 + _JB_FP], %g3
-1: cmp %fp, %g3
- bl,a 1b
+ ldx [%i0 + _JB_SP], %fp
+ ldx [%i0 + _JB_PC], %i7
+ mov 1, %i0
+ movrnz %i1, %i1, %i0
+ ret
restore
- be,a 2f
- ldx [%g2 + _JB_SP], %o0
-
-.Lbotch:
- call CNAME(longjmperror)
- nop
- call CNAME(abort)
- nop
- illtrap
-
-2: cmp %o0, %sp
- bge,a 3f
- mov %o0, %sp
- b,a .Lbotch
- nop
-3: ldx [%g2 + _JB_PC], %o7
- retl
- mov %g1, %o0
END(__longjmp)
OpenPOWER on IntegriCloud