-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
cstyle-export-rules: export global symbols from upstream static libraries
#150335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -846,15 +846,31 @@ impl<'a> Linker for GccLinker<'a> { | |
| // Write an LD version script | ||
| let res: io::Result<()> = try { | ||
| let mut f = File::create_buffered(&path)?; | ||
| writeln!(f, "{{")?; | ||
| if !symbols.is_empty() { | ||
| writeln!(f, " global:")?; | ||
| for (sym, _) in symbols { | ||
| debug!(" {sym};"); | ||
| writeln!(f, " {sym};")?; | ||
| if self.sess.opts.unstable_opts.cstyle_export_rules { | ||
| writeln!(f, "{{")?; | ||
| writeln!(f, " global:\n *;\n")?; | ||
| if !symbols.is_empty() { | ||
| writeln!(f, " local:")?; | ||
| // writeln!(f, " _ZN*;")?; | ||
| // writeln!(f, " _R*;")?; | ||
| for (sym, _) in symbols { | ||
| debug!(" {sym};"); | ||
| writeln!(f, " {sym};")?; | ||
| } | ||
| } | ||
| writeln!(f, "\n}};")?; | ||
| } else { | ||
| writeln!(f, "{{")?; | ||
| if !symbols.is_empty() { | ||
| writeln!(f, " global:")?; | ||
| for (sym, _) in symbols { | ||
| debug!(" {sym};"); | ||
| writeln!(f, " {sym};")?; | ||
| } | ||
| } | ||
| writeln!(f, "\n local:\n *;\n}};")?; | ||
| } | ||
| writeln!(f, "\n local:\n *;\n}};")?; | ||
|
|
||
| }; | ||
| if let Err(error) = res { | ||
| self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error }); | ||
|
|
@@ -1812,6 +1828,38 @@ pub(crate) fn exported_symbols( | |
| } | ||
| } | ||
|
|
||
| pub(crate) fn exported_symbols_cstyle( | ||
| tcx: TyCtxt<'_>, | ||
| crate_type: CrateType, | ||
| ) -> Vec<(String, SymbolExportKind)> { | ||
| if let Some(ref exports) = tcx.sess.target.override_export_symbols { | ||
| return exports | ||
| .iter() | ||
| .map(|name| { | ||
| ( | ||
| name.to_string(), | ||
| // FIXME use the correct export kind for this symbol. override_export_symbols | ||
| // can't directly specify the SymbolExportKind as it is defined in rustc_middle | ||
| // which rustc_target can't depend on. | ||
| SymbolExportKind::Text, | ||
| ) | ||
| }) | ||
| .collect(); | ||
| } | ||
|
|
||
| let mut symbols = Vec::new(); | ||
| let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); | ||
| for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This lists all exported symbols, while you need all non-exported symbols too.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is the correct position to iterate through all exported symbols and invert the selection rules of the original |
||
| if !info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know that the original criterion for selecting symbols into exported_symbols was exit status: 1
|
= note: "cc" "-Wl,--version-script=/tmp/rustcenvqxB/list" "-Wl,--no-undefined-version" "-m64" "/tmp/rustcenvqxB/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/root/cezarbbb/include-libs-test3/downstream-cdylib/target/debug/deps/libupstream-8102da413a3d22f9.rlib" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/tmp/rustcenvqxB/raw-dylibs" "-B<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld" "-fuse-ld=lld" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/root/cezarbbb/include-libs-test3/downstream-cdylib/target/debug/deps/libdownstream_cdylib.so" "-Wl,--gc-sections" "-shared" "-Wl,-z,relro,-z,now" "-nodefaultlibs"
= note: some arguments are omitted. use `--verbose` to show all linker arguments
= note: rust-lld: error: version script assignment of 'local' to symbol '__rustc_proc_macro_decls_908feb11bfb2de80__' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol 'rust_metadata_downstream_cdylib_908feb11bfb2de80' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__addtf3' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__ashlti3' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__ashrti3' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__bswapdi2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__bswapsi2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__clzdi2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__clzti2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__ctzdi2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__ctzti2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__divmodti4' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__divtf3' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__divti3' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__eqtf2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__extenddftf2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__extendhfdf2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__extendhftf2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__extendsfdf2' failed: symbol not defined
rust-lld: error: version script assignment of 'local' to symbol '__extendsftf2' failed: symbol not defined
rust-lld: error: too many errors emitted, stopping now (use --error-limit=0 to see all errors) collect2: error: ld returned 1 exit statusIt seems
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right. All compiler-builtins symbols have hidden visibility, so I guess they shouldn't be listed in the version script at all. |
||
| symbols.push(( | ||
| symbol_export::exporting_symbol_name_for_instance_in_crate(tcx, symbol, cnum), | ||
| info.kind, | ||
| )); | ||
| } | ||
| }); | ||
| symbols | ||
| } | ||
|
|
||
| fn exported_symbols_for_non_proc_macro( | ||
| tcx: TyCtxt<'_>, | ||
| crate_type: CrateType, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # `cstyle-export-rules` | ||
|
|
||
| This option forces rustc to export the `global` symbol from the upstream C static library. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For proc-macros we should keep using an allowlist containing just two symbols.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same situation occurs when adding proc_macro, as can be seen in the error message above(
__rustc_proc_macro_decls_908feb11bfb2de80__andrust_metadata_downstream_cdylib_908feb11bfb2de80).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These symbols must be exported from proc-macros. If they aren't, rustc will fail to load the proc-macro. In any case it looks like you put those symbols on the denylist rather than the allowlist.