Rollup merge of #127370 - ChrisDenton:win-sys, r=Mark-Simulacrum

Windows: Add experimental support for linking std-required system DLLs using raw-dylib

For Windows, this allows std to define system imports without needing the user to have import libraries. It's intended for this to become the default.

For now it's an experimental feature so it can be tested using build-std.
This commit is contained in:
Jubilee 2024-07-13 20:18:23 -07:00 committed by GitHub
commit 5c56577948
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 82 additions and 67 deletions

View File

@ -87,6 +87,10 @@ std_detect_file_io = ["std_detect/std_detect_file_io"]
std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"]
std_detect_env_override = ["std_detect/std_detect_env_override"]
# Enable using raw-dylib for Windows imports.
# This will eventually be the default.
windows_raw_dylib = []
[package.metadata.fortanix-sgx]
# Maximum possible number of threads when testing
threads = 125

View File

@ -4,7 +4,7 @@
use crate::ffi::c_void;
use crate::ptr;
use crate::sync::atomic::{AtomicPtr, Ordering};
use crate::sys::c;
use crate::sys::c::{self, windows_targets};
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
use core::mem::MaybeUninit;
@ -17,15 +17,13 @@
// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed.
const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008;
#[link(name = "kernel32")]
extern "system" {
// Get a handle to the default heap of the current process, or null if the operation fails.
//
// SAFETY: Successful calls to this function within the same process are assumed to
// always return the same handle, which remains valid for the entire lifetime of the process.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
fn GetProcessHeap() -> c::HANDLE;
windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> c::HANDLE);
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
@ -41,7 +39,7 @@
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
fn HeapAlloc(hHeap: c::HANDLE, dwFlags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID;
windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dwflags: u32, dwbytes: usize) -> *mut core::ffi::c_void);
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
@ -62,12 +60,12 @@
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
fn HeapReAlloc(
hHeap: c::HANDLE,
dwFlags: c::DWORD,
lpMem: c::LPVOID,
dwBytes: c::SIZE_T,
) -> c::LPVOID;
windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
hheap: c::HANDLE,
dwflags : u32,
lpmem: *const core::ffi::c_void,
dwbytes: usize
) -> *mut core::ffi::c_void);
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
@ -83,8 +81,7 @@ fn HeapReAlloc(
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
fn HeapFree(hHeap: c::HANDLE, dwFlags: c::DWORD, lpMem: c::LPVOID) -> c::BOOL;
}
windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const core::ffi::c_void) -> c::BOOL);
// Cached handle to the default heap of the current process.
// Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed.

View File

@ -13,7 +13,7 @@
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
use crate::ptr;
mod windows_targets;
pub(super) mod windows_targets;
mod windows_sys;
pub use windows_sys::*;

View File

@ -3,6 +3,18 @@
//! This is a simple wrapper around an `extern` block with a `#[link]` attribute.
//! It's very roughly equivalent to the windows-targets crate.
#[cfg(feature = "windows_raw_dylib")]
pub macro link {
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
#[cfg_attr(not(target_arch = "x86"), link(name = $library, kind = "raw-dylib", modifiers = "+verbatim"))]
#[cfg_attr(target_arch = "x86", link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated"))]
extern $abi {
$(#[link_name=$link_name])?
pub fn $($function)*;
}
)
}
#[cfg(not(feature = "windows_raw_dylib"))]
pub macro link {
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
@ -17,6 +29,7 @@
)
}
#[cfg(not(feature = "windows_raw_dylib"))]
#[link(name = "advapi32")]
#[link(name = "ntdll")]
#[link(name = "userenv")]

View File

@ -27,3 +27,4 @@ profiler = ["std/profiler"]
std_detect_file_io = ["std/std_detect_file_io"]
std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"]
std_detect_env_override = ["std/std_detect_env_override"]
windows_raw_dylib = ["std/windows_raw_dylib"]