|
4 | 4 | // are exported, and that generics are only shown if explicitely requested.
|
5 | 5 | // See https://github.com/rust-lang/rust/issues/37530
|
6 | 6 |
|
7 |
| -//@ ignore-windows-msvc |
8 |
| - |
9 |
| -//FIXME(Oneirical): This currently uses llvm-nm for symbol detection. However, |
10 |
| -// the custom Rust-based solution of #128314 may prove to be an interesting alternative. |
11 |
| - |
12 |
| -use run_make_support::{bin_name, dynamic_lib_name, is_darwin, is_windows, llvm_nm, regex, rustc}; |
| 7 | +use run_make_support::object::read::Object; |
| 8 | +use run_make_support::{bin_name, dynamic_lib_name, is_msvc, object, regex, rfs, rustc}; |
13 | 9 |
|
14 | 10 | fn main() {
|
15 | 11 | let cdylib_name = dynamic_lib_name("a_cdylib");
|
@@ -64,16 +60,15 @@ fn main() {
|
64 | 60 | );
|
65 | 61 |
|
66 | 62 | // 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 |
| - // } |
| 63 | + if is_msvc() { |
| 64 | + // Check that an executable does not export any dynamic symbols |
| 65 | + symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), false); |
| 66 | + symbols_check( |
| 67 | + &exe_name, |
| 68 | + SymbolCheckType::StrSymbol("public_rust_function_from_exe"), |
| 69 | + false, |
| 70 | + ); |
| 71 | + } |
77 | 72 |
|
78 | 73 | // Check the combined case, where we generate a cdylib and an rlib in the same
|
79 | 74 | // compilation session:
|
@@ -131,44 +126,37 @@ fn main() {
|
131 | 126 | );
|
132 | 127 |
|
133 | 128 | // 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 |
| - // } |
| 129 | + if is_msvc() { |
| 130 | + // Check that an executable does not export any dynamic symbols |
| 131 | + symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), false); |
| 132 | + symbols_check( |
| 133 | + &exe_name, |
| 134 | + SymbolCheckType::StrSymbol("public_rust_function_from_exe"), |
| 135 | + false, |
| 136 | + ); |
| 137 | + } |
144 | 138 | }
|
145 | 139 |
|
146 | 140 | #[track_caller]
|
147 | 141 | fn symbols_check(path: &str, symbol_check_type: SymbolCheckType, exists_once: bool) {
|
148 |
| - let mut nm = llvm_nm(); |
149 |
| - if is_windows() { |
150 |
| - nm.arg("--extern-only"); |
151 |
| - } else if is_darwin() { |
152 |
| - nm.arg("--extern-only").arg("--defined-only"); |
153 |
| - } else { |
154 |
| - nm.arg("--dynamic"); |
| 142 | + let binary_data = rfs::read(path); |
| 143 | + let file = object::File::parse(&*binary_data).unwrap(); |
| 144 | + let mut found: u64 = 0; |
| 145 | + for export in file.exports().unwrap() { |
| 146 | + let name = std::str::from_utf8(export.name()).unwrap(); |
| 147 | + if has_symbol(name, symbol_check_type) { |
| 148 | + found += 1; |
| 149 | + } |
155 | 150 | }
|
156 |
| - let out = nm.input(path).run().stdout_utf8(); |
157 |
| - assert_eq!( |
158 |
| - out.lines() |
159 |
| - .filter(|&line| !line.contains("__imp_") && has_symbol(line, symbol_check_type)) |
160 |
| - .count() |
161 |
| - == 1, |
162 |
| - exists_once |
163 |
| - ); |
| 151 | + assert_eq!(found, exists_once as u64); |
164 | 152 | }
|
165 | 153 |
|
166 |
| -fn has_symbol(line: &str, symbol_check_type: SymbolCheckType) -> bool { |
| 154 | +fn has_symbol(name: &str, symbol_check_type: SymbolCheckType) -> bool { |
167 | 155 | if let SymbolCheckType::StrSymbol(expected) = symbol_check_type {
|
168 |
| - line.contains(expected) |
| 156 | + name.contains(expected) |
169 | 157 | } else {
|
170 | 158 | let regex = regex::Regex::new(r#"_ZN.*h.*E\|_R[a-zA-Z0-9_]+"#).unwrap();
|
171 |
| - regex.is_match(line) |
| 159 | + regex.is_match(name) |
172 | 160 | }
|
173 | 161 | }
|
174 | 162 |
|
|
0 commit comments