-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'nolibc.2023.04.04a' of git://git.kernel.org/pub/scm/linux/…
…kernel/git/paulmck/linux-rcu Pull nolibc updates from Paul McKenney: - Add support for loongarch - Fix stack-protector issues - Support additional integral types and signal-related macros - Add support for stdin, stdout, and stderr - Add getuid() and geteuid() - Allow S_I* macros to be overridden by program - Defer to linux/fcntl.h and linux/stat.h to avoid duplicate definitions - Many improvements to the selftests * tag 'nolibc.2023.04.04a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu: (22 commits) tools/nolibc: x86_64: add stackprotector support tools/nolibc: i386: add stackprotector support tools/nolibc: tests: add test for -fstack-protector tools/nolibc: tests: fold in no-stack-protector cflags tools/nolibc: add support for stack protector tools/nolibc: tests: constify test_names tools/nolibc: add helpers for wait() signal exits tools/nolibc: add definitions for standard fds selftests/nolibc: Adjust indentation for Makefile selftests/nolibc: Add support for LoongArch tools/nolibc: Add support for LoongArch tools/nolibc: Add statx() and make stat() rely on statx() if necessary tools/nolibc: Include linux/fcntl.h and remove duplicate code tools/nolibc: check for S_I* macros before defining them selftests/nolibc: skip the chroot_root and link_dir tests when not privileged tools/nolibc: add getuid() and geteuid() tools/nolibc: add tests for the integer limits in stdint.h tools/nolibc: enlarge column width of tests tools/nolibc: add integer types and integer limit macros tools/nolibc: add stdint.h ...
- Loading branch information
Showing
15 changed files
with
718 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sysroot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ | ||
/* | ||
* LoongArch specific definitions for NOLIBC | ||
* Copyright (C) 2023 Loongson Technology Corporation Limited | ||
*/ | ||
|
||
#ifndef _NOLIBC_ARCH_LOONGARCH_H | ||
#define _NOLIBC_ARCH_LOONGARCH_H | ||
|
||
/* Syscalls for LoongArch : | ||
* - stack is 16-byte aligned | ||
* - syscall number is passed in a7 | ||
* - arguments are in a0, a1, a2, a3, a4, a5 | ||
* - the system call is performed by calling "syscall 0" | ||
* - syscall return comes in a0 | ||
* - the arguments are cast to long and assigned into the target | ||
* registers which are then simply passed as registers to the asm code, | ||
* so that we don't have to experience issues with register constraints. | ||
* | ||
* On LoongArch, select() is not implemented so we have to use pselect6(). | ||
*/ | ||
#define __ARCH_WANT_SYS_PSELECT6 | ||
|
||
#define my_syscall0(num) \ | ||
({ \ | ||
register long _num __asm__ ("a7") = (num); \ | ||
register long _arg1 __asm__ ("a0"); \ | ||
\ | ||
__asm__ volatile ( \ | ||
"syscall 0\n" \ | ||
: "=r"(_arg1) \ | ||
: "r"(_num) \ | ||
: "memory", "$t0", "$t1", "$t2", "$t3", \ | ||
"$t4", "$t5", "$t6", "$t7", "$t8" \ | ||
); \ | ||
_arg1; \ | ||
}) | ||
|
||
#define my_syscall1(num, arg1) \ | ||
({ \ | ||
register long _num __asm__ ("a7") = (num); \ | ||
register long _arg1 __asm__ ("a0") = (long)(arg1); \ | ||
\ | ||
__asm__ volatile ( \ | ||
"syscall 0\n" \ | ||
: "+r"(_arg1) \ | ||
: "r"(_num) \ | ||
: "memory", "$t0", "$t1", "$t2", "$t3", \ | ||
"$t4", "$t5", "$t6", "$t7", "$t8" \ | ||
); \ | ||
_arg1; \ | ||
}) | ||
|
||
#define my_syscall2(num, arg1, arg2) \ | ||
({ \ | ||
register long _num __asm__ ("a7") = (num); \ | ||
register long _arg1 __asm__ ("a0") = (long)(arg1); \ | ||
register long _arg2 __asm__ ("a1") = (long)(arg2); \ | ||
\ | ||
__asm__ volatile ( \ | ||
"syscall 0\n" \ | ||
: "+r"(_arg1) \ | ||
: "r"(_arg2), \ | ||
"r"(_num) \ | ||
: "memory", "$t0", "$t1", "$t2", "$t3", \ | ||
"$t4", "$t5", "$t6", "$t7", "$t8" \ | ||
); \ | ||
_arg1; \ | ||
}) | ||
|
||
#define my_syscall3(num, arg1, arg2, arg3) \ | ||
({ \ | ||
register long _num __asm__ ("a7") = (num); \ | ||
register long _arg1 __asm__ ("a0") = (long)(arg1); \ | ||
register long _arg2 __asm__ ("a1") = (long)(arg2); \ | ||
register long _arg3 __asm__ ("a2") = (long)(arg3); \ | ||
\ | ||
__asm__ volatile ( \ | ||
"syscall 0\n" \ | ||
: "+r"(_arg1) \ | ||
: "r"(_arg2), "r"(_arg3), \ | ||
"r"(_num) \ | ||
: "memory", "$t0", "$t1", "$t2", "$t3", \ | ||
"$t4", "$t5", "$t6", "$t7", "$t8" \ | ||
); \ | ||
_arg1; \ | ||
}) | ||
|
||
#define my_syscall4(num, arg1, arg2, arg3, arg4) \ | ||
({ \ | ||
register long _num __asm__ ("a7") = (num); \ | ||
register long _arg1 __asm__ ("a0") = (long)(arg1); \ | ||
register long _arg2 __asm__ ("a1") = (long)(arg2); \ | ||
register long _arg3 __asm__ ("a2") = (long)(arg3); \ | ||
register long _arg4 __asm__ ("a3") = (long)(arg4); \ | ||
\ | ||
__asm__ volatile ( \ | ||
"syscall 0\n" \ | ||
: "+r"(_arg1) \ | ||
: "r"(_arg2), "r"(_arg3), "r"(_arg4), \ | ||
"r"(_num) \ | ||
: "memory", "$t0", "$t1", "$t2", "$t3", \ | ||
"$t4", "$t5", "$t6", "$t7", "$t8" \ | ||
); \ | ||
_arg1; \ | ||
}) | ||
|
||
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ | ||
({ \ | ||
register long _num __asm__ ("a7") = (num); \ | ||
register long _arg1 __asm__ ("a0") = (long)(arg1); \ | ||
register long _arg2 __asm__ ("a1") = (long)(arg2); \ | ||
register long _arg3 __asm__ ("a2") = (long)(arg3); \ | ||
register long _arg4 __asm__ ("a3") = (long)(arg4); \ | ||
register long _arg5 __asm__ ("a4") = (long)(arg5); \ | ||
\ | ||
__asm__ volatile ( \ | ||
"syscall 0\n" \ | ||
: "+r"(_arg1) \ | ||
: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ | ||
"r"(_num) \ | ||
: "memory", "$t0", "$t1", "$t2", "$t3", \ | ||
"$t4", "$t5", "$t6", "$t7", "$t8" \ | ||
); \ | ||
_arg1; \ | ||
}) | ||
|
||
#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ | ||
({ \ | ||
register long _num __asm__ ("a7") = (num); \ | ||
register long _arg1 __asm__ ("a0") = (long)(arg1); \ | ||
register long _arg2 __asm__ ("a1") = (long)(arg2); \ | ||
register long _arg3 __asm__ ("a2") = (long)(arg3); \ | ||
register long _arg4 __asm__ ("a3") = (long)(arg4); \ | ||
register long _arg5 __asm__ ("a4") = (long)(arg5); \ | ||
register long _arg6 __asm__ ("a5") = (long)(arg6); \ | ||
\ | ||
__asm__ volatile ( \ | ||
"syscall 0\n" \ | ||
: "+r"(_arg1) \ | ||
: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \ | ||
"r"(_num) \ | ||
: "memory", "$t0", "$t1", "$t2", "$t3", \ | ||
"$t4", "$t5", "$t6", "$t7", "$t8" \ | ||
); \ | ||
_arg1; \ | ||
}) | ||
|
||
char **environ __attribute__((weak)); | ||
const unsigned long *_auxv __attribute__((weak)); | ||
|
||
#if __loongarch_grlen == 32 | ||
#define LONGLOG "2" | ||
#define SZREG "4" | ||
#define REG_L "ld.w" | ||
#define LONG_S "st.w" | ||
#define LONG_ADD "add.w" | ||
#define LONG_ADDI "addi.w" | ||
#define LONG_SLL "slli.w" | ||
#define LONG_BSTRINS "bstrins.w" | ||
#else // __loongarch_grlen == 64 | ||
#define LONGLOG "3" | ||
#define SZREG "8" | ||
#define REG_L "ld.d" | ||
#define LONG_S "st.d" | ||
#define LONG_ADD "add.d" | ||
#define LONG_ADDI "addi.d" | ||
#define LONG_SLL "slli.d" | ||
#define LONG_BSTRINS "bstrins.d" | ||
#endif | ||
|
||
/* startup code */ | ||
void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) _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 | ||
"syscall 0\n" | ||
); | ||
__builtin_unreachable(); | ||
} | ||
|
||
#endif // _NOLIBC_ARCH_LOONGARCH_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ | ||
/* | ||
* Stack protector support for NOLIBC | ||
* Copyright (C) 2023 Thomas Weißschuh <linux@weissschuh.net> | ||
*/ | ||
|
||
#ifndef _NOLIBC_STACKPROTECTOR_H | ||
#define _NOLIBC_STACKPROTECTOR_H | ||
|
||
#include "arch.h" | ||
|
||
#if defined(NOLIBC_STACKPROTECTOR) | ||
|
||
#if !defined(__ARCH_SUPPORTS_STACK_PROTECTOR) | ||
#error "nolibc does not support stack protectors on this arch" | ||
#endif | ||
|
||
#include "sys.h" | ||
#include "stdlib.h" | ||
|
||
/* The functions in this header are using raw syscall macros to avoid | ||
* triggering stack protector errors themselves | ||
*/ | ||
|
||
__attribute__((weak,noreturn,section(".text.nolibc_stack_chk"))) | ||
void __stack_chk_fail(void) | ||
{ | ||
pid_t pid; | ||
my_syscall3(__NR_write, STDERR_FILENO, "!!Stack smashing detected!!\n", 28); | ||
pid = my_syscall0(__NR_getpid); | ||
my_syscall2(__NR_kill, pid, SIGABRT); | ||
for (;;); | ||
} | ||
|
||
__attribute__((weak,noreturn,section(".text.nolibc_stack_chk"))) | ||
void __stack_chk_fail_local(void) | ||
{ | ||
__stack_chk_fail(); | ||
} | ||
|
||
__attribute__((weak,section(".data.nolibc_stack_chk"))) | ||
uintptr_t __stack_chk_guard; | ||
|
||
__attribute__((weak,no_stack_protector,section(".text.nolibc_stack_chk"))) | ||
void __stack_chk_init(void) | ||
{ | ||
my_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0); | ||
/* a bit more randomness in case getrandom() fails */ | ||
__stack_chk_guard ^= (uintptr_t) &__stack_chk_guard; | ||
} | ||
#endif // defined(NOLIBC_STACKPROTECTOR) | ||
|
||
#endif // _NOLIBC_STACKPROTECTOR_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.