From df0fc6daeede7722d631bcb45ed3755eb693580e Mon Sep 17 00:00:00 2001 From: David Calavera Date: Fri, 12 Feb 2021 10:24:16 -0800 Subject: [PATCH] Make symbols stripping work on MacOS X As reported in the stabilization issue, MacOS' linker doesn't support the `-s` and `-S` flags to strip symbols anymore. However, the os ships a separated tool to perform these operations. This change allows the compiler to use that tool after a target has been compiled to strip symbols. For rationale, see: https://github.com/rust-lang/rust/issues/72110#issuecomment-641169818 For option selection, see: https://www.unix.com/man-page/osx/1/strip/ Signed-off-by: David Calavera --- compiler/rustc_codegen_ssa/src/back/link.rs | 51 +++++++++++++++---- compiler/rustc_codegen_ssa/src/back/linker.rs | 11 ++-- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ea75943d6f314..0e55cb32f1e13 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -5,7 +5,7 @@ use rustc_fs_util::fix_windows_verbatim_for_gcc; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::cstore::{EncodedMetadata, LibSource}; use rustc_middle::middle::dependency_format::Linkage; -use rustc_session::config::{self, CFGuard, CrateType, DebugInfo}; +use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, Strip}; use rustc_session::config::{OutputFilenames, OutputType, PrintRequest}; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; use rustc_session::search_paths::PathKind; @@ -717,14 +717,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( } } - fn escape_string(s: &[u8]) -> String { - str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| { - let mut x = "Non-UTF-8 output: ".to_string(); - x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from)); - x - }) - } - match prog { Ok(prog) => { if !prog.status.success() { @@ -866,6 +858,47 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( // ... and otherwise we're processing a `*.dwp` packed dwarf file. SplitDebuginfo::Packed => link_dwarf_object(sess, &out_filename), } + + if sess.target.is_like_osx { + if let Some(option) = osx_strip_opt(sess.opts.debugging_opts.strip) { + strip_symbols_in_osx(sess, &out_filename, option); + } + } +} + +fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: &str) { + let prog = Command::new("strip").arg(option).arg(out_filename).output(); + match prog { + Ok(prog) => { + if !prog.status.success() { + let mut output = prog.stderr.clone(); + output.extend_from_slice(&prog.stdout); + sess.struct_warn(&format!( + "stripping debug info with `strip` failed: {}", + prog.status + )) + .note(&escape_string(&output)) + .emit(); + } + } + Err(e) => sess.fatal(&format!("unable to run `strip`: {}", e)), + } +} + +fn osx_strip_opt<'a>(strip: Strip) -> Option<&'a str> { + match strip { + Strip::Debuginfo => Some("-S"), + Strip::Symbols => Some("-x"), + Strip::None => None, + } +} + +fn escape_string(s: &[u8]) -> String { + str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| { + let mut x = "Non-UTF-8 output: ".to_string(); + x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from)); + x + }) } fn link_sanitizers(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) { diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 77d8ab49ff258..cd24d87505c1a 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -482,15 +482,18 @@ impl<'a> Linker for GccLinker<'a> { fn control_flow_guard(&mut self) {} fn debuginfo(&mut self, strip: Strip) { + // MacOS linker doesn't support stripping symbols directly anymore. + if self.sess.target.is_like_osx { + return; + } + match strip { Strip::None => {} Strip::Debuginfo => { - // MacOS linker does not support longhand argument --strip-debug - self.linker_arg("-S"); + self.linker_arg("--strip-debug"); } Strip::Symbols => { - // MacOS linker does not support longhand argument --strip-all - self.linker_arg("-s"); + self.linker_arg("--strip-all"); } } }