From 80419817e6b6388a000b2a18c60a944b971423b5 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Thu, 4 Jun 2020 13:48:25 +0200 Subject: [PATCH] ARM: Mes C Library: Support gcc-sans-libc. * lib/linux/arm-mes-gcc/crt1.c: New file. * lib/linux/arm-mes-gcc/mini.c: New file. * lib/arm-mes-gcc/setjmp.c: New file. Co-Authored-By: Danny Milosavljevic --- lib/arm-mes-gcc/setjmp.c | 62 +++++++++++++++++++++++++++++ lib/linux/arm-mes-gcc/crt1.c | 77 ++++++++++++++++++++++++++++++++++++ lib/linux/arm-mes-gcc/mini.c | 60 ++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 lib/arm-mes-gcc/setjmp.c create mode 100644 lib/linux/arm-mes-gcc/crt1.c create mode 100644 lib/linux/arm-mes-gcc/mini.c diff --git a/lib/arm-mes-gcc/setjmp.c b/lib/arm-mes-gcc/setjmp.c new file mode 100644 index 00000000..5e6d1fb6 --- /dev/null +++ b/lib/arm-mes-gcc/setjmp.c @@ -0,0 +1,62 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen + * Copyright © 2019,2020 Danny Milosavljevic + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include +#include + +void +__attribute__ ((noinline)) +longjmp (jmp_buf env, int val) +{ + // *INDENT-OFF* + asm ( + "mov r0, %0\n\t" + "mov r1, %1\n\t" + "cmp r1, #0\n\t" + "moveq r1, #1\n\t" /* returning 0 is not allowed, even when the user wanted to. */ + "ldr r13, [r0], #4\n\t" /* stack pointer (sp) */ + "ldr r14, [r0], #4\n\t" /* link register (lr) */ + "ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11}\n\t" + // TODO: If using VFP, vldmia r0!, {d8-d15} + "mov r0, r1\n\t" + : + : "r" (env), "r" (val)); + // *INDENT-ON* + // not reached +} + +int +__attribute__ ((noinline)) +setjmp (jmp_buf env) +{ + // *INDENT-OFF* + asm ( + "mov r0, %0\n\t" + "str r13, [r0], #4\n\t" /* stack pointer (sp) */ + "str r14, [r0], #4\n\t" /* link register (lr) */ + "stmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11}\n\t" + // TODO: If using VFP, vstmia r0!, {d8-d15} + : + : "r" (env) + : "r0"); + // *INDENT-ON* + return 0; +} diff --git a/lib/linux/arm-mes-gcc/crt1.c b/lib/linux/arm-mes-gcc/crt1.c new file mode 100644 index 00000000..300dd8c9 --- /dev/null +++ b/lib/linux/arm-mes-gcc/crt1.c @@ -0,0 +1,77 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen + * Copyright © 2019,2020 Danny Milosavljevic + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include +//int main (int argc, char *argv[], char *envp[]); + +/* Note: GCC automatically emits a preable in order to set up the frame pointer: +"push {fp}" +"add fp, sp, 0" + */ +// *INDENT-OFF* +void +_start () +{ + asm ( + "mov r0,#0\n\t" + "mov %0,r0\n" + : "=r" (__stdin) + : //no inputs "" + ); + + asm ( + "mov r0,#1\n\t" + "mov %0,r0\n" + : "=r" (__stdout) + : //no inputs "" + ); + + asm ( + "mov r0,#2\n\t" + "mov %0,r0\n" + : "=r" (__stderr) + : //no inputs "" + ); + + /* environ = argv + argc + 1 */ + asm ( + "ldr r0,[fp,#4]\n\t" /* r0 = argc */ + "add r1,fp,#8\n\t" /* r1 = &argv[0] */ + "add r2,r0,#1\n\t" /* r2 = r0 + 1 */ + "lsl r2,#2\n\t" /* r2 = (r0 + 1) << 2 */ + "add r2,r2,r1\n\t" /* r2 = ((r0 + 1) << 2) + r1 */ + "push {r2}\n\t" /* envp */ + "push {r1}\n\t" /* argv */ + "push {r0}\n\t" /* argc */ + "mov %0,r2\n\t" + : "=r" (environ) + : //no inputs "" + ); + asm ( + "ldr r0,[sp]\n\t" /* argc */ + "ldr r1,[sp, #4]\n\t" /* argv */ + "ldr r2,[sp, #8]\n\t" /* envp */ + "bl main\n\t" + "mov r7, #1\n\t" + "swi #0\n\t" + "wfi \n\t" + ); +} diff --git a/lib/linux/arm-mes-gcc/mini.c b/lib/linux/arm-mes-gcc/mini.c new file mode 100644 index 00000000..400e68b5 --- /dev/null +++ b/lib/linux/arm-mes-gcc/mini.c @@ -0,0 +1,60 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2019 Jan (janneke) Nieuwenhuizen + * Copyright © 2019,2020 Danny Milosavljevic + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include "mes/lib-mini.h" + +#define SYS_exit "0x01" +#define SYS_write "0x04" + +// *INDENT-OFF* +void +_exit (int code) +{ + asm ( + "mov r7, $"SYS_exit"\n\t" + "mov r0, %0\n\t" + "swi $0\n\t" + : // no outputs "=" (r) + : "r" (code) + : "r0", "r7" + ); + // not reached + _exit (0); +} + +ssize_t +_write (int filedes, void const *buffer, size_t size) +{ + long r; + asm ( + "mov r7, $"SYS_write"\n\t" + "mov r0, %1\n\t" + "mov r1, %2\n\t" + "mov r3, %3\n\t" + "swi $0\n\t" + "mov %0, r0\n\t" + : "=r" (r) + : "r" (filedes), "r" (buffer), "r" (size) + : "r0", "r1", "r2", "r7" + ); + return r; +} +// *INDENT-ON*