@@ -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+ }
0 commit comments