diff options
| author | Ayush Singh <ayushsingh1325@gmail.com> | 2023-05-21 14:26:59 +0530 |
|---|---|---|
| committer | Ayush Singh <ayushdevel1325@gmail.com> | 2023-09-22 17:23:33 +0530 |
| commit | c7e5f3ca085c3adfd285a6d41080ff65a6299bc9 (patch) | |
| tree | 116df502759aa3ddff2b95e388736ba981c3ac7e /library/std/src/sys/uefi | |
| parent | 40c3dacc767a4fbf42ea5dfa686a54acf9ded5fb (diff) | |
| download | rust-c7e5f3ca085c3adfd285a6d41080ff65a6299bc9.tar.gz rust-c7e5f3ca085c3adfd285a6d41080ff65a6299bc9.zip | |
Rebase to master
- Update Example - Add thread_parking to sys::uefi - Fix unsafe in unsafe errors - Improve docs - Improve os/exit - Some asserts - Switch back to atomics Signed-off-by: Ayush Singh <ayushdevel1325@gmail.com>
Diffstat (limited to 'library/std/src/sys/uefi')
| -rw-r--r-- | library/std/src/sys/uefi/helpers.rs | 14 | ||||
| -rw-r--r-- | library/std/src/sys/uefi/mod.rs | 36 | ||||
| -rw-r--r-- | library/std/src/sys/uefi/os.rs | 42 |
3 files changed, 66 insertions, 26 deletions
diff --git a/library/std/src/sys/uefi/helpers.rs b/library/std/src/sys/uefi/helpers.rs index 2e1bcb36944..126661bfc96 100644 --- a/library/std/src/sys/uefi/helpers.rs +++ b/library/std/src/sys/uefi/helpers.rs @@ -60,13 +60,14 @@ pub(crate) fn locate_handles(mut guid: Guid) -> io::Result<Vec<NonNull<crate::ff } // The returned buf_len is in bytes - let mut buf: Vec<r_efi::efi::Handle> = - Vec::with_capacity(buf_len / size_of::<r_efi::efi::Handle>()); + assert_eq!(buf_len % size_of::<r_efi::efi::Handle>(), 0); + let num_of_handles = buf_len / size_of::<r_efi::efi::Handle>(); + let mut buf: Vec<r_efi::efi::Handle> = Vec::with_capacity(num_of_handles); match inner(&mut guid, boot_services, &mut buf_len, buf.as_mut_ptr()) { Ok(()) => { // This is safe because the call will succeed only if buf_len >= required length. // Also, on success, the `buf_len` is updated with the size of bufferv (in bytes) written - unsafe { buf.set_len(buf_len / size_of::<r_efi::efi::Handle>()) }; + unsafe { buf.set_len(num_of_handles) }; Ok(buf.into_iter().filter_map(|x| NonNull::new(x)).collect()) } Err(e) => Err(e), @@ -114,16 +115,15 @@ pub(crate) fn create_event( ) -> io::Result<NonNull<crate::ffi::c_void>> { let boot_services: NonNull<efi::BootServices> = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast(); - let mut exit_boot_service_event: r_efi::efi::Event = crate::ptr::null_mut(); + let mut event: r_efi::efi::Event = crate::ptr::null_mut(); let r = unsafe { let create_event = (*boot_services.as_ptr()).create_event; - (create_event)(signal, tpl, handler, context, &mut exit_boot_service_event) + (create_event)(signal, tpl, handler, context, &mut event) }; if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { - NonNull::new(exit_boot_service_event) - .ok_or(const_io_error!(io::ErrorKind::Other, "null protocol")) + NonNull::new(event).ok_or(const_io_error!(io::ErrorKind::Other, "null protocol")) } } diff --git a/library/std/src/sys/uefi/mod.rs b/library/std/src/sys/uefi/mod.rs index 85d00caf149..9a10395af8e 100644 --- a/library/std/src/sys/uefi/mod.rs +++ b/library/std/src/sys/uefi/mod.rs @@ -12,7 +12,6 @@ //! [`OsStr`]: crate::ffi::OsStr //! [`OsString`]: crate::ffi::OsString -#![deny(unsafe_op_in_unsafe_fn)] pub mod alloc; #[path = "../unsupported/args.rs"] pub mod args; @@ -43,6 +42,8 @@ pub mod stdio; pub mod thread; #[path = "../unsupported/thread_local_key.rs"] pub mod thread_local_key; +#[path = "../unsupported/thread_parking.rs"] +pub mod thread_parking; #[path = "../unsupported/time.rs"] pub mod time; @@ -53,18 +54,17 @@ mod tests; pub type RawOsError = usize; -use crate::cell::Cell; use crate::io as std_io; use crate::os::uefi; use crate::ptr::NonNull; +use crate::sync::atomic::{AtomicPtr, Ordering}; pub mod memchr { pub use core::slice::memchr::{memchr, memrchr}; } -thread_local! { - static EXIT_BOOT_SERVICE_EVENT: Cell<Option<NonNull<crate::ffi::c_void>>> = Cell::new(None); -} +static EXIT_BOOT_SERVICE_EVENT: AtomicPtr<crate::ffi::c_void> = + AtomicPtr::new(crate::ptr::null_mut()); /// # SAFETY /// - must be called only once during runtime initialization. @@ -75,8 +75,6 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) { let image_handle = unsafe { NonNull::new(*argv as *mut crate::ffi::c_void).unwrap() }; let system_table = unsafe { NonNull::new(*argv.add(1) as *mut crate::ffi::c_void).unwrap() }; unsafe { uefi::env::init_globals(image_handle, system_table) }; - // Enable boot services once GLOBALS are initialized - uefi::env::enable_boot_services(); // Register exit boot services handler match helpers::create_event( @@ -86,7 +84,17 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) { crate::ptr::null_mut(), ) { Ok(x) => { - EXIT_BOOT_SERVICE_EVENT.set(Some(x)); + if EXIT_BOOT_SERVICE_EVENT + .compare_exchange( + crate::ptr::null_mut(), + x.as_ptr(), + Ordering::Release, + Ordering::Acquire, + ) + .is_err() + { + abort_internal(); + }; } Err(_) => abort_internal(), } @@ -96,7 +104,9 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) { /// this is not guaranteed to run, for example when the program aborts. /// - must be called only once during runtime cleanup. pub unsafe fn cleanup() { - if let Some(exit_boot_service_event) = EXIT_BOOT_SERVICE_EVENT.take() { + if let Some(exit_boot_service_event) = + NonNull::new(EXIT_BOOT_SERVICE_EVENT.swap(crate::ptr::null_mut(), Ordering::Acquire)) + { let _ = unsafe { helpers::close_event(exit_boot_service_event) }; } } @@ -159,7 +169,9 @@ pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind { } pub fn abort_internal() -> ! { - if let Some(exit_boot_service_event) = EXIT_BOOT_SERVICE_EVENT.take() { + if let Some(exit_boot_service_event) = + NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire)) + { let _ = unsafe { helpers::close_event(exit_boot_service_event) }; } @@ -226,3 +238,7 @@ fn get_random() -> Option<(u64, u64)> { extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut crate::ffi::c_void) { uefi::env::disable_boot_services(); } + +pub fn is_interrupted(_code: RawOsError) -> bool { + false +} diff --git a/library/std/src/sys/uefi/os.rs b/library/std/src/sys/uefi/os.rs index cd489d8f7f9..e6693db68e6 100644 --- a/library/std/src/sys/uefi/os.rs +++ b/library/std/src/sys/uefi/os.rs @@ -4,15 +4,16 @@ use crate::ffi::{OsStr, OsString}; use crate::fmt; use crate::io; use crate::marker::PhantomData; +use crate::os::uefi; use crate::path::{self, PathBuf}; +use crate::ptr::NonNull; +use r_efi::efi::Status; pub fn errno() -> RawOsError { 0 } pub fn error_string(errno: RawOsError) -> String { - use r_efi::efi::Status; - // Keep the List in Alphabetical Order // The Messages are taken from UEFI Specification Appendix D - Status Codes match r_efi::efi::Status::from_usize(errno) { @@ -160,12 +161,7 @@ impl fmt::Display for JoinPathsError { } } -impl StdError for JoinPathsError { - #[allow(deprecated)] - fn description(&self) -> &str { - "not supported on this platform yet" - } -} +impl StdError for JoinPathsError {} pub fn current_exe() -> io::Result<PathBuf> { unsupported() @@ -173,6 +169,14 @@ pub fn current_exe() -> io::Result<PathBuf> { pub struct Env(!); +impl Env { + // FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt. + pub fn str_debug(&self) -> impl fmt::Debug + '_ { + let Self(inner) = self; + match *inner {} + } +} + impl Iterator for Env { type Item = (OsString, OsString); fn next(&mut self) -> Option<(OsString, OsString)> { @@ -180,6 +184,13 @@ impl Iterator for Env { } } +impl fmt::Debug for Env { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self(inner) = self; + match *inner {} + } +} + pub fn env() -> Env { panic!("not supported on this platform") } @@ -204,7 +215,20 @@ pub fn home_dir() -> Option<PathBuf> { None } -pub fn exit(_code: i32) -> ! { +pub fn exit(code: i32) -> ! { + if let (Some(boot_services), Some(handle)) = + (uefi::env::boot_services(), uefi::env::try_image_handle()) + { + let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast(); + let _ = unsafe { + ((*boot_services.as_ptr()).exit)( + handle.as_ptr(), + Status::from_usize(code as usize), + 0, + crate::ptr::null_mut(), + ) + }; + } crate::intrinsics::abort() } |
