@@ -10,9 +10,10 @@ use rustc_middle::middle::exported_symbols::{
10
10
ExportedSymbol , SymbolExportInfo , SymbolExportKind , SymbolExportLevel , metadata_symbol_name,
11
11
} ;
12
12
use rustc_middle:: query:: LocalCrate ;
13
- use rustc_middle:: ty:: { self , GenericArgKind , GenericArgsRef , Instance , SymbolName , TyCtxt } ;
13
+ use rustc_middle:: ty:: { self , GenericArgKind , GenericArgsRef , Instance , SymbolName , Ty , TyCtxt } ;
14
14
use rustc_middle:: util:: Providers ;
15
15
use rustc_session:: config:: { CrateType , OomStrategy } ;
16
+ use rustc_target:: callconv:: Conv ;
16
17
use rustc_target:: spec:: { SanitizerSet , TlsModel } ;
17
18
use tracing:: debug;
18
19
@@ -551,6 +552,42 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
551
552
}
552
553
}
553
554
555
+ fn calling_convention_for_symbol < ' tcx > (
556
+ tcx : TyCtxt < ' tcx > ,
557
+ symbol : ExportedSymbol < ' tcx > ,
558
+ ) -> ( Conv , & ' tcx [ rustc_target:: callconv:: ArgAbi < ' tcx , Ty < ' tcx > > ] ) {
559
+ let instance = match symbol {
560
+ ExportedSymbol :: NonGeneric ( def_id) | ExportedSymbol :: Generic ( def_id, _)
561
+ if tcx. is_static ( def_id) =>
562
+ {
563
+ None
564
+ }
565
+ ExportedSymbol :: NonGeneric ( def_id) => Some ( Instance :: mono ( tcx, def_id) ) ,
566
+ ExportedSymbol :: Generic ( def_id, args) => Some ( Instance :: new ( def_id, args) ) ,
567
+ // DropGlue always use the Rust calling convention and thus follow the target's default
568
+ // symbol decoration scheme.
569
+ ExportedSymbol :: DropGlue ( ..) => None ,
570
+ // AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
571
+ // target's default symbol decoration scheme.
572
+ ExportedSymbol :: AsyncDropGlueCtorShim ( ..) => None ,
573
+ // NoDefId always follow the target's default symbol decoration scheme.
574
+ ExportedSymbol :: NoDefId ( ..) => None ,
575
+ // ThreadLocalShim always follow the target's default symbol decoration scheme.
576
+ ExportedSymbol :: ThreadLocalShim ( ..) => None ,
577
+ } ;
578
+
579
+ instance
580
+ . map ( |i| {
581
+ tcx. fn_abi_of_instance (
582
+ ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( ( i, ty:: List :: empty ( ) ) ) ,
583
+ )
584
+ . unwrap_or_else ( |_| bug ! ( "fn_abi_of_instance({i:?}) failed" ) )
585
+ } )
586
+ . map ( |fnabi| ( fnabi. conv , & fnabi. args [ ..] ) )
587
+ // FIXME(workingjubilee): why don't we know the convention here?
588
+ . unwrap_or ( ( Conv :: Rust , & [ ] ) )
589
+ }
590
+
554
591
/// This is the symbol name of the given instance as seen by the linker.
555
592
///
556
593
/// On 32-bit Windows symbols are decorated according to their calling conventions.
@@ -559,8 +596,6 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
559
596
symbol : ExportedSymbol < ' tcx > ,
560
597
instantiating_crate : CrateNum ,
561
598
) -> String {
562
- use rustc_target:: callconv:: Conv ;
563
-
564
599
let mut undecorated = symbol_name_for_instance_in_crate ( tcx, symbol, instantiating_crate) ;
565
600
566
601
// thread local will not be a function call,
@@ -584,35 +619,7 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
584
619
_ => return undecorated,
585
620
} ;
586
621
587
- let instance = match symbol {
588
- ExportedSymbol :: NonGeneric ( def_id) | ExportedSymbol :: Generic ( def_id, _)
589
- if tcx. is_static ( def_id) =>
590
- {
591
- None
592
- }
593
- ExportedSymbol :: NonGeneric ( def_id) => Some ( Instance :: mono ( tcx, def_id) ) ,
594
- ExportedSymbol :: Generic ( def_id, args) => Some ( Instance :: new ( def_id, args) ) ,
595
- // DropGlue always use the Rust calling convention and thus follow the target's default
596
- // symbol decoration scheme.
597
- ExportedSymbol :: DropGlue ( ..) => None ,
598
- // AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
599
- // target's default symbol decoration scheme.
600
- ExportedSymbol :: AsyncDropGlueCtorShim ( ..) => None ,
601
- // NoDefId always follow the target's default symbol decoration scheme.
602
- ExportedSymbol :: NoDefId ( ..) => None ,
603
- // ThreadLocalShim always follow the target's default symbol decoration scheme.
604
- ExportedSymbol :: ThreadLocalShim ( ..) => None ,
605
- } ;
606
-
607
- let ( conv, args) = instance
608
- . map ( |i| {
609
- tcx. fn_abi_of_instance (
610
- ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( ( i, ty:: List :: empty ( ) ) ) ,
611
- )
612
- . unwrap_or_else ( |_| bug ! ( "fn_abi_of_instance({i:?}) failed" ) )
613
- } )
614
- . map ( |fnabi| ( fnabi. conv , & fnabi. args [ ..] ) )
615
- . unwrap_or ( ( Conv :: Rust , & [ ] ) ) ;
622
+ let ( conv, args) = calling_convention_for_symbol ( tcx, symbol) ;
616
623
617
624
// Decorate symbols with prefixes, suffixes and total number of bytes of arguments.
618
625
// Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170
@@ -644,6 +651,27 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
644
651
maybe_emutls_symbol_name ( tcx, symbol, & undecorated) . unwrap_or ( undecorated)
645
652
}
646
653
654
+ /// On amdhsa, `gpu-kernel` functions have an associated metadata object with a `.kd` suffix.
655
+ /// Add it to the symbols list for all kernel functions, so that it is exported in the linked
656
+ /// object.
657
+ pub ( crate ) fn extend_exported_symbols < ' tcx > (
658
+ symbols : & mut Vec < String > ,
659
+ tcx : TyCtxt < ' tcx > ,
660
+ symbol : ExportedSymbol < ' tcx > ,
661
+ instantiating_crate : CrateNum ,
662
+ ) {
663
+ let ( conv, _) = calling_convention_for_symbol ( tcx, symbol) ;
664
+
665
+ if conv != Conv :: GpuKernel || tcx. sess . target . os != "amdhsa" {
666
+ return ;
667
+ }
668
+
669
+ let undecorated = symbol_name_for_instance_in_crate ( tcx, symbol, instantiating_crate) ;
670
+
671
+ // Add the symbol for the kernel descriptor (with .kd suffix)
672
+ symbols. push ( format ! ( "{undecorated}.kd" ) ) ;
673
+ }
674
+
647
675
fn maybe_emutls_symbol_name < ' tcx > (
648
676
tcx : TyCtxt < ' tcx > ,
649
677
symbol : ExportedSymbol < ' tcx > ,
0 commit comments