Skip to content

Commit 3df71e6

Browse files
committed
Apply fixes suggested in PR
1. Limit scope to crate 2. Make std::io::error private again 3. Fix atomic ordering 4. Remove unnecessary inlines 5. Remove r-efi re-exports: Returning void pointer in place of SystemTable pointer now. It can be cast to SystemTable pointer of user's choice. 6. Remove std::path::Prefix::UefiDevice 7. Fix CI 8. Mimic Windows OsStrExt and OsStringExt 9. move parse_lp_cmd_line to sys_common: This allows sharing parse_lp_cmd_line between Windows and UEFI. 10. No longer storing path in File struct. 11. Removed Windows panic_abort instructions since they did not work for UEFI 12. Overhaul VariableBox a. No longer implementing Deref, DerefMut, AsRef and AsRefMut for VariableBox. More about why this should be avoided can be found here: rust-lang/unsafe-code-guidelines#256 b. Only accessing contents of VariableBox using pointers Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
1 parent a95933b commit 3df71e6

File tree

28 files changed

+913
-1030
lines changed

28 files changed

+913
-1030
lines changed

library/std/src/io/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ pub(crate) use error::const_io_error;
287287
mod buffered;
288288
pub(crate) mod copy;
289289
mod cursor;
290-
pub(crate) mod error;
290+
mod error;
291291
mod impls;
292292
pub mod prelude;
293293
mod readbuf;

library/std/src/os/uefi/env.rs

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,39 @@
11
//! UEFI-specific extensions to the primitives in `std::env` module
22
3-
use super::raw::{BootServices, RuntimeServices, SystemTable};
43
use crate::ffi::c_void;
54
use crate::ptr::NonNull;
65
use crate::sync::atomic::{AtomicPtr, Ordering};
76

8-
static GLOBAL_SYSTEM_TABLE: AtomicPtr<SystemTable> = AtomicPtr::new(crate::ptr::null_mut());
9-
static GLOBAL_SYSTEM_HANDLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
7+
static GLOBAL_SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
8+
static GLOBAL_IMAGE_HANDLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
109

11-
/// Initializes Global Atomic Pointers to SystemTable and Handle.
12-
/// Should only be called once in the program execution under normal circumstances.
13-
/// The caller should ensure that the pointers are valid.
10+
/// Initializes the global System Table and Image Handle pointers.
11+
///
12+
/// The standard library requires access to the UEFI System Table and the Application Image Handle
13+
/// to operate. Those are provided to UEFI Applications via their application entry point. By
14+
/// calling `init_globals()`, those pointers are retained by the standard library for future use.
15+
/// The pointers are never exposed to any entity outside of this application and it is guaranteed
16+
/// that, once the application exited, these pointers are never dereferenced again.
17+
///
18+
/// Callers are required to ensure the pointers are valid for the entire lifetime of this
19+
/// application. In particular, UEFI Boot Services must not be exited while an application with the
20+
/// standard library is loaded.
21+
///
22+
/// This function must not be called more than once.
1423
#[unstable(feature = "uefi_std", issue = "100499")]
15-
pub fn init_globals(handle: NonNull<c_void>, system_table: NonNull<SystemTable>) {
16-
GLOBAL_SYSTEM_TABLE.store(system_table.as_ptr(), Ordering::SeqCst);
17-
GLOBAL_SYSTEM_HANDLE.store(handle.as_ptr(), Ordering::SeqCst);
24+
pub unsafe fn init_globals(handle: NonNull<c_void>, system_table: NonNull<c_void>) {
25+
GLOBAL_SYSTEM_TABLE.store(system_table.as_ptr(), Ordering::Release);
26+
GLOBAL_IMAGE_HANDLE.store(handle.as_ptr(), Ordering::Release);
1827
}
1928

2029
/// Get the SystemTable Pointer.
2130
#[unstable(feature = "uefi_std", issue = "100499")]
22-
pub fn get_system_table() -> Option<NonNull<SystemTable>> {
23-
NonNull::new(GLOBAL_SYSTEM_TABLE.load(Ordering::SeqCst))
31+
pub fn system_table() -> Option<NonNull<c_void>> {
32+
NonNull::new(GLOBAL_SYSTEM_TABLE.load(Ordering::Acquire))
2433
}
2534

2635
/// Get the SystemHandle Pointer.
2736
#[unstable(feature = "uefi_std", issue = "100499")]
28-
pub fn get_system_handle() -> Option<NonNull<c_void>> {
29-
NonNull::new(GLOBAL_SYSTEM_HANDLE.load(Ordering::SeqCst))
30-
}
31-
32-
/// Get the BootServices Pointer.
33-
#[unstable(feature = "uefi_std", issue = "100499")]
34-
pub fn get_boot_services() -> Option<NonNull<BootServices>> {
35-
let system_table = get_system_table()?;
36-
let boot_services = unsafe { (*system_table.as_ptr()).boot_services };
37-
NonNull::new(boot_services)
38-
}
39-
40-
/// Get the RuntimeServices Pointer.
41-
#[unstable(feature = "uefi_std", issue = "100499")]
42-
pub fn get_runtime_services() -> Option<NonNull<RuntimeServices>> {
43-
let system_table = get_system_table()?;
44-
let runtime_services = unsafe { (*system_table.as_ptr()).runtime_services };
45-
NonNull::new(runtime_services)
37+
pub fn image_handle() -> Option<NonNull<c_void>> {
38+
NonNull::new(GLOBAL_IMAGE_HANDLE.load(Ordering::Acquire))
4639
}

library/std/src/os/uefi/ffi.rs

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,33 @@ use crate::sealed::Sealed;
33
use crate::sys_common::ucs2;
44

55
#[unstable(feature = "uefi_std", issue = "100499")]
6-
pub trait OsStrExt: Sealed {
7-
/// This function does not do any allocation
8-
fn to_ucs2<'a>(&'a self) -> ucs2::EncodeUcs2<'a>;
6+
pub use ucs2::EncodeUcs2;
97

10-
/// Creates a UCS-2 Vec which can be passed for FFI.
11-
/// Note: This function will replace `NULL` and other characters which are not valid in UEFI
12-
/// strings with `std::sys_common::ucs::Ucs2Char::REPLACEMENT_CHARACTER`
13-
fn to_ffi_string(&self) -> Vec<u16> {
14-
let mut v: Vec<u16> = self
15-
.to_ucs2()
16-
.map(|x| match x {
17-
Ok(c) => c,
18-
Err(_) => ucs2::Ucs2Char::REPLACEMENT_CHARACTER,
19-
})
20-
.map(u16::from)
21-
.collect();
22-
v.push(0);
23-
v.shrink_to_fit();
24-
v
25-
}
8+
#[unstable(feature = "uefi_std", issue = "100499")]
9+
pub trait OsStrExt: Sealed {
10+
/// Re-encodes an `OsStr` as a wide character sequence, i.e., UCS-2
11+
///
12+
/// # Examples
13+
///
14+
/// ```
15+
/// use std::ffi::OsString;
16+
/// use std::os::uefi::ffi::*;
17+
///
18+
/// // UTF-2 encoding for "Unicode".
19+
/// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
20+
///
21+
/// let string = OsString::from_wide(&source[..]);
22+
///
23+
/// let result: Vec<u16> = string.encode_wide().collect();
24+
/// assert_eq!(&source[..], &result[..]);
25+
/// ```
26+
fn encode_wide<'a>(&'a self) -> EncodeUcs2<'a>;
2627
}
2728

2829
impl OsStrExt for OsStr {
29-
fn to_ucs2<'a>(&'a self) -> ucs2::EncodeUcs2<'a> {
30-
// This conversion should never fail since the underlying OsStr is UTF-8 encoded
30+
fn encode_wide<'a>(&'a self) -> EncodeUcs2<'a> {
31+
// SAFETY: Calling unwrap on `self.to_str` is safe since the underlying OsStr is UTF-8
32+
// encoded
3133
ucs2::EncodeUcs2::from_str(self.to_str().unwrap())
3234
}
3335
}
@@ -37,26 +39,23 @@ pub trait OsStringExt: Sealed
3739
where
3840
Self: Sized,
3941
{
40-
fn from_ucs2_lossy(ucs: &[u16]) -> Self;
41-
42-
// For Null terminated UCS-2 Strings.
43-
#[inline]
44-
fn from_ucs2_null_termintated(ucs: &[u16]) -> Self {
45-
Self::from_ucs2_lossy(&ucs[..(ucs.len() - 1)])
46-
}
47-
48-
// Create OsString from an FFI obtained pointer.
49-
// Len is the number of elemented in the string, not number of bytes.
50-
// Note: This string is assumed to be null terminated
51-
#[inline]
52-
unsafe fn from_ffi(ucs: *mut u16, len: usize) -> Self {
53-
let s = crate::slice::from_raw_parts(ucs, len);
54-
Self::from_ucs2_null_termintated(s)
55-
}
42+
/// Creates an `OsString` from a UCS-2 slice of 16-bit code units.
43+
/// # Examples
44+
///
45+
/// ```
46+
/// use std::ffi::OsString;
47+
/// use std::os::uefi::ffi::*;
48+
///
49+
/// // UTF-16 encoding for "Unicode".
50+
/// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
51+
///
52+
/// let string = OsString::from_wide(&source[..]);
53+
/// ```
54+
fn from_wide(ucs: &[u16]) -> Self;
5655
}
5756

5857
impl OsStringExt for OsString {
59-
fn from_ucs2_lossy(ucs: &[u16]) -> Self {
58+
fn from_wide(ucs: &[u16]) -> Self {
6059
// Min capacity(in case of all ASCII) is `ucs.len()`
6160
let mut buf = String::with_capacity(ucs.len());
6261

library/std/src/os/uefi/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@
44

55
pub mod env;
66
pub mod ffi;
7-
pub mod raw;

library/std/src/os/uefi/raw.rs

Lines changed: 0 additions & 3 deletions
This file was deleted.

library/std/src/path.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,6 @@ pub enum Prefix<'a> {
186186
/// Prefix `C:` for the given disk drive.
187187
#[stable(feature = "rust1", since = "1.0.0")]
188188
Disk(#[stable(feature = "rust1", since = "1.0.0")] u8),
189-
190-
/// UEFI Device Prefix. e.g., `PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/CDROM(0x0)`
191-
/// Sometimes also represented like Windows Disks, but this is more general
192-
#[unstable(feature = "uefi_std", issue = "100499")]
193-
UefiDevice(&'a OsStr),
194189
}
195190

196191
impl<'a> Prefix<'a> {
@@ -209,7 +204,6 @@ impl<'a> Prefix<'a> {
209204
UNC(x, y) => 2 + os_str_len(x) + if os_str_len(y) > 0 { 1 + os_str_len(y) } else { 0 },
210205
DeviceNS(x) => 4 + os_str_len(x),
211206
Disk(_) => 2,
212-
UefiDevice(x) => os_str_len(x),
213207
}
214208
}
215209

@@ -2165,7 +2159,7 @@ impl Path {
21652159
!self.is_absolute()
21662160
}
21672161

2168-
pub(crate) fn prefix(&self) -> Option<Prefix<'_>> {
2162+
fn prefix(&self) -> Option<Prefix<'_>> {
21692163
self.components().prefix
21702164
}
21712165

library/std/src/sys/uefi/alloc.rs

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
//! Takes a lot of inspiration from Windows allocator for Alignment > 8.
44
55
use crate::alloc::{GlobalAlloc, Layout, System};
6-
use crate::os::uefi;
6+
use crate::ptr;
7+
use crate::sys::uefi::common;
78

89
pub(crate) const POOL_ALIGNMENT: usize = 8;
9-
// FIXME: Maybe allow chaing the MEMORY_TYPE. However, since allocation is done even before main,
10-
// there will be a few allocations with the default MEMORY_TYPE.
10+
1111
const MEMORY_TYPE: u32 = r_efi::efi::LOADER_DATA;
1212

1313
#[stable(feature = "alloc_system_type", since = "1.28.0")]
@@ -16,46 +16,39 @@ unsafe impl GlobalAlloc for System {
1616
let align = layout.align();
1717
let size = layout.size();
1818

19-
// Return NULL pointer if `layout.size == 0`
20-
if size == 0 {
21-
return core::ptr::null_mut();
22-
}
23-
2419
// Return NULL pointer if boot_services pointer cannot be obtained. The only time this
2520
// should happen is if SystemTable has not been initialized
26-
let boot_services = match uefi::env::get_boot_services() {
21+
let boot_services = match common::get_boot_services() {
2722
Some(x) => x,
28-
None => return core::ptr::null_mut(),
23+
None => return ptr::null_mut(),
2924
};
3025

3126
let allocate_pool_ptr = unsafe { (*boot_services.as_ptr()).allocate_pool };
3227

33-
let mut ptr: *mut crate::ffi::c_void = crate::ptr::null_mut();
28+
let mut ptr: *mut crate::ffi::c_void = ptr::null_mut();
3429
let aligned_size = align_size(size, align);
3530

3631
let r = (allocate_pool_ptr)(MEMORY_TYPE, aligned_size, &mut ptr);
3732

3833
if r.is_error() || ptr.is_null() {
39-
return crate::ptr::null_mut();
34+
return ptr::null_mut();
4035
}
4136

4237
unsafe { align_ptr(ptr.cast(), align) }
4338
}
4439

4540
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
46-
if layout.size() != 0 {
47-
let boot_services = match uefi::env::get_boot_services() {
48-
Some(x) => x,
49-
None => return,
50-
};
41+
let boot_services = match common::get_boot_services() {
42+
Some(x) => x,
43+
None => return,
44+
};
5145

52-
let free_pool_ptr = unsafe { (*boot_services.as_ptr()).free_pool };
46+
let free_pool_ptr = unsafe { (*boot_services.as_ptr()).free_pool };
5347

54-
let ptr = unsafe { unalign_ptr(ptr, layout.align()) };
55-
let r = (free_pool_ptr)(ptr.cast());
48+
let ptr = unsafe { unalign_ptr(ptr, layout.align()) };
49+
let r = (free_pool_ptr)(ptr.cast());
5650

57-
assert!(!r.is_error());
58-
}
51+
assert!(!r.is_error());
5952
}
6053
}
6154

0 commit comments

Comments
 (0)