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
This commit is contained in:
commit
1c68bb6ec9
7 changed files with 19 additions and 14 deletions
|
@ -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();
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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(),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue