From 65665ee122e7ad4bd821281fcf3b0beea619e12a Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sun, 11 Oct 2026 12:33:18 +0900 Subject: [PATCH] Return just the target name from the ELF linker's link functions link returned a LinkResult, Result: 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 --- arch/elf-arm32/lib.rs | 2 +- arch/elf-arm32be/lib.rs | 2 +- arch/elf-arm64/lib.rs | 2 +- arch/elf-arm64be/lib.rs | 2 +- arch/elf-i386/lib.rs | 2 +- arch/elf-loongarch32/lib.rs | 2 +- arch/elf-loongarch64/lib.rs | 2 +- arch/elf-m68k/lib.rs | 2 +- arch/elf-ppc32/lib.rs | 2 +- arch/elf-ppc64v1/lib.rs | 2 +- arch/elf-ppc64v2/lib.rs | 2 +- arch/elf-riscv32/lib.rs | 2 +- arch/elf-riscv32be/lib.rs | 2 +- arch/elf-riscv64/lib.rs | 2 +- arch/elf-riscv64be/lib.rs | 2 +- arch/elf-s390x/lib.rs | 2 +- arch/elf-sh4/lib.rs | 2 +- arch/elf-sh4be/lib.rs | 2 +- arch/elf-sparc64/lib.rs | 2 +- arch/elf-x86_64/lib.rs | 2 +- cli/main.rs | 7 ++++--- elf/driver.rs | 29 +++++++++++++---------------- 22 files changed, 37 insertions(+), 39 deletions(-) diff --git a/arch/elf-arm32/lib.rs b/arch/elf-arm32/lib.rs index fcddcd58e..dbb0ff9e4 100644 --- a/arch/elf-arm32/lib.rs +++ b/arch/elf-arm32/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-arm32be/lib.rs b/arch/elf-arm32be/lib.rs index 9458d0b93..aed25ab9d 100644 --- a/arch/elf-arm32be/lib.rs +++ b/arch/elf-arm32be/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-arm64/lib.rs b/arch/elf-arm64/lib.rs index d8dbb4ca6..1553c8d58 100644 --- a/arch/elf-arm64/lib.rs +++ b/arch/elf-arm64/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-arm64be/lib.rs b/arch/elf-arm64be/lib.rs index aab292740..71dae7b2b 100644 --- a/arch/elf-arm64be/lib.rs +++ b/arch/elf-arm64be/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-i386/lib.rs b/arch/elf-i386/lib.rs index b610ae5a9..41ae8bfe1 100644 --- a/arch/elf-i386/lib.rs +++ b/arch/elf-i386/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-loongarch32/lib.rs b/arch/elf-loongarch32/lib.rs index eb8b7f219..9c1a2163f 100644 --- a/arch/elf-loongarch32/lib.rs +++ b/arch/elf-loongarch32/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-loongarch64/lib.rs b/arch/elf-loongarch64/lib.rs index cec16ce3c..86fbc8077 100644 --- a/arch/elf-loongarch64/lib.rs +++ b/arch/elf-loongarch64/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-m68k/lib.rs b/arch/elf-m68k/lib.rs index d88b87667..1dd5e3075 100644 --- a/arch/elf-m68k/lib.rs +++ b/arch/elf-m68k/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-ppc32/lib.rs b/arch/elf-ppc32/lib.rs index 087a2f7ac..e698f602e 100644 --- a/arch/elf-ppc32/lib.rs +++ b/arch/elf-ppc32/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-ppc64v1/lib.rs b/arch/elf-ppc64v1/lib.rs index 95e83d68a..cb3a6db73 100644 --- a/arch/elf-ppc64v1/lib.rs +++ b/arch/elf-ppc64v1/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-ppc64v2/lib.rs b/arch/elf-ppc64v2/lib.rs index 9c401c8b3..11932a424 100644 --- a/arch/elf-ppc64v2/lib.rs +++ b/arch/elf-ppc64v2/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-riscv32/lib.rs b/arch/elf-riscv32/lib.rs index 9ffc79039..0d3a15409 100644 --- a/arch/elf-riscv32/lib.rs +++ b/arch/elf-riscv32/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-riscv32be/lib.rs b/arch/elf-riscv32be/lib.rs index 8831e246f..08690b3ea 100644 --- a/arch/elf-riscv32be/lib.rs +++ b/arch/elf-riscv32be/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-riscv64/lib.rs b/arch/elf-riscv64/lib.rs index 8fc4f67fb..81527e7ed 100644 --- a/arch/elf-riscv64/lib.rs +++ b/arch/elf-riscv64/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-riscv64be/lib.rs b/arch/elf-riscv64be/lib.rs index ad5b76612..1d004c2e3 100644 --- a/arch/elf-riscv64be/lib.rs +++ b/arch/elf-riscv64be/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-s390x/lib.rs b/arch/elf-s390x/lib.rs index 6ff2f38a1..ad3219d1c 100644 --- a/arch/elf-s390x/lib.rs +++ b/arch/elf-s390x/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-sh4/lib.rs b/arch/elf-sh4/lib.rs index 56380f049..062442838 100644 --- a/arch/elf-sh4/lib.rs +++ b/arch/elf-sh4/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-sh4be/lib.rs b/arch/elf-sh4be/lib.rs index 12c6b8f59..b1348b4aa 100644 --- a/arch/elf-sh4be/lib.rs +++ b/arch/elf-sh4be/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-sparc64/lib.rs b/arch/elf-sparc64/lib.rs index 64595c746..d42e776e7 100644 --- a/arch/elf-sparc64/lib.rs +++ b/arch/elf-sparc64/lib.rs @@ -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::(cmdline) } diff --git a/arch/elf-x86_64/lib.rs b/arch/elf-x86_64/lib.rs index 4211eb5bf..9c4578dcb 100644 --- a/arch/elf-x86_64/lib.rs +++ b/arch/elf-x86_64/lib.rs @@ -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::(cmdline) } diff --git a/cli/main.rs b/cli/main.rs index 58b97de2e..2c1a247d2 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -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); } diff --git a/elf/driver.rs b/elf/driver.rs index c567aa14c..b90a4d40a 100644 --- a/elf/driver.rs +++ b/elf/driver.rs @@ -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; - -/// 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, 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(cmdline: Cmdline) -> LinkResult { +/// Links for the target `E`, or returns the target the inputs are +/// actually for. +pub fn link(cmdline: Cmdline) -> Option<&'static str> { let parsed = cmdline::parse_args(&target_traits::(), &cmdline); let cmdline::ParsedArgs { args, jobs, .. } = parsed; let mut ctx = Context::::new(args, cmdline); @@ -95,7 +92,7 @@ pub fn link(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(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(cmdline: Cmdline) -> LinkResult { error::exit_after_cleanup(0); } error::checkpoint(); - Ok(0) + None } /// Opens the output file that the command line names.