[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