Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3ad2560

Browse files
authoredJul 14, 2024
Rollup merge of rust-lang#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.
2 parents 6b67c66 + 6b7a259 commit 3ad2560

File tree

5 files changed

+82
-67
lines changed

5 files changed

+82
-67
lines changed
 

‎std/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ std_detect_file_io = ["std_detect/std_detect_file_io"]
8787
std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"]
8888
std_detect_env_override = ["std_detect/std_detect_env_override"]
8989

90+
# Enable using raw-dylib for Windows imports.
91+
# This will eventually be the default.
92+
windows_raw_dylib = []
93+
9094
[package.metadata.fortanix-sgx]
9195
# Maximum possible number of threads when testing
9296
threads = 125

‎std/src/sys/pal/windows/alloc.rs

+63-66
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::alloc::{GlobalAlloc, Layout, System};
44
use crate::ffi::c_void;
55
use crate::ptr;
66
use crate::sync::atomic::{AtomicPtr, Ordering};
7-
use crate::sys::c;
7+
use crate::sys::c::{self, windows_targets};
88
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
99
use core::mem::MaybeUninit;
1010

@@ -17,74 +17,71 @@ mod tests;
1717
// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed.
1818
const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008;
1919

20-
#[link(name = "kernel32")]
21-
extern "system" {
22-
// Get a handle to the default heap of the current process, or null if the operation fails.
23-
//
24-
// SAFETY: Successful calls to this function within the same process are assumed to
25-
// always return the same handle, which remains valid for the entire lifetime of the process.
26-
//
27-
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
28-
fn GetProcessHeap() -> c::HANDLE;
20+
// Get a handle to the default heap of the current process, or null if the operation fails.
21+
//
22+
// SAFETY: Successful calls to this function within the same process are assumed to
23+
// always return the same handle, which remains valid for the entire lifetime of the process.
24+
//
25+
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
26+
windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> c::HANDLE);
2927

30-
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
31-
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
32-
// set to `HEAP_ZERO_MEMORY`.
33-
//
34-
// Returns a pointer to the newly-allocated memory or null if the operation fails.
35-
// The returned pointer will be aligned to at least `MIN_ALIGN`.
36-
//
37-
// SAFETY:
38-
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
39-
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
40-
//
41-
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
42-
//
43-
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
44-
fn HeapAlloc(hHeap: c::HANDLE, dwFlags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID;
28+
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
29+
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
30+
// set to `HEAP_ZERO_MEMORY`.
31+
//
32+
// Returns a pointer to the newly-allocated memory or null if the operation fails.
33+
// The returned pointer will be aligned to at least `MIN_ALIGN`.
34+
//
35+
// SAFETY:
36+
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
37+
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
38+
//
39+
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
40+
//
41+
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
42+
windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dwflags: u32, dwbytes: usize) -> *mut core::ffi::c_void);
4543

46-
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
47-
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
48-
// or allocating at a new location, copying memory, and freeing the original location.
49-
//
50-
// Returns a pointer to the reallocated memory or null if the operation fails.
51-
// The returned pointer will be aligned to at least `MIN_ALIGN`.
52-
// If the operation fails the given block will never have been freed.
53-
//
54-
// SAFETY:
55-
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
56-
// - `dwFlags` must be set to zero.
57-
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
58-
// `HeapReAlloc`, that has not already been freed.
59-
// If the block was successfully reallocated at a new location, pointers pointing to
60-
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
61-
//
62-
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
63-
//
64-
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
65-
fn HeapReAlloc(
66-
hHeap: c::HANDLE,
67-
dwFlags: c::DWORD,
68-
lpMem: c::LPVOID,
69-
dwBytes: c::SIZE_T,
70-
) -> c::LPVOID;
44+
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
45+
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
46+
// or allocating at a new location, copying memory, and freeing the original location.
47+
//
48+
// Returns a pointer to the reallocated memory or null if the operation fails.
49+
// The returned pointer will be aligned to at least `MIN_ALIGN`.
50+
// If the operation fails the given block will never have been freed.
51+
//
52+
// SAFETY:
53+
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
54+
// - `dwFlags` must be set to zero.
55+
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
56+
// `HeapReAlloc`, that has not already been freed.
57+
// If the block was successfully reallocated at a new location, pointers pointing to
58+
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
59+
//
60+
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
61+
//
62+
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
63+
windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
64+
hheap: c::HANDLE,
65+
dwflags : u32,
66+
lpmem: *const core::ffi::c_void,
67+
dwbytes: usize
68+
) -> *mut core::ffi::c_void);
7169

72-
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
73-
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
74-
//
75-
// SAFETY:
76-
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
77-
// - `dwFlags` must be set to zero.
78-
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
79-
// that has not already been freed.
80-
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
81-
// must not be dereferenced ever again.
82-
//
83-
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
84-
//
85-
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
86-
fn HeapFree(hHeap: c::HANDLE, dwFlags: c::DWORD, lpMem: c::LPVOID) -> c::BOOL;
87-
}
70+
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
71+
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
72+
//
73+
// SAFETY:
74+
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
75+
// - `dwFlags` must be set to zero.
76+
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
77+
// that has not already been freed.
78+
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
79+
// must not be dereferenced ever again.
80+
//
81+
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
82+
//
83+
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
84+
windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const core::ffi::c_void) -> c::BOOL);
8885

8986
// Cached handle to the default heap of the current process.
9087
// Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed.

‎std/src/sys/pal/windows/c.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_vo
1313
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
1414
use crate::ptr;
1515

16-
mod windows_targets;
16+
pub(super) mod windows_targets;
1717

1818
mod windows_sys;
1919
pub use windows_sys::*;

‎std/src/sys/pal/windows/c/windows_targets.rs

+13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
//! This is a simple wrapper around an `extern` block with a `#[link]` attribute.
44
//! It's very roughly equivalent to the windows-targets crate.
55
6+
#[cfg(feature = "windows_raw_dylib")]
7+
pub macro link {
8+
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
9+
#[cfg_attr(not(target_arch = "x86"), link(name = $library, kind = "raw-dylib", modifiers = "+verbatim"))]
10+
#[cfg_attr(target_arch = "x86", link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated"))]
11+
extern $abi {
12+
$(#[link_name=$link_name])?
13+
pub fn $($function)*;
14+
}
15+
)
16+
}
17+
#[cfg(not(feature = "windows_raw_dylib"))]
618
pub macro link {
719
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
820
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
@@ -17,6 +29,7 @@ pub macro link {
1729
)
1830
}
1931

32+
#[cfg(not(feature = "windows_raw_dylib"))]
2033
#[link(name = "advapi32")]
2134
#[link(name = "ntdll")]
2235
#[link(name = "userenv")]

‎sysroot/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ profiler = ["std/profiler"]
2727
std_detect_file_io = ["std/std_detect_file_io"]
2828
std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"]
2929
std_detect_env_override = ["std/std_detect_env_override"]
30+
windows_raw_dylib = ["std/windows_raw_dylib"]

0 commit comments

Comments
 (0)
Failed to load comments.