Skip to content

Commit f175a6e

Browse files
committed
Add /EXPORT entries to symbols.o
1 parent be61f27 commit f175a6e

File tree

4 files changed

+109
-59
lines changed

4 files changed

+109
-59
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,9 +1976,10 @@ fn add_linked_symbol_object(
19761976
cmd: &mut dyn Linker,
19771977
sess: &Session,
19781978
tmpdir: &Path,
1979-
symbols: &[(String, SymbolExportKind)],
1979+
linked_symbols: &[(String, SymbolExportKind)],
1980+
exported_symbols: &[(String, SymbolExportKind)],
19801981
) {
1981-
if symbols.is_empty() {
1982+
if linked_symbols.is_empty() {
19821983
return;
19831984
}
19841985

@@ -2015,7 +2016,7 @@ fn add_linked_symbol_object(
20152016
None
20162017
};
20172018

2018-
for (sym, kind) in symbols.iter() {
2019+
for (sym, kind) in linked_symbols.iter() {
20192020
let symbol = file.add_symbol(object::write::Symbol {
20202021
name: sym.clone().into(),
20212022
value: 0,
@@ -2073,6 +2074,23 @@ fn add_linked_symbol_object(
20732074
}
20742075
}
20752076

2077+
if sess.target.is_like_msvc {
2078+
let drectve = exported_symbols
2079+
.into_iter()
2080+
.map(|(sym, kind)| {
2081+
if *kind == SymbolExportKind::Text {
2082+
format!(" /EXPORT:\"{sym}\"")
2083+
} else {
2084+
format!(" /EXPORT:\"{sym}\",DATA")
2085+
}
2086+
})
2087+
.collect::<Vec<_>>()
2088+
.join("");
2089+
2090+
let section = file.add_section(vec![], b".drectve".to_vec(), object::SectionKind::Linker);
2091+
file.append_section_data(section, drectve.as_bytes(), 1);
2092+
}
2093+
20762094
let path = tmpdir.join("symbols.o");
20772095
let result = std::fs::write(&path, file.write().unwrap());
20782096
if let Err(error) = result {
@@ -2248,6 +2266,7 @@ fn linker_with_args(
22482266
sess,
22492267
tmpdir,
22502268
&codegen_results.crate_info.linked_symbols[&crate_type],
2269+
&codegen_results.crate_info.exported_symbols[&crate_type],
22512270
);
22522271

22532272
// Sanitizer libraries.

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 84 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -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,7 +824,7 @@ 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, _) in symbols {
818828
debug!(" _{symbol}");
819829
// Quote the name in case it's reserved by linker in some way
820830
// (this accounts for names with dots in particular).
@@ -831,7 +841,7 @@ impl<'a> Linker for GccLinker<'a> {
831841
writeln!(f, "{{")?;
832842
if !symbols.is_empty() {
833843
writeln!(f, " global:")?;
834-
for sym in symbols {
844+
for (sym, _) in symbols {
835845
debug!(" {sym};");
836846
writeln!(f, " {sym};")?;
837847
}
@@ -1098,35 +1108,12 @@ impl<'a> Linker for MsvcLinker<'a> {
10981108
// crates. Upstream rlibs may be linked statically to this dynamic library,
10991109
// in which case they may continue to transitively be used and hence need
11001110
// 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);
1111+
fn export_symbols(
1112+
&mut self,
1113+
_tmpdir: &Path,
1114+
_crate_type: CrateType,
1115+
_symbols: &[(String, SymbolExportKind)],
1116+
) {
11301117
}
11311118

11321119
fn subsystem(&mut self, subsystem: &str) {
@@ -1259,14 +1246,19 @@ impl<'a> Linker for EmLinker<'a> {
12591246
self.cc_arg("-nodefaultlibs");
12601247
}
12611248

1262-
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
1249+
fn export_symbols(
1250+
&mut self,
1251+
_tmpdir: &Path,
1252+
_crate_type: CrateType,
1253+
symbols: &[(String, SymbolExportKind)],
1254+
) {
12631255
debug!("EXPORTED SYMBOLS:");
12641256

12651257
self.cc_arg("-s");
12661258

12671259
let mut arg = OsString::from("EXPORTED_FUNCTIONS=");
12681260
let encoded = serde_json::to_string(
1269-
&symbols.iter().map(|sym| "_".to_owned() + sym).collect::<Vec<_>>(),
1261+
&symbols.iter().map(|(sym, _)| "_".to_owned() + sym).collect::<Vec<_>>(),
12701262
)
12711263
.unwrap();
12721264
debug!("{encoded}");
@@ -1428,8 +1420,13 @@ impl<'a> Linker for WasmLd<'a> {
14281420

14291421
fn no_default_libraries(&mut self) {}
14301422

1431-
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
1432-
for sym in symbols {
1423+
fn export_symbols(
1424+
&mut self,
1425+
_tmpdir: &Path,
1426+
_crate_type: CrateType,
1427+
symbols: &[(String, SymbolExportKind)],
1428+
) {
1429+
for (sym, _) in symbols {
14331430
self.link_args(&["--export", sym]);
14341431
}
14351432

@@ -1563,7 +1560,7 @@ impl<'a> Linker for L4Bender<'a> {
15631560
self.cc_arg("-nostdlib");
15641561
}
15651562

1566-
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
1563+
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[(String, SymbolExportKind)]) {
15671564
// ToDo, not implemented, copy from GCC
15681565
self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented);
15691566
}
@@ -1720,12 +1717,17 @@ impl<'a> Linker for AixLinker<'a> {
17201717

17211718
fn no_default_libraries(&mut self) {}
17221719

1723-
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
1720+
fn export_symbols(
1721+
&mut self,
1722+
tmpdir: &Path,
1723+
_crate_type: CrateType,
1724+
symbols: &[(String, SymbolExportKind)],
1725+
) {
17241726
let path = tmpdir.join("list.exp");
17251727
let res: io::Result<()> = try {
17261728
let mut f = File::create_buffered(&path)?;
17271729
// FIXME: use llvm-nm to generate export list.
1728-
for symbol in symbols {
1730+
for (symbol, _) in symbols {
17291731
debug!(" _{symbol}");
17301732
writeln!(f, " {symbol}")?;
17311733
}
@@ -1769,9 +1771,15 @@ fn for_each_exported_symbols_include_dep<'tcx>(
17691771
}
17701772
}
17711773

1772-
pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
1774+
pub(crate) fn exported_symbols(
1775+
tcx: TyCtxt<'_>,
1776+
crate_type: CrateType,
1777+
) -> Vec<(String, SymbolExportKind)> {
17731778
if let Some(ref exports) = tcx.sess.target.override_export_symbols {
1774-
return exports.iter().map(ToString::to_string).collect();
1779+
return exports
1780+
.iter()
1781+
.map(|sym| (sym.to_string(), SymbolExportKind::Text /* FIXME */))
1782+
.collect();
17751783
}
17761784

17771785
if let CrateType::ProcMacro = crate_type {
@@ -1781,16 +1789,20 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
17811789
}
17821790
}
17831791

1784-
fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
1792+
fn exported_symbols_for_non_proc_macro(
1793+
tcx: TyCtxt<'_>,
1794+
crate_type: CrateType,
1795+
) -> Vec<(String, SymbolExportKind)> {
17851796
let mut symbols = Vec::new();
17861797
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
17871798
for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
17881799
// Do not export mangled symbols from cdylibs and don't attempt to export compiler-builtins
17891800
// from any cdylib. The latter doesn't work anyway as we use hidden visibility for
17901801
// compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
17911802
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,
1803+
symbols.push((
1804+
symbol_export::exporting_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
1805+
info.kind,
17941806
));
17951807
symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, cnum);
17961808
}
@@ -1799,7 +1811,7 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
17991811
symbols
18001812
}
18011813

1802-
fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
1814+
fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<(String, SymbolExportKind)> {
18031815
// `exported_symbols` will be empty when !should_codegen.
18041816
if !tcx.sess.opts.output_types.should_codegen() {
18051817
return Vec::new();
@@ -1809,7 +1821,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
18091821
let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
18101822
let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
18111823

1812-
vec![proc_macro_decls_name, metadata_symbol_name]
1824+
vec![
1825+
(proc_macro_decls_name, SymbolExportKind::Data),
1826+
(metadata_symbol_name, SymbolExportKind::Data),
1827+
]
18131828
}
18141829

18151830
pub(crate) fn linked_symbols(
@@ -1906,7 +1921,13 @@ impl<'a> Linker for PtxLinker<'a> {
19061921

19071922
fn ehcont_guard(&mut self) {}
19081923

1909-
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {}
1924+
fn export_symbols(
1925+
&mut self,
1926+
_tmpdir: &Path,
1927+
_crate_type: CrateType,
1928+
_symbols: &[(String, SymbolExportKind)],
1929+
) {
1930+
}
19101931

19111932
fn subsystem(&mut self, _subsystem: &str) {}
19121933

@@ -1975,10 +1996,15 @@ impl<'a> Linker for LlbcLinker<'a> {
19751996

19761997
fn ehcont_guard(&mut self) {}
19771998

1978-
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
1999+
fn export_symbols(
2000+
&mut self,
2001+
_tmpdir: &Path,
2002+
_crate_type: CrateType,
2003+
symbols: &[(String, SymbolExportKind)],
2004+
) {
19792005
match _crate_type {
19802006
CrateType::Cdylib => {
1981-
for sym in symbols {
2007+
for (sym, _) in symbols {
19822008
self.link_args(&["--export-symbol", sym]);
19832009
}
19842010
}
@@ -2052,11 +2078,16 @@ impl<'a> Linker for BpfLinker<'a> {
20522078

20532079
fn ehcont_guard(&mut self) {}
20542080

2055-
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
2081+
fn export_symbols(
2082+
&mut self,
2083+
tmpdir: &Path,
2084+
_crate_type: CrateType,
2085+
symbols: &[(String, SymbolExportKind)],
2086+
) {
20562087
let path = tmpdir.join("symbols");
20572088
let res: io::Result<()> = try {
20582089
let mut f = File::create_buffered(&path)?;
2059-
for sym in symbols {
2090+
for (sym, _) in symbols {
20602091
writeln!(f, "{sym}")?;
20612092
}
20622093
};

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
753753
/// Add it to the symbols list for all kernel functions, so that it is exported in the linked
754754
/// object.
755755
pub(crate) fn extend_exported_symbols<'tcx>(
756-
symbols: &mut Vec<String>,
756+
symbols: &mut Vec<(String, SymbolExportKind)>,
757757
tcx: TyCtxt<'tcx>,
758758
symbol: ExportedSymbol<'tcx>,
759759
instantiating_crate: CrateNum,
@@ -767,7 +767,7 @@ pub(crate) fn extend_exported_symbols<'tcx>(
767767
let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
768768

769769
// Add the symbol for the kernel descriptor (with .kd suffix)
770-
symbols.push(format!("{undecorated}.kd"));
770+
symbols.push((format!("{undecorated}.kd"), SymbolExportKind::Data));
771771
}
772772

773773
fn maybe_emutls_symbol_name<'tcx>(

compiler/rustc_codegen_ssa/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ pub struct CrateInfo {
218218
pub target_cpu: String,
219219
pub target_features: Vec<String>,
220220
pub crate_types: Vec<CrateType>,
221-
pub exported_symbols: UnordMap<CrateType, Vec<String>>,
221+
pub exported_symbols: UnordMap<CrateType, Vec<(String, SymbolExportKind)>>,
222222
pub linked_symbols: FxIndexMap<CrateType, Vec<(String, SymbolExportKind)>>,
223223
pub local_crate_name: Symbol,
224224
pub compiler_builtins: Option<CrateNum>,

0 commit comments

Comments
 (0)