diff --git a/Cargo.lock b/Cargo.lock index 77497754ed..1f02be85ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,7 +318,7 @@ dependencies = [ [[package]] name = "object" version = "0.36.7" -source = "git+https://gitlab.redox-os.org/andypython/object#7270e3f0d06e5ef4c2b80abc6166d31f4ddf4fea" +source = "git+https://gitlab.redox-os.org/andypython/object?branch=new#da781336d847df0deb897ed1162785f6c2057c56" dependencies = [ "memchr", ] @@ -610,9 +610,9 @@ checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] @@ -625,9 +625,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index d5df814424..da93af5fbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,6 +117,7 @@ features = ["c_api"] [dependencies.object] version = "0.36.7" git = "https://gitlab.redox-os.org/andypython/object" +branch = "new" default-features = false features = ["elf", "read_core"] diff --git a/Makefile b/Makefile index c7c2967a5b..4534cf829f 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ BUILTINS_VERSION=0.1.70 all: | headers libs -headers: $(HEADERS_DEPS) +headers: $(BUILD)/$(PROFILE)/librelibc.a $(HEADERS_DEPS) rm -rf $(TARGET_HEADERS) mkdir -p $(TARGET_HEADERS) cp -r include/* $(TARGET_HEADERS) @@ -51,13 +51,13 @@ endif @set -e ; \ for header in $(HEADERS_UNPARSED); do \ if test -f "src/header/$$header/cbindgen.toml"; then \ - echo -e "\033[0;36;49mWriting Header $$header\033[0m"; \ + printf "\033[0;36;49mWriting Header $$header\033[0m\n"; \ out=`echo "$$header" | sed 's/_/\//g'`; \ out="$(TARGET_HEADERS)/$$out.h"; \ cat "src/header/$$header/cbindgen.toml" cbindgen.globdefs.toml \ | cbindgen "src/header/$$header/mod.rs" --config=/dev/stdin --output "$$out"; \ fi \ - done; echo -e "\033[0;36;49mAll headers written\033[0m"; + done; printf "\033[0;36;49mAll headers written\033[0m\n"; clean: $(CARGO) clean @@ -79,20 +79,19 @@ libs: \ $(BUILD)/$(PROFILE)/libc.so \ $(BUILD)/$(PROFILE)/crt0.o \ $(BUILD)/$(PROFILE)/crti.o \ - $(BUILD)/$(PROFILE)/crtn.o \ - $(BUILD)/$(PROFILE)/ld.so + $(BUILD)/$(PROFILE)/crtn.o install-libs: headers libs mkdir -pv "$(DESTDIR)/lib" cp -v "$(BUILD)/$(PROFILE)/libc.a" "$(DESTDIR)/lib" cp -v "$(BUILD)/$(PROFILE)/libc.so" "$(DESTDIR)/lib" ln -vnfs libc.so "$(DESTDIR)/lib/libc.so.6" + ln -vnfs libc.so "$(DESTDIR)/lib/$(LD_SONAME)" cp -v "$(BUILD)/$(PROFILE)/crt0.o" "$(DESTDIR)/lib" ln -vnfs crt0.o "$(DESTDIR)/lib/crt1.o" ln -vnfs crt0.o "$(DESTDIR)/lib/Scrt1.o" cp -v "$(BUILD)/$(PROFILE)/crti.o" "$(DESTDIR)/lib" cp -v "$(BUILD)/$(PROFILE)/crtn.o" "$(DESTDIR)/lib" - cp -v "$(BUILD)/$(PROFILE)/ld.so" "$(DESTDIR)/$(LD_SO_PATH)" ifeq ($(USE_RUST_LIBM),) cp -v "$(BUILD)/openlibm/libopenlibm.a" "$(DESTDIR)/lib/libm.a" else @@ -135,10 +134,16 @@ test-once: sysroot/$(TARGET) $(MAKE) -C tests run-once TESTBIN=$(TESTBIN) -$(BUILD)/$(PROFILE)/libc.so: $(BUILD)/$(PROFILE)/libc.a +$(BUILD)/$(PROFILE)/libc.so: $(BUILD)/$(PROFILE)/ld_so.o $(BUILD)/$(PROFILE)/libc.a + # Specifying a dynamic list makes all non-local `STV_DEFAULT` + # definitions non-preemptible, except for the symbols listed in + # `dynlst.txt`. So, the symbols defined in `dynlst.txt` may be + # interposed by other definitions at runtime (either from the + # executable or some shared library). $(CC) -nostdlib \ -shared \ -Wl,--gc-sections \ + -Wl,--dynamic-list=dynlst.txt \ -Wl,-z,pack-relative-relocs \ -Wl,--sort-common \ -Wl,--whole-archive $^ -Wl,--no-whole-archive \ @@ -146,10 +151,6 @@ $(BUILD)/$(PROFILE)/libc.so: $(BUILD)/$(PROFILE)/libc.a $(LINKFLAGS) \ -o $@ -$(BUILD)/$(PROFILE)/ld.so: $(BUILD)/$(PROFILE)/ld_so.o $(BUILD)/$(PROFILE)/libc.a - # TODO: merge ld.so with libc.so: --dynamic-list=dynamic-list-file - $(LD) --shared -Bsymbolic --no-relax -T ld_so/ld_script/$(TARGET).ld --gc-sections $^ -o $@ - $(BUILD)/$(PROFILE)/libc.a: $(BUILD)/$(PROFILE)/librelibc.a $(BUILD)/openlibm/libopenlibm.a echo "create $@" > "$@.mri" for lib in $^; do\ @@ -219,9 +220,9 @@ $(BUILD)/openlibm: openlibm touch $@ ifeq ($(USE_RUST_LIBM),) -$(BUILD)/openlibm/libopenlibm.a: $(BUILD)/openlibm $(BUILD)/$(PROFILE)/librelibc.a +$(BUILD)/openlibm/libopenlibm.a: $(BUILD)/openlibm headers $(BUILD)/$(PROFILE)/librelibc.a $(MAKE) -s AR=$(AR) CC="$(CC_WRAPPER) $(CC)" LD=$(LD) CPPFLAGS="$(CPPFLAGS) -fno-stack-protector -I$(shell pwd)/include -I$(TARGET_HEADERS)" -C $< libopenlibm.a - ./renamesyms.sh "$@" "$(BUILD)/release/deps/" + ./renamesyms.sh "$@" "$(BUILD)/$(PROFILE)/deps/" else $(BUILD)/openlibm/libopenlibm.a: mkdir -p "$(BUILD)/openlibm" diff --git a/config.mk b/config.mk index f3b4b025bc..2a36dc7226 100644 --- a/config.mk +++ b/config.mk @@ -9,7 +9,7 @@ ifeq ($(TARGET),aarch64-unknown-linux-gnu) export NM=aarch64-linux-gnu-nm export OBJCOPY=aarch64-linux-gnu-objcopy export CPPFLAGS= - LD_SO_PATH=lib/ld.so.1 + LD_SONAME=ld.so.1 endif ifeq ($(TARGET),aarch64-unknown-linux-relibc) @@ -19,7 +19,7 @@ ifeq ($(TARGET),aarch64-unknown-linux-relibc) export NM=aarch64-linux-relibc-nm export OBJCOPY=aarch64-linux-relibc-objcopy export CPPFLAGS= - LD_SO_PATH=lib/ld.so.1 + LD_SONAME=ld.so.1 endif @@ -30,7 +30,7 @@ ifeq ($(TARGET),aarch64-unknown-redox) export NM=aarch64-unknown-redox-nm export OBJCOPY=aarch64-unknown-redox-objcopy export CPPFLAGS= - LD_SO_PATH=lib/ld.so.1 + LD_SONAME=ld.so.1 endif ifeq ($(TARGET),i586-unknown-redox) @@ -40,7 +40,7 @@ ifeq ($(TARGET),i586-unknown-redox) export NM=i586-unknown-redox-nm export OBJCOPY=i586-unknown-redox-objcopy export CPPFLAGS= - LD_SO_PATH=lib/libc.so.1 + LD_SONAME=ld.so.1 endif ifeq ($(TARGET),i686-unknown-redox) @@ -50,7 +50,7 @@ ifeq ($(TARGET),i686-unknown-redox) export NM=i686-unknown-redox-nm export OBJCOPY=i686-unknown-redox-objcopy export CPPFLAGS= - LD_SO_PATH=lib/libc.so.1 + LD_SONAME=ld.so.1 endif ifeq ($(TARGET),x86_64-unknown-linux-gnu) @@ -60,7 +60,7 @@ ifeq ($(TARGET),x86_64-unknown-linux-gnu) export NM=x86_64-linux-gnu-nm export OBJCOPY=objcopy export CPPFLAGS= - LD_SO_PATH=lib/ld64.so.1 + LD_SONAME=ld64.so.1 endif ifeq ($(TARGET),x86_64-unknown-linux-relibc) @@ -70,7 +70,7 @@ ifeq ($(TARGET),x86_64-unknown-linux-relibc) export NM=x86_64-linux-relibc-nm export OBJCOPY=x86_64-linux-relibc-objcopy export CPPFLAGS= - LD_SO_PATH=lib/ld64.so.1 + LD_SONAME=ld64.so.1 endif ifeq ($(TARGET),x86_64-unknown-redox) @@ -80,7 +80,7 @@ ifeq ($(TARGET),x86_64-unknown-redox) export NM=x86_64-unknown-redox-nm export OBJCOPY=x86_64-unknown-redox-objcopy export CPPFLAGS= - LD_SO_PATH=lib/ld64.so.1 + LD_SONAME=ld64.so.1 endif ifeq ($(TARGET),riscv64gc-unknown-redox) @@ -90,5 +90,5 @@ ifeq ($(TARGET),riscv64gc-unknown-redox) export NM=riscv64-unknown-redox-nm export OBJCOPY=riscv64-unknown-redox-objcopy export CPPFLAGS=-march=rv64gc -mabi=lp64d - LD_SO_PATH=lib/ld.so.1 + LD_SONAME=ld.so.1 endif diff --git a/dynlst.txt b/dynlst.txt new file mode 100644 index 0000000000..d199c919fe --- /dev/null +++ b/dynlst.txt @@ -0,0 +1,27 @@ +{ +environ; + +stdin; +stdout; +stderr; + +timezone; +daylight; +tzname; +__timezone; +__daylight; +__tzname; + +signgam; +__signgam; + +optarg; +optind; +opterr; +optreset; +__optreset; + +getdate_err; + +__stack_chk_guard; +}; diff --git a/generic-rt/src/lib.rs b/generic-rt/src/lib.rs index 064444afee..9634ca83d0 100644 --- a/generic-rt/src/lib.rs +++ b/generic-rt/src/lib.rs @@ -1,6 +1,5 @@ #![no_std] #![allow(internal_features)] -#![feature(core_intrinsics)] #![deny(unsafe_op_in_unsafe_fn)] use core::{ diff --git a/ld_so/ld_script/aarch64-unknown-linux-gnu.ld b/ld_so/ld_script/aarch64-unknown-linux-gnu.ld deleted file mode 100644 index a344feef5d..0000000000 --- a/ld_so/ld_script/aarch64-unknown-linux-gnu.ld +++ /dev/null @@ -1,263 +0,0 @@ -/* Script for -z combreloc */ -/* Copyright (C) 2014-2025 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-littleaarch64", "elf64-bigaarch64", "elf64-littleaarch64") -OUTPUT_ARCH(aarch64) -ENTRY(_start) -SEARCH_DIR("=/usr/aarch64-linux-gnu/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/aarch64-linux-gnu/lib"); 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", 0x400000) + SIZEOF_HEADERS; - /* Place the build-id as close to the ELF headers as possible. This - maximises the chance the build-id will be present in core files, - which GDB can then use to locate the associated debuginfo file. */ - .note.gnu.build-id : { *(.note.gnu.build-id) } - .interp : { *(.interp) } - .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.ifunc) - } - .rela.plt : - { - *(.rela.plt) - PROVIDE_HIDDEN (__rela_iplt_start = .); - *(.rela.iplt) - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .relr.dyn : { *(.relr.dyn) } - /* Start of the executable code region. */ - .init : - { - KEEP (*(SORT_NONE(.init))) - } =0x1f2003d5 - .plt : ALIGN(16) { *(.plt) *(.iplt) } - .text : - { - *(.text.unlikely .text.*_unlikely .text.unlikely.*) - *(.text.exit .text.exit.*) - *(.text.startup .text.startup.*) - *(.text.hot .text.hot.*) - *(SORT(.text.sorted.*)) - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf.em. */ - *(.gnu.warning) - } =0x1f2003d5 - .fini : - { - KEEP (*(SORT_NONE(.fini))) - } =0x1f2003d5 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - /* Start of the Read Only Data region. */ - .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.*) } - .sframe : ONLY_IF_RO { *(.sframe) *(.sframe.*) } - .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*) } - /* Various note sections. Placed here so that they are always included - in the read-only segment and not treated as orphan sections. The - current orphan handling algorithm does place note sections after R/O - data, but this is not guaranteed to always be the case. */ - .note.build-id : { *(.note.build-id) } - .note.GNU-stack : { *(.note.GNU-stack) } - .note.gnu-property : { *(.note.gnu-property) } - .note.ABI-tag : { *(.note.ABI-tag) } - .note.package : { *(.note.package) } - .note.dlopen : { *(.note.dlopen) } - .note.netbsd.ident : { *(.note.netbsd.ident) } - .note.openbsd.ident : { *(.note.openbsd.ident) } - /* Start of the Read Write Data region. */ - /* 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.*) } - .sframe : ONLY_IF_RW { *(.sframe) *(.sframe.*) } - .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 (24, .); - .got.plt : { *(.got.plt) *(.igot.plt) } - .data : - { - PROVIDE (__data_start = .); - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - _edata = .; - PROVIDE (edata = .); - . = ALIGN(ALIGNOF(NEXT_SECTION)); - __bss_start = .; - __bss_start__ = .; - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that in the common case of there only being one - type of .bss section, the 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); - } - _bss_end__ = .; __bss_end__ = .; - . = ALIGN(64 / 8); - /* Start of the Large Data region. */ - . = SEGMENT_START("ldata-segment", .); - . = ALIGN(64 / 8); - __end__ = .; - _end = .; - PROVIDE (end = .); - . = DATA_SEGMENT_END (.); - /* Start of the Tiny Data region. */ - /* 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 (INFO) : { *(.comment); LINKER_VERSION; } - .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 5. */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - .debug_sup 0 : { *(.debug_sup) } - .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } - .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } - /DISCARD/ : { - *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) - /* - * XXX: As of now, ld.so links with relibc which has the main functionality. In the next refactor, - * ld.so will be moved out of relibc. So, till that time, we have to discard any sections - * that may reference use thread local storage. - * - * .init_array also depends on TLS and is discarded as we don't need it. - */ - *(.gnu.linkonce.tb.*) *(.tcommon) - *(.init_array) - } -} diff --git a/ld_so/ld_script/aarch64-unknown-linux-relibc.ld b/ld_so/ld_script/aarch64-unknown-linux-relibc.ld deleted file mode 120000 index 024e3d58fe..0000000000 --- a/ld_so/ld_script/aarch64-unknown-linux-relibc.ld +++ /dev/null @@ -1 +0,0 @@ -./aarch64-unknown-linux-gnu.ld \ No newline at end of file diff --git a/ld_so/ld_script/aarch64-unknown-redox.ld b/ld_so/ld_script/aarch64-unknown-redox.ld deleted file mode 100644 index 64ead42b5e..0000000000 --- a/ld_so/ld_script/aarch64-unknown-redox.ld +++ /dev/null @@ -1,255 +0,0 @@ -/* 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-littleaarch64", "elf64-littleaarch64", - "elf64-littleaarch64") -OUTPUT_ARCH(aarch64) -ENTRY(_start) -SEARCH_DIR("/aarch64-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)); - .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_*) - /* - * XXX: As of now, ld.so links with relibc which has the main functionality. In the next refactor, - * ld.so will be moved out of relibc. So, till that time, we have to discard any sections - * that may reference use thread local storage. - * - * .init_array need to be not discarded unlike x86_64 linker variant - */ - *(.gnu.linkonce.tb.*) *(.tcommon) - } -} diff --git a/ld_so/ld_script/i586-unknown-redox.ld b/ld_so/ld_script/i586-unknown-redox.ld deleted file mode 100644 index 86b9e46c4c..0000000000 --- a/ld_so/ld_script/i586-unknown-redox.ld +++ /dev/null @@ -1,256 +0,0 @@ -/* 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_*) - /* - * XXX: As of now, ld.so links with relibc which has the main functionality. In the next refactor, - * ld.so will be moved out of relibc. So, till that time, we have to discard any sections - * that may reference use thread local storage. - * - * .init_array also depends on TLS and is discarded as we don't need it. - */ - *(.gnu.linkonce.tb.*) *(.tcommon) - *(.init_array) - } -} diff --git a/ld_so/ld_script/i686-unknown-redox.ld b/ld_so/ld_script/i686-unknown-redox.ld deleted file mode 100644 index 7e68c6c8bb..0000000000 --- a/ld_so/ld_script/i686-unknown-redox.ld +++ /dev/null @@ -1,256 +0,0 @@ -/* 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_*) - /* - * XXX: As of now, ld.so links with relibc which has the main functionality. In the next refactor, - * ld.so will be moved out of relibc. So, till that time, we have to discard any sections - * that may reference use thread local storage. - * - * .init_array also depends on TLS and is discarded as we don't need it. - */ - *(.gnu.linkonce.tb.*) *(.tcommon) - *(.init_array) - } -} diff --git a/ld_so/ld_script/riscv64gc-unknown-redox.ld b/ld_so/ld_script/riscv64gc-unknown-redox.ld deleted file mode 100644 index fc657797ea..0000000000 --- a/ld_so/ld_script/riscv64gc-unknown-redox.ld +++ /dev/null @@ -1,247 +0,0 @@ -/* 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_*) - /* - * XXX: As of now, ld.so links with relibc which has the main functionality. In the next refactor, - * ld.so will be moved out of relibc. So, till that time, we have to discard any sections - * that may reference use thread local storage. - * - * .init_array also depends on TLS and is discarded as we don't need it. - */ - *(.gnu.linkonce.tb.*) *(.tcommon) - *(.init_array) - } -} diff --git a/ld_so/ld_script/x86_64-unknown-linux-gnu.ld b/ld_so/ld_script/x86_64-unknown-linux-gnu.ld deleted file mode 100644 index be84e120e1..0000000000 --- a/ld_so/ld_script/x86_64-unknown-linux-gnu.ld +++ /dev/null @@ -1,259 +0,0 @@ -/* 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-x86-64", "elf64-x86-64", - "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64"); -SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.33.164"); -SEARCH_DIR("/usr/local/lib64"); -SEARCH_DIR("/lib64"); -SEARCH_DIR("/usr/lib64"); -SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib"); -SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.33.1"); -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 : ALIGN(4K) - { - 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_*) - /* - * XXX: As of now, ld.so links with relibc which has the main functionality. In the next refactor, - * ld.so will be moved out of relibc. So, till that time, we have to discard any sections - * that may reference use thread local storage. - * - * .init_array also depends on TLS and is discarded as we don't need it. - */ - *(.gnu.linkonce.tb.*) *(.tcommon) - *(.init_array) - } -} diff --git a/ld_so/ld_script/x86_64-unknown-linux-relibc.ld b/ld_so/ld_script/x86_64-unknown-linux-relibc.ld deleted file mode 120000 index 632f839b51..0000000000 --- a/ld_so/ld_script/x86_64-unknown-linux-relibc.ld +++ /dev/null @@ -1 +0,0 @@ -./x86_64-unknown-linux-gnu.ld \ No newline at end of file diff --git a/ld_so/ld_script/x86_64-unknown-redox.ld b/ld_so/ld_script/x86_64-unknown-redox.ld deleted file mode 100644 index 3e54c4a6d7..0000000000 --- a/ld_so/ld_script/x86_64-unknown-redox.ld +++ /dev/null @@ -1,256 +0,0 @@ -/* 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-x86-64", "elf64-x86-64", - "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -SEARCH_DIR("/x86_64-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)); - .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 : ALIGN(4K) - { - 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_*) - /* - * XXX: As of now, ld.so links with relibc which has the main functionality. In the next refactor, - * ld.so will be moved out of relibc. So, till that time, we have to discard any sections - * that may reference use thread local storage. - * - * .init_array also depends on TLS and is discarded as we don't need it. - */ - *(.gnu.linkonce.tb.*) *(.tcommon) - *(.init_array) - } -} diff --git a/ld_so/src/lib.rs b/ld_so/src/lib.rs index e68f260ef6..787de1b253 100644 --- a/ld_so/src/lib.rs +++ b/ld_so/src/lib.rs @@ -112,7 +112,7 @@ global_asm!( .globl _start _start: mv a0, sp - jal relibc_ld_so_start + call relibc_ld_so_start unimp " ); diff --git a/redox-rt/src/proc.rs b/redox-rt/src/proc.rs index 0b5553df17..a89bd11baa 100644 --- a/redox-rt/src/proc.rs +++ b/redox-rt/src/proc.rs @@ -706,6 +706,7 @@ impl<'a> MmapGuard<'a> { Ok(()) } + #[expect(clippy::mut_from_ref)] pub unsafe fn map_mut_anywhere( fd: &'a FdGuardUpper, offset: usize, diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index acabed309b..e88a33270a 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -953,6 +953,10 @@ impl FdTbl { pub const CONTEXT_MAX_FILES: u32 = 65_536; pub const DEFAULT_CAPACITY: usize = usize::BITS as usize; + #[expect( + clippy::new_without_default, + reason = "default not expected for this type" + )] pub const fn new() -> Self { Self { fd: None, @@ -1300,6 +1304,10 @@ bitflags::bitflags! { } impl PosixFdTbl { + #[expect( + clippy::new_without_default, + reason = "default not expected for this type" + )] pub const fn new() -> Self { Self { table: Vec::new(), @@ -1628,6 +1636,10 @@ pub struct UpperFdTbl { } impl UpperFdTbl { + #[expect( + clippy::new_without_default, + reason = "default not expected for this type" + )] pub const fn new() -> Self { Self { table: Vec::new(), diff --git a/src/c_str.rs b/src/c_str.rs index 8ed3cdea7a..7403b77ee9 100644 --- a/src/c_str.rs +++ b/src/c_str.rs @@ -258,6 +258,7 @@ impl<'a, T: Kind> NulStr<'a, T> { /// Scan the string to get its length. #[doc(alias = "strlen")] #[doc(alias = "wcslen")] + #[expect(clippy::len_without_is_empty, reason = "len() signature intentional")] pub fn len(self) -> usize { self.to_chars().len() } diff --git a/src/header/bits_pthread/mod.rs b/src/header/bits_pthread/mod.rs index e0a2cf4483..36757a6d42 100644 --- a/src/header/bits_pthread/mod.rs +++ b/src/header/bits_pthread/mod.rs @@ -76,7 +76,7 @@ macro_rules! pthread_assert_equal_size( // Fail at compile-time if alignments differ. let a = [0_u8; core::mem::align_of::<$export>()]; - #[allow(clippy::useless_transmute)] + #[expect(clippy::useless_transmute)] let b: [u8; core::mem::align_of::()] = core::mem::transmute(a); }; // TODO: Turn into a macro? @@ -88,6 +88,7 @@ macro_rules! pthread_assert_equal_size( let _: libc::$export = core::mem::transmute(export.__relibc_internal_size); let a = [0_u8; core::mem::align_of::<$export>()]; + #[expect(clippy::useless_transmute)] let b: [u8; core::mem::align_of::()] = core::mem::transmute(a); }; diff --git a/src/header/bits_timespec/mod.rs b/src/header/bits_timespec/mod.rs index a8bdb39700..3bf5b34b98 100644 --- a/src/header/bits_timespec/mod.rs +++ b/src/header/bits_timespec/mod.rs @@ -68,13 +68,13 @@ impl<'a> From<&'a syscall::TimeSpec> for timespec { fn from(value: &'a syscall::TimeSpec) -> Self { Self { tv_sec: value.tv_sec as _, - tv_nsec: value.tv_nsec as _, + tv_nsec: value.tv_nsec.into(), } } } #[cfg(target_os = "redox")] -impl<'a> From<&'a timespec> for syscall::TimeSpec { +impl From<×pec> for syscall::TimeSpec { fn from(tp: ×pec) -> Self { Self { tv_sec: tp.tv_sec as _, diff --git a/src/header/dlfcn/mod.rs b/src/header/dlfcn/mod.rs index 33e33ab9c7..eeab93f7f5 100644 --- a/src/header/dlfcn/mod.rs +++ b/src/header/dlfcn/mod.rs @@ -11,10 +11,13 @@ use core::{ sync::atomic::{AtomicUsize, Ordering}, }; +use alloc::sync::Arc; + use crate::{ c_str::CStr, ld_so::{ - linker::{DlError, ObjectHandle, Resolve, ScopeKind}, + dso::DSO, + linker::{DlError, Resolve, ScopeKind}, tcb::Tcb, }, platform::types::{c_char, c_int, c_void}, @@ -123,11 +126,8 @@ pub unsafe extern "C" fn dlopen(cfilename: *const c_char, flags: c_int) -> *mut let mut linker = unsafe { (*tcb.linker_ptr).lock() }; - let cbs_c = linker.cbs.clone(); - let cbs = cbs_c.borrow(); - - match (cbs.load_library)(&mut linker, filename, resolve, scope, noload) { - Ok(handle) => handle.as_ptr().cast_mut(), + match linker.load_library(filename, resolve, scope, noload) { + Ok(handle) => Arc::into_raw(handle).cast::().cast_mut(), Err(error) => { set_last_error(error); ptr::null_mut() @@ -138,7 +138,7 @@ pub unsafe extern "C" fn dlopen(cfilename: *const c_char, flags: c_int) -> *mut /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void { - let handle = ObjectHandle::from_ptr(handle); + let handle = unsafe { handle.cast::().as_ref() }; if symbol.is_null() { ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); @@ -161,9 +161,8 @@ pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *m } let linker = unsafe { (*tcb.linker_ptr).lock() }; - let cbs_c = linker.cbs.clone(); - let cbs = cbs_c.borrow(); - match (cbs.get_sym)(&linker, handle, symbol_str) { + + match linker.get_sym(handle, symbol_str) { Some(sym) => sym, _ => { ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); @@ -185,15 +184,14 @@ pub unsafe extern "C" fn dlclose(handle: *mut c_void) -> c_int { return -1; }; - let Some(handle) = ObjectHandle::from_ptr(handle) else { + if handle.is_null() { set_last_error(DlError::InvalidHandle); return -1; - }; + } let mut linker = unsafe { (*tcb.linker_ptr).lock() }; - let cbs_c = linker.cbs.clone(); - let cbs = cbs_c.borrow(); - (cbs.unload)(&mut linker, handle); + let obj = unsafe { Arc::from_raw(handle.cast::()) }; + linker.unload(obj); 0 } diff --git a/src/header/poll/mod.rs b/src/header/poll/mod.rs index 7de0ba5a5b..a09a453028 100644 --- a/src/header/poll/mod.rs +++ b/src/header/poll/mod.rs @@ -98,11 +98,16 @@ pub unsafe fn poll_epoll(fds: &mut [pollfd], timeout: c_int, sigmask: *const sig continue; } - #[expect(clippy::needless_update)] + #[cfg(target_os = "redox")] + let mut event = epoll_event { + events: 0, + data: epoll_data { u64: i as u64 }, + ..Default::default() + }; + #[cfg(target_os = "linux")] let mut event = epoll_event { events: 0, data: epoll_data { u64: i as u64 }, - ..Default::default() // needed only on redox for _pad field }; for (p, ep) in event_map.iter() { diff --git a/src/header/pwd/redox.rs b/src/header/pwd/redox.rs index 8b3d723907..ce50b77165 100644 --- a/src/header/pwd/redox.rs +++ b/src/header/pwd/redox.rs @@ -5,7 +5,7 @@ pub fn split(line: &mut [u8]) -> Option { let mut parts = line.split_mut(|&c| c == b'\0'); Some(passwd { pw_name: parts.next()?.as_mut_ptr().cast::(), - pw_passwd: c"x".as_ptr() as *const c_char as *mut c_char, + pw_passwd: c"x".as_ptr().cast::().cast_mut(), pw_uid: parsed(parts.next())?, pw_gid: parsed(parts.next())?, pw_gecos: parts.next()?.as_mut_ptr().cast::(), diff --git a/src/header/sys_ioctl/redox/mod.rs b/src/header/sys_ioctl/redox/mod.rs index c5100f5f67..d66aba4d77 100644 --- a/src/header/sys_ioctl/redox/mod.rs +++ b/src/header/sys_ioctl/redox/mod.rs @@ -22,7 +22,9 @@ fn dup_read(fd: c_int, name: &str, t: &mut T) -> syscall::Result { let size = mem::size_of::(); - let bytes = dup.read(unsafe { slice::from_raw_parts_mut(t as *mut T as *mut u8, size) })?; + let bytes = dup.read(unsafe { + slice::from_raw_parts_mut(core::ptr::from_mut::(t).cast::(), size) + })?; Ok(bytes / size) } @@ -33,7 +35,8 @@ fn dup_write(fd: c_int, name: &str, t: &T) -> Result { let size = mem::size_of::(); - let bytes = dup.write(unsafe { slice::from_raw_parts(t as *const T as *const u8, size) })?; + let bytes = dup + .write(unsafe { slice::from_raw_parts(core::ptr::from_ref::(t).cast::(), size) })?; Ok(bytes / size) } @@ -50,13 +53,13 @@ impl IoctlBuffer { unsafe fn read(&self) -> Result { let (ptr, size) = match *self { Self::Write(ptr, size) => (ptr, size), - Self::ReadWrite(ptr, size) => (ptr as *const c_void, size), + Self::ReadWrite(ptr, size) => (ptr.cast_const(), size), _ => { return Err(Errno(EINVAL)); } }; if size == mem::size_of::() { - let value = unsafe { ptr::read(ptr as *const T) }; + let value = unsafe { ptr::read(ptr.cast::()) }; Ok(value) } else { Err(Errno(EINVAL)) @@ -64,14 +67,11 @@ impl IoctlBuffer { } unsafe fn write(&mut self, value: T) -> Result<()> { - let (ptr, size) = match *self { - Self::Read(ptr, size) | Self::ReadWrite(ptr, size) => (ptr, size), - _ => { - return Err(Errno(EINVAL)); - } + let (Self::Read(ptr, size) | Self::ReadWrite(ptr, size)) = *self else { + return Err(Errno(EINVAL)); }; if size == mem::size_of::() { - unsafe { ptr::write(ptr as *mut T, value) }; + unsafe { ptr::write(ptr.cast::(), value) }; Ok(()) } else { Err(Errno(EINVAL)) @@ -83,7 +83,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu match request { FIONBIO => { let mut flags = Sys::fcntl(fd, fcntl::F_GETFL, 0)?; - flags = if unsafe { *(out as *mut c_int) } == 0 { + flags = if unsafe { *out.cast::() } == 0 { flags & !fcntl::O_NONBLOCK } else { flags | fcntl::O_NONBLOCK @@ -91,7 +91,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu Sys::fcntl(fd, fcntl::F_SETFL, flags as c_ulonglong)?; } TCGETS => { - let termios = unsafe { &mut *(out as *mut termios::termios) }; + let termios = unsafe { &mut *out.cast::() }; dup_read(fd, "termios", termios)?; } // TODO: give these different behaviors @@ -119,7 +119,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu todo_skip!(0, "ioctl TIOCSCTTY"); } TIOCGPGRP => { - let pgrp = unsafe { &mut *(out as *mut pid_t) }; + let pgrp = unsafe { &mut *out.cast::() }; dup_read(fd, "pgrp", pgrp)?; } TIOCSPGRP => { @@ -127,7 +127,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu dup_write(fd, "pgrp", pgrp)?; } TIOCGWINSZ => { - let winsize = unsafe { &mut *(out as *mut winsize) }; + let winsize = unsafe { &mut *out.cast::() }; dup_read(fd, "winsize", winsize)?; } TIOCSWINSZ => { @@ -135,7 +135,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu dup_write(fd, "winsize", winsize)?; } TIOCGPTLCK => { - let lock = unsafe { &mut *(out as *mut c_int) }; + let lock = unsafe { &mut *out.cast::() }; dup_read(fd, "ptlock", lock)?; } TIOCSPTLCK => { @@ -143,7 +143,7 @@ pub unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Resu dup_write(fd, "ptlock", lock)?; } TIOCGPTN => { - let name = unsafe { &mut *(out as *mut c_int) }; + let name = unsafe { &mut *out.cast::() }; dup_read(fd, "ptsname", name)?; } SIOCATMARK => { diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index 9060918364..351d1244e9 100644 --- a/src/header/time/mod.rs +++ b/src/header/time/mod.rs @@ -72,7 +72,7 @@ pub(crate) struct timer_internal_t { #[cfg(target_os = "redox")] impl timer_internal_t { pub unsafe fn from_raw(timerid: timer_t) -> &'static mut Self { - unsafe { &mut *(timerid as *mut Self) } + unsafe { &mut *timerid.cast::() } } } diff --git a/src/header/unistd/sysconf.rs b/src/header/unistd/sysconf.rs index 0db38b0bbe..50a40fe664 100644 --- a/src/header/unistd/sysconf.rs +++ b/src/header/unistd/sysconf.rs @@ -1,4 +1,6 @@ -/// sysconf.h: . +//! `sysconf.h` implementation. +//! +//! See . #[cfg(target_os = "redox")] #[path = "sysconf/redox.rs"] diff --git a/src/header/unistd/sysconf/redox.rs b/src/header/unistd/sysconf/redox.rs index 3d4f46e627..cc5c6ba35c 100644 --- a/src/header/unistd/sysconf/redox.rs +++ b/src/header/unistd/sysconf/redox.rs @@ -40,7 +40,7 @@ pub(super) fn sysconf_impl(name: c_int) -> c_long { _SC_TIMEOUTS => 202405, _SC_TIMERS => 202405, _SC_SYMLOOP_MAX => -1, - _SC_HOST_NAME_MAX => limits::HOST_NAME_MAX.try_into().unwrap_or(-1), + _SC_HOST_NAME_MAX => limits::HOST_NAME_MAX, _SC_NPROCESSORS_CONF => get_cpu_count().unwrap_or(None).unwrap_or(1), _SC_NPROCESSORS_ONLN => get_cpu_count().unwrap_or(None).unwrap_or(1), _SC_PHYS_PAGES => get_mem_stat().map(|s| s.f_blocks as c_long).unwrap_or(-1), @@ -77,6 +77,6 @@ pub fn get_mem_stat() -> Result { let mut buf = sys_statvfs::statvfs::default(); let res = Sys::fstatvfs(fd, Out::from_mut(&mut buf)); if let Ok(()) = Sys::close(fd) {}; // TODO handle error - let _ = res?; - return Ok(buf); + res?; + Ok(buf) } diff --git a/src/ld_so/callbacks.rs b/src/ld_so/callbacks.rs deleted file mode 100644 index 5b322ef440..0000000000 --- a/src/ld_so/callbacks.rs +++ /dev/null @@ -1,39 +0,0 @@ -use super::linker::{Linker, ObjectHandle, Resolve, Result, ScopeKind}; -use crate::platform::types::c_void; -use alloc::boxed::Box; - -pub struct LinkerCallbacks { - pub unload: Box, - pub load_library: - Box, Resolve, ScopeKind, bool) -> Result>, - pub get_sym: Box, &str) -> Option<*mut c_void>>, -} - -impl LinkerCallbacks { - #[allow(clippy::new_without_default)] - pub fn new() -> LinkerCallbacks { - LinkerCallbacks { - unload: Box::new(unload), - load_library: Box::new(load_library), - get_sym: Box::new(get_sym), - } - } -} - -fn unload(linker: &mut Linker, handle: ObjectHandle) { - linker.unload(handle) -} - -fn load_library( - linker: &mut Linker, - name: Option<&str>, - resolve: Resolve, - scope: ScopeKind, - noload: bool, -) -> Result { - linker.load_library(name, resolve, scope, noload) -} - -fn get_sym(linker: &Linker, handle: Option, name: &str) -> Option<*mut c_void> { - linker.get_sym(handle, name) -} diff --git a/src/ld_so/dso.rs b/src/ld_so/dso.rs index 9c9778ce73..dd210ced26 100644 --- a/src/ld_so/dso.rs +++ b/src/ld_so/dso.rs @@ -3,7 +3,7 @@ //! * use object::{ - NativeEndian, Object, StringTable, SymbolIndex, elf, + NativeEndian, Object, StringTable, SymbolIndex, U32, elf, read::elf::{ Dyn as _, GnuHashTable, HashTable as SysVHashTable, ProgramHeader as _, Rel as _, Rela as _, Sym as _, Version, VersionTable, @@ -42,25 +42,29 @@ pub type Relr = usize; #[cfg(target_pointer_width = "32")] mod shim { - use object::{NativeEndian, elf::*, read::elf::ElfFile32}; - pub type Dyn = Dyn32; - pub type Rel = Rel32; - pub type Rela = Rela32; - pub type Sym = Sym32; - pub type FileHeader = FileHeader32; - pub type ProgramHeader = ProgramHeader32; + use object::{NativeEndian, elf, read::elf::ElfFile32}; + pub type Dyn = elf::Dyn32; + pub type Rel = elf::Rel32; + pub type Rela = elf::Rela32; + pub type Sym = elf::Sym32; + pub type FileHeader = elf::FileHeader32; + pub type ProgramHeader = elf::ProgramHeader32; + pub type GnuHashHeader = elf::GnuHashHeader; + pub type SysVHashHeader = elf::HashHeader; pub type ElfFile<'a> = ElfFile32<'a, NativeEndian>; } #[cfg(target_pointer_width = "64")] mod shim { - use object::{NativeEndian, elf::*, read::elf::ElfFile64}; - pub type Dyn = Dyn64; - pub type Rel = Rel64; - pub type Rela = Rela64; - pub type Sym = Sym64; - pub type FileHeader = FileHeader64; - pub type ProgramHeader = ProgramHeader64; + use object::{NativeEndian, elf, read::elf::ElfFile64}; + pub type Dyn = elf::Dyn64; + pub type Rel = elf::Rel64; + pub type Rela = elf::Rela64; + pub type Sym = elf::Sym64; + pub type FileHeader = elf::FileHeader64; + pub type ProgramHeader = elf::ProgramHeader64; + pub type GnuHashHeader = elf::GnuHashHeader; + pub type SysVHashHeader = elf::HashHeader; pub type ElfFile<'a> = ElfFile64<'a, NativeEndian>; } @@ -176,7 +180,7 @@ impl<'data> Dynamic<'data> { unsafe impl Send for Dynamic<'_> {} unsafe impl Sync for Dynamic<'_> {} -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub(super) struct Relocation { pub(super) offset: usize, pub(super) addend: Option, @@ -331,14 +335,35 @@ impl SymbolBinding { } } +pub struct MemoryMapHandle { + ptr: *const u8, + size: usize, +} + +impl MemoryMapHandle { + pub fn as_ptr(&self) -> *const u8 { + self.ptr + } + + pub fn size(&self) -> usize { + self.size + } +} + +impl Drop for MemoryMapHandle { + fn drop(&mut self) { + unsafe { Sys::munmap(self.ptr as *mut c_void, self.size).unwrap() }; + } +} + /// Use to represent a library as well as all the symbols that is loaded withen it. pub struct DSO { pub name: String, pub id: usize, pub dlopened: bool, pub entry_point: usize, - /// Loaded library in-memory data - pub mmap: &'static [u8], + pub base: *const u8, + pub mmap: Option, pub tls_module_id: usize, pub tls_offset: usize, @@ -350,9 +375,56 @@ pub struct DSO { /// Whether this DSO *and* its dependencies have been successfully loaded. is_ready: AtomicBool, + + /// Is this DSO for ld.so? + is_me: bool, } impl DSO { + #[expect(clippy::not_unsafe_ptr_arg_deref, reason = "see FIXME note")] + pub fn from_raw( + base: *const u8, + dyns: &[Dyn], + phdrs: &[ProgramHeader], + id: usize, + tls_module_id: usize, + tls_offset: usize, + ) -> (Self, Master) { + // FIXME: What should `path` be set to? + // FIXME: this function and `parse_dynamic` should be unsafe. + let (dynamic, _debug) = Self::parse_dynamic("", base, true, dyns).unwrap(); + + let tcb_master = phdrs + .iter() + .find(|ph| ph.p_type(NativeEndian) == elf::PT_TLS) + .map(|ph| Master { + ptr: unsafe { base.byte_add(ph.p_vaddr(NativeEndian) as usize) }, + image_size: ph.p_filesz(NativeEndian) as usize, + segment_size: ph.p_memsz(NativeEndian) as usize, + offset: tls_offset + ph.p_memsz(NativeEndian) as usize, + }) + .unwrap(); + + ( + Self { + name: String::from("libc.so.6"), + id, + tls_offset: tcb_master.offset, + tls_module_id, + dlopened: false, + entry_point: 0, + base, + mmap: None, + dynamic, + scope: spin::Once::new(), + pie: true, + is_ready: AtomicBool::new(false), + is_me: true, + }, + tcb_master, + ) + } + pub fn new( path: &str, data: &[u8], @@ -385,7 +457,10 @@ impl DSO { id, dlopened, entry_point, - mmap, + + base: mmap.as_ptr(), + mmap: Some(mmap), + tls_module_id: if tcb_master.is_some() { tls_module_id } else { @@ -397,13 +472,14 @@ impl DSO { dynamic, scope: spin::Once::new(), is_ready: AtomicBool::new(false), + is_me: false, }; Ok((dso, tcb_master, elf.elf_program_headers().to_vec())) } #[inline] - pub fn mark_ready(&self) { + pub unsafe fn mark_ready(&self) { self.is_ready.store(true, Ordering::SeqCst); } @@ -444,11 +520,7 @@ impl DSO { Some(( Symbol { name, - base: if self.pie { - self.mmap.as_ptr() as usize - } else { - 0 - }, + base: if self.pie { self.base as usize } else { 0 }, value: sym.st_value(NativeEndian) as usize, size: sym.st_size(NativeEndian) as usize, sym_type: sym.st_type(), @@ -468,7 +540,7 @@ impl DSO { } } - pub fn run_fini(&self) { + pub unsafe fn run_fini(&self) { for f in self.dynamic.fini_array.iter().rev() { unsafe { f() } } @@ -480,7 +552,7 @@ impl DSO { data: &'a [u8], base_addr: Option, tls_offset: usize, - ) -> Result<(&'static [u8], Option, Dynamic<'static>), String> { + ) -> Result<(MemoryMapHandle, Option, Dynamic<'static>), String> { let endian = elf.endian(); log::trace!("# {}", path); // data for struct LinkMap @@ -640,8 +712,9 @@ impl DSO { let dynamic = dynamic.ok_or_else(|| "Unable to find PT_DYNAMIC section".to_string())?; - let (parsed_dynamic, debug) = Self::parse_dynamic(path, mmap, is_pie_enabled(elf), dynamic) - .map_err(|e| e.to_string())?; + let (parsed_dynamic, debug) = + Self::parse_dynamic(path, mmap.as_ptr(), is_pie_enabled(elf), dynamic.1) + .map_err(|e| e.to_string())?; if let Some(i) = debug { // FIXME: cleanup @@ -664,14 +737,21 @@ impl DSO { } } - Ok((mmap, tcb_master, parsed_dynamic)) + Ok(( + MemoryMapHandle { + ptr: mmap.as_ptr(), + size: mmap.len(), + }, + tcb_master, + parsed_dynamic, + )) } fn parse_dynamic<'a>( path: &str, - mmap: &'a [u8], + mmap: *const u8, is_pie: bool, - (_, entries): (&ProgramHeader, &[Dyn]), + entries: &[Dyn], ) -> object::Result<(Dynamic<'a>, Option)> { let mut runpath = None; let mut got = None; @@ -692,28 +772,79 @@ impl DSO { for (i, entry) in entries.iter().enumerate() { let val = entry.d_val(NativeEndian); - let relative_idx = val as usize - if is_pie { 0 } else { mmap.as_ptr() as usize }; - let ptr = (val as usize + if is_pie { mmap.as_ptr() as usize } else { 0 }) as *const u8; + let relative_idx = val as usize - if is_pie { 0 } else { mmap as usize }; + let ptr = (val as usize + if is_pie { mmap as usize } else { 0 }) as *const u8; let tag = entry.d_tag(NativeEndian) as u32; match tag { elf::DT_DEBUG => debug = Some(i), - // {Gnu,SysV}HashTable::parse() - // - // > The header does not contain a length field, and so all of - // > `data` will be used as the hash table values. It does not - // > matter if this is longer than needed... elf::DT_GNU_HASH => { - let value = GnuHashTable::parse(NativeEndian, &mmap[relative_idx..])?; - hash_table = Some(HashTable::Gnu(value)); + let header = unsafe { ptr.cast::().as_ref() }.unwrap(); + let bloom_count = header.bloom_count.get(NativeEndian) as usize; + let bucket_count = header.bucket_count.get(NativeEndian) as usize; + let symbol_base = header.symbol_base.get(NativeEndian); + + let bloom_size = bloom_count * size_of::(); + let mut ptr = unsafe { ptr.byte_add(size_of::()) }; + + let bloom_filters = unsafe { slice::from_raw_parts(ptr, bloom_size) }; + unsafe { ptr = ptr.byte_add(bloom_size) }; + + let buckets = unsafe { + slice::from_raw_parts(ptr.cast::>(), bucket_count) + }; + unsafe { ptr = ptr.byte_add(bucket_count * size_of::()) }; + + let mut max_symbol = 0; + for bucket in buckets { + let bucket = bucket.get(NativeEndian); + if max_symbol < bucket { + max_symbol = bucket; + } + } + + assert_ne!(max_symbol, 0); + let chains_ptr = ptr.cast::(); + let mut i = max_symbol - symbol_base; + + while unsafe { chains_ptr.add(i as usize).read() & 1 == 0 } { + i += 1; + } + + let values = unsafe { + slice::from_raw_parts(ptr.cast::>(), i as usize + 1) + }; + + let table = GnuHashTable { + symbol_base, + bloom_shift: header.bloom_shift.get(NativeEndian), + bloom_filters, + buckets, + values, + }; + + hash_table = Some(HashTable::Gnu(table)); } // XXX: Both GNU_HASH and HASH may be present, we give priority // to GNU_HASH as it is significantly faster. elf::DT_HASH if hash_table.is_none() => { - let value = SysVHashTable::parse(NativeEndian, &mmap[relative_idx..])?; - hash_table = Some(HashTable::Sysv(value)); + let header = unsafe { ptr.cast::().as_ref() }.unwrap(); + let bucket_count = header.bucket_count.get(NativeEndian) as usize; + let chain_count = header.chain_count.get(NativeEndian) as usize; + + let mut ptr = unsafe { + ptr.byte_add(size_of::()) + .cast::>() + }; + + let buckets = unsafe { slice::from_raw_parts(ptr, bucket_count) }; + unsafe { ptr = ptr.add(bucket_count) }; + let chains = unsafe { slice::from_raw_parts(ptr, chain_count) }; + + let table = SysVHashTable { buckets, chains }; + hash_table = Some(HashTable::Sysv(table)); } elf::DT_PLTGOT => { @@ -771,14 +902,16 @@ impl DSO { } } - let strtab_offset = strtab_offset.expect("mandatory DT_STRTAB not present"); - let strtab_size = strtab_size.expect("mandatory DT_STRSZ not present"); + let hash_table = hash_table.expect("either DT_GNU_HASH and/or DT_HASH mut be present"); + + let strtab_offset = strtab_offset.expect("DT_STRTAB must be present"); + let strtab_size = strtab_size.expect("DT_STRSZ must be present"); #[expect(clippy::unnecessary_cast, reason = "needed on i586")] let dynstrtab = StringTable::new( - mmap, - strtab_offset as u64, - strtab_offset as u64 + strtab_size as u64, + unsafe { slice::from_raw_parts(mmap.byte_add(strtab_offset), strtab_size as usize) }, + 0, + strtab_size as u64, ); let get_str = |entry: &Dyn| { @@ -812,7 +945,6 @@ impl DSO { let soname = soname.map(get_str).transpose()?; let jmprel = jmprel.unwrap_or_default(); - let hash_table = hash_table.expect("either DT_GNU_HASH and/or DT_HASH mut be present"); let init_array = unsafe { get_array(init_array_ptr, init_array_len) }; let fini_array = unsafe { get_array(fini_array_ptr, fini_array_len) }; @@ -889,8 +1021,6 @@ impl DSO { } fn static_relocate(&self, global_scope: &Scope, reloc: Relocation) -> object::Result<()> { - let b = self.mmap.as_ptr() as usize; - let (sym, my_sym) = if reloc.sym != STN_UNDEF { let name = self.dynamic.symbol_name(reloc.sym).unwrap(); @@ -923,7 +1053,7 @@ impl DSO { .unwrap_or((0, self)); let ptr = if self.pie { - (b + reloc.offset) as *mut u8 + unsafe { self.base.byte_add(reloc.offset).cast_mut() } } else { reloc.offset as *mut u8 }; @@ -956,7 +1086,7 @@ impl DSO { } RelocationKind::GOT => set_usize(s), RelocationKind::OFFSET => set_usize((s + a).wrapping_sub(p)), - RelocationKind::RELATIVE => set_usize(b + a), + RelocationKind::RELATIVE => set_usize(self.base as usize + a), RelocationKind::SYMBOLIC => set_usize(s + a), RelocationKind::TPOFF => { assert!( @@ -974,7 +1104,8 @@ impl DSO { } } RelocationKind::IRELATIVE => unsafe { - let f: unsafe extern "C" fn() -> usize = core::mem::transmute(b + a); + let f: unsafe extern "C" fn() -> usize = + core::mem::transmute(self.base as usize + a); set_usize(f()); }, RelocationKind::COPY => unsafe { @@ -1007,7 +1138,6 @@ impl DSO { return Ok(()); }; - let object_base_addr = self.mmap.as_ptr() as usize; let jmprel = self.dynamic.jmprel; let pltrelsz = self.dynamic.pltrelsz; @@ -1031,14 +1161,14 @@ impl DSO { }; let ptr = if self.pie { - (object_base_addr + reloc.offset) as *mut usize + (self.base as usize + reloc.offset) as *mut usize } else { reloc.offset as *mut usize }; match (reloc.kind, resolve) { (RelocationKind::PLT, Resolve::Lazy) if self.pie => unsafe { - *ptr += object_base_addr; + *ptr += self.base as usize; }, (RelocationKind::PLT, Resolve::Lazy) => { @@ -1082,20 +1212,31 @@ impl DSO { Ok(()) } - pub fn relocate(&self, ph: &[ProgramHeader], resolve: Resolve) -> object::Result<()> { + pub fn relocate(&self, ph: Option<&[ProgramHeader]>, resolve: Resolve) -> object::Result<()> { let global_scope = GLOBAL_SCOPE.read(); - let base = self.mmap.as_ptr(); - unsafe { - apply_relr(base, self.dynamic.relr); + if !self.is_me { + unsafe { + apply_relr(self.base, self.dynamic.relr); + } } - self.dynamic - .static_relocations() - .try_for_each(|reloc| self.static_relocate(&global_scope, reloc))?; + for reloc in self.dynamic.static_relocations() { + if reloc.kind == RelocationKind::RELATIVE && self.is_me { + continue; + } + self.static_relocate(&global_scope, reloc)?; + } + + if self.is_me { + // TODO: assert that ld.so have no lazy relocations. + return Ok(()); + } self.lazy_relocate(&global_scope, resolve)?; + let ph = ph.unwrap(); + // Protect pages for ph in ph .iter() @@ -1120,7 +1261,7 @@ impl DSO { unsafe { let ptr = if self.pie { - self.mmap.as_ptr().add(vaddr) + self.base.add(vaddr) } else { vaddr as *const u8 }; @@ -1135,12 +1276,16 @@ impl DSO { impl Drop for DSO { fn drop(&mut self) { + if self.is_me { + return; + } if self.is_ready.load(Ordering::SeqCst) { // `run_fini` should not be called if we are being prematurely // dropped (e.g. failed to satisfy dependencies). - self.run_fini(); + unsafe { + self.run_fini(); + } } - unsafe { Sys::munmap(self.mmap.as_ptr() as *mut c_void, self.mmap.len()).unwrap() }; } } @@ -1309,3 +1454,7 @@ pub unsafe fn apply_relr(base: *const u8, relr: &[Relr]) { } } } + +// TODO: Add safety comment. +unsafe impl Send for DSO {} +unsafe impl Sync for DSO {} diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index 56193ff1ab..f7788e8c82 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -1,6 +1,5 @@ use alloc::{ collections::BTreeMap, - rc::Rc, string::{String, ToString}, sync::{Arc, Weak}, vec::Vec, @@ -12,13 +11,9 @@ use object::{ read::elf::{Rela as _, Sym}, }; -use core::{ - cell::RefCell, - ptr::{self, NonNull}, -}; +use core::ptr; use crate::{ - ALLOCATOR, c_str::{CStr, CString}, error::Errno, header::{ @@ -26,7 +21,7 @@ use crate::{ fcntl, sys_mman, unistd::F_OK, }, - ld_so::dso::SymbolBinding, + ld_so::dso::{Dyn, SymbolBinding}, out::Out, platform::{ Pal, Sys, @@ -43,7 +38,6 @@ use super::dso::Rela; use super::{ PATH_SEP, access::accessible, - callbacks::LinkerCallbacks, debug::{_dl_debug_state, _r_debug, RTLDState}, dso::{DSO, ProgramHeader}, tcb::{Master, Tcb}, @@ -328,41 +322,6 @@ impl Scope { } } -// Used by dlfcn.h -// -// We need this as the handle must be created and destroyed with the dynamic -// linker's allocator. -pub struct ObjectHandle(*const DSO); - -impl ObjectHandle { - #[inline] - fn new(obj: Arc) -> Self { - Self(Arc::into_raw(obj)) - } - - #[inline] - fn into_inner(self) -> Arc { - unsafe { Arc::from_raw(self.0) } - } - - #[inline] - pub fn as_ptr(&self) -> *const c_void { - self.0.cast() - } - - #[inline] - pub fn from_ptr(ptr: *const c_void) -> Option { - NonNull::new(ptr as *mut DSO).map(|ptr| Self(ptr.as_ptr())) - } -} - -impl AsRef for ObjectHandle { - #[inline] - fn as_ref(&self) -> &DSO { - unsafe { &*self.0 } - } -} - bitflags::bitflags! { #[derive(Debug, Default)] pub struct DebugFlags: u32 { @@ -417,29 +376,36 @@ impl Config { } } +pub struct Me { + pub base: *const u8, + pub phdrs: &'static [ProgramHeader], + pub dyns: &'static [Dyn], +} + pub struct Linker { config: Config, + me: Me, + next_object_id: usize, next_tls_module_id: usize, tls_size: usize, objects: BTreeMap>, name_to_object_id_map: BTreeMap, - pub cbs: Rc>, } const ROOT_ID: usize = 1; impl Linker { - pub fn new(config: Config) -> Self { + pub fn new(me: Me, config: Config) -> Self { Self { + me, config, next_object_id: ROOT_ID, next_tls_module_id: 1, tls_size: 0, objects: BTreeMap::new(), name_to_object_id_map: BTreeMap::new(), - cbs: Rc::new(RefCell::new(LinkerCallbacks::new())), } } @@ -465,7 +431,7 @@ impl Linker { resolve: Resolve, scope: ScopeKind, noload: bool, - ) -> Result { + ) -> Result> { log::trace!( "[ld.so] load_library(name={:?}, resolve={:#?}, scope={:#?}, noload={})", name, @@ -500,14 +466,14 @@ impl Linker { self.scope_debug(); } - Ok(ObjectHandle::new(obj.clone())) + Ok(obj.clone()) } else if !noload { let parent_runpath = &self .objects .get(&ROOT_ID) .and_then(|parent| parent.runpath().cloned()); - Ok(ObjectHandle::new(self.load_object( + Ok(self.load_object( name, parent_runpath, None, @@ -518,29 +484,24 @@ impl Linker { resolve }, scope, - )?)) + )?) } else { - // FIXME: LoadError? - // Err(Error::Malformed(format!( - // "object '{}' has not yet been loaded", - // name - // ))) - Ok(ObjectHandle(ptr::null())) + Err(DlError::NotFound) } } None => match self.objects.get(&ROOT_ID) { - Some(obj) => Ok(ObjectHandle::new(obj.clone())), + Some(obj) => Ok(obj.clone()), None => Err(DlError::NotFound), }, } } - pub fn get_sym(&self, handle: Option, name: &str) -> Option<*mut c_void> { + pub fn get_sym(&self, handle: Option<&DSO>, name: &str) -> Option<*mut c_void> { let guard; - if let Some(handle) = handle.as_ref() { - handle.as_ref().scope() + if let Some(handle) = handle { + handle.scope() } else { guard = GLOBAL_SCOPE.read(); &guard @@ -560,8 +521,7 @@ impl Linker { }) } - pub fn unload(&mut self, handle: ObjectHandle) { - let obj = handle.into_inner(); + pub fn unload(&mut self, obj: Arc) { if !obj.dlopened { return; } @@ -590,7 +550,7 @@ impl Linker { if let Some(name) = self.name_to_object_id_map.get(*dep) && let Some(object_name) = self.objects.get(name) { - self.unload(ObjectHandle::new(object_name.clone())); + self.unload(object_name.clone()); } } self.name_to_object_id_map.remove(&obj.name); @@ -603,7 +563,9 @@ impl Linker { pub fn fini(&self) { for obj in self.objects.values() { - obj.run_fini(); + unsafe { + obj.run_fini(); + } } } @@ -642,7 +604,7 @@ impl Linker { )?; for (i, obj) in new_objects.iter().enumerate() { - obj.relocate(&objects_data[i], resolve).unwrap(); + obj.relocate(objects_data[i].as_deref(), resolve).unwrap(); } unsafe { @@ -664,14 +626,18 @@ impl Linker { let new_tcb_len = new_tcb.generic.tcb_len; // Unmap just the TCB page. - Sys::munmap(new_tcb as *mut Tcb as *mut c_void, syscall::PAGE_SIZE).unwrap(); + Sys::munmap( + core::ptr::from_mut::(new_tcb).cast::(), + syscall::PAGE_SIZE, + ) + .unwrap(); let new_addr = ptr::addr_of!(*new_tcb) as usize; assert_eq!( syscall::syscall5( syscall::SYS_MREMAP, - old_tcb as *mut Tcb as usize, + core::ptr::from_mut::(old_tcb) as usize, syscall::PAGE_SIZE, new_addr, syscall::PAGE_SIZE, @@ -692,7 +658,11 @@ impl Linker { new_tcb.generic.tcb_len = new_tcb_len; drop(_guard); - (new_tcb, old_tcb as *mut Tcb as *mut c_void, thr_fd) + ( + new_tcb, + core::ptr::from_mut::(old_tcb).cast::(), + thr_fd, + ) }; #[cfg(not(target_os = "redox"))] @@ -735,7 +705,6 @@ impl Linker { #[cfg(target_os = "redox")] Some(thr_fd), ); - tcb.mspace = ALLOCATOR.get(); #[cfg(target_os = "redox")] { @@ -751,7 +720,10 @@ impl Linker { } for obj in new_objects.into_iter() { - obj.mark_ready(); + // SAFETY: `obj` and its dependencies have been successfuly loaded. + unsafe { + obj.mark_ready(); + } self.run_init(&obj); self.register_object(obj); } @@ -788,7 +760,7 @@ impl Linker { base_addr: Option, dlopened: bool, new_objects: &mut Vec>, - objects_data: &mut Vec>, + objects_data: &mut Vec>>, tcb_masters: &mut Vec, // Scope of the object that caused this object to be loaded. dependent_scope: Option<&mut Scope>, @@ -821,6 +793,49 @@ impl Linker { let debug = self.config.debug_flags.contains(DebugFlags::LOAD); + if name == "libc.so.6" || name == "libc.so" { + if debug { + println!( + "[ld.so]: loading libc.so.6 (aka. ld.so) at {:#?}", + self.me.base + ); + } + + let (me, master) = DSO::from_raw( + self.me.base, + self.me.dyns, + self.me.phdrs, + self.next_object_id, + self.next_tls_module_id, + self.tls_size.next_multiple_of(16), + ); + + self.tls_size = master.offset; + self.next_tls_module_id += 1; + self.next_object_id += 1; + + let obj = Arc::new(me); + + tcb_masters.push(master); + objects_data.push(None); + new_objects.push(obj.clone()); + + if let Some(dependent_scope) = dependent_scope { + match scope_kind { + ScopeKind::Local => dependent_scope.add(&obj), + ScopeKind::Global => GLOBAL_SCOPE.write().add(&obj), + } + } else if let ScopeKind::Global = scope_kind { + GLOBAL_SCOPE.write().add(&obj); + } + + let mut scope = Scope::local(); + scope.set_owner(Arc::downgrade(&obj)); + obj.scope.call_once(|| scope); + + return Ok(obj); + } + let path = self.search_object(name, parent_runpath)?; let file = self.read_file(&path)?; let data = file.data(); @@ -846,8 +861,8 @@ impl Linker { eprintln!( "[ld.so]: loading object: {} at {:#x}:{:#x} (pie: {})", name, - obj.mmap.as_ptr() as usize, - obj.mmap.as_ptr() as usize + obj.mmap.len(), + obj.mmap.as_ref().unwrap().as_ptr() as usize, + obj.mmap.as_ref().unwrap().as_ptr() as usize + obj.mmap.as_ref().unwrap().size(), obj.pie, ); } @@ -896,7 +911,7 @@ impl Linker { )?; } - objects_data.push(elf); + objects_data.push(Some(elf)); new_objects.push(obj.clone()); scope.set_owner(Arc::downgrade(&obj)); @@ -1011,7 +1026,7 @@ impl Linker { #[cfg(target_pointer_width = "64")] extern "C" fn __plt_resolve_inner(obj: *const DSO, relocation_index: c_uint) -> *mut c_void { let obj = unsafe { &*obj }; - let obj_base = obj.mmap.as_ptr() as usize; + let obj_base = obj.base as usize; let jmprel = obj.dynamic.jmprel; let rela = unsafe { &*(jmprel as *const Rela).add(relocation_index as usize) }; diff --git a/src/ld_so/mod.rs b/src/ld_so/mod.rs index f8b90af0f6..0bf42bf182 100644 --- a/src/ld_so/mod.rs +++ b/src/ld_so/mod.rs @@ -21,9 +21,8 @@ use crate::{ pub const PATH_SEP: char = ':'; mod access; -pub mod callbacks; pub mod debug; -mod dso; +pub mod dso; pub mod linker; pub mod start; pub mod tcb; diff --git a/src/ld_so/start.rs b/src/ld_so/start.rs index ee30ac7410..a00f1d328f 100644 --- a/src/ld_so/start.rs +++ b/src/ld_so/start.rs @@ -1,6 +1,6 @@ // Start code adapted from https://gitlab.redox-os.org/redox-os/relibc/blob/master/src/start.rs -use core::slice; +use core::{slice, str::FromStr}; use alloc::{ borrow::ToOwned, @@ -9,10 +9,11 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; +use log::LevelFilter; use object::{ NativeEndian, elf::{self, PT_DYNAMIC, PT_PHDR}, - read::elf::{Dyn as _, ProgramHeader as _}, + read::elf::{Dyn as _, FileHeader as _, ProgramHeader as _}, }; use crate::{ @@ -23,12 +24,12 @@ use crate::{ }, ld_so::{ dso::{ - DT_RELR, DT_RELRENT, DT_RELRSZ, Dyn, ProgramHeader, Rel, Rela, Relocation, + DT_RELR, DT_RELRENT, DT_RELRSZ, Dyn, FileHeader, ProgramHeader, Rel, Rela, Relocation, RelocationKind, Relr, apply_relr, }, - linker::DebugFlags, + linker::{DebugFlags, Me}, }, - platform::{auxv_iter, get_auxvs, types::c_char}, + platform::{auxv_iter, get_auxvs, logger::RELIBC_LOG_ENV_VAR, types::c_char}, start::Stack, sync::mutex::Mutex, }; @@ -41,12 +42,6 @@ use super::{ tcb::Tcb, }; -#[cfg(target_pointer_width = "32")] -pub const SIZEOF_EHDR: usize = 52; - -#[cfg(target_pointer_width = "64")] -pub const SIZEOF_EHDR: usize = 64; - unsafe fn get_argv(mut ptr: *const usize) -> (Vec, *const usize) { //traverse the stack and collect argument vector let mut argv = Vec::new(); @@ -211,7 +206,7 @@ pub unsafe extern "C" fn relibc_ld_so_start( let is_manual = at_entry == ld_entry; // Whether the dynamic linker was invoked as a command. - let mut i = dynamic; + let mut i = 0; let mut rela_ptr = None; let mut rela_len = None; let mut relr_ptr = None; @@ -219,7 +214,7 @@ pub unsafe extern "C" fn relibc_ld_so_start( let mut rel_ptr = None; let mut rel_len = None; loop { - let entry = unsafe { &*i }; + let entry = unsafe { &*dynamic.add(i) }; let val = entry.d_val(NativeEndian); let ptr = val as *const u8; match entry.d_tag(NativeEndian) as u32 { @@ -241,9 +236,11 @@ pub unsafe extern "C" fn relibc_ld_so_start( } _ => {} } - i = unsafe { i.add(1) }; + i += 1; } + let dyns = unsafe { slice::from_raw_parts(dynamic, i) }; + unsafe fn get_array<'a, T>( ptr: Option<*const T>, len: Option, @@ -251,7 +248,7 @@ pub unsafe extern "C" fn relibc_ld_so_start( ) -> &'a [T] { if let Some(ptr) = ptr { let len = len.expect("dynamic entry was present without it's corresponding size"); - unsafe { core::slice::from_raw_parts(ptr.byte_add(base_addr), len) } + unsafe { slice::from_raw_parts(ptr.byte_add(base_addr), len) } } else { &[] } @@ -298,7 +295,23 @@ pub unsafe extern "C" fn relibc_ld_so_start( } } - stage2(sp, self_base, is_manual, base_addr) + unsafe extern "C" { + safe static __ehdr_start: FileHeader; + } + + let ph_off = __ehdr_start.e_phoff(NativeEndian) as usize; + let ph_num = __ehdr_start.e_phnum(NativeEndian) as usize; + + let my_phdrs = unsafe { + slice::from_raw_parts( + core::ptr::addr_of!(__ehdr_start) + .byte_add(ph_off) + .cast::(), + ph_num, + ) + }; + + stage2(sp, self_base, is_manual, base_addr, dyns, my_phdrs) } fn stage2( @@ -306,6 +319,8 @@ fn stage2( self_base: usize, is_manual: bool, base_addr: Option, + my_dyns: &'static [Dyn], + my_phdrs: &'static [ProgramHeader], ) -> usize { // Setup TCB for ourselves. unsafe { @@ -392,9 +407,12 @@ fn stage2( .collect::>(), ); - crate::platform::environ = crate::platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr(); - - crate::platform::logger::init(); + if let Some(env) = envs.get(RELIBC_LOG_ENV_VAR.to_str().unwrap()) + && let Ok(level) = LevelFilter::from_str(env) + && let Err(_) = crate::platform::logger::init(level) + { + log::error!("Logger has already been initialised"); + } } // we might need global lock for this kind of stuff @@ -435,7 +453,14 @@ fn stage2( } } - let mut linker = Linker::new(config); + let mut linker = Linker::new( + Me { + base: self_base as *const u8, + phdrs: my_phdrs, + dyns: my_dyns, + }, + config, + ); let entry = match linker.load_program(&path, base_addr) { Ok(entry) => entry, Err(err) => { diff --git a/src/ld_so/tcb.rs b/src/ld_so/tcb.rs index 73c37709e0..7bffec76d0 100644 --- a/src/ld_so/tcb.rs +++ b/src/ld_so/tcb.rs @@ -11,7 +11,7 @@ use generic_rt::GenericTcb; use crate::{ header::sys_mman, ld_so::linker::Linker, - platform::{Dlmalloc, Pal, Sys}, + platform::{Pal, Sys}, pthread::{OsTid, Pthread}, sync::{mutex::Mutex, waitval::Waitval}, }; @@ -56,8 +56,6 @@ pub struct Tcb { pub num_copied_masters: usize, /// Pointer to dynamic linker pub linker_ptr: *const Mutex, - /// pointer to rust memory allocator structure - pub mspace: *const Mutex, /// Underlying pthread_t struct, pthread_self() returns &self.pthread pub pthread: Pthread, @@ -98,7 +96,6 @@ impl Tcb { masters_len: 0, num_copied_masters: 0, linker_ptr: ptr::null(), - mspace: ptr::null(), pthread: Pthread { waitval: Waitval::new(), flags: Default::default(), diff --git a/src/macros.rs b/src/macros.rs index d36f9c7ef7..a964963b17 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -117,6 +117,7 @@ macro_rules! trace_expr { // log::trace! but functions inside them will // not be evaluated or compiled unless enabled +#[cfg(target_os = "redox")] // currently only used in redox macro_rules! trace_log { ($($arg:tt)+) => { #[cfg(not(feature = "no_trace"))] diff --git a/src/platform/allocator/mod.rs b/src/platform/allocator/mod.rs index acdb643787..e10ddd0d94 100644 --- a/src/platform/allocator/mod.rs +++ b/src/platform/allocator/mod.rs @@ -3,8 +3,7 @@ use core::{ cell::SyncUnsafeCell, cmp, mem::align_of, - ptr::{self, copy_nonoverlapping, write_bytes}, - sync::atomic::{AtomicPtr, Ordering}, + ptr::{copy_nonoverlapping, write_bytes}, }; mod sys; @@ -17,31 +16,18 @@ pub type Dlmalloc = DlmallocCApi; #[allow(clippy::declare_interior_mutable_const)] pub const NEWALLOCATOR: Allocator = Allocator::new(); -pub struct Allocator { - inner: SyncUnsafeCell>, - pub ptr: AtomicPtr>, -} +pub struct Allocator(SyncUnsafeCell>); impl Allocator { #[allow(clippy::new_without_default)] pub const fn new() -> Self { - Allocator { - inner: SyncUnsafeCell::new(Mutex::new(Dlmalloc::new(sys::System::new()))), - ptr: AtomicPtr::new(ptr::null_mut()), - } + Self(SyncUnsafeCell::new(Mutex::new(Dlmalloc::new( + sys::System::new(), + )))) } pub fn get(&self) -> *const Mutex { - let ptr = self.ptr.load(Ordering::Acquire); - if !ptr.is_null() { - return ptr; - } - - self.inner.get() - } - - pub fn set(&self, mspace: *const Mutex) { - self.ptr.store(mspace.cast_mut(), Ordering::Release); + self.0.get() } } diff --git a/src/platform/logger.rs b/src/platform/logger.rs index a61de9a795..fd75347f68 100644 --- a/src/platform/logger.rs +++ b/src/platform/logger.rs @@ -1,36 +1,33 @@ -use core::{fmt, str::FromStr}; +use core::fmt; use crate::{c_str::CStr, io::prelude::*, sync::Mutex}; use alloc::string::{String, ToString}; -use log::{Metadata, Record}; +use log::{LevelFilter, Metadata, Record, SetLoggerError}; const DEFAULT_LOG_LEVEL: log::LevelFilter = log::LevelFilter::Info; -pub unsafe fn init() { +pub const RELIBC_LOG_ENV_VAR: &core::ffi::CStr = c"RELIBC_LOG_LEVEL"; + +pub unsafe fn init(level: LevelFilter) -> Result<(), SetLoggerError> { let mut logger = RedoxLogger::new(); - let log_env = c"RELIBC_LOG_LEVEL".as_ptr(); #[cfg(feature = "no_trace")] let mut trace_warn = false; unsafe { - if let Some(env) = CStr::from_nullable_ptr(crate::header::stdlib::getenv(log_env)) - && let Ok(level) = log::LevelFilter::from_str(env.to_str().unwrap_or("")) - { - #[cfg(feature = "no_trace")] - if level == log::LevelFilter::Trace { - trace_warn = true; - } - - logger = logger.with_output(OutputBuilder::stderr().with_filter(level).build()); + #[cfg(feature = "no_trace")] + if level == log::LevelFilter::Trace { + trace_warn = true; } + + logger = logger.with_output(OutputBuilder::stderr().with_filter(level).build()); + if let Some(name) = CStr::from_nullable_ptr(crate::platform::program_invocation_short_name) { logger = logger.with_process_name(name.to_str().unwrap_or("").to_string()); } } - if logger.enable().is_err() { - log::error!("Logger already initialized"); - } + + logger.enable()?; #[cfg(feature = "no_trace")] if trace_warn { @@ -38,6 +35,8 @@ pub unsafe fn init() { "The 'no_trace' feature is enabled but RELIBC_LOG_LEVEL=TRACE, there will be no trace logs" ); } + + Ok(()) } /// Copied from redox_log crate with some modifications, in future we might use it instead? diff --git a/src/platform/redox/epoll.rs b/src/platform/redox/epoll.rs index 4cfb41df35..fdbb8680b0 100644 --- a/src/platform/redox/epoll.rs +++ b/src/platform/redox/epoll.rs @@ -102,13 +102,12 @@ impl PalEpoll for Sys { }; let callback = || { - let res = syscall::read(epfd as usize, unsafe { + syscall::read(epfd as usize, unsafe { slice::from_raw_parts_mut( - events as *mut u8, + events.cast::(), maxevents as usize * mem::size_of::(), ) - }); - res + }) }; let bytes_read = if sigset.is_null() { @@ -126,7 +125,7 @@ impl PalEpoll for Sys { unsafe { let event_ptr = events.add(i); let target_ptr = events.add(count); - let event = *(event_ptr as *mut Event); + let event = *event_ptr.cast::(); *target_ptr = epoll_event { events: event_flags_to_epoll(event.flags), data: epoll_data { diff --git a/src/platform/redox/exec.rs b/src/platform/redox/exec.rs index 513e0ba979..012c6ac3c1 100644 --- a/src/platform/redox/exec.rs +++ b/src/platform/redox/exec.rs @@ -31,7 +31,7 @@ fn fexec_impl( interp_override: new_interp_override, } = redox_rt::proc::fexec_impl( exec_file, - &RtTcb::current().thread_fd(), + RtTcb::current().thread_fd(), redox_rt::current_proc_fd(), path, args, @@ -49,11 +49,11 @@ fn fexec_impl( // null-terminated. Violating this should therefore give the "format error" ENOEXEC. let path_cstr = CStr::from_bytes_with_nul(&path).map_err(|_| Error::new(ENOEXEC))?; - return execve( + execve( Executable::AtPath(path_cstr), ArgEnv::Parsed { args, envs }, Some(new_interp_override), - ); + ) } pub enum ArgEnv<'a> { @@ -166,7 +166,7 @@ pub fn execve( let mut args: Vec<&[u8]> = Vec::with_capacity(len); if let Some(interpreter) = &interpreter_path { - image_file = File::open(CStr::borrow(&interpreter), O_RDONLY as c_int) + image_file = File::open(CStr::borrow(interpreter), O_RDONLY as c_int) .map_err(|_| Error::new(ENOENT))?; // Push interpreter to arguments diff --git a/src/platform/redox/extra.rs b/src/platform/redox/extra.rs index da9cb0d954..71536e4d63 100644 --- a/src/platform/redox/extra.rs +++ b/src/platform/redox/extra.rs @@ -9,7 +9,7 @@ use syscall::{F_SETFD, F_SETFL, O_CLOEXEC, O_RDONLY, O_WRONLY}; #[unsafe(no_mangle)] pub unsafe extern "C" fn redox_fpath(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t { syscall::fpath(fd as usize, unsafe { - slice::from_raw_parts_mut(buf as *mut u8, count) + slice::from_raw_parts_mut(buf.cast::(), count) }) .map_err(Errno::from) .map(|l| l as ssize_t) diff --git a/src/platform/redox/libcscheme.rs b/src/platform/redox/libcscheme.rs index b4f07ccf6b..8d4863e478 100644 --- a/src/platform/redox/libcscheme.rs +++ b/src/platform/redox/libcscheme.rs @@ -1,8 +1,7 @@ -use crate::{c_str::CStr, header::stdlib::getenv, platform::types::*}; -use core::ptr; +use crate::{c_str::CStr, header::stdlib::getenv, platform::types::c_char}; use syscall::{EIO, ENOENT, Error, Result, flag::*}; -pub const LIBC_SCHEME: &'static str = "libc:"; +pub const LIBC_SCHEME: &str = "libc:"; const ENV_MAX_LEN: i32 = i32::MAX; @@ -10,8 +9,8 @@ macro_rules! env_str { ($lit:expr) => { #[allow(unused_unsafe)] { - let val_bytes = unsafe { getenv(concat!($lit, "\0").as_ptr() as *const c_char) }; - if val_bytes != ptr::null_mut() { + let val_bytes = unsafe { getenv(concat!($lit, "\0").as_ptr().cast::()) }; + if !val_bytes.is_null() { if let Ok(val_str) = unsafe { CStr::from_ptr(val_bytes) }.to_str() { Some(val_str) } else { diff --git a/src/platform/redox/libredox.rs b/src/platform/redox/libredox.rs index 166f083536..91be7a78ef 100644 --- a/src/platform/redox/libredox.rs +++ b/src/platform/redox/libredox.rs @@ -31,7 +31,7 @@ pub fn openat(dirfd: c_int, path: RedoxStr<'_>, oflag: c_int, mode: mode_t) -> R ((oflag as usize) & 0xFFFF_0000) | ((mode as usize) & 0xFFFF), )?; - if let Err(_) = c_int::try_from(usize_fd) { + if c_int::try_from(usize_fd).is_err() { let _ = redox_rt::sys::close(usize_fd); return Err(Error::new(EMFILE)); } @@ -42,7 +42,7 @@ pub fn fchmod(fd: usize, new_mode: u16) -> Result<()> { std_fs_call_wo( fd, &[], - &StdFsCallMeta::new(StdFsCallKind::Fchmod, new_mode as u64, 0), + &StdFsCallMeta::new(StdFsCallKind::Fchmod, u64::from(new_mode), 0), )?; Ok(()) } @@ -77,7 +77,7 @@ pub fn getdents(fd: usize, buf: &mut [u8], opaque: u64) -> Result { }) => (), other => { //println!("REAL GETDENTS {:?}", other); - return Ok(other?); + return other; } } @@ -87,7 +87,7 @@ pub fn getdents(fd: usize, buf: &mut [u8], opaque: u64) -> Result { let (header, name) = buf.split_at_mut(mem::size_of::()); - let bytes_read = Sys::pread(fd as c_int, name, opaque as i64)? as usize; + let bytes_read = Sys::pread(fd as c_int, name, opaque as i64)?; if bytes_read == 0 { return Ok(0); } @@ -122,14 +122,21 @@ pub unsafe fn fstat(fd: usize, buf: *mut crate::header::sys_stat::stat) -> Resul if let Some(buf) = unsafe { buf.as_mut() } { buf.st_dev = redox_buf.st_dev as dev_t; buf.st_ino = redox_buf.st_ino as ino_t; - buf.st_nlink = redox_buf.st_nlink as nlink_t; + buf.st_nlink = nlink_t::from(redox_buf.st_nlink); buf.st_mode = redox_buf.st_mode as mode_t; buf.st_uid = redox_buf.st_uid as uid_t; buf.st_gid = redox_buf.st_gid as gid_t; // TODO st_rdev buf.st_rdev = 0; buf.st_size = redox_buf.st_size as off_t; - buf.st_blksize = redox_buf.st_blksize as blksize_t; + #[cfg(target_pointer_width = "32")] + { + buf.st_blksize = redox_buf.st_blksize as blksize_t; + } + #[cfg(target_pointer_width = "64")] + { + buf.st_blksize = blksize_t::from(redox_buf.st_blksize); + } buf.st_blocks = redox_buf.st_blocks as blkcnt_t; buf.st_atim = timespec { tv_sec: redox_buf.st_atime as time_t, @@ -202,7 +209,7 @@ pub unsafe fn futimens(fd: usize, times: *const timespec) -> Result<()> { }; let redox_buf = unsafe { slice::from_raw_parts( - times.as_ptr() as *const u8, + times.as_ptr().cast::(), times.len() * mem::size_of::(), ) }; @@ -215,7 +222,7 @@ pub unsafe fn futimens(fd: usize, times: *const timespec) -> Result<()> { } pub fn clock_gettime(clock: usize, mut tp: Out) -> Result<()> { let mut redox_tp = syscall::TimeSpec::default(); - syscall::clock_gettime(clock as usize, &mut redox_tp)?; + syscall::clock_gettime(clock, &mut redox_tp)?; tp.write((&redox_tp).into()); Ok(()) } @@ -228,9 +235,8 @@ pub unsafe extern "C" fn redox_open_v1( mode: u16, ) -> RawResult { let path = unsafe { str::from_utf8_unchecked(slice::from_raw_parts(path_base, path_len)) }; - let path = match RedoxStr::new(path) { - Some(path) => path, - None => return Error::mux(Err(Error::new(EINVAL))), + let Some(path) = RedoxStr::new(path) else { + return Error::mux(Err(Error::new(EINVAL))); }; Error::mux(openat(AT_FDCWD, path, flags as c_int, mode as mode_t)) } diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index e3ced16b88..a1844ba887 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -171,7 +171,7 @@ impl Pal for Sys { let perms = (if stat.st_uid == uid { stat.st_mode >> (3 * 2) } else if stat.st_gid == gid { - stat.st_mode >> (3 * 1) + stat.st_mode >> 3 } else { stat.st_mode }) & 0o7; @@ -204,7 +204,7 @@ impl Pal for Sys { unsafe { BRK_CUR = allocated; - BRK_END = (allocated as *mut u8).add(BRK_MAX_SIZE) as *mut c_void + BRK_END = allocated.cast::().add(BRK_MAX_SIZE).cast::() }; } @@ -222,7 +222,7 @@ impl Pal for Sys { } fn chdir(path: CStr) -> Result<()> { - let path = RedoxStr::new_c(path.to_cstr()).ok_or_else(|| Errno(EINVAL))?; + let path = RedoxStr::new_c(path.to_cstr()).ok_or(Errno(EINVAL))?; path::chdir(path)?; Ok(()) } @@ -243,11 +243,11 @@ impl Pal for Sys { CLOCK_MONOTONIC => "/scheme/time/4/getres", _ => return Err(Errno(EINVAL)), }; - let timerfd = FdGuard::open(&path, syscall::O_RDONLY)?; + let timerfd = FdGuard::open(path, syscall::O_RDONLY)?; let mut redox_res = timespec::default(); let buffer = unsafe { slice::from_raw_parts_mut( - &mut redox_res as *mut _ as *mut u8, + (&raw mut redox_res).cast::(), mem::size_of::(), ) }; @@ -285,8 +285,7 @@ impl Pal for Sys { } fn exit(status: c_int) -> ! { - let _ = redox_rt::sys::posix_exit(status); - loop {} + redox_rt::sys::posix_exit(status) } unsafe fn execve(path: CStr, argv: *const *mut c_char, envp: *const *mut c_char) -> Result<()> { @@ -382,7 +381,7 @@ impl Pal for Sys { let start = start as u64 | if is_ofd { 1 << 63 } else { 0 }; let len = len as u64; - match flock.l_type as i32 { + match i32::from(flock.l_type) { F_UNLCK => { let meta = StdFsCallMeta::new(StdFsCallKind::Unlock, start, len); syscall::std_fs_call(fd as usize, &mut [], &meta)?; @@ -393,7 +392,7 @@ impl Pal for Sys { let meta = StdFsCallMeta::new( StdFsCallKind::Lock, start, - len | if flock.l_type as i32 == F_WRLCK { + len | if i32::from(flock.l_type) == F_WRLCK { 1 << 63 } else { 0 @@ -429,7 +428,7 @@ impl Pal for Sys { } let mut len = len as u64; - if flock.l_type as i32 == F_WRLCK { + if i32::from(flock.l_type) == F_WRLCK { len |= 1 << 63; } @@ -562,7 +561,7 @@ impl Pal for Sys { #[inline] unsafe fn futex_wait(addr: *mut u32, val: u32, deadline: Option<×pec>) -> Result<()> { - let deadline = deadline.map(|d| syscall::TimeSpec::from(d)); + let deadline = deadline.map(syscall::TimeSpec::from); (unsafe { redox_rt::sys::sys_futex_wait(addr, val, deadline.as_ref()) })?; Ok(()) } @@ -611,7 +610,7 @@ impl Pal for Sys { // NOTE: fn is unsafe, but this just means we can assume more things. impl is safe unsafe fn dent_reclen_offset(this_dent: &[u8], offset: usize) -> Option<(u16, u64)> { let mut header = DirentHeader::default(); - header.copy_from_slice(&this_dent.get(..size_of::())?); + header.copy_from_slice(this_dent.get(..size_of::())?); // If scheme does not send a NUL byte, this shouldn't be able to cause UB for the caller. if this_dent.get(usize::from(header.record_len) - 1) != Some(&b'\0') { @@ -665,7 +664,7 @@ impl Pal for Sys { } if found { - if !list.is_empty() && (count as usize) < list.len() { + if !list.is_empty() && count < list.len() { list.index(count).write(grp.gr_gid); } count += 1; @@ -674,7 +673,7 @@ impl Pal for Sys { grp::endgrent(); } - if !list.is_empty() && (count as usize) > list.len() { + if !list.is_empty() && count > list.len() { return Err(Errno(EINVAL)); } @@ -698,9 +697,9 @@ impl Pal for Sys { } fn getpriority(which: c_int, who: id_t) -> Result { - match redox_rt::sys::posix_getpriority(which, who as u32) { + match redox_rt::sys::posix_getpriority(which, who) { Ok(kernel_prio) => { - let posix_prio = (kernel_prio as i32 * -1) + 40 as i32; + let posix_prio = -(kernel_prio as i32) + 40_i32; Ok(posix_prio) } Err(e) => Err(Errno(e.errno)), @@ -851,7 +850,7 @@ impl Pal for Sys { if (flags & !(AT_SYMLINK_FOLLOW)) != 0 { return Err(Errno(EINVAL)); } - let newpath = RedoxStr::new_c(newpath.to_cstr()).ok_or_else(|| Errno(EINVAL))?; + let newpath = RedoxStr::new_c(newpath.to_cstr()).ok_or(Errno(EINVAL))?; // By default, we don't follow the symlink if there is one. // We only follow it if AT_SYMLINK_FOLLOW is passed in flags. @@ -992,7 +991,7 @@ impl Pal for Sys { redox_rmtp = unsafe { (&*rmtp).into() }; } match redox_rt::sys::posix_nanosleep(&redox_rqtp, &mut redox_rmtp) { - Ok(_) => Ok(()), + Ok(()) => Ok(()), Err(Error { errno: EINTR }) => { unsafe { if !rmtp.is_null() { @@ -1040,7 +1039,7 @@ impl Pal for Sys { let total_offset = offset.checked_add(length).ok_or(Errno(EFBIG))?; let mut stat: stat = unsafe { mem::zeroed() }; - unsafe { libredox::fstat(fd as usize, &mut stat)? }; + unsafe { libredox::fstat(fd as usize, &raw mut stat)? }; let st_size = stat.st_size as u64; // The difference between total_offset and the file size is the number of bytes to // allocate. So, if it's negative then the file is already large enough and we don't @@ -1129,7 +1128,7 @@ impl Pal for Sys { let redox_path = str::from_utf8(&buf[..count]) .ok() - .and_then(|x| redox_path::RedoxPath::from_absolute(x)) + .and_then(redox_path::RedoxPath::from_absolute) .ok_or(Errno(EINVAL))?; let (scheme, reference) = redox_path.as_parts().ok_or(Errno(EINVAL))?; @@ -1216,8 +1215,8 @@ impl Pal for Sys { let clamped_prio = prio.clamp(-20, 19); let kernel_prio = (20 + clamped_prio) as u32; - match redox_rt::sys::posix_setpriority(which, who as u32, kernel_prio) { - Ok(_) => Ok(()), + match redox_rt::sys::posix_setpriority(which, who, kernel_prio) { + Ok(()) => Ok(()), Err(e) => Err(Errno(e.errno)), } } @@ -1290,7 +1289,7 @@ impl Pal for Sys { } } - args[0] = &program.to_bytes(); + args[0] = program.to_bytes(); let new_file_table = child.thr_fd.dup_into_upper(b"filetable-binary")?; @@ -1606,7 +1605,7 @@ impl Pal for Sys { CLOCK_MONOTONIC => "/scheme/time/4", _ => return Err(Errno(EINVAL)), }; - let timerfd = FdGuard::open_into_upper(&path, syscall::O_RDWR)?; + let timerfd = FdGuard::open_into_upper(path, syscall::O_RDWR)?; let eventfd = FdGuard::new(Error::demux(unsafe { event::redox_event_queue_create_v1(0) })?) @@ -1627,7 +1626,7 @@ impl Pal for Sys { let mut memory_pointer: *mut timer_internal_t = ptr::null_mut(); unsafe { let result = posix_memalign( - (&mut memory_pointer as *mut *mut timer_internal_t).cast(), + (&raw mut memory_pointer).cast(), align_of::(), size_of::(), ); @@ -1653,36 +1652,44 @@ impl Pal for Sys { Ok(()) } + #[expect(clippy::not_unsafe_ptr_arg_deref)] fn timer_delete(timerid: timer_t) -> Result<()> { let timers = &mut TIMERS.lock().0; let removed = timers.remove(&timerid); if !removed { return Err(Errno(EINVAL)); } + // SAFETY: `timerid` should have already been created via `timer_create()` + // before calling `timer_delete()` so should not be NULL let timer_st = unsafe { timer_internal_t::from_raw(timerid) }; let _ = redox_rt::sys::close(timer_st.timerfd); let _ = redox_rt::sys::close(timer_st.eventfd); if !timer_st.thread.is_null() { let _ = unsafe { pthread_cancel(timer_st.thread) }; } + // SAFETY: `timerid` should have already been created via `timer_create()` + // before calling `timer_delete()` so should not be NULL unsafe { free(timerid) }; Ok(()) } + #[expect(clippy::not_unsafe_ptr_arg_deref)] fn timer_gettime(timerid: timer_t, mut value: Out) -> Result<()> { let timers = &mut TIMERS.lock().0; if !timers.contains(&timerid) { return Err(Errno(EINVAL)); } + // SAFETY: `timerid` should have already been created via `timer_create()` + // before calling `timer_delete()` so should not be NULL let timer_st = unsafe { timer_internal_t::from_raw(timerid) }; let mut now = timespec::default(); Self::clock_gettime(timer_st.clockid, Out::from_mut(&mut now))?; - if timer_st.evp.sigev_notify == SIGEV_NONE { - if timespec::subtract(&timer_st.next_wake_time.it_value, &now).is_none() { - // error here means the timer is disarmed - let _ = timer_update_wake_time(timer_st); - } + if timer_st.evp.sigev_notify == SIGEV_NONE + && timespec::subtract(&timer_st.next_wake_time.it_value, &now).is_none() + { + // error here means the timer is disarmed + let _ = timer_update_wake_time(timer_st); } let remaining = &timer_st.next_wake_time.it_value; value.write(if remaining.is_zero() { @@ -1698,6 +1705,7 @@ impl Pal for Sys { Ok(()) } + #[expect(clippy::not_unsafe_ptr_arg_deref)] fn timer_settime( timerid: timer_t, flags: c_int, @@ -1712,6 +1720,8 @@ impl Pal for Sys { if !timers.contains(&timerid) { return Err(Errno(EINVAL)); } + // SAFETY: `timerid` should have already been created via `timer_create()` + // before calling `timer_delete()` so should not be NULL let timer_st = unsafe { timer_internal_t::from_raw(timerid) }; if value.it_value.is_zero() { @@ -1747,10 +1757,10 @@ impl Pal for Sys { let mut tid = pthread_t::default(); let result = unsafe { pthread_create( - &mut tid as *mut _, + &raw mut tid, ptr::null(), timer_routine, - timerid as *mut c_void, + timerid.cast::(), ) }; if result != 0 { @@ -1804,21 +1814,19 @@ impl Pal for Sys { } match gethostname(nodename.as_slice_mut().cast_slice_to::()) { - Ok(_) => (), + Ok(()) => (), Err(_) => return Err(Errno(EIO)), } let file_path = c"/scheme/sys/uname".into(); - let mut file = match File::open(file_path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) { - Ok(ok) => ok, - Err(_) => return Err(Errno(EIO)), + let Ok(mut file) = File::open(file_path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) else { + return Err(Errno(EIO)); }; let mut lines = BufReader::new(&mut file).lines(); let mut read_line = |mut dst: Out<[u8]>| { - let mut line = match lines.next() { - Some(Ok(l)) => l, - None | Some(Err(_)) => return Err(Errno(EIO)), + let Some(Ok(mut line)) = lines.next() else { + return Err(Errno(EIO)); }; line.push('\0'); let line_slice: &[u8] = line.as_bytes(); @@ -1864,6 +1872,7 @@ impl Pal for Sys { Ok(()) } + #[expect(clippy::unnecessary_literal_unwrap, reason = "res needs refactoring")] fn waitpid(pid: pid_t, stat_loc: Option>, options: c_int) -> Result { let res = None; let mut status = 0; @@ -1962,7 +1971,7 @@ impl Sys { len: off_t, ) -> Result<(off_t, off_t)> { // let file_off = Self::lseek(fd, 0, SEEK_SET)?; - match whence as i32 { + match i32::from(whence) { SEEK_SET => { let (start, len) = if len < 0 { (start + len, -len) diff --git a/src/platform/redox/path.rs b/src/platform/redox/path.rs index 55ae546cf8..51dadb3a03 100644 --- a/src/platform/redox/path.rs +++ b/src/platform/redox/path.rs @@ -29,7 +29,7 @@ pub fn chdir(path: RedoxStr<'_>) -> Result<()> { let (redox, fd) = match path { RedoxStr::Absolute(path) => { let path = path.to_standard_canon(); - let fd = FdGuard::open_into_upper(&path.as_reference(), O_STAT); + let fd = FdGuard::open_into_upper(path.as_reference(), O_STAT); (path.into_owned(), fd) } RedoxStr::Relative(redox_reference) => { @@ -112,7 +112,7 @@ pub struct Cwd<'a> { static CWD: RwLock>> = RwLock::new(None); pub fn to_cwd_path(path: &str) -> Result { - ArrayString::from_str(&path).or(Err(Error::new(ENAMETOOLONG))) + ArrayString::from_str(path).or(Err(Error::new(ENAMETOOLONG))) } pub fn set_cwd_manual(path: CwdPath, fd: FdGuardUpper) -> Result<()> { @@ -126,7 +126,7 @@ pub fn set_cwd_manual(path: CwdPath, fd: FdGuardUpper) -> Result<()> { pub fn clone_cwd() -> Option { let _siglock = tmp_disable_signals(); - CWD.read().as_ref().map(|cwd| cwd.path.clone()) + CWD.read().as_ref().map(|cwd| cwd.path) } fn open_absolute(path: &str, flags: usize) -> Result { @@ -138,9 +138,9 @@ fn open_absolute(path: &str, flags: usize) -> Result { } // Read symlink content -fn read_link_content<'a, 'b>( +fn read_link_content<'b>( dirfd: Option<&FdGuard>, - path: &'a str, + path: &str, is_relative: bool, ) -> Result> { let resolve_flags = O_CLOEXEC | O_SYMLINK | O_RDONLY; @@ -156,7 +156,7 @@ fn read_link_content<'a, 'b>( log::trace!( "read_link_content ({:?} {:?} {}): {:?}", dirfd, - &path, + path, is_relative, fd ); @@ -180,7 +180,7 @@ fn resolve_sym_links<'a>(mut current_path_string: RedoxPath<'a>, flags: usize) - let dirname = current_path_string.dirname(); let cow: Cow<'_, str> = current_path_string.into(); let initial_res = open_absolute(&cow, flags); - log::trace!("resolve_sym_links({:?}): {:?}", &cow, initial_res); + log::trace!("resolve_sym_links({:?}): {:?}", cow, initial_res); match initial_res { Ok(fd) => return Ok(fd), Err(e) if e == Error::new(EXDEV) => { @@ -309,12 +309,21 @@ pub struct FileLock(c_int); impl FileLock { pub fn lock(fd: c_int, op: c_int) -> Result { - if op & sys_file::LOCK_SH | sys_file::LOCK_EX == 0 { - return Err(Error::new(EINVAL)); + const LOCK_SH_NB: c_int = sys_file::LOCK_SH | sys_file::LOCK_NB; + const LOCK_EX_NB: c_int = sys_file::LOCK_EX | sys_file::LOCK_NB; + const LOCK_UN_NB: c_int = sys_file::LOCK_UN | sys_file::LOCK_NB; + match op { + sys_file::LOCK_SH + | sys_file::LOCK_EX + | sys_file::LOCK_UN + | LOCK_SH_NB + | LOCK_EX_NB + | LOCK_UN_NB => { + Sys::flock(fd, op)?; + Ok(Self(fd)) + } + _ => Err(Error::new(EINVAL)), } - - Sys::flock(fd, op)?; - Ok(Self(fd)) } pub fn unlock(self) -> Result<()> { @@ -384,14 +393,14 @@ fn at_flags_to_open_flags(at_flags: c_int) -> c_int { /// # Arguments /// * `dirfd` is a directory descriptor to which `path` is resolved. /// * `path` is a relative or absolute path. Relative paths are resolved in relation to `dirfd` -/// while absolute paths skip `dirfd`. +/// while absolute paths skip `dirfd`. /// * `at_flags` constrains how `path` is resolved. /// * `oflags` are flags that are passed to open. /// /// # Constants /// `at_flags`: /// * AT_EMPTY_PATH returns the path at `dirfd` itself if `path` is empty. If `path` is not -/// empty, it's resolved w.r.t `dirfd` like normal. +/// empty, it's resolved w.r.t `dirfd` like normal. /// /// `dirfd`: /// `AT_FDCWD` is a special constant for `dirfd` that resolves `path` under the current working diff --git a/src/platform/redox/ptrace.rs b/src/platform/redox/ptrace.rs index eef280d46b..51cb764683 100644 --- a/src/platform/redox/ptrace.rs +++ b/src/platform/redox/ptrace.rs @@ -60,7 +60,7 @@ pub fn init_state() -> &'static State { if STATE.unsafe_ref().is_none() { STATE.unsafe_set(Some(State::new())); } - let state_ptr = STATE.unsafe_ref().as_ref().unwrap() as *const State; + let state_ptr = core::ptr::from_ref::(STATE.unsafe_ref().as_ref().unwrap()); &*state_ptr } } @@ -193,7 +193,7 @@ unsafe fn inner_ptrace( Ok(0) } sys_ptrace::PTRACE_GETREGS => { - let c_regs = unsafe { &mut *(data as *mut user_regs_struct) }; + let c_regs = unsafe { &mut *data.cast::() }; let mut redox_regs = syscall::IntRegisters::default(); (&mut &session.regs).read(&mut redox_regs)?; *c_regs = user_regs_struct { @@ -228,7 +228,7 @@ unsafe fn inner_ptrace( Ok(0) } sys_ptrace::PTRACE_SETREGS => { - let c_regs = unsafe { &*(data as *mut user_regs_struct) }; + let c_regs = unsafe { &*data.cast::() }; let redox_regs = syscall::IntRegisters { r15: c_regs.r15 as _, r14: c_regs.r14 as _, diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index c33fb554e2..6d29af132b 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -115,7 +115,14 @@ impl PalSignal for Sys { SigactionKind::Handled { handler: if c_act.sa_flags & crate::header::signal::SA_SIGINFO as c_int != 0 { SignalHandler { - sigaction: unsafe { core::mem::transmute(c_act.sa_handler) }, + sigaction: unsafe { + core::mem::transmute::< + core::option::Option, + core::option::Option< + unsafe extern "C" fn(i32, *const (), *mut ()), + >, + >(c_act.sa_handler) + }, } } else { SignalHandler { @@ -138,20 +145,33 @@ impl PalSignal for Sys { if let (Some(c_oact), Some(old_action)) = (c_oact, old_action) { *c_oact = match old_action.kind { SigactionKind::Ignore => sigaction { - sa_handler: unsafe { core::mem::transmute(SIG_IGN) }, + sa_handler: unsafe { + core::mem::transmute::>( + SIG_IGN, + ) + }, sa_flags: 0, sa_restorer: None, sa_mask: 0, }, SigactionKind::Default => sigaction { - sa_handler: unsafe { core::mem::transmute(SIG_DFL) }, + sa_handler: unsafe { + core::mem::transmute::>( + SIG_DFL, + ) + }, sa_flags: 0, sa_restorer: None, sa_mask: 0, }, SigactionKind::Handled { handler } => sigaction { sa_handler: if old_action.flags.contains(SigactionFlags::SIGINFO) { - unsafe { core::mem::transmute(handler.sigaction) } + unsafe { + core::mem::transmute::< + core::option::Option, + core::option::Option, + >(handler.sigaction) + } } else { unsafe { handler.handler } }, diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs index 0a3c25e2d6..c81a439f30 100644 --- a/src/platform/redox/socket.rs +++ b/src/platform/redox/socket.rs @@ -1,4 +1,4 @@ -use alloc::{borrow::Cow, vec::Vec}; +use alloc::{borrow::Cow, string::ToString, vec::Vec}; use core::{cmp, mem, ptr, slice, str}; use redox_path::RedoxStr; use redox_protocols::protocol::{FsCall, O_CLOEXEC, SocketCall}; @@ -42,16 +42,16 @@ unsafe fn bind_or_connect( return Err(Errno(EINVAL)); } - let path = match unsafe { (*address).sa_family } as c_int { + let path = match c_int::from(unsafe { (*address).sa_family }) { AF_INET => { if (address_len as usize) != mem::size_of::() { return Err(Errno(EINVAL)); } - let data = unsafe { &*(address as *const sockaddr_in) }; + let data = unsafe { &*address.cast::() }; let addr = unsafe { slice::from_raw_parts( - &data.sin_addr.s_addr as *const _ as *const u8, + (&raw const data.sin_addr.s_addr).cast::(), mem::size_of_val(&data.sin_addr.s_addr), ) }; @@ -78,7 +78,7 @@ unsafe fn bind_or_connect( } SocketCall::Connect => { // When a connect is made using AF_UNSPEC TCP and UDP need to disconnect from the default peer - format!("disconnect") + "disconnect".to_string() } _ => unreachable!(), }, @@ -101,12 +101,12 @@ pub unsafe fn bind_or_connect_into( } unsafe fn inner_af_unix(buf: &[u8], address: *mut sockaddr, address_len: *mut socklen_t) { - let data = unsafe { &mut *(address as *mut sockaddr_un) }; + let data = unsafe { &mut *address.cast::() }; data.sun_family = AF_UNIX as c_ushort; let path = unsafe { - slice::from_raw_parts_mut(&mut data.sun_path as *mut _ as *mut u8, data.sun_path.len()) + slice::from_raw_parts_mut((&raw mut data.sun_path).cast::(), data.sun_path.len()) }; let len = cmp::min(path.len(), buf.len()); @@ -142,11 +142,11 @@ unsafe fn inner_af_inet( // Make address be followed by a NUL-byte colon[0] = b'\0'; - log::trace!("address: {:?}, port: {:?}", str::from_utf8(&raw_addr), port); + log::trace!("address: {:?}, port: {:?}", str::from_utf8(raw_addr), port); let mut addr = in_addr::default(); assert_eq!( - unsafe { inet_aton(raw_addr.as_ptr() as *mut c_char, &mut addr) }, + unsafe { inet_aton(raw_addr.as_ptr() as *mut c_char, &raw mut addr) }, 1, "inet_aton might be broken, failed to parse netstack address" ); @@ -161,7 +161,7 @@ unsafe fn inner_af_inet( let len = cmp::min(unsafe { *address_len } as usize, mem::size_of_val(&ret)); unsafe { - ptr::copy_nonoverlapping(&ret as *const _ as *const u8, address as *mut u8, len); + ptr::copy_nonoverlapping((&raw const ret).cast::(), address.cast::(), len); *address_len = len as socklen_t; } } @@ -282,11 +282,11 @@ unsafe fn serialize_ancillary_data_to_stream( let fds_usize: Vec = c_fds.iter().map(|&fd| fd as usize).collect(); let fds_slice = unsafe { slice::from_raw_parts( - fds_usize.as_ptr() as *const u8, + fds_usize.as_ptr().cast::(), fds_usize.len() * mem::size_of::(), ) }; - redox_rt::sys::sys_call_wo(socket as usize, &fds_slice, CallFlags::FD, &[])?; + redox_rt::sys::sys_call_wo(socket as usize, fds_slice, CallFlags::FD, &[])?; } // Serialize to ancillary_data_stream. @@ -300,7 +300,7 @@ unsafe fn serialize_ancillary_data_to_stream( (SOL_SOCKET, SCM_CREDENTIALS) => { // Our intermediate format: data_len is 0, no data payload let data_for_stream_len = 0usize; - msg_stream.extend_from_slice(&(data_for_stream_len as usize).to_le_bytes()); + msg_stream.extend_from_slice(&data_for_stream_len.to_le_bytes()); } _ => { return Err(Errno(EOPNOTSUPP)); @@ -330,8 +330,8 @@ unsafe fn deserialize_name_from_stream( (unsafe { inner_get_name_inner( false, - mhdr.msg_name as *mut sockaddr, - &mut mhdr.msg_namelen, + mhdr.msg_name.cast::(), + &raw mut mhdr.msg_namelen, name_buffer, ) })?; @@ -380,7 +380,7 @@ unsafe fn deserialize_payload_from_stream( let bytes_to_write = cmp::min(iov.iov_len, source_bytes_remaining); if bytes_to_write > 0 { let dest_slice: &mut [u8] = - unsafe { slice::from_raw_parts_mut(iov.iov_base as *mut u8, iov.iov_len) }; + unsafe { slice::from_raw_parts_mut(iov.iov_base.cast::(), iov.iov_len) }; let source_sub_slice = &payload_data_from_stream [source_bytes_consumed..source_bytes_consumed + bytes_to_write]; @@ -448,13 +448,13 @@ unsafe fn deserialize_ancillary_data_from_stream( if cmsg_data_len_in_stream != mem::size_of::() { return Err(Errno(EINVAL)); } - let fd_count = read_num::(&cmsg_data_from_stream)?; + let fd_count = read_num::(cmsg_data_from_stream)?; let mut fds_usize = vec![0usize; fd_count]; let fds_bytes = unsafe { slice::from_raw_parts_mut( - fds_usize.as_mut_ptr() as *mut u8, + fds_usize.as_mut_ptr().cast::(), fds_usize.len() * mem::size_of::(), ) }; @@ -478,7 +478,7 @@ unsafe fn deserialize_ancillary_data_from_stream( return Err(Errno(EINVAL)); } - let pid = read_num::(&cmsg_data_from_stream)?; + let pid = read_num::(cmsg_data_from_stream)?; let uid_offset = mem::size_of::(); let uid = read_num::(&cmsg_data_from_stream[uid_offset..])?; let gid_offset = uid_offset + mem::size_of::(); @@ -486,10 +486,7 @@ unsafe fn deserialize_ancillary_data_from_stream( let cred = ucred { pid, uid, gid }; temp_posix_cmsg_data_buf.extend_from_slice(unsafe { - slice::from_raw_parts( - &cred as *const ucred as *const u8, - mem::size_of::(), - ) + slice::from_raw_parts((&raw const cred).cast::(), mem::size_of::()) }); temp_posix_cmsg_data_buf.len() } @@ -513,7 +510,7 @@ unsafe fn deserialize_ancillary_data_from_stream( unsafe { ptr::copy_nonoverlapping( temp_posix_cmsg_data_buf.as_ptr(), - data_ptr_in_user_cmsg as *mut u8, + data_ptr_in_user_cmsg.cast::(), actual_posix_cmsg_data_len, ) }; @@ -539,22 +536,23 @@ impl PalSocket for Sys { address_len: *mut socklen_t, ) -> Result { let stream = redox_rt::sys::dup(socket as usize, b"listen")?; - if address != ptr::null_mut() && address_len != ptr::null_mut() { - if let Err(err) = unsafe { Self::getpeername(stream as c_int, address, address_len) } { - let _ = redox_rt::sys::close(stream); - return Err(err); - } + if !address.is_null() + && !address_len.is_null() + && let Err(err) = unsafe { Self::getpeername(stream as c_int, address, address_len) } + { + let _ = redox_rt::sys::close(stream); + return Err(err); } Ok(stream as c_int) } unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> Result<()> { - match unsafe { (*address).sa_family } as c_int { + match c_int::from(unsafe { (*address).sa_family }) { AF_INET => { (unsafe { bind_or_connect_into(SocketCall::Bind, socket, address, address_len) })?; } AF_UNIX => { - let data = unsafe { &*(address as *const sockaddr_un) }; + let data = unsafe { &*address.cast::() }; // NOTE: It's UB to access data in given address that exceeds // the given address length. @@ -569,11 +567,15 @@ impl PalSocket for Sys { // The maximum length of the address maxlen, // The first NUL byte, if any - unsafe { strnlen(&data.sun_path as *const _, maxlen as size_t) }, + // FIXME applying clippy suggestion fails to compile + #[expect(clippy::borrow_as_ptr)] + unsafe { + strnlen(&data.sun_path as *const _, maxlen as size_t) + }, ); let addr = - unsafe { slice::from_raw_parts(&data.sun_path as *const _ as *const u8, len) }; + unsafe { slice::from_raw_parts((&raw const data.sun_path).cast::(), len) }; let path = str::from_utf8(addr).map_err(|_| Errno(EINVAL))?; log::trace!("bind(): path: {:?}", path); @@ -635,12 +637,12 @@ impl PalSocket for Sys { address: *const sockaddr, address_len: socklen_t, ) -> Result { - match unsafe { (*address).sa_family } as c_int { + match c_int::from(unsafe { (*address).sa_family }) { AF_INET => unsafe { bind_or_connect_into(SocketCall::Connect, socket, address, address_len) }, AF_UNIX => { - let data = unsafe { &*(address as *const sockaddr_un) }; + let data = unsafe { &*address.cast::() }; // NOTE: It's UB to access data in given address that exceeds // the given address length. @@ -655,11 +657,15 @@ impl PalSocket for Sys { // The maximum length of the address maxlen, // The first NUL byte, if any - unsafe { strnlen(&data.sun_path as *const _, maxlen as size_t) }, + // FIXME applying clippy suggestion fails to compile + #[expect(clippy::borrow_as_ptr)] + unsafe { + strnlen(&data.sun_path as *const _, maxlen as size_t) + }, ); let addr = - unsafe { slice::from_raw_parts(&data.sun_path as *const _ as *const u8, len) }; + unsafe { slice::from_raw_parts((&raw const data.sun_path).cast::(), len) }; let path = str::from_utf8(addr).map_err(|_| Errno(EINVAL))?; log::trace!("bind(): path: {:?}", path); @@ -743,11 +749,12 @@ impl PalSocket for Sys { return Err(Errno(EINVAL)); } - Ok(unsafe { &mut *(option_value as *mut c_int) }) + Ok(unsafe { &mut *option_value.cast::() }) }; - match level { - SOL_SOCKET => match option_name { + // TODO convert back to match when we support more levels + if level == SOL_SOCKET { + match option_name { SO_DOMAIN => { let option = option_c_int()?; *option = socket_domain_type(socket)?.0; @@ -770,7 +777,7 @@ impl PalSocket for Sys { _ => { let metadata = [SocketCall::GetSockOpt as u64, option_name as u64]; let payload = - unsafe { slice::from_raw_parts_mut(option_value as *mut u8, option_len) }; + unsafe { slice::from_raw_parts_mut(option_value.cast::(), option_len) }; let call_flags = CallFlags::empty(); unsafe { *option_len_ptr = redox_rt::sys::sys_call_ro( @@ -782,8 +789,7 @@ impl PalSocket for Sys { } return Ok(()); } - }, - _ => (), + } } todo_skip!( @@ -813,7 +819,7 @@ impl PalSocket for Sys { ) -> Result { if address.is_null() && flags == 0 { Self::read(socket, unsafe { - slice::from_raw_parts_mut(buf as *mut u8, len) + slice::from_raw_parts_mut(buf.cast::(), len) }) } else { // Convert to recvmsg @@ -822,23 +828,23 @@ impl PalSocket for Sys { iov_len: len, }; let mut msg = msghdr { - msg_name: address as *mut c_void, + msg_name: address.cast::(), msg_namelen: if !address_len.is_null() { unsafe { *address_len } } else { 0 }, - msg_iov: &mut iov, + msg_iov: &raw mut iov, msg_iovlen: 1, msg_control: ptr::null_mut(), msg_controllen: 0, msg_flags: 0, }; - let count = unsafe { Self::recvmsg(socket, &mut msg, flags) }?; + let count = unsafe { Self::recvmsg(socket, &raw mut msg, flags) }?; if !address_len.is_null() { unsafe { *address_len = msg.msg_namelen }; } - return Ok(count); + Ok(count) } } @@ -846,11 +852,11 @@ impl PalSocket for Sys { if msg.is_null() { return Err(Errno(EINVAL)); } - let mut mhdr = unsafe { &mut *msg }; + let mhdr = unsafe { &mut *msg }; let iovs_slice: &[iovec] = if mhdr.msg_iov.is_null() || mhdr.msg_iovlen == 0 { &[] } else { - unsafe { slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen as usize) } + unsafe { slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen) } }; let whole_iov_size: usize = iovs_slice.iter().map(|iov| iov.iov_len).sum(); @@ -867,7 +873,7 @@ impl PalSocket for Sys { + mem::size_of::() // payload_len + whole_iov_size // payload_data_buffer + mem::size_of::() // control_len - + mhdr.msg_controllen as usize // ancillary_stream_buffer + + mhdr.msg_controllen // ancillary_stream_buffer }; msg_stream .try_reserve_exact(expected_stream_size) @@ -883,7 +889,7 @@ impl PalSocket for Sys { .copy_from_slice(&(whole_iov_size).to_le_bytes()); cursor += mem::size_of::(); msg_stream[cursor..cursor + mem::size_of::()] - .copy_from_slice(&(mhdr.msg_controllen as usize).to_le_bytes()); + .copy_from_slice(&mhdr.msg_controllen.to_le_bytes()); // Read the message stream. let metadata = [SocketCall::RecvMsg as u64, flags as u64]; @@ -897,12 +903,12 @@ impl PalSocket for Sys { mhdr.msg_flags = 0; // Read sender name. - (unsafe { deserialize_name_from_stream(&mut mhdr, &msg_stream, &mut cursor) })?; + (unsafe { deserialize_name_from_stream(mhdr, &msg_stream, &mut cursor) })?; // Read payload data. let actual_payload_bytes_written_to_iov = unsafe { deserialize_payload_from_stream( - &mut mhdr, + mhdr, &msg_stream, iovs_slice, whole_iov_size, @@ -921,7 +927,7 @@ impl PalSocket for Sys { socket, &msg_stream, &mut cursor, - cmsg_space_provided_by_user as usize, + cmsg_space_provided_by_user, flags, ) })?; @@ -943,7 +949,7 @@ impl PalSocket for Sys { let iovs_slice: &[iovec] = if mhdr.msg_iov.is_null() || mhdr.msg_iovlen == 0 { &[] } else { - unsafe { slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen as usize) } + unsafe { slice::from_raw_parts(mhdr.msg_iov, mhdr.msg_iovlen) } }; let mut msg_stream: Vec = Vec::new(); @@ -952,7 +958,7 @@ impl PalSocket for Sys { .try_reserve_exact( mem::size_of::() // payload_len + whole_iov_size // payload_data_buffer - + mhdr.msg_controllen as usize, // ancillary_stream_buffer + + mhdr.msg_controllen, // ancillary_stream_buffer ) .map_err(|_| Errno(ENOMEM))?; @@ -960,7 +966,7 @@ impl PalSocket for Sys { let mut actual_payload_bytes_serialized = 0; if !mhdr.msg_iov.is_null() && mhdr.msg_iovlen > 0 { actual_payload_bytes_serialized = unsafe { - serialize_payload_to_stream(&mut msg_stream, &iovs_slice, whole_iov_size) + serialize_payload_to_stream(&mut msg_stream, iovs_slice, whole_iov_size) }?; } // Process Control Messages from msghdr and serialize them. @@ -995,30 +1001,30 @@ impl PalSocket for Sys { if flags != 0 { // Convert to sendmsg let mut iov = iovec { - iov_base: buf as *mut c_void, + iov_base: buf.cast_mut(), iov_len: len, }; let msg = msghdr { msg_name: dest_addr as *mut c_void, msg_namelen: dest_len, - msg_iov: &mut iov, + msg_iov: &raw mut iov, msg_iovlen: 1, msg_control: ptr::null_mut(), msg_controllen: 0, msg_flags: 0, }; - return unsafe { Self::sendmsg(socket, &msg, flags) }; + return unsafe { Self::sendmsg(socket, &raw const msg, flags) }; } - if dest_addr == ptr::null() || dest_len == 0 { + if dest_addr.is_null() || dest_len == 0 { Self::write(socket, unsafe { - slice::from_raw_parts(buf as *const u8, len) + slice::from_raw_parts(buf.cast::(), len) }) } else { let fd = FdGuard::new(unsafe { bind_or_connect(SocketCall::Connect, socket, dest_addr, dest_len) }?); Self::write(fd.as_c_fd().unwrap(), unsafe { - slice::from_raw_parts(buf as *const u8, len) + slice::from_raw_parts(buf.cast::(), len) }) } } @@ -1039,7 +1045,7 @@ impl PalSocket for Sys { return Err(Errno(EINVAL)); } - let timeval = unsafe { &*(option_value as *const timeval) }; + let timeval = unsafe { &*option_value.cast::() }; let fd = FdGuard::new(redox_rt::sys::dup(socket as usize, timeout_name)?); @@ -1048,7 +1054,7 @@ impl PalSocket for Sys { }; let timespec = syscall::TimeSpec { - tv_sec: timeval.tv_sec as i64, + tv_sec: timeval.tv_sec, tv_nsec, }; @@ -1056,8 +1062,9 @@ impl PalSocket for Sys { Ok(()) }; - match level { - SOL_SOCKET => match option_name { + // TODO convert back to match when we support more levels + if level == SOL_SOCKET { + match option_name { SO_RCVTIMEO => return set_timeout(b"read_timeout"), SO_SNDTIMEO => return set_timeout(b"write_timeout"), _ => { @@ -1074,8 +1081,7 @@ impl PalSocket for Sys { )?; return Ok(()); } - }, - _ => (), + } } todo_skip!( @@ -1183,7 +1189,7 @@ impl NumFromBytes for i32 { buffer .get(..mem::size_of::()) .and_then(|slice| slice.try_into().ok()) - .ok_or_else(|| Errno(EFAULT))?, + .ok_or(Errno(EFAULT))?, )) } } @@ -1193,7 +1199,7 @@ impl NumFromBytes for usize { buffer .get(..mem::size_of::()) .and_then(|slice| slice.try_into().ok()) - .ok_or_else(|| Errno(EFAULT))?, + .ok_or(Errno(EFAULT))?, )) } } diff --git a/src/platform/redox/timer.rs b/src/platform/redox/timer.rs index 585ab0aa42..af9d34166b 100644 --- a/src/platform/redox/timer.rs +++ b/src/platform/redox/timer.rs @@ -70,16 +70,15 @@ pub extern "C" fn timer_routine(arg: *mut c_void) -> *mut c_void { if let Some(fun) = timer_st.evp.sigev_notify_function { fun(timer_st.evp.sigev_value); } - } else if timer_st.evp.sigev_notify == SIGEV_SIGNAL { - if Sys::sigqueue( + } else if timer_st.evp.sigev_notify == SIGEV_SIGNAL + && Sys::sigqueue( timer_st.process_pid, timer_st.evp.sigev_signo as _, timer_st.evp.sigev_value, ) .is_err() - { - break; - } + { + break; } } @@ -107,7 +106,7 @@ fn timer_next_event(timer_st: &mut timer_internal_t) -> Result<()> { syscall::TimeSpec::from(&timer_st.next_wake_time.it_value) }; - let bytes_written = redox_rt::sys::posix_write(timer_st.timerfd, &*buf_to_write)?; + let bytes_written = redox_rt::sys::posix_write(timer_st.timerfd, &buf_to_write)?; if bytes_written < size_of::() { return Err(Errno(EIO)); } diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs index 970c92bfa4..a3592eacc6 100644 --- a/src/pthread/mod.rs +++ b/src/pthread/mod.rs @@ -173,7 +173,6 @@ pub(crate) unsafe fn create( new_tcb.masters_ptr = current_tcb.masters_ptr; new_tcb.masters_len = current_tcb.masters_len; new_tcb.linker_ptr = current_tcb.linker_ptr; - new_tcb.mspace = current_tcb.mspace; let stack_end = unsafe { stack_base.add(stack_size) }; let mut stack = stack_end.cast::(); diff --git a/src/start.rs b/src/start.rs index 59f8299dff..8ac8f546a6 100644 --- a/src/start.rs +++ b/src/start.rs @@ -1,14 +1,13 @@ //! Startup code. -use alloc::{boxed::Box, vec::Vec}; -use core::{intrinsics, ptr}; +use alloc::vec::Vec; +use core::{intrinsics, ptr, str::FromStr}; use crate::{ - ALLOCATOR, + c_str::CStr, header::{libgen, stdio, stdlib}, - ld_so::{self, linker::Linker}, - platform::{self, Pal, Sys, get_auxvs, types::*}, - sync::mutex::Mutex, + ld_so::{self}, + platform::{self, Pal, Sys, get_auxvs, logger::RELIBC_LOG_ENV_VAR, types::*}, }; #[repr(C)] @@ -89,26 +88,9 @@ static mut INIT_COMPLETE: bool = false; #[unsafe(no_mangle)] static mut __relibc_init_environ: *mut *mut c_char = ptr::null_mut(); -fn alloc_init() { - unsafe { - if INIT_COMPLETE { - return; - } - } - unsafe { - if let Some(tcb) = ld_so::tcb::Tcb::current() - && !tcb.mspace.is_null() - { - ALLOCATOR.set(tcb.mspace); - } - } -} - extern "C" fn init_array() { // The thing is that we cannot guarantee if // init_array runs first or if relibc_start runs first - // Still whoever gets to run first must initialize rust - // memory allocator before doing anything else. unsafe { if INIT_COMPLETE { @@ -116,15 +98,14 @@ extern "C" fn init_array() { } } - alloc_init(); - io_init(); - unsafe { if platform::environ.is_null() { platform::environ = __relibc_init_environ; } } + io_init(); + unsafe { crate::pthread::init(); INIT_COMPLETE = true @@ -203,26 +184,14 @@ pub unsafe extern "C" fn relibc_start_v1( redox_rt::TLS_ACTIVATED.store(true, core::sync::atomic::Ordering::Relaxed); } - // Set up the right allocator... - // if any memory rust based memory allocation happen before this step .. we are doomed. - alloc_init(); - - if let Some(tcb) = unsafe { ld_so::tcb::Tcb::current() } { - // Update TCB mspace - if tcb.mspace.is_null() { - tcb.mspace = ALLOCATOR.get(); - } - - // Set linker pointer if necessary - if tcb.linker_ptr.is_null() { - //TODO: get ld path - let linker = Linker::new(ld_so::linker::Config::default()); - //TODO: load root object - tcb.linker_ptr = Box::into_raw(Box::new(Mutex::new(linker))); - } + let is_dynamically_linked = if let Some(tcb) = unsafe { ld_so::tcb::Tcb::current() } { #[cfg(target_os = "redox")] redox_rt::signal::setup_sighandler(&tcb.os_specific, true); - } + + !tcb.linker_ptr.is_null() + } else { + false + }; // Set up argc and argv let argc = sp.argc; @@ -249,9 +218,19 @@ pub unsafe extern "C" fn relibc_start_v1( } let auxvs = unsafe { get_auxvs(sp.auxv().cast()) }; - unsafe { crate::platform::init(auxvs) }; - init_array(); - unsafe { crate::platform::logger::init() }; + if !is_dynamically_linked { + unsafe { crate::platform::init(auxvs) }; + init_array(); + } + + if let Some(env) = unsafe { + CStr::from_nullable_ptr(crate::header::stdlib::getenv(RELIBC_LOG_ENV_VAR.as_ptr())) + } && let Ok(level) = log::LevelFilter::from_str(env.to_str().unwrap_or("")) + && let Err(_) = unsafe { crate::platform::logger::init(level) } + && !is_dynamically_linked + { + log::error!("Logger has already been initialised"); + } // Run preinit array { diff --git a/tests/Makefile b/tests/Makefile index 46e38becfc..9709a28a0c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -44,7 +44,8 @@ run-once: $(BUILD)/bins_verify/relibc-tests $(BUILD)/$(TESTBIN) support_build $(BUILD)/bins_verify/relibc-tests: src/main.rs mkdir -p $(BUILD)/bins_verify RUSTFLAGS="-C target-feature=-crt-static" $(CARGO_TEST) build --release --bin relibc-tests \ - --artifact-dir $(BUILD)/bins_verify --target-dir $(BUILD)/target -Z unstable-options + --artifact-dir $(BUILD)/bins_verify --target-dir $(BUILD)/target -Z unstable-options \ + --target $(TARGET) rm -rf $(BUILD)/target $(BUILD)/Makefile: Makefile.run.mk @@ -112,7 +113,7 @@ STATIC_FLAGS+=\ ifeq ($(IS_REDOX),0) DYNAMIC_FLAGS+=\ - -Wl,-dynamic-linker=$(SYSROOT_TARGET)/$(LD_SO_PATH) \ + -Wl,-dynamic-linker=$(SYSROOT_TARGET)/lib/$(LD_SONAME) \ -Wl,-rpath=$(SYSROOT_TARGET)/lib:\$$ORIGIN \ -L $(SYSROOT)/lib \ -lc \ diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk index 01442a8a00..fe5d955bca 100644 --- a/tests/Makefile.tests.mk +++ b/tests/Makefile.tests.mk @@ -5,8 +5,6 @@ FAILING_TESTS= else # Wrong modified time FAILING_TESTS := futimens -# Crash, mmap issue -FAILING_TESTS += malloc/usable_size # Not a FIFO FAILING_TESTS += mkfifo # Waitpid had EINTR @@ -72,6 +70,7 @@ EXPECT_NAMES=\ locale/duplocale \ locale/newlocale \ locale/setlocale \ + malloc/usable_size \ math \ regex \ semaphore/lock \ diff --git a/tests/expected/malloc/usable_size.stdout b/tests/expected/malloc/usable_size.stdout index 4188b67b66..8a214d652d 100644 --- a/tests/expected/malloc/usable_size.stdout +++ b/tests/expected/malloc/usable_size.stdout @@ -1,2 +1,2 @@ malloc: 27 bytes -malloc_usable_size: 48 bytes +malloc_usable_size: 40 bytes diff --git a/tests/unistd/alarm_fn.c b/tests/unistd/alarm_fn.c index 6d1135655e..f2077f21db 100644 --- a/tests/unistd/alarm_fn.c +++ b/tests/unistd/alarm_fn.c @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include #include "test_helpers.h" +#include +#include +#include +#include +#include static sigjmp_buf jmpenv; @@ -15,6 +15,7 @@ void alarm_handler(int sig) { int main() { struct sigaction sa; + sa.sa_flags = 0; sa.sa_handler = alarm_handler; sigemptyset(&sa.sa_mask); @@ -27,7 +28,7 @@ int main() { } alarm(1); - sleep(5); + sleep(5); assert(0); // unreachable -} \ No newline at end of file +}