From f66adb067f07ff14012a1ffdc5138da0bec2ee78 Mon Sep 17 00:00:00 2001 From: binarycat Date: Sun, 28 Jul 2024 14:04:55 -0400 Subject: [PATCH 1/4] port tests/run-make/extern-fn-reachable to rmake uses helper functions added in #128147, must not be merged before that PR. --- .../src/external_deps/rustc.rs | 5 ++++ src/tools/run-make-support/src/symbols.rs | 26 +++++++++++++++++++ .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/extern-fn-reachable/Makefile | 26 ------------------- tests/run-make/extern-fn-reachable/rmake.rs | 7 +++++ 5 files changed, 38 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/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index cece58d29566c..0c987222a4e7b 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -194,6 +194,11 @@ impl Rustc { self } + /// Make `rustc` prefere dynamic linking + pub fn prefer_dynamic(&mut self) -> &mut Self { + self.arg("-Cprefer-dynamic") + } + /// Specify directory path used for profile generation pub fn profile_generate>(&mut self, path: P) -> &mut Self { let mut arg = OsString::new(); diff --git a/src/tools/run-make-support/src/symbols.rs b/src/tools/run-make-support/src/symbols.rs index fd0c866bcc927..4ac74f9014f19 100644 --- a/src/tools/run-make-support/src/symbols.rs +++ b/src/tools/run-make-support/src/symbols.rs @@ -42,3 +42,29 @@ pub fn any_symbol_contains(path: impl AsRef, substrings: &[&str]) -> bool false }) } + +/// Check if an object file contains *all* of the given symbols. +/// +/// The symbol names must match exactly. +/// +/// Panics if `path` is not a valid object file readable by the current user. +pub fn contains_exact_symbols(path: impl AsRef, symbol_names: &[&str]) -> bool { + let mut found = vec![false; symbol_names.len()]; + with_symbol_iter(path, |syms| { + for sym in syms { + for (i, symbol_name) in symbol_names.iter().enumerate() { + found[i] |= sym.name_bytes().unwrap() == symbol_name.as_bytes(); + } + } + }); + let result = found.iter().all(|x| *x); + if !result { + eprintln!("does not contain symbol(s): "); + for i in 0..found.len() { + if !found[i] { + eprintln!("* {}", symbol_names[i]); + } + } + } + result +} diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a2cfdea712e7c..8399c754d9b74 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -5,7 +5,6 @@ run-make/dep-info-doesnt-run-much/Makefile run-make/dep-info-spaces/Makefile run-make/dep-info/Makefile run-make/emit-to-stdout/Makefile -run-make/extern-fn-reachable/Makefile run-make/incr-add-rust-src-component/Makefile run-make/issue-84395-lto-embed-bitcode/Makefile run-make/jobserver-error/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/rmake.rs b/tests/run-make/extern-fn-reachable/rmake.rs new file mode 100644 index 0000000000000..c9c822f01150f --- /dev/null +++ b/tests/run-make/extern-fn-reachable/rmake.rs @@ -0,0 +1,7 @@ +//@ ignore-cross-compile +use run_make_support::{rustc, symbols::contains_exact_symbols}; + +fn main() { + rustc().input("dylib.rs").output("dylib.so").prefer_dynamic().run(); + assert!(contains_exact_symbols("dylib.so", &["fun1", "fun2", "fun3", "fun4", "fun5"])); +} From 158f1ea6ad8e5da50dbf8001681e420a6f41e1bf Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 2 Aug 2024 12:11:02 -0400 Subject: [PATCH 2/4] fmt --- tests/run-make/extern-fn-reachable/rmake.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/run-make/extern-fn-reachable/rmake.rs b/tests/run-make/extern-fn-reachable/rmake.rs index c9c822f01150f..1a37909368566 100644 --- a/tests/run-make/extern-fn-reachable/rmake.rs +++ b/tests/run-make/extern-fn-reachable/rmake.rs @@ -1,5 +1,6 @@ //@ ignore-cross-compile -use run_make_support::{rustc, symbols::contains_exact_symbols}; +use run_make_support::rustc; +use run_make_support::symbols::contains_exact_symbols; fn main() { rustc().input("dylib.rs").output("dylib.so").prefer_dynamic().run(); From 8663bbecd5e35042cf1a432098b793346e1844d7 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 6 Aug 2024 14:53:52 -0400 Subject: [PATCH 3/4] refactor extern-fn-reachable to make sure symbols are exported --- src/tools/run-make-support/src/symbols.rs | 34 +++++++++++++-------- tests/run-make/extern-fn-reachable/rmake.rs | 10 ++++-- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/tools/run-make-support/src/symbols.rs b/src/tools/run-make-support/src/symbols.rs index 4ac74f9014f19..4a6d222e7a3f6 100644 --- a/src/tools/run-make-support/src/symbols.rs +++ b/src/tools/run-make-support/src/symbols.rs @@ -1,6 +1,6 @@ use std::path::Path; -use object::{self, Object, ObjectSymbol, SymbolIterator}; +use object::{self, Object, Symbol, ObjectSymbol, SymbolIterator}; /// Iterate through the symbols in an object file. /// @@ -43,28 +43,38 @@ pub fn any_symbol_contains(path: impl AsRef, substrings: &[&str]) -> bool }) } -/// Check if an object file contains *all* of the given symbols. +/// Get a list of symbols that are in `symbol_names` but not the final binary. +/// +/// The symbols must also match `pred`. /// /// The symbol names must match exactly. /// /// Panics if `path` is not a valid object file readable by the current user. -pub fn contains_exact_symbols(path: impl AsRef, symbol_names: &[&str]) -> bool { +pub fn missing_exact_symbols<'a>(path: impl AsRef, symbol_names: &[&'a str], pred: impl Fn(&Symbol<'_, '_>) -> bool) -> Vec<&'a str> { let mut found = vec![false; symbol_names.len()]; with_symbol_iter(path, |syms| { - for sym in syms { + for sym in syms.filter(&pred) { for (i, symbol_name) in symbol_names.iter().enumerate() { found[i] |= sym.name_bytes().unwrap() == symbol_name.as_bytes(); } } }); - let result = found.iter().all(|x| *x); - if !result { - eprintln!("does not contain symbol(s): "); - for i in 0..found.len() { - if !found[i] { - eprintln!("* {}", symbol_names[i]); - } + return found.iter().enumerate() + .filter_map(|(i, found)| if !*found { + Some(symbol_names[i]) + } else { + None + }).collect(); +} + +/// Assert that the symbol file contains all of the listed symbols and they all match the given predicate +pub fn assert_contains_exact_symbols(path: impl AsRef, symbol_names: &[&str], pred: impl Fn(&Symbol<'_, '_>) -> bool) { + let missing = missing_exact_symbols(path.as_ref(), symbol_names, pred); + if missing.len() > 0 { + eprintln!("{} does not contain symbol(s): ", path.as_ref().display()); + for sn in missing { + eprintln!("* {}", sn); } + panic!("missing symbols"); } - result } diff --git a/tests/run-make/extern-fn-reachable/rmake.rs b/tests/run-make/extern-fn-reachable/rmake.rs index 1a37909368566..1c53c58a0da9e 100644 --- a/tests/run-make/extern-fn-reachable/rmake.rs +++ b/tests/run-make/extern-fn-reachable/rmake.rs @@ -1,8 +1,12 @@ //@ ignore-cross-compile use run_make_support::rustc; -use run_make_support::symbols::contains_exact_symbols; - +use run_make_support::symbols::assert_contains_exact_symbols; +use run_make_support::object::ObjectSymbol; fn main() { rustc().input("dylib.rs").output("dylib.so").prefer_dynamic().run(); - assert!(contains_exact_symbols("dylib.so", &["fun1", "fun2", "fun3", "fun4", "fun5"])); + assert_contains_exact_symbols( + "dylib.so", + &["fun1", "fun2", "fun3", "fun4", "fun5"], + |sym| dbg!(dbg!(sym).is_global()) && !dbg!(sym.is_undefined()), + ); } From c1d8892acf1d485e9b3bc63d09d987e9cd816d0e Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 6 Aug 2024 15:07:02 -0400 Subject: [PATCH 4/4] fmt --- src/tools/run-make-support/src/symbols.rs | 25 +++++++++++++-------- tests/run-make/extern-fn-reachable/rmake.rs | 10 ++++----- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/tools/run-make-support/src/symbols.rs b/src/tools/run-make-support/src/symbols.rs index 4a6d222e7a3f6..54d84302df233 100644 --- a/src/tools/run-make-support/src/symbols.rs +++ b/src/tools/run-make-support/src/symbols.rs @@ -1,6 +1,6 @@ use std::path::Path; -use object::{self, Object, Symbol, ObjectSymbol, SymbolIterator}; +use object::{self, Object, ObjectSymbol, Symbol, SymbolIterator}; /// Iterate through the symbols in an object file. /// @@ -50,7 +50,11 @@ pub fn any_symbol_contains(path: impl AsRef, substrings: &[&str]) -> bool /// The symbol names must match exactly. /// /// Panics if `path` is not a valid object file readable by the current user. -pub fn missing_exact_symbols<'a>(path: impl AsRef, symbol_names: &[&'a str], pred: impl Fn(&Symbol<'_, '_>) -> bool) -> Vec<&'a str> { +pub fn missing_exact_symbols<'a>( + path: impl AsRef, + symbol_names: &[&'a str], + pred: impl Fn(&Symbol<'_, '_>) -> bool, +) -> Vec<&'a str> { let mut found = vec![false; symbol_names.len()]; with_symbol_iter(path, |syms| { for sym in syms.filter(&pred) { @@ -59,16 +63,19 @@ pub fn missing_exact_symbols<'a>(path: impl AsRef, symbol_names: &[&'a str } } }); - return found.iter().enumerate() - .filter_map(|(i, found)| if !*found { - Some(symbol_names[i]) - } else { - None - }).collect(); + return found + .iter() + .enumerate() + .filter_map(|(i, found)| if !*found { Some(symbol_names[i]) } else { None }) + .collect(); } /// Assert that the symbol file contains all of the listed symbols and they all match the given predicate -pub fn assert_contains_exact_symbols(path: impl AsRef, symbol_names: &[&str], pred: impl Fn(&Symbol<'_, '_>) -> bool) { +pub fn assert_contains_exact_symbols( + path: impl AsRef, + symbol_names: &[&str], + pred: impl Fn(&Symbol<'_, '_>) -> bool, +) { let missing = missing_exact_symbols(path.as_ref(), symbol_names, pred); if missing.len() > 0 { eprintln!("{} does not contain symbol(s): ", path.as_ref().display()); diff --git a/tests/run-make/extern-fn-reachable/rmake.rs b/tests/run-make/extern-fn-reachable/rmake.rs index 1c53c58a0da9e..dce2e3d526830 100644 --- a/tests/run-make/extern-fn-reachable/rmake.rs +++ b/tests/run-make/extern-fn-reachable/rmake.rs @@ -1,12 +1,10 @@ //@ ignore-cross-compile +use run_make_support::object::ObjectSymbol; use run_make_support::rustc; use run_make_support::symbols::assert_contains_exact_symbols; -use run_make_support::object::ObjectSymbol; fn main() { rustc().input("dylib.rs").output("dylib.so").prefer_dynamic().run(); - assert_contains_exact_symbols( - "dylib.so", - &["fun1", "fun2", "fun3", "fun4", "fun5"], - |sym| dbg!(dbg!(sym).is_global()) && !dbg!(sym.is_undefined()), - ); + assert_contains_exact_symbols("dylib.so", &["fun1", "fun2", "fun3", "fun4", "fun5"], |sym| { + dbg!(dbg!(sym).is_global()) && !dbg!(sym.is_undefined()) + }); }