@@ -700,9 +700,6 @@ fn link_natively(sess: &Session,
700700 prog = time ( sess. time_passes ( ) , "running linker" , || {
701701 exec_linker ( sess, & mut cmd, tmpdir)
702702 } ) ;
703- if !retry_on_segfault || i > 3 {
704- break
705- }
706703 let output = match prog {
707704 Ok ( ref output) => output,
708705 Err ( _) => break ,
@@ -713,6 +710,31 @@ fn link_natively(sess: &Session,
713710 let mut out = output. stderr . clone ( ) ;
714711 out. extend ( & output. stdout ) ;
715712 let out = String :: from_utf8_lossy ( & out) ;
713+
714+ // Check to see if the link failed with "unrecognized command line option:
715+ // '-no-pie'" for gcc or "unknown argument: '-no-pie'" for clang. If so,
716+ // reperform the link step without the -no-pie option. This is safe because
717+ // if the linker doesn't support -no-pie then it should not default to
718+ // linking executables as pie. Different versions of gcc seem to use
719+ // different quotes in the error message so don't check for them.
720+ if sess. target . target . options . linker_is_gnu &&
721+ ( out. contains ( "unrecognized command line option" ) ||
722+ out. contains ( "unknown argument" ) ) &&
723+ out. contains ( "-no-pie" ) &&
724+ cmd. get_args ( ) . iter ( ) . any ( |e| e. to_string_lossy ( ) == "-no-pie" ) {
725+ info ! ( "linker output: {:?}" , out) ;
726+ warn ! ( "Linker does not support -no-pie command line option. Retrying without." ) ;
727+ for arg in cmd. take_args ( ) {
728+ if arg. to_string_lossy ( ) != "-no-pie" {
729+ cmd. arg ( arg) ;
730+ }
731+ }
732+ info ! ( "{:?}" , & cmd) ;
733+ continue ;
734+ }
735+ if !retry_on_segfault || i > 3 {
736+ break
737+ }
716738 let msg_segv = "clang: error: unable to execute command: Segmentation fault: 11" ;
717739 let msg_bus = "clang: error: unable to execute command: Bus error: 10" ;
718740 if !( out. contains ( msg_segv) || out. contains ( msg_bus) ) {
@@ -949,16 +971,30 @@ fn link_args(cmd: &mut Linker,
949971
950972 let used_link_args = & trans. crate_info . link_args ;
951973
952- if crate_type == config:: CrateTypeExecutable &&
953- t. options . position_independent_executables {
954- let empty_vec = Vec :: new ( ) ;
955- let args = sess. opts . cg . link_args . as_ref ( ) . unwrap_or ( & empty_vec) ;
956- let more_args = & sess. opts . cg . link_arg ;
957- let mut args = args. iter ( ) . chain ( more_args. iter ( ) ) . chain ( used_link_args. iter ( ) ) ;
958-
959- if get_reloc_model ( sess) == llvm:: RelocMode :: PIC
960- && !sess. crt_static ( ) && !args. any ( |x| * x == "-static" ) {
974+ if crate_type == config:: CrateTypeExecutable {
975+ let mut position_independent_executable = false ;
976+
977+ if t. options . position_independent_executables {
978+ let empty_vec = Vec :: new ( ) ;
979+ let args = sess. opts . cg . link_args . as_ref ( ) . unwrap_or ( & empty_vec) ;
980+ let more_args = & sess. opts . cg . link_arg ;
981+ let mut args = args. iter ( ) . chain ( more_args. iter ( ) ) . chain ( used_link_args. iter ( ) ) ;
982+
983+ if get_reloc_model ( sess) == llvm:: RelocMode :: PIC
984+ && !sess. crt_static ( ) && !args. any ( |x| * x == "-static" ) {
985+ position_independent_executable = true ;
986+ }
987+ }
988+
989+ if position_independent_executable {
961990 cmd. position_independent_executable ( ) ;
991+ } else {
992+ // recent versions of gcc can be configured to generate position
993+ // independent executables by default. We have to pass -no-pie to
994+ // explicitly turn that off.
995+ if sess. target . target . options . linker_is_gnu {
996+ cmd. no_position_independent_executable ( ) ;
997+ }
962998 }
963999 }
9641000
0 commit comments