@@ -10,9 +10,10 @@ use rustc_middle::middle::exported_symbols::{
1010 ExportedSymbol , SymbolExportInfo , SymbolExportKind , SymbolExportLevel , metadata_symbol_name,
1111} ;
1212use 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 } ;
1414use rustc_middle:: util:: Providers ;
1515use rustc_session:: config:: { CrateType , OomStrategy } ;
16+ use rustc_target:: callconv:: Conv ;
1617use rustc_target:: spec:: { SanitizerSet , TlsModel } ;
1718use tracing:: debug;
1819
@@ -551,6 +552,41 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
551552 }
552553}
553554
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+ . unwrap_or ( ( Conv :: Rust , & [ ] ) )
588+ }
589+
554590/// This is the symbol name of the given instance as seen by the linker.
555591///
556592/// On 32-bit Windows symbols are decorated according to their calling conventions.
@@ -559,8 +595,6 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
559595 symbol : ExportedSymbol < ' tcx > ,
560596 instantiating_crate : CrateNum ,
561597) -> String {
562- use rustc_target:: callconv:: Conv ;
563-
564598 let mut undecorated = symbol_name_for_instance_in_crate ( tcx, symbol, instantiating_crate) ;
565599
566600 // thread local will not be a function call,
@@ -584,35 +618,7 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
584618 _ => return undecorated,
585619 } ;
586620
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 , & [ ] ) ) ;
621+ let ( conv, args) = calling_convention_for_symbol ( tcx, symbol) ;
616622
617623 // Decorate symbols with prefixes, suffixes and total number of bytes of arguments.
618624 // Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170
@@ -644,6 +650,27 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
644650 maybe_emutls_symbol_name ( tcx, symbol, & undecorated) . unwrap_or ( undecorated)
645651}
646652
653+ /// On amdhsa, `gpu-kernel` functions have an associated metadata object with a `.kd` suffix.
654+ /// Add it to the symbols list for all kernel functions, so that it is exported in the linked
655+ /// object.
656+ pub ( crate ) fn extend_exported_symbols < ' tcx > (
657+ symbols : & mut Vec < String > ,
658+ tcx : TyCtxt < ' tcx > ,
659+ symbol : ExportedSymbol < ' tcx > ,
660+ instantiating_crate : CrateNum ,
661+ ) {
662+ let ( conv, _) = calling_convention_for_symbol ( tcx, symbol) ;
663+
664+ if conv != Conv :: GpuKernel || tcx. sess . target . os != "amdhsa" {
665+ return ;
666+ }
667+
668+ let undecorated = symbol_name_for_instance_in_crate ( tcx, symbol, instantiating_crate) ;
669+
670+ // Add the symbol for the kernel descriptor (with .kd suffix)
671+ symbols. push ( format ! ( "{undecorated}.kd" ) ) ;
672+ }
673+
647674fn maybe_emutls_symbol_name < ' tcx > (
648675 tcx : TyCtxt < ' tcx > ,
649676 symbol : ExportedSymbol < ' tcx > ,
0 commit comments