Skip to content

Add support for raw-dylib #1524

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ cranelift-object = { version = "0.110.1" }
target-lexicon = "0.12.0"
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"] }
ar_archive_writer = "0.3"

indexmap = "2.0.0"
libloading = { version = "0.8.0", optional = true }
Expand Down
1 change: 1 addition & 0 deletions build_system/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
]);
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(
Expand Down
1 change: 1 addition & 0 deletions config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ aot.issue-59326
aot.polymorphize_coroutine
aot.neon
aot.gen_block_iterate
aot.raw-dylib

testsuite.extended_sysroot
test.rust-random/rand
Expand Down
31 changes: 31 additions & 0 deletions example/raw-dylib.rs
Original file line number Diff line number Diff line change
@@ -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"));
}
}
}
47 changes: 0 additions & 47 deletions patches/0029-stdlib-rawdylib-processprng.patch

This file was deleted.

This file was deleted.

79 changes: 74 additions & 5 deletions src/archive.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use std::borrow::Borrow;
use std::fs;
use std::path::Path;

use ar_archive_writer::{COFFShortExport, MachineTypes};
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;

pub(crate) struct ArArchiveBuilderBuilder;
Expand All @@ -15,10 +20,74 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
fn create_dll_import_lib(
&self,
sess: &Session,
_lib_name: &str,
_import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
_output_path: &Path,
lib_name: &str,
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
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(),
));
}
}
}
}