-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #135458 - jieyouxu:migrate-extern-fn-reachable, r=lqd
tests: Port `extern-fn-reachable` to rmake.rs Part of #121876. ## Summary This PR ports `tests/run-make/extern-fn-reachable` to use `rmake.rs`. Notable changes: - We now use the `object` crate and look at the exported symbols specifically. - This test's coverage regressed against windows-msvc back in [replace dynamic library module with libloading #90716](#90716), but since we use `object` now, we're able to claw the test coverage back. - The checks are now stricter: 1. It no longer looks for substring symbol matches in `nm` textual outputs, it inspects the symbol names precisely. 2. We now also explicitly check for the presence of leading underscore in exported symbol names on apple vs non-apple targets. - Added another case of `#[no_mangle] fn fun6() {}` (note the lack of `pub`) to check that Rust nameres visibility is orthogonal to symbol visibility in dylib. ## History - Test was initially introduced as a run-pass[^run-pass] test as part of [Don't mark reachable extern fns as internal #10539](#10539). - Test re-introduced as a run-make test in #13741. - Later, the test coverage regressed in #90716. [^run-pass]: no longer a thing nowadays Supersedes #128314. Co-authored with `@lolbinarycat.` try-job: x86_64-msvc try-job: i686-msvc try-job: i686-mingw try-job: x86_64-mingw-1 try-job: x86_64-apple-1 try-job: aarch64-apple try-job: test-various
- Loading branch information
Showing
4 changed files
with
61 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,34 @@ | ||
#![crate_type = "dylib"] | ||
#![allow(dead_code)] | ||
|
||
// `pub` extern fn here is a Rust nameres visibility concept, and should not affect symbol | ||
// visibility in the dylib. | ||
#[no_mangle] | ||
pub extern "C" fn fun1() {} | ||
|
||
// (Lack of) `pub` for the extern fn here is a Rust nameres visibility concept, and should not | ||
// affect symbol visibility in the dylib. | ||
#[no_mangle] | ||
extern "C" fn fun2() {} | ||
|
||
// Modules are a Rust nameres concept, and should not affect symbol visibility in the dylib if the | ||
// extern fn is nested inside a module. | ||
mod foo { | ||
#[no_mangle] | ||
pub extern "C" fn fun3() {} | ||
} | ||
|
||
// Similarly, the Rust visibility of the containing module is a Rust nameres concept, and should not | ||
// affect symbol visibility in the dylib. | ||
pub mod bar { | ||
#[no_mangle] | ||
pub extern "C" fn fun4() {} | ||
} | ||
|
||
// Non-extern `#[no_mangle]` fn should induce a symbol visible in the dylib. | ||
#[no_mangle] | ||
pub fn fun5() {} | ||
|
||
// The Rust visibility of the fn should not affect is symbol visibility in the dylib. | ||
#[no_mangle] | ||
fn fun6() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
//! Smoke test to check that that symbols of `extern "C"` functions and `#[no_mangle]` rust | ||
//! functions: | ||
//! | ||
//! 1. Are externally visible in the dylib produced. | ||
//! 2. That the symbol visibility is orthogonal to the Rust nameres visibility of the functions | ||
//! involved. | ||
//@ ignore-cross-compile | ||
|
||
use std::collections::BTreeSet; | ||
|
||
use run_make_support::object::{self, Object}; | ||
use run_make_support::{dynamic_lib_name, is_darwin, path, rfs, rustc}; | ||
|
||
fn main() { | ||
let dylib = dynamic_lib_name("dylib"); | ||
rustc().input("dylib.rs").output(&dylib).arg("-Cprefer-dynamic").run(); | ||
|
||
let expected_symbols = if is_darwin() { | ||
// Mach-O states that all exported symbols should have an underscore as prefix. At the | ||
// same time dlsym will implicitly add it, so outside of compilers, linkers and people | ||
// writing assembly, nobody needs to be aware of this. | ||
BTreeSet::from(["_fun1", "_fun2", "_fun3", "_fun4", "_fun5", "_fun6"]) | ||
} else { | ||
BTreeSet::from(["fun1", "fun2", "fun3", "fun4", "fun5", "fun6"]) | ||
}; | ||
|
||
let mut found_symbols = BTreeSet::new(); | ||
|
||
let blob = rfs::read(path(dylib)); | ||
let file = object::File::parse(&*blob).unwrap(); | ||
for export in file.exports().unwrap() { | ||
let sym_name = export.name(); | ||
let sym_name = std::str::from_utf8(sym_name).unwrap(); | ||
found_symbols.insert(sym_name); | ||
} | ||
|
||
println!("expected_symbols = {:?}", expected_symbols); | ||
println!("found_symbols = {:?}", found_symbols); | ||
if !found_symbols.is_superset(&expected_symbols) { | ||
for diff in expected_symbols.difference(&found_symbols) { | ||
eprintln!("missing symbol: {}", diff); | ||
} | ||
panic!("missing expected symbols"); | ||
} | ||
} |