about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-02 00:16:26 -0700
committerGitHub <noreply@github.com>2020-07-02 00:16:26 -0700
commit1c68bb6ec9c6fa3eab136a917778ec0625fbdd20 (patch)
treec8de6085c3b63ab84c6c53e73ac0788b4fe2f139
parent63d392e44fba5877f7a1e1a645bee724642980f1 (diff)
parent79a42e37084d0fc584c9f312c2a355104a113889 (diff)
downloadrust-1c68bb6ec9c6fa3eab136a917778ec0625fbdd20.tar.gz
rust-1c68bb6ec9c6fa3eab136a917778ec0625fbdd20.zip
Rollup merge of #73564 - petrochenkov:ehdr, r=Amanieu
linker: Create GNU_EH_FRAME header by default when producing ELFs

Do it in a centralized way in `link.rs` instead of individual target specs.

The opt-out is `-Clink-arg=(-Wl,)--no-eh-frame-hdr` if necessary.

Fixes https://github.com/rust-lang/rust/issues/73451
cc https://github.com/rust-lang/rust/pull/73483
-rw-r--r--src/librustc_codegen_ssa/back/link.rs3
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs14
-rw-r--r--src/librustc_target/spec/cloudabi_base.rs1
-rw-r--r--src/librustc_target/spec/fuchsia_base.rs1
-rw-r--r--src/librustc_target/spec/linux_musl_base.rs8
-rw-r--r--src/librustc_target/spec/mipsel_sony_psp.rs5
-rw-r--r--src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs1
7 files changed, 19 insertions, 14 deletions
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index a3402941078..3adaa07db91 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 d6ef94bfd17..54f55c806d0 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 3659c9ecdfc..39039435f58 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 dd55788b664..6f432dc1171 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 0fdd8760806..b90e91d2901 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 0c74454d0c5..b3bda97c8a5 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 d01545619c8..3b5233a3e67 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<Target, String> {
     const PRE_LINK_ARGS: &[&str] = &[
         "--as-needed",
-        "--eh-frame-hdr",
         "-z",
         "noexecstack",
         "-e",