@@ -700,9 +700,6 @@ fn link_natively(sess: &Session,
700
700
prog = time ( sess. time_passes ( ) , "running linker" , || {
701
701
exec_linker ( sess, & mut cmd, tmpdir)
702
702
} ) ;
703
- if !retry_on_segfault || i > 3 {
704
- break
705
- }
706
703
let output = match prog {
707
704
Ok ( ref output) => output,
708
705
Err ( _) => break ,
@@ -713,6 +710,31 @@ fn link_natively(sess: &Session,
713
710
let mut out = output. stderr . clone ( ) ;
714
711
out. extend ( & output. stdout ) ;
715
712
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
+ }
716
738
let msg_segv = "clang: error: unable to execute command: Segmentation fault: 11" ;
717
739
let msg_bus = "clang: error: unable to execute command: Bus error: 10" ;
718
740
if !( out. contains ( msg_segv) || out. contains ( msg_bus) ) {
@@ -949,16 +971,30 @@ fn link_args(cmd: &mut Linker,
949
971
950
972
let used_link_args = & trans. crate_info . link_args ;
951
973
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 {
961
990
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
+ }
962
998
}
963
999
}
964
1000
0 commit comments