This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ARM interworking support for glibc


This patch changes the ARM port to use the 'bx' instruction whenver
possible.  Along with the binutils changes I committed earlier this week,
and another binutils patch that Paul's working on, these changes are enough
to build an interworking-safe glibc and use Thumb in dynamic objects (on ARM
v5t; this doesn't try to fix up glibc for the stricter v4t requirements).

Please apply if the patch is OK.

-- 
Daniel Jacobowitz

2004-11-18  Daniel Jacobowitz  <dan@codesourcery.com>

	* sysdeps/arm/sysdep.h: Define __USE_BX__ if bx is available.
	Use it instead of __THUMB_INTERWORK__.  Make RETINSTR take
	only a condition and a register.
	* sysdeps/arm/dl-machine.h: Use __USE_BX__ instead of
	__THUMB_INTERWORK__.
	(_dl_start_user): Use BX.
	* sysdeps/arm/strlen.S: Use DO_RET.
	* sysdeps/unix/arm/brk.S, sysdeps/unix/arm/fork.S,
	sysdeps/unix/arm/sysdep.S, sysdeps/unix/arm/sysdep.h: Likewise.
	* sysdeps/unix/sysv/linux/arm/clone.S,
	sysdeps/unix/sysv/linux/arm/mmap.S,
	sysdeps/unix/sysv/linux/arm/mmap64.S,
	sysdeps/unix/sysv/linux/arm/socket.S,
	sysdeps/unix/sysv/linux/arm/sysdep.h,
	sysdeps/unix/sysv/linux/arm/vfork.S: Update uses of RETINSTR.

2004-11-18  Daniel Jacobowitz  <dan@codesourcery.com>

	* sysdeps/unix/sysv/linux/arm/sysdep-cancel.h: Update RETINSTR use.
	* sysdeps/unix/sysv/linux/arm/vfork.S: Likewise.

Index: linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h,v
retrieving revision 1.6
diff -u -p -r1.6 sysdep-cancel.h
--- linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h	6 Jun 2003 17:31:40 -0000	1.6
+++ linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h	17 Nov 2004 19:57:27 -0000
@@ -112,7 +112,7 @@ extern int __local_multiple_threads attr
 #   define MAYBE_SAVE_LR						\
   str lr, [sp, $-4]!;
 #   define PSEUDO_RET_MOV						\
-  RETINSTR(movcc, pc, lr);						\
+  RETINSTR(cc, lr);							\
   b PLTJMP(SYSCALL_ERROR)
 #   define PSEUDO_PROLOGUE
 #  else
Index: linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S,v
retrieving revision 1.3
diff -u -p -r1.3 vfork.S
--- linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S	17 Sep 2003 18:07:04 -0000	1.3
+++ linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S	17 Nov 2004 19:57:49 -0000
@@ -46,7 +46,7 @@ ENTRY (__vfork)
 		
 	swi	__NR_vfork
 	cmn	a1, #4096
-	RETINSTR(movcc, pc, lr)
+	RETINSTR(cc, lr)
 
 #ifndef __ASSUME_VFORK_SYSCALL
 	/* Check if vfork syscall is known at all.  */
@@ -60,7 +60,7 @@ ENTRY (__vfork)
 	/* If we don't have vfork, fork is close enough.  */
 	swi	__NR_fork
 	cmn	a1, #4096
-	RETINSTR(movcc, pc, lr)
+	RETINSTR(cc, lr)
 #elif !defined __NR_vfork
 # error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"
 #endif
Index: sysdeps/arm/dl-machine.h
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/arm/dl-machine.h,v
retrieving revision 1.48
diff -u -p -r1.48 dl-machine.h
--- sysdeps/arm/dl-machine.h	29 Apr 2004 20:06:49 -0000	1.48
+++ sysdeps/arm/dl-machine.h	18 Nov 2004 17:35:59 -0000
@@ -123,7 +123,7 @@ elf_machine_runtime_setup (struct link_m
   return lazy;
 }
 
-#if defined(__THUMB_INTERWORK__)
+#if defined(__USE_BX__)
 #define BX(x) "bx\t" #x
 #else
 #define BX(x) "mov\tpc, " #x
@@ -293,7 +293,7 @@ _dl_start_user:\n\
 	ldr	r0, .L_FINI_PROC\n\
 	add	r0, sl, r0\n\
 	@ jump to the user_s entry point\n\
-	mov	pc, r6\n\
+	" BX(r6) "\n\
 .L_GET_GOT:\n\
 	.word	_GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n\
 .L_SKIP_ARGS:\n\
Index: sysdeps/arm/strlen.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/arm/strlen.S,v
retrieving revision 1.5
diff -u -p -r1.5 strlen.S
--- sysdeps/arm/strlen.S	11 Jun 2004 10:15:34 -0000	1.5
+++ sysdeps/arm/strlen.S	17 Nov 2004 20:03:40 -0000
@@ -68,6 +68,6 @@ Llastword:				@ drop through to here onc
 	tstne   r2, $0x00ff0000         @ (if first three all non-zero, 4th
 	addne   r0, r0, $1              @  must be zero)
 #endif
-	RETINSTR(mov,pc,lr)
+	DO_RET(lr)
 END(strlen)
 libc_hidden_builtin_def (strlen)
Index: sysdeps/arm/sysdep.h
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/arm/sysdep.h,v
retrieving revision 1.10
diff -u -p -r1.10 sysdep.h
--- sysdeps/arm/sysdep.h	17 Sep 2003 18:09:36 -0000	1.10
+++ sysdeps/arm/sysdep.h	18 Nov 2004 17:44:46 -0000
@@ -19,6 +19,11 @@
 
 #include <sysdeps/generic/sysdep.h>
 
+#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
+     && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__))
+# define __USE_BX__
+#endif
+
 #ifdef	__ASSEMBLER__
 
 /* Syntactic details of assembler.  */
@@ -50,20 +55,22 @@
 #ifdef __APCS_32__
 #define LOADREGS(cond, base, reglist...)\
 	ldm##cond	base,reglist
-#define RETINSTR(instr, regs...)\
-	instr	regs
-#ifdef __THUMB_INTERWORK__
+#ifdef __USE_BX__
+#define RETINSTR(cond, reg)	\
+	bx##cond	reg
 #define DO_RET(_reg)		\
 	bx _reg
 #else
+#define RETINSTR(cond, reg)	\
+	mov##cond	pc, reg
 #define DO_RET(_reg)		\
 	mov pc, _reg
 #endif
 #else  /* APCS-26 */
 #define LOADREGS(cond, base, reglist...)\
 	ldm##cond	base,reglist^
-#define RETINSTR(instr, regs...)\
-	instr##s	regs
+#define RETINSTR(cond, reg)	\
+	mov##cond##s	pc, reg
 #define DO_RET(_reg)		\
 	movs pc, _reg
 #endif
Index: sysdeps/unix/arm/brk.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/arm/brk.S,v
retrieving revision 1.5
diff -u -p -r1.5 brk.S
--- sysdeps/unix/arm/brk.S	24 Jul 2002 17:36:14 -0000	1.5
+++ sysdeps/unix/arm/brk.S	17 Nov 2004 20:06:20 -0000
@@ -43,7 +43,7 @@ SYSCALL__ (brk, 1)
 #endif
 	str r0, [r1]
 	mov r0, $0
-	RETINSTR(mov, pc, r14)
+	DO_RET (r14)
 #ifdef PIC
 1:	.long _GLOBAL_OFFSET_TABLE_ - 2b - 8
 _cb_addr:
Index: sysdeps/unix/arm/fork.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/arm/fork.S,v
retrieving revision 1.6
diff -u -p -r1.6 fork.S
--- sysdeps/unix/arm/fork.S	31 Dec 2002 20:37:26 -0000	1.6
+++ sysdeps/unix/arm/fork.S	17 Nov 2004 20:17:20 -0000
@@ -27,7 +27,7 @@ SYSCALL__ (fork, 0)
 	   R0&-1==R0, and the child gets R0&0==0.  */
 	sub r1, r1, $1
 	and r0, r0, r1
-	RETINSTR(mov, pc, r14)
+	DO_RET (r14)
 PSEUDO_END (__fork)
 libc_hidden_def (__fork)
 
Index: sysdeps/unix/arm/sysdep.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/arm/sysdep.S,v
retrieving revision 1.6
diff -u -p -r1.6 sysdep.S
--- sysdeps/unix/arm/sysdep.S	8 Jan 2003 00:14:43 -0000	1.6
+++ sysdeps/unix/arm/sysdep.S	17 Nov 2004 20:17:51 -0000
@@ -50,7 +50,7 @@ syscall_error:
 	ldr r1, 1f
 	str r0, [r1]
 	mvn r0, $0
-	RETINSTR(mov, pc, r14)
+	DO_RET (r14)
 
 1:	.long C_SYMBOL_NAME(errno)
 #else
@@ -60,7 +60,7 @@ syscall_error:
 0:	add r2, pc, r2
 	str r0, [r1, r2]
 	mvn r0, $0
-	RETINSTR(mov, pc, r14)
+	DO_RET (r14)
 
 1:	.word _GLOBAL_OFFSET_TABLE_ - 0b - 8
 2:	.word C_SYMBOL_NAME(errno)(GOTOFF)
Index: sysdeps/unix/arm/sysdep.h
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/arm/sysdep.h,v
retrieving revision 1.6
diff -u -p -r1.6 sysdep.h
--- sysdeps/unix/arm/sysdep.h	6 Jul 2001 04:56:07 -0000	1.6
+++ sysdeps/unix/arm/sysdep.h	17 Nov 2004 20:17:45 -0000
@@ -24,7 +24,7 @@
 
 #ifdef __ASSEMBLER__
 
-#define ret		RETINSTR(mov, pc, r14)
+#define ret		DO_RET (r14)
 #define MOVE(a,b)	mov b,a
 
 #endif
Index: sysdeps/unix/sysv/linux/arm/clone.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/sysv/linux/arm/clone.S,v
retrieving revision 1.7
diff -u -p -r1.7 clone.S
--- sysdeps/unix/sysv/linux/arm/clone.S	21 Dec 2002 18:36:55 -0000	1.7
+++ sysdeps/unix/sysv/linux/arm/clone.S	17 Nov 2004 20:18:23 -0000
@@ -45,7 +45,7 @@ ENTRY(__clone)
 	swi	SYS_ify(clone)
 	movs	a1, a1
 	blt	PLTJMP(C_SYMBOL_NAME(__syscall_error))
-	RETINSTR(movne, pc, lr)
+	RETINSTR(ne, lr)
 
 	@ pick the function arg and call address off the stack and execute
 	ldr	r0, [sp, #4]
Index: sysdeps/unix/sysv/linux/arm/mmap.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/sysv/linux/arm/mmap.S,v
retrieving revision 1.6
diff -u -p -r1.6 mmap.S
--- sysdeps/unix/sysv/linux/arm/mmap.S	14 Sep 2003 19:54:40 -0000	1.6
+++ sysdeps/unix/sysv/linux/arm/mmap.S	17 Nov 2004 20:18:41 -0000
@@ -51,7 +51,7 @@ ENTRY (__mmap)
 	ldr	r5, [sp], #4
 
 	cmn	r0, $4096
-	RETINSTR(movcc, pc, lr)
+	RETINSTR(cc, lr)
 	b	PLTJMP(syscall_error)
 
 .Linval:
@@ -83,7 +83,7 @@ ENTRY (__mmap)
 	add	sp, sp, #16
 
 	cmn	r0, $4096
-	RETINSTR(movcc, pc, lr)
+	RETINSTR(cc, lr)
 	b	PLTJMP(syscall_error);
 #endif
 
Index: sysdeps/unix/sysv/linux/arm/mmap64.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/sysv/linux/arm/mmap64.S,v
retrieving revision 1.6
diff -u -p -r1.6 mmap64.S
--- sysdeps/unix/sysv/linux/arm/mmap64.S	14 Sep 2003 19:54:53 -0000	1.6
+++ sysdeps/unix/sysv/linux/arm/mmap64.S	17 Nov 2004 20:18:50 -0000
@@ -43,12 +43,12 @@ ENTRY (__mmap64)
 # ifdef __ASSUME_MMAP2_SYSCALL
 	ldr	r4, [sp], #4
 	ldr	r5, [sp], #4
-	RETINSTR(movcc, pc, lr)	
+	RETINSTR(cc, lr)	
 	b	PLTJMP(syscall_error)
 # else
 	ldrcc	r4, [sp], #4
 	ldrcc	r5, [sp], #4
-	RETINSTR(movcc, pc, lr)
+	RETINSTR(cc, lr)
 	cmn	r0, $ENOSYS
 	bne	.Lerror
 	/* The current kernel does not support mmap2.  Fall back to plain
Index: sysdeps/unix/sysv/linux/arm/socket.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/sysv/linux/arm/socket.S,v
retrieving revision 1.11
diff -u -p -r1.11 socket.S
--- sysdeps/unix/sysv/linux/arm/socket.S	12 Jan 2003 09:06:28 -0000	1.11
+++ sysdeps/unix/sysv/linux/arm/socket.S	17 Nov 2004 20:18:58 -0000
@@ -91,7 +91,7 @@ ENTRY (__socket)
 
 	/* r0 is < 0 if there was an error.  */
 	cmn r0, $124
-	RETINSTR(movcc, pc, r14)
+	RETINSTR(cc, r14)
 	b PLTJMP(SYSCALL_ERROR)
 
 #if defined NEED_CANCELLATION && defined CENABLE
@@ -114,7 +114,7 @@ ENTRY (__socket)
 
 	/* r0 is < 0 if there was an error.  */
 	cmn r0, $124
-	RETINSTR(movcc, pc, r14)
+	RETINSTR(cc, r14)
 	b PLTJMP(SYSCALL_ERROR)
 #endif
 
Index: sysdeps/unix/sysv/linux/arm/sysdep.h
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/sysv/linux/arm/sysdep.h,v
retrieving revision 1.25
diff -u -p -r1.25 sysdep.h
--- sysdeps/unix/sysv/linux/arm/sysdep.h	25 Aug 2003 18:30:43 -0000	1.25
+++ sysdeps/unix/sysv/linux/arm/sysdep.h	17 Nov 2004 20:19:36 -0000
@@ -54,7 +54,7 @@
     cmn r0, $4096;
 
 #define PSEUDO_RET							      \
-    RETINSTR(movcc, pc, lr);						      \
+    RETINSTR(cc, lr);							      \
     b PLTJMP(SYSCALL_ERROR)
 #undef ret
 #define ret PSEUDO_RET
@@ -71,7 +71,7 @@
     DO_CALL (syscall_name, args);
 
 #define PSEUDO_RET_NOERRNO						      \
-    RETINSTR(mov, pc, lr);
+    DO_RET (lr);
 
 #undef ret_NOERRNO
 #define ret_NOERRNO PSEUDO_RET_NOERRNO
Index: sysdeps/unix/sysv/linux/arm/vfork.S
===================================================================
RCS file: /big/fsf/rsync/glibc-cvs/libc/sysdeps/unix/sysv/linux/arm/vfork.S,v
retrieving revision 1.8
diff -u -p -r1.8 vfork.S
--- sysdeps/unix/sysv/linux/arm/vfork.S	17 Sep 2003 18:09:53 -0000	1.8
+++ sysdeps/unix/sysv/linux/arm/vfork.S	17 Nov 2004 20:19:44 -0000
@@ -32,7 +32,7 @@ ENTRY (__vfork)
 #ifdef __NR_vfork
 	swi	__NR_vfork
 	cmn	a1, #4096
-	RETINSTR(movcc, pc, lr)
+	RETINSTR(cc, lr)
 
 # ifdef __ASSUME_VFORK_SYSCALL
 	b	PLTJMP(C_SYMBOL_NAME(__syscall_error))
@@ -47,7 +47,7 @@ ENTRY (__vfork)
 	/* If we don't have vfork, fork is close enough.  */
 	swi	__NR_fork
 	cmn	a1, #4096
-	RETINSTR(movcc, pc, lr)
+	RETINSTR(cc, lr)
     	b	PLTJMP(C_SYMBOL_NAME(__syscall_error))
 #elif !defined __NR_vfork
 # error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]