Skip to content

Commit 8e06142

Browse files
committed
Auto merge of rust-lang#128393 - jieyouxu:exp-pr-127060, r=<try>
[EXPERIMENTAL] `symbol-visibility`: `x86_64-mingw`, what did you see?! r? `@ghost` try-job: x86_64-mingw
2 parents 1ddedba + b5df083 commit 8e06142

File tree

5 files changed

+186
-124
lines changed

5 files changed

+186
-124
lines changed

src/tools/compiletest/src/command-list.rs

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
117117
"ignore-watchos",
118118
"ignore-windows",
119119
"ignore-windows-gnu",
120+
"ignore-windows-msvc",
120121
"ignore-x32",
121122
"ignore-x86",
122123
"ignore-x86_64",

src/tools/run-make-support/src/command.rs

+8
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,19 @@ pub struct CompletedProcess {
163163

164164
impl CompletedProcess {
165165
#[must_use]
166+
#[track_caller]
166167
pub fn stdout_utf8(&self) -> String {
167168
String::from_utf8(self.output.stdout.clone()).expect("stdout is not valid UTF-8")
168169
}
169170

170171
#[must_use]
172+
#[track_caller]
173+
pub fn invalid_stdout_utf8(&self) -> String {
174+
String::from_utf8_lossy(&self.output.stdout.clone()).to_string()
175+
}
176+
177+
#[must_use]
178+
#[track_caller]
171179
pub fn stderr_utf8(&self) -> String {
172180
String::from_utf8(self.output.stderr.clone()).expect("stderr is not valid UTF-8")
173181
}

src/tools/tidy/src/allowed_run_make_makefiles.txt

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ run-make/split-debuginfo/Makefile
5252
run-make/stable-symbol-names/Makefile
5353
run-make/staticlib-dylib-linkage/Makefile
5454
run-make/symbol-mangling-hashed/Makefile
55-
run-make/symbol-visibility/Makefile
5655
run-make/sysroot-crates-are-unstable/Makefile
5756
run-make/thumb-none-cortex-m/Makefile
5857
run-make/thumb-none-qemu/Makefile

tests/run-make/symbol-visibility/Makefile

-123
This file was deleted.
+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
//! Dynamic libraries on Rust used to export a very high amount of symbols, going as far as filling
2+
//! the output with mangled names and generic function names. After the rework in #38117, this test
3+
//! checks that no mangled Rust symbols are exported, and that generics are only shown if explicitly
4+
//! requested.
5+
//!
6+
//! See <https://github.com/rust-lang/rust/issues/37530>.
7+
8+
//@ ignore-windows-msvc
9+
// FIXME(jieyouxu): unknown reason why this test fails on msvc, likely because certain assertions
10+
// fail.
11+
12+
use run_make_support::{bin_name, dynamic_lib_name, is_windows, llvm_readobj, regex, rustc};
13+
14+
fn main() {
15+
let mut cdylib_name = dynamic_lib_name("a_cdylib");
16+
let mut rdylib_name = dynamic_lib_name("a_rust_dylib");
17+
let exe_name = bin_name("an_executable");
18+
let mut combined_cdylib_name = dynamic_lib_name("combined_rlib_dylib");
19+
rustc().arg("-Zshare-generics=no").input("an_rlib.rs").run();
20+
rustc().arg("-Zshare-generics=no").input("a_cdylib.rs").run();
21+
rustc().arg("-Zshare-generics=no").input("a_rust_dylib.rs").run();
22+
rustc().arg("-Zshare-generics=no").input("a_proc_macro.rs").run();
23+
rustc().arg("-Zshare-generics=no").input("an_executable.rs").run();
24+
rustc()
25+
.arg("-Zshare-generics=no")
26+
.input("a_cdylib.rs")
27+
.crate_name("combined_rlib_dylib")
28+
.crate_type("rlib,cdylib")
29+
.run();
30+
31+
// Check that a cdylib exports its public #[no_mangle] functions
32+
symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), true);
33+
// Check that a cdylib exports the public #[no_mangle] functions of dependencies
34+
symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true);
35+
// Check that a cdylib DOES NOT export any public Rust functions
36+
symbols_check(&cdylib_name, SymbolCheckType::AnyRustSymbol, false);
37+
38+
// Check that a Rust dylib exports its monomorphic functions
39+
symbols_check(
40+
&rdylib_name,
41+
SymbolCheckType::StrSymbol("public_c_function_from_rust_dylib"),
42+
true,
43+
);
44+
symbols_check(
45+
&rdylib_name,
46+
SymbolCheckType::StrSymbol("public_rust_function_from_rust_dylib"),
47+
true,
48+
);
49+
// Check that a Rust dylib does not export generics if -Zshare-generics=no
50+
symbols_check(
51+
&rdylib_name,
52+
SymbolCheckType::StrSymbol("public_generic_function_from_rust_dylib"),
53+
false,
54+
);
55+
56+
// Check that a Rust dylib exports the monomorphic functions from its dependencies
57+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true);
58+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_rust_function_from_rlib"), true);
59+
// Check that a Rust dylib does not export generics if -Zshare-generics=no
60+
symbols_check(
61+
&rdylib_name,
62+
SymbolCheckType::StrSymbol("public_generic_function_from_rlib"),
63+
false,
64+
);
65+
66+
// FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032
67+
// if is_windows() {
68+
// // Check that an executable does not export any dynamic symbols
69+
// symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib")
70+
//, false);
71+
// symbols_check(
72+
// &exe_name,
73+
// SymbolCheckType::StrSymbol("public_rust_function_from_exe"),
74+
// false,
75+
// );
76+
// }
77+
78+
// Check the combined case, where we generate a cdylib and an rlib in the same
79+
// compilation session:
80+
// Check that a cdylib exports its public //[no_mangle] functions
81+
symbols_check(
82+
&combined_cdylib_name,
83+
SymbolCheckType::StrSymbol("public_c_function_from_cdylib"),
84+
true,
85+
);
86+
// Check that a cdylib exports the public //[no_mangle] functions of dependencies
87+
symbols_check(
88+
&combined_cdylib_name,
89+
SymbolCheckType::StrSymbol("public_c_function_from_rlib"),
90+
true,
91+
);
92+
// Check that a cdylib DOES NOT export any public Rust functions
93+
symbols_check(&combined_cdylib_name, SymbolCheckType::AnyRustSymbol, false);
94+
95+
rustc().arg("-Zshare-generics=yes").input("an_rlib.rs").run();
96+
rustc().arg("-Zshare-generics=yes").input("a_cdylib.rs").run();
97+
rustc().arg("-Zshare-generics=yes").input("a_rust_dylib.rs").run();
98+
rustc().arg("-Zshare-generics=yes").input("an_executable.rs").run();
99+
100+
// Check that a cdylib exports its public //[no_mangle] functions
101+
symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), true);
102+
// Check that a cdylib exports the public //[no_mangle] functions of dependencies
103+
symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true);
104+
// Check that a cdylib DOES NOT export any public Rust functions
105+
symbols_check(&cdylib_name, SymbolCheckType::AnyRustSymbol, false);
106+
107+
// Check that a Rust dylib exports its monomorphic functions, including generics this time
108+
symbols_check(
109+
&rdylib_name,
110+
SymbolCheckType::StrSymbol("public_c_function_from_rust_dylib"),
111+
true,
112+
);
113+
symbols_check(
114+
&rdylib_name,
115+
SymbolCheckType::StrSymbol("public_rust_function_from_rust_dylib"),
116+
true,
117+
);
118+
symbols_check(
119+
&rdylib_name,
120+
SymbolCheckType::StrSymbol("public_generic_function_from_rust_dylib"),
121+
true,
122+
);
123+
124+
// Check that a Rust dylib exports the monomorphic functions from its dependencies
125+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true);
126+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_rust_function_from_rlib"), true);
127+
symbols_check(
128+
&rdylib_name,
129+
SymbolCheckType::StrSymbol("public_generic_function_from_rlib"),
130+
true,
131+
);
132+
133+
// FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032
134+
// if is_windows() {
135+
// // Check that an executable does not export any dynamic symbols
136+
// symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib")
137+
//, false);
138+
// symbols_check(
139+
// &exe_name,
140+
// SymbolCheckType::StrSymbol("public_rust_function_from_exe"),
141+
// false,
142+
// );
143+
// }
144+
}
145+
146+
#[track_caller]
147+
fn symbols_check(path: &str, symbol_check_type: SymbolCheckType, exists_once: bool) {
148+
let out = llvm_readobj().arg("--dyn-symbols").input(path).run().invalid_stdout_utf8();
149+
150+
let matched_lines = out
151+
.lines()
152+
.filter(|&line| !line.contains("__imp_") && has_symbol(line, symbol_check_type))
153+
.collect::<Vec<_>>();
154+
155+
if exists_once && matched_lines.len() != 1 {
156+
eprintln!("symbol_check_type: {:?}", symbol_check_type);
157+
eprintln!("exists_once: {}", exists_once);
158+
eprintln!("matched_lines:\n{:#?}", matched_lines);
159+
}
160+
161+
assert_eq!(matched_lines.len() == 1, exists_once);
162+
}
163+
164+
fn has_symbol(line: &str, symbol_check_type: SymbolCheckType) -> bool {
165+
if let SymbolCheckType::StrSymbol(expected) = symbol_check_type {
166+
line.contains(expected)
167+
} else {
168+
let regex = regex::Regex::new(r#"_ZN.*h.*E\|_R[a-zA-Z0-9_]+"#).unwrap();
169+
regex.is_match(line)
170+
}
171+
}
172+
173+
#[derive(Debug, Clone, Copy)]
174+
enum SymbolCheckType {
175+
StrSymbol(&'static str),
176+
AnyRustSymbol,
177+
}

0 commit comments

Comments
 (0)