Share expanded command line arguments through target dispatch

This commit is contained in:
Rui Ueyama committed 2026-09-14 22:54:34 +09:00
1 parent 40ad3e5700
commit 96e6a38d08
24 files changed
+98 -33

No files matched your search

+5 -2
View File
@@ -3,13 +3,16 @@
//! that the compiler can build them in parallel, and a feature per target
//! decides which of them are built in.
use std::ffi::OsString;
use std::sync::Arc;
// A Rust executable can define only one global allocator, so select mimalloc
// here rather than in the linker library.
#[cfg(not(feature = "system-allocator"))]
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
type LinkFn = fn(&[std::ffi::OsString]) -> Result<i32, &'static str>;
type LinkFn = fn(Arc<[OsString]>) -> Result<i32, &'static str>;
// Each target has its own monomorphized link function. Start with the first
// enabled target and switch to the matching function if the inputs differ.
@@ -56,7 +59,7 @@ const TARGETS: &[(&str, LinkFn)] = &[
("loongarch32", mold_target_loongarch32::link),
];
fn link_for_target(target: &str, cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
fn link_for_target(target: &str, cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
for &(name, link) in TARGETS {
if name == target {
return link(cmdline);
+2 -2
View File
@@ -787,13 +787,13 @@ fn read_response_file(path: &Path, depth: usize) -> Vec<OsString> {
}
// Replace "@path/to/some/text/file" with its file contents.
pub fn expand_response_files(argv: &[OsString]) -> Vec<OsString> {
pub fn expand_response_files(argv: Vec<OsString>) -> Vec<OsString> {
let mut args = Vec::new();
for arg in argv {
if let Some(path) = arg.as_encoded_bytes().strip_prefix(b"@") {
args.extend(read_response_file(Path::new(util::os_str(path)), 1));
} else {
args.push(arg.clone());
args.push(arg);
}
}
args
+3 -2
View File
@@ -1,6 +1,7 @@
//! The linker context: everything about one link, from parsed arguments
//! to output chunks.
use std::ffi::OsString;
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::path::Path;
@@ -105,7 +106,7 @@ pub struct Context<E: Arch> {
pub args: Args,
// Fully-expanded command line args
pub cmdline_args: Arc<[std::ffi::OsString]>,
pub cmdline_args: Arc<[OsString]>,
pub timers: Timers,
// Symbol table. Object file parsing records each global symbol with add(),
@@ -233,7 +234,7 @@ pub struct Context<E: Arch> {
}
impl<E: Arch> Context<E> {
pub fn new(args: Args, cmdline_args: Vec<std::ffi::OsString>) -> Context<E> {
pub fn new(args: Args, cmdline_args: impl Into<Arc<[OsString]>>) -> Context<E> {
let mut symbols = SymbolTable::new();
let syms = SyntheticSymbols {
entry: symbols.intern(crate::util::leak_bytes(args.entry.clone())),
+8 -7
View File
@@ -1,5 +1,6 @@
//! The linker driver: runs the passes in order.
use std::ffi::OsString;
use std::fmt;
use std::ops::Range;
use std::sync::{mpsc, Arc};
@@ -22,9 +23,9 @@ use crate::{error, fatal, passes};
/// target the inputs are actually for; the executable provides both, as
/// the targets are instantiated in crates of their own.
pub fn main(
argv: Vec<std::ffi::OsString>,
argv: Vec<OsString>,
initial_target: &str,
link_for_target: impl Fn(&str, &[std::ffi::OsString]) -> Result<i32, &'static str>,
link_for_target: impl Fn(&str, Arc<[OsString]>) -> Result<i32, &'static str>,
) -> i32 {
// A parent's transparent huge page disable flag is inherited. Restore
// the system's default policy so large links can use huge pages.
@@ -45,7 +46,7 @@ pub fn main(
let orig_cwd = std::env::current_dir().ok();
// Parse non-positional command line options
let cmdline = cmdline::expand_response_files(&argv);
let cmdline: Arc<[_]> = cmdline::expand_response_files(argv).into();
// Parse with an enabled target's defaults; if the target turns out to
// be different, start over with the right one.
@@ -54,7 +55,7 @@ pub fn main(
if let Some(cwd) = &orig_cwd {
let _ = std::env::set_current_dir(cwd);
}
match link_for_target(target, &cmdline) {
match link_for_target(target, Arc::clone(&cmdline)) {
Ok(status) => return status,
Err(actual) => target = actual,
}
@@ -95,10 +96,10 @@ fn wait_for_background<T>(receiver: mpsc::Receiver<T>, name: &str) -> T {
/// Links for the target `E`, or reports the target the inputs are actually
/// for.
pub fn link<E: Arch>(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
let parsed = cmdline::parse_args(&target_traits::<E>(), cmdline);
pub fn link<E: Arch>(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
let parsed = cmdline::parse_args(&target_traits::<E>(), &cmdline);
let cmdline::ParsedArgs { args, jobs, .. } = parsed;
let mut ctx = Context::<E>::new(args, cmdline.to_vec());
let mut ctx = Context::<E>::new(args, cmdline);
// If no -m option is given, deduce it from input files.
if ctx.args.emulation.is_empty() {
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for arm32. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Arm32>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for arm32be. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Arm32Be>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for arm64. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Arm64>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for arm64be. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Arm64Be>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for i386. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::I386>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for loongarch32. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::LoongArch32>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for loongarch64. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::LoongArch64>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for m68k. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::M68k>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for ppc32. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Ppc32>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for ppc64v1. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Ppc64V1>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for ppc64v2. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Ppc64V2>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for riscv32. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Riscv32>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for riscv32be. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Riscv32Be>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for riscv64. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Riscv64>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for riscv64be. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Riscv64Be>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for s390x. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::S390x>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for sh4. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Sh4>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for sh4be. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Sh4Be>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for sparc64. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::Sparc64>(cmdline)
}
+4 -1
View File
@@ -1,8 +1,11 @@
//! The linker instantiated for x86_64. Every target has a crate like this
//! one, so that the compiler can build the targets in parallel.
use std::ffi::OsString;
use std::sync::Arc;
/// Links for this target, or reports the target the inputs are actually
/// for.
pub fn link(cmdline: &[std::ffi::OsString]) -> Result<i32, &'static str> {
pub fn link(cmdline: Arc<[OsString]>) -> Result<i32, &'static str> {
mold::driver::link::<mold::arch::X86_64>(cmdline)
}