about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-06-20 23:26:24 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-06-27 12:36:41 +0300
commit79a42e37084d0fc584c9f312c2a355104a113889 (patch)
tree6ccd18ddd19302c09403d3bfc11faceca59c652b /src/librustc_codegen_ssa
parent394e1b40d264aa6928811919c1124fa248e7d802 (diff)
linker: Create GNU_EH_FRAME header by default when producing ELFs
Diffstat (limited to 'src/librustc_codegen_ssa')
-rw-r--r--src/librustc_codegen_ssa/back/link.rs3
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs14
2 files changed, 17 insertions, 0 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> {