From ec6e07b09d0c499f4f3233f04826ecf2ce77800b Mon Sep 17 00:00:00 2001
From: Jerry Wang <jerrylwang123@gmail.com>
Date: Sat, 13 Jul 2024 14:27:56 -0400
Subject: [PATCH 1/2] Migrate `crate-hash-rustc-version` to `rmake`

---
 .../tidy/src/allowed_run_make_makefiles.txt   |  1 -
 .../crate-hash-rustc-version/Makefile         | 38 ---------------
 .../crate-hash-rustc-version/rmake.rs         | 47 +++++++++++++++++++
 3 files changed, 47 insertions(+), 39 deletions(-)
 delete mode 100644 tests/run-make/crate-hash-rustc-version/Makefile
 create mode 100644 tests/run-make/crate-hash-rustc-version/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 f7ec7d0b3f6b9..b2c1ff3f5f418 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -12,7 +12,6 @@ run-make/cdylib-dylib-linkage/Makefile
 run-make/compiler-lookup-paths-2/Makefile
 run-make/compiler-lookup-paths/Makefile
 run-make/compiler-rt-works-on-mingw/Makefile
-run-make/crate-hash-rustc-version/Makefile
 run-make/cross-lang-lto-clang/Makefile
 run-make/cross-lang-lto-pgo-smoketest/Makefile
 run-make/cross-lang-lto-upstream-rlibs/Makefile
diff --git a/tests/run-make/crate-hash-rustc-version/Makefile b/tests/run-make/crate-hash-rustc-version/Makefile
deleted file mode 100644
index 6bf504bf01be5..0000000000000
--- a/tests/run-make/crate-hash-rustc-version/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# Ensure that crates compiled with different rustc versions cannot
-# be dynamically linked.
-
-FLAGS := -Cprefer-dynamic -Csymbol-mangling-version=v0
-UNAME := $(shell uname)
-ifeq ($(UNAME),Linux)
-  EXT=".so"
-  NM_CMD := nm -D
-endif
-ifeq ($(UNAME),Darwin)
-  EXT=".dylib"
-  NM_CMD := nm
-endif
-
-ifndef NM_CMD
-all:
-	exit 0
-else
-all:
-	# a.rs is a dylib
-	$(RUSTC) a.rs --crate-type=dylib $(FLAGS)
-	# Write symbols to disk.
-	$(NM_CMD) $(call DYLIB,a) > $(TMPDIR)/symbolsbefore
-	# b.rs is a binary
-	$(RUSTC) b.rs --extern a=$(TMPDIR)/liba$(EXT) --crate-type=bin -Crpath $(FLAGS)
-	$(call RUN,b)
-	# Now re-compile a.rs with another rustc version
-	RUSTC_FORCE_RUSTC_VERSION=deadfeed $(RUSTC) a.rs --crate-type=dylib $(FLAGS)
-	# After compiling with a different rustc version, write symbols to disk again.
-	$(NM_CMD) $(call DYLIB,a) > $(TMPDIR)/symbolsafter
-	# As a sanity check, test if the symbols changed:
-	# If the symbols are identical, there's been an error.
-	if diff $(TMPDIR)/symbolsbefore $(TMPDIR)/symbolsafter; then exit 1; fi
-	$(call FAIL,b)
-endif
diff --git a/tests/run-make/crate-hash-rustc-version/rmake.rs b/tests/run-make/crate-hash-rustc-version/rmake.rs
new file mode 100644
index 0000000000000..6418deb126bd9
--- /dev/null
+++ b/tests/run-make/crate-hash-rustc-version/rmake.rs
@@ -0,0 +1,47 @@
+// Ensure that crates compiled with different rustc versions cannot
+// be dynamically linked.
+
+//@ ignore-cross-compile
+//@ only-unix
+
+use run_make_support::{cmd, diff, dynamic_lib_name, is_darwin, run, run_fail, rustc};
+
+fn main() {
+    let flags = ["-Cprefer-dynamic", "-Csymbol-mangling-version=v0"];
+    let nm_flag = if is_darwin() { [].as_slice() } else { ["-D"].as_slice() };
+
+    // a.rs is compiled to a dylib
+    rustc().input("a.rs").crate_type("dylib").args(&flags).run();
+
+    // Store symbols
+    let symbols_before = cmd("nm").args(nm_flag).arg(dynamic_lib_name("a")).run().stdout_utf8();
+
+    // b.rs is compiled to a binary
+    rustc()
+        .input("b.rs")
+        .extern_("a", dynamic_lib_name("a"))
+        .crate_type("bin")
+        .arg("-Crpath")
+        .args(&flags)
+        .run();
+    run("b");
+
+    // Now re-compile a.rs with another rustc version
+    rustc()
+        .env("RUSTC_FORCE_RUSTC_VERSION", "deadfeed")
+        .input("a.rs")
+        .crate_type("dylib")
+        .args(&flags)
+        .run();
+
+    // After compiling with a different rustc version, store symbols again.
+    let symbols_after = cmd("nm").args(nm_flag).arg(dynamic_lib_name("a")).run().stdout_utf8();
+
+    // As a sanity check, test if the symbols changed:
+    // If the symbols are identical, there's been an error.
+    diff()
+        .expected_text("symbols_before", symbols_before)
+        .actual_text("symbols_after", symbols_after)
+        .run_fail();
+    run_fail("b");
+}

From eea6502dcb91942785b1d5cb8fea74c41bcc3f32 Mon Sep 17 00:00:00 2001
From: Jerry Wang <jerrylwang123@gmail.com>
Date: Mon, 15 Jul 2024 19:52:22 -0400
Subject: [PATCH 2/2] Use `llvm-readobj` for
 `run-make/crate-hash-rustc-version`

---
 .../run-make/crate-hash-rustc-version/rmake.rs | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/tests/run-make/crate-hash-rustc-version/rmake.rs b/tests/run-make/crate-hash-rustc-version/rmake.rs
index 6418deb126bd9..97b3dd3931e87 100644
--- a/tests/run-make/crate-hash-rustc-version/rmake.rs
+++ b/tests/run-make/crate-hash-rustc-version/rmake.rs
@@ -4,17 +4,27 @@
 //@ ignore-cross-compile
 //@ only-unix
 
-use run_make_support::{cmd, diff, dynamic_lib_name, is_darwin, run, run_fail, rustc};
+use run_make_support::llvm;
+use run_make_support::{diff, dynamic_lib_name, is_darwin, run, run_fail, rustc};
+
+fn llvm_readobj() -> llvm::LlvmReadobj {
+    let mut cmd = llvm::llvm_readobj();
+    if is_darwin() {
+        cmd.symbols();
+    } else {
+        cmd.dynamic_table();
+    }
+    cmd
+}
 
 fn main() {
     let flags = ["-Cprefer-dynamic", "-Csymbol-mangling-version=v0"];
-    let nm_flag = if is_darwin() { [].as_slice() } else { ["-D"].as_slice() };
 
     // a.rs is compiled to a dylib
     rustc().input("a.rs").crate_type("dylib").args(&flags).run();
 
     // Store symbols
-    let symbols_before = cmd("nm").args(nm_flag).arg(dynamic_lib_name("a")).run().stdout_utf8();
+    let symbols_before = llvm_readobj().arg(dynamic_lib_name("a")).run().stdout_utf8();
 
     // b.rs is compiled to a binary
     rustc()
@@ -35,7 +45,7 @@ fn main() {
         .run();
 
     // After compiling with a different rustc version, store symbols again.
-    let symbols_after = cmd("nm").args(nm_flag).arg(dynamic_lib_name("a")).run().stdout_utf8();
+    let symbols_after = llvm_readobj().arg(dynamic_lib_name("a")).run().stdout_utf8();
 
     // As a sanity check, test if the symbols changed:
     // If the symbols are identical, there's been an error.