Skip to content

Commit

Permalink
tests: port extern-fn-reachable to rmake.rs
Browse files Browse the repository at this point in the history
Co-authored-by: binarycat <[email protected]>
  • Loading branch information
jieyouxu and lolbinarycat committed Jan 14, 2025
1 parent c074d8e commit 98f673e
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 27 deletions.
1 change: 0 additions & 1 deletion src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
run-make/cat-and-grep-sanity-check/Makefile
run-make/extern-fn-reachable/Makefile
run-make/jobserver-error/Makefile
run-make/split-debuginfo/Makefile
run-make/symbol-mangling-hashed/Makefile
Expand Down
26 changes: 0 additions & 26 deletions tests/run-make/extern-fn-reachable/Makefile

This file was deleted.

15 changes: 15 additions & 0 deletions tests/run-make/extern-fn-reachable/dylib.rs
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() {}
46 changes: 46 additions & 0 deletions tests/run-make/extern-fn-reachable/rmake.rs
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");
}
}

0 comments on commit 98f673e

Please sign in to comment.