Initial RISC-V64 support
This commit is contained in:
+2
-1
@@ -1,6 +1,7 @@
|
||||
[submodule "openlibm"]
|
||||
path = openlibm
|
||||
url = https://gitlab.redox-os.org/redox-os/openlibm.git
|
||||
url = https://github.com/JuliaMath/openlibm.git
|
||||
branch = master
|
||||
[submodule "posix-regex"]
|
||||
path = posix-regex
|
||||
url = https://gitlab.redox-os.org/redox-os/posix-regex.git
|
||||
|
||||
Generated
+4
-5
@@ -67,9 +67,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
|
||||
version = "1.1.22"
|
||||
source = "git+https://github.com/tea/cc-rs?branch=riscv-abi-arch-fix#588ceacb084af41415690c57688e338a32a1f1b4"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
@@ -344,9 +343,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.5"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62871f2d65009c0256aed1b9cfeeb8ac272833c404e13d53d400cd0dad7a2ac0"
|
||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
@@ -74,3 +74,6 @@ panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
|
||||
[patch.crates-io]
|
||||
cc-11 = { git = "https://github.com/tea/cc-rs", branch="riscv-abi-arch-fix", package = "cc" }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
TARGET?=$(shell rustc -Z unstable-options --print target-spec-json | grep llvm-target | cut -d '"' -f4)
|
||||
export TARGET?=$(shell rustc -Z unstable-options --print target-spec-json | grep llvm-target | cut -d '"' -f4)
|
||||
|
||||
CARGO?=cargo
|
||||
CARGO_TEST?=$(CARGO)
|
||||
@@ -20,35 +20,54 @@ ifeq ($(TARGET),aarch64-unknown-linux-gnu)
|
||||
export CC=aarch64-linux-gnu-gcc
|
||||
export LD=aarch64-linux-gnu-ld
|
||||
export AR=aarch64-linux-gnu-ar
|
||||
export NM=aarch64-linux-gnu-nm
|
||||
export OBJCOPY=aarch64-linux-gnu-objcopy
|
||||
export CPPFLAGS=
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),aarch64-unknown-redox)
|
||||
export CC=aarch64-unknown-redox-gcc
|
||||
export LD=aarch64-unknown-redox-ld
|
||||
export AR=aarch64-unknown-redox-ar
|
||||
export NM=aarch64-unknown-redox-nm
|
||||
export OBJCOPY=aarch64-unknown-redox-objcopy
|
||||
export CPPFLAGS=
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),x86_64-unknown-linux-gnu)
|
||||
export CC=x86_64-linux-gnu-gcc
|
||||
export LD=x86_64-linux-gnu-ld
|
||||
export AR=x86_64-linux-gnu-ar
|
||||
export NM=x86_64-linux-gnu-nm
|
||||
export OBJCOPY=x86_64-linux-gnu-objcopy
|
||||
export CPPFLAGS=
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),i686-unknown-redox)
|
||||
export CC=i686-unknown-redox-gcc
|
||||
export LD=i686-unknown-redox-ld
|
||||
export AR=i686-unknown-redox-ar
|
||||
export NM=i686-unknown-redox-nm
|
||||
export OBJCOPY=i686-unknown-redox-objcopy
|
||||
export CPPFLAGS=
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),x86_64-unknown-redox)
|
||||
export CC=x86_64-unknown-redox-gcc
|
||||
export LD=x86_64-unknown-redox-ld
|
||||
export AR=x86_64-unknown-redox-ar
|
||||
export NM=x86_64-unknown-redox-nm
|
||||
export OBJCOPY=x86_64-unknown-redox-objcopy
|
||||
export CPPFLAGS=
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),riscv64gc-unknown-redox)
|
||||
export CC=riscv64-unknown-redox-gcc
|
||||
export LD=riscv64-unknown-redox-ld
|
||||
export AR=riscv64-unknown-redox-ar
|
||||
export NM=riscv64-unknown-redox-nm
|
||||
export OBJCOPY=riscv64-unknown-redox-objcopy
|
||||
export CPPFLAGS=-march=rv64gc -mabi=lp64d
|
||||
endif
|
||||
|
||||
SRC=\
|
||||
@@ -158,7 +177,7 @@ $(BUILD)/debug/libc.so: $(BUILD)/debug/librelibc.a $(BUILD)/openlibm/libopenlibm
|
||||
|
||||
$(BUILD)/debug/librelibc.a: $(SRC)
|
||||
$(CARGO) rustc $(CARGOFLAGS) -- --emit link=$@ $(RUSTCFLAGS)
|
||||
./renamesyms.sh $@ $(BUILD)/debug/deps/
|
||||
./renamesyms.sh "$@" "$(BUILD)/debug/deps/"
|
||||
touch $@
|
||||
|
||||
$(BUILD)/debug/crt0.o: $(SRC)
|
||||
@@ -198,7 +217,7 @@ $(BUILD)/release/librelibc.a: $(SRC)
|
||||
$(CARGO) rustc --release $(CARGOFLAGS) -- --emit link=$@ $(RUSTCFLAGS)
|
||||
# TODO: Better to only allow a certain whitelisted set of symbols? Perhaps
|
||||
# use some cbindgen hook, specify them manually, or grep for #[no_mangle].
|
||||
./renamesyms.sh $@ $(BUILD)/release/deps/
|
||||
./renamesyms.sh "$@" "$(BUILD)/release/deps/"
|
||||
touch $@
|
||||
|
||||
$(BUILD)/release/crt0.o: $(SRC)
|
||||
@@ -230,4 +249,4 @@ $(BUILD)/openlibm: openlibm
|
||||
touch $@
|
||||
|
||||
$(BUILD)/openlibm/libopenlibm.a: $(BUILD)/openlibm $(BUILD)/release/librelibc.a
|
||||
$(MAKE) AR=$(AR) CC=$(CC) LD=$(LD) CPPFLAGS="-fno-stack-protector -I$(shell pwd)/include -I$(TARGET_HEADERS)" -C $< libopenlibm.a
|
||||
$(MAKE) AR=$(AR) CC=$(CC) LD=$(LD) CPPFLAGS="$(CPPFLAGS) -fno-stack-protector -I$(shell pwd)/include -I$(TARGET_HEADERS)" -C $< libopenlibm.a
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
"target_arch=x86" = "__i386__"
|
||||
"target_arch=x86_64" = "__x86_64__"
|
||||
"target_arch=aarch64" = "__aarch64__"
|
||||
# This is not exact. It should be `defined(__riscv) && defined(__LP64__)`, or `defined(__riscv) && __riscv_xlen==64`
|
||||
# This will do however, as long as we only support riscv64 and not riscv32
|
||||
"target_arch=riscv64" = "__riscv"
|
||||
|
||||
# XXX: silences a warning
|
||||
"feature = no_std" = "__relibc__"
|
||||
|
||||
@@ -64,6 +64,21 @@ impl<Os> GenericTcb<Os> {
|
||||
value
|
||||
}
|
||||
|
||||
/// Architecture specific code to read a usize from the TCB - riscv64
|
||||
#[inline(always)]
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
unsafe fn arch_read(offset: usize) -> usize {
|
||||
let value;
|
||||
asm!(
|
||||
"ld {value}, -8(tp)", // TCB
|
||||
"add {value}, {value}, {offset}",
|
||||
"ld {value}, 0({value})",
|
||||
value = out(reg) value,
|
||||
offset = in(reg) offset,
|
||||
);
|
||||
value
|
||||
}
|
||||
|
||||
pub unsafe fn current_ptr() -> Option<*mut Self> {
|
||||
let tcb_ptr = Self::arch_read(offset_of!(Self, tcb_ptr)) as *mut Self;
|
||||
let tcb_len = Self::arch_read(offset_of!(Self, tcb_len));
|
||||
|
||||
@@ -61,6 +61,10 @@ typedef unsigned long long jmp_buf[8];
|
||||
typedef unsigned long jmp_buf[8];
|
||||
#endif
|
||||
|
||||
#ifdef __riscv
|
||||
typedef unsigned long jmp_buf[26];
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+3
-1
@@ -4,8 +4,10 @@
|
||||
#include <arch/x64/user.h>
|
||||
#elif defined(__aarch64__)
|
||||
#include <arch/aarch64/user.h>
|
||||
#elif defined(__riscv) && __riscv_xlen==64
|
||||
#include <arch/riscv64/user.h>
|
||||
#else
|
||||
#error "Unknown architecture"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
/* Script for -z combreloc */
|
||||
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv" )
|
||||
OUTPUT_ARCH(riscv)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("/riscv64-unknown-redox/lib");
|
||||
SEARCH_DIR("/usr/local/lib64");
|
||||
SEARCH_DIR("/lib64");
|
||||
SEARCH_DIR("/usr/lib64");
|
||||
SEARCH_DIR("/usr/local/lib");
|
||||
SEARCH_DIR("/lib");
|
||||
SEARCH_DIR("/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
|
||||
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
|
||||
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
. = ALIGN(CONSTANT (MAXPAGESIZE));
|
||||
.plt : { *(.plt) *(.iplt) }
|
||||
.plt.got : { *(.plt.got) }
|
||||
.plt.sec : { *(.plt.sec) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf.em. */
|
||||
*(.gnu.warning)
|
||||
}
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
. = ALIGN(CONSTANT (MAXPAGESIZE));
|
||||
/* Adjust the address for the rodata segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata :
|
||||
{
|
||||
PROVIDE_HIDDEN (__tdata_start = .);
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
}
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
.data :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we do not
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
.lbss :
|
||||
{
|
||||
*(.dynlbss)
|
||||
*(.lbss .lbss.* .gnu.linkonce.lb.*)
|
||||
*(LARGE_COMMON)
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
|
||||
}
|
||||
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.ldata .ldata.* .gnu.linkonce.l.*)
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.debug_addr 0 : { *(.debug_addr) }
|
||||
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
@@ -62,6 +62,17 @@ _start:
|
||||
"
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
global_asm!(
|
||||
"
|
||||
.globl _start
|
||||
_start:
|
||||
mv a0, sp
|
||||
jal relibc_ld_so_start
|
||||
unimp
|
||||
"
|
||||
);
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn main(_argc: isize, _argv: *const *const i8) -> usize {
|
||||
// LD
|
||||
|
||||
+1
-1
Submodule openlibm updated: e2da0dafd3...5992e5a177
@@ -12,3 +12,8 @@ pub mod i686;
|
||||
pub use self::x86_64::*;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod x86_64;
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub use self::riscv64::*;
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub mod riscv64;
|
||||
|
||||
@@ -0,0 +1,622 @@
|
||||
use crate::{
|
||||
proc::{fork_inner, FdGuard},
|
||||
signal::{get_sigaltstack, inner_c, PosixStackt, RtSigarea, SigStack},
|
||||
RtTcb, Tcb,
|
||||
};
|
||||
use core::{mem::offset_of, ptr::NonNull, sync::atomic::Ordering};
|
||||
use syscall::{data::*, error::*};
|
||||
|
||||
// Setup a stack starting from the very end of the address space, and then growing downwards.
|
||||
pub(crate) const STACK_TOP: usize = 1 << 47;
|
||||
pub(crate) const STACK_SIZE: usize = 1024 * 1024;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[repr(C)]
|
||||
pub struct SigArea {
|
||||
pub tmp_sp: u64,
|
||||
pub tmp_t1: u64,
|
||||
pub tmp_t2: u64,
|
||||
pub tmp_t3: u64,
|
||||
pub tmp_t4: u64,
|
||||
pub tmp_a0: u64,
|
||||
pub tmp_a1: u64,
|
||||
pub tmp_a2: u64,
|
||||
pub tmp_a7: u64,
|
||||
|
||||
pub pctl: usize, // TODO: remove
|
||||
pub tmp_ip: u64,
|
||||
pub tmp_rt_inf: RtSigInfo,
|
||||
pub tmp_id_inf: u64,
|
||||
pub altstack_top: usize,
|
||||
pub altstack_bottom: usize,
|
||||
pub disable_signals_depth: u64,
|
||||
pub last_sig_was_restart: bool,
|
||||
pub last_sigstack: Option<NonNull<SigStack>>,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ArchIntRegs {
|
||||
pub int_regs: [u64; 31],
|
||||
pub pc: u64,
|
||||
pub fp_regs: [u64; 32],
|
||||
pub fcsr: u32,
|
||||
_pad: u32,
|
||||
}
|
||||
|
||||
/// Deactive TLS, used before exec() on Redox to not trick target executable into thinking TLS
|
||||
/// is already initialized as if it was a thread.
|
||||
pub unsafe fn deactivate_tcb(open_via_dup: usize) -> Result<()> {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = FdGuard::new(syscall::dup(open_via_dup, b"regs/env")?);
|
||||
|
||||
env.tp = 0;
|
||||
|
||||
let _ = syscall::write(*file, &mut env)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn copy_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> {
|
||||
// Copy environment registers.
|
||||
{
|
||||
let cur_env_regs_fd = FdGuard::new(syscall::dup(cur_pid_fd, b"regs/env")?);
|
||||
let new_env_regs_fd = FdGuard::new(syscall::dup(new_pid_fd, b"regs/env")?);
|
||||
|
||||
let mut env_regs = syscall::EnvRegisters::default();
|
||||
let _ = syscall::read(*cur_env_regs_fd, &mut env_regs)?;
|
||||
let _ = syscall::write(*new_env_regs_fd, &env_regs)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe extern "C" fn fork_impl(initial_rsp: *mut usize) -> usize {
|
||||
Error::mux(fork_inner(initial_rsp))
|
||||
}
|
||||
|
||||
unsafe extern "C" fn child_hook(cur_filetable_fd: usize, new_pid_fd: usize) {
|
||||
let _ = syscall::close(cur_filetable_fd);
|
||||
crate::child_hook_common(FdGuard::new(new_pid_fd));
|
||||
}
|
||||
|
||||
asmfunction!(__relibc_internal_fork_wrapper -> usize: ["
|
||||
.attribute arch, \"rv64gc\" # rust bug 80608
|
||||
addi sp, sp, -200
|
||||
sd s0, 0(sp)
|
||||
sd s1, 8(sp)
|
||||
sd s2, 16(sp)
|
||||
sd s3, 24(sp)
|
||||
sd s4, 32(sp)
|
||||
sd s5, 40(sp)
|
||||
sd s6, 48(sp)
|
||||
sd s7, 56(sp)
|
||||
sd s8, 64(sp)
|
||||
sd s9, 72(sp)
|
||||
sd s10, 80(sp)
|
||||
sd s11, 88(sp)
|
||||
sd ra, 96(sp)
|
||||
|
||||
fsd fs0, 104(sp)
|
||||
fsd fs1, 112(sp)
|
||||
fsd fs2, 120(sp)
|
||||
fsd fs3, 128(sp)
|
||||
fsd fs4, 136(sp)
|
||||
fsd fs5, 144(sp)
|
||||
fsd fs6, 152(sp)
|
||||
fsd fs7, 160(sp)
|
||||
fsd fs8, 168(sp)
|
||||
fsd fs9, 176(sp)
|
||||
fsd fs10, 184(sp)
|
||||
fsd fs11, 192(sp)
|
||||
|
||||
addi sp, sp, -32
|
||||
mv a0, sp
|
||||
jal {fork_impl}
|
||||
|
||||
addi sp, sp, 32
|
||||
|
||||
ld s0, 0(sp)
|
||||
ld s1, 8(sp)
|
||||
ld s2, 16(sp)
|
||||
ld s3, 24(sp)
|
||||
ld s4, 32(sp)
|
||||
ld s5, 40(sp)
|
||||
ld s6, 48(sp)
|
||||
ld s7, 56(sp)
|
||||
ld s8, 64(sp)
|
||||
ld s9, 72(sp)
|
||||
ld s10, 80(sp)
|
||||
ld s11, 88(sp)
|
||||
ld ra, 96(sp)
|
||||
|
||||
fld fs0, 104(sp)
|
||||
fld fs1, 112(sp)
|
||||
fld fs2, 120(sp)
|
||||
fld fs3, 128(sp)
|
||||
fld fs4, 136(sp)
|
||||
fld fs5, 144(sp)
|
||||
fld fs6, 152(sp)
|
||||
fld fs7, 160(sp)
|
||||
fld fs8, 168(sp)
|
||||
fld fs9, 176(sp)
|
||||
fld fs10, 184(sp)
|
||||
fld fs11, 192(sp)
|
||||
|
||||
addi sp, sp, 200
|
||||
ret
|
||||
"] <= [fork_impl = sym fork_impl]);
|
||||
|
||||
asmfunction!(__relibc_internal_fork_ret: ["
|
||||
.attribute arch, \"rv64gc\" # rust bug 80608
|
||||
ld a0, 0(sp)
|
||||
ld a1, 8(sp)
|
||||
jal {child_hook}
|
||||
|
||||
mv a0, x0
|
||||
|
||||
addi sp, sp, 32
|
||||
|
||||
ld s0, 0(sp)
|
||||
ld s1, 8(sp)
|
||||
ld s2, 16(sp)
|
||||
ld s3, 24(sp)
|
||||
ld s4, 32(sp)
|
||||
ld s5, 40(sp)
|
||||
ld s6, 48(sp)
|
||||
ld s7, 56(sp)
|
||||
ld s8, 64(sp)
|
||||
ld s9, 72(sp)
|
||||
ld s10, 80(sp)
|
||||
ld s11, 88(sp)
|
||||
ld ra, 96(sp)
|
||||
|
||||
fld fs0, 104(sp)
|
||||
fld fs1, 112(sp)
|
||||
fld fs2, 120(sp)
|
||||
fld fs3, 128(sp)
|
||||
fld fs4, 136(sp)
|
||||
fld fs5, 144(sp)
|
||||
fld fs6, 152(sp)
|
||||
fld fs7, 160(sp)
|
||||
fld fs8, 168(sp)
|
||||
fld fs9, 176(sp)
|
||||
fld fs10, 184(sp)
|
||||
fld fs11, 192(sp)
|
||||
|
||||
addi sp, sp, 200
|
||||
ret
|
||||
"] <= [child_hook = sym child_hook]);
|
||||
|
||||
asmfunction!(__relibc_internal_sigentry: ["
|
||||
.attribute arch, \"rv64gc\" # rust bug 80608
|
||||
// Save some registers
|
||||
ld t0, -8(tp) // Tcb
|
||||
sd sp, ({tcb_sa_off} + {sa_tmp_sp})(t0)
|
||||
sd t1, ({tcb_sa_off} + {sa_tmp_t1})(t0)
|
||||
sd t2, ({tcb_sa_off} + {sa_tmp_t2})(t0)
|
||||
sd t3, ({tcb_sa_off} + {sa_tmp_t3})(t0)
|
||||
sd t4, ({tcb_sa_off} + {sa_tmp_t4})(t0)
|
||||
ld t4, ({tcb_sa_off} + {sa_off_pctl})(t0)
|
||||
|
||||
// First, select signal, always pick first available bit
|
||||
99:
|
||||
// Read first signal word
|
||||
ld t1, ({tcb_sc_off} + {sc_word})(t0)
|
||||
srli t2, t1, 32 // bitset to low word
|
||||
and t1, t1, t2 // masked bitset in low word
|
||||
beqz t1, 3f
|
||||
|
||||
// Found in first thread signal word
|
||||
mv t3, x0
|
||||
2: andi t2, t1, 1
|
||||
bnez t2, 10f
|
||||
addi t3, t3, 1
|
||||
srli t1, t1, 1
|
||||
j 2b
|
||||
|
||||
// If no unblocked thread signal was found, check for process.
|
||||
// This is competitive; we need to atomically check if *we* cleared the process-wide pending
|
||||
// bit, otherwise restart.
|
||||
3: lw t1, {pctl_off_pending}(t4)
|
||||
and t1, t1, t2
|
||||
beqz t1, 3f
|
||||
// Found in first process signal word
|
||||
li t3, -1
|
||||
2: andi t2, t1, 1
|
||||
addi t3, t3, 1
|
||||
srli t1, t1, 1
|
||||
beqz t2, 2b
|
||||
slli t1, t3, 3 // * 8 == size_of SenderInfo
|
||||
add t1, t1, t4
|
||||
ld t1, {pctl_off_sender_infos}(t1)
|
||||
sd t1, ({tcb_sa_off} + {sa_tmp_id_inf})(t0)
|
||||
li t1, 1
|
||||
sll t1, t1, t3
|
||||
not t1, t1
|
||||
addi t2, t4, {pctl_off_pending}
|
||||
amoand.w.aq t2, t1, (t2)
|
||||
and t1, t1, t2
|
||||
bne t1, t2, 9f
|
||||
|
||||
3:
|
||||
// Read second signal word - both process and thread simultaneously.
|
||||
// This must be done since POSIX requires low realtime signals to be picked first.
|
||||
ld t1, ({tcb_sc_off} + {sc_word} + 8)(t0)
|
||||
lw t2, ({pctl_off_pending} + 4)(t4)
|
||||
or t4, t1, t2
|
||||
srli t2, t1, 32
|
||||
and t4, t2, t4
|
||||
beqz t4, 7f
|
||||
li t3, -1
|
||||
2: andi t2, t4, 1
|
||||
addi t3, t3, 1
|
||||
srli t4, t4, 1
|
||||
beqz t2, 2b
|
||||
li t2, 1
|
||||
sll t2, t2, t3
|
||||
and t1, t1, t2
|
||||
addi t3, t3, 32
|
||||
bnez t1, 10f // thread signal
|
||||
|
||||
// otherwise, try (competitively) dequeueing realtime signal
|
||||
sd a0, ({tcb_sa_off} + {sa_tmp_a0})(t0)
|
||||
sd a1, ({tcb_sa_off} + {sa_tmp_a1})(t0)
|
||||
sd a2, ({tcb_sa_off} + {sa_tmp_a2})(t0)
|
||||
sd a7, ({tcb_sa_off} + {sa_tmp_a7})(t0)
|
||||
li a0, {SYS_SIGDEQUEUE}
|
||||
addi a1, t3, -32
|
||||
add a2, t0, {tcb_sa_off} + {sa_tmp_rt_inf} // out pointer of dequeued realtime sig
|
||||
ecall
|
||||
bnez a0, 99b // assumes error can only be EAGAIN
|
||||
j 9f
|
||||
|
||||
10: // thread signal. t3 holds signal number
|
||||
srli t1, t3, 5
|
||||
bnez t1, 2f // FIXME senderinfo?
|
||||
sll t2, t3, 3 // * 8 == size_of SenderInfo
|
||||
add t2, t2, t0
|
||||
ld t2, ({tcb_sc_off} + {sc_sender_infos})(t2)
|
||||
sd t2, ({tcb_sa_off} + {sa_tmp_id_inf})(t0)
|
||||
2: andi t4, t3, 31
|
||||
li t2, 1
|
||||
sll t2, t2, t4
|
||||
not t2, t2
|
||||
sll t1, t1, 3
|
||||
add t1, t1, t0
|
||||
addi t1, t1, {tcb_sc_off} + {sc_word}
|
||||
amoand.w.aq x0, t2, (t1)
|
||||
addi t3, t3, 64 // indicate signal was targeted at thread
|
||||
|
||||
9: // process signal t3 holds signal number
|
||||
|
||||
// By now we have selected a signal, stored in eax (6-bit). We now need to choose whether or
|
||||
// not to switch to the alternate signal stack. If SA_ONSTACK is clear for this signal, then
|
||||
// skip the sigaltstack logic.
|
||||
ld t4, ({tcb_sa_off} + {sa_off_pctl})(t0)
|
||||
andi t1, t3, 63
|
||||
slli t1, t1, 4 // * 16 == size_of RawAction
|
||||
add t1, t1, t4
|
||||
ld t1, {pctl_off_actions}(t1)
|
||||
slli t1, t1, 63-58 // SA_ONSTACK in sign bit
|
||||
bgez t1, 3f
|
||||
|
||||
// If current RSP is above altstack region, switch to altstack
|
||||
ld t1, ({tcb_sa_off} + {sa_altstack_top})(t0)
|
||||
bgtu sp, t1, 2f
|
||||
ld t2, ({tcb_sa_off} + {sa_altstack_bottom})(t0)
|
||||
bgtu sp, t3, 3f
|
||||
2: mv sp, t1
|
||||
3:
|
||||
// form mcontext on stack
|
||||
addi sp, sp, -33 * 8
|
||||
fsd f0, (0 * 8)(sp)
|
||||
fsd f1, (1 * 8)(sp)
|
||||
fsd f2, (2 * 8)(sp)
|
||||
fsd f3, (3 * 8)(sp)
|
||||
fsd f4, (4 * 8)(sp)
|
||||
fsd f5, (5 * 8)(sp)
|
||||
fsd f6, (6 * 8)(sp)
|
||||
fsd f7, (7 * 8)(sp)
|
||||
fsd f8, (8 * 8)(sp)
|
||||
fsd f9, (9 * 8)(sp)
|
||||
fsd f10, (10 * 8)(sp)
|
||||
fsd f11, (11 * 8)(sp)
|
||||
fsd f12, (12 * 8)(sp)
|
||||
fsd f13, (13 * 8)(sp)
|
||||
fsd f14, (14 * 8)(sp)
|
||||
fsd f15, (15 * 8)(sp)
|
||||
fsd f16, (16 * 8)(sp)
|
||||
fsd f17, (17 * 8)(sp)
|
||||
fsd f18, (18 * 8)(sp)
|
||||
fsd f19, (19 * 8)(sp)
|
||||
fsd f20, (20 * 8)(sp)
|
||||
fsd f21, (21 * 8)(sp)
|
||||
fsd f22, (22 * 8)(sp)
|
||||
fsd f23, (23 * 8)(sp)
|
||||
fsd f24, (24 * 8)(sp)
|
||||
fsd f25, (25 * 8)(sp)
|
||||
fsd f26, (26 * 8)(sp)
|
||||
fsd f27, (27 * 8)(sp)
|
||||
fsd f28, (28 * 8)(sp)
|
||||
fsd f29, (29 * 8)(sp)
|
||||
fsd f30, (30 * 8)(sp)
|
||||
fsd f31, (31 * 8)(sp)
|
||||
csrr t1, fcsr
|
||||
sw t1, (32 * 8)(sp)
|
||||
|
||||
addi sp, sp, -32 * 8
|
||||
sd x1, 0(sp)
|
||||
ld t1, ({tcb_sa_off} + {sa_tmp_sp})(t0)
|
||||
sd t1, (1 * 8)(sp) // x2 is sp
|
||||
sd x3, (2 * 8)(sp)
|
||||
sd x4, (3 * 8)(sp)
|
||||
ld t1, ({tcb_sc_off} + {sc_saved_t0})(t0)
|
||||
sd t1, (4 * 8)(sp) // x5 is t0
|
||||
ld t1, ({tcb_sa_off} + {sa_tmp_t1})(t0)
|
||||
sd t1, (5 * 8)(sp) // x6 is t1
|
||||
ld t1, ({tcb_sa_off} + {sa_tmp_t2})(t0)
|
||||
sd t1, (6 * 8)(sp) // x7 is t2
|
||||
sd x8, (7 * 8)(sp)
|
||||
sd x9, (8 * 8)(sp)
|
||||
sd x10, (9 * 8)(sp)
|
||||
sd x11, (10 * 8)(sp)
|
||||
sd x12, (11 * 8)(sp)
|
||||
sd x13, (12 * 8)(sp)
|
||||
sd x14, (13 * 8)(sp)
|
||||
sd x15, (14 * 8)(sp)
|
||||
sd x16, (15 * 8)(sp)
|
||||
sd x17, (16 * 8)(sp)
|
||||
sd x18, (17 * 8)(sp)
|
||||
sd x19, (18 * 8)(sp)
|
||||
sd x20, (19 * 8)(sp)
|
||||
sd x21, (20 * 8)(sp)
|
||||
sd x22, (21 * 8)(sp)
|
||||
sd x23, (22 * 8)(sp)
|
||||
sd x24, (23 * 8)(sp)
|
||||
sd x25, (24 * 8)(sp)
|
||||
sd x26, (25 * 8)(sp)
|
||||
sd x27, (26 * 8)(sp)
|
||||
ld t1, ({tcb_sa_off} + {sa_tmp_t3})(t0)
|
||||
sd t1, (27 * 8)(sp) // t3 is x28
|
||||
ld t1, ({tcb_sa_off} + {sa_tmp_t4})(t0)
|
||||
sd t1, (28 * 8)(sp) // t4 is x29
|
||||
sd x30, (29 * 8)(sp)
|
||||
sd x31, (30 * 8)(sp)
|
||||
ld t1, ({tcb_sc_off} + {sc_saved_ip})(t0)
|
||||
sd t1, (31 * 8)(sp)
|
||||
|
||||
// form ucontext
|
||||
addi sp, sp, -64
|
||||
sw t3, 60(sp)
|
||||
|
||||
mv t0, sp
|
||||
jal {inner}
|
||||
|
||||
addi sp, sp, 64
|
||||
|
||||
addi t0, sp, 32 * 8
|
||||
fld f0, (0 * 8)(t0)
|
||||
fld f1, (1 * 8)(t0)
|
||||
fld f2, (2 * 8)(t0)
|
||||
fld f3, (3 * 8)(t0)
|
||||
fld f4, (4 * 8)(t0)
|
||||
fld f5, (5 * 8)(t0)
|
||||
fld f6, (6 * 8)(t0)
|
||||
fld f7, (7 * 8)(t0)
|
||||
fld f8, (8 * 8)(t0)
|
||||
fld f9, (9 * 8)(t0)
|
||||
fld f10, (10 * 8)(t0)
|
||||
fld f11, (11 * 8)(t0)
|
||||
fld f12, (12 * 8)(t0)
|
||||
fld f13, (13 * 8)(t0)
|
||||
fld f14, (14 * 8)(t0)
|
||||
fld f15, (15 * 8)(t0)
|
||||
fld f16, (16 * 8)(t0)
|
||||
fld f17, (17 * 8)(t0)
|
||||
fld f18, (18 * 8)(t0)
|
||||
fld f19, (19 * 8)(t0)
|
||||
fld f20, (20 * 8)(t0)
|
||||
fld f21, (21 * 8)(t0)
|
||||
fld f22, (22 * 8)(t0)
|
||||
fld f23, (23 * 8)(t0)
|
||||
fld f24, (24 * 8)(t0)
|
||||
fld f25, (25 * 8)(t0)
|
||||
fld f26, (26 * 8)(t0)
|
||||
fld f27, (27 * 8)(t0)
|
||||
fld f28, (28 * 8)(t0)
|
||||
fld f29, (29 * 8)(t0)
|
||||
fld f30, (30 * 8)(t0)
|
||||
fld f31, (31 * 8)(t0)
|
||||
lw t1, (32 * 8)(t0)
|
||||
csrw fcsr, t1
|
||||
|
||||
ld x1, 0(sp)
|
||||
// skip sp
|
||||
// skip gp
|
||||
ld x4, (3 * 8)(sp)
|
||||
ld x5, (4 * 8)(sp)
|
||||
ld x6, (5 * 8)(sp)
|
||||
ld x7, (6 * 8)(sp)
|
||||
ld x8, (7 * 8)(sp)
|
||||
ld x9, (8 * 8)(sp)
|
||||
ld x10, (9 * 8)(sp)
|
||||
ld x11, (10 * 8)(sp)
|
||||
ld x12, (11 * 8)(sp)
|
||||
ld x13, (12 * 8)(sp)
|
||||
ld x14, (13 * 8)(sp)
|
||||
ld x15, (14 * 8)(sp)
|
||||
ld x16, (15 * 8)(sp)
|
||||
ld x17, (16 * 8)(sp)
|
||||
ld x18, (17 * 8)(sp)
|
||||
ld x19, (18 * 8)(sp)
|
||||
ld x20, (19 * 8)(sp)
|
||||
ld x21, (20 * 8)(sp)
|
||||
ld x22, (21 * 8)(sp)
|
||||
ld x23, (22 * 8)(sp)
|
||||
ld x24, (23 * 8)(sp)
|
||||
ld x25, (24 * 8)(sp)
|
||||
ld x26, (25 * 8)(sp)
|
||||
ld x27, (26 * 8)(sp)
|
||||
ld x28, (27 * 8)(sp)
|
||||
ld x29, (28 * 8)(sp)
|
||||
ld x30, (29 * 8)(sp)
|
||||
ld x31, (30 * 8)(sp)
|
||||
ld gp, (31 * 8)(sp) // new IP; this clobbers register x3/gp which is ABI reserved
|
||||
.global __relibc_internal_sigentry_crit_first
|
||||
__relibc_internal_sigentry_crit_first:
|
||||
ld sp, (1 * 8)(sp)
|
||||
.global __relibc_internal_sigentry_crit_second
|
||||
__relibc_internal_sigentry_crit_second:
|
||||
jr gp
|
||||
7:
|
||||
// A spurious signal occurred. Signals are still disabled here, but will need to be re-enabled.
|
||||
|
||||
// restore stack
|
||||
ld sp, ({tcb_sa_off} + {sa_tmp_sp})(t0)
|
||||
|
||||
// move saved IP away from control, allowing arch_pre to save us if interrupted.
|
||||
ld t1, ({tcb_sc_off} + {sc_saved_ip})(t0)
|
||||
sd t1, ({tcb_sa_off} + {sa_tmp_ip})(t0)
|
||||
|
||||
// restore regs
|
||||
ld t2, ({tcb_sa_off} + {sa_tmp_t2})(t0)
|
||||
ld t3, ({tcb_sa_off} + {sa_tmp_t3})(t0)
|
||||
ld t4, ({tcb_sa_off} + {sa_tmp_t4})(t0)
|
||||
|
||||
// move saved t0 away from control as well
|
||||
mv t1, t0
|
||||
ld t0, ({tcb_sc_off} + {sc_saved_t0})(t0)
|
||||
|
||||
// Re-enable signals. This code can be interrupted after this signal, so we need to define
|
||||
// 'crit_third'.
|
||||
ld gp, ({tcb_sc_off} + {sc_control})(t1)
|
||||
andi gp, gp, ~1
|
||||
sd gp, ({tcb_sc_off} + {sc_control})(t1)
|
||||
|
||||
.globl __relibc_internal_sigentry_crit_third
|
||||
__relibc_internal_sigentry_crit_third:
|
||||
ld gp, ({tcb_sa_off} + {sa_tmp_ip})(t1)
|
||||
.globl __relibc_internal_sigentry_crit_fourth
|
||||
__relibc_internal_sigentry_crit_fourth:
|
||||
ld t1, ({tcb_sa_off} + {sa_tmp_t1})(t1)
|
||||
.globl __relibc_internal_sigentry_crit_fifth
|
||||
__relibc_internal_sigentry_crit_fifth:
|
||||
jr gp
|
||||
"] <= [
|
||||
tcb_sc_off = const (offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, control)),
|
||||
sc_word = const offset_of!(Sigcontrol, word),
|
||||
sc_saved_t0 = const offset_of!(Sigcontrol, saved_archdep_reg),
|
||||
sc_saved_ip = const offset_of!(Sigcontrol, saved_ip),
|
||||
sc_sender_infos = const offset_of!(Sigcontrol, sender_infos),
|
||||
sc_control = const offset_of!(Sigcontrol, control_flags),
|
||||
|
||||
tcb_sa_off = const (offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, arch)),
|
||||
sa_off_pctl = const offset_of!(SigArea, pctl),
|
||||
sa_tmp_sp = const offset_of!(SigArea, tmp_sp),
|
||||
sa_tmp_t1 = const offset_of!(SigArea, tmp_t1),
|
||||
sa_tmp_t2 = const offset_of!(SigArea, tmp_t2),
|
||||
sa_tmp_t3 = const offset_of!(SigArea, tmp_t3),
|
||||
sa_tmp_t4 = const offset_of!(SigArea, tmp_t4),
|
||||
sa_tmp_a0 = const offset_of!(SigArea, tmp_a0),
|
||||
sa_tmp_a1 = const offset_of!(SigArea, tmp_a1),
|
||||
sa_tmp_a2 = const offset_of!(SigArea, tmp_a2),
|
||||
sa_tmp_a7 = const offset_of!(SigArea, tmp_a7),
|
||||
sa_tmp_ip = const offset_of!(SigArea, tmp_ip),
|
||||
sa_tmp_id_inf = const offset_of!(SigArea, tmp_id_inf),
|
||||
sa_tmp_rt_inf = const offset_of!(SigArea, tmp_rt_inf),
|
||||
sa_altstack_top = const offset_of!(SigArea, altstack_top),
|
||||
sa_altstack_bottom = const offset_of!(SigArea, altstack_bottom),
|
||||
|
||||
pctl_off_actions = const offset_of!(SigProcControl, actions),
|
||||
inner = sym inner_c,
|
||||
pctl_off_pending = const offset_of!(SigProcControl, pending),
|
||||
pctl_off_sender_infos = const offset_of!(SigProcControl, sender_infos),
|
||||
SYS_SIGDEQUEUE = const syscall::SYS_SIGDEQUEUE,
|
||||
]);
|
||||
|
||||
asmfunction!(__relibc_internal_rlct_clone_ret: ["
|
||||
ld t0, 0(sp)
|
||||
ld a0, 8(sp)
|
||||
ld a1, 16(sp)
|
||||
ld a2, 24(sp)
|
||||
ld a3, 32(sp)
|
||||
ld a4, 40(sp)
|
||||
ld a5, 48(sp)
|
||||
addi sp, sp, 56
|
||||
|
||||
jalr t0
|
||||
ret
|
||||
"] <= []);
|
||||
|
||||
pub fn current_sp() -> usize {
|
||||
let sp: usize;
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"mv {}, sp",
|
||||
out(reg) sp,
|
||||
options(nomem));
|
||||
}
|
||||
sp
|
||||
}
|
||||
|
||||
pub unsafe fn manually_enter_trampoline() {
|
||||
let ctl = &Tcb::current().unwrap().os_specific.control;
|
||||
|
||||
ctl.control_flags.store(
|
||||
ctl.control_flags.load(Ordering::Relaxed) | syscall::flag::INHIBIT_DELIVERY.bits(),
|
||||
Ordering::Release,
|
||||
);
|
||||
ctl.saved_archdep_reg.set(0);
|
||||
let ip_location = &ctl.saved_ip as *const _ as usize;
|
||||
|
||||
core::arch::asm!("
|
||||
jal 2f
|
||||
j 3f
|
||||
2:
|
||||
sd ra, 0(t0)
|
||||
la t0, __relibc_internal_sigentry
|
||||
jalr x0, t0
|
||||
3:
|
||||
", inout("t0") ip_location => _, out("ra") _);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn __relibc_internal_sigentry_crit_first();
|
||||
fn __relibc_internal_sigentry_crit_second();
|
||||
fn __relibc_internal_sigentry_crit_third();
|
||||
fn __relibc_internal_sigentry_crit_fourth();
|
||||
fn __relibc_internal_sigentry_crit_fifth();
|
||||
}
|
||||
pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt {
|
||||
// It is impossible to update SP and PC atomically. Instead, we abuse the fact that
|
||||
// signals are disabled in the prologue of the signal trampoline, which allows us to emulate
|
||||
// atomicity inside the critical section, consisting of one instruction at 'crit_first', and
|
||||
// one at 'crit_second', see asm.
|
||||
|
||||
if stack.regs.pc == __relibc_internal_sigentry_crit_first as u64 {
|
||||
// Reexecute 'ld sp, (1 * 8)(sp)'
|
||||
let stack_ptr = stack.regs.int_regs[1] as *const u64; // x2
|
||||
stack.regs.int_regs[1] = stack_ptr.add(1).read();
|
||||
// and 'jr gp' steps.
|
||||
stack.regs.pc = stack.regs.int_regs[2];
|
||||
} else if stack.regs.pc == __relibc_internal_sigentry_crit_second as u64
|
||||
|| stack.regs.pc == __relibc_internal_sigentry_crit_fifth as u64
|
||||
{
|
||||
// just reexecute the jump
|
||||
stack.regs.pc = stack.regs.int_regs[2];
|
||||
} else if stack.regs.pc == __relibc_internal_sigentry_crit_third as u64 {
|
||||
// ld gp, ({tcb_sa_off} + {sa_tmp_ip})(t1)
|
||||
stack.regs.int_regs[2] = area.tmp_ip;
|
||||
// ld t1, ({tcb_sa_off} + {sa_tmp_t1})(t1)
|
||||
stack.regs.int_regs[5] = area.tmp_t1;
|
||||
// j gp
|
||||
stack.regs.pc = stack.regs.int_regs[2];
|
||||
} else if stack.regs.pc == __relibc_internal_sigentry_crit_fourth as u64 {
|
||||
// ld t1, ({tcb_sa_off} + {sa_tmp_t1})(t1)
|
||||
stack.regs.int_regs[5] = area.tmp_t1;
|
||||
// jr gp
|
||||
stack.regs.pc = stack.regs.int_regs[2];
|
||||
}
|
||||
|
||||
get_sigaltstack(area, stack.regs.int_regs[1] as usize).into()
|
||||
}
|
||||
+20
-1
@@ -119,6 +119,20 @@ pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end_and_tcb_start: usize, _tls_len:
|
||||
let _ = syscall::write(*file, &env).expect_notls("failed to write fsbase");
|
||||
}
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox riscv64
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
// tp points to static tls block
|
||||
// FIXME limited to a single initial master
|
||||
let tls_start = tls_end - tls_len;
|
||||
let abi_ptr = tls_start - 8;
|
||||
core::ptr::write(abi_ptr as *mut usize, tls_end);
|
||||
core::arch::asm!(
|
||||
"mv tp, {}",
|
||||
in(reg) tls_start
|
||||
);
|
||||
}
|
||||
|
||||
/// Initialize redox-rt in situations where relibc is not used
|
||||
pub unsafe fn initialize_freestanding() {
|
||||
// TODO: This code is a hack! Integrate the ld_so TCB code into generic-rt, and then use that
|
||||
@@ -145,7 +159,7 @@ pub unsafe fn initialize_freestanding() {
|
||||
page.tls_end = (page as *mut Tcb).cast();
|
||||
*page.os_specific.thr_fd.get_mut() = None;
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
#[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))]
|
||||
unsafe {
|
||||
let tcb_addr = page as *mut Tcb as usize;
|
||||
tcb_activate(&page.os_specific, tcb_addr, 0)
|
||||
@@ -155,6 +169,11 @@ pub unsafe fn initialize_freestanding() {
|
||||
let abi_ptr = core::ptr::addr_of_mut!(page.tcb_ptr);
|
||||
core::arch::asm!("msr tpidr_el0, {}", in(reg) abi_ptr);
|
||||
}
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
unsafe {
|
||||
let abi_ptr = core::ptr::addr_of_mut!(page.tcb_ptr) as usize;
|
||||
core::arch::asm!("mv tp, {}", in(reg) (abi_ptr + 8));
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
pub unsafe fn initialize() {
|
||||
|
||||
@@ -28,7 +28,11 @@ pub fn sighandler_function() -> usize {
|
||||
/// ucontext_t representation
|
||||
#[repr(C)]
|
||||
pub struct SigStack {
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
|
||||
#[cfg(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "riscv64"
|
||||
))]
|
||||
_pad: [usize; 1], // pad from 7*8 to 64
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
@@ -45,6 +49,7 @@ pub struct SigStack {
|
||||
// x86_64: 864 bytes
|
||||
// i686: 512 bytes
|
||||
// aarch64: 272 bytes (SIMD TODO)
|
||||
// riscv64: 520 bytes (vector extensions TODO)
|
||||
pub regs: ArchIntRegs,
|
||||
}
|
||||
#[repr(C)]
|
||||
@@ -558,7 +563,7 @@ pub fn setup_sighandler(tcb: &RtTcb) {
|
||||
arch.altstack_top = usize::MAX;
|
||||
arch.altstack_bottom = 0;
|
||||
// TODO
|
||||
#[cfg(any(target_arch = "x86", target_arch = "aarch64"))]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
{
|
||||
arch.pctl = core::ptr::addr_of!(PROC_CONTROL_STRUCT) as usize;
|
||||
}
|
||||
|
||||
+14
-2
@@ -1,4 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
target=$1
|
||||
deps_dir=$2
|
||||
|
||||
@@ -7,6 +10,15 @@ if [ -z "$target" ] || [ -z "$deps_dir" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$target" ]; then
|
||||
echo "Target file '$target' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "$deps_dir" ] ; then
|
||||
echo "Deps dir '$deps_dir' does not exist or not a directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
symbols_file=`mktemp`
|
||||
special_syms=(
|
||||
__rdl_oom
|
||||
@@ -25,7 +37,7 @@ special_syms=(
|
||||
)
|
||||
|
||||
for dep in `find $deps_dir -type f -name "*.rlib"`; do
|
||||
"${TARGET}-nm" --format=posix -g "$dep" 2>/dev/null | sed 's/.*:.*//g' | awk '{if ($2 == "T") print $1}' | sed 's/^\(.*\)$/\1 __relibc_\1/g' >> $symbols_file
|
||||
"${NM}" --format=posix -g "$dep" 2>/dev/null | sed 's/.*:.*//g' | awk '{if ($2 == "T") print $1}' | sed 's/^\(.*\)$/\1 __relibc_\1/g' >> $symbols_file
|
||||
done
|
||||
|
||||
for special_sym in "${special_syms[@]}"; do
|
||||
@@ -36,6 +48,6 @@ sorted_file=`mktemp`
|
||||
sort -u "$symbols_file" > "$sorted_file"
|
||||
rm -f "$symbols_file"
|
||||
|
||||
"${TARGET}-objcopy" --redefine-syms="$sorted_file" "$target"
|
||||
"${OBJCOPY}" --redefine-syms="$sorted_file" "$target"
|
||||
|
||||
rm -f "$sorted_file"
|
||||
|
||||
@@ -60,6 +60,17 @@ _start:
|
||||
"
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
global_asm!(
|
||||
"
|
||||
.globl _start
|
||||
_start:
|
||||
mv a0, sp
|
||||
la t0, relibc_start
|
||||
jalr ra, t0
|
||||
"
|
||||
);
|
||||
|
||||
#[linkage = "weak"]
|
||||
#[no_mangle]
|
||||
extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
|
||||
|
||||
@@ -72,6 +72,8 @@ global_asm!(
|
||||
"#
|
||||
);
|
||||
|
||||
// risc-v has no _init / _fini functions; it exclusively uses init/fini arrays
|
||||
|
||||
#[linkage = "weak"]
|
||||
#[no_mangle]
|
||||
extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
|
||||
|
||||
@@ -58,6 +58,8 @@ global_asm!(
|
||||
"#
|
||||
);
|
||||
|
||||
// risc-v has no _init / _fini functions; it exclusively uses init/fini arrays
|
||||
|
||||
#[linkage = "weak"]
|
||||
#[no_mangle]
|
||||
extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
sys_includes = []
|
||||
include_guard = "_RISCV64_USER_H"
|
||||
language = "C"
|
||||
style = "Tag"
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
@@ -0,0 +1,39 @@
|
||||
use crate::platform::types::*;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct user_regs_struct {
|
||||
pub regs: [c_ulong; 31], // x1-x31
|
||||
pub pc: c_ulong,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct user_fpregs_f_struct {
|
||||
pub fpregs: [c_float; 32],
|
||||
pub fcsr: c_uint,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct user_fpregs_g_struct {
|
||||
pub fpregs: [c_double; 32],
|
||||
pub fcsr: c_uint,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct user_fpregs_struct {
|
||||
pub f_regs: user_fpregs_f_struct,
|
||||
pub g_regs: user_fpregs_g_struct,
|
||||
}
|
||||
|
||||
pub type elf_greg_t = c_ulong;
|
||||
pub type elf_gregset_t = user_regs_struct;
|
||||
pub type elf_fpregset_t = user_fpregs_struct;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _cbindgen_only_generates_structs_if_they_are_mentioned_which_is_dumb_riscv64_user(
|
||||
a: user_regs_struct,
|
||||
b: user_fpregs_struct,
|
||||
c: elf_gregset_t,
|
||||
d: elf_greg_t,
|
||||
e: elf_fpregset_t,
|
||||
) {
|
||||
}
|
||||
+32
-12
@@ -16,18 +16,38 @@ pub unsafe extern "C" fn __tls_get_addr(ti: *mut dl_tls_index) -> *mut c_void {
|
||||
(*ti).ti_module,
|
||||
(*ti).ti_offset
|
||||
);
|
||||
if let Some(tcb) = Tcb::current() {
|
||||
if let Some(masters) = tcb.masters() {
|
||||
if let Some(master) = masters.get((*ti).ti_module as usize) {
|
||||
let addr = tcb.tls_end.sub(master.offset).add((*ti).ti_offset as usize);
|
||||
trace!(
|
||||
"__tls_get_addr({:p}: {:#x}, {:#x}) = {:p}",
|
||||
ti,
|
||||
(*ti).ti_module,
|
||||
(*ti).ti_offset,
|
||||
addr
|
||||
);
|
||||
return addr as *mut c_void;
|
||||
let mod_id = (*ti).ti_module as usize;
|
||||
let offset = if cfg!(target_arch = "riscv64") {
|
||||
((*ti).ti_offset as usize).wrapping_add(0x800) // dynamic offsets are 0x800-based on risc-v
|
||||
} else {
|
||||
(*ti).ti_offset as usize
|
||||
};
|
||||
if mod_id > 0 {
|
||||
if let Some(tcb) = Tcb::current() {
|
||||
if let Some(masters) = tcb.masters() {
|
||||
if let Some(master) = masters.get(mod_id - 1) {
|
||||
// module id is 1-based
|
||||
let addr = if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
|
||||
tcb.tls_end.sub(master.offset).add(offset)
|
||||
} else {
|
||||
// FIXME aarch64/risc-v only support static master
|
||||
if mod_id == 1 && offset < tcb.tls_len {
|
||||
tcb.tls_end.sub(tcb.tls_len).add(offset)
|
||||
} else {
|
||||
0 as *mut u8
|
||||
}
|
||||
};
|
||||
if !addr.is_null() {
|
||||
trace!(
|
||||
"__tls_get_addr({:p}: {:#x}, {:#x}) = {:p}",
|
||||
ti,
|
||||
(*ti).ti_module,
|
||||
(*ti).ti_offset,
|
||||
addr
|
||||
);
|
||||
return addr as *mut c_void;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ pub mod sys_time;
|
||||
pub mod sys_timeb;
|
||||
//pub mod sys_times;
|
||||
pub mod arch_aarch64_user;
|
||||
pub mod arch_riscv64_user;
|
||||
pub mod arch_x64_user;
|
||||
#[cfg(not(target_arch = "x86"))] // TODO: x86
|
||||
pub mod sys_procfs;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
.attribute arch, "rv64gc" # see rust issue #80608
|
||||
.global __longjmp
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type __longjmp, %function
|
||||
.type _longjmp, %function
|
||||
.type longjmp, %function
|
||||
__longjmp:
|
||||
_longjmp:
|
||||
longjmp:
|
||||
ld s0, 0(a0)
|
||||
ld s1, 8(a0)
|
||||
ld s2, 16(a0)
|
||||
ld s3, 24(a0)
|
||||
ld s4, 32(a0)
|
||||
ld s5, 40(a0)
|
||||
ld s6, 48(a0)
|
||||
ld s7, 56(a0)
|
||||
ld s8, 64(a0)
|
||||
ld s9, 72(a0)
|
||||
ld s10, 80(a0)
|
||||
ld s11, 88(a0)
|
||||
ld sp, 96(a0)
|
||||
ld ra, 104(a0)
|
||||
|
||||
fld fs0, 112(a0)
|
||||
fld fs1, 120(a0)
|
||||
fld fs2, 128(a0)
|
||||
fld fs3, 136(a0)
|
||||
fld fs4, 144(a0)
|
||||
fld fs5, 152(a0)
|
||||
fld fs6, 160(a0)
|
||||
fld fs7, 168(a0)
|
||||
fld fs8, 176(a0)
|
||||
fld fs9, 184(a0)
|
||||
fld fs10, 192(a0)
|
||||
fld fs11, 200(a0)
|
||||
|
||||
seqz a0, a1
|
||||
add a0, a0, a1
|
||||
ret
|
||||
@@ -0,0 +1,40 @@
|
||||
.attribute arch, "rv64gc" # see rust issue #80608
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp, %function
|
||||
.type _setjmp, %function
|
||||
.type setjmp, %function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
sd s0, 0(a0)
|
||||
sd s1, 8(a0)
|
||||
sd s2, 16(a0)
|
||||
sd s3, 24(a0)
|
||||
sd s4, 32(a0)
|
||||
sd s5, 40(a0)
|
||||
sd s6, 48(a0)
|
||||
sd s7, 56(a0)
|
||||
sd s8, 64(a0)
|
||||
sd s9, 72(a0)
|
||||
sd s10, 80(a0)
|
||||
sd s11, 88(a0)
|
||||
sd sp, 96(a0)
|
||||
sd ra, 104(a0)
|
||||
|
||||
fsd fs0, 112(a0)
|
||||
fsd fs1, 120(a0)
|
||||
fsd fs2, 128(a0)
|
||||
fsd fs3, 136(a0)
|
||||
fsd fs4, 144(a0)
|
||||
fsd fs5, 152(a0)
|
||||
fsd fs6, 160(a0)
|
||||
fsd fs7, 168(a0)
|
||||
fsd fs8, 176(a0)
|
||||
fsd fs9, 184(a0)
|
||||
fsd fs10, 192(a0)
|
||||
fsd fs11, 200(a0)
|
||||
|
||||
li a0, 0
|
||||
ret
|
||||
@@ -17,4 +17,5 @@ platform_specific! {
|
||||
"aarch64","aarch64", "s";
|
||||
"x86","i386","s";
|
||||
"x86_64","x86_64","s";
|
||||
"riscv64", "riscv64", "S";
|
||||
}
|
||||
|
||||
@@ -24,6 +24,16 @@ global_asm!(
|
||||
"
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
global_asm!(
|
||||
"
|
||||
.global __restore_rt
|
||||
__restore_rt:
|
||||
li a7, 139
|
||||
ecall
|
||||
"
|
||||
);
|
||||
|
||||
pub const SIGHUP: usize = 1;
|
||||
pub const SIGINT: usize = 2;
|
||||
pub const SIGQUIT: usize = 3;
|
||||
|
||||
@@ -77,7 +77,11 @@ pub(crate) type mcontext_t = mcontext;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ucontext {
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
|
||||
#[cfg(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "riscv64"
|
||||
))]
|
||||
_pad: [usize; 1], // pad from 7*8 to 64
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
@@ -100,6 +104,8 @@ pub struct mcontext {
|
||||
_opaque: [u8; 864],
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
_opaque: [u8; 272],
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
_opaque: [u8; 520],
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __completely_unused_cbindgen_workaround_fn_ucontext_mcontext(
|
||||
|
||||
@@ -313,7 +313,10 @@ pub unsafe extern "C" fn exit(status: c_int) {
|
||||
(*f)();
|
||||
}
|
||||
|
||||
_fini();
|
||||
#[cfg(not(target_arch = "riscv64"))] // risc-v uses arrays exclusively
|
||||
{
|
||||
_fini();
|
||||
}
|
||||
|
||||
ld_so::fini();
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::header::arch_aarch64_user::*;
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
use crate::header::arch_riscv64_user::*;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::header::arch_x64_user::*;
|
||||
use crate::platform::types::*;
|
||||
|
||||
+2
-2
@@ -62,7 +62,7 @@ impl Linker {
|
||||
Self {
|
||||
ld_library_path: ld_library_path,
|
||||
next_object_id: root_id,
|
||||
next_tls_module_id: 0,
|
||||
next_tls_module_id: 1,
|
||||
tls_size: 0,
|
||||
objects: BTreeMap::new(),
|
||||
name_to_object_id_map: BTreeMap::new(),
|
||||
@@ -227,7 +227,7 @@ impl Linker {
|
||||
self.next_object_id += 1;
|
||||
|
||||
if let Some(master) = tcb_master {
|
||||
if self.next_tls_module_id == 0 {
|
||||
if self.next_tls_module_id == 1 {
|
||||
// Hack to allocate TCB on the first TLS module
|
||||
unsafe {
|
||||
if Tcb::current().is_none() {
|
||||
|
||||
@@ -153,6 +153,13 @@ pub unsafe fn init(sp: &'static Stack) {
|
||||
|
||||
tp = env.fsbase as usize;
|
||||
}
|
||||
#[cfg(all(target_os = "redox", target_arch = "riscv64"))]
|
||||
{
|
||||
core::arch::asm!(
|
||||
"mv {}, tp",
|
||||
out(reg) tp,
|
||||
);
|
||||
}
|
||||
|
||||
if tp == 0 {
|
||||
static_init(sp);
|
||||
|
||||
@@ -256,6 +256,17 @@ unsafe fn inner_ptrace(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
fn inner_ptrace(
|
||||
request: c_int,
|
||||
pid: pid_t,
|
||||
addr: *mut c_void,
|
||||
data: *mut c_void,
|
||||
) -> io::Result<c_int> {
|
||||
//TODO: riscv64
|
||||
unimplemented!("inner_ptrace not implemented on riscv64");
|
||||
}
|
||||
|
||||
impl PalPtrace for Sys {
|
||||
unsafe fn ptrace(
|
||||
request: c_int,
|
||||
|
||||
+4
-1
@@ -201,7 +201,10 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
|
||||
}
|
||||
|
||||
// Call init section
|
||||
_init();
|
||||
#[cfg(not(target_arch = "riscv64"))] // risc-v uses arrays exclusively
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
// Run init array
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user