@@ -337,7 +337,12 @@ pub(crate) trait Linker {
337337 fn debuginfo ( & mut self , strip : Strip , natvis_debugger_visualizers : & [ PathBuf ] ) ;
338338 fn no_crt_objects ( & mut self ) ;
339339 fn no_default_libraries ( & mut self ) ;
340- fn export_symbols ( & mut self , tmpdir : & Path , crate_type : CrateType , symbols : & [ String ] ) ;
340+ fn export_symbols (
341+ & mut self ,
342+ tmpdir : & Path ,
343+ crate_type : CrateType ,
344+ symbols : & [ ( String , SymbolExportKind ) ] ,
345+ ) ;
341346 fn subsystem ( & mut self , subsystem : & str ) ;
342347 fn linker_plugin_lto ( & mut self ) ;
343348 fn add_eh_frame_header ( & mut self ) { }
@@ -770,7 +775,12 @@ impl<'a> Linker for GccLinker<'a> {
770775 }
771776 }
772777
773- fn export_symbols ( & mut self , tmpdir : & Path , crate_type : CrateType , symbols : & [ String ] ) {
778+ fn export_symbols (
779+ & mut self ,
780+ tmpdir : & Path ,
781+ crate_type : CrateType ,
782+ symbols : & [ ( String , SymbolExportKind ) ] ,
783+ ) {
774784 // Symbol visibility in object files typically takes care of this.
775785 if crate_type == CrateType :: Executable {
776786 let should_export_executable_symbols =
@@ -799,7 +809,7 @@ impl<'a> Linker for GccLinker<'a> {
799809 // Write a plain, newline-separated list of symbols
800810 let res: io:: Result < ( ) > = try {
801811 let mut f = File :: create_buffered ( & path) ?;
802- for sym in symbols {
812+ for ( sym, _ ) in symbols {
803813 debug ! ( " _{sym}" ) ;
804814 writeln ! ( f, "_{sym}" ) ?;
805815 }
@@ -814,11 +824,12 @@ impl<'a> Linker for GccLinker<'a> {
814824 // .def file similar to MSVC one but without LIBRARY section
815825 // because LD doesn't like when it's empty
816826 writeln ! ( f, "EXPORTS" ) ?;
817- for symbol in symbols {
827+ for ( symbol, kind) in symbols {
828+ let kind_marker = if * kind == SymbolExportKind :: Data { " DATA" } else { "" } ;
818829 debug ! ( " _{symbol}" ) ;
819830 // Quote the name in case it's reserved by linker in some way
820831 // (this accounts for names with dots in particular).
821- writeln ! ( f, " \" {symbol}\" " ) ?;
832+ writeln ! ( f, " \" {symbol}\" {kind_marker} " ) ?;
822833 }
823834 } ;
824835 if let Err ( error) = res {
@@ -831,7 +842,7 @@ impl<'a> Linker for GccLinker<'a> {
831842 writeln ! ( f, "{{" ) ?;
832843 if !symbols. is_empty ( ) {
833844 writeln ! ( f, " global:" ) ?;
834- for sym in symbols {
845+ for ( sym, _ ) in symbols {
835846 debug ! ( " {sym};" ) ;
836847 writeln ! ( f, " {sym};" ) ?;
837848 }
@@ -1098,7 +1109,12 @@ impl<'a> Linker for MsvcLinker<'a> {
10981109 // crates. Upstream rlibs may be linked statically to this dynamic library,
10991110 // in which case they may continue to transitively be used and hence need
11001111 // their symbols exported.
1101- fn export_symbols ( & mut self , tmpdir : & Path , crate_type : CrateType , symbols : & [ String ] ) {
1112+ fn export_symbols (
1113+ & mut self ,
1114+ tmpdir : & Path ,
1115+ crate_type : CrateType ,
1116+ symbols : & [ ( String , SymbolExportKind ) ] ,
1117+ ) {
11021118 // Symbol visibility takes care of this typically
11031119 if crate_type == CrateType :: Executable {
11041120 let should_export_executable_symbols =
@@ -1116,9 +1132,10 @@ impl<'a> Linker for MsvcLinker<'a> {
11161132 // straight to exports.
11171133 writeln ! ( f, "LIBRARY" ) ?;
11181134 writeln ! ( f, "EXPORTS" ) ?;
1119- for symbol in symbols {
1135+ for ( symbol, kind) in symbols {
1136+ let kind_marker = if * kind == SymbolExportKind :: Data { " DATA" } else { "" } ;
11201137 debug ! ( " _{symbol}" ) ;
1121- writeln ! ( f, " {symbol}" ) ?;
1138+ writeln ! ( f, " {symbol}{kind_marker} " ) ?;
11221139 }
11231140 } ;
11241141 if let Err ( error) = res {
@@ -1259,14 +1276,19 @@ impl<'a> Linker for EmLinker<'a> {
12591276 self . cc_arg ( "-nodefaultlibs" ) ;
12601277 }
12611278
1262- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1279+ fn export_symbols (
1280+ & mut self ,
1281+ _tmpdir : & Path ,
1282+ _crate_type : CrateType ,
1283+ symbols : & [ ( String , SymbolExportKind ) ] ,
1284+ ) {
12631285 debug ! ( "EXPORTED SYMBOLS:" ) ;
12641286
12651287 self . cc_arg ( "-s" ) ;
12661288
12671289 let mut arg = OsString :: from ( "EXPORTED_FUNCTIONS=" ) ;
12681290 let encoded = serde_json:: to_string (
1269- & symbols. iter ( ) . map ( |sym| "_" . to_owned ( ) + sym) . collect :: < Vec < _ > > ( ) ,
1291+ & symbols. iter ( ) . map ( |( sym, _ ) | "_" . to_owned ( ) + sym) . collect :: < Vec < _ > > ( ) ,
12701292 )
12711293 . unwrap ( ) ;
12721294 debug ! ( "{encoded}" ) ;
@@ -1428,8 +1450,13 @@ impl<'a> Linker for WasmLd<'a> {
14281450
14291451 fn no_default_libraries ( & mut self ) { }
14301452
1431- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1432- for sym in symbols {
1453+ fn export_symbols (
1454+ & mut self ,
1455+ _tmpdir : & Path ,
1456+ _crate_type : CrateType ,
1457+ symbols : & [ ( String , SymbolExportKind ) ] ,
1458+ ) {
1459+ for ( sym, _) in symbols {
14331460 self . link_args ( & [ "--export" , sym] ) ;
14341461 }
14351462
@@ -1563,7 +1590,7 @@ impl<'a> Linker for L4Bender<'a> {
15631590 self . cc_arg ( "-nostdlib" ) ;
15641591 }
15651592
1566- fn export_symbols ( & mut self , _: & Path , _: CrateType , _: & [ String ] ) {
1593+ fn export_symbols ( & mut self , _: & Path , _: CrateType , _: & [ ( String , SymbolExportKind ) ] ) {
15671594 // ToDo, not implemented, copy from GCC
15681595 self . sess . dcx ( ) . emit_warn ( errors:: L4BenderExportingSymbolsUnimplemented ) ;
15691596 }
@@ -1720,12 +1747,17 @@ impl<'a> Linker for AixLinker<'a> {
17201747
17211748 fn no_default_libraries ( & mut self ) { }
17221749
1723- fn export_symbols ( & mut self , tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1750+ fn export_symbols (
1751+ & mut self ,
1752+ tmpdir : & Path ,
1753+ _crate_type : CrateType ,
1754+ symbols : & [ ( String , SymbolExportKind ) ] ,
1755+ ) {
17241756 let path = tmpdir. join ( "list.exp" ) ;
17251757 let res: io:: Result < ( ) > = try {
17261758 let mut f = File :: create_buffered ( & path) ?;
17271759 // FIXME: use llvm-nm to generate export list.
1728- for symbol in symbols {
1760+ for ( symbol, _ ) in symbols {
17291761 debug ! ( " _{symbol}" ) ;
17301762 writeln ! ( f, " {symbol}" ) ?;
17311763 }
@@ -1769,9 +1801,23 @@ fn for_each_exported_symbols_include_dep<'tcx>(
17691801 }
17701802}
17711803
1772- pub ( crate ) fn exported_symbols ( tcx : TyCtxt < ' _ > , crate_type : CrateType ) -> Vec < String > {
1804+ pub ( crate ) fn exported_symbols (
1805+ tcx : TyCtxt < ' _ > ,
1806+ crate_type : CrateType ,
1807+ ) -> Vec < ( String , SymbolExportKind ) > {
17731808 if let Some ( ref exports) = tcx. sess . target . override_export_symbols {
1774- return exports. iter ( ) . map ( ToString :: to_string) . collect ( ) ;
1809+ return exports
1810+ . iter ( )
1811+ . map ( |name| {
1812+ (
1813+ name. to_string ( ) ,
1814+ // FIXME use the correct export kind for this symbol. override_export_symbols
1815+ // can't directly specify the SymbolExportKind as it is defined in rustc_middle
1816+ // which rustc_target can't depend on.
1817+ SymbolExportKind :: Text ,
1818+ )
1819+ } )
1820+ . collect ( ) ;
17751821 }
17761822
17771823 if let CrateType :: ProcMacro = crate_type {
@@ -1781,16 +1827,20 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
17811827 }
17821828}
17831829
1784- fn exported_symbols_for_non_proc_macro ( tcx : TyCtxt < ' _ > , crate_type : CrateType ) -> Vec < String > {
1830+ fn exported_symbols_for_non_proc_macro (
1831+ tcx : TyCtxt < ' _ > ,
1832+ crate_type : CrateType ,
1833+ ) -> Vec < ( String , SymbolExportKind ) > {
17851834 let mut symbols = Vec :: new ( ) ;
17861835 let export_threshold = symbol_export:: crates_export_threshold ( & [ crate_type] ) ;
17871836 for_each_exported_symbols_include_dep ( tcx, crate_type, |symbol, info, cnum| {
17881837 // Do not export mangled symbols from cdylibs and don't attempt to export compiler-builtins
17891838 // from any cdylib. The latter doesn't work anyway as we use hidden visibility for
17901839 // compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
17911840 if info. level . is_below_threshold ( export_threshold) && !tcx. is_compiler_builtins ( cnum) {
1792- symbols. push ( symbol_export:: exporting_symbol_name_for_instance_in_crate (
1793- tcx, symbol, cnum,
1841+ symbols. push ( (
1842+ symbol_export:: exporting_symbol_name_for_instance_in_crate ( tcx, symbol, cnum) ,
1843+ info. kind ,
17941844 ) ) ;
17951845 symbol_export:: extend_exported_symbols ( & mut symbols, tcx, symbol, cnum) ;
17961846 }
@@ -1799,7 +1849,7 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
17991849 symbols
18001850}
18011851
1802- fn exported_symbols_for_proc_macro_crate ( tcx : TyCtxt < ' _ > ) -> Vec < String > {
1852+ fn exported_symbols_for_proc_macro_crate ( tcx : TyCtxt < ' _ > ) -> Vec < ( String , SymbolExportKind ) > {
18031853 // `exported_symbols` will be empty when !should_codegen.
18041854 if !tcx. sess . opts . output_types . should_codegen ( ) {
18051855 return Vec :: new ( ) ;
@@ -1809,7 +1859,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
18091859 let proc_macro_decls_name = tcx. sess . generate_proc_macro_decls_symbol ( stable_crate_id) ;
18101860 let metadata_symbol_name = exported_symbols:: metadata_symbol_name ( tcx) ;
18111861
1812- vec ! [ proc_macro_decls_name, metadata_symbol_name]
1862+ vec ! [
1863+ ( proc_macro_decls_name, SymbolExportKind :: Data ) ,
1864+ ( metadata_symbol_name, SymbolExportKind :: Data ) ,
1865+ ]
18131866}
18141867
18151868pub ( crate ) fn linked_symbols (
@@ -1831,7 +1884,9 @@ pub(crate) fn linked_symbols(
18311884 || info. used
18321885 {
18331886 symbols. push ( (
1834- symbol_export:: linking_symbol_name_for_instance_in_crate ( tcx, symbol, cnum) ,
1887+ symbol_export:: linking_symbol_name_for_instance_in_crate (
1888+ tcx, symbol, info. kind , cnum,
1889+ ) ,
18351890 info. kind ,
18361891 ) ) ;
18371892 }
@@ -1906,7 +1961,13 @@ impl<'a> Linker for PtxLinker<'a> {
19061961
19071962 fn ehcont_guard ( & mut self ) { }
19081963
1909- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , _symbols : & [ String ] ) { }
1964+ fn export_symbols (
1965+ & mut self ,
1966+ _tmpdir : & Path ,
1967+ _crate_type : CrateType ,
1968+ _symbols : & [ ( String , SymbolExportKind ) ] ,
1969+ ) {
1970+ }
19101971
19111972 fn subsystem ( & mut self , _subsystem : & str ) { }
19121973
@@ -1975,10 +2036,15 @@ impl<'a> Linker for LlbcLinker<'a> {
19752036
19762037 fn ehcont_guard ( & mut self ) { }
19772038
1978- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
2039+ fn export_symbols (
2040+ & mut self ,
2041+ _tmpdir : & Path ,
2042+ _crate_type : CrateType ,
2043+ symbols : & [ ( String , SymbolExportKind ) ] ,
2044+ ) {
19792045 match _crate_type {
19802046 CrateType :: Cdylib => {
1981- for sym in symbols {
2047+ for ( sym, _ ) in symbols {
19822048 self . link_args ( & [ "--export-symbol" , sym] ) ;
19832049 }
19842050 }
@@ -2052,11 +2118,16 @@ impl<'a> Linker for BpfLinker<'a> {
20522118
20532119 fn ehcont_guard ( & mut self ) { }
20542120
2055- fn export_symbols ( & mut self , tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
2121+ fn export_symbols (
2122+ & mut self ,
2123+ tmpdir : & Path ,
2124+ _crate_type : CrateType ,
2125+ symbols : & [ ( String , SymbolExportKind ) ] ,
2126+ ) {
20562127 let path = tmpdir. join ( "symbols" ) ;
20572128 let res: io:: Result < ( ) > = try {
20582129 let mut f = File :: create_buffered ( & path) ?;
2059- for sym in symbols {
2130+ for ( sym, _ ) in symbols {
20602131 writeln ! ( f, "{sym}" ) ?;
20612132 }
20622133 } ;
0 commit comments