diff --git a/Cargo.lock b/Cargo.lock index e470fd012445fa1727e479fe82c0f816474d872d..7a972425e5cd1a7575f927189116c34070d88d25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0" +checksum = "534cfe58d6a18cc17120fbf4635d53d14691c1fe4d951064df9bd326178d7d5a" dependencies = [ "bitflags", ] @@ -327,7 +327,7 @@ dependencies = [ "posix-regex", "ralloc", "rand", - "redox_syscall 0.2.12", + "redox_syscall 0.2.15", "sc", "spin 0.9.2", ] @@ -502,7 +502,7 @@ dependencies = [ "cfg-if", "fastrand", "libc", - "redox_syscall 0.2.12", + "redox_syscall 0.2.15", "remove_dir_all", "winapi", ] diff --git a/Cargo.toml b/Cargo.toml index cd281f8828e967ac693727cb043bdddc26c6a253..ba2c6ca44d5e69fde1e1e8243e8de18408e82347 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ optional = true sc = "0.2.3" [target.'cfg(target_os = "redox")'.dependencies] -redox_syscall = "0.2.12" +redox_syscall = "0.2.15" spin = "0.9.0" [features] diff --git a/Makefile b/Makefile index 828e9d31fab2dc8717f8b50c985911132628550a..0358a308917cacdc850a36717a98e8d7d1b4443a 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,13 @@ ifeq ($(TARGET),x86_64-unknown-linux-gnu) export OBJCOPY=x86_64-linux-gnu-objcopy 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 OBJCOPY=i686-unknown-redox-objcopy +endif + ifeq ($(TARGET),x86_64-unknown-redox) export CC=x86_64-unknown-redox-gcc export LD=x86_64-unknown-redox-ld diff --git a/src/header/mod.rs b/src/header/mod.rs index 69621f4b035c71136fc6ef273c8be2ecd96e9909..016a71d2cc35dc3196a02e199f97b1c41c603e29 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -49,6 +49,7 @@ pub mod sys_timeb; //pub mod sys_times; pub mod arch_aarch64_user; pub mod arch_x64_user; +#[cfg(not(target_arch = "x86"))] // TODO: x86 pub mod sys_procfs; pub mod sys_random; pub mod sys_types; diff --git a/src/ld_so/dso.rs b/src/ld_so/dso.rs index cd78de8eea83255775ef2688b2e982e6871815dd..f09d5df90016f0a662a3e461827a316e8b8c2d34 100644 --- a/src/ld_so/dso.rs +++ b/src/ld_so/dso.rs @@ -17,15 +17,25 @@ use core::{ ptr, slice, }; use goblin::{ - elf::{ - header::ET_DYN, - program_header, - r#dyn::{Dyn, DT_DEBUG, DT_RUNPATH}, - section_header::{SHN_UNDEF, SHT_FINI_ARRAY, SHT_INIT_ARRAY}, - sym, Elf, - }, + elf::Elf, error::{Error, Result}, }; +#[cfg(target_pointer_width = "32")] +use goblin::elf32::{ + header::ET_DYN, + program_header, + r#dyn::{Dyn, DT_DEBUG, DT_RUNPATH}, + section_header::{SHN_UNDEF, SHT_FINI_ARRAY, SHT_INIT_ARRAY}, + sym, +}; +#[cfg(target_pointer_width = "64")] +use goblin::elf64::{ + header::ET_DYN, + program_header, + r#dyn::{Dyn, DT_DEBUG, DT_RUNPATH}, + section_header::{SHN_UNDEF, SHT_FINI_ARRAY, SHT_INIT_ARRAY}, + sym, +}; /// Use to represent a library as well as all the symbols that is loaded withen it. #[derive(Default)] diff --git a/src/ld_so/ld_script/aarch64-unknown-redox.ld b/src/ld_so/ld_script/aarch64-unknown-redox.ld index 52e92cfe64775bab4745507b9589bb6feb16bc03..1d08c36eb6832407ebdec66ba2a358cdeae870c9 100644 --- a/src/ld_so/ld_script/aarch64-unknown-redox.ld +++ b/src/ld_so/ld_script/aarch64-unknown-redox.ld @@ -7,7 +7,7 @@ OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") OUTPUT_ARCH(aarch64) ENTRY(_start) -SEARCH_DIR("/x86_64-unknown-redox/lib"); +SEARCH_DIR("/aarch64-unknown-redox/lib"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); diff --git a/src/ld_so/ld_script/i686-unknown-redox.ld b/src/ld_so/ld_script/i686-unknown-redox.ld new file mode 100644 index 0000000000000000000000000000000000000000..f9badfd1d93599a8f17ca5c4c7630da848c1e526 --- /dev/null +++ b/src/ld_so/ld_script/i686-unknown-redox.ld @@ -0,0 +1,245 @@ +/* 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("elf32-i386", "elf32-i386", + "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SEARCH_DIR("/i686-unknown-redox/lib"); +SEARCH_DIR("/usr/local/lib32"); +SEARCH_DIR("/lib32"); +SEARCH_DIR("/usr/lib32"); +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)); + .init : + { + KEEP (*(SORT_NONE(.init))) + } + .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) + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + 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_*) } +} diff --git a/src/ld_so/tcb.rs b/src/ld_so/tcb.rs index 3714a811f54e801a84961236fa6a3941c2bd5f95..01327e8ef2acd338d0467058b7742b61f307b71a 100644 --- a/src/ld_so/tcb.rs +++ b/src/ld_so/tcb.rs @@ -213,7 +213,7 @@ impl Tcb { /// Architecture specific code to read a usize from the TCB - x86_64 #[inline(always)] - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] unsafe fn arch_read(offset: usize) -> usize { let value; asm!( @@ -239,6 +239,25 @@ impl Tcb { //TODO: aarch64 } + /// OS and architecture specific code to activate TLS - Redox x86 + #[cfg(all(target_os = "redox", target_arch = "x86"))] + unsafe fn os_arch_activate(tp: usize) { + let mut env = syscall::EnvRegisters::default(); + + let file = syscall::open("thisproc:current/regs/env", syscall::O_CLOEXEC | syscall::O_RDWR) + .expect_notls("failed to open handle for process registers"); + + let _ = syscall::read(file, &mut env) + .expect_notls("failed to read fsbase"); + + env.fsbase = tp as u32; + + let _ = syscall::write(file, &env) + .expect_notls("failed to write fsbase"); + + let _ = syscall::close(file); + } + /// OS and architecture specific code to activate TLS - Redox x86_64 #[cfg(all(target_os = "redox", target_arch = "x86_64"))] unsafe fn os_arch_activate(tp: usize) { diff --git a/src/platform/redox/extra.rs b/src/platform/redox/extra.rs index 9953ec2c0eb19b699a2cf8a1d5add434c096ba85..4793096bdef7441d25695edfe3d2d8084e3a8c62 100644 --- a/src/platform/redox/extra.rs +++ b/src/platform/redox/extra.rs @@ -53,6 +53,7 @@ extern "C" { pub fn pte_clone_inner(stack: usize) -> usize; } +#[cfg(target_arch = "x86_64")] global_asm!(" .globl pte_clone_inner .type pte_clone_inner, @function diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index c1f36feea0629a284ae3fb6ef11738101c28e487..9597d15ba20214505cfc69d251466dbf55c3dadc 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -850,6 +850,12 @@ impl Pal for Sys { unimplemented!("pte_clone not implemented on aarch64"); } + #[cfg(target_arch = "x86")] + unsafe fn pte_clone(stack: *mut usize) -> pid_t { + //TODO: x86 + unimplemented!("pte_clone not implemented on x86"); + } + #[cfg(target_arch = "x86_64")] unsafe fn pte_clone(stack: *mut usize) -> pid_t { e(syscall::Error::demux(extra::pte_clone_inner(stack as usize))) as pid_t diff --git a/src/platform/redox/ptrace.rs b/src/platform/redox/ptrace.rs index 9022675144118124d4a2024cc0ed9db585373a2a..e1020845cf379c5a646988ec3751cd57f5c21e16 100644 --- a/src/platform/redox/ptrace.rs +++ b/src/platform/redox/ptrace.rs @@ -110,6 +110,17 @@ fn inner_ptrace( unimplemented!("inner_ptrace not implemented on aarch64"); } +#[cfg(target_arch = "x86")] +fn inner_ptrace( + request: c_int, + pid: pid_t, + addr: *mut c_void, + data: *mut c_void, +) -> io::Result<c_int> { + //TODO: x86 + unimplemented!("inner_ptrace not implemented on x86"); +} + #[cfg(target_arch = "x86_64")] fn inner_ptrace( request: c_int,