@@ -134,15 +134,13 @@ pub fn get_linker<'a>(
134
134
}
135
135
LinkerFlavor :: Em => Box :: new ( EmLinker { cmd, sess } ) as Box < dyn Linker > ,
136
136
LinkerFlavor :: Gcc => {
137
- Box :: new ( GccLinker { cmd, sess, target_cpu, hinted_static : false , is_ld : false } )
138
- as Box < dyn Linker >
137
+ Box :: new ( GccLinker :: new ( cmd, sess, target_cpu, false ) ) as Box < dyn Linker >
139
138
}
140
139
141
140
LinkerFlavor :: Lld ( LldFlavor :: Ld )
142
141
| LinkerFlavor :: Lld ( LldFlavor :: Ld64 )
143
142
| LinkerFlavor :: Ld => {
144
- Box :: new ( GccLinker { cmd, sess, target_cpu, hinted_static : false , is_ld : true } )
145
- as Box < dyn Linker >
143
+ Box :: new ( GccLinker :: new ( cmd, sess, target_cpu, true ) ) as Box < dyn Linker >
146
144
}
147
145
148
146
LinkerFlavor :: Lld ( LldFlavor :: Wasm ) => Box :: new ( WasmLd :: new ( cmd, sess) ) as Box < dyn Linker > ,
@@ -220,6 +218,17 @@ pub struct GccLinker<'a> {
220
218
}
221
219
222
220
impl < ' a > GccLinker < ' a > {
221
+ fn new ( mut cmd : Command , sess : & ' a Session , target_cpu : & ' a str , is_ld : bool ) -> GccLinker < ' a > {
222
+ if sess. target . os == "l4re" {
223
+ // FIXME: Why is this a rustc's job at all?
224
+ // Why can't l4-bender read the `L4_BENDER_ARGS` variable instead?
225
+ // If this needs to be done with rustc, then why it cannot be done with existing
226
+ // generic tools like `-Clink-arg` or `-Zpre-link-arg`
227
+ add_l4bender_args ( & mut cmd) ;
228
+ }
229
+ GccLinker { cmd, sess, target_cpu, is_ld, hinted_static : false }
230
+ }
231
+
223
232
/// Argument that must be passed *directly* to the linker
224
233
///
225
234
/// These arguments need to be prepended with `-Wl`, when a GCC-style linker is used.
@@ -339,6 +348,10 @@ impl<'a> Linker for GccLinker<'a> {
339
348
}
340
349
341
350
fn set_output_kind ( & mut self , output_kind : LinkOutputKind , out_filename : & Path ) {
351
+ if self . sess . target . os == "l4re" {
352
+ // FIXME: Should be unnecessary if the targets correctly specify not supporting dylibs and cdylibs.
353
+ return ;
354
+ }
342
355
match output_kind {
343
356
LinkOutputKind :: DynamicNoPicExe => {
344
357
if !self . is_ld && self . sess . target . linker_is_gnu {
@@ -433,7 +446,12 @@ impl<'a> Linker for GccLinker<'a> {
433
446
}
434
447
fn link_staticlib ( & mut self , lib : Symbol , verbatim : bool ) {
435
448
self . hint_static ( ) ;
436
- self . cmd . arg ( format ! ( "-l{}{}" , if verbatim { ":" } else { "" } , lib) ) ;
449
+ if self . sess . target . os == "l4re" {
450
+ // FIXME: Why is this deliberate difference from gcc necessary?
451
+ self . cmd . arg ( format ! ( "-PC{}" , lib) ) ;
452
+ } else {
453
+ self . cmd . arg ( format ! ( "-l{}{}" , if verbatim { ":" } else { "" } , lib) ) ;
454
+ }
437
455
}
438
456
fn link_rlib ( & mut self , lib : & Path ) {
439
457
self . hint_static ( ) ;
@@ -452,14 +470,33 @@ impl<'a> Linker for GccLinker<'a> {
452
470
self . cmd . arg ( path) ;
453
471
}
454
472
fn full_relro ( & mut self ) {
455
- self . linker_arg ( "-zrelro" ) ;
456
- self . linker_arg ( "-znow" ) ;
473
+ if self . sess . target . os == "l4re" {
474
+ // FIXME: Why a comma between `-z` and `relro`?
475
+ // FIXME: Why a comma between `-z,relro and -z,now`?
476
+ // FIXME: Will `-zrelro` without space or comma work?
477
+ self . cmd . arg ( "-z,relro,-z,now" ) ;
478
+ } else {
479
+ self . linker_arg ( "-zrelro" ) ;
480
+ self . linker_arg ( "-znow" ) ;
481
+ }
457
482
}
458
483
fn partial_relro ( & mut self ) {
459
- self . linker_arg ( "-zrelro" ) ;
484
+ if self . sess . target . os == "l4re" {
485
+ // FIXME: Why a comma between `-z` and `relro`?
486
+ // FIXME: Will `-zrelro` without space or comma work?
487
+ self . cmd . arg ( "-z,relro" ) ;
488
+ } else {
489
+ self . linker_arg ( "-zrelro" ) ;
490
+ }
460
491
}
461
492
fn no_relro ( & mut self ) {
462
- self . linker_arg ( "-znorelro" ) ;
493
+ if self . sess . target . os == "l4re" {
494
+ // FIXME: Why a comma between `-z` and `norelro`?
495
+ // FIXME: Will `-znorelro` without space or comma work?
496
+ self . cmd . arg ( "-z,norelro" ) ;
497
+ } else {
498
+ self . linker_arg ( "-znorelro" ) ;
499
+ }
463
500
}
464
501
465
502
fn link_rust_dylib ( & mut self , lib : Symbol , _path : & Path ) {
@@ -537,7 +574,9 @@ impl<'a> Linker for GccLinker<'a> {
537
574
// eliminate the metadata. If we're building an executable, however,
538
575
// --gc-sections drops the size of hello world from 1.8MB to 597K, a 67%
539
576
// reduction.
540
- } else if ( self . sess . target . linker_is_gnu || self . sess . target . is_like_wasm )
577
+ } else if ( self . sess . target . linker_is_gnu
578
+ || self . sess . target . is_like_wasm
579
+ || self . sess . target . os == "l4re" )
541
580
&& !keep_metadata
542
581
{
543
582
self . linker_arg ( "--gc-sections" ) ;
@@ -553,7 +592,11 @@ impl<'a> Linker for GccLinker<'a> {
553
592
}
554
593
555
594
fn optimize ( & mut self ) {
556
- if !self . sess . target . linker_is_gnu && !self . sess . target . is_like_wasm {
595
+ if self . sess . target . os == "l4re" {
596
+ // FIXME: Why the difference with the GNU case below?
597
+ self . cmd . arg ( "-O2" ) ;
598
+ return ;
599
+ } else if !self . sess . target . linker_is_gnu && !self . sess . target . is_like_wasm {
557
600
return ;
558
601
}
559
602
@@ -713,8 +756,13 @@ impl<'a> Linker for GccLinker<'a> {
713
756
}
714
757
715
758
fn subsystem ( & mut self , subsystem : & str ) {
716
- self . linker_arg ( "--subsystem" ) ;
717
- self . linker_arg ( & subsystem) ;
759
+ if self . sess . target . os == "l4re" {
760
+ // FIXME: Why the comma between --subsystem and its name?
761
+ self . cmd . arg ( & format ! ( "--subsystem,{}" , subsystem) ) ;
762
+ } else {
763
+ self . linker_arg ( "--subsystem" ) ;
764
+ self . linker_arg ( & subsystem) ;
765
+ }
718
766
}
719
767
720
768
fn reset_per_library_state ( & mut self ) {
@@ -1597,3 +1645,31 @@ impl<'a> Linker for BpfLinker<'a> {
1597
1645
1598
1646
fn linker_plugin_lto ( & mut self ) { }
1599
1647
}
1648
+
1649
+ fn add_l4bender_args ( cmd : & mut Command ) {
1650
+ if let Ok ( l4bender_args) = env:: var ( "L4_BENDER_ARGS" ) {
1651
+ // This parses a shell-escaped string and unquotes the arguments. It doesn't attempt to
1652
+ // completely understand shell, but should instead allow passing arguments like
1653
+ // `-Dlinker="ld -m x86_64"`, and a copy without quotes, but spaces preserved, is added
1654
+ // as an argument to the given Command. This means that constructs as \" are not
1655
+ // understood, so quote wisely.
1656
+ let mut arg = String :: new ( ) ;
1657
+ let mut quoted = false ;
1658
+ for character in l4bender_args. chars ( ) {
1659
+ match character {
1660
+ ' ' if !quoted => {
1661
+ cmd. arg ( & arg) ;
1662
+ arg. clear ( ) ;
1663
+ }
1664
+ '"' | '\'' => quoted = !quoted,
1665
+ _ => arg. push ( character) ,
1666
+ } ;
1667
+ }
1668
+ if arg. len ( ) > 0 {
1669
+ cmd. arg ( & arg) ;
1670
+ arg. clear ( ) ;
1671
+ }
1672
+ }
1673
+
1674
+ cmd. arg ( "--" ) ; // separate direct l4-bender args from linker args
1675
+ }
0 commit comments