@@ -1976,9 +1976,11 @@ fn add_linked_symbol_object(
1976
1976
cmd : & mut dyn Linker ,
1977
1977
sess : & Session ,
1978
1978
tmpdir : & Path ,
1979
- symbols : & [ ( String , SymbolExportKind ) ] ,
1979
+ crate_type : CrateType ,
1980
+ linked_symbols : & [ ( String , SymbolExportKind ) ] ,
1981
+ exported_symbols : & [ String ] ,
1980
1982
) {
1981
- if symbols . is_empty ( ) {
1983
+ if linked_symbols . is_empty ( ) && exported_symbols . is_empty ( ) {
1982
1984
return ;
1983
1985
}
1984
1986
@@ -2015,7 +2017,7 @@ fn add_linked_symbol_object(
2015
2017
None
2016
2018
} ;
2017
2019
2018
- for ( sym, kind) in symbols . iter ( ) {
2020
+ for ( sym, kind) in linked_symbols . iter ( ) {
2019
2021
let symbol = file. add_symbol ( object:: write:: Symbol {
2020
2022
name : sym. clone ( ) . into ( ) ,
2021
2023
value : 0 ,
@@ -2073,6 +2075,38 @@ fn add_linked_symbol_object(
2073
2075
}
2074
2076
}
2075
2077
2078
+ if sess. target . is_like_msvc {
2079
+ // Symbol visibility takes care of this for executables typically
2080
+ let should_filter_symbols = if crate_type == CrateType :: Executable {
2081
+ sess. opts . unstable_opts . export_executable_symbols
2082
+ } else {
2083
+ true
2084
+ } ;
2085
+ if should_filter_symbols {
2086
+ // Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
2087
+ // export symbols from a dynamic library. When building a dynamic library,
2088
+ // however, we're going to want some symbols exported, so this adds a
2089
+ // `.drectve` section which lists all the symbols using /EXPORT arguments.
2090
+ //
2091
+ // The linker will read these arguments from the `.drectve` section and
2092
+ // export all the symbols from the dynamic library. Note that this is not
2093
+ // as simple as just exporting all the symbols in the current crate (as
2094
+ // specified by `codegen.reachable`) but rather we also need to possibly
2095
+ // export the symbols of upstream crates. Upstream rlibs may be linked
2096
+ // statically to this dynamic library, in which case they may continue to
2097
+ // transitively be used and hence need their symbols exported.
2098
+ let drectve = exported_symbols
2099
+ . into_iter ( )
2100
+ . map ( |sym| format ! ( " /EXPORT:\" {sym}\" " ) )
2101
+ . collect :: < Vec < _ > > ( )
2102
+ . join ( "" ) ;
2103
+
2104
+ let section =
2105
+ file. add_section ( vec ! [ ] , b".drectve" . to_vec ( ) , object:: SectionKind :: Linker ) ;
2106
+ file. append_section_data ( section, drectve. as_bytes ( ) , 1 ) ;
2107
+ }
2108
+ }
2109
+
2076
2110
let path = tmpdir. join ( "symbols.o" ) ;
2077
2111
let result = std:: fs:: write ( & path, file. write ( ) . unwrap ( ) ) ;
2078
2112
if let Err ( error) = result {
@@ -2247,7 +2281,9 @@ fn linker_with_args(
2247
2281
cmd,
2248
2282
sess,
2249
2283
tmpdir,
2284
+ crate_type,
2250
2285
& codegen_results. crate_info . linked_symbols [ & crate_type] ,
2286
+ & codegen_results. crate_info . exported_symbols [ & crate_type] ,
2251
2287
) ;
2252
2288
2253
2289
// Sanitizer libraries.
0 commit comments