From 98f673e93a47b33a451f6b2cd99e5d5b03b57563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 14 Jan 2025 04:32:33 +0800 Subject: [PATCH] tests: port `extern-fn-reachable` to rmake.rs Co-authored-by: binarycat --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/extern-fn-reachable/Makefile | 26 ----------- tests/run-make/extern-fn-reachable/dylib.rs | 15 ++++++ tests/run-make/extern-fn-reachable/rmake.rs | 46 +++++++++++++++++++ 4 files changed, 61 insertions(+), 27 deletions(-) delete mode 100644 tests/run-make/extern-fn-reachable/Makefile create mode 100644 tests/run-make/extern-fn-reachable/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index b20d8678d0eae..575716eb6dd9d 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -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 diff --git a/tests/run-make/extern-fn-reachable/Makefile b/tests/run-make/extern-fn-reachable/Makefile deleted file mode 100644 index 3297251bfd1aa..0000000000000 --- a/tests/run-make/extern-fn-reachable/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# ignore-windows-msvc - -NM=nm -D - -ifeq ($(UNAME),Darwin) -NM=nm -gU -endif - -ifdef IS_WINDOWS -NM=nm -g -endif - -# This overrides the LD_LIBRARY_PATH for RUN -TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR) - -all: - $(RUSTC) dylib.rs -o $(TMPDIR)/libdylib.so -C prefer-dynamic - - [ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun1)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun2)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun3)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun4)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun5)" -eq "1" ] diff --git a/tests/run-make/extern-fn-reachable/dylib.rs b/tests/run-make/extern-fn-reachable/dylib.rs index fe0c7023b27b8..42b8270b214a3 100644 --- a/tests/run-make/extern-fn-reachable/dylib.rs +++ b/tests/run-make/extern-fn-reachable/dylib.rs @@ -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() {} diff --git a/tests/run-make/extern-fn-reachable/rmake.rs b/tests/run-make/extern-fn-reachable/rmake.rs new file mode 100644 index 0000000000000..2fc992b14ebb3 --- /dev/null +++ b/tests/run-make/extern-fn-reachable/rmake.rs @@ -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"); + } +}