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:
commit
5c56577948
@ -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
|
||||
|
@ -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,74 +17,71 @@
|
||||
// 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;
|
||||
// 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
|
||||
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
|
||||
// set to `HEAP_ZERO_MEMORY`.
|
||||
//
|
||||
// Returns a pointer to the newly-allocated memory or null if the operation fails.
|
||||
// The returned pointer will be aligned to at least `MIN_ALIGN`.
|
||||
//
|
||||
// SAFETY:
|
||||
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
||||
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
|
||||
//
|
||||
// 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;
|
||||
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
|
||||
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
|
||||
// set to `HEAP_ZERO_MEMORY`.
|
||||
//
|
||||
// Returns a pointer to the newly-allocated memory or null if the operation fails.
|
||||
// The returned pointer will be aligned to at least `MIN_ALIGN`.
|
||||
//
|
||||
// SAFETY:
|
||||
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
||||
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
|
||||
//
|
||||
// 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
|
||||
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,
|
||||
// or allocating at a new location, copying memory, and freeing the original location.
|
||||
//
|
||||
// Returns a pointer to the reallocated memory or null if the operation fails.
|
||||
// The returned pointer will be aligned to at least `MIN_ALIGN`.
|
||||
// If the operation fails the given block will never have been freed.
|
||||
//
|
||||
// SAFETY:
|
||||
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
||||
// - `dwFlags` must be set to zero.
|
||||
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
|
||||
// `HeapReAlloc`, that has not already been freed.
|
||||
// If the block was successfully reallocated at a new location, pointers pointing to
|
||||
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
|
||||
//
|
||||
// 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;
|
||||
// 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,
|
||||
// or allocating at a new location, copying memory, and freeing the original location.
|
||||
//
|
||||
// Returns a pointer to the reallocated memory or null if the operation fails.
|
||||
// The returned pointer will be aligned to at least `MIN_ALIGN`.
|
||||
// If the operation fails the given block will never have been freed.
|
||||
//
|
||||
// SAFETY:
|
||||
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
||||
// - `dwFlags` must be set to zero.
|
||||
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
|
||||
// `HeapReAlloc`, that has not already been freed.
|
||||
// If the block was successfully reallocated at a new location, pointers pointing to
|
||||
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
|
||||
//
|
||||
// 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
|
||||
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.
|
||||
//
|
||||
// SAFETY:
|
||||
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
||||
// - `dwFlags` must be set to zero.
|
||||
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
|
||||
// that has not already been freed.
|
||||
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
|
||||
// must not be dereferenced ever again.
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
// 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.
|
||||
//
|
||||
// SAFETY:
|
||||
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
|
||||
// - `dwFlags` must be set to zero.
|
||||
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
|
||||
// that has not already been freed.
|
||||
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
|
||||
// must not be dereferenced ever again.
|
||||
//
|
||||
// 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
|
||||
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.
|
||||
|
@ -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::*;
|
||||
|
@ -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")]
|
||||
|
@ -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"]
|
||||
|
Loading…
Reference in New Issue
Block a user