Merge branch 'linking_cleanups' into 'master'

Couple of linking related cleanups

Closes #211

See merge request redox-os/relibc!1235
This commit is contained in:
Jeremy Soller
2026-04-28 10:15:21 -06:00
9 changed files with 13 additions and 199 deletions
+5 -6
View File
@@ -80,7 +80,7 @@ libs: \
$(BUILD)/$(PROFILE)/crt0.o \
$(BUILD)/$(PROFILE)/crti.o \
$(BUILD)/$(PROFILE)/crtn.o \
$(BUILD)/$(PROFILE)/ld_so
$(BUILD)/$(PROFILE)/ld.so
install-libs: headers libs
mkdir -pv "$(DESTDIR)/lib"
@@ -91,7 +91,7 @@ install-libs: headers libs
ln -vnfs crt0.o "$(DESTDIR)/lib/crt1.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)"
cp -v "$(BUILD)/$(PROFILE)/ld.so" "$(DESTDIR)/$(LD_SO_PATH)"
ifeq ($(USE_RUST_LIBM),)
cp -v "$(BUILD)/openlibm/libopenlibm.a" "$(DESTDIR)/lib/libm.a"
endif
@@ -132,21 +132,20 @@ test-once: sysroot/$(TARGET)
$(MAKE) -C tests run-once TESTBIN=$(TESTBIN)
$(BUILD)/$(PROFILE)/libc.so: $(BUILD)/$(PROFILE)/librelibc.a $(BUILD)/openlibm/libopenlibm.a
$(BUILD)/$(PROFILE)/libc.so: $(BUILD)/$(PROFILE)/libc.a
$(CC) -nostdlib \
-shared \
-Wl,--gc-sections \
-Wl,-z,pack-relative-relocs \
-Wl,--sort-common \
-Wl,--allow-multiple-definition \
-Wl,--whole-archive $^ -Wl,--no-whole-archive \
-Wl,-soname,libc.so.6 \
$(LINKFLAGS) \
-o $@
$(BUILD)/$(PROFILE)/ld_so: $(BUILD)/$(PROFILE)/ld_so.o $(BUILD)/$(PROFILE)/crti.o $(BUILD)/$(PROFILE)/libc.a $(BUILD)/$(PROFILE)/crtn.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 --allow-multiple-definition --gc-sections $^ -o $@
$(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"
+1 -7
View File
@@ -2,15 +2,9 @@ extern crate cc;
use std::{env, fs};
fn get_target() -> String {
env::var("TARGET").unwrap_or(
option_env!("TARGET").map_or("x86_64-unknown-redox".to_string(), |x| x.to_string()),
)
}
fn main() {
let _crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
let target = get_target();
let target = env::var("TARGET").unwrap();
println!("cargo:rerun-if-changed=src/c");
-4
View File
@@ -4,9 +4,5 @@ version = "0.1.0"
authors = ["jD91mZM2 <me@krake.one>"]
edition = "2024"
[lib]
name = "crti"
crate-type = ["staticlib"]
[lints]
workspace = true
+1 -86
View File
@@ -1,88 +1,3 @@
//! crti
#![no_std]
#![feature(linkage)]
#[cfg(not(target_arch = "riscv64"))]
use core::arch::global_asm;
#[cfg(target_arch = "x86")]
global_asm!(
r#"
.section .init
.global _init
_init:
push ebp
mov ebp, esp
// Created a new stack frame and updated the stack pointer
// Body will be filled in by gcc and ended by crtn.o
.section .fini
.global _fini
_fini:
push ebp
mov ebp, esp
// Created a new stack frame and updated the stack pointer
// Body will be filled in by gcc and ended by crtn.o
"#
);
// https://wiki.osdev.org/Creating_a_C_Library#crtbegin.o.2C_crtend.o.2C_crti.o.2C_and_crtn.o
#[cfg(target_arch = "x86_64")]
global_asm!(
r#"
.section .init
.global _init
_init:
push rbp
mov rbp, rsp
// Created a new stack frame and updated the stack pointer
// Body will be filled in by gcc and ended by crtn.o
.section .fini
.global _fini
_fini:
push rbp
mov rbp, rsp
// Created a new stack frame and updated the stack pointer
// Body will be filled in by gcc and ended by crtn.o
"#
);
// https://git.musl-libc.org/cgit/musl/tree/crt/aarch64/crti.s
#[cfg(target_arch = "aarch64")]
global_asm!(
r#"
.section .init
.global _init
.type _init,%function
_init:
stp x29,x30,[sp,-16]!
mov x29,sp
// stp: "stores two doublewords from the first and second argument to memory addressed by addr"
// Body will be filled in by gcc and ended by crtn.o
.section .fini
.global _fini
.type _fini,%function
_fini:
stp x29,x30,[sp,-16]!
mov x29,sp
// stp: "stores two doublewords from the first and second argument to memory addressed by addr"
// Body will be filled in by gcc and ended by crtn.o
"#
);
// risc-v has no _init / _fini functions; it exclusively uses init/fini arrays
#[linkage = "weak"]
#[unsafe(no_mangle)]
extern "C" fn relibc_panic(_pi: &::core::panic::PanicInfo) -> ! {
loop {}
}
#[panic_handler]
#[linkage = "weak"]
pub unsafe fn rust_begin_unwind(pi: &::core::panic::PanicInfo) -> ! {
relibc_panic(pi)
}
// we don't support _init/_fini functions, only init/fini arrays
-4
View File
@@ -4,9 +4,5 @@ version = "0.1.0"
authors = ["jD91mZM2 <me@krake.one>"]
edition = "2024"
[lib]
name = "crtn"
crate-type = ["staticlib"]
[lints]
workspace = true
+1 -72
View File
@@ -1,74 +1,3 @@
//! crti
#![no_std]
#![feature(linkage)]
#[cfg(not(target_arch = "riscv64"))]
use core::arch::global_asm;
#[cfg(target_arch = "x86")]
global_asm!(
r#"
.section .init
// This happens after crti.o and gcc has inserted code
// Pop the stack frame
pop ebp
ret
.section .fini
// This happens after crti.o and gcc has inserted code
// Pop the stack frame
pop ebp
ret
"#
);
// https://wiki.osdev.org/Creating_a_C_Library#crtbegin.o.2C_crtend.o.2C_crti.o.2C_and_crtn.o
#[cfg(target_arch = "x86_64")]
global_asm!(
r#"
.section .init
// This happens after crti.o and gcc has inserted code
// Pop the stack frame
pop rbp
ret
.section .fini
// This happens after crti.o and gcc has inserted code
// Pop the stack frame
pop rbp
ret
"#
);
// https://git.musl-libc.org/cgit/musl/tree/crt/aarch64/crtn.s
#[cfg(target_arch = "aarch64")]
global_asm!(
r#"
.section .init
// This happens after crti.o and gcc has inserted code
// ldp: "loads two doublewords from memory addressed by the third argument to the first and second"
ldp x29,x30,[sp],#16
ret
.section .fini
// This happens after crti.o and gcc has inserted code
// ldp: "loads two doublewords from memory addressed by the third argument to the first and second"
ldp x29,x30,[sp],#16
ret
"#
);
// risc-v has no _init / _fini functions; it exclusively uses init/fini arrays
#[linkage = "weak"]
#[unsafe(no_mangle)]
extern "C" fn relibc_panic(_pi: &::core::panic::PanicInfo) -> ! {
loop {}
}
#[panic_handler]
#[linkage = "weak"]
pub unsafe fn rust_begin_unwind(pi: &::core::panic::PanicInfo) -> ! {
relibc_panic(pi)
}
// we don't support _init/_fini functions, only init/fini arrays
-7
View File
@@ -355,8 +355,6 @@ pub unsafe extern "C" fn exit(status: c_int) -> ! {
unsafe extern "C" {
static __fini_array_start: extern "C" fn();
static __fini_array_end: extern "C" fn();
fn _fini();
}
for i in (0..unsafe { ATEXIT_FUNCS.unsafe_ref().len() }).rev() {
@@ -373,11 +371,6 @@ pub unsafe extern "C" fn exit(status: c_int) -> ! {
(unsafe { *f })();
}
#[cfg(not(target_arch = "riscv64"))] // risc-v uses arrays exclusively
{
unsafe { _fini() };
}
unsafe { ld_so::fini() };
unsafe { crate::pthread::terminate_from_main_thread() };
+1 -1
View File
@@ -38,7 +38,7 @@ static mut STATIC_TCB_MASTER: Master = Master {
};
#[inline(never)]
pub fn static_init(
fn static_init(
sp: &'static Stack,
#[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuardUpper,
) {
+4 -12
View File
@@ -85,7 +85,7 @@ pub unsafe fn relibc_verify_host() {
#[used]
static INIT_ARRAY: [extern "C" fn(); 1] = [init_array];
static mut init_complete: bool = false;
static mut INIT_COMPLETE: bool = false;
#[used]
#[unsafe(no_mangle)]
@@ -93,7 +93,7 @@ static mut __relibc_init_environ: *mut *mut c_char = ptr::null_mut();
fn alloc_init() {
unsafe {
if init_complete {
if INIT_COMPLETE {
return;
}
}
@@ -113,7 +113,7 @@ extern "C" fn init_array() {
// memory allocator before doing anything else.
unsafe {
if init_complete {
if INIT_COMPLETE {
return;
}
}
@@ -129,7 +129,7 @@ extern "C" fn init_array() {
unsafe {
crate::pthread::init();
init_complete = true
INIT_COMPLETE = true
}
}
@@ -158,8 +158,6 @@ pub unsafe extern "C" fn relibc_start_v1(
static __preinit_array_end: extern "C" fn();
static __init_array_start: extern "C" fn();
static __init_array_end: extern "C" fn();
fn _init();
}
// Ensure correct host system before executing more system calls
@@ -244,12 +242,6 @@ pub unsafe extern "C" fn relibc_start_v1(
}
}
// Call init section
#[cfg(not(target_arch = "riscv64"))] // risc-v uses arrays exclusively
{
unsafe { _init() };
}
// Run init array
{
let mut f = unsafe { &__init_array_start } as *const _;