Skip to content

Commit d2ec57d

Browse files
committed
rewrite symbol-visibility to rmake
1 parent 2495953 commit d2ec57d

File tree

3 files changed

+139
-124
lines changed

3 files changed

+139
-124
lines changed

Diff for: src/tools/tidy/src/allowed_run_make_makefiles.txt

-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ run-make/staticlib-blank-lib/Makefile
176176
run-make/staticlib-dylib-linkage/Makefile
177177
run-make/std-core-cycle/Makefile
178178
run-make/symbol-mangling-hashed/Makefile
179-
run-make/symbol-visibility/Makefile
180179
run-make/symbols-include-type-name/Makefile
181180
run-make/sysroot-crates-are-unstable/Makefile
182181
run-make/target-cpu-native/Makefile

Diff for: tests/run-make/symbol-visibility/Makefile

-123
This file was deleted.

Diff for: tests/run-make/symbol-visibility/rmake.rs

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// Dynamic libraries on Rust used to export a very high amount of symbols,
2+
// going as far as filling the output with mangled names and generic function
3+
// names. After the rework of #38117, this test checks that no mangled Rust symbols
4+
// are exported, and that generics are only shown if explicitely requested.
5+
// See https://github.com/rust-lang/rust/issues/37530
6+
7+
// FIXME(Oneirical): This may work without ignore-windows-msvc and ignore-cross-compile
8+
9+
use run_make_support::{bin_name, dynamic_lib_name, is_windows, llvm_readobj, regex, rustc};
10+
11+
fn main() {
12+
let cdylib_name = dynamic_lib_name("a_cdylib");
13+
let rdylib_name = dynamic_lib_name("a_rust_dylib");
14+
let exe_name = bin_name("an_executable");
15+
let combined_cdylib_name = dynamic_lib_name("combined_rlib_dylib");
16+
rustc().arg("-Zshare-generics=no").input("an_rlib.rs").run();
17+
rustc().arg("-Zshare-generics=no").input("a_cdylib.rs").run();
18+
rustc().arg("-Zshare-generics=no").input("a_rust_dylib.rs").run();
19+
rustc().arg("-Zshare-generics=no").input("a_proc_macro.rs").run();
20+
rustc().arg("-Zshare-generics=no").input("an_executable.rs").run();
21+
rustc()
22+
.arg("-Zshare-generics=no")
23+
.input("a_cdylib.rs")
24+
.crate_name("combined_rlib_dylib")
25+
.crate_type("rlib,cdylib")
26+
.run();
27+
28+
// Check that a cdylib exports its public #[no_mangle] functions
29+
symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), 2);
30+
// Check that a cdylib exports the public #[no_mangle] functions of dependencies
31+
symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), 2);
32+
// Check that a cdylib DOES NOT export any public Rust functions
33+
symbols_check(&cdylib_name, SymbolCheckType::AnyRustSymbol, 0);
34+
35+
// Check that a Rust dylib exports its monomorphic functions
36+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rust_dylib"), 2);
37+
symbols_check(
38+
&rdylib_name,
39+
SymbolCheckType::StrSymbol("public_rust_function_from_rust_dylib"),
40+
2,
41+
);
42+
// Check that a Rust dylib does not export generics if -Zshare-generics=no
43+
symbols_check(
44+
&rdylib_name,
45+
SymbolCheckType::StrSymbol("public_generic_function_from_rust_dylib"),
46+
1,
47+
);
48+
49+
// Check that a Rust dylib exports the monomorphic functions from its dependencies
50+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), 2);
51+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_rust_function_from_rlib"), 2);
52+
// Check that a Rust dylib does not export generics if -Zshare-generics=no
53+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_generic_function_from_rlib"), 1);
54+
55+
if is_windows() {
56+
// Check that an executable does not export any dynamic symbols
57+
symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), 0);
58+
symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_rust_function_from_exe"), 0);
59+
}
60+
61+
// Check the combined case, where we generate a cdylib and an rlib in the same
62+
// compilation session:
63+
// Check that a cdylib exports its public //[no_mangle] functions
64+
symbols_check(
65+
&combined_cdylib_name,
66+
SymbolCheckType::StrSymbol("public_c_function_from_cdylib"),
67+
2,
68+
);
69+
// Check that a cdylib exports the public //[no_mangle] functions of dependencies
70+
symbols_check(
71+
&combined_cdylib_name,
72+
SymbolCheckType::StrSymbol("public_c_function_from_rlib"),
73+
2,
74+
);
75+
// Check that a cdylib DOES NOT export any public Rust functions
76+
symbols_check(&combined_cdylib_name, SymbolCheckType::AnyRustSymbol, 0);
77+
78+
rustc().arg("-Zshare-generics=yes").input("an_rlib.rs").run();
79+
rustc().arg("-Zshare-generics=yes").input("a_cdylib.rs").run();
80+
rustc().arg("-Zshare-generics=yes").input("a_rust_dylib.rs").run();
81+
rustc().arg("-Zshare-generics=yes").input("an_executable.rs").run();
82+
83+
// Check that a cdylib exports its public //[no_mangle] functions
84+
symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), 2);
85+
// Check that a cdylib exports the public //[no_mangle] functions of dependencies
86+
symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), 2);
87+
// Check that a cdylib DOES NOT export any public Rust functions
88+
symbols_check(&cdylib_name, SymbolCheckType::AnyRustSymbol, 0);
89+
90+
// Check that a Rust dylib exports its monomorphic functions, including generics this time
91+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rust_dylib"), 2);
92+
symbols_check(
93+
&rdylib_name,
94+
SymbolCheckType::StrSymbol("public_rust_function_from_rust_dylib"),
95+
2,
96+
);
97+
symbols_check(
98+
&rdylib_name,
99+
SymbolCheckType::StrSymbol("public_generic_function_from_rust_dylib"),
100+
2,
101+
);
102+
103+
// Check that a Rust dylib exports the monomorphic functions from its dependencies
104+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), 2);
105+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_rust_function_from_rlib"), 2);
106+
symbols_check(&rdylib_name, SymbolCheckType::StrSymbol("public_generic_function_from_rlib"), 2);
107+
108+
if is_windows() {
109+
// Check that an executable does not export any dynamic symbols
110+
symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), 0);
111+
symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_rust_function_from_exe"), 0);
112+
}
113+
}
114+
115+
#[track_caller]
116+
fn symbols_check(path: &str, symbol_check_type: SymbolCheckType, count: usize) {
117+
let out = llvm_readobj().arg("--symbols").input(path).run().stdout_utf8();
118+
assert_eq!(
119+
out.lines()
120+
.filter(|&line| !line.contains("__imp_") && has_symbol(line, symbol_check_type))
121+
.count(),
122+
count
123+
);
124+
}
125+
126+
fn has_symbol(line: &str, symbol_check_type: SymbolCheckType) -> bool {
127+
if let SymbolCheckType::StrSymbol(expected) = symbol_check_type {
128+
line.contains(expected)
129+
} else {
130+
let regex = regex::Regex::new(r#"_ZN.*h.*E\|_R[a-zA-Z0-9_]+"#).unwrap();
131+
regex.is_match(line)
132+
}
133+
}
134+
135+
#[derive(Clone, Copy)]
136+
enum SymbolCheckType {
137+
StrSymbol(&'static str),
138+
AnyRustSymbol,
139+
}

0 commit comments

Comments
 (0)