summaryrefslogtreecommitdiffstats
path: root/libc/sysdeps/linux/arm
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/arm')
-rw-r--r--libc/sysdeps/linux/arm/Makefile21
-rw-r--r--libc/sysdeps/linux/arm/__longjmp.S7
-rw-r--r--libc/sysdeps/linux/arm/bits/kernel_stat.h67
-rw-r--r--libc/sysdeps/linux/arm/bsd-_setjmp.S13
-rw-r--r--libc/sysdeps/linux/arm/bsd-setjmp.S13
-rw-r--r--libc/sysdeps/linux/arm/clone.S41
-rw-r--r--libc/sysdeps/linux/arm/crt0.S150
-rw-r--r--libc/sysdeps/linux/arm/mmap64.S41
-rw-r--r--libc/sysdeps/linux/arm/setjmp.S13
-rw-r--r--libc/sysdeps/linux/arm/sigrestorer.S8
-rw-r--r--libc/sysdeps/linux/arm/vfork.S63
11 files changed, 147 insertions, 290 deletions
diff --git a/libc/sysdeps/linux/arm/Makefile b/libc/sysdeps/linux/arm/Makefile
index 94929304e..77245307a 100644
--- a/libc/sysdeps/linux/arm/Makefile
+++ b/libc/sysdeps/linux/arm/Makefile
@@ -19,33 +19,37 @@
TOPDIR=../../../../
include $(TOPDIR)Rules.mak
-CRT0_SRC = crt0.S
-CRT0_OBJ = crt0.o crt1.o
-CRT0_DEPS=gmon-start.S
+CRT_SRC = crt1.S
+CRT_OBJ = crt1.o
+SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ))
CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S \
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)
+OBJS=$(SOBJS) $(COBJS)
OBJ_LIST=../../../obj.sysdeps.$(TARGET_ARCH)
all: $(OBJ_LIST)
-$(OBJ_LIST): $(OBJS) $(CRT0_OBJ) $(CTOR_TARGETS)
+$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS)
echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $(OBJ_LIST)
$(INSTALL) -d $(TOPDIR)lib/
- cp $(CRT0_OBJ) $(TOPDIR)lib/
+ cp $(CRT_OBJ) $(SCRT_OBJ) $(TOPDIR)lib/
-$(CRT0_OBJ): $(CRT0_SRC)
+$(CRT_OBJ): $(CRT_SRC)
$(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
$(STRIPTOOL) -x -R .note -R .comment $*.o
+$(SCRT_OBJ): $(CRT_SRC)
+ $(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* $< -c -o $*.o
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
$(SOBJS): %.o : %.S
$(CC) $(ASFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
@@ -83,4 +87,3 @@ headers:
clean:
$(RM) *.[oa] *~ core
$(RM) bits/sysnum.h
- $(RM) gmon-start.S
diff --git a/libc/sysdeps/linux/arm/__longjmp.S b/libc/sysdeps/linux/arm/__longjmp.S
index e280d842d..44837911b 100644
--- a/libc/sysdeps/linux/arm/__longjmp.S
+++ b/libc/sysdeps/linux/arm/__longjmp.S
@@ -23,9 +23,9 @@
#include <bits/setjmp.h>
-.globl __longjmp;
+.global __longjmp
.type __longjmp,%function
-.align 4;
+.align 4
__longjmp:
mov ip, r0 /* save jmp_buf pointer */
@@ -39,4 +39,5 @@ __longjmp:
#endif
ldmia ip , {v1-v6, sl, fp, sp, pc}
-.size __longjmp,.-__longjmp;
+
+.size __longjmp,.-__longjmp
diff --git a/libc/sysdeps/linux/arm/bits/kernel_stat.h b/libc/sysdeps/linux/arm/bits/kernel_stat.h
index bfef64cea..70d268c19 100644
--- a/libc/sysdeps/linux/arm/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/arm/bits/kernel_stat.h
@@ -6,51 +6,68 @@
* different opinion on the subject... */
struct kernel_stat {
+#if defined(__ARMEB__)
unsigned short st_dev;
unsigned short __pad1;
+#else
+ unsigned long st_dev;
+#endif
unsigned long st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
+#if defined(__ARMEB__)
unsigned short st_rdev;
unsigned short __pad2;
+#else
+ unsigned long st_rdev;
+#endif
unsigned long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
- unsigned long __unused1;
+ unsigned long st_atime_nsec;
unsigned long st_mtime;
- unsigned long __unused2;
+ unsigned long st_mtime_nsec;
unsigned long st_ctime;
- unsigned long __unused3;
+ unsigned long st_ctime_nsec;
unsigned long __unused4;
unsigned long __unused5;
};
+/* see the notes in common/xstatconv.c about why we have these
+ * funky funk unions here ... i blame the schools */
struct kernel_stat64 {
- unsigned short st_dev;
- unsigned char __pad0[10];
+ unsigned long long st_dev;
+ unsigned char __pad0[4];
+
#define _HAVE_STAT64___ST_INO
- unsigned long __st_ino;
- unsigned int st_mode;
- unsigned int st_nlink;
- unsigned long st_uid;
- unsigned long st_gid;
- unsigned short st_rdev;
- unsigned char __pad3[10];
- long long st_size;
- unsigned long st_blksize;
- unsigned long st_blocks; /* Number 512-byte blocks allocated. */
- unsigned long __pad4; /* future possible st_blocks high bits */
- unsigned long st_atime;
- unsigned long __pad5;
- unsigned long st_mtime;
- unsigned long __pad6;
- unsigned long st_ctime;
- unsigned long __pad7; /* will be high 32 bits of ctime someday */
- unsigned long long st_ino;
-};
+ unsigned long __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ unsigned long st_uid;
+ unsigned long st_gid;
-#endif /* _BITS_STAT_STRUCT_H */
+ unsigned long long st_rdev;
+ unsigned char __pad3[4];
+ long long st_size;
+ unsigned long st_blksize;
+#if defined(__ARMEB__)
+ unsigned long __pad4; /* future possible st_blocks high bits */
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+#else
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+ unsigned long __pad4; /* future possible st_blocks high bits */
+#endif
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+ unsigned long long st_ino;
+} __attribute__((packed));
+
+#endif /* _BITS_STAT_STRUCT_H */
diff --git a/libc/sysdeps/linux/arm/bsd-_setjmp.S b/libc/sysdeps/linux/arm/bsd-_setjmp.S
index 7f092c18b..3f3a986b3 100644
--- a/libc/sysdeps/linux/arm/bsd-_setjmp.S
+++ b/libc/sysdeps/linux/arm/bsd-_setjmp.S
@@ -25,10 +25,15 @@
#define _ASM
#include <bits/setjmp.h>
-.globl _setjmp;
+.global _setjmp
.type _setjmp,%function
-.align 4;
+.align 4
_setjmp:
mov r1, #0
- b __sigsetjmp (PLT)
-.size _setjmp,.-_setjmp;
+#ifdef __PIC__
+ b __sigsetjmp(PLT)
+#else
+ b __sigsetjmp
+#endif
+
+.size _setjmp,.-_setjmp
diff --git a/libc/sysdeps/linux/arm/bsd-setjmp.S b/libc/sysdeps/linux/arm/bsd-setjmp.S
index 16f077a79..3e5ff59fa 100644
--- a/libc/sysdeps/linux/arm/bsd-setjmp.S
+++ b/libc/sysdeps/linux/arm/bsd-setjmp.S
@@ -25,10 +25,15 @@
#define _ASM
#include <bits/setjmp.h>
-.globl setjmp;
+.global setjmp
.type setjmp,%function
-.align 4;
+.align 4
setjmp:
mov r1, #1
- b __sigsetjmp (PLT)
-.size setjmp,.-setjmp;
+#ifdef __PIC__
+ b __sigsetjmp(PLT)
+#else
+ b __sigsetjmp
+#endif
+
+.size setjmp,.-setjmp
diff --git a/libc/sysdeps/linux/arm/clone.S b/libc/sysdeps/linux/arm/clone.S
index f417be07f..a4d5f99bd 100644
--- a/libc/sysdeps/linux/arm/clone.S
+++ b/libc/sysdeps/linux/arm/clone.S
@@ -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;
+.global __clone
.type __clone,%function
-.align 4;
+.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 @@ __clone:
@ 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,18 @@ __clone:
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
-__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
+__error:
+ b __syscall_error
- /* errno = -result */
- str r2, [r9,r3]
+.size __clone,.-__clone
- /* return -1 */
- mvn r0, $0
- mov pc, lr
-.size __clone,.-__clone;
-
-.L4: .word errno
-
-
-.globl clone;
- clone = __clone
+.weak clone
+ clone = __clone
+#endif
diff --git a/libc/sysdeps/linux/arm/crt0.S b/libc/sysdeps/linux/arm/crt0.S
deleted file mode 100644
index f58885d17..000000000
--- a/libc/sysdeps/linux/arm/crt0.S
+++ /dev/null
@@ -1,150 +0,0 @@
-/* When we enter this piece of code, the program stack looks like this:
- argc argument counter (integer)
- argv[0] program name (pointer)
- argv[1...N] program args (pointers)
- argv[argc-1] end of args (integer)
- NULL
- env[0...N] environment variables (pointers)
- NULL
-
- For uClinux it looks like this:
-
- argc argument counter (integer)
- argv char *argv[]
- envp char *envp[]
- argv[0] program name (pointer)
- argv[1...N] program args (pointers)
- argv[argc-1] end of args (integer)
- NULL
- env[0...N] environment variables (pointers)
- NULL
-
- When we are done here, we want
- a1=argc
- a2=argv[0]
- a3=argv[argc+1]
-
-ARM register quick reference:
-
- Name Number ARM Procedure Calling Standard Role
-
- a1 r0 argument 1 / integer result / scratch register / argc
- a2 r1 argument 2 / scratch register / argv
- a3 r2 argument 3 / scratch register / envp
- a4 r3 argument 4 / scratch register
- v1 r4 register variable
- v2 r5 register variable
- v3 r6 register variable
- v4 r7 register variable
- v5 r8 register variable
- sb/v6 r9 static base / register variable
- sl/v7 r10 stack limit / stack chunk handle / reg. variable
- fp r11 frame pointer
- ip r12 scratch register / new-sb in inter-link-unit calls
- sp r13 lower end of current stack frame
- lr r14 link address / scratch register
- pc r15 program counter
-*/
-
-#include <features.h>
-
-.text
- .global _start
- .type _start,%function
-#if defined L_crt0 || ! defined __UCLIBC_CTOR_DTOR__
- .type __uClibc_main,%function
-#else
- .weak _init
- .weak _fini
- .type __uClibc_start_main,%function
-#endif
-/* Stick in a dummy reference to main(), so that if an application
- * is linking when the main() function is in a static library (.a)
- * we can be sure that main() actually gets linked in */
- .type main,%function
-
-
-.text
-_start:
- /* clear the frame pointer */
- mov fp, #0
-
-#ifdef __ARCH_HAS_MMU__
- /* Load register r0 (argc) from the stack to its final resting place */
- ldr r0, [sp], #4
-
- /* Copy argv pointer into r1 -- which its final resting place */
- mov r1, sp
-
- /* Skip to the end of argv and put a pointer to whatever
- we find there (hopefully the environment) in r2 */
- add r2, r1, r0, lsl #2
- add r2, r2, #4
-
-#else
- /*
- * uClinux stacks look a little different from normal
- * MMU-full Linux stacks (for no good reason)
- */
- /* pull argc, argv and envp off the stack */
- ldr r0,[sp, #0]
- ldr r1,[sp, #4]
- ldr r2,[sp, #8]
-#endif
-
-#if (defined L_crt1 ) && defined __UCLIBC_CTOR_DTOR__
-#ifdef __PIC__
- /* Store the address of _init in r3 as an argument to main() */
- adr r5, .L_init
- ldr r3, .L_init
- add r3, r3, r5
-
- /* Push _fini onto the stack as the final argument to main() */
- ldr r4, .L_init + 4
- add r4, r4, r5
-#else
- /* Store the address of _init in r3 as an argument to main() */
- ldr r3, =_init
-
- /* Push _fini onto the stack as the final argument to main() */
- ldr r4, =_fini
-#endif
- stmfd sp!, {r4}
-
- /* Ok, now run uClibc's main() -- shouldn't return */
- bl __uClibc_start_main
-#else
- bl __uClibc_main
-#endif
-
- /* Crash if somehow `exit' returns anyways. */
- bl abort
-
-#if (defined L_crt1 ) && defined __UCLIBC_CTOR_DTOR__ && defined __PIC__
-.L_init:
- .word _init - .L_init
- .word _fini - .L_init
-#endif
-
-/* We need this stuff to make gdb behave itself, otherwise
- gdb will chokes with SIGILL when trying to debug apps.
-*/
- .section ".note.ABI-tag", "a"
- .align 4
- .long 1f - 0f
- .long 3f - 2f
- .long 1
-0: .asciz "GNU"
-1: .align 4
-2: .long 0
- .long 2,0,0
-3: .align 4
-
-/* Define a symbol for the first piece of initialized data. */
- .data
- .globl __data_start
-__data_start:
- .long 0
- .weak data_start
- data_start = __data_start
-
diff --git a/libc/sysdeps/linux/arm/mmap64.S b/libc/sysdeps/linux/arm/mmap64.S
index 0da4afbb0..63b02f9df 100644
--- a/libc/sysdeps/linux/arm/mmap64.S
+++ b/libc/sysdeps/linux/arm/mmap64.S
@@ -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;
-
+/* 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,26 @@ mmap64:
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)
-
-__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]
+ b __error
- /* return -1 */
- mvn r0, $0
- mov pc, lr
-.size mmap64,.-mmap64;
+__error:
+ b __syscall_error
-.L4: .word errno
+.size mmap64,.-mmap64
#endif
diff --git a/libc/sysdeps/linux/arm/setjmp.S b/libc/sysdeps/linux/arm/setjmp.S
index 402a66422..62d038cc5 100644
--- a/libc/sysdeps/linux/arm/setjmp.S
+++ b/libc/sysdeps/linux/arm/setjmp.S
@@ -22,9 +22,9 @@
#define _ASM
#include <bits/setjmp.h>
-.globl __sigsetjmp;
+.global __sigsetjmp
.type __sigsetjmp,%function
-.align 4;
+.align 4
__sigsetjmp:
/* Save registers */
#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
@@ -38,5 +38,10 @@ __sigsetjmp:
sub r0, r0, #48
/* Make a tail call to __sigjmp_save; it takes the same args. */
- B __sigjmp_save (PLT)
-.size __sigsetjmp,.-__sigsetjmp;
+#ifdef __PIC__
+ B __sigjmp_save(PLT)
+#else
+ B __sigjmp_save
+#endif
+
+.size __sigsetjmp,.-__sigsetjmp
diff --git a/libc/sysdeps/linux/arm/sigrestorer.S b/libc/sysdeps/linux/arm/sigrestorer.S
index a90881eb0..b4e17326b 100644
--- a/libc/sysdeps/linux/arm/sigrestorer.S
+++ b/libc/sysdeps/linux/arm/sigrestorer.S
@@ -22,18 +22,18 @@
one of these. This avoids the need for the kernel to synthesise a return
instruction on the stack, which would involve expensive cache flushes. */
-.globl __default_sa_restorer;
+.global __default_sa_restorer
.type __default_sa_restorer,%function
-.align 4;
+.align 4
__default_sa_restorer:
swi __NR_sigreturn
#ifdef __NR_rt_sigreturn
-.globl __default_rt_sa_restorer;
+.global __default_rt_sa_restorer
.type __default_rt_sa_restorer,%function
-.align 4;
+.align 4
__default_rt_sa_restorer:
swi __NR_rt_sigreturn
diff --git a/libc/sysdeps/linux/arm/vfork.S b/libc/sysdeps/linux/arm/vfork.S
index 9d18945d1..cf9d3d8d6 100644
--- a/libc/sysdeps/linux/arm/vfork.S
+++ b/libc/sysdeps/linux/arm/vfork.S
@@ -20,52 +20,37 @@
* 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
+ /* 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
+ /* Syscal worked. Return to child/parent */
+ movcc pc, lr
+__error:
+ b __syscall_error
+.size vfork,.-vfork
+#endif