fix(ld): make environ preemptable

Signed-off-by: Anhad Singh <andypython@protonmail.com>
This commit is contained in:
Anhad Singh
2026-07-15 22:40:29 +10:00
parent a6cda1cdb6
commit 260bccbd3c
5 changed files with 32 additions and 23 deletions
+2
View File
@@ -1,4 +1,6 @@
{
environ;
stdin;
stdout;
stderr;
+3 -1
View File
@@ -563,7 +563,9 @@ impl Linker {
pub fn fini(&self) {
for obj in self.objects.values() {
obj.run_fini();
unsafe {
obj.run_fini();
}
}
}
+7 -5
View File
@@ -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,6 +9,7 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
use log::LevelFilter;
use object::{
NativeEndian,
elf::{self, PT_DYNAMIC, PT_PHDR},
@@ -28,7 +29,7 @@ use crate::{
},
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,
};
@@ -406,9 +407,10 @@ fn stage2(
.collect::<Vec<_>>(),
);
crate::platform::environ = crate::platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr();
if let Err(_) = 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");
}
}
+11 -13
View File
@@ -1,28 +1,26 @@
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, SetLoggerError};
use log::{LevelFilter, Metadata, Record, SetLoggerError};
const DEFAULT_LOG_LEVEL: log::LevelFilter = log::LevelFilter::Info;
pub unsafe fn init() -> Result<(), SetLoggerError> {
pub const RELIBC_LOG_ENV_VAR: &'static 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());
+9 -4
View File
@@ -1,12 +1,13 @@
//! Startup code.
use alloc::vec::Vec;
use core::{intrinsics, ptr};
use core::{intrinsics, ptr, str::FromStr};
use crate::{
c_str::CStr,
header::{libgen, stdio, stdlib},
ld_so::{self},
platform::{self, Pal, Sys, get_auxvs, types::*},
platform::{self, Pal, Sys, get_auxvs, logger::RELIBC_LOG_ENV_VAR, types::*},
};
#[repr(C)]
@@ -221,8 +222,12 @@ pub unsafe extern "C" fn relibc_start_v1(
unsafe { crate::platform::init(auxvs) };
init_array();
}
unsafe {
if let Err(_) = crate::platform::logger::init()
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(""))
{
if let Err(_) = unsafe { crate::platform::logger::init(level) }
&& !is_dynamically_linked
{
log::error!("Logger has already been initialised");