Skip to content

Commit 581adb0

Browse files
committed
Add Minimal Std implementation for UEFI
Implemented modules: 1. alloc 2. os_str 3. env 4. math Tracking Issue: rust-lang#100499 API Change Proposal: rust-lang/libs-team#87 This was originally part of rust-lang#100316. Since that PR was becoming too unwieldy and cluttered, and with suggestion from @dvdhrm, I have extracted a minimal std implementation to this PR. Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
1 parent ce798a5 commit 581adb0

File tree

24 files changed

+718
-18
lines changed

24 files changed

+718
-18
lines changed

.nlsp-settings/rust_analyzer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"rust-analyzer.cargo.target": "x86_64-unknown-uefi"
3+
}

Cargo.lock

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2924,6 +2924,27 @@ dependencies = [
29242924
"proc-macro2",
29252925
]
29262926

2927+
[[package]]
2928+
name = "r-efi"
2929+
version = "4.1.0"
2930+
source = "registry+https://github.com/rust-lang/crates.io-index"
2931+
checksum = "9e7345c622833c6745e7b027a28aa95618813dc1f3c3de396206410267dce6f3"
2932+
dependencies = [
2933+
"compiler_builtins",
2934+
"rustc-std-workspace-core",
2935+
]
2936+
2937+
[[package]]
2938+
name = "r-efi-alloc"
2939+
version = "1.0.0"
2940+
source = "registry+https://github.com/rust-lang/crates.io-index"
2941+
checksum = "31d6f09fe2b6ad044bc3d2c34ce4979796581afd2f1ebc185837e02421e02fd7"
2942+
dependencies = [
2943+
"compiler_builtins",
2944+
"r-efi",
2945+
"rustc-std-workspace-core",
2946+
]
2947+
29272948
[[package]]
29282949
name = "rand"
29292950
version = "0.8.5"
@@ -4930,6 +4951,8 @@ dependencies = [
49304951
"panic_abort",
49314952
"panic_unwind",
49324953
"profiler_builtins",
4954+
"r-efi",
4955+
"r-efi-alloc",
49334956
"rand",
49344957
"rand_xorshift",
49354958
"rustc-demangle",

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,11 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
420420
rust_main_def_id: DefId,
421421
entry_type: EntryFnType,
422422
) -> Bx::Function {
423-
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
424-
// depending on whether the target needs `argc` and `argv` to be passed in.
425-
let llfty = if cx.sess().target.main_needs_argc_argv {
423+
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`, or
424+
// `Status efi_main(Handle hd, SystemTable *st)` depending on the target.
425+
let llfty = if cx.sess().target.os.contains("uefi") {
426+
cx.type_func(&[cx.type_ptr(), cx.type_ptr()], cx.type_isize())
427+
} else if cx.sess().target.main_needs_argc_argv {
426428
cx.type_func(&[cx.type_int(), cx.type_ptr()], cx.type_int())
427429
} else {
428430
cx.type_func(&[], cx.type_int())
@@ -485,8 +487,12 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
485487
};
486488

487489
let result = bx.call(start_ty, None, None, start_fn, &args, None);
488-
let cast = bx.intcast(result, cx.type_int(), true);
489-
bx.ret(cast);
490+
if cx.sess().target.os.contains("uefi") {
491+
bx.ret(result);
492+
} else {
493+
let cast = bx.intcast(result, cx.type_int(), true);
494+
bx.ret(cast);
495+
}
490496

491497
llfn
492498
}
@@ -497,7 +503,18 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
497503
cx: &'a Bx::CodegenCx,
498504
bx: &mut Bx,
499505
) -> (Bx::Value, Bx::Value) {
500-
if cx.sess().target.main_needs_argc_argv {
506+
if cx.sess().target.os.contains("uefi") {
507+
// Params for UEFI
508+
let param_handle = bx.get_param(0);
509+
let param_system_table = bx.get_param(1);
510+
let arg_argc = bx.const_int(cx.type_isize(), 2);
511+
let arg_argv = bx.alloca(cx.type_array(cx.type_i8p(), 2), Align::ONE);
512+
bx.store(param_handle, arg_argv, Align::ONE);
513+
let arg_argv_el1 =
514+
bx.gep(cx.type_ptr_to(cx.type_i8()), arg_argv, &[bx.const_int(cx.type_int(), 1)]);
515+
bx.store(param_system_table, arg_argv_el1, Align::ONE);
516+
(arg_argc, arg_argv)
517+
} else if cx.sess().target.main_needs_argc_argv {
501518
// Params from native `main()` used as args for rust start function
502519
let param_argc = bx.get_param(0);
503520
let param_argv = bx.get_param(1);
@@ -549,7 +566,11 @@ pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option<AllocatorKind> {
549566
use rustc_middle::middle::dependency_format::Linkage;
550567
list.iter().any(|&linkage| linkage == Linkage::Dynamic)
551568
});
552-
if any_dynamic_crate { None } else { tcx.allocator_kind(()) }
569+
if any_dynamic_crate {
570+
None
571+
} else {
572+
tcx.allocator_kind(())
573+
}
553574
}
554575

555576
pub fn codegen_crate<B: ExtraBackendMethods>(

compiler/rustc_target/src/spec/uefi_msvc_base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub fn opts() -> TargetOptions {
4646
stack_probes: StackProbeType::Call,
4747
singlethread: true,
4848
linker: Some("rust-lld".into()),
49+
entry_name: "efi_main".into(),
4950
..base
5051
}
5152
}

compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
66
// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
77

8-
use crate::spec::Target;
8+
use crate::{abi::call::Conv, spec::Target};
99

1010
pub fn target() -> Target {
1111
let mut base = super::uefi_msvc_base::opts();
1212
base.cpu = "x86-64".into();
1313
base.plt_by_default = false;
1414
base.max_atomic_width = Some(64);
15+
base.entry_abi = Conv::X86_64Win64;
1516

1617
// We disable MMX and SSE for now, even though UEFI allows using them. Problem is, you have to
1718
// enable these CPU features explicitly before their first use, otherwise their instructions

library/panic_abort/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn BoxMeUp) -> u32 {
4343
libc::abort();
4444
}
4545
} else if #[cfg(any(target_os = "hermit",
46+
target_os = "uefi",
4647
all(target_vendor = "fortanix", target_env = "sgx")
4748
))] {
4849
unsafe fn abort() -> ! {

library/std/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ hermit-abi = { version = "0.3.2", features = ['rustc-dep-of-std'], public = true
4848
[target.'cfg(target_os = "wasi")'.dependencies]
4949
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
5050

51+
[target.'cfg(target_os = "uefi")'.dependencies]
52+
r-efi = { version = "4.1.0", features = ['rustc-dep-of-std', 'efiapi']}
53+
r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std']}
54+
5155
[features]
5256
backtrace = [
5357
"gimli-symbolize",

library/std/build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ fn main() {
3737
|| target.contains("nintendo-3ds")
3838
|| target.contains("vita")
3939
|| target.contains("nto")
40+
|| target.contains("uefi")
4041
// See src/bootstrap/synthetic_targets.rs
4142
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
4243
{
@@ -49,7 +50,7 @@ fn main() {
4950
// - mipsel-sony-psp
5051
// - nvptx64-nvidia-cuda
5152
// - arch=avr
52-
// - uefi (x86_64-unknown-uefi, i686-unknown-uefi)
53+
// - tvos (aarch64-apple-tvos, x86_64-apple-tvos)
5354
// - JSON targets
5455
// - Any new targets that have not been explicitly added above.
5556
println!("cargo:rustc-cfg=feature=\"restricted-std\"");

library/std/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@
238238
#![cfg_attr(windows, feature(round_char_boundary))]
239239
//
240240
// Language features:
241-
// tidy-alphabetical-start
242241
#![feature(alloc_error_handler)]
243242
#![feature(allocator_internals)]
244243
#![feature(allow_internal_unsafe)]

library/std/src/os/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ pub mod solid;
140140
#[cfg(target_os = "tvos")]
141141
#[path = "ios/mod.rs"]
142142
pub(crate) mod tvos;
143+
#[cfg(target_os = "uefi")]
144+
pub mod uefi;
143145
#[cfg(target_os = "vita")]
144146
pub mod vita;
145147
#[cfg(target_os = "vxworks")]

0 commit comments

Comments
 (0)