[uClibc] Re: non-PIC ARM assembly

Peter S. Mazinger ps.m at gmx.net
Fri Jun 10 08:23:05 UTC 2005


On Fri, 10 Jun 2005, Joakim Tjernlund wrote:

> > 
> > > 
> > > You are completely right about non-PIC code, clone.S/mmap64.S/vfork.S 
> > > produce. Currently in gentoo-land we have 2 corrections, one done by 
> > > Mike Frysinger (vapier), the other by me. Haven't tested Mike's version, 
> > > mine is running on a v4 LE removing all off the text relocations from 
> > > uclibc. I attach both of them, if you have arm asm knowledge, please 
> > > review them, correct them, and provide them ;)
> > 
> > Nope, this does not look right. Don't think you can have
> > a local version of errno in those assembler files. I think the best way is
> > to copy powerpc/__syscall_error.c(add a attribute_hidden while you are at it).
> > The rest you have to figure out.

the attached patch does:
- copied __syscall_error.c from powerpc and added to Makefile (where to 
	add attribute_hidden?)
- removed __syscall_error: from clone/mmap64/vfork.S and use above
- all (PLT) uses are ifdef'd __PIC__ (done in the other asm files as well)
- uses bits/errno.h instead of asm/errno.h
- added ifdef __NR_clone/__NR_fork to respective files
- instead of .globl clone and .type clone,%function use .weak clone
- the rest is white space cleanup

Peter

-- 
Peter S. Mazinger <ps dot m at gmx dot net>           ID: 0xA5F059F2
Key fingerprint = 92A4 31E1 56BC 3D5A 2D08  BB6E C389 975E A5F0 59F2
-------------- next part --------------
--- uClibc-0.9.27/libc/sysdeps/linux/arm/clone.S.pic~	2005-06-10 09:49:56 +0200
+++ uClibc-0.9.27/libc/sysdeps/linux/arm/clone.S	2005-06-10 10:06:43 +0200
@@ -20,21 +20,23 @@
 /* clone() is even more special than fork() as it mucks with stacks
    and invokes a function in the right context after its all over.  */
 
-#include <asm/errno.h>
+#define _ERRNO_H
+#include <bits/errno.h>
 #include <sys/syscall.h>
 
+#ifdef __NR_clone
 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
 
-.text
-.globl __clone;
-.type __clone,%function
-.align 4;
+	.text
+	.globl __clone;
+	.type __clone,%function
+	.align 4;
 __clone:
 	@ sanity check args
 	cmp	r0, #0
 	cmpne	r1, #0
 	moveq	r0, #-EINVAL
-	beq	__syscall_error (PLT)
+	beq	__error
 
 	@ insert the args onto the new stack
 	sub	r1, r1, #8
@@ -48,7 +50,7 @@
 	@ new sp is already in r1
 	swi	__NR_clone
 	movs	a1, a1
-	blt	__syscall_error  (PLT)
+	blt	__error
 	movne    pc, lr
 
 	@ pick the function arg and call address off the stack and execute
@@ -57,25 +59,22 @@
 	ldr 	pc, [sp]
 
 	@ and we are done, passing the return value through r0
-	b	_exit	(PLT)
+#ifdef __PIC__
+	b	_exit(PLT)
+#else
+	b	_exit
+#endif
+
+__error:
+#ifdef __PIC__
+	b	__syscall_error(PLT)
+#else
+	b	__syscall_error
+#endif
 
-__syscall_error:
-	/* Looks like the syscall choked -- set errno */
-	ldr  r3, .L4
-	/* Calculate the - of the syscall result, in case we need it */
-	rsb  r2, r0, $0
+	.size __clone,.-__clone;
 
-	/* errno = -result */
-	str  r2, [r9,r3]
-
-	/* return -1 */
-	mvn  r0, $0
-	mov  pc, lr
-.size __clone,.-__clone;
-
-.L4:  .word errno
-
-
-.globl	clone;
-    clone = __clone
+	.weak clone;
+	clone = __clone
 
+#endif
--- uClibc-0.9.27/libc/sysdeps/linux/arm/__syscall_error.c.pic~	2005-06-10 09:49:56 +0200
+++ uClibc-0.9.27/libc/sysdeps/linux/arm/__syscall_error.c	2005-06-10 09:50:16 +0200
@@ -0,0 +1,29 @@
+/* Wrapper around clone system call.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ * an error number into errno.  */
+int __syscall_error (int err_no)
+{
+	__set_errno (err_no);
+	return -1;
+}
+
--- uClibc-0.9.27/libc/sysdeps/linux/arm/Makefile.pic~	2005-06-10 09:49:56 +0200
+++ uClibc-0.9.27/libc/sysdeps/linux/arm/Makefile	2005-06-10 09:50:16 +0200
@@ -28,7 +28,7 @@
 	bsd-_setjmp.S sigrestorer.S mmap64.S
 SOBJS=$(patsubst %.S,%.o, $(SSRC))
 
-CSRC=brk.c syscall.c ioperm.c sigaction.c
+CSRC=brk.c syscall.c ioperm.c sigaction.c __syscall_error.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 
 OBJS=$(SOBJS) $(MOBJ) $(COBJS)
--- uClibc-0.9.27/libc/sysdeps/linux/arm/vfork.S.pic~	2005-06-10 09:49:56 +0200
+++ uClibc-0.9.27/libc/sysdeps/linux/arm/vfork.S	2005-06-10 10:07:01 +0200
@@ -20,52 +20,42 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
-#include <asm/errno.h>
+#define _ERRNO_H
+#include <bits/errno.h>
 #include <sys/syscall.h>
 
-
-
-		.text
-		.global vfork;
-		.type vfork,%function
-		.align 4;                                                               \
-
-
-
+#ifdef __NR_fork
+	.text
+	.global vfork;
+	.type vfork,%function
+	.align 4;                                                               \
 vfork:
 
 #ifdef __NR_vfork
-		swi		__NR_vfork
-		cmn		r0, #4096
-		movcc	pc, lr
-
-		/* Check if vfork even exists.  */
-		ldr     r1, =-ENOSYS
-		teq     r0, r1
-		bne     __syscall_error
+	swi	__NR_vfork
+	cmn	r0, #4096
+	movcc	pc, lr
+
+	/* Check if vfork even exists.  */
+	ldr     r1, =-ENOSYS
+	teq     r0, r1
+	bne     __error
 #endif
 
-		/* If we don't have vfork, use fork.  */
-		swi     __NR_fork
-		cmn     r0, #4096
-
-		/* Syscal worked.  Return to child/parent */
-		movcc   pc, lr
-
-__syscall_error:
-
-		/* Looks like the syscall choked -- set errno */
-		ldr  r3, .L4
-		/* Calculate the - of the syscall result, in case we need it */
-		rsb  r2, r0, $0
-
-		/* errno = -result */
-		str  r2, [r9,r3]
-
-		/* return -1 */
-		mvn  r0, $0
-		mov  pc, lr
-
-.L4:  .word errno
+	/* If we don't have vfork, use fork.  */
+	swi     __NR_fork
+	cmn     r0, #4096
+
+	/* Syscal worked.  Return to child/parent */
+	movcc   pc, lr
+
+__error:
+#ifdef __PIC__
+	b	__syscall_error(PLT)
+#else
+	b	__syscall_error
+#endif
 
+	.size vfork,.-vfork;
 
+#endif
--- uClibc-0.9.27/libc/sysdeps/linux/arm/mmap64.S.pic~	2005-06-10 09:49:56 +0200
+++ uClibc-0.9.27/libc/sysdeps/linux/arm/mmap64.S	2005-06-10 10:06:51 +0200
@@ -16,20 +16,18 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#define _ERRNO_H	1
 #include <features.h>
+#define _ERRNO_H
 #include <bits/errno.h>
 #include <sys/syscall.h>
 
 #if defined __UCLIBC_HAS_LFS__ && defined __NR_mmap2
 
-
 	/* The mmap2 system call takes six arguments, all in registers.  */
 	.text
 	.global mmap64;
 	.type mmap64,%function
 	.align 4;
-
 mmap64:
 	stmfd	sp!, {r4, r5, lr}
 	ldr	r5, [sp, $16]
@@ -47,33 +45,30 @@
 	ldmccfd	sp!, {r4, r5, pc}
 	cmn	r0, $ENOSYS
 	ldmnefd	sp!, {r4, r5, lr}
-	bne	__syscall_error (PLT)
+	bne	__error
 	/* The current kernel does not support mmap2.  Fall back to plain
 	   mmap if the offset is small enough.  */
 	ldr	r5, [sp, $20]
 	mov	r0, ip			@ first arg was clobbered
 	teq	r5, $0
 	ldmeqfd	sp!, {r4, r5, lr}
-	beq	mmap (PLT)
+#ifdef __PIC__
+	beq	mmap(PLT)
+#else
+	beq	mmap
+#endif
 .Linval:
 	mov	r0, $-EINVAL
 	ldmfd	sp!, {r4, r5, lr}
-	b	__syscall_error (PLT)
+	b	__error
 
-__syscall_error:
-	/* Looks like the syscall choked -- set errno */
-	ldr  r3, .L4
-	/* Calculate the - of the syscall result, in case we need it */
-	rsb  r2, r0, $0
-
-	/* errno = -result */
-	str  r2, [r9,r3]
-
-	/* return -1 */
-	mvn  r0, $0
-	mov  pc, lr
-.size mmap64,.-mmap64;
+__error:
+#ifdef __PIC__
+	b	__syscall_error(PLT)
+#else
+	b	__syscall_error
+#endif
 
-.L4:  .word errno
+	.size mmap64,.-mmap64;
 
 #endif
--- uClibc-0.9.27/libc/sysdeps/linux/arm/bsd-_setjmp.S.pic~	2005-06-10 10:02:14 +0200
+++ uClibc-0.9.27/libc/sysdeps/linux/arm/bsd-_setjmp.S	2005-06-10 10:02:38 +0200
@@ -30,5 +30,9 @@
 .align 4;
 _setjmp:
 	mov	r1, #0
-	b	__sigsetjmp (PLT)
+#ifdef __PIC__
+	b	__sigsetjmp(PLT)
+#else
+	b	__sigsetjmp
+#endif
 .size _setjmp,.-_setjmp;
--- uClibc-0.9.27/libc/sysdeps/linux/arm/bsd-setjmp.S.pic~	2005-06-10 10:02:50 +0200
+++ uClibc-0.9.27/libc/sysdeps/linux/arm/bsd-setjmp.S	2005-06-10 10:01:59 +0200
@@ -30,5 +30,9 @@
 .align 4;
 setjmp:
 	mov	r1, #1
-	b	__sigsetjmp (PLT)
+#ifdef __PIC__
+	b	__sigsetjmp(PLT)
+#else
+	b	__sigsetjmp
+#endif
 .size setjmp,.-setjmp;
--- uClibc-0.9.27/libc/sysdeps/linux/arm/setjmp.S.pic~	2005-06-10 10:03:22 +0200
+++ uClibc-0.9.27/libc/sysdeps/linux/arm/setjmp.S	2005-06-10 10:03:52 +0200
@@ -38,5 +38,9 @@
 	sub     r0, r0, #48
 
 	/* Make a tail call to __sigjmp_save; it takes the same args.  */
-	B	__sigjmp_save	(PLT)
+#ifdef __PIC__
+	B	__sigjmp_save(PLT)
+#else
+	B	__sigjmp_save
+#endif
 .size __sigsetjmp,.-__sigsetjmp;


More information about the uClibc mailing list