diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-06-27 10:56:41 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-06-27 10:56:41 -0700 |
| commit | b19edac5992da0188be98454ca592621d3d89844 (patch) | |
| tree | 57ebeb5f3583c172e6d4aa64a33841086e7cc5db /tools | |
| parent | af96134dc8562f9fcbb8358af36f6086619a29ab (diff) | |
| parent | dd58d666ac08eb5eb81e4956172fc52b3bf0ab38 (diff) | |
| download | linux-b19edac5992da0188be98454ca592621d3d89844.tar.gz linux-b19edac5992da0188be98454ca592621d3d89844.tar.bz2 linux-b19edac5992da0188be98454ca592621d3d89844.zip | |
Merge tag 'nolibc.2023.06.22a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu
Pull nolibc updates from Paul McKenney:
- Add stackprotector support
- Fix RISC-V load-store instruction syntax to support 32-bit binaries,
plus fixes for generic 32-bit support
- Fix use of s390 sys_fork()
- Add my_syscall6() for ARM
- Support different platforms having different errno definitions
- Fix ppoll/ppoll_time64 arguments (add the fifth argument)
- Force use of little endian on MIPS
- Improved testing, for example, better handling of different compilers
and compiler versions, comparing nolibc behavior to that of libc, and
additional test cases
- Improve syntax and header ordering
- Use existing <linux/reboot.h> instead of redefining constants
- Add syscall()
* tag 'nolibc.2023.06.22a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu: (53 commits)
selftests/nolibc: make sure gcc always use little endian on MIPS
selftests/nolibc: also count skipped and failed tests in output
selftests/nolibc: add new gettimeofday test cases
selftests/nolibc: remove gettimeofday_bad1/2 completely
selftests/nolibc: support two errnos with EXPECT_SYSER2()
tools/nolibc: open: fix up compile warning for arm
tools/nolibc: arm: add missing my_syscall6
selftests/nolibc: use INT_MAX instead of __INT_MAX__
selftests/nolibc: not include limits.h for nolibc
selftests/nolibc: fix up compile warning with glibc on x86_64
selftests/nolibc: allow specify extra arguments for qemu
selftests/nolibc: remove test gettimeofday_null
tools/nolibc: ensure fast64 integer types have 64 bits
selftests/nolibc: test_fork: fix up duplicated print
tools/nolibc: ppoll/ppoll_time64: add a missing argument
selftests/nolibc: remove the duplicated gettimeofday_bad2
selftests/nolibc: print name instead of number for EOVERFLOW
tools/nolibc: support nanoseconds in stat()
selftests/nolibc: prevent coredumps during test execution
tools/nolibc: add support for prctl()
...
Diffstat (limited to 'tools')
23 files changed, 704 insertions, 313 deletions
diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile index 9839feafd38a..64d67b080744 100644 --- a/tools/include/nolibc/Makefile +++ b/tools/include/nolibc/Makefile @@ -25,8 +25,23 @@ endif nolibc_arch := $(patsubst arm64,aarch64,$(ARCH)) arch_file := arch-$(nolibc_arch).h -all_files := ctype.h errno.h nolibc.h signal.h stackprotector.h std.h stdint.h \ - stdio.h stdlib.h string.h sys.h time.h types.h unistd.h +all_files := \ + compiler.h \ + ctype.h \ + errno.h \ + nolibc.h \ + signal.h \ + stackprotector.h \ + std.h \ + stdint.h \ + stdlib.h \ + string.h \ + sys.h \ + time.h \ + types.h \ + unistd.h \ + stdio.h \ + # install all headers needed to support a bare-metal compiler all: headers diff --git a/tools/include/nolibc/arch-aarch64.h b/tools/include/nolibc/arch-aarch64.h index 383baddef701..11f294a406b7 100644 --- a/tools/include/nolibc/arch-aarch64.h +++ b/tools/include/nolibc/arch-aarch64.h @@ -7,6 +7,8 @@ #ifndef _NOLIBC_ARCH_AARCH64_H #define _NOLIBC_ARCH_AARCH64_H +#include "compiler.h" + /* The struct returned by the newfstatat() syscall. Differs slightly from the * x86_64's stat one by field ordering, so be careful. */ @@ -173,27 +175,30 @@ 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 ( - "ldr x0, [sp]\n" // argc (x0) was in the stack - "add x1, sp, 8\n" // argv (x1) = sp - "lsl x2, x0, 3\n" // envp (x2) = 8*argc ... - "add x2, x2, 8\n" // + 8 (skip null) - "add x2, x2, x1\n" // + argv - "adrp x3, environ\n" // x3 = &environ (high bits) - "str x2, [x3, #:lo12:environ]\n" // store envp into environ - "mov x4, x2\n" // search for auxv (follows NULL after last env) +#ifdef _NOLIBC_STACKPROTECTOR + "bl __stack_chk_init\n" /* initialize stack protector */ +#endif + "ldr x0, [sp]\n" /* argc (x0) was in the stack */ + "add x1, sp, 8\n" /* argv (x1) = sp */ + "lsl x2, x0, 3\n" /* envp (x2) = 8*argc ... */ + "add x2, x2, 8\n" /* + 8 (skip null) */ + "add x2, x2, x1\n" /* + argv */ + "adrp x3, environ\n" /* x3 = &environ (high bits) */ + "str x2, [x3, #:lo12:environ]\n" /* store envp into environ */ + "mov x4, x2\n" /* search for auxv (follows NULL after last env) */ "0:\n" - "ldr x5, [x4], 8\n" // x5 = *x4; x4 += 8 - "cbnz x5, 0b\n" // and stop at NULL after last env - "adrp x3, _auxv\n" // x3 = &_auxv (high bits) - "str x4, [x3, #:lo12:_auxv]\n" // store x4 into _auxv - "and sp, x1, -16\n" // sp must be 16-byte aligned in the callee - "bl main\n" // main() returns the status code, we'll exit with it. - "mov x8, 93\n" // NR_exit == 93 + "ldr x5, [x4], 8\n" /* x5 = *x4; x4 += 8 */ + "cbnz x5, 0b\n" /* and stop at NULL after last env */ + "adrp x3, _auxv\n" /* x3 = &_auxv (high bits) */ + "str x4, [x3, #:lo12:_auxv]\n" /* store x4 into _auxv */ + "and sp, x1, -16\n" /* sp must be 16-byte aligned in the callee */ + "bl main\n" /* main() returns the status code, we'll exit with it. */ + "mov x8, 93\n" /* NR_exit == 93 */ "svc #0\n" ); __builtin_unreachable(); } -#endif // _NOLIBC_ARCH_AARCH64_H +#endif /* _NOLIBC_ARCH_AARCH64_H */ 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 */ diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h index 2d98d78fd3f3..3d672d925e9e 100644 --- a/tools/include/nolibc/arch-i386.h +++ b/tools/include/nolibc/arch-i386.h @@ -7,6 +7,8 @@ #ifndef _NOLIBC_ARCH_I386_H #define _NOLIBC_ARCH_I386_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). */ @@ -181,8 +183,6 @@ struct sys_stat_struct { char **environ __attribute__((weak)); const unsigned long *_auxv __attribute__((weak)); -#define __ARCH_SUPPORTS_STACK_PROTECTOR - /* startup code */ /* * i386 System V ABI mandates: @@ -190,35 +190,35 @@ const unsigned long *_auxv __attribute__((weak)); * 2) The deepest stack frame should be set to zero * */ -void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void) +void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void) { __asm__ volatile ( -#ifdef NOLIBC_STACKPROTECTOR - "call __stack_chk_init\n" // initialize stack protector +#ifdef _NOLIBC_STACKPROTECTOR + "call __stack_chk_init\n" /* initialize stack protector */ #endif - "pop %eax\n" // argc (first arg, %eax) - "mov %esp, %ebx\n" // argv[] (second arg, %ebx) - "lea 4(%ebx,%eax,4),%ecx\n" // then a NULL then envp (third arg, %ecx) - "mov %ecx, environ\n" // save environ - "xor %ebp, %ebp\n" // zero the stack frame - "mov %ecx, %edx\n" // search for auxv (follows NULL after last env) + "pop %eax\n" /* argc (first arg, %eax) */ + "mov %esp, %ebx\n" /* argv[] (second arg, %ebx) */ + "lea 4(%ebx,%eax,4),%ecx\n" /* then a NULL then envp (third arg, %ecx) */ + "mov %ecx, environ\n" /* save environ */ + "xor %ebp, %ebp\n" /* zero the stack frame */ + "mov %ecx, %edx\n" /* search for auxv (follows NULL after last env) */ "0:\n" - "add $4, %edx\n" // search for auxv using edx, it follows the - "cmp -4(%edx), %ebp\n" // ... NULL after last env (ebp is zero here) + "add $4, %edx\n" /* search for auxv using edx, it follows the */ + "cmp -4(%edx), %ebp\n" /* ... NULL after last env (ebp is zero here) */ "jnz 0b\n" - "mov %edx, _auxv\n" // save it into _auxv - "and $-16, %esp\n" // x86 ABI : esp must be 16-byte aligned before - "sub $4, %esp\n" // the call instruction (args are aligned) - "push %ecx\n" // push all registers on the stack so that we - "push %ebx\n" // support both regparm and plain stack modes + "mov %edx, _auxv\n" /* save it into _auxv */ + "and $-16, %esp\n" /* x86 ABI : esp must be 16-byte aligned before */ + "sub $4, %esp\n" /* the call instruction (args are aligned) */ + "push %ecx\n" /* push all registers on the stack so that we */ + "push %ebx\n" /* support both regparm and plain stack modes */ "push %eax\n" - "call main\n" // main() returns the status code in %eax - "mov %eax, %ebx\n" // retrieve exit code (32-bit int) - "movl $1, %eax\n" // NR_exit == 1 - "int $0x80\n" // exit now - "hlt\n" // ensure it does not + "call main\n" /* main() returns the status code in %eax */ + "mov %eax, %ebx\n" /* retrieve exit code (32-bit int) */ + "movl $1, %eax\n" /* NR_exit == 1 */ + "int $0x80\n" /* exit now */ + "hlt\n" /* ensure it does not */ ); __builtin_unreachable(); } -#endif // _NOLIBC_ARCH_I386_H +#endif /* _NOLIBC_ARCH_I386_H */ diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h index 029ee3cd6baf..ad3f266e7093 100644 --- a/tools/include/nolibc/arch-loongarch.h +++ b/tools/include/nolibc/arch-loongarch.h @@ -7,6 +7,8 @@ #ifndef _NOLIBC_ARCH_LOONGARCH_H #define _NOLIBC_ARCH_LOONGARCH_H +#include "compiler.h" + /* Syscalls for LoongArch : * - stack is 16-byte aligned * - syscall number is passed in a7 @@ -158,7 +160,7 @@ const unsigned long *_auxv __attribute__((weak)); #define LONG_ADDI "addi.w" #define LONG_SLL "slli.w" #define LONG_BSTRINS "bstrins.w" -#else // __loongarch_grlen == 64 +#else /* __loongarch_grlen == 64 */ #define LONGLOG "3" #define SZREG "8" #define REG_L "ld.d" @@ -170,31 +172,34 @@ const unsigned long *_auxv __attribute__((weak)); #endif /* 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 ( - REG_L " $a0, $sp, 0\n" // argc (a0) was in the stack - LONG_ADDI " $a1, $sp, "SZREG"\n" // argv (a1) = sp + SZREG - LONG_SLL " $a2, $a0, "LONGLOG"\n" // envp (a2) = SZREG*argc ... - LONG_ADDI " $a2, $a2, "SZREG"\n" // + SZREG (skip null) - LONG_ADD " $a2, $a2, $a1\n" // + argv - - "move $a3, $a2\n" // iterate a3 over envp to find auxv (after NULL) - "0:\n" // do { - REG_L " $a4, $a3, 0\n" // a4 = *a3; - LONG_ADDI " $a3, $a3, "SZREG"\n" // a3 += sizeof(void*); - "bne $a4, $zero, 0b\n" // } while (a4); - "la.pcrel $a4, _auxv\n" // a4 = &_auxv - LONG_S " $a3, $a4, 0\n" // store a3 into _auxv - - "la.pcrel $a3, environ\n" // a3 = &environ - LONG_S " $a2, $a3, 0\n" // store envp(a2) into environ - LONG_BSTRINS " $sp, $zero, 3, 0\n" // sp must be 16-byte aligned - "bl main\n" // main() returns the status code, we'll exit with it. - "li.w $a7, 93\n" // NR_exit == 93 +#ifdef _NOLIBC_STACKPROTECTOR + "bl __stack_chk_init\n" /* initialize stack protector */ +#endif + REG_L " $a0, $sp, 0\n" /* argc (a0) was in the stack */ + LONG_ADDI " $a1, $sp, "SZREG"\n" /* argv (a1) = sp + SZREG */ + LONG_SLL " $a2, $a0, "LONGLOG"\n" /* envp (a2) = SZREG*argc ... */ + LONG_ADDI " $a2, $a2, "SZREG"\n" /* + SZREG (skip null) */ + LONG_ADD " $a2, $a2, $a1\n" /* + argv */ + + "move $a3, $a2\n" /* iterate a3 over envp to find auxv (after NULL) */ + "0:\n" /* do { */ + REG_L " $a4, $a3, 0\n" /* a4 = *a3; */ + LONG_ADDI " $a3, $a3, "SZREG"\n" /* a3 += sizeof(void*); */ + "bne $a4, $zero, 0b\n" /* } while (a4); */ + "la.pcrel $a4, _auxv\n" /* a4 = &_auxv */ + LONG_S " $a3, $a4, 0\n" /* store a3 into _auxv */ + + "la.pcrel $a3, environ\n" /* a3 = &environ */ + LONG_S " $a2, $a3, 0\n" /* store envp(a2) into environ */ + LONG_BSTRINS " $sp, $zero, 3, 0\n" /* sp must be 16-byte aligned */ + "bl main\n" /* main() returns the status code, we'll exit with it. */ + "li.w $a7, 93\n" /* NR_exit == 93 */ "syscall 0\n" ); __builtin_unreachable(); } -#endif // _NOLIBC_ARCH_LOONGARCH_H +#endif /* _NOLIBC_ARCH_LOONGARCH_H */ diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h index bf83432d23ed..db24e0837a39 100644 --- a/tools/include/nolibc/arch-mips.h +++ b/tools/include/nolibc/arch-mips.h @@ -7,6 +7,8 @@ #ifndef _NOLIBC_ARCH_MIPS_H #define _NOLIBC_ARCH_MIPS_H +#include "compiler.h" + /* The struct returned by the stat() syscall. 88 bytes are returned by the * syscall. */ @@ -180,45 +182,49 @@ char **environ __attribute__((weak)); const unsigned long *_auxv __attribute__((weak)); /* startup code, note that it's called __start on MIPS */ -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 ( - //".set nomips16\n" + /*".set nomips16\n"*/ ".set push\n" ".set noreorder\n" ".option pic0\n" - //".ent __start\n" - //"__start:\n" - "lw $a0,($sp)\n" // argc was in the stack - "addiu $a1, $sp, 4\n" // argv = sp + 4 - "sll $a2, $a0, 2\n" // a2 = argc * 4 - "add $a2, $a2, $a1\n" // envp = argv + 4*argc ... - "addiu $a2, $a2, 4\n" // ... + 4 - "lui $a3, %hi(environ)\n" // load environ into a3 (hi) - "addiu $a3, %lo(environ)\n" // load environ into a3 (lo) - "sw $a2,($a3)\n" // store envp(a2) into environ - - "move $t0, $a2\n" // iterate t0 over envp, look for NULL - "0:" // do { - "lw $a3, ($t0)\n" // a3=*(t0); - "bne $a3, $0, 0b\n" // } while (a3); - "addiu $t0, $t0, 4\n" // delayed slot: t0+=4; - "lui $a3, %hi(_auxv)\n" // load _auxv into a3 (hi) - "addiu $a3, %lo(_auxv)\n" // load _auxv into a3 (lo) - "sw $t0, ($a3)\n" // store t0 into _auxv +#ifdef _NOLIBC_STACKPROTECTOR + "jal __stack_chk_init\n" /* initialize stack protector */ + "nop\n" /* delayed slot */ +#endif + /*".ent __start\n"*/ + /*"__start:\n"*/ + "lw $a0,($sp)\n" /* argc was in the stack */ + "addiu $a1, $sp, 4\n" /* argv = sp + 4 */ + "sll $a2, $a0, 2\n" /* a2 = argc * 4 */ + "add $a2, $a2, $a1\n" /* envp = argv + 4*argc ... */ + "addiu $a2, $a2, 4\n" /* ... + 4 */ + "lui $a3, %hi(environ)\n" /* load environ into a3 (hi) */ + "addiu $a3, %lo(environ)\n" /* load environ into a3 (lo) */ + "sw $a2,($a3)\n" /* store envp(a2) into environ */ + + "move $t0, $a2\n" /* iterate t0 over envp, look for NULL */ + "0:" /* do { */ + "lw $a3, ($t0)\n" /* a3=*(t0); */ + "bne $a3, $0, 0b\n" /* } while (a3); */ + "addiu $t0, $t0, 4\n" /* delayed slot: t0+=4; */ + "lui $a3, %hi(_auxv)\n" /* load _auxv into a3 (hi) */ + "addiu $a3, %lo(_auxv)\n" /* load _auxv into a3 (lo) */ + "sw $t0, ($a3)\n" /* store t0 into _auxv */ "li $t0, -8\n" - "and $sp, $sp, $t0\n" // sp must be 8-byte aligned - "addiu $sp,$sp,-16\n" // the callee expects to save a0..a3 there! - "jal main\n" // main() returns the status code, we'll exit with it. - "nop\n" // delayed slot - "move $a0, $v0\n" // retrieve 32-bit exit code from v0 - "li $v0, 4001\n" // NR_exit == 4001 + "and $sp, $sp, $t0\n" /* sp must be 8-byte aligned */ + "addiu $sp,$sp,-16\n" /* the callee expects to save a0..a3 there! */ + "jal main\n" /* main() returns the status code, we'll exit with it. */ + "nop\n" /* delayed slot */ + "move $a0, $v0\n" /* retrieve 32-bit exit code from v0 */ + "li $v0, 4001\n" /* NR_exit == 4001 */ "syscall\n" - //".end __start\n" + /*".end __start\n"*/ ".set pop\n" ); __builtin_unreachable(); } -#endif // _NOLIBC_ARCH_MIPS_H +#endif /* _NOLIBC_ARCH_MIPS_H */ diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h index e197fcb10ac0..a2e8564e66d6 100644 --- a/tools/include/nolibc/arch-riscv.h +++ b/tools/include/nolibc/arch-riscv.h @@ -7,6 +7,8 @@ #ifndef _NOLIBC_ARCH_RISCV_H #define _NOLIBC_ARCH_RISCV_H +#include "compiler.h" + struct sys_stat_struct { unsigned long st_dev; /* Device. */ unsigned long st_ino; /* File serial number. */ @@ -33,9 +35,13 @@ struct sys_stat_struct { #if __riscv_xlen == 64 #define PTRLOG "3" #define SZREG "8" +#define REG_L "ld" +#define REG_S "sd" #elif __riscv_xlen == 32 #define PTRLOG "2" #define SZREG "4" +#define REG_L "lw" +#define REG_S "sw" #endif /* Syscalls for RISCV : @@ -174,35 +180,38 @@ 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 ( ".option push\n" ".option norelax\n" "lla gp, __global_pointer$\n" ".option pop\n" - "lw a0, 0(sp)\n" // argc (a0) was in the stack - "add a1, sp, "SZREG"\n" // argv (a1) = sp - "slli a2, a0, "PTRLOG"\n" // envp (a2) = SZREG*argc ... - "add a2, a2, "SZREG"\n" // + SZREG (skip null) - "add a2,a2,a1\n" // + argv - - "add a3, a2, zero\n" // iterate a3 over envp to find auxv (after NULL) - "0:\n" // do { - "ld a4, 0(a3)\n" // a4 = *a3; - "add a3, a3, "SZREG"\n" // a3 += sizeof(void*); - "bne a4, zero, 0b\n" // } while (a4); - "lui a4, %hi(_auxv)\n" // a4 = &_auxv (high bits) - "sd a3, %lo(_auxv)(a4)\n" // store a3 into _auxv - - "lui a3, %hi(environ)\n" // a3 = &environ (high bits) - "sd a2,%lo(environ)(a3)\n" // store envp(a2) into environ - "andi sp,a1,-16\n" // sp must be 16-byte aligned - "call main\n" // main() returns the status code, we'll exit with it. - "li a7, 93\n" // NR_exit == 93 +#ifdef _NOLIBC_STACKPROTECTOR + "call __stack_chk_init\n" /* initialize stack protector */ +#endif + REG_L" a0, 0(sp)\n" /* argc (a0) was in the stack */ + "add a1, sp, "SZREG"\n" /* argv (a1) = sp */ + "slli a2, a0, "PTRLOG"\n" /* envp (a2) = SZREG*argc ... */ + "add a2, a2, "SZREG"\n" /* + SZREG (skip null) */ + "add a2,a2,a1\n" /* + argv */ + + "add a3, a2, zero\n" /* iterate a3 over envp to find auxv (after NULL) */ + "0:\n" /* do { */ + REG_L" a4, 0(a3)\n" /* a4 = *a3; */ + "add a3, a3, "SZREG"\n" /* a3 += sizeof(void*); */ + "bne a4, zero, 0b\n" /* } while (a4); */ + "lui a4, %hi(_auxv)\n" /* a4 = &_auxv (high bits) */ + REG_S" a3, %lo(_auxv)(a4)\n" /* store a3 into _auxv */ + + "lui a3, %hi(environ)\n" /* a3 = &environ (high bits) */ + REG_S" a2,%lo(environ)(a3)\n"/* store envp(a2) into environ */ + "andi sp,a1,-16\n" /* sp must be 16-byte aligned */ + "call main\n" /* main() returns the status code, we'll exit with it. */ + "li a7, 93\n" /* NR_exit == 93 */ "ecall\n" ); __builtin_unreachable(); } -#endif // _NOLIBC_ARCH_RISCV_H +#endif /* _NOLIBC_ARCH_RISCV_H */ diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/arch-s390.h index 6b0e54ed543d..516dff5bff8b 100644 --- a/tools/include/nolibc/arch-s390.h +++ b/tools/include/nolibc/arch-s390.h @@ -5,8 +5,11 @@ #ifndef _NOLIBC_ARCH_S390_H #define _NOLIBC_ARCH_S390_H +#include <asm/signal.h> #include <asm/unistd.h> +#include "compiler.h" + /* The struct returned by the stat() syscall, equivalent to stat64(). The * syscall returns 116 bytes and stops in the middle of __unused. */ @@ -163,7 +166,7 @@ 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 ( "lg %r2,0(%r15)\n" /* argument count */ @@ -223,4 +226,12 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, return (void *)my_syscall1(__NR_mmap, &args); } #define sys_mmap sys_mmap -#endif // _NOLIBC_ARCH_S390_H + +static __attribute__((unused)) +pid_t sys_fork(void) +{ + return my_syscall5(__NR_clone, 0, SIGCHLD, 0, 0, 0); +} +#define sys_fork sys_fork + +#endif /* _NOLIBC_ARCH_S390_H */ diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h index f7f2a11d4c3b..6fc4d8392742 100644 --- a/tools/include/nolibc/arch-x86_64.h +++ b/tools/include/nolibc/arch-x86_64.h @@ -7,6 +7,8 @@ #ifndef _NOLIBC_ARCH_X86_64_H #define _NOLIBC_ARCH_X86_64_H +#include "compiler.h" + /* The struct returned by the stat() syscall, equivalent to stat64(). The * syscall returns 116 bytes and stops in the middle of __unused. */ @@ -181,8 +183,6 @@ struct sys_stat_struct { char **environ __attribute__((weak)); const unsigned long *_auxv __attribute__((weak)); -#define __ARCH_SUPPORTS_STACK_PROTECTOR - /* startup code */ /* * x86-64 System V ABI mandates: @@ -190,31 +190,31 @@ const unsigned long *_auxv __attribute__((weak)); * 2) The deepest stack frame should be zero (the %rbp). * */ -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 ( -#ifdef NOLIBC_STACKPROTECTOR - "call __stack_chk_init\n" // initialize stack protector +#ifdef _NOLIBC_STACKPROTECTOR + "call __stack_chk_init\n" /* initialize stack protector */ #endif - "pop %rdi\n" // argc (first arg, %rdi) - "mov %rsp, %rsi\n" // argv[] (second arg, %rsi) - "lea 8(%rsi,%rdi,8),%rdx\n" // then a NULL then envp (third arg, %rdx) - "mov %rdx, environ\n" // save environ - "xor %ebp, %ebp\n" // zero the stack frame - "mov %rdx, %rax\n" // search for auxv (follows NULL after last env) + "pop %rdi\n" /* argc (first arg, %rdi) */ + "mov %rsp, %rsi\n" /* argv[] (second arg, %rsi) */ + "lea 8(%rsi,%rdi,8),%rdx\n" /* then a NULL then envp (third arg, %rdx) */ + "mov %rdx, environ\n" /* save environ */ + "xor %ebp, %ebp\n" /* zero the stack frame */ + "mov %rdx, %rax\n" /* search for auxv (follows NULL after last env) */ "0:\n" - "add $8, %rax\n" // search for auxv using rax, it follows the - "cmp -8(%rax), %rbp\n" // ... NULL after last env (rbp is zero here) + "add $8, %rax\n" /* search for auxv using rax, it follows the */ + "cmp -8(%rax), %rbp\n" /* ... NULL after last env (rbp is zero here) */ "jnz 0b\n" - "mov %rax, _auxv\n" // save it into _auxv - "and $-16, %rsp\n" // x86 ABI : esp must be 16-byte aligned before call - "call main\n" // main() returns the status code, we'll ex |
