Skip to content

Commit 10841e5

Browse files
tests: port symbol-mangling-hashed to rmake.rs
- Use `object` based test logic instead of processing `nm` human-readable textual output. - Try to expand test coverage to not be limited to only linux + x86_64. Co-authored-by: binarycat <[email protected]>
1 parent 2eddc58 commit 10841e5

File tree

3 files changed

+264
-49
lines changed

3 files changed

+264
-49
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
run-make/cat-and-grep-sanity-check/Makefile
22
run-make/jobserver-error/Makefile
33
run-make/split-debuginfo/Makefile
4-
run-make/symbol-mangling-hashed/Makefile
54
run-make/translation/Makefile

tests/run-make/symbol-mangling-hashed/Makefile

-48
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
// ignore-tidy-linelength
2+
//! Basic smoke test for the unstable option `-C symbol_mangling_version=hashed` which aims to
3+
//! replace full symbol mangling names based on hash digests to shorten symbol name lengths in
4+
//! dylibs for space savings.
5+
//!
6+
//! # References
7+
//!
8+
//! - MCP #705: Provide option to shorten symbol names by replacing them with a digest:
9+
//! <https://github.com/rust-lang/compiler-team/issues/705>.
10+
//! - Implementation PR: <https://github.com/rust-lang/rust/pull/118636>.
11+
//! - PE format: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format>.
12+
13+
//@ ignore-cross-compile
14+
15+
#![deny(warnings)]
16+
17+
use run_make_support::object::{self, Object, ObjectSection};
18+
use run_make_support::symbols::{
19+
dynamic_symbol_names, global_undefined_dynamic_symbol_names,
20+
text_section_global_dynamic_symbol_names,
21+
};
22+
use run_make_support::{bin_name, cwd, dynamic_lib_name, is_msvc, rfs, rustc};
23+
const TEXT_SECTION: &str = ".text";
24+
25+
fn main() {
26+
rustc()
27+
.input("a_dylib.rs")
28+
.prefer_dynamic()
29+
.arg("-Zunstable-options")
30+
.symbol_mangling_version("hashed")
31+
.metadata("foo")
32+
.run();
33+
34+
rustc()
35+
.input("a_rlib.rs")
36+
.prefer_dynamic()
37+
.arg("-Zunstable-options")
38+
.symbol_mangling_version("hashed")
39+
.metadata("bar")
40+
.run();
41+
42+
rustc().input("b_dylib.rs").library_search_path(cwd()).prefer_dynamic().run();
43+
rustc().input("b_bin.rs").library_search_path(cwd()).prefer_dynamic().run();
44+
45+
// Check hashed symbol name
46+
47+
{
48+
let dylib_filename = dynamic_lib_name("a_dylib");
49+
println!("checking dylib `{dylib_filename}`");
50+
51+
let dylib_blob = rfs::read(&dylib_filename);
52+
let dylib_file = object::File::parse(&*dylib_blob)
53+
.unwrap_or_else(|e| panic!("failed to parse `{dylib_filename}`: {e}"));
54+
55+
if is_msvc() {
56+
let dynamic_symbols = dylib_file.exports().unwrap();
57+
let dynamic_symbol_names: Vec<_> = dynamic_symbols
58+
.iter()
59+
.map(|exp| std::str::from_utf8(exp.name()).unwrap())
60+
.collect();
61+
62+
if dynamic_symbol_names.iter().filter(|sym| sym.contains("hello")).count() != 0 {
63+
eprintln!("dynamic symbols: {:#?}", dynamic_symbols);
64+
panic!("expected no occurrence of `hello`");
65+
}
66+
67+
if dynamic_symbol_names.iter().filter(|sym| sym.starts_with("_RNxC7a_dylib")).count()
68+
!= 2
69+
{
70+
eprintln!("dynamic symbols: {:#?}", dynamic_symbol_names);
71+
panic!("expected two dynamic symbols starting with `_RNxC7a_dylib`");
72+
}
73+
} else {
74+
let dynamic_symbols = dynamic_symbol_names(&dylib_file);
75+
76+
let text_section =
77+
dylib_file.section_by_name(TEXT_SECTION).expect("couldn't find `.text` section");
78+
let text_section_global_dynamic_symbols =
79+
text_section_global_dynamic_symbol_names(&dylib_file, text_section.index());
80+
81+
if dynamic_symbols.iter().filter(|sym| sym.contains("hello")).count() != 0 {
82+
eprintln!("dynamic symbols: {:#?}", dynamic_symbols);
83+
panic!("expected no occurrence of `hello`");
84+
}
85+
86+
if text_section_global_dynamic_symbols
87+
.iter()
88+
.filter(|sym| sym.starts_with("_RNxC7a_dylib"))
89+
.count()
90+
!= 2
91+
{
92+
eprintln!(
93+
"global dynamic symbols in `.text` section: {:#?}",
94+
text_section_global_dynamic_symbols
95+
);
96+
panic!(
97+
"expected two global dynamic symbols starting with `_RNxC7a_dylib` in `.text` section"
98+
);
99+
}
100+
}
101+
}
102+
103+
{
104+
let so_filename = dynamic_lib_name("b_dylib");
105+
println!("checking so `{so_filename}`");
106+
107+
let so_blob = rfs::read(&so_filename);
108+
let so_file = object::File::parse(&*so_blob)
109+
.unwrap_or_else(|e| panic!("failed to parse `{so_filename}`: {e}"));
110+
111+
if is_msvc() {
112+
let dynamic_symbols = so_file.exports().unwrap();
113+
let dynamic_symbol_names: Vec<_> = dynamic_symbols
114+
.iter()
115+
.map(|exp| std::str::from_utf8(exp.name()).unwrap())
116+
.collect();
117+
118+
if dynamic_symbol_names
119+
.iter()
120+
.filter(|sym| sym.contains("b_dylib") && sym.contains("hello"))
121+
.count()
122+
!= 1
123+
{
124+
eprintln!("dynamic symbols: {:#?}", dynamic_symbol_names);
125+
panic!("expected one occurrence of mangled `hello`");
126+
}
127+
128+
if dynamic_symbol_names.iter().filter(|sym| sym.starts_with("_RNxC6a_rlib")).count()
129+
!= 2
130+
{
131+
eprintln!("dynamic symbols: {:#?}", dynamic_symbol_names);
132+
panic!(
133+
"expected two global dynamic symbols starting with `_RNxC6a_rlib` in `.text` section"
134+
);
135+
}
136+
137+
if dynamic_symbol_names.iter().any(|sym| sym.starts_with("_RNxC7a_dylib")) {
138+
eprintln!("dynamic symbols: {:#?}", dynamic_symbol_names);
139+
panic!("did not expect any symbols starting with `_RNxC7a_dylib`");
140+
}
141+
} else {
142+
let dynamic_symbols = dynamic_symbol_names(&so_file);
143+
144+
let text_section =
145+
so_file.section_by_name(TEXT_SECTION).expect("couldn't find `.text` section");
146+
let text_section_global_dynamic_symbols =
147+
text_section_global_dynamic_symbol_names(&so_file, text_section.index());
148+
149+
let global_undefined_dynamic_symbols = global_undefined_dynamic_symbol_names(&so_file);
150+
151+
if dynamic_symbols
152+
.iter()
153+
.filter(|sym| sym.contains("b_dylib") && sym.contains("hello"))
154+
.count()
155+
!= 1
156+
{
157+
eprintln!("dynamic symbols: {:#?}", dynamic_symbols);
158+
panic!("expected one occurrence of mangled `hello`");
159+
}
160+
161+
if text_section_global_dynamic_symbols
162+
.iter()
163+
.filter(|sym| sym.starts_with("_RNxC6a_rlib"))
164+
.count()
165+
!= 2
166+
{
167+
eprintln!(
168+
"global dynamic symbols in `.text` section: {:#?}",
169+
text_section_global_dynamic_symbols
170+
);
171+
panic!(
172+
"expected two global dynamic symbols starting with `_RNxC6a_rlib` in `.text` section"
173+
);
174+
}
175+
176+
if global_undefined_dynamic_symbols
177+
.iter()
178+
.filter(|sym| sym.starts_with("_RNxC7a_dylib"))
179+
.count()
180+
!= 1
181+
{
182+
eprintln!(
183+
"global undefined dynamic symbols: {:#?}",
184+
global_undefined_dynamic_symbols
185+
);
186+
panic!(
187+
"expected one global undefined dynamic symbol starting with `_RNxC7a_dylib`"
188+
);
189+
}
190+
}
191+
}
192+
193+
{
194+
let bin_filename = bin_name("b_bin");
195+
println!("checking bin `{bin_filename}`");
196+
197+
let bin_blob = rfs::read(&bin_filename);
198+
let bin_file = object::File::parse(&*bin_blob)
199+
.unwrap_or_else(|e| panic!("failed to parse `{bin_filename}`: {e}"));
200+
201+
if is_msvc() {
202+
let dynamic_symbols = bin_file.exports().unwrap();
203+
let dynamic_symbol_names: Vec<_> = dynamic_symbols
204+
.iter()
205+
.map(|exp| std::str::from_utf8(exp.name()).unwrap())
206+
.collect();
207+
208+
if dynamic_symbol_names.iter().any(|sym| {
209+
sym.starts_with("_RNxC6a_rlib")
210+
|| sym.starts_with("_RNxC7a_dylib")
211+
|| (sym.contains("b_dylib") && sym.contains("hello"))
212+
}) {
213+
eprintln!("dynamic symbols: {:#?}", dynamic_symbol_names);
214+
panic!(
215+
"did not expect any symbols to (1) start with `_RNxC6a_rlib` or (2) start with \
216+
`_RNxC7a_dylib` or (3) to be of the form `*b_dylib*hello*`"
217+
);
218+
}
219+
} else {
220+
let global_undefined_dynamic_symbols = global_undefined_dynamic_symbol_names(&bin_file);
221+
222+
if global_undefined_dynamic_symbols
223+
.iter()
224+
.filter(|sym| sym.starts_with("_RNxC6a_rlib"))
225+
.count()
226+
!= 1
227+
{
228+
eprintln!(
229+
"global undefined dynamic symbols: {:#?}",
230+
global_undefined_dynamic_symbols
231+
);
232+
panic!("expected one global undefined dynamic symbol starting with `_RNxC6a_rlib`");
233+
}
234+
235+
if global_undefined_dynamic_symbols
236+
.iter()
237+
.filter(|sym| sym.starts_with("_RNxC7a_dylib"))
238+
.count()
239+
!= 1
240+
{
241+
eprintln!(
242+
"global undefined dynamic symbols: {:#?}",
243+
global_undefined_dynamic_symbols
244+
);
245+
panic!(
246+
"expected one global undefined dynamic symbol starting with `_RNxC7a_dylib`"
247+
);
248+
}
249+
250+
if global_undefined_dynamic_symbols
251+
.iter()
252+
.filter(|sym| sym.contains("b_dylib") && sym.contains("hello"))
253+
.count()
254+
!= 1
255+
{
256+
eprintln!(
257+
"global undefined dynamic symbols: {:#?}",
258+
global_undefined_dynamic_symbols
259+
);
260+
panic!("expected one global undefined dynamic mangled `hello`");
261+
}
262+
}
263+
}
264+
}

0 commit comments

Comments
 (0)