@@ -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 }
@@ -808,30 +818,15 @@ impl<'a> Linker for GccLinker<'a> {
808818 self . sess . dcx ( ) . emit_fatal ( errors:: LibDefWriteFailure { error } ) ;
809819 }
810820 } else if is_windows {
811- let res: io:: Result < ( ) > = try {
812- let mut f = File :: create_buffered ( & path) ?;
813-
814- // .def file similar to MSVC one but without LIBRARY section
815- // because LD doesn't like when it's empty
816- writeln ! ( f, "EXPORTS" ) ?;
817- for symbol in symbols {
818- debug ! ( " _{symbol}" ) ;
819- // Quote the name in case it's reserved by linker in some way
820- // (this accounts for names with dots in particular).
821- writeln ! ( f, " \" {symbol}\" " ) ?;
822- }
823- } ;
824- if let Err ( error) = res {
825- self . sess . dcx ( ) . emit_fatal ( errors:: LibDefWriteFailure { error } ) ;
826- }
821+ // We already add -export arguments to the .drectve section of symbols.o
827822 } else {
828823 // Write an LD version script
829824 let res: io:: Result < ( ) > = try {
830825 let mut f = File :: create_buffered ( & path) ?;
831826 writeln ! ( f, "{{" ) ?;
832827 if !symbols. is_empty ( ) {
833828 writeln ! ( f, " global:" ) ?;
834- for sym in symbols {
829+ for ( sym, _ ) in symbols {
835830 debug ! ( " {sym};" ) ;
836831 writeln ! ( f, " {sym};" ) ?;
837832 }
@@ -1086,47 +1081,13 @@ impl<'a> Linker for MsvcLinker<'a> {
10861081 }
10871082 }
10881083
1089- // Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
1090- // export symbols from a dynamic library. When building a dynamic library,
1091- // however, we're going to want some symbols exported, so this function
1092- // generates a DEF file which lists all the symbols.
1093- //
1094- // The linker will read this `*.def` file and export all the symbols from
1095- // the dynamic library. Note that this is not as simple as just exporting
1096- // all the symbols in the current crate (as specified by `codegen.reachable`)
1097- // but rather we also need to possibly export the symbols of upstream
1098- // crates. Upstream rlibs may be linked statically to this dynamic library,
1099- // in which case they may continue to transitively be used and hence need
1100- // their symbols exported.
1101- fn export_symbols ( & mut self , tmpdir : & Path , crate_type : CrateType , symbols : & [ String ] ) {
1102- // Symbol visibility takes care of this typically
1103- if crate_type == CrateType :: Executable {
1104- let should_export_executable_symbols =
1105- self . sess . opts . unstable_opts . export_executable_symbols ;
1106- if !should_export_executable_symbols {
1107- return ;
1108- }
1109- }
1110-
1111- let path = tmpdir. join ( "lib.def" ) ;
1112- let res: io:: Result < ( ) > = try {
1113- let mut f = File :: create_buffered ( & path) ?;
1114-
1115- // Start off with the standard module name header and then go
1116- // straight to exports.
1117- writeln ! ( f, "LIBRARY" ) ?;
1118- writeln ! ( f, "EXPORTS" ) ?;
1119- for symbol in symbols {
1120- debug ! ( " _{symbol}" ) ;
1121- writeln ! ( f, " {symbol}" ) ?;
1122- }
1123- } ;
1124- if let Err ( error) = res {
1125- self . sess . dcx ( ) . emit_fatal ( errors:: LibDefWriteFailure { error } ) ;
1126- }
1127- let mut arg = OsString :: from ( "/DEF:" ) ;
1128- arg. push ( path) ;
1129- self . link_arg ( & arg) ;
1084+ fn export_symbols (
1085+ & mut self ,
1086+ _tmpdir : & Path ,
1087+ _crate_type : CrateType ,
1088+ _symbols : & [ ( String , SymbolExportKind ) ] ,
1089+ ) {
1090+ // We already add /EXPORT arguments to the .drectve section of symbols.o
11301091 }
11311092
11321093 fn subsystem ( & mut self , subsystem : & str ) {
@@ -1259,14 +1220,19 @@ impl<'a> Linker for EmLinker<'a> {
12591220 self . cc_arg ( "-nodefaultlibs" ) ;
12601221 }
12611222
1262- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1223+ fn export_symbols (
1224+ & mut self ,
1225+ _tmpdir : & Path ,
1226+ _crate_type : CrateType ,
1227+ symbols : & [ ( String , SymbolExportKind ) ] ,
1228+ ) {
12631229 debug ! ( "EXPORTED SYMBOLS:" ) ;
12641230
12651231 self . cc_arg ( "-s" ) ;
12661232
12671233 let mut arg = OsString :: from ( "EXPORTED_FUNCTIONS=" ) ;
12681234 let encoded = serde_json:: to_string (
1269- & symbols. iter ( ) . map ( |sym| "_" . to_owned ( ) + sym) . collect :: < Vec < _ > > ( ) ,
1235+ & symbols. iter ( ) . map ( |( sym, _ ) | "_" . to_owned ( ) + sym) . collect :: < Vec < _ > > ( ) ,
12701236 )
12711237 . unwrap ( ) ;
12721238 debug ! ( "{encoded}" ) ;
@@ -1428,8 +1394,13 @@ impl<'a> Linker for WasmLd<'a> {
14281394
14291395 fn no_default_libraries ( & mut self ) { }
14301396
1431- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1432- for sym in symbols {
1397+ fn export_symbols (
1398+ & mut self ,
1399+ _tmpdir : & Path ,
1400+ _crate_type : CrateType ,
1401+ symbols : & [ ( String , SymbolExportKind ) ] ,
1402+ ) {
1403+ for ( sym, _) in symbols {
14331404 self . link_args ( & [ "--export" , sym] ) ;
14341405 }
14351406
@@ -1563,7 +1534,7 @@ impl<'a> Linker for L4Bender<'a> {
15631534 self . cc_arg ( "-nostdlib" ) ;
15641535 }
15651536
1566- fn export_symbols ( & mut self , _: & Path , _: CrateType , _: & [ String ] ) {
1537+ fn export_symbols ( & mut self , _: & Path , _: CrateType , _: & [ ( String , SymbolExportKind ) ] ) {
15671538 // ToDo, not implemented, copy from GCC
15681539 self . sess . dcx ( ) . emit_warn ( errors:: L4BenderExportingSymbolsUnimplemented ) ;
15691540 }
@@ -1720,12 +1691,17 @@ impl<'a> Linker for AixLinker<'a> {
17201691
17211692 fn no_default_libraries ( & mut self ) { }
17221693
1723- fn export_symbols ( & mut self , tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1694+ fn export_symbols (
1695+ & mut self ,
1696+ tmpdir : & Path ,
1697+ _crate_type : CrateType ,
1698+ symbols : & [ ( String , SymbolExportKind ) ] ,
1699+ ) {
17241700 let path = tmpdir. join ( "list.exp" ) ;
17251701 let res: io:: Result < ( ) > = try {
17261702 let mut f = File :: create_buffered ( & path) ?;
17271703 // FIXME: use llvm-nm to generate export list.
1728- for symbol in symbols {
1704+ for ( symbol, _ ) in symbols {
17291705 debug ! ( " _{symbol}" ) ;
17301706 writeln ! ( f, " {symbol}" ) ?;
17311707 }
@@ -1769,9 +1745,15 @@ fn for_each_exported_symbols_include_dep<'tcx>(
17691745 }
17701746}
17711747
1772- pub ( crate ) fn exported_symbols ( tcx : TyCtxt < ' _ > , crate_type : CrateType ) -> Vec < String > {
1748+ pub ( crate ) fn exported_symbols (
1749+ tcx : TyCtxt < ' _ > ,
1750+ crate_type : CrateType ,
1751+ ) -> Vec < ( String , SymbolExportKind ) > {
17731752 if let Some ( ref exports) = tcx. sess . target . override_export_symbols {
1774- return exports. iter ( ) . map ( ToString :: to_string) . collect ( ) ;
1753+ return exports
1754+ . iter ( )
1755+ . map ( |sym| ( sym. to_string ( ) , SymbolExportKind :: Text /* FIXME */ ) )
1756+ . collect ( ) ;
17751757 }
17761758
17771759 if let CrateType :: ProcMacro = crate_type {
@@ -1781,16 +1763,20 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
17811763 }
17821764}
17831765
1784- fn exported_symbols_for_non_proc_macro ( tcx : TyCtxt < ' _ > , crate_type : CrateType ) -> Vec < String > {
1766+ fn exported_symbols_for_non_proc_macro (
1767+ tcx : TyCtxt < ' _ > ,
1768+ crate_type : CrateType ,
1769+ ) -> Vec < ( String , SymbolExportKind ) > {
17851770 let mut symbols = Vec :: new ( ) ;
17861771 let export_threshold = symbol_export:: crates_export_threshold ( & [ crate_type] ) ;
17871772 for_each_exported_symbols_include_dep ( tcx, crate_type, |symbol, info, cnum| {
17881773 // Do not export mangled symbols from cdylibs and don't attempt to export compiler-builtins
17891774 // from any cdylib. The latter doesn't work anyway as we use hidden visibility for
17901775 // compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
17911776 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,
1777+ symbols. push ( (
1778+ symbol_export:: exporting_symbol_name_for_instance_in_crate ( tcx, symbol, cnum) ,
1779+ info. kind ,
17941780 ) ) ;
17951781 symbol_export:: extend_exported_symbols ( & mut symbols, tcx, symbol, cnum) ;
17961782 }
@@ -1799,7 +1785,7 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
17991785 symbols
18001786}
18011787
1802- fn exported_symbols_for_proc_macro_crate ( tcx : TyCtxt < ' _ > ) -> Vec < String > {
1788+ fn exported_symbols_for_proc_macro_crate ( tcx : TyCtxt < ' _ > ) -> Vec < ( String , SymbolExportKind ) > {
18031789 // `exported_symbols` will be empty when !should_codegen.
18041790 if !tcx. sess . opts . output_types . should_codegen ( ) {
18051791 return Vec :: new ( ) ;
@@ -1809,7 +1795,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
18091795 let proc_macro_decls_name = tcx. sess . generate_proc_macro_decls_symbol ( stable_crate_id) ;
18101796 let metadata_symbol_name = exported_symbols:: metadata_symbol_name ( tcx) ;
18111797
1812- vec ! [ proc_macro_decls_name, metadata_symbol_name]
1798+ vec ! [
1799+ ( proc_macro_decls_name, SymbolExportKind :: Data ) ,
1800+ ( metadata_symbol_name, SymbolExportKind :: Data ) ,
1801+ ]
18131802}
18141803
18151804pub ( crate ) fn linked_symbols (
@@ -1906,7 +1895,13 @@ impl<'a> Linker for PtxLinker<'a> {
19061895
19071896 fn ehcont_guard ( & mut self ) { }
19081897
1909- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , _symbols : & [ String ] ) { }
1898+ fn export_symbols (
1899+ & mut self ,
1900+ _tmpdir : & Path ,
1901+ _crate_type : CrateType ,
1902+ _symbols : & [ ( String , SymbolExportKind ) ] ,
1903+ ) {
1904+ }
19101905
19111906 fn subsystem ( & mut self , _subsystem : & str ) { }
19121907
@@ -1975,10 +1970,15 @@ impl<'a> Linker for LlbcLinker<'a> {
19751970
19761971 fn ehcont_guard ( & mut self ) { }
19771972
1978- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1973+ fn export_symbols (
1974+ & mut self ,
1975+ _tmpdir : & Path ,
1976+ _crate_type : CrateType ,
1977+ symbols : & [ ( String , SymbolExportKind ) ] ,
1978+ ) {
19791979 match _crate_type {
19801980 CrateType :: Cdylib => {
1981- for sym in symbols {
1981+ for ( sym, _ ) in symbols {
19821982 self . link_args ( & [ "--export-symbol" , sym] ) ;
19831983 }
19841984 }
@@ -2052,11 +2052,16 @@ impl<'a> Linker for BpfLinker<'a> {
20522052
20532053 fn ehcont_guard ( & mut self ) { }
20542054
2055- fn export_symbols ( & mut self , tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
2055+ fn export_symbols (
2056+ & mut self ,
2057+ tmpdir : & Path ,
2058+ _crate_type : CrateType ,
2059+ symbols : & [ ( String , SymbolExportKind ) ] ,
2060+ ) {
20562061 let path = tmpdir. join ( "symbols" ) ;
20572062 let res: io:: Result < ( ) > = try {
20582063 let mut f = File :: create_buffered ( & path) ?;
2059- for sym in symbols {
2064+ for ( sym, _ ) in symbols {
20602065 writeln ! ( f, "{sym}" ) ?;
20612066 }
20622067 } ;
0 commit comments