summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-03-05 04:39:24 +0000
committermarcel <marcel@FreeBSD.org>2003-03-05 04:39:24 +0000
commitd4ee62b07a76bf06911d862a0e2084a2309efa36 (patch)
tree43c9fbba16caef13b08438e9431452fba63c0dde
parentcf2b37334bdcf41af17a17f34a5d80417cc188d8 (diff)
downloadFreeBSD-src-d4ee62b07a76bf06911d862a0e2084a2309efa36.zip
FreeBSD-src-d4ee62b07a76bf06911d862a0e2084a2309efa36.tar.gz
Fix threaded applications on ia64 that are linked dynamicly. We did
not save (restore) the global pointer (GP) in the jmpbuf in setjmp (longjmp) because it's not needed in general. GP is considered a scratch register at callsites and hence is always restored after a call (when it's possible that the call resolves to a symbol in a different loadmodule; otherwise GP does not have to be saved and restored at all), including calls to setjmp/longjmp. There's just one problem with this now that we use setjmp/longjmp for context switching: A new context must have GP defined properly for the thread's entry point. This means that we need to put GP in the jmpbuf and consequently that we have to restore is in longjmp. This automaticly requires us to save it as well. When setjmp/longjmp isn't used for context switching, this can be reverted again.
-rw-r--r--lib/libc/ia64/gen/_setjmp.S8
-rw-r--r--lib/libc_r/uthread/pthread_private.h1
-rw-r--r--sys/ia64/include/setjmp.h3
3 files changed, 8 insertions, 4 deletions
diff --git a/lib/libc/ia64/gen/_setjmp.S b/lib/libc/ia64/gen/_setjmp.S
index a48e5f1..8e3ba12 100644
--- a/lib/libc/ia64/gen/_setjmp.S
+++ b/lib/libc/ia64/gen/_setjmp.S
@@ -171,10 +171,11 @@ ENTRY(_setjmp, 1)
mov r3 = b4
;;
st8 [r11] = r2, J_B5-J_B3
- st8 [r10] = r3
+ st8 [r10] = r3, J_GP-J_B4
mov r2 = b5
;;
st8 [r11] = r2
+ st8 [r10] = r1
;;
//
// return
@@ -290,11 +291,12 @@ ENTRY(___longjmp, 2)
mov b1 = r2
mov b2 = r3
ld8 r2 = [r10], J_B5-J_B3
- ld8 r3 = [r11],
+ ld8 r3 = [r11], J_GP-J_B4
;;
mov b3 = r2
- mov b4 = r3
+ mov b4 = r3
ld8 r2 = [r10]
+ ld8 r1 = [r11]
ld8 r21 = [r31] // get user unat
;;
mov b5 = r2
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index b2f7a61..143772d 100644
--- a/lib/libc_r/uthread/pthread_private.h
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -109,6 +109,7 @@
#define SET_RETURN_ADDR_JB(jb, ra) \
do { \
*((unsigned long*)JMPBUF_ADDR_OF(jb,J_B0)) = ((long*)(ra))[0]; \
+ *((unsigned long*)JMPBUF_ADDR_OF(jb,J_GP)) = ((long*)(ra))[1]; \
*((unsigned long*)JMPBUF_ADDR_OF(jb,J_PFS)) &= ~0x1FFFFFFFFFUL; \
} while (0)
#define SET_STACK_JB(jb, stk, sz) \
diff --git a/sys/ia64/include/setjmp.h b/sys/ia64/include/setjmp.h
index 208e072..6f4fab9 100644
--- a/sys/ia64/include/setjmp.h
+++ b/sys/ia64/include/setjmp.h
@@ -88,10 +88,11 @@
#define J_B5 0x1d0
#define J_SIGMASK 0x1d8
#define J_SIGSET 0x1e0
+#define J_GP 0x1f0
#endif /* __BSD_VISIBLE */
/*
- * We have 16 bytes left for future use, but it's a nice round,
+ * We have 8 bytes left for future use, but it's a nice round,
* but above all large number. Size is in bytes.
*/
#define _JMPBUFSZ 0x200
OpenPOWER on IntegriCloud