diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index a34029410784a..3adaa07db91b0 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1597,6 +1597,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( cmd.arg(format!("--dynamic-linker={}ld.so.1", prefix)); } + // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER + cmd.add_eh_frame_header(); + // NO-OPT-OUT, OBJECT-FILES-NO if crt_objects_fallback { cmd.no_crt_objects(); diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index d6ef94bfd1727..54f55c806d035 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -129,6 +129,7 @@ pub trait Linker { fn group_start(&mut self); fn group_end(&mut self); fn linker_plugin_lto(&mut self); + fn add_eh_frame_header(&mut self) {} fn finalize(&mut self); } @@ -615,6 +616,19 @@ impl<'a> Linker for GccLinker<'a> { } } } + + // Add the `GNU_EH_FRAME` program header which is required to locate unwinding information. + // Some versions of `gcc` add it implicitly, some (e.g. `musl-gcc`) don't, + // so we just always add it. + fn add_eh_frame_header(&mut self) { + // The condition here is "uses ELF" basically. + if !self.sess.target.target.options.is_like_osx + && !self.sess.target.target.options.is_like_windows + && self.sess.target.target.target_os != "uefi" + { + self.linker_arg("--eh-frame-hdr"); + } + } } pub struct MsvcLinker<'a> { diff --git a/src/librustc_target/spec/cloudabi_base.rs b/src/librustc_target/spec/cloudabi_base.rs index 3659c9ecdfca6..39039435f5815 100644 --- a/src/librustc_target/spec/cloudabi_base.rs +++ b/src/librustc_target/spec/cloudabi_base.rs @@ -7,7 +7,6 @@ pub fn opts() -> TargetOptions { vec![ "-Wl,-Bstatic".to_string(), "-Wl,--no-dynamic-linker".to_string(), - "-Wl,--eh-frame-hdr".to_string(), "-Wl,--gc-sections".to_string(), ], ); diff --git a/src/librustc_target/spec/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs index dd55788b664ea..6f432dc11718d 100644 --- a/src/librustc_target/spec/fuchsia_base.rs +++ b/src/librustc_target/spec/fuchsia_base.rs @@ -6,7 +6,6 @@ pub fn opts() -> TargetOptions { LinkerFlavor::Lld(LldFlavor::Ld), vec![ "--build-id".to_string(), - "--eh-frame-hdr".to_string(), "--hash-style=gnu".to_string(), "-z".to_string(), "max-page-size=4096".to_string(), diff --git a/src/librustc_target/spec/linux_musl_base.rs b/src/librustc_target/spec/linux_musl_base.rs index 0fdd876080677..b90e91d2901a8 100644 --- a/src/librustc_target/spec/linux_musl_base.rs +++ b/src/librustc_target/spec/linux_musl_base.rs @@ -1,15 +1,9 @@ use crate::spec::crt_objects::{self, CrtObjectsFallback}; -use crate::spec::{LinkerFlavor, TargetOptions}; +use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); - // At least when this was tested, the linker would not add the - // `GNU_EH_FRAME` program header to executables generated, which is required - // when unwinding to locate the unwinding information. I'm not sure why this - // argument is *not* necessary for normal builds, but it can't hurt! - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--eh-frame-hdr".to_string()); - base.pre_link_objects_fallback = crt_objects::pre_musl_fallback(); base.post_link_objects_fallback = crt_objects::post_musl_fallback(); base.crt_objects_fallback = Some(CrtObjectsFallback::Musl); diff --git a/src/librustc_target/spec/mipsel_sony_psp.rs b/src/librustc_target/spec/mipsel_sony_psp.rs index 0c74454d0c5fe..b3bda97c8a570 100644 --- a/src/librustc_target/spec/mipsel_sony_psp.rs +++ b/src/librustc_target/spec/mipsel_sony_psp.rs @@ -6,10 +6,7 @@ const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld"); pub fn target() -> TargetResult { let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert( - LinkerFlavor::Lld(LldFlavor::Ld), - vec!["--eh-frame-hdr".to_string(), "--emit-relocs".to_string()], - ); + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["--emit-relocs".to_string()]); Ok(Target { llvm_target: "mipsel-sony-psp".to_string(), diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs index d01545619c8fa..3b5233a3e677d 100644 --- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs +++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs @@ -5,7 +5,6 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; pub fn target() -> Result { const PRE_LINK_ARGS: &[&str] = &[ "--as-needed", - "--eh-frame-hdr", "-z", "noexecstack", "-e",