@@ -337,7 +337,12 @@ pub(crate) trait Linker {
337
337
fn debuginfo ( & mut self , strip : Strip , natvis_debugger_visualizers : & [ PathBuf ] ) ;
338
338
fn no_crt_objects ( & mut self ) ;
339
339
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
+ ) ;
341
346
fn subsystem ( & mut self , subsystem : & str ) ;
342
347
fn linker_plugin_lto ( & mut self ) ;
343
348
fn add_eh_frame_header ( & mut self ) { }
@@ -770,7 +775,12 @@ impl<'a> Linker for GccLinker<'a> {
770
775
}
771
776
}
772
777
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
+ ) {
774
784
// Symbol visibility in object files typically takes care of this.
775
785
if crate_type == CrateType :: Executable {
776
786
let should_export_executable_symbols =
@@ -799,7 +809,7 @@ impl<'a> Linker for GccLinker<'a> {
799
809
// Write a plain, newline-separated list of symbols
800
810
let res: io:: Result < ( ) > = try {
801
811
let mut f = File :: create_buffered ( & path) ?;
802
- for sym in symbols {
812
+ for ( sym, _ ) in symbols {
803
813
debug ! ( " _{sym}" ) ;
804
814
writeln ! ( f, "_{sym}" ) ?;
805
815
}
@@ -808,30 +818,15 @@ impl<'a> Linker for GccLinker<'a> {
808
818
self . sess . dcx ( ) . emit_fatal ( errors:: LibDefWriteFailure { error } ) ;
809
819
}
810
820
} 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
827
822
} else {
828
823
// Write an LD version script
829
824
let res: io:: Result < ( ) > = try {
830
825
let mut f = File :: create_buffered ( & path) ?;
831
826
writeln ! ( f, "{{" ) ?;
832
827
if !symbols. is_empty ( ) {
833
828
writeln ! ( f, " global:" ) ?;
834
- for sym in symbols {
829
+ for ( sym, _ ) in symbols {
835
830
debug ! ( " {sym};" ) ;
836
831
writeln ! ( f, " {sym};" ) ?;
837
832
}
@@ -1086,47 +1081,13 @@ impl<'a> Linker for MsvcLinker<'a> {
1086
1081
}
1087
1082
}
1088
1083
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
1130
1091
}
1131
1092
1132
1093
fn subsystem ( & mut self , subsystem : & str ) {
@@ -1259,14 +1220,19 @@ impl<'a> Linker for EmLinker<'a> {
1259
1220
self . cc_arg ( "-nodefaultlibs" ) ;
1260
1221
}
1261
1222
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
+ ) {
1263
1229
debug ! ( "EXPORTED SYMBOLS:" ) ;
1264
1230
1265
1231
self . cc_arg ( "-s" ) ;
1266
1232
1267
1233
let mut arg = OsString :: from ( "EXPORTED_FUNCTIONS=" ) ;
1268
1234
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 < _ > > ( ) ,
1270
1236
)
1271
1237
. unwrap ( ) ;
1272
1238
debug ! ( "{encoded}" ) ;
@@ -1428,8 +1394,13 @@ impl<'a> Linker for WasmLd<'a> {
1428
1394
1429
1395
fn no_default_libraries ( & mut self ) { }
1430
1396
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 {
1433
1404
self . link_args ( & [ "--export" , sym] ) ;
1434
1405
}
1435
1406
@@ -1563,7 +1534,7 @@ impl<'a> Linker for L4Bender<'a> {
1563
1534
self . cc_arg ( "-nostdlib" ) ;
1564
1535
}
1565
1536
1566
- fn export_symbols ( & mut self , _: & Path , _: CrateType , _: & [ String ] ) {
1537
+ fn export_symbols ( & mut self , _: & Path , _: CrateType , _: & [ ( String , SymbolExportKind ) ] ) {
1567
1538
// ToDo, not implemented, copy from GCC
1568
1539
self . sess . dcx ( ) . emit_warn ( errors:: L4BenderExportingSymbolsUnimplemented ) ;
1569
1540
}
@@ -1720,12 +1691,17 @@ impl<'a> Linker for AixLinker<'a> {
1720
1691
1721
1692
fn no_default_libraries ( & mut self ) { }
1722
1693
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
+ ) {
1724
1700
let path = tmpdir. join ( "list.exp" ) ;
1725
1701
let res: io:: Result < ( ) > = try {
1726
1702
let mut f = File :: create_buffered ( & path) ?;
1727
1703
// FIXME: use llvm-nm to generate export list.
1728
- for symbol in symbols {
1704
+ for ( symbol, _ ) in symbols {
1729
1705
debug ! ( " _{symbol}" ) ;
1730
1706
writeln ! ( f, " {symbol}" ) ?;
1731
1707
}
@@ -1769,9 +1745,15 @@ fn for_each_exported_symbols_include_dep<'tcx>(
1769
1745
}
1770
1746
}
1771
1747
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 ) > {
1773
1752
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 ( ) ;
1775
1757
}
1776
1758
1777
1759
if let CrateType :: ProcMacro = crate_type {
@@ -1781,16 +1763,20 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
1781
1763
}
1782
1764
}
1783
1765
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 ) > {
1785
1770
let mut symbols = Vec :: new ( ) ;
1786
1771
let export_threshold = symbol_export:: crates_export_threshold ( & [ crate_type] ) ;
1787
1772
for_each_exported_symbols_include_dep ( tcx, crate_type, |symbol, info, cnum| {
1788
1773
// Do not export mangled symbols from cdylibs and don't attempt to export compiler-builtins
1789
1774
// from any cdylib. The latter doesn't work anyway as we use hidden visibility for
1790
1775
// compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
1791
1776
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 ,
1794
1780
) ) ;
1795
1781
symbol_export:: extend_exported_symbols ( & mut symbols, tcx, symbol, cnum) ;
1796
1782
}
@@ -1799,7 +1785,7 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
1799
1785
symbols
1800
1786
}
1801
1787
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 ) > {
1803
1789
// `exported_symbols` will be empty when !should_codegen.
1804
1790
if !tcx. sess . opts . output_types . should_codegen ( ) {
1805
1791
return Vec :: new ( ) ;
@@ -1809,7 +1795,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
1809
1795
let proc_macro_decls_name = tcx. sess . generate_proc_macro_decls_symbol ( stable_crate_id) ;
1810
1796
let metadata_symbol_name = exported_symbols:: metadata_symbol_name ( tcx) ;
1811
1797
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
+ ]
1813
1802
}
1814
1803
1815
1804
pub ( crate ) fn linked_symbols (
@@ -1906,7 +1895,13 @@ impl<'a> Linker for PtxLinker<'a> {
1906
1895
1907
1896
fn ehcont_guard ( & mut self ) { }
1908
1897
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
+ }
1910
1905
1911
1906
fn subsystem ( & mut self , _subsystem : & str ) { }
1912
1907
@@ -1975,10 +1970,15 @@ impl<'a> Linker for LlbcLinker<'a> {
1975
1970
1976
1971
fn ehcont_guard ( & mut self ) { }
1977
1972
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
+ ) {
1979
1979
match _crate_type {
1980
1980
CrateType :: Cdylib => {
1981
- for sym in symbols {
1981
+ for ( sym, _ ) in symbols {
1982
1982
self . link_args ( & [ "--export-symbol" , sym] ) ;
1983
1983
}
1984
1984
}
@@ -2052,11 +2052,16 @@ impl<'a> Linker for BpfLinker<'a> {
2052
2052
2053
2053
fn ehcont_guard ( & mut self ) { }
2054
2054
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
+ ) {
2056
2061
let path = tmpdir. join ( "symbols" ) ;
2057
2062
let res: io:: Result < ( ) > = try {
2058
2063
let mut f = File :: create_buffered ( & path) ?;
2059
- for sym in symbols {
2064
+ for ( sym, _ ) in symbols {
2060
2065
writeln ! ( f, "{sym}" ) ?;
2061
2066
}
2062
2067
} ;
0 commit comments