[uClibc] Re: non-PIC ARM assembly

Joakim Tjernlund Joakim.Tjernlund at lumentis.se
Thu Jun 9 22:04:41 UTC 2005

> > 
> > 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.

This could possibly work for clone:
(Probably white space damaged)

#include <asm/errno.h>
#include <sys/syscall.h>

/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */

        .globl __clone;
        .type __clone,%function
        .align 4;
        @ sanity check args
        cmp     r0, #0
        cmpne   r1, #0
        moveq   r0, #-EINVAL
        beq     __error

        @ insert the args onto the new stack
        sub     r1, r1, #8
        str     r3, [r1, #4]
        @ save the function pointer as the 0th element
        str     r0, [r1]

        @ do the system call
        @ get flags
        mov     r0, r2
        @ new sp is already in r1
        swi     __NR_clone
        movs    a1, a1
        blt     __error
        movne    pc, lr

        @ pick the function arg and call address off the stack and execute
        ldr     r0, [sp, #4]
        mov     lr, pc
        ldr     pc, [sp]

        @ and we are done, passing the return value through r0
        b       _exit   (PLT)

        b       __syscall_error
        .size __clone,.-__clone;

        .globl  clone;
        .type clone,%function
        clone = __clone

With __syscall_error.c like so:

#include <errno.h>

/* This routine is jumped to by all the syscall handlers, to stash
 * an error number into errno.  */
int attribute_hidden __syscall_error (int err_no)
        __set_errno (err_no);
        return -1;

More information about the uClibc mailing list