about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@systemhalted.org>2012-10-29 23:16:44 -0400
committerCarlos O'Donell <carlos@systemhalted.org>2012-10-29 23:16:44 -0400
commite22f413005ccb0080ef1f13e59a1bc8aa36105cb (patch)
treefd74b46c6b1732f8511e23fba3abe207f6a68e75
parent4ebdb0102714696914e9425bf2e4c40666ee9beb (diff)
downloadglibc-e22f413005ccb0080ef1f13e59a1bc8aa36105cb.tar.gz
glibc-e22f413005ccb0080ef1f13e59a1bc8aa36105cb.tar.xz
glibc-e22f413005ccb0080ef1f13e59a1bc8aa36105cb.zip
hppa: Fix r19 save and restore.
We must save and restore r19 in both PIC and non-PIC
situations since the kernel paths that clobber r19
are independent of that PIC-ness of userspace.
In addition we choose r4 as the temporary register over
r3 which is being used by recent gcc's as the frame
pointer.
-rw-r--r--ports/ChangeLog.hppa9
-rw-r--r--ports/sysdeps/unix/sysv/linux/hppa/sysdep.h40
2 files changed, 27 insertions, 22 deletions
diff --git a/ports/ChangeLog.hppa b/ports/ChangeLog.hppa
index 6d5d5a33c1..b30a61cb30 100644
--- a/ports/ChangeLog.hppa
+++ b/ports/ChangeLog.hppa
@@ -1,5 +1,14 @@
 2012-10-29  Carlos O'Donell  <carlos@systemhalted.org>
 
+	* sysdeps/unix/sysv/linux/hppa/sysdep.h: Document register clobbering.
+	[PIC](TREG, SAVE_PIC, LOAD_PIC, TREG_ASM, SAVE_ASM_PIC, LOAD_ASM_PIC
+	CLOB_TREG, PIC_REG_DEF, PIC_REG_USE): Move...
+	(TREG, SAVE_PIC, LOAD_PIC, TREG_ASM, SAVE_ASM_PIC, LOAD_ASM_PIC
+	CLOB_TREG, PIC_REG_DEF, PIC_REG_USE): ... to here.
+	[!PIC](TREG, SAVE_PIC, LOAD_PIC, TREG_ASM, SAVE_ASM_PIC, LOAD_ASM_PIC
+	CLOB_TREG, PIC_REG_DEF, PIC_REG_USE): Remove.
+	(TREG): Use r4.
+
 	* sysdeps/unix/sysv/linux/hppa/sysdep.h: Don't include sys/syscall.h.
 	Document nop removal.
 	(PSEUDO): Remove nop.
diff --git a/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h b/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
index 5c0db64b7e..daf2eafdb5 100644
--- a/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
+++ b/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
@@ -32,32 +32,28 @@
 #undef SYS_ify
 #define SYS_ify(syscall_name)	(__NR_##syscall_name)
 
+/* The vfork, fork, and clone syscalls clobber r19
+ * and r21. We list r21 as either clobbered or as an
+ * input to a 6-argument syscall. We must save and
+ * restore r19 in both PIC and non-PIC cases.
+ */
 /* WARNING: TREG must be a callee saves register so
    that it doesn't have to be restored after a call
    to another function */
-#ifdef PIC
-# define TREG %r3
-# define SAVE_PIC(SREG) copy %r19, SREG ASM_LINE_SEP
-# define LOAD_PIC(LREG) copy LREG, %r19 ASM_LINE_SEP
+#define TREG 4
+#define SAVE_PIC(SREG) \
+	copy %r19, SREG ASM_LINE_SEP	\
+	.cfi_register 19, SREG
+#define LOAD_PIC(LREG) \
+	copy LREG , %r19 ASM_LINE_SEP	\
+	.cfi_restore 19
 /* Inline assembly defines */
-# define TREG_ASM "%r4" /* Cant clobber r3, it holds framemarker */
-# define SAVE_ASM_PIC	"       copy %%r19, %" TREG_ASM "\n"
-# define LOAD_ASM_PIC	"       copy %" TREG_ASM ", %%r19\n"
-# define CLOB_TREG	TREG_ASM ,
-# define PIC_REG_DEF	register unsigned long __r19 asm("r19");
-# define PIC_REG_USE	, "r" (__r19)
-#else
-# define TREG %r3
-# define SAVE_PIC(SREG) nop ASM_LINE_SEP
-# define LOAD_PIC(LREG) nop ASM_LINE_SEP
-/* Inline assembly defines */
-# define TREG_ASM
-# define SAVE_ASM_PIC	"nop \n"
-# define LOAD_ASM_PIC	"nop \n"
-# define CLOB_TREG
-# define PIC_REG_DEF
-# define PIC_REG_USE
-#endif
+#define TREG_ASM "%r4" /* Cant clobber r3, it holds framemarker */
+#define SAVE_ASM_PIC	"       copy %%r19, %" TREG_ASM "\n"
+#define LOAD_ASM_PIC	"       copy %" TREG_ASM ", %%r19\n"
+#define CLOB_TREG	TREG_ASM ,
+#define PIC_REG_DEF	register unsigned long __r19 asm("r19");
+#define PIC_REG_USE	, "r" (__r19)
 
 #ifdef __ASSEMBLER__