From d234e81fc9cd7e24be85d44e5fb41288eb31b6bf Mon Sep 17 00:00:00 2001 From: Anhad Singh Date: Tue, 17 Feb 2026 00:15:10 +1100 Subject: [PATCH] fix(ld.so): debug build Signed-off-by: Anhad Singh --- Makefile | 4 ++-- src/ld_so/start.rs | 53 +++++++++++++++++++++++++++------------------ src/platform/mod.rs | 6 ++--- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 2bb04c48c1..bdb822d45c 100644 --- a/Makefile +++ b/Makefile @@ -149,7 +149,7 @@ $(BUILD)/debug/libc.a: $(BUILD)/debug/librelibc.a $(BUILD)/openlibm/libopenlibm. $(AR) -M < "$@.mri" $(BUILD)/debug/librelibc.a: $(SRC) - $(CARGO) rustc $(CARGOFLAGS) -- --emit link=$@ -g -C debug-assertions=no -C opt-level=2 $(RUSTCFLAGS) + $(CARGO) rustc $(CARGOFLAGS) -- --emit link=$@ -g -C debug-assertions=no $(RUSTCFLAGS) ./renamesyms.sh "$@" "$(BUILD)/debug/deps/" ./stripcore.sh "$@" touch $@ @@ -214,6 +214,6 @@ $(BUILD)/openlibm: openlibm mv $@.partial $@ touch $@ -$(BUILD)/openlibm/libopenlibm.a: $(BUILD)/openlibm $(BUILD)/release/librelibc.a +$(BUILD)/openlibm/libopenlibm.a: $(BUILD)/openlibm $(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/" diff --git a/src/ld_so/start.rs b/src/ld_so/start.rs index 72eb54096b..25d4fccc1c 100644 --- a/src/ld_so/start.rs +++ b/src/ld_so/start.rs @@ -168,6 +168,14 @@ pub unsafe extern "C" fn relibc_ld_so_start( ld_entry: usize, dynamic: *const Dyn, ) -> usize { + // Relocate ourselves. + // + // This function is very delicate as it must **not** contain relocations itself. References to + // external symbols **cannot** be made until `__relibc_ld_stage2()` so, this function might not + // be very elegant. + // + // At this stage the TCB is not setup either so `expect_notls` must be used instead of `expect` + // and `unwrap`. let mut at_phdr = None; let mut at_phnum = None; let mut at_phent = None; @@ -184,13 +192,13 @@ pub unsafe extern "C" fn relibc_ld_so_start( } } - let at_phdr = at_phdr.unwrap(); - let at_phnum = at_phnum.expect("`AT_PHNUM` must be present if `AT_PHDR` is"); - let at_phent = at_phent.expect("`AT_PHENT` must be present if `AT_PHDR` is"); + let at_phdr = at_phdr.expect_notls("`AT_PHDR` must be present"); + let at_phnum = at_phnum.expect_notls("`AT_PHNUM` must be present if `AT_PHDR` is"); + let at_phent = at_phent.expect_notls("`AT_PHENT` must be present if `AT_PHDR` is"); assert!(!at_phdr.is_null() && at_phnum != 0 && at_phent == size_of::()); let phdrs = unsafe { slice::from_raw_parts(at_phdr, at_phnum) }; - let at_entry = at_entry.unwrap(); + let at_entry = at_entry.expect_notls("`AT_ENTRY` must be present"); let at_base = at_base.unwrap_or_default(); let self_base = if at_base != 0 { @@ -244,32 +252,34 @@ pub unsafe extern "C" fn relibc_ld_so_start( base_addr: usize, ) -> &'a [T] { if let Some(ptr) = ptr { - let len = len.expect("dynamic entry was present without it's corresponding size"); + let len = len.expect_notls("dynamic entry was present without it's corresponding size"); unsafe { core::slice::from_raw_parts(ptr.byte_add(base_addr), len) } } else { - assert!(len.is_none()); &[] } } - for reloc in unsafe { get_array::(rela_ptr, rela_len, self_base) } - .iter() - .map(Relocation::from) - .chain( - unsafe { get_array::(rel_ptr, rel_len, self_base) } - .iter() - .map(Relocation::from), - ) + fn do_relocs<'a, T>(relocs: &'a [T], self_base: usize) + where + Relocation: From<&'a T>, { - let ptr = (reloc.offset + self_base) as *mut usize; - match reloc.kind { - RelocationKind::RELATIVE => { - unsafe { ptr.write(self_base + reloc.addend.unwrap_or_default()) }; + for reloc in relocs { + let reloc: Relocation = reloc.into(); + let ptr = (reloc.offset + self_base) as *mut usize; + match reloc.kind { + RelocationKind::RELATIVE => { + unsafe { *ptr = self_base + reloc.addend.unwrap_or_default() }; + } + _ => {} } - _ => {} } } + let rela = unsafe { get_array::(rela_ptr, rela_len, self_base) }; + let rel = unsafe { get_array::(rel_ptr, rel_len, self_base) }; + do_relocs(rela, self_base); + do_relocs(rel, self_base); + unsafe { let relr = get_array(relr_ptr, relr_len, self_base); apply_relr(self_base as *const u8, relr); @@ -293,10 +303,11 @@ pub unsafe extern "C" fn relibc_ld_so_start( } } - stage2(sp, self_base, is_manual, base_addr) + __relibc_ld_stage2(sp, self_base, is_manual, base_addr) } -fn stage2( +#[unsafe(no_mangle)] +fn __relibc_ld_stage2( sp: &'static mut Stack, self_base: usize, is_manual: bool, diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 19792ba194..c4250cfbd8 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -287,11 +287,11 @@ pub unsafe fn auxv_iter<'a>(ptr: *const usize) -> impl Iterator Option { unsafe { - if self.0.read() == self::auxv_defs::AT_NULL { + if *self.0 == self::auxv_defs::AT_NULL { return None; } - let kind = self.0.read(); - let value = self.0.add(1).read(); + let kind = *self.0; + let value = *self.0.add(1); self.0 = self.0.add(2); Some([kind, value])