diff --git a/repos/base-linux/lib/import/import-lx_hybrid.mk b/repos/base-linux/lib/import/import-lx_hybrid.mk index e47af6fa07..1821983234 100644 --- a/repos/base-linux/lib/import/import-lx_hybrid.mk +++ b/repos/base-linux/lib/import/import-lx_hybrid.mk @@ -74,7 +74,7 @@ EXT_OBJECTS += $(shell $(CUSTOM_CC) $(CC_MARCH) -print-file-name=crtbegin.o) EXT_OBJECTS += $(shell $(CUSTOM_CC) $(CC_MARCH) -print-file-name=crtend.o) EXT_OBJECTS += $(shell $(CUSTOM_HOST_CC) $(CC_MARCH) -print-file-name=crtn.o) -LX_LIBS_OPT += -lgcc -lgcc_s -lsupc++ -lc -lpthread +LX_LIBS_OPT += -lgcc_s -lsupc++ -lc -lpthread -lgcc USE_HOST_LD_SCRIPT = yes @@ -98,6 +98,11 @@ CXX_LINK_OPT += -Wl,--dynamic-linker=/lib/ld-linux.so.3 LD_SCRIPT_STATIC = ldscripts/armelf_linux_eabi.xc endif +ifeq (arm_64,$(findstring arm_64,$(SPECS))) +CXX_LINK_OPT += -Wl,--dynamic-linker=/lib/ld-linux-aarch64.so.1 +LD_SCRIPT_STATIC = /usr/lib/aarch64-linux-gnu/ldscripts/aarch64elf.xc +endif + # # Because we use the host compiler's libgcc, omit the Genode toolchain's # version and put all libraries here we depend on. diff --git a/repos/base-linux/lib/import/import-syscall-linux.mk b/repos/base-linux/lib/import/import-syscall-linux.mk index d02ff8ffb5..f873dafb99 100644 --- a/repos/base-linux/lib/import/import-syscall-linux.mk +++ b/repos/base-linux/lib/import/import-syscall-linux.mk @@ -11,6 +11,7 @@ HOST_INC_DIR += /usr/include/$(shell $(CUSTOM_HOST_CC) -dumpmachine) # HOST_INC_DIR += /usr/include/i386-linux-gnu HOST_INC_DIR += /usr/include/x86_64-linux-gnu +HOST_INC_DIR += /usr/include/aarch64-linux-gnu # # Some header files installed on GNU/Linux test for the GNU compiler. For diff --git a/repos/base-linux/lib/mk/spec/arm_64/base-linux.mk b/repos/base-linux/lib/mk/spec/arm_64/base-linux.mk new file mode 100644 index 0000000000..cfccca9a66 --- /dev/null +++ b/repos/base-linux/lib/mk/spec/arm_64/base-linux.mk @@ -0,0 +1,3 @@ +LIBS += timeout-arm + +include $(REP_DIR)/lib/mk/base-linux.mk diff --git a/repos/base-linux/lib/mk/spec/arm_64/ld-linux.mk b/repos/base-linux/lib/mk/spec/arm_64/ld-linux.mk new file mode 100644 index 0000000000..9b11772e95 --- /dev/null +++ b/repos/base-linux/lib/mk/spec/arm_64/ld-linux.mk @@ -0,0 +1,3 @@ +BASE_LIBS += base-linux-common base-linux + +include $(BASE_DIR)/lib/mk/spec/arm_64/ld-platform.inc diff --git a/repos/base-linux/lib/mk/spec/arm_64/seccomp.mk b/repos/base-linux/lib/mk/spec/arm_64/seccomp.mk new file mode 100644 index 0000000000..40d742d8b1 --- /dev/null +++ b/repos/base-linux/lib/mk/spec/arm_64/seccomp.mk @@ -0,0 +1,3 @@ +SRC_BIN += seccomp_bpf_policy.bin + +vpath seccomp_bpf_policy.bin $(REP_DIR)/src/lib/seccomp/spec/arm_64 diff --git a/repos/base-linux/lib/mk/spec/arm_64/startup-linux.mk b/repos/base-linux/lib/mk/spec/arm_64/startup-linux.mk new file mode 100644 index 0000000000..60269cc775 --- /dev/null +++ b/repos/base-linux/lib/mk/spec/arm_64/startup-linux.mk @@ -0,0 +1 @@ +include $(BASE_DIR)/lib/mk/spec/arm_64/startup.inc diff --git a/repos/base-linux/lib/mk/spec/arm_64/syscall-linux.mk b/repos/base-linux/lib/mk/spec/arm_64/syscall-linux.mk new file mode 100644 index 0000000000..6daedb52f9 --- /dev/null +++ b/repos/base-linux/lib/mk/spec/arm_64/syscall-linux.mk @@ -0,0 +1,5 @@ +SRC_S += lx_clone.S +SRC_S += lx_syscall.S + +vpath lx_clone.S $(REP_DIR)/src/lib/syscall/spec/arm_64 +vpath lx_syscall.S $(REP_DIR)/src/lib/syscall/spec/arm_64 diff --git a/repos/base-linux/recipes/src/base-linux/content.mk b/repos/base-linux/recipes/src/base-linux/content.mk index f63694205a..ad1db4cc75 100644 --- a/repos/base-linux/recipes/src/base-linux/content.mk +++ b/repos/base-linux/recipes/src/base-linux/content.mk @@ -6,7 +6,7 @@ lib/import src/ld: $(mirror_from_rep_dir) content: - for spec in x86_32 x86_64 arm; do \ + for spec in x86_32 x86_64 arm arm_64; do \ mv lib/mk/spec/$$spec/ld-linux.mk lib/mk/spec/$$spec/ld.mk; done; sed -i "/TARGET/s/core-linux/core/" src/core/linux/target.mk sed -i "s/BOARD.*unknown/BOARD := linux/" lib/mk/core-linux.inc diff --git a/repos/base-linux/src/core/include/core_linux_syscalls.h b/repos/base-linux/src/core/include/core_linux_syscalls.h index e2f613331e..3813a93cb5 100644 --- a/repos/base-linux/src/core/include/core_linux_syscalls.h +++ b/repos/base-linux/src/core/include/core_linux_syscalls.h @@ -60,6 +60,11 @@ inline int lx_open(char const *pathname, int flags, mode_t mode = 0) inline int lx_stat_size(char const *path, Genode::uint64_t &out_size) { +#ifdef __aarch64__ + struct statx buf { }; + int result = lx_syscall(SYS_statx, AT_FDCWD, path, 0, STATX_SIZE, &buf); + out_size = buf.stx_size; +#else #ifdef _LP64 struct stat buf { }; int result = lx_syscall(SYS_stat, path, &buf); @@ -68,6 +73,7 @@ inline int lx_stat_size(char const *path, Genode::uint64_t &out_size) struct stat64 buf { }; int result = lx_syscall(SYS_stat64, path, &buf); out_size = buf.st_size; +#endif #endif return result; } diff --git a/repos/base-linux/src/lib/seccomp/spec/arm_64/seccomp_bpf_policy.bin b/repos/base-linux/src/lib/seccomp/spec/arm_64/seccomp_bpf_policy.bin new file mode 100644 index 0000000000..74cef5c6a7 Binary files /dev/null and b/repos/base-linux/src/lib/seccomp/spec/arm_64/seccomp_bpf_policy.bin differ diff --git a/repos/base-linux/src/lib/syscall/linux_syscalls.h b/repos/base-linux/src/lib/syscall/linux_syscalls.h index 2a192c58d3..3b5f986dd2 100644 --- a/repos/base-linux/src/lib/syscall/linux_syscalls.h +++ b/repos/base-linux/src/lib/syscall/linux_syscalls.h @@ -356,7 +356,7 @@ inline int lx_sigaction(int signum, void (*handler)(int), bool altstack) * with EINTR. We therefore set the SA_RESTART flag in signal handlers. */ -#ifdef _LP64 +#ifdef __x86_64__ /* * The SA_RESTORER flag is not officially documented, but used internally * by the glibc implementation of sigaction(). Without specifying this flag diff --git a/repos/base-linux/src/lib/syscall/spec/arm_64/lx_clone.S b/repos/base-linux/src/lib/syscall/spec/arm_64/lx_clone.S new file mode 100644 index 0000000000..676bbba091 --- /dev/null +++ b/repos/base-linux/src/lib/syscall/spec/arm_64/lx_clone.S @@ -0,0 +1,19 @@ +/* + * \brief Linux clone() binding + * \author Norman Feske + * \date 2021-04-12 + */ + +#define SYS_clone 220 + + .text + .globl lx_clone + .type lx_clone, #function +lx_clone: + stp x29, x30, [sp, #-16]! /* save sp and link register */ + stp x3, x0, [x1, #-16]! /* supply fn and argp at new thread's stack */ + mov x0, x2 /* flags */ + mov w8, #SYS_clone + svc #0 /* syscall, return value in x0 */ + ldp x29, x30, [sp], #16 /* restore sp and link register */ + ret diff --git a/repos/base-linux/src/lib/syscall/spec/arm_64/lx_syscall.S b/repos/base-linux/src/lib/syscall/spec/arm_64/lx_syscall.S new file mode 100644 index 0000000000..13f5f35664 --- /dev/null +++ b/repos/base-linux/src/lib/syscall/spec/arm_64/lx_syscall.S @@ -0,0 +1,21 @@ +/* + * \brief Linux syscall() binding + * \author Norman Feske + * \date 2021-04-07 + */ + + .text + .globl lx_syscall + .type lx_syscall, #function +lx_syscall: + stp x29, x30, [sp, #-16]! /* save sp and link register */ + mov x8, x0 /* system call number */ + mov x0, x1 /* arguments ... */ + mov x1, x2 + mov x2, x3 + mov x3, x4 + mov x4, x5 + mov x5, x6 + svc #0 /* syscall, return value in x0 */ + ldp x29, x30, [sp], #16 /* restore sp and link register */ + ret diff --git a/repos/base/lib/mk/spec/arm_64/startup.inc b/repos/base/lib/mk/spec/arm_64/startup.inc new file mode 100644 index 0000000000..2e0b44eb62 --- /dev/null +++ b/repos/base/lib/mk/spec/arm_64/startup.inc @@ -0,0 +1,3 @@ +include $(BASE_DIR)/lib/mk/startup.inc + +vpath crt0.s $(call select_from_repositories,src/lib/startup/spec/arm_64) diff --git a/repos/base/src/lib/startup/spec/arm_64/crt0.s b/repos/base/src/lib/startup/spec/arm_64/crt0.s index 41db7888d9..9826594fe7 100644 --- a/repos/base/src/lib/startup/spec/arm_64/crt0.s +++ b/repos/base/src/lib/startup/spec/arm_64/crt0.s @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2019 Genode Labs GmbH + * Copyright (C) 2019-2021 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -24,6 +24,12 @@ .global _start_initial_stack _start_initial_stack: + /* save initial SP value, used to pass the environment on base-linux */ + adrp x4, :got:__initial_sp + ldr x4, [x4, #:got_lo12:__initial_sp] + mov x1, sp + str x1, [x4] + /* * Install initial temporary environment that is replaced later by the * environment that init_main_thread creates. @@ -53,6 +59,10 @@ *********************************/ .bss + /* initial value of the SP register */ + .global __initial_sp + __initial_sp: + .space 8 /* stack of the temporary initial environment */ .p2align 8 diff --git a/tool/builddir/build.conf/run_arm_v8 b/tool/builddir/build.conf/run_arm_v8 index c8c10b729c..c7df3ed4ac 100644 --- a/tool/builddir/build.conf/run_arm_v8 +++ b/tool/builddir/build.conf/run_arm_v8 @@ -8,6 +8,7 @@ QEMU_RUN_OPT := --include power_on/qemu --include log/qemu #BOARD ?= rpi3 # local variable for run-tool arguments that depend on the used board +BOARD_RUN_OPT(linux) := --include power_on/linux --include log/linux BOARD_RUN_OPT(rpi3) := $(QEMU_RUN_OPT) BOARD_RUN_OPT(virt_qemu) := $(QEMU_RUN_OPT) diff --git a/tool/seccomp/.gitignore b/tool/seccomp/.gitignore index b9659241aa..ec4436084e 100644 --- a/tool/seccomp/.gitignore +++ b/tool/seccomp/.gitignore @@ -1,3 +1,4 @@ -/seccomp_bpf_policy_arm.bin +/seccomp_bpf_policy_arm_32.bin +/seccomp_bpf_policy_arm_64.bin /seccomp_bpf_policy_x86_32.bin /seccomp_bpf_policy_x86_64.bin diff --git a/tool/seccomp/Makefile b/tool/seccomp/Makefile index 15f213cb27..504ae61b0e 100644 --- a/tool/seccomp/Makefile +++ b/tool/seccomp/Makefile @@ -1,6 +1,8 @@ .DEFAULT_GOAL := seccomp_bpf_filters -seccomp_bpf_filters: seccomp_bpf_policy_x86_32.bin seccomp_bpf_policy_x86_64.bin seccomp_bpf_policy_arm.bin +ARCHS := x86_32 x86_64 arm_32 arm_64 + +seccomp_bpf_filters: $(foreach A,$(ARCHS),seccomp_bpf_policy_$A.bin) seccomp_bpf_policy_%.bin: seccomp_bpf_compiler_%.prg ./$< > $@ diff --git a/tool/seccomp/seccomp_bpf_compiler.h b/tool/seccomp/seccomp_bpf_compiler.h index 4c6c9ac293..389b0e8e79 100644 --- a/tool/seccomp/seccomp_bpf_compiler.h +++ b/tool/seccomp/seccomp_bpf_compiler.h @@ -122,8 +122,9 @@ class Filter _add_allow_rule(SCMP_SYS(gettimeofday)); _add_allow_rule(SCMP_SYS(getpeername)); - int clone_flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND - | CLONE_THREAD | CLONE_SYSVSEM; + unsigned long clone_flags = CLONE_VM | CLONE_FS | CLONE_FILES + | CLONE_SIGHAND | CLONE_THREAD + | CLONE_SYSVSEM; switch (_arch) { @@ -196,6 +197,16 @@ class Filter _add_allow_rule(SCMP_SYS(sigreturn)); } break; + case SCMP_ARCH_AARCH64: + { + _add_allow_rule(SCMP_SYS(tgkill), SCMP_CMP32(0, SCMP_CMP_EQ, 0xCAFEAFFE), + SCMP_CMP32(2, SCMP_CMP_EQ, SIGRTMIN)); + _add_allow_rule(SCMP_SYS(clone), SCMP_CMP32(0, SCMP_CMP_EQ, clone_flags)); + _add_allow_rule(SCMP_SYS(mmap)); + _add_allow_rule(SCMP_SYS(cacheflush)); + _add_allow_rule(SCMP_SYS(sigreturn)); + } + break; default: fprintf(stderr, "Unsupported architecture\n"); throw -104; diff --git a/tool/seccomp/seccomp_bpf_compiler_arm.cc b/tool/seccomp/seccomp_bpf_compiler_arm_32.cc similarity index 100% rename from tool/seccomp/seccomp_bpf_compiler_arm.cc rename to tool/seccomp/seccomp_bpf_compiler_arm_32.cc diff --git a/tool/seccomp/seccomp_bpf_compiler_arm_64.cc b/tool/seccomp/seccomp_bpf_compiler_arm_64.cc new file mode 100644 index 0000000000..7e389b375f --- /dev/null +++ b/tool/seccomp/seccomp_bpf_compiler_arm_64.cc @@ -0,0 +1,23 @@ +/* + * \brief Generate seccomp filter policy for base-linux on arm + * \author Stefan Thoeni + * \date 2019-12-13 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * Copyright (C) 2019 gapfruit AG + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#include /* printf */ +#include /* libseccomp */ +#include "seccomp_bpf_compiler.h" + +int main() +{ + Filter filter(SCMP_ARCH_AARCH64); + return filter.create(); +}