From 689bb118ce3f24da8fa2ce20a0c34e4d76097a26 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 16:32:54 -0400 Subject: [PATCH 1/3] rewrite symbol-visibility to rmake --- src/tools/compiletest/src/command-list.rs | 1 + src/tools/run-make-support/src/command.rs | 2 + .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/symbol-visibility/Makefile | 123 ------------- tests/run-make/symbol-visibility/rmake.rs | 168 ++++++++++++++++++ 5 files changed, 171 insertions(+), 124 deletions(-) delete mode 100644 tests/run-make/symbol-visibility/Makefile create mode 100644 tests/run-make/symbol-visibility/rmake.rs diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs index c356f4266f016..288f90ea12399 100644 --- a/src/tools/compiletest/src/command-list.rs +++ b/src/tools/compiletest/src/command-list.rs @@ -117,6 +117,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-watchos", "ignore-windows", "ignore-windows-gnu", + "ignore-windows-msvc", "ignore-x32", "ignore-x86", "ignore-x86_64", diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index fb94ff996f0d6..86d2e4a852a30 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -163,11 +163,13 @@ pub struct CompletedProcess { impl CompletedProcess { #[must_use] + #[track_caller] pub fn stdout_utf8(&self) -> String { String::from_utf8(self.output.stdout.clone()).expect("stdout is not valid UTF-8") } #[must_use] + #[track_caller] pub fn stderr_utf8(&self) -> String { String::from_utf8(self.output.stderr.clone()).expect("stderr is not valid UTF-8") } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a84b89ff4a113..6bb9ba0428eca 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -52,7 +52,6 @@ run-make/split-debuginfo/Makefile run-make/stable-symbol-names/Makefile run-make/staticlib-dylib-linkage/Makefile run-make/symbol-mangling-hashed/Makefile -run-make/symbol-visibility/Makefile run-make/sysroot-crates-are-unstable/Makefile run-make/thumb-none-cortex-m/Makefile run-make/thumb-none-qemu/Makefile diff --git a/tests/run-make/symbol-visibility/Makefile b/tests/run-make/symbol-visibility/Makefile deleted file mode 100644 index 9159af214ca7b..0000000000000 --- a/tests/run-make/symbol-visibility/Makefile +++ /dev/null @@ -1,123 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# ignore-windows-msvc - -NM=nm -D -CDYLIB_NAME=liba_cdylib.so -RDYLIB_NAME=liba_rust_dylib.so -PROC_MACRO_NAME=liba_proc_macro.so -EXE_NAME=an_executable -COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.so - -ifeq ($(UNAME),Darwin) -NM=nm -gU -CDYLIB_NAME=liba_cdylib.dylib -RDYLIB_NAME=liba_rust_dylib.dylib -PROC_MACRO_NAME=liba_proc_macro.dylib -EXE_NAME=an_executable -COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.dylib -endif - -ifdef IS_WINDOWS -NM=nm -g -CDYLIB_NAME=liba_cdylib.dll.a -RDYLIB_NAME=liba_rust_dylib.dll.a -PROC_MACRO_NAME=liba_proc_macro.dll -EXE_NAME=an_executable.exe -COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.dll.a -endif - -# `grep` regex for symbols produced by either `legacy` or `v0` mangling -RE_ANY_RUST_SYMBOL="_ZN.*h.*E\|_R[a-zA-Z0-9_]+" - -all: - $(RUSTC) -Zshare-generics=no an_rlib.rs - $(RUSTC) -Zshare-generics=no a_cdylib.rs - $(RUSTC) -Zshare-generics=no a_rust_dylib.rs - $(RUSTC) -Zshare-generics=no a_proc_macro.rs - $(RUSTC) -Zshare-generics=no an_executable.rs - $(RUSTC) -Zshare-generics=no a_cdylib.rs --crate-name combined_rlib_dylib --crate-type=rlib,cdylib - - # Check that a cdylib exports its public #[no_mangle] functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_cdylib)" -eq "1" ] - # Check that a cdylib exports the public #[no_mangle] functions of dependencies - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ] - # Check that a cdylib DOES NOT export any public Rust functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] - - # Check that a Rust dylib exports its monomorphic functions - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rust_dylib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_rust_function_from_rust_dylib)" -eq "1" ] - # Check that a Rust dylib does not export generics if -Zshare-generics=no - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_generic_function_from_rust_dylib)" -eq "0" ] - - - # Check that a Rust dylib exports the monomorphic functions from its dependencies - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_rust_function_from_rlib)" -eq "1" ] - # Check that a Rust dylib does not export generics if -Zshare-generics=no - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_generic_function_from_rlib)" -eq "0" ] - - # Check that a proc macro exports its public #[no_mangle] functions - # FIXME(#99978) avoid exporting #[no_mangle] symbols for proc macros - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_cdylib)" -eq "1" ] - # Check that a proc macro exports the public #[no_mangle] functions of dependencies - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ] - # Check that a proc macro DOES NOT export any public Rust functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] - -# FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032 -ifndef IS_WINDOWS - # Check that an executable does not export any dynamic symbols - [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "0" ] - [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_rust_function_from_exe)" -eq "0" ] -endif - - - # Check the combined case, where we generate a cdylib and an rlib in the same - # compilation session: - # Check that a cdylib exports its public #[no_mangle] functions - [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_cdylib)" -eq "1" ] - # Check that a cdylib exports the public #[no_mangle] functions of dependencies - [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ] - # Check that a cdylib DOES NOT export any public Rust functions - [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -v __imp_ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] - - - $(RUSTC) -Zshare-generics=yes an_rlib.rs - $(RUSTC) -Zshare-generics=yes a_cdylib.rs - $(RUSTC) -Zshare-generics=yes a_rust_dylib.rs - $(RUSTC) -Zshare-generics=yes a_proc_macro.rs - $(RUSTC) -Zshare-generics=yes an_executable.rs - - # Check that a cdylib exports its public #[no_mangle] functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_cdylib)" -eq "1" ] - # Check that a cdylib exports the public #[no_mangle] functions of dependencies - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ] - # Check that a cdylib DOES NOT export any public Rust functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] - - # Check that a Rust dylib exports its monomorphic functions, including generics this time - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rust_dylib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_rust_function_from_rust_dylib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_generic_function_from_rust_dylib)" -eq "1" ] - - # Check that a Rust dylib exports the monomorphic functions from its dependencies - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_rust_function_from_rlib)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_generic_function_from_rlib)" -eq "1" ] - - # Check that a proc macro exports its public #[no_mangle] functions - # FIXME(#99978) avoid exporting #[no_mangle] symbols for proc macros - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_cdylib)" -eq "1" ] - # Check that a proc macro exports the public #[no_mangle] functions of dependencies - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ] - # Check that a proc macro DOES NOT export any public Rust functions - [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ] - -ifndef IS_WINDOWS - # Check that an executable does not export any dynamic symbols - [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "0" ] - [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_rust_function_from_exe)" -eq "0" ] -endif diff --git a/tests/run-make/symbol-visibility/rmake.rs b/tests/run-make/symbol-visibility/rmake.rs new file mode 100644 index 0000000000000..5fff89e071e11 --- /dev/null +++ b/tests/run-make/symbol-visibility/rmake.rs @@ -0,0 +1,168 @@ +// Dynamic libraries on Rust used to export a very high amount of symbols, +// going as far as filling the output with mangled names and generic function +// names. After the rework of #38117, this test checks that no mangled Rust symbols +// are exported, and that generics are only shown if explicitely requested. +// See https://github.com/rust-lang/rust/issues/37530 + +//@ ignore-windows-msvc + +use run_make_support::{bin_name, dynamic_lib_name, is_windows, llvm_readobj, regex, rustc}; + +fn main() { + let mut cdylib_name = dynamic_lib_name("a_cdylib"); + let mut rdylib_name = dynamic_lib_name("a_rust_dylib"); + let exe_name = bin_name("an_executable"); + let mut combined_cdylib_name = dynamic_lib_name("combined_rlib_dylib"); + rustc().arg("-Zshare-generics=no").input("an_rlib.rs").run(); + rustc().arg("-Zshare-generics=no").input("a_cdylib.rs").run(); + rustc().arg("-Zshare-generics=no").input("a_rust_dylib.rs").run(); + rustc().arg("-Zshare-generics=no").input("a_proc_macro.rs").run(); + rustc().arg("-Zshare-generics=no").input("an_executable.rs").run(); + rustc() + .arg("-Zshare-generics=no") + .input("a_cdylib.rs") + .crate_name("combined_rlib_dylib") + .crate_type("rlib,cdylib") + .run(); + + // Check that a cdylib exports its public #[no_mangle] functions + symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), true); + // Check that a cdylib exports the public #[no_mangle] functions of dependencies + symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true); + // Check that a cdylib DOES NOT export any public Rust functions + symbols_check(&cdylib_name, SymbolCheckType::AnyRustSymbol, false); + + // Check that a Rust dylib exports its monomorphic functions + symbols_check( + &rdylib_name, + SymbolCheckType::StrSymbol("public_c_function_from_rust_dylib"), + true, + ); + symbols_check( + &rdylib_name, + SymbolCheckType::StrSymbol("public_rust_function_from_rust_dylib"), + true, + ); + // Check that a Rust dylib does not export generics if -Zshare-generics=no + symbols_check( + &rdylib_name, + SymbolCheckType::StrSymbol("public_generic_function_from_rust_dylib"), + false, + ); + + // Check that a Rust dylib exports the monomorphic functions from its dependencies + symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true); + symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_rust_function_from_rlib"), true); + // Check that a Rust dylib does not export generics if -Zshare-generics=no + symbols_check( + &rdylib_name, + SymbolCheckType::StrSymbol("public_generic_function_from_rlib"), + false, + ); + + // FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032 + // if is_windows() { + // // Check that an executable does not export any dynamic symbols + // symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib") + //, false); + // symbols_check( + // &exe_name, + // SymbolCheckType::StrSymbol("public_rust_function_from_exe"), + // false, + // ); + // } + + // Check the combined case, where we generate a cdylib and an rlib in the same + // compilation session: + // Check that a cdylib exports its public //[no_mangle] functions + symbols_check( + &combined_cdylib_name, + SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), + true, + ); + // Check that a cdylib exports the public //[no_mangle] functions of dependencies + symbols_check( + &combined_cdylib_name, + SymbolCheckType::StrSymbol("public_c_function_from_rlib"), + true, + ); + // Check that a cdylib DOES NOT export any public Rust functions + symbols_check(&combined_cdylib_name, SymbolCheckType::AnyRustSymbol, false); + + rustc().arg("-Zshare-generics=yes").input("an_rlib.rs").run(); + rustc().arg("-Zshare-generics=yes").input("a_cdylib.rs").run(); + rustc().arg("-Zshare-generics=yes").input("a_rust_dylib.rs").run(); + rustc().arg("-Zshare-generics=yes").input("an_executable.rs").run(); + + // Check that a cdylib exports its public //[no_mangle] functions + symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), true); + // Check that a cdylib exports the public //[no_mangle] functions of dependencies + symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true); + // Check that a cdylib DOES NOT export any public Rust functions + symbols_check(&cdylib_name, SymbolCheckType::AnyRustSymbol, false); + + // Check that a Rust dylib exports its monomorphic functions, including generics this time + symbols_check( + &rdylib_name, + SymbolCheckType::StrSymbol("public_c_function_from_rust_dylib"), + true, + ); + symbols_check( + &rdylib_name, + SymbolCheckType::StrSymbol("public_rust_function_from_rust_dylib"), + true, + ); + symbols_check( + &rdylib_name, + SymbolCheckType::StrSymbol("public_generic_function_from_rust_dylib"), + true, + ); + + // Check that a Rust dylib exports the monomorphic functions from its dependencies + symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true); + symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_rust_function_from_rlib"), true); + symbols_check( + &rdylib_name, + SymbolCheckType::StrSymbol("public_generic_function_from_rlib"), + true, + ); + + // FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032 + // if is_windows() { + // // Check that an executable does not export any dynamic symbols + // symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib") + //, false); + // symbols_check( + // &exe_name, + // SymbolCheckType::StrSymbol("public_rust_function_from_exe"), + // false, + // ); + // } +} + +#[track_caller] +fn symbols_check(path: &str, symbol_check_type: SymbolCheckType, exists_once: bool) { + let out = llvm_readobj().arg("--dyn-symbols").input(path).run().stdout_utf8(); + assert_eq!( + out.lines() + .filter(|&line| !line.contains("__imp_") && has_symbol(line, symbol_check_type)) + .count() + == 1, + exists_once + ); +} + +fn has_symbol(line: &str, symbol_check_type: SymbolCheckType) -> bool { + if let SymbolCheckType::StrSymbol(expected) = symbol_check_type { + line.contains(expected) + } else { + let regex = regex::Regex::new(r#"_ZN.*h.*E\|_R[a-zA-Z0-9_]+"#).unwrap(); + regex.is_match(line) + } +} + +#[derive(Clone, Copy)] +enum SymbolCheckType { + StrSymbol(&'static str), + AnyRustSymbol, +} From dcaa17a661d5101c7ee79703f0c4a14e8ddcb5f5 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Mon, 15 Jul 2024 11:52:37 -0400 Subject: [PATCH 2/3] invalid stdout_utf8 handling in run_make_support --- src/tools/run-make-support/src/command.rs | 6 ++++++ tests/run-make/symbol-visibility/rmake.rs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index 86d2e4a852a30..532e3b8e048a0 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -168,6 +168,12 @@ impl CompletedProcess { String::from_utf8(self.output.stdout.clone()).expect("stdout is not valid UTF-8") } + #[must_use] + #[track_caller] + pub fn invalid_stdout_utf8(&self) -> String { + String::from_utf8_lossy(&self.output.stdout.clone()).to_string() + } + #[must_use] #[track_caller] pub fn stderr_utf8(&self) -> String { diff --git a/tests/run-make/symbol-visibility/rmake.rs b/tests/run-make/symbol-visibility/rmake.rs index 5fff89e071e11..cd085cf05d0ed 100644 --- a/tests/run-make/symbol-visibility/rmake.rs +++ b/tests/run-make/symbol-visibility/rmake.rs @@ -142,7 +142,7 @@ fn main() { #[track_caller] fn symbols_check(path: &str, symbol_check_type: SymbolCheckType, exists_once: bool) { - let out = llvm_readobj().arg("--dyn-symbols").input(path).run().stdout_utf8(); + let out = llvm_readobj().arg("--dyn-symbols").input(path).run().invalid_stdout_utf8(); assert_eq!( out.lines() .filter(|&line| !line.contains("__imp_") && has_symbol(line, symbol_check_type)) From ea04b0afbf3e5346c2df015b9c59ff1b0b3bc270 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 30 Jul 2024 13:07:49 -0400 Subject: [PATCH 3/3] use llvm-nm in symbol-visibility rmake test --- .../src/external_deps/llvm.rs | 30 +++++++++++++++++++ src/tools/run-make-support/src/lib.rs | 4 +-- tests/run-make/symbol-visibility/rmake.rs | 29 ++++++++++++------ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs index b116bd08e3a6c..259bb6159461b 100644 --- a/src/tools/run-make-support/src/external_deps/llvm.rs +++ b/src/tools/run-make-support/src/external_deps/llvm.rs @@ -36,6 +36,12 @@ pub fn llvm_ar() -> LlvmAr { LlvmAr::new() } +/// Construct a new `llvm-nm` invocation. This assumes that `llvm-nm` is available +/// at `$LLVM_BIN_DIR/llvm-nm`. +pub fn llvm_nm() -> LlvmNm { + LlvmNm::new() +} + /// A `llvm-readobj` invocation builder. #[derive(Debug)] #[must_use] @@ -71,11 +77,19 @@ pub struct LlvmAr { cmd: Command, } +/// A `llvm-nm` invocation builder. +#[derive(Debug)] +#[must_use] +pub struct LlvmNm { + cmd: Command, +} + crate::macros::impl_common_helpers!(LlvmReadobj); crate::macros::impl_common_helpers!(LlvmProfdata); crate::macros::impl_common_helpers!(LlvmFilecheck); crate::macros::impl_common_helpers!(LlvmObjdump); crate::macros::impl_common_helpers!(LlvmAr); +crate::macros::impl_common_helpers!(LlvmNm); /// Generate the path to the bin directory of LLVM. #[must_use] @@ -244,3 +258,19 @@ impl LlvmAr { self } } + +impl LlvmNm { + /// Construct a new `llvm-nm` invocation. This assumes that `llvm-nm` is available + /// at `$LLVM_BIN_DIR/llvm-nm`. + pub fn new() -> Self { + let llvm_nm = llvm_bin_dir().join("llvm-nm"); + let cmd = Command::new(llvm_nm); + Self { cmd } + } + + /// Provide an input file. + pub fn input>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 085120764b463..9ced61932585c 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -48,8 +48,8 @@ pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc}; pub use clang::{clang, Clang}; pub use htmldocck::htmldocck; pub use llvm::{ - llvm_ar, llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmFilecheck, - LlvmObjdump, LlvmProfdata, LlvmReadobj, + llvm_ar, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, + LlvmFilecheck, LlvmNm, LlvmObjdump, LlvmProfdata, LlvmReadobj, }; pub use python::python_command; pub use rustc::{aux_build, bare_rustc, rustc, Rustc}; diff --git a/tests/run-make/symbol-visibility/rmake.rs b/tests/run-make/symbol-visibility/rmake.rs index cd085cf05d0ed..b37ff44f4ead6 100644 --- a/tests/run-make/symbol-visibility/rmake.rs +++ b/tests/run-make/symbol-visibility/rmake.rs @@ -6,13 +6,16 @@ //@ ignore-windows-msvc -use run_make_support::{bin_name, dynamic_lib_name, is_windows, llvm_readobj, regex, rustc}; +//FIXME(Oneirical): This currently uses llvm-nm for symbol detection. However, +// the custom Rust-based solution of #128314 may prove to be an interesting alternative. + +use run_make_support::{bin_name, dynamic_lib_name, is_darwin, is_windows, llvm_nm, regex, rustc}; fn main() { - let mut cdylib_name = dynamic_lib_name("a_cdylib"); - let mut rdylib_name = dynamic_lib_name("a_rust_dylib"); + let cdylib_name = dynamic_lib_name("a_cdylib"); + let rdylib_name = dynamic_lib_name("a_rust_dylib"); let exe_name = bin_name("an_executable"); - let mut combined_cdylib_name = dynamic_lib_name("combined_rlib_dylib"); + let combined_cdylib_name = dynamic_lib_name("combined_rlib_dylib"); rustc().arg("-Zshare-generics=no").input("an_rlib.rs").run(); rustc().arg("-Zshare-generics=no").input("a_cdylib.rs").run(); rustc().arg("-Zshare-generics=no").input("a_rust_dylib.rs").run(); @@ -74,13 +77,13 @@ fn main() { // Check the combined case, where we generate a cdylib and an rlib in the same // compilation session: - // Check that a cdylib exports its public //[no_mangle] functions + // Check that a cdylib exports its public #[no_mangle] functions symbols_check( &combined_cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), true, ); - // Check that a cdylib exports the public //[no_mangle] functions of dependencies + // Check that a cdylib exports the public #[no_mangle] functions of dependencies symbols_check( &combined_cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), @@ -94,9 +97,9 @@ fn main() { rustc().arg("-Zshare-generics=yes").input("a_rust_dylib.rs").run(); rustc().arg("-Zshare-generics=yes").input("an_executable.rs").run(); - // Check that a cdylib exports its public //[no_mangle] functions + // Check that a cdylib exports its public #[no_mangle] functions symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), true); - // Check that a cdylib exports the public //[no_mangle] functions of dependencies + // Check that a cdylib exports the public #[no_mangle] functions of dependencies symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true); // Check that a cdylib DOES NOT export any public Rust functions symbols_check(&cdylib_name, SymbolCheckType::AnyRustSymbol, false); @@ -142,7 +145,15 @@ fn main() { #[track_caller] fn symbols_check(path: &str, symbol_check_type: SymbolCheckType, exists_once: bool) { - let out = llvm_readobj().arg("--dyn-symbols").input(path).run().invalid_stdout_utf8(); + let mut nm = llvm_nm(); + if is_windows() { + nm.arg("--extern-only"); + } else if is_darwin() { + nm.arg("--extern-only").arg("--defined-only"); + } else { + nm.arg("--dynamic"); + } + let out = nm.input(path).run().stdout_utf8(); assert_eq!( out.lines() .filter(|&line| !line.contains("__imp_") && has_symbol(line, symbol_check_type))