Inject win arm32 shims into metadata generation

This commit is contained in:
Chris Denton 2024-07-20 08:21:26 +00:00
parent 9057c3ffec
commit c629bfc9e1
No known key found for this signature in database
GPG Key ID: 713472F2F45627DE
4 changed files with 45 additions and 41 deletions

View File

@ -457,44 +457,3 @@ compat_fn_with_fallback! {
Status as u32 Status as u32
} }
} }
// # Arm32 shim
//
// AddVectoredExceptionHandler and WSAStartup use platform-specific types.
// However, Microsoft no longer supports thumbv7a so definitions for those targets
// are not included in the win32 metadata. We work around that by defining them here.
//
// Where possible, these definitions should be kept in sync with https://docs.rs/windows-sys
cfg_if::cfg_if! {
if #[cfg(not(target_vendor = "uwp"))] {
#[link(name = "kernel32")]
extern "system" {
pub fn AddVectoredExceptionHandler(
first: u32,
handler: PVECTORED_EXCEPTION_HANDLER,
) -> *mut c_void;
}
pub type PVECTORED_EXCEPTION_HANDLER = Option<
unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32,
>;
#[repr(C)]
pub struct EXCEPTION_POINTERS {
pub ExceptionRecord: *mut EXCEPTION_RECORD,
pub ContextRecord: *mut CONTEXT,
}
#[cfg(target_arch = "arm")]
pub enum CONTEXT {}
}}
// WSAStartup is only redefined here so that we can override WSADATA for Arm32
windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32);
#[cfg(target_arch = "arm")]
#[repr(C)]
pub struct WSADATA {
pub wVersion: u16,
pub wHighVersion: u16,
pub szDescription: [u8; 257],
pub szSystemStatus: [u8; 129],
pub iMaxSockets: u16,
pub iMaxUdpDg: u16,
pub lpVendorInfo: PSTR,
}

View File

@ -2175,6 +2175,7 @@ Windows.Win32.Networking.WinSock.WSARecv
Windows.Win32.Networking.WinSock.WSASend Windows.Win32.Networking.WinSock.WSASend
Windows.Win32.Networking.WinSock.WSASERVICE_NOT_FOUND Windows.Win32.Networking.WinSock.WSASERVICE_NOT_FOUND
Windows.Win32.Networking.WinSock.WSASocketW Windows.Win32.Networking.WinSock.WSASocketW
Windows.Win32.Networking.WinSock.WSAStartup
Windows.Win32.Networking.WinSock.WSASYSCALLFAILURE Windows.Win32.Networking.WinSock.WSASYSCALLFAILURE
Windows.Win32.Networking.WinSock.WSASYSNOTREADY Windows.Win32.Networking.WinSock.WSASYSNOTREADY
Windows.Win32.Networking.WinSock.WSATRY_AGAIN Windows.Win32.Networking.WinSock.WSATRY_AGAIN
@ -2419,6 +2420,7 @@ Windows.Win32.System.Console.STD_HANDLE
Windows.Win32.System.Console.STD_INPUT_HANDLE Windows.Win32.System.Console.STD_INPUT_HANDLE
Windows.Win32.System.Console.STD_OUTPUT_HANDLE Windows.Win32.System.Console.STD_OUTPUT_HANDLE
Windows.Win32.System.Console.WriteConsoleW Windows.Win32.System.Console.WriteConsoleW
Windows.Win32.System.Diagnostics.Debug.AddVectoredExceptionHandler
Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128 Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128
Windows.Win32.System.Diagnostics.Debug.CONTEXT Windows.Win32.System.Diagnostics.Debug.CONTEXT
Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD

View File

@ -5,6 +5,7 @@ windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle
windows_targets::link!("advapi32.dll" "system" "SystemFunction036" fn RtlGenRandom(randombuffer : *mut core::ffi::c_void, randombufferlength : u32) -> BOOLEAN); windows_targets::link!("advapi32.dll" "system" "SystemFunction036" fn RtlGenRandom(randombuffer : *mut core::ffi::c_void, randombufferlength : u32) -> BOOLEAN);
windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockExclusive(srwlock : *mut SRWLOCK)); windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockExclusive(srwlock : *mut SRWLOCK));
windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockShared(srwlock : *mut SRWLOCK)); windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockShared(srwlock : *mut SRWLOCK));
windows_targets::link!("kernel32.dll" "system" fn AddVectoredExceptionHandler(first : u32, handler : PVECTORED_EXCEPTION_HANDLER) -> *mut core::ffi::c_void);
windows_targets::link!("kernel32.dll" "system" fn CancelIo(hfile : HANDLE) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn CancelIo(hfile : HANDLE) -> BOOL);
windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL);
windows_targets::link!("kernel32.dll" "system" fn CompareStringOrdinal(lpstring1 : PCWSTR, cchcount1 : i32, lpstring2 : PCWSTR, cchcount2 : i32, bignorecase : BOOL) -> COMPARESTRING_RESULT); windows_targets::link!("kernel32.dll" "system" fn CompareStringOrdinal(lpstring1 : PCWSTR, cchcount1 : i32, lpstring2 : PCWSTR, cchcount2 : i32, bignorecase : BOOL) -> COMPARESTRING_RESULT);
@ -113,6 +114,7 @@ windows_targets::link!("ws2_32.dll" "system" fn WSAGetLastError() -> WSA_ERROR);
windows_targets::link!("ws2_32.dll" "system" fn WSARecv(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytesrecvd : *mut u32, lpflags : *mut u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32); windows_targets::link!("ws2_32.dll" "system" fn WSARecv(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytesrecvd : *mut u32, lpflags : *mut u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
windows_targets::link!("ws2_32.dll" "system" fn WSASend(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytessent : *mut u32, dwflags : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32); windows_targets::link!("ws2_32.dll" "system" fn WSASend(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytessent : *mut u32, dwflags : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
windows_targets::link!("ws2_32.dll" "system" fn WSASocketW(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOW, g : u32, dwflags : u32) -> SOCKET); windows_targets::link!("ws2_32.dll" "system" fn WSASocketW(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOW, g : u32, dwflags : u32) -> SOCKET);
windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested : u16, lpwsadata : *mut WSADATA) -> i32);
windows_targets::link!("ws2_32.dll" "system" fn accept(s : SOCKET, addr : *mut SOCKADDR, addrlen : *mut i32) -> SOCKET); windows_targets::link!("ws2_32.dll" "system" fn accept(s : SOCKET, addr : *mut SOCKADDR, addrlen : *mut i32) -> SOCKET);
windows_targets::link!("ws2_32.dll" "system" fn bind(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32); windows_targets::link!("ws2_32.dll" "system" fn bind(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32); windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32);
@ -2283,6 +2285,12 @@ pub type EXCEPTION_DISPOSITION = i32;
pub const EXCEPTION_MAXIMUM_PARAMETERS: u32 = 15u32; pub const EXCEPTION_MAXIMUM_PARAMETERS: u32 = 15u32;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct EXCEPTION_POINTERS {
pub ExceptionRecord: *mut EXCEPTION_RECORD,
pub ContextRecord: *mut CONTEXT,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct EXCEPTION_RECORD { pub struct EXCEPTION_RECORD {
pub ExceptionCode: NTSTATUS, pub ExceptionCode: NTSTATUS,
pub ExceptionFlags: u32, pub ExceptionFlags: u32,
@ -2859,6 +2867,8 @@ pub type PTIMERAPCROUTINE = Option<
dwtimerhighvalue: u32, dwtimerhighvalue: u32,
), ),
>; >;
pub type PVECTORED_EXCEPTION_HANDLER =
Option<unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32>;
pub type PWSTR = *mut u16; pub type PWSTR = *mut u16;
pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32; pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32;
pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32; pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32;
@ -3283,5 +3293,19 @@ pub struct XSAVE_FORMAT {
pub XmmRegisters: [M128A; 8], pub XmmRegisters: [M128A; 8],
pub Reserved4: [u8; 224], pub Reserved4: [u8; 224],
} }
#[cfg(target_arch = "arm")]
#[repr(C)]
pub struct WSADATA {
pub wVersion: u16,
pub wHighVersion: u16,
pub szDescription: [u8; 257],
pub szSystemStatus: [u8; 129],
pub iMaxSockets: u16,
pub iMaxUdpDg: u16,
pub lpVendorInfo: PSTR,
}
#[cfg(target_arch = "arm")]
pub enum CONTEXT {}
// ignore-tidy-filelength // ignore-tidy-filelength
use super::windows_targets; use super::windows_targets;

View File

@ -4,6 +4,24 @@ use std::fs;
use std::io::{Read, Seek, SeekFrom, Write}; use std::io::{Read, Seek, SeekFrom, Write};
use std::path::PathBuf; use std::path::PathBuf;
/// 32-bit ARM is not supported by Microsoft so ARM types are not generated.
/// Therefore we need to inject a few types to make the bindings work.
const ARM32_SHIM: &str = r#"
#[cfg(target_arch = "arm")]
#[repr(C)]
pub struct WSADATA {
pub wVersion: u16,
pub wHighVersion: u16,
pub szDescription: [u8; 257],
pub szSystemStatus: [u8; 129],
pub iMaxSockets: u16,
pub iMaxUdpDg: u16,
pub lpVendorInfo: PSTR,
}
#[cfg(target_arch = "arm")]
pub enum CONTEXT {}
"#;
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let mut path: PathBuf = let mut path: PathBuf =
env::args_os().nth(1).expect("a path to the rust repository is required").into(); env::args_os().nth(1).expect("a path to the rust repository is required").into();
@ -16,6 +34,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("{info}"); println!("{info}");
let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?; let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?;
f.write_all(ARM32_SHIM.as_bytes())?;
writeln!(&mut f, "// ignore-tidy-filelength")?; writeln!(&mut f, "// ignore-tidy-filelength")?;
writeln!(&mut f, "use super::windows_targets;")?; writeln!(&mut f, "use super::windows_targets;")?;