@@ -897,16 +897,33 @@ fn link_args(cmd: &mut Linker,
897
897
898
898
let used_link_args = & trans. crate_info . link_args ;
899
899
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
+ }
910
927
}
911
928
}
912
929
@@ -1421,3 +1438,32 @@ fn is_full_lto_enabled(sess: &Session) -> bool {
1421
1438
Lto :: ThinLocal => false ,
1422
1439
}
1423
1440
}
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
+ }
0 commit comments