Add support for raw-dylib

This commit is contained in:
Daniel Paoliello 2024-08-02 13:53:09 -07:00
parent fdc6a5562b
commit 2756bd6ff7
8 changed files with 120 additions and 91 deletions

14
Cargo.lock generated
View File

@ -20,6 +20,15 @@ version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "ar_archive_writer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f2bcb7cf51decfbbfc7ef476e28b0775b13e5eb1190f8b7df145cd53d4f4374"
dependencies = [
"object",
]
[[package]] [[package]]
name = "arbitrary" name = "arbitrary"
version = "1.3.2" version = "1.3.2"
@ -289,9 +298,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.1" version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"hashbrown 0.14.5", "hashbrown 0.14.5",
@ -358,6 +367,7 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
name = "rustc_codegen_cranelift" name = "rustc_codegen_cranelift"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"ar_archive_writer",
"cranelift-codegen", "cranelift-codegen",
"cranelift-frontend", "cranelift-frontend",
"cranelift-jit", "cranelift-jit",

View File

@ -17,6 +17,7 @@ cranelift-object = { version = "0.110.1" }
target-lexicon = "0.12.0" target-lexicon = "0.12.0"
gimli = { version = "0.28", default-features = false, features = ["write"]} gimli = { version = "0.28", default-features = false, features = ["write"]}
object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
ar_archive_writer = "0.3"
indexmap = "2.0.0" indexmap = "2.0.0"
libloading = { version = "0.8.0", optional = true } libloading = { version = "0.8.0", optional = true }

View File

@ -106,6 +106,7 @@ const fn jit_bin(config: &'static str, source: &'static str, args: &'static str)
]); ]);
runner.run_out_command("gen_block_iterate", &[]); runner.run_out_command("gen_block_iterate", &[]);
}), }),
TestCase::build_bin_and_run("aot.raw-dylib", "example/raw-dylib.rs", &[]),
]; ];
pub(crate) static RAND_REPO: GitRepo = GitRepo::github( pub(crate) static RAND_REPO: GitRepo = GitRepo::github(

View File

@ -45,6 +45,7 @@ aot.issue-59326
aot.polymorphize_coroutine aot.polymorphize_coroutine
aot.neon aot.neon
aot.gen_block_iterate aot.gen_block_iterate
aot.raw-dylib
testsuite.extended_sysroot testsuite.extended_sysroot
test.rust-random/rand test.rust-random/rand

31
example/raw-dylib.rs Normal file
View File

@ -0,0 +1,31 @@
// Tests the raw-dylib feature for Windows.
// https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute
fn main() {
#[cfg(windows)]
{
#[link(name = "kernel32", kind = "raw-dylib")]
extern "C" {
fn GetModuleFileNameA(
module: *mut std::ffi::c_void,
filename: *mut u8,
size: u32,
) -> u32;
}
// Get the filename of the current executable....
let mut buffer = [0u8; 1024];
let size = unsafe {
GetModuleFileNameA(core::ptr::null_mut(), buffer.as_mut_ptr(), buffer.len() as u32)
};
if size == 0 {
eprintln!("failed to get module file name: {}", std::io::Error::last_os_error());
return;
} else {
// ...and make sure that it matches the test name.
let filename =
std::ffi::CStr::from_bytes_with_nul(&buffer[..size as usize + 1]).unwrap();
assert!(filename.to_str().unwrap().ends_with("raw-dylib.exe"));
}
}
}

View File

@ -1,47 +0,0 @@
From 9f65e742ba3e41474e6126c6c4469c48eaa6ca7e Mon Sep 17 00:00:00 2001
From: Chris Denton <chris@chrisdenton.dev>
Date: Tue, 20 Feb 2024 16:01:40 -0300
Subject: [PATCH] Don't use raw-dylib in std
---
library/std/src/sys/pal/windows/c.rs | 2 +-
library/std/src/sys/pal/windows/rand.rs | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index ad8e01bfa9b..9ca8e4c16ce 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -312,7 +312,7 @@ pub unsafe fn NtWriteFile(
// Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
cfg_if::cfg_if! {
-if #[cfg(not(target_vendor = "win7"))] {
+if #[cfg(any())] {
#[cfg(target_arch = "x86")]
#[link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")]
extern "system" {
diff --git a/library/std/src/sys/pal/windows/rand.rs b/library/std/src/sys/pal/windows/rand.rs
index e427546222a..f2fe42a4d51 100644
--- a/library/std/src/sys/pal/windows/rand.rs
+++ b/library/std/src/sys/pal/windows/rand.rs
@@ -2,7 +2,7 @@
use crate::sys::c;
-#[cfg(not(target_vendor = "win7"))]
+#[cfg(any())]
#[inline]
pub fn hashmap_random_keys() -> (u64, u64) {
let mut v = (0, 0);
@@ -13,7 +13,6 @@ pub fn hashmap_random_keys() -> (u64, u64) {
v
}
-#[cfg(target_vendor = "win7")]
pub fn hashmap_random_keys() -> (u64, u64) {
use crate::ffi::c_void;
use crate::io;
--
2.42.0.windows.2

View File

@ -1,37 +0,0 @@
From 0d741cf82c3c908616abd39dc84ebf7d8702e0c3 Mon Sep 17 00:00:00 2001
From: Chris Denton <chris@chrisdenton.dev>
Date: Tue, 16 Apr 2024 15:51:34 +0000
Subject: [PATCH] Revert use raw-dylib for Windows futex APIs
---
library/std/src/sys/pal/windows/c.rs | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 9d58ce05f01..1c828bac4b6 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -357,19 +357,7 @@ pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 {
}
#[cfg(not(target_vendor = "win7"))]
-// Use raw-dylib to import synchronization functions to workaround issues with the older mingw import library.
-#[cfg_attr(
- target_arch = "x86",
- link(
- name = "api-ms-win-core-synch-l1-2-0",
- kind = "raw-dylib",
- import_name_type = "undecorated"
- )
-)]
-#[cfg_attr(
- not(target_arch = "x86"),
- link(name = "api-ms-win-core-synch-l1-2-0", kind = "raw-dylib")
-)]
+#[link(name = "synchronization")]
extern "system" {
pub fn WaitOnAddress(
address: *const c_void,
--
2.42.0.windows.2

View File

@ -1,8 +1,13 @@
use std::borrow::Borrow;
use std::fs;
use std::path::Path; use std::path::Path;
use ar_archive_writer::{COFFShortExport, MachineTypes};
use rustc_codegen_ssa::back::archive::{ use rustc_codegen_ssa::back::archive::{
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER, create_mingw_dll_import_lib, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
DEFAULT_OBJECT_READER,
}; };
use rustc_codegen_ssa::common::is_mingw_gnu_toolchain;
use rustc_session::Session; use rustc_session::Session;
pub(crate) struct ArArchiveBuilderBuilder; pub(crate) struct ArArchiveBuilderBuilder;
@ -15,10 +20,74 @@ fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder +
fn create_dll_import_lib( fn create_dll_import_lib(
&self, &self,
sess: &Session, sess: &Session,
_lib_name: &str, lib_name: &str,
_import_name_and_ordinal_vector: Vec<(String, Option<u16>)>, import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
_output_path: &Path, output_path: &Path,
) { ) {
sess.dcx().fatal("raw-dylib is not yet supported by rustc_codegen_cranelift"); if is_mingw_gnu_toolchain(&sess.target) {
// The binutils linker used on -windows-gnu targets cannot read the import
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
// that loaded but crashed with an AV upon calling one of the imported
// functions. Therefore, use binutils to create the import library instead,
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
create_mingw_dll_import_lib(
sess,
lib_name,
import_name_and_ordinal_vector,
output_path,
);
} else {
let mut file =
match fs::OpenOptions::new().write(true).create_new(true).open(&output_path) {
Ok(file) => file,
Err(error) => {
sess.dcx().fatal(format!(
"failed to create import library file `{path}`: {error}",
path = output_path.display(),
));
}
};
let machine = match sess.target.arch.borrow() {
"x86" => MachineTypes::I386,
"x86_64" => MachineTypes::AMD64,
"arm" => MachineTypes::ARMNT,
"aarch64" => MachineTypes::ARM64,
_ => {
sess.dcx().fatal(format!(
"unsupported target architecture `{arch}`",
arch = sess.target.arch,
));
}
};
let exports = import_name_and_ordinal_vector
.iter()
.map(|(name, ordinal)| COFFShortExport {
name: name.to_string(),
ext_name: None,
symbol_name: None,
alias_target: None,
ordinal: ordinal.unwrap_or(0),
noname: ordinal.is_some(),
data: false,
private: false,
constant: false,
})
.collect::<Vec<_>>();
if let Err(error) = ar_archive_writer::write_import_library(
&mut file,
lib_name,
&exports,
machine,
!sess.target.is_like_msvc,
) {
sess.dcx().fatal(format!(
"failed to create import library `{path}`: `{error}`",
path = output_path.display(),
));
}
}
} }
} }