@@ -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
@@ -584,6 +585,42 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
584
585
}
585
586
}
586
587
588
+ fn calling_convention_for_symbol < ' tcx > (
589
+ tcx : TyCtxt < ' tcx > ,
590
+ symbol : ExportedSymbol < ' tcx > ,
591
+ ) -> ( Conv , & ' tcx [ rustc_target:: callconv:: ArgAbi < ' tcx , Ty < ' tcx > > ] ) {
592
+ let instance = match symbol {
593
+ ExportedSymbol :: NonGeneric ( def_id) | ExportedSymbol :: Generic ( def_id, _)
594
+ if tcx. is_static ( def_id) =>
595
+ {
596
+ None
597
+ }
598
+ ExportedSymbol :: NonGeneric ( def_id) => Some ( Instance :: mono ( tcx, def_id) ) ,
599
+ ExportedSymbol :: Generic ( def_id, args) => Some ( Instance :: new ( def_id, args) ) ,
600
+ // DropGlue always use the Rust calling convention and thus follow the target's default
601
+ // symbol decoration scheme.
602
+ ExportedSymbol :: DropGlue ( ..) => None ,
603
+ // AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
604
+ // target's default symbol decoration scheme.
605
+ ExportedSymbol :: AsyncDropGlueCtorShim ( ..) => None ,
606
+ // NoDefId always follow the target's default symbol decoration scheme.
607
+ ExportedSymbol :: NoDefId ( ..) => None ,
608
+ // ThreadLocalShim always follow the target's default symbol decoration scheme.
609
+ ExportedSymbol :: ThreadLocalShim ( ..) => None ,
610
+ } ;
611
+
612
+ instance
613
+ . map ( |i| {
614
+ tcx. fn_abi_of_instance (
615
+ ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( ( i, ty:: List :: empty ( ) ) ) ,
616
+ )
617
+ . unwrap_or_else ( |_| bug ! ( "fn_abi_of_instance({i:?}) failed" ) )
618
+ } )
619
+ . map ( |fnabi| ( fnabi. conv , & fnabi. args [ ..] ) )
620
+ // FIXME(workingjubilee): why don't we know the convention here?
621
+ . unwrap_or ( ( Conv :: Rust , & [ ] ) )
622
+ }
623
+
587
624
/// This is the symbol name of the given instance as seen by the linker.
588
625
///
589
626
/// On 32-bit Windows symbols are decorated according to their calling conventions.
@@ -592,8 +629,6 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
592
629
symbol : ExportedSymbol < ' tcx > ,
593
630
instantiating_crate : CrateNum ,
594
631
) -> String {
595
- use rustc_target:: callconv:: Conv ;
596
-
597
632
let mut undecorated = symbol_name_for_instance_in_crate ( tcx, symbol, instantiating_crate) ;
598
633
599
634
// thread local will not be a function call,
@@ -617,35 +652,7 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
617
652
_ => return undecorated,
618
653
} ;
619
654
620
- let instance = match symbol {
621
- ExportedSymbol :: NonGeneric ( def_id) | ExportedSymbol :: Generic ( def_id, _)
622
- if tcx. is_static ( def_id) =>
623
- {
624
- None
625
- }
626
- ExportedSymbol :: NonGeneric ( def_id) => Some ( Instance :: mono ( tcx, def_id) ) ,
627
- ExportedSymbol :: Generic ( def_id, args) => Some ( Instance :: new ( def_id, args) ) ,
628
- // DropGlue always use the Rust calling convention and thus follow the target's default
629
- // symbol decoration scheme.
630
- ExportedSymbol :: DropGlue ( ..) => None ,
631
- // AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
632
- // target's default symbol decoration scheme.
633
- ExportedSymbol :: AsyncDropGlueCtorShim ( ..) => None ,
634
- // NoDefId always follow the target's default symbol decoration scheme.
635
- ExportedSymbol :: NoDefId ( ..) => None ,
636
- // ThreadLocalShim always follow the target's default symbol decoration scheme.
637
- ExportedSymbol :: ThreadLocalShim ( ..) => None ,
638
- } ;
639
-
640
- let ( conv, args) = instance
641
- . map ( |i| {
642
- tcx. fn_abi_of_instance (
643
- ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( ( i, ty:: List :: empty ( ) ) ) ,
644
- )
645
- . unwrap_or_else ( |_| bug ! ( "fn_abi_of_instance({i:?}) failed" ) )
646
- } )
647
- . map ( |fnabi| ( fnabi. conv , & fnabi. args [ ..] ) )
648
- . unwrap_or ( ( Conv :: Rust , & [ ] ) ) ;
655
+ let ( conv, args) = calling_convention_for_symbol ( tcx, symbol) ;
649
656
650
657
// Decorate symbols with prefixes, suffixes and total number of bytes of arguments.
651
658
// Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170
@@ -677,6 +684,27 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
677
684
maybe_emutls_symbol_name ( tcx, symbol, & undecorated) . unwrap_or ( undecorated)
678
685
}
679
686
687
+ /// On amdhsa, `gpu-kernel` functions have an associated metadata object with a `.kd` suffix.
688
+ /// Add it to the symbols list for all kernel functions, so that it is exported in the linked
689
+ /// object.
690
+ pub ( crate ) fn extend_exported_symbols < ' tcx > (
691
+ symbols : & mut Vec < String > ,
692
+ tcx : TyCtxt < ' tcx > ,
693
+ symbol : ExportedSymbol < ' tcx > ,
694
+ instantiating_crate : CrateNum ,
695
+ ) {
696
+ let ( conv, _) = calling_convention_for_symbol ( tcx, symbol) ;
697
+
698
+ if conv != Conv :: GpuKernel || tcx. sess . target . os != "amdhsa" {
699
+ return ;
700
+ }
701
+
702
+ let undecorated = symbol_name_for_instance_in_crate ( tcx, symbol, instantiating_crate) ;
703
+
704
+ // Add the symbol for the kernel descriptor (with .kd suffix)
705
+ symbols. push ( format ! ( "{undecorated}.kd" ) ) ;
706
+ }
707
+
680
708
fn maybe_emutls_symbol_name < ' tcx > (
681
709
tcx : TyCtxt < ' tcx > ,
682
710
symbol : ExportedSymbol < ' tcx > ,
0 commit comments