Skip to content

Commit b75711a

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

File tree

3 files changed

+144
-124
lines changed

3 files changed

+144
-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

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

0 commit comments

Comments
 (0)