@@ -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
}
@@ -814,9 +824,10 @@ impl<'a> Linker for GccLinker<'a> {
814
824
// .def file similar to MSVC one but without LIBRARY section
815
825
// because LD doesn't like when it's empty
816
826
writeln ! ( f, "EXPORTS" ) ?;
817
- for symbol in symbols {
827
+ for ( symbol, kind) in symbols {
828
+ let kind_marker = if * kind == SymbolExportKind :: Data { " DATA" } else { "" } ;
818
829
debug ! ( " _{symbol}" ) ;
819
- writeln ! ( f, " {symbol}" ) ?;
830
+ writeln ! ( f, " {symbol}{kind_marker} " ) ?;
820
831
}
821
832
} ;
822
833
if let Err ( error) = res {
@@ -829,7 +840,7 @@ impl<'a> Linker for GccLinker<'a> {
829
840
writeln ! ( f, "{{" ) ?;
830
841
if !symbols. is_empty ( ) {
831
842
writeln ! ( f, " global:" ) ?;
832
- for sym in symbols {
843
+ for ( sym, _ ) in symbols {
833
844
debug ! ( " {sym};" ) ;
834
845
writeln ! ( f, " {sym};" ) ?;
835
846
}
@@ -1096,7 +1107,12 @@ impl<'a> Linker for MsvcLinker<'a> {
1096
1107
// crates. Upstream rlibs may be linked statically to this dynamic library,
1097
1108
// in which case they may continue to transitively be used and hence need
1098
1109
// their symbols exported.
1099
- fn export_symbols ( & mut self , tmpdir : & Path , crate_type : CrateType , symbols : & [ String ] ) {
1110
+ fn export_symbols (
1111
+ & mut self ,
1112
+ tmpdir : & Path ,
1113
+ crate_type : CrateType ,
1114
+ symbols : & [ ( String , SymbolExportKind ) ] ,
1115
+ ) {
1100
1116
// Symbol visibility takes care of this typically
1101
1117
if crate_type == CrateType :: Executable {
1102
1118
let should_export_executable_symbols =
@@ -1114,9 +1130,10 @@ impl<'a> Linker for MsvcLinker<'a> {
1114
1130
// straight to exports.
1115
1131
writeln ! ( f, "LIBRARY" ) ?;
1116
1132
writeln ! ( f, "EXPORTS" ) ?;
1117
- for symbol in symbols {
1133
+ for ( symbol, kind) in symbols {
1134
+ let kind_marker = if * kind == SymbolExportKind :: Data { " DATA" } else { "" } ;
1118
1135
debug ! ( " _{symbol}" ) ;
1119
- writeln ! ( f, " {symbol}" ) ?;
1136
+ writeln ! ( f, " {symbol}{kind_marker} " ) ?;
1120
1137
}
1121
1138
} ;
1122
1139
if let Err ( error) = res {
@@ -1257,14 +1274,19 @@ impl<'a> Linker for EmLinker<'a> {
1257
1274
self . cc_arg ( "-nodefaultlibs" ) ;
1258
1275
}
1259
1276
1260
- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1277
+ fn export_symbols (
1278
+ & mut self ,
1279
+ _tmpdir : & Path ,
1280
+ _crate_type : CrateType ,
1281
+ symbols : & [ ( String , SymbolExportKind ) ] ,
1282
+ ) {
1261
1283
debug ! ( "EXPORTED SYMBOLS:" ) ;
1262
1284
1263
1285
self . cc_arg ( "-s" ) ;
1264
1286
1265
1287
let mut arg = OsString :: from ( "EXPORTED_FUNCTIONS=" ) ;
1266
1288
let encoded = serde_json:: to_string (
1267
- & symbols. iter ( ) . map ( |sym| "_" . to_owned ( ) + sym) . collect :: < Vec < _ > > ( ) ,
1289
+ & symbols. iter ( ) . map ( |( sym, _ ) | "_" . to_owned ( ) + sym) . collect :: < Vec < _ > > ( ) ,
1268
1290
)
1269
1291
. unwrap ( ) ;
1270
1292
debug ! ( "{encoded}" ) ;
@@ -1426,8 +1448,13 @@ impl<'a> Linker for WasmLd<'a> {
1426
1448
1427
1449
fn no_default_libraries ( & mut self ) { }
1428
1450
1429
- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1430
- for sym in symbols {
1451
+ fn export_symbols (
1452
+ & mut self ,
1453
+ _tmpdir : & Path ,
1454
+ _crate_type : CrateType ,
1455
+ symbols : & [ ( String , SymbolExportKind ) ] ,
1456
+ ) {
1457
+ for ( sym, _) in symbols {
1431
1458
self . link_args ( & [ "--export" , sym] ) ;
1432
1459
}
1433
1460
@@ -1561,7 +1588,7 @@ impl<'a> Linker for L4Bender<'a> {
1561
1588
self . cc_arg ( "-nostdlib" ) ;
1562
1589
}
1563
1590
1564
- fn export_symbols ( & mut self , _: & Path , _: CrateType , _: & [ String ] ) {
1591
+ fn export_symbols ( & mut self , _: & Path , _: CrateType , _: & [ ( String , SymbolExportKind ) ] ) {
1565
1592
// ToDo, not implemented, copy from GCC
1566
1593
self . sess . dcx ( ) . emit_warn ( errors:: L4BenderExportingSymbolsUnimplemented ) ;
1567
1594
}
@@ -1718,12 +1745,17 @@ impl<'a> Linker for AixLinker<'a> {
1718
1745
1719
1746
fn no_default_libraries ( & mut self ) { }
1720
1747
1721
- fn export_symbols ( & mut self , tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
1748
+ fn export_symbols (
1749
+ & mut self ,
1750
+ tmpdir : & Path ,
1751
+ _crate_type : CrateType ,
1752
+ symbols : & [ ( String , SymbolExportKind ) ] ,
1753
+ ) {
1722
1754
let path = tmpdir. join ( "list.exp" ) ;
1723
1755
let res: io:: Result < ( ) > = try {
1724
1756
let mut f = File :: create_buffered ( & path) ?;
1725
1757
// FIXME: use llvm-nm to generate export list.
1726
- for symbol in symbols {
1758
+ for ( symbol, _ ) in symbols {
1727
1759
debug ! ( " _{symbol}" ) ;
1728
1760
writeln ! ( f, " {symbol}" ) ?;
1729
1761
}
@@ -1767,9 +1799,12 @@ fn for_each_exported_symbols_include_dep<'tcx>(
1767
1799
}
1768
1800
}
1769
1801
1770
- pub ( crate ) fn exported_symbols ( tcx : TyCtxt < ' _ > , crate_type : CrateType ) -> Vec < String > {
1802
+ pub ( crate ) fn exported_symbols (
1803
+ tcx : TyCtxt < ' _ > ,
1804
+ crate_type : CrateType ,
1805
+ ) -> Vec < ( String , SymbolExportKind ) > {
1771
1806
if let Some ( ref exports) = tcx. sess . target . override_export_symbols {
1772
- return exports. iter ( ) . map ( ToString :: to_string ) . collect ( ) ;
1807
+ return exports. iter ( ) . map ( |name| ( name . to_string ( ) , SymbolExportKind :: Text ) ) . collect ( ) ;
1773
1808
}
1774
1809
1775
1810
if let CrateType :: ProcMacro = crate_type {
@@ -1779,25 +1814,29 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
1779
1814
}
1780
1815
}
1781
1816
1782
- fn exported_symbols_for_non_proc_macro ( tcx : TyCtxt < ' _ > , crate_type : CrateType ) -> Vec < String > {
1817
+ fn exported_symbols_for_non_proc_macro (
1818
+ tcx : TyCtxt < ' _ > ,
1819
+ crate_type : CrateType ,
1820
+ ) -> Vec < ( String , SymbolExportKind ) > {
1783
1821
let mut symbols = Vec :: new ( ) ;
1784
1822
let export_threshold = symbol_export:: crates_export_threshold ( & [ crate_type] ) ;
1785
1823
for_each_exported_symbols_include_dep ( tcx, crate_type, |symbol, info, cnum| {
1786
1824
// Do not export mangled symbols from cdylibs and don't attempt to export compiler-builtins
1787
1825
// from any cdylib. The latter doesn't work anyway as we use hidden visibility for
1788
1826
// compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
1789
1827
if info. level . is_below_threshold ( export_threshold) && !tcx. is_compiler_builtins ( cnum) {
1790
- symbols. push ( symbol_export:: exporting_symbol_name_for_instance_in_crate (
1791
- tcx, symbol, cnum,
1828
+ symbols. push ( (
1829
+ symbol_export:: exporting_symbol_name_for_instance_in_crate ( tcx, symbol, cnum) ,
1830
+ info. kind ,
1792
1831
) ) ;
1793
- symbol_export:: extend_exported_symbols ( & mut symbols, tcx, symbol, cnum) ;
1832
+ symbol_export:: extend_exported_symbols ( & mut symbols, tcx, symbol, info , cnum) ;
1794
1833
}
1795
1834
} ) ;
1796
1835
1797
1836
symbols
1798
1837
}
1799
1838
1800
- fn exported_symbols_for_proc_macro_crate ( tcx : TyCtxt < ' _ > ) -> Vec < String > {
1839
+ fn exported_symbols_for_proc_macro_crate ( tcx : TyCtxt < ' _ > ) -> Vec < ( String , SymbolExportKind ) > {
1801
1840
// `exported_symbols` will be empty when !should_codegen.
1802
1841
if !tcx. sess . opts . output_types . should_codegen ( ) {
1803
1842
return Vec :: new ( ) ;
@@ -1807,7 +1846,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
1807
1846
let proc_macro_decls_name = tcx. sess . generate_proc_macro_decls_symbol ( stable_crate_id) ;
1808
1847
let metadata_symbol_name = exported_symbols:: metadata_symbol_name ( tcx) ;
1809
1848
1810
- vec ! [ proc_macro_decls_name, metadata_symbol_name]
1849
+ vec ! [
1850
+ ( proc_macro_decls_name, SymbolExportKind :: Text ) ,
1851
+ ( metadata_symbol_name, SymbolExportKind :: Text ) ,
1852
+ ]
1811
1853
}
1812
1854
1813
1855
pub ( crate ) fn linked_symbols (
@@ -1829,7 +1871,9 @@ pub(crate) fn linked_symbols(
1829
1871
|| info. used
1830
1872
{
1831
1873
symbols. push ( (
1832
- symbol_export:: linking_symbol_name_for_instance_in_crate ( tcx, symbol, cnum) ,
1874
+ symbol_export:: linking_symbol_name_for_instance_in_crate (
1875
+ tcx, symbol, info. kind , cnum,
1876
+ ) ,
1833
1877
info. kind ,
1834
1878
) ) ;
1835
1879
}
@@ -1904,7 +1948,13 @@ impl<'a> Linker for PtxLinker<'a> {
1904
1948
1905
1949
fn ehcont_guard ( & mut self ) { }
1906
1950
1907
- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , _symbols : & [ String ] ) { }
1951
+ fn export_symbols (
1952
+ & mut self ,
1953
+ _tmpdir : & Path ,
1954
+ _crate_type : CrateType ,
1955
+ _symbols : & [ ( String , SymbolExportKind ) ] ,
1956
+ ) {
1957
+ }
1908
1958
1909
1959
fn subsystem ( & mut self , _subsystem : & str ) { }
1910
1960
@@ -1973,10 +2023,15 @@ impl<'a> Linker for LlbcLinker<'a> {
1973
2023
1974
2024
fn ehcont_guard ( & mut self ) { }
1975
2025
1976
- fn export_symbols ( & mut self , _tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
2026
+ fn export_symbols (
2027
+ & mut self ,
2028
+ _tmpdir : & Path ,
2029
+ _crate_type : CrateType ,
2030
+ symbols : & [ ( String , SymbolExportKind ) ] ,
2031
+ ) {
1977
2032
match _crate_type {
1978
2033
CrateType :: Cdylib => {
1979
- for sym in symbols {
2034
+ for ( sym, _ ) in symbols {
1980
2035
self . link_args ( & [ "--export-symbol" , sym] ) ;
1981
2036
}
1982
2037
}
@@ -2050,11 +2105,16 @@ impl<'a> Linker for BpfLinker<'a> {
2050
2105
2051
2106
fn ehcont_guard ( & mut self ) { }
2052
2107
2053
- fn export_symbols ( & mut self , tmpdir : & Path , _crate_type : CrateType , symbols : & [ String ] ) {
2108
+ fn export_symbols (
2109
+ & mut self ,
2110
+ tmpdir : & Path ,
2111
+ _crate_type : CrateType ,
2112
+ symbols : & [ ( String , SymbolExportKind ) ] ,
2113
+ ) {
2054
2114
let path = tmpdir. join ( "symbols" ) ;
2055
2115
let res: io:: Result < ( ) > = try {
2056
2116
let mut f = File :: create_buffered ( & path) ?;
2057
- for sym in symbols {
2117
+ for ( sym, _ ) in symbols {
2058
2118
writeln ! ( f, "{sym}" ) ?;
2059
2119
}
2060
2120
} ;
0 commit comments