@@ -12,7 +12,7 @@ use rustc_session::utils::NativeLibKind;
1212/// need out of the shared crate context before we get rid of it. 
1313use  rustc_session:: { filesearch,  Session } ; 
1414use  rustc_span:: symbol:: Symbol ; 
15- use  rustc_target:: spec:: crt_objects:: CrtObjectsFallback ; 
15+ use  rustc_target:: spec:: crt_objects:: { CrtObjects ,   CrtObjectsFallback } ; 
1616use  rustc_target:: spec:: { LinkOutputKind ,  LinkerFlavor ,  LldFlavor } ; 
1717use  rustc_target:: spec:: { PanicStrategy ,  RelocModel ,  RelroLevel } ; 
1818
@@ -25,16 +25,10 @@ use crate::{looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FIL
2525use  cc:: windows_registry; 
2626use  tempfile:: { Builder  as  TempFileBuilder ,  TempDir } ; 
2727
28- use  std:: ascii; 
29- use  std:: char; 
30- use  std:: env; 
3128use  std:: ffi:: OsString ; 
32- use  std:: fmt; 
33- use  std:: fs; 
34- use  std:: io; 
3529use  std:: path:: { Path ,  PathBuf } ; 
3630use  std:: process:: { ExitStatus ,  Output ,  Stdio } ; 
37- use  std:: str; 
31+ use  std:: { ascii ,  char ,  env ,  fmt ,  fs ,  io ,  mem ,   str} ; 
3832
3933pub  fn  remove ( sess :  & Session ,  path :  & Path )  { 
4034    if  let  Err ( e)  = fs:: remove_file ( path)  { 
@@ -543,6 +537,61 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
543537            continue ; 
544538        } 
545539
540+         // Detect '-static-pie' used with an older version of gcc or clang not supporting it. 
541+         // Fallback from '-static-pie' to '-static' in that case. 
542+         if  sess. target . target . options . linker_is_gnu 
543+             && flavor != LinkerFlavor :: Ld 
544+             && ( out. contains ( "unrecognized command line option" ) 
545+                 || out. contains ( "unknown argument" ) ) 
546+             && ( out. contains ( "-static-pie" )  || out. contains ( "--no-dynamic-linker" ) ) 
547+             && cmd. get_args ( ) . iter ( ) . any ( |e| e. to_string_lossy ( )  == "-static-pie" ) 
548+         { 
549+             info ! ( "linker output: {:?}" ,  out) ; 
550+             warn ! ( 
551+                 "Linker does not support -static-pie command line option. Retrying with -static instead." 
552+             ) ; 
553+             // Mirror `add_(pre,post)_link_objects` to replace CRT objects. 
554+             let  fallback = crt_objects_fallback ( sess,  crate_type) ; 
555+             let  opts = & sess. target . target . options ; 
556+             let  pre_objects =
557+                 if  fallback {  & opts. pre_link_objects_fallback  }  else  {  & opts. pre_link_objects  } ; 
558+             let  post_objects =
559+                 if  fallback {  & opts. post_link_objects_fallback  }  else  {  & opts. post_link_objects  } ; 
560+             let  get_objects = |objects :  & CrtObjects ,  kind| { 
561+                 objects
562+                     . get ( & kind) 
563+                     . iter ( ) 
564+                     . copied ( ) 
565+                     . flatten ( ) 
566+                     . map ( |obj| get_object_file_path ( sess,  obj) . into_os_string ( ) ) 
567+                     . collect :: < Vec < _ > > ( ) 
568+             } ; 
569+             let  pre_objects_static_pie = get_objects ( pre_objects,  LinkOutputKind :: StaticPicExe ) ; 
570+             let  post_objects_static_pie = get_objects ( post_objects,  LinkOutputKind :: StaticPicExe ) ; 
571+             let  mut  pre_objects_static = get_objects ( pre_objects,  LinkOutputKind :: StaticNoPicExe ) ; 
572+             let  mut  post_objects_static = get_objects ( post_objects,  LinkOutputKind :: StaticNoPicExe ) ; 
573+             // Assume that we know insertion positions for the replacement arguments from replaced 
574+             // arguments, which is true for all supported targets. 
575+             assert ! ( pre_objects_static. is_empty( )  || !pre_objects_static_pie. is_empty( ) ) ; 
576+             assert ! ( post_objects_static. is_empty( )  || !post_objects_static_pie. is_empty( ) ) ; 
577+             for  arg in  cmd. take_args ( )  { 
578+                 if  arg. to_string_lossy ( )  == "-static-pie"  { 
579+                     // Replace the output kind. 
580+                     cmd. arg ( "-static" ) ; 
581+                 }  else  if  pre_objects_static_pie. contains ( & arg)  { 
582+                     // Replace the pre-link objects (replace the first and remove the rest). 
583+                     cmd. args ( mem:: take ( & mut  pre_objects_static) ) ; 
584+                 }  else  if  post_objects_static_pie. contains ( & arg)  { 
585+                     // Replace the post-link objects (replace the first and remove the rest). 
586+                     cmd. args ( mem:: take ( & mut  post_objects_static) ) ; 
587+                 }  else  { 
588+                     cmd. arg ( arg) ; 
589+                 } 
590+             } 
591+             info ! ( "{:?}" ,  & cmd) ; 
592+             continue ; 
593+         } 
594+ 
546595        // Here's a terribly awful hack that really shouldn't be present in any 
547596        // compiler. Here an environment variable is supported to automatically 
548597        // retry the linker invocation if the linker looks like it segfaulted. 
0 commit comments