@@ -12,7 +12,7 @@ use rustc_session::utils::NativeLibKind;
12
12
/// need out of the shared crate context before we get rid of it.
13
13
use rustc_session:: { filesearch, Session } ;
14
14
use rustc_span:: symbol:: Symbol ;
15
- use rustc_target:: spec:: crt_objects:: CrtObjectsFallback ;
15
+ use rustc_target:: spec:: crt_objects:: { CrtObjects , CrtObjectsFallback } ;
16
16
use rustc_target:: spec:: { LinkOutputKind , LinkerFlavor , LldFlavor } ;
17
17
use rustc_target:: spec:: { PanicStrategy , RelocModel , RelroLevel } ;
18
18
@@ -25,16 +25,10 @@ use crate::{looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FIL
25
25
use cc:: windows_registry;
26
26
use tempfile:: { Builder as TempFileBuilder , TempDir } ;
27
27
28
- use std:: ascii;
29
- use std:: char;
30
- use std:: env;
31
28
use std:: ffi:: OsString ;
32
- use std:: fmt;
33
- use std:: fs;
34
- use std:: io;
35
29
use std:: path:: { Path , PathBuf } ;
36
30
use std:: process:: { ExitStatus , Output , Stdio } ;
37
- use std:: str;
31
+ use std:: { ascii , char , env , fmt , fs , io , mem , str} ;
38
32
39
33
pub fn remove ( sess : & Session , path : & Path ) {
40
34
if let Err ( e) = fs:: remove_file ( path) {
@@ -543,6 +537,61 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
543
537
continue ;
544
538
}
545
539
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
+
546
595
// Here's a terribly awful hack that really shouldn't be present in any
547
596
// compiler. Here an environment variable is supported to automatically
548
597
// retry the linker invocation if the linker looks like it segfaulted.
0 commit comments