Skip to content

Commit 1635052

Browse files
committed
pass correct pie args to gcc linker
When linking with gcc, run gcc -v to see if --enable-default-pie is compiled in. If it is, pass -no-pie when necessary to disable pie. Otherwise, pass -pie when necessary to enable it. Fixes #48032 and fixes #35061
1 parent 4d2d3fc commit 1635052

File tree

2 files changed

+66
-10
lines changed

2 files changed

+66
-10
lines changed

src/librustc_trans/back/link.rs

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -897,16 +897,33 @@ fn link_args(cmd: &mut Linker,
897897

898898
let used_link_args = &trans.crate_info.link_args;
899899

900-
if crate_type == config::CrateTypeExecutable &&
901-
t.options.position_independent_executables {
902-
let empty_vec = Vec::new();
903-
let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
904-
let more_args = &sess.opts.cg.link_arg;
905-
let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());
906-
907-
if get_reloc_model(sess) == llvm::RelocMode::PIC
908-
&& !sess.crt_static() && !args.any(|x| *x == "-static") {
909-
cmd.position_independent_executable();
900+
if crate_type == config::CrateTypeExecutable {
901+
let mut position_independent_executable = false;
902+
903+
if t.options.position_independent_executables {
904+
let empty_vec = Vec::new();
905+
let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
906+
let more_args = &sess.opts.cg.link_arg;
907+
let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());
908+
909+
if get_reloc_model(sess) == llvm::RelocMode::PIC
910+
&& !sess.crt_static() && !args.any(|x| *x == "-static") {
911+
position_independent_executable = true;
912+
}
913+
}
914+
915+
// Check to see if gcc defaults to generating a position independent
916+
// executable. If so, tell it when to disable pie. Otherwise, tell it
917+
// when to enable it. We can't do both because older versions of gcc
918+
// don't understand -no-pie and will blow up.
919+
if is_pie_default(sess) {
920+
if !position_independent_executable {
921+
cmd.no_position_independent_executable();
922+
}
923+
} else {
924+
if position_independent_executable {
925+
cmd.position_independent_executable();
926+
}
910927
}
911928
}
912929

@@ -1421,3 +1438,32 @@ fn is_full_lto_enabled(sess: &Session) -> bool {
14211438
Lto::ThinLocal => false,
14221439
}
14231440
}
1441+
1442+
fn is_pie_default(sess: &Session) -> bool {
1443+
match sess.linker_flavor() {
1444+
LinkerFlavor::Gcc => {
1445+
let (_, mut cmd, envs) = get_linker(sess);
1446+
// This will set PATH on windows
1447+
cmd.envs(envs);
1448+
cmd.arg("-v");
1449+
1450+
info!("{:?}", &cmd);
1451+
1452+
let output = cmd.command()
1453+
.stdout(Stdio::piped()).stderr(Stdio::piped())
1454+
.spawn()
1455+
.unwrap()
1456+
.wait_with_output()
1457+
.unwrap();
1458+
1459+
let ret = String::from_utf8_lossy(&output.stderr)
1460+
.contains("--enable-default-pie");
1461+
1462+
info!("gcc {} compiled with --enable-default-pie",
1463+
if ret { "IS" } else { "is NOT" });
1464+
1465+
ret
1466+
},
1467+
_ => false,
1468+
}
1469+
}

src/librustc_trans/back/linker.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub trait Linker {
105105
fn add_object(&mut self, path: &Path);
106106
fn gc_sections(&mut self, keep_metadata: bool);
107107
fn position_independent_executable(&mut self);
108+
fn no_position_independent_executable(&mut self);
108109
fn partial_relro(&mut self);
109110
fn full_relro(&mut self);
110111
fn optimize(&mut self);
@@ -179,6 +180,7 @@ impl<'a> Linker for GccLinker<'a> {
179180
fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); }
180181
fn add_object(&mut self, path: &Path) { self.cmd.arg(path); }
181182
fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); }
183+
fn no_position_independent_executable(&mut self) { self.cmd.arg("-no-pie"); }
182184
fn partial_relro(&mut self) { self.linker_arg("-z,relro"); }
183185
fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); }
184186
fn build_static_executable(&mut self) { self.cmd.arg("-static"); }
@@ -439,6 +441,10 @@ impl<'a> Linker for MsvcLinker<'a> {
439441
// noop
440442
}
441443

444+
fn no_position_independent_executable(&mut self) {
445+
// noop
446+
}
447+
442448
fn partial_relro(&mut self) {
443449
// noop
444450
}
@@ -647,6 +653,10 @@ impl<'a> Linker for EmLinker<'a> {
647653
// noop
648654
}
649655

656+
fn no_position_independent_executable(&mut self) {
657+
// noop
658+
}
659+
650660
fn partial_relro(&mut self) {
651661
// noop
652662
}

0 commit comments

Comments
 (0)