From dda9f6d081d68848a1d602c375e0d7a8871e4ae4 Mon Sep 17 00:00:00 2001 From: "Jan (janneke) Nieuwenhuizen" Date: Sat, 20 Feb 2021 15:32:53 +0100 Subject: [PATCH 8/8] bootstrappable: arm: Support EABI system calls. Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 * sysdeps/unix/sysv/linux/arm/sysdep.h (DO_CALL,INLINE_SYSCALL) [__ARM_EABI__]: Use eabi calling convention for syscalls. * sysdeps/arm/dl-machine.h (CLEAR_CACHE): Likewise. * sysdeps/unix/sysv/linux/arm/brk.c (__brk): Likewise.Likewise. * sysdeps/unix/sysv/linux/arm/clone.S: Likewise. * sysdeps/unix/sysv/linux/arm/mmap.S: Likewise. * sysdeps/unix/sysv/linux/arm/mmap64.S: Likewise. * sysdeps/unix/sysv/linux/arm/sigrestorer.S: Likewise. * sysdeps/unix/sysv/linux/arm/socket.S: Likewise. * sysdeps/unix/sysv/linux/arm/vfork.S: Likewise. --- sysdeps/arm/dl-machine.h | 14 ++++++ sysdeps/unix/sysv/linux/arm/brk.c | 10 +++++ sysdeps/unix/sysv/linux/arm/clone.S | 7 +++ sysdeps/unix/sysv/linux/arm/mmap.S | 7 +++ sysdeps/unix/sysv/linux/arm/mmap64.S | 7 +++ sysdeps/unix/sysv/linux/arm/sigrestorer.S | 14 ++++++ sysdeps/unix/sysv/linux/arm/socket.S | 7 +++ sysdeps/unix/sysv/linux/arm/sysdep.h | 54 +++++++++++++++++++++++ sysdeps/unix/sysv/linux/arm/vfork.S | 14 ++++++ 9 files changed, 134 insertions(+) diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index 2d802b7..02c48bd 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -32,6 +32,19 @@ && VALID_ELF_OSABI (hdr[EI_OSABI]) \ && VALID_ELF_ABIVERSION (hdr[EI_ABIVERSION]) +#if __ARM_EABI__ +#define CLEAR_CACHE(BEG,END) \ +{ \ + register unsigned long _beg __asm ("a1") = (unsigned long)(BEG); \ + register unsigned long _end __asm ("a2") = (unsigned long)(END); \ + register unsigned long _flg __asm ("a3") = 0; \ + __asm __volatile ("mov r7, 0x9f0002\n\t" \ + "swi 0x0 @ sys_cacheflush" \ + : /* no outputs */ \ + : /* no inputs */ \ + : "a1","r7"); \ +} +#else // !__ARM_EABI__ #define CLEAR_CACHE(BEG,END) \ { \ register unsigned long _beg __asm ("a1") = (unsigned long)(BEG); \ @@ -42,6 +55,7 @@ : /* no inputs */ \ : "a1"); \ } +#endif // !__ARM_EABI__ /* Return nonzero iff ELF header is compatible with the running host. */ static inline int __attribute__ ((unused)) diff --git a/sysdeps/unix/sysv/linux/arm/brk.c b/sysdeps/unix/sysv/linux/arm/brk.c index 153d893..d5d0904 100644 --- a/sysdeps/unix/sysv/linux/arm/brk.c +++ b/sysdeps/unix/sysv/linux/arm/brk.c @@ -29,12 +29,22 @@ __brk (void *addr) { void *newbrk; +#if __ARM_EABI__ + asm ("mov a1, %1\n" /* save the argment in r0 */ + "mov r7, %2\n" /* system call nr in r7 */ + "swi 0x0\n" /* do the system call */ + "mov %0, a1;" /* keep the return value */ + : "=r"(newbrk) + : "r"(addr), "i" (SYS_ify (brk)) + : "a1","r7"); +#else // !__ARM_EABI__ asm ("mov a1, %1\n" /* save the argment in r0 */ "swi %2\n" /* do the system call */ "mov %0, a1;" /* keep the return value */ : "=r"(newbrk) : "r"(addr), "i" (SYS_ify (brk)) : "a1"); +#endif // !__ARM_EABI__ __curbrk = newbrk; diff --git a/sysdeps/unix/sysv/linux/arm/clone.S b/sysdeps/unix/sysv/linux/arm/clone.S index c9a1ec2..bd088b4 100644 --- a/sysdeps/unix/sysv/linux/arm/clone.S +++ b/sysdeps/unix/sysv/linux/arm/clone.S @@ -44,7 +44,14 @@ ENTRY(__clone) @ get flags mov r0, r2 @ new sp is already in r1 +#if __ARM_EABI__ + str r7, [sp, #-4]! + mov r7, #SYS_ify(clone) + swi 0x0 + ldr r7, [sp], #4 +#else // !__ARM_EABI__ swi SYS_ify(clone) +#endif // !__ARM_EABI__ movs a1, a1 blt PLTJMP(C_SYMBOL_NAME(__syscall_error)) RETINSTR(movne, pc, lr) diff --git a/sysdeps/unix/sysv/linux/arm/mmap.S b/sysdeps/unix/sysv/linux/arm/mmap.S index af93c7b..97b4a55 100644 --- a/sysdeps/unix/sysv/linux/arm/mmap.S +++ b/sysdeps/unix/sysv/linux/arm/mmap.S @@ -41,7 +41,14 @@ ENTRY (__mmap) /* do the syscall */ mov a1, sp +#if __ARM_EABI__ + str r7, [sp, #-4]! + mov r7, #SYS_ify (mmap) + swi 0x0 + ldr r7, [sp], #4 +#else // !__ARM_EABI__ swi SYS_ify (mmap) +#endif // !__ARM_EABI__ /* pop args off the stack. */ add sp, sp, #16 diff --git a/sysdeps/unix/sysv/linux/arm/mmap64.S b/sysdeps/unix/sysv/linux/arm/mmap64.S index 1f19bf0..8cb40f5 100644 --- a/sysdeps/unix/sysv/linux/arm/mmap64.S +++ b/sysdeps/unix/sysv/linux/arm/mmap64.S @@ -36,7 +36,14 @@ ENTRY (__mmap64) movs ip, ip, lsr $12 bne .Linval @ check for overflow mov ip, r0 +#if __ARM_EABI__ + str r7, [sp, #-4]! + mov r7, #SYS_ify (mmap2) + swi 0x0 + ldr r7, [sp], #4 +#else // !__ARM_EABI__ swi SYS_ify (mmap2) +#endif // !__ARM_EABI__ cmn r0, $4096 LOADREGS(ccfd, sp!, {r4, r5, pc}) cmn r0, $ENOSYS diff --git a/sysdeps/unix/sysv/linux/arm/sigrestorer.S b/sysdeps/unix/sysv/linux/arm/sigrestorer.S index a4769ca..54aa196 100644 --- a/sysdeps/unix/sysv/linux/arm/sigrestorer.S +++ b/sysdeps/unix/sysv/linux/arm/sigrestorer.S @@ -24,12 +24,26 @@ #ifdef __NR_sigreturn ENTRY(__default_sa_restorer) +#if __ARM_EABI__ + str r7, [sp, #-4]! + mov r7, #SYS_ify(sigreturn) + swi 0x0 + ldr r7, [sp], #4 +#else // !__ARM_EABI__ swi SYS_ify(sigreturn) +#endif // !__ARM_EABI__ #endif #ifdef __NR_rt_sigreturn ENTRY(__default_rt_sa_restorer) +#if __ARM_EABI__ + str r7, [sp, #-4]! + mov r7, #SYS_ify(rt_sigreturn) + swi 0x0 + ldr r7, [sp], #4 +#else // !__ARM_EABI__ swi SYS_ify(rt_sigreturn) +#endif // !__ARM_EABI__ #endif diff --git a/sysdeps/unix/sysv/linux/arm/socket.S b/sysdeps/unix/sysv/linux/arm/socket.S index c8143a2..f0d6e08 100644 --- a/sysdeps/unix/sysv/linux/arm/socket.S +++ b/sysdeps/unix/sysv/linux/arm/socket.S @@ -72,7 +72,14 @@ ENTRY (__socket) mov a1, $P(SOCKOP_,socket) mov a2, sp #ifdef __NR_socketcall +#if __ARM_EABI__ + str r7, [sp, #-4]! + mov r7, #SYS_ify(socketcall) + swi 0x0 + ldr r7, [sp], #4 +#else // !__ARM_EABI__ swi SYS_ify(socketcall) +#endif // !__ARM_EABI__ #endif /* Pop args off the stack */ diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h index 89ad194..f8e88e4 100644 --- a/sysdeps/unix/sysv/linux/arm/sysdep.h +++ b/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -95,10 +95,40 @@ */ #undef DO_CALL +#if __ARM_EABI__ +#define DO_CALL(args, syscall_name) \ + DOARGS_##args \ + ldr r7, =SYS_ify (syscall_name); \ + swi 0x0; \ + UNDOARGS_##args +#else //!__ARM_EABI__ #define DO_CALL(args, syscall_name) \ DOARGS_##args \ swi SYS_ify (syscall_name); \ UNDOARGS_##args +#endif //!__ARM_EABI__ + +#if __ARM_EABI__ + +#define DOARGS_0 str r7, [sp, $-4]!; +#define DOARGS_1 str r7, [sp, $-4]!; +#define DOARGS_2 str r7, [sp, $-4]!; +#define DOARGS_3 str r7, [sp, $-4]!; +#define DOARGS_4 str r7, [sp, $-4]!; +#define DOARGS_5 mov ip, sp; stmfd sp!, {r4, r7}; ldmia ip, {r4, r7}; +#define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5, r7}; ldmia ip, {r4, r5, r7}; +#define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6, r7}; ldmia ip, {r4, r5, r6, r7}; + +#define UNDOARGS_0 ldr r7, [sp], $4; +#define UNDOARGS_1 ldr r7, [sp], $4; +#define UNDOARGS_2 ldr r7, [sp], $4; +#define UNDOARGS_3 ldr r7, [sp], $4; +#define UNDOARGS_4 ldr r7, [sp], $4; +#define UNDOARGS_5 ldmfd sp!, {r4, r7}; +#define UNDOARGS_6 ldmfd sp!, {r4, r5, r7}; +#define UNDOARGS_7 ldmfd sp!, {r4, r5, r6, r7}; + +#else //!__ARM_EABI__ #define DOARGS_0 /* nothing */ #define DOARGS_1 /* nothing */ @@ -118,11 +148,34 @@ #define UNDOARGS_6 ldmfd sp!, {r4, r5}; #define UNDOARGS_7 ldmfd sp!, {r4, r5, r6}; +#endif //!__ARM_EABI__ + #else /* not __ASSEMBLER__ */ /* Define a macro which expands into the inline wrapper code for a system call. */ #undef INLINE_SYSCALL + +#if __ARM_EABI__ +#define INLINE_SYSCALL(name, nr, args...) \ + ({ unsigned int _sys_result; \ + { \ + register int _a1 asm ("a1"); \ + LOAD_ARGS_##nr (args) \ + asm volatile ("mov r7, %1\n\t" \ + "swi $0 @ syscall " #name \ + : "=r" (_a1) \ + : "i" (SYS_ify(name)) ASM_ARGS_##nr \ + : "a1", "r7", "memory"); \ + _sys_result = _a1; \ + } \ + if (_sys_result >= (unsigned int) -4095) \ + { \ + __set_errno (-_sys_result); \ + _sys_result = (unsigned int) -1; \ + } \ + (int) _sys_result; }) +#else //!__ARM_EABI__ #define INLINE_SYSCALL(name, nr, args...) \ ({ unsigned int _sys_result; \ { \ @@ -140,6 +193,7 @@ _sys_result = (unsigned int) -1; \ } \ (int) _sys_result; }) +#endif //!__ARM_EABI__ #define LOAD_ARGS_0() #define ASM_ARGS_0 diff --git a/sysdeps/unix/sysv/linux/arm/vfork.S b/sysdeps/unix/sysv/linux/arm/vfork.S index b10117e..ba2259d 100644 --- a/sysdeps/unix/sysv/linux/arm/vfork.S +++ b/sysdeps/unix/sysv/linux/arm/vfork.S @@ -29,7 +29,14 @@ ENTRY (__vfork) #ifdef __NR_vfork +#if __ARM_EABI__ + str r7, [sp, #-4]! + mov r7, #__NR_vfork + swi 0x0 + ldr r7, [sp], #4 +#else // !__ARM_EABI__ swi __NR_vfork +#endif // !__ARM_EABI__ cmn a1, #4096 RETINSTR(movcc, pc, lr) @@ -40,7 +47,14 @@ ENTRY (__vfork) #endif /* If we don't have vfork, fork is close enough. */ +#if __ARM_EABI__ + str r7, [sp, #-4]! + mov r7, #__NR_fork + swi 0x0 + ldr r7, [sp], #4 +#else // !__ARM_EABI__ swi __NR_fork +#endif // !__ARM_EABI__ cmn a1, #4096 RETINSTR(movcc, pc, lr) b PLTJMP(C_SYMBOL_NAME(__syscall_error)) -- Jan Nieuwenhuizen | GNU LilyPond http://lilypond.org Freelance IT http://JoyofSource.com | AvatarĀ® http://AvatarAcademy.com