Skip to content

Commit

Permalink
Merge pull request #1524 from dpaoliello/rawdylib
Browse files Browse the repository at this point in the history
Add support for raw-dylib
  • Loading branch information
bjorn3 authored Aug 8, 2024
2 parents fdc6a55 + 2756bd6 commit a2f3413
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 91 deletions.
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(),
));
}
}
}
}

0 comments on commit a2f3413

Please sign in to comment.