summaryrefslogtreecommitdiff
path: root/tools/include/nolibc/arch-arm.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/include/nolibc/arch-arm.h')
-rw-r--r--tools/include/nolibc/arch-arm.h74
1 files changed, 51 insertions, 23 deletions
diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index 42499f23e73c..ca4c66987497 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -7,6 +7,8 @@
#ifndef _NOLIBC_ARCH_ARM_H
#define _NOLIBC_ARCH_ARM_H
+#include "compiler.h"
+
/* The struct returned by the stat() syscall, 32-bit only, the syscall returns
* exactly 56 bytes (stops before the unused array). In big endian, the format
* differs as devices are returned as short only.
@@ -196,41 +198,67 @@ struct sys_stat_struct {
_arg1; \
})
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ \
+ register long _num __asm__(_NOLIBC_SYSCALL_REG) = (num); \
+ register long _arg1 __asm__ ("r0") = (long)(arg1); \
+ register long _arg2 __asm__ ("r1") = (long)(arg2); \
+ register long _arg3 __asm__ ("r2") = (long)(arg3); \
+ register long _arg4 __asm__ ("r3") = (long)(arg4); \
+ register long _arg5 __asm__ ("r4") = (long)(arg5); \
+ register long _arg6 __asm__ ("r5") = (long)(arg6); \
+ \
+ __asm__ volatile ( \
+ _NOLIBC_THUMB_SET_R7 \
+ "svc #0\n" \
+ _NOLIBC_THUMB_RESTORE_R7 \
+ : "=r"(_arg1), "=r" (_num) \
+ : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
+ "r"(_arg6), "r"(_num) \
+ : "memory", "cc", "lr" \
+ ); \
+ _arg1; \
+})
+
+
char **environ __attribute__((weak));
const unsigned long *_auxv __attribute__((weak));
/* startup code */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) _start(void)
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
{
__asm__ volatile (
- "pop {%r0}\n" // argc was in the stack
- "mov %r1, %sp\n" // argv = sp
+#ifdef _NOLIBC_STACKPROTECTOR
+ "bl __stack_chk_init\n" /* initialize stack protector */
+#endif
+ "pop {%r0}\n" /* argc was in the stack */
+ "mov %r1, %sp\n" /* argv = sp */
- "add %r2, %r0, $1\n" // envp = (argc + 1) ...
- "lsl %r2, %r2, $2\n" // * 4 ...
- "add %r2, %r2, %r1\n" // + argv
- "ldr %r3, 1f\n" // r3 = &environ (see below)
- "str %r2, [r3]\n" // store envp into environ
+ "add %r2, %r0, $1\n" /* envp = (argc + 1) ... */
+ "lsl %r2, %r2, $2\n" /* * 4 ... */
+ "add %r2, %r2, %r1\n" /* + argv */
+ "ldr %r3, 1f\n" /* r3 = &environ (see below) */
+ "str %r2, [r3]\n" /* store envp into environ */
- "mov r4, r2\n" // search for auxv (follows NULL after last env)
+ "mov r4, r2\n" /* search for auxv (follows NULL after last env) */
"0:\n"
- "mov r5, r4\n" // r5 = r4
- "add r4, r4, #4\n" // r4 += 4
- "ldr r5,[r5]\n" // r5 = *r5 = *(r4-4)
- "cmp r5, #0\n" // and stop at NULL after last env
+ "mov r5, r4\n" /* r5 = r4 */
+ "add r4, r4, #4\n" /* r4 += 4 */
+ "ldr r5,[r5]\n" /* r5 = *r5 = *(r4-4) */
+ "cmp r5, #0\n" /* and stop at NULL after last env */
"bne 0b\n"
- "ldr %r3, 2f\n" // r3 = &_auxv (low bits)
- "str r4, [r3]\n" // store r4 into _auxv
+ "ldr %r3, 2f\n" /* r3 = &_auxv (low bits) */
+ "str r4, [r3]\n" /* store r4 into _auxv */
- "mov %r3, $8\n" // AAPCS : sp must be 8-byte aligned in the
- "neg %r3, %r3\n" // callee, and bl doesn't push (lr=pc)
- "and %r3, %r3, %r1\n" // so we do sp = r1(=sp) & r3(=-8);
- "mov %sp, %r3\n" //
+ "mov %r3, $8\n" /* AAPCS : sp must be 8-byte aligned in the */
+ "neg %r3, %r3\n" /* callee, and bl doesn't push (lr=pc) */
+ "and %r3, %r3, %r1\n" /* so we do sp = r1(=sp) & r3(=-8); */
+ "mov %sp, %r3\n"
- "bl main\n" // main() returns the status code, we'll exit with it.
- "movs r7, $1\n" // NR_exit == 1
+ "bl main\n" /* main() returns the status code, we'll exit with it. */
+ "movs r7, $1\n" /* NR_exit == 1 */
"svc $0x00\n"
- ".align 2\n" // below are the pointers to a few variables
+ ".align 2\n" /* below are the pointers to a few variables */
"1:\n"
".word environ\n"
"2:\n"
@@ -239,4 +267,4 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) _start(void)
__builtin_unreachable();
}
-#endif // _NOLIBC_ARCH_ARM_H
+#endif /* _NOLIBC_ARCH_ARM_H */