Return just the target name from the ELF linker's link functions

link returned a LinkResult, Result<i32, &str>: an exit status, or the
target the inputs are actually for. The status was always 0, as a link
that fails exits in the middle, so link now returns Option<&str>, the
other target if there is one, and the driver returns nothing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Rui UeyamaandClaude Opus 5.5 committed 2026-10-11 13:40:30 +09:00
1 parent 4e43149228
commit 65665ee122
22 files changed
+37 -39

No files matched your search

+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Arm32>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Arm32Be>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Arm64>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Arm64Be>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::I386>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::LoongArch32>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::LoongArch64>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::M68k>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Ppc32>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Ppc64V1>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Ppc64V2>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Riscv32>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Riscv32Be>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Riscv64>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Riscv64Be>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::S390x>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Sh4>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Sh4Be>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::Sparc64>(cmdline)
}
+1 -1
View File
@@ -1,3 +1,3 @@
pub fn link(cmdline: mold_elf::driver::Cmdline) -> mold_elf::driver::LinkResult {
pub fn link(cmdline: mold_elf::driver::Cmdline) -> Option<&'static str> {
mold_elf::driver::link::<mold_elf::arch::X86_64>(cmdline)
}
+4 -3
View File
@@ -11,7 +11,7 @@
// the speed of unwinding, so we keep rustc from reporting it.
#![cfg_attr(all(target_vendor = "apple", debug_assertions), allow(linker_messages))]
use mold_elf::driver::{Cmdline, LinkResult};
use mold_elf::driver::Cmdline;
use std::ffi::OsStr;
use std::path::Path;
@@ -21,7 +21,7 @@ use std::path::Path;
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
type LinkFn = fn(Cmdline) -> LinkResult;
type LinkFn = fn(Cmdline) -> Option<&'static str>;
type MachoLinkFn = fn(mold_macho::driver::ParsedArgs);
// Each target has its own monomorphized link function. The ELF linker
@@ -110,5 +110,6 @@ fn main() {
std::process::exit(1);
};
let link = |target: &str, cmdline| link_fn(ELF_TARGETS, target)(cmdline);
std::process::exit(mold_elf::driver::main(args, initial_target, link));
mold_elf::driver::main(args, initial_target, link);
std::process::exit(0);
}
+13 -16
View File
@@ -21,21 +21,18 @@ use crate::passes;
/// that report it.
pub type Cmdline = Arc<[Cow<'static, OsStr>]>;
/// The exit status of a link, or the name of the target the inputs are
/// actually for.
pub type LinkResult = Result<i32, &'static str>;
/// Runs the linker with the given command line. Returns the exit status.
/// Runs the linker with the given command line. A link that fails exits
/// in the middle (see mold_common::error::checkpoint).
///
/// `initial_target` is an enabled target used for the initial argument
/// parsing. `link_for_target` links for a named target, or reports the
/// parsing. `link_for_target` links for a named target, or returns the
/// 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<OsString>,
initial_target: &str,
link_for_target: impl Fn(&str, Cmdline) -> LinkResult,
) -> i32 {
link_for_target: impl Fn(&str, Cmdline) -> Option<&'static str>,
) {
// A parent's transparent huge page disable flag is inherited. Restore
// the system's default policy so large links can use huge pages.
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -65,8 +62,8 @@ pub fn main(
let _ = std::env::set_current_dir(cwd);
}
match link_for_target(target, Arc::clone(&cmdline)) {
Ok(status) => return status,
Err(actual) => target = actual,
Some(actual) => target = actual,
None => return,
}
}
}
@@ -81,9 +78,9 @@ fn thread_count(args: &Args) -> usize {
.unwrap_or_else(|| std::thread::available_parallelism().map_or(1, |n| n.get()).min(32))
}
/// Links for the target `E`, or reports the target the inputs are actually
/// for.
pub fn link<E: Target>(cmdline: Cmdline) -> LinkResult {
/// Links for the target `E`, or returns the target the inputs are
/// actually for.
pub fn link<E: Target>(cmdline: Cmdline) -> Option<&'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);
@@ -95,7 +92,7 @@ pub fn link<E: Target>(cmdline: Cmdline) -> LinkResult {
// Redo if -m does not match our speculation.
if ctx.args.emulation != E::NAME {
return Err(ctx.args.emulation);
return Some(ctx.args.emulation);
}
let t_all = ctx.timer("all");
@@ -234,7 +231,7 @@ pub fn link<E: Target>(cmdline: Cmdline) -> LinkResult {
// in a separate file.
if ctx.args.relocatable {
crate::relocatable::combine_objects(&mut ctx);
return Ok(0);
return None;
}
// Create .bss sections for common symbols.
@@ -627,7 +624,7 @@ pub fn link<E: Target>(cmdline: Cmdline) -> LinkResult {
error::exit_after_cleanup(0);
}
error::checkpoint();
Ok(0)
None
}
/// Opens the output file that the command line names.