diff --git a/aarch64-unknown-none.json b/aarch64-unknown-none.json index 076e72fa..2a1d6619 100644 --- a/aarch64-unknown-none.json +++ b/aarch64-unknown-none.json @@ -2,11 +2,11 @@ "llvm-target": "aarch64-unknown-none", "abi": "softfloat", "arch": "aarch64", - "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", "disable-redzone": true, "features": "+strict-align,-neon,-fp-armv8", "linker": "rust-lld", - "linker-flavor": "ld.lld", + "linker-flavor": "gnu-lld", "os": "none", "executables": true, "max-atomic-width": 128, @@ -15,6 +15,9 @@ "relocation-model": "pic", "target-pointer-width": "64", "pre-link-args": { - "ld.lld": ["--script=aarch64-unknown-none.ld", "--oformat=binary"] + "gnu-lld": [ + "--script=aarch64-unknown-none.ld", + "--oformat=binary" + ] } -} +} \ No newline at end of file diff --git a/aarch64-unknown-none.ld b/aarch64-unknown-none.ld index 2cbab38c..1a3e0fcf 100644 --- a/aarch64-unknown-none.ld +++ b/aarch64-unknown-none.ld @@ -32,6 +32,7 @@ SECTIONS data_start = .; .data : { *(.data .data.*) } .rodata : { *(.rodata .rodata.*) } + .got : { *(.got .got.*) } /* The BSS section isn't mapped from file data. It is just zeroed in RAM. */ .bss : { diff --git a/riscv64gcv-unknown-none-elf.json b/riscv64gcv-unknown-none-elf.json index e84d424b..971d880b 100644 --- a/riscv64gcv-unknown-none-elf.json +++ b/riscv64gcv-unknown-none-elf.json @@ -6,16 +6,17 @@ "eh-frame-header": false, "emit-debug-gdb-scripts": false, "features": "+m,+a,-f,+d,+c,-v", - "is-builtin": false, "linker": "rust-lld", - "linker-flavor": "ld.lld", + "linker-flavor": "gnu-lld", "llvm-abiname": "lp64d", "llvm-target": "riscv64", "max-atomic-width": 64, "panic-strategy": "abort", "relocation-model": "static", "target-pointer-width": "64", - "pre-link-args": { - "ld.lld": ["--script=riscv64gcv-unknown-none-elf.ld"] + "pre-link-args": { + "gnu-lld": [ + "--script=riscv64gcv-unknown-none-elf.ld" + ] } -} +} \ No newline at end of file diff --git a/riscv64gcv-unknown-none-elf.ld b/riscv64gcv-unknown-none-elf.ld index b00bc5e4..ade5681e 100644 --- a/riscv64gcv-unknown-none-elf.ld +++ b/riscv64gcv-unknown-none-elf.ld @@ -26,6 +26,7 @@ SECTIONS } .rodata : { *(.rodata .rodata.*) } + .got : { *(.got .got.*) } /* The BSS section isn't mapped from file data. It is just zeroed in RAM. */ .bss : { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index c8a2d6a1..94c4dcb0 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "nightly-2024-05-13" +channel = "nightly-2025-06-05" components = ["rust-src", "clippy", "rustfmt"] targets = [ "aarch64-unknown-linux-gnu", diff --git a/src/arch/aarch64/paging.rs b/src/arch/aarch64/paging.rs index ce195ada..16b0bade 100644 --- a/src/arch/aarch64/paging.rs +++ b/src/arch/aarch64/paging.rs @@ -277,13 +277,17 @@ impl interface::Mmu for MemoryManagementUnit { self.setup_mair(); // Populate translation tables. + #[allow(static_mut_refs)] KERNEL_TABLES .get_mut() .populate_tt_entries() .map_err(MmuEnableError::Other)?; // Set the "Translation Table Base Register". - TTBR0_EL1.set_baddr(KERNEL_TABLES.get_mut().phys_base_address()); + TTBR0_EL1.set_baddr( + #[allow(static_mut_refs)] + KERNEL_TABLES.get_mut().phys_base_address(), + ); self.configure_translation_control(); diff --git a/src/arch/x86_64/gdt.rs b/src/arch/x86_64/gdt.rs index 4846ca02..34aab85a 100644 --- a/src/arch/x86_64/gdt.rs +++ b/src/arch/x86_64/gdt.rs @@ -1,8 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2020 Google LLC -use core::mem::size_of; - bitflags::bitflags! { // An extension of x86_64::structures::gdt::DescriptorFlags struct Descriptor: u64 { @@ -43,7 +41,7 @@ struct Pointer { impl Pointer { const fn new(gdt: &'static [Descriptor]) -> Self { - let size = gdt.len() * size_of::(); + let size = core::mem::size_of_val(gdt); Self { limit: size as u16 - 1, base: &gdt[0], diff --git a/src/arch/x86_64/paging.rs b/src/arch/x86_64/paging.rs index 9ee23229..947977fd 100644 --- a/src/arch/x86_64/paging.rs +++ b/src/arch/x86_64/paging.rs @@ -25,8 +25,9 @@ static mut L2_TABLES: SyncUnsafeCell<[PageTable; ADDRESS_SPACE_GIB]> = pub fn setup() { // SAFETY: This function is idempontent and only writes to static memory and // CR3. Thus, it is safe to run multiple times or on multiple threads. + #[allow(static_mut_refs)] let (l4, l3, l2s) = unsafe { (L4_TABLE.get_mut(), L3_TABLE.get_mut(), L2_TABLES.get_mut()) }; - info!("Setting up {} GiB identity mapping", ADDRESS_SPACE_GIB); + info!("Setting up {ADDRESS_SPACE_GIB} GiB identity mapping"); let pt_flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE; // Setup Identity map using L2 huge pages diff --git a/src/common.rs b/src/common.rs index 056131db..f0c1820a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -17,7 +17,7 @@ macro_rules! container_of_mut { // SAFETY: Requires that addr point to a static, null-terminated C-string. // The returned slice does not include the null-terminator. -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", not(feature = "coreboot")))] pub unsafe fn from_cstring(addr: u64) -> &'static [u8] { if addr == 0 { return &[]; diff --git a/src/efi/alloc.rs b/src/efi/alloc.rs index 1095af9f..9f41603d 100644 --- a/src/efi/alloc.rs +++ b/src/efi/alloc.rs @@ -42,7 +42,7 @@ impl Allocator { } pub fn page_count(&self, size: usize) -> u64 { - ((size + self.page_size as usize - 1) / self.page_size as usize) as u64 + size.div_ceil(self.page_size as usize) as u64 } // Assume called in order with non-overlapping sections. @@ -338,7 +338,7 @@ impl Allocator { } pub fn allocate_pool(&mut self, memory_type: MemoryType, size: usize) -> (Status, u64) { - let page_count = (size as u64 + self.page_size - 1) / self.page_size; + let page_count = (size as u64).div_ceil(self.page_size); let (status, address) = self.allocate_pages(efi::ALLOCATE_ANY_PAGES, memory_type, page_count, 0); diff --git a/src/efi/block.rs b/src/efi/block.rs index 7c9917c6..d0b75425 100644 --- a/src/efi/block.rs +++ b/src/efi/block.rs @@ -17,7 +17,7 @@ use crate::{ }; #[allow(dead_code)] -#[repr(packed)] +#[repr(C, packed)] pub struct ControllerDevicePathProtocol { pub device_path: DevicePathProtocol, pub controller: u32, @@ -121,7 +121,7 @@ impl<'a> BlockWrapper<'a> { start_lba: u64, last_lba: u64, uuid: [u8; 16], - ) -> *mut BlockWrapper { + ) -> *mut BlockWrapper<'a> { let last_block = (*block).get_capacity() - 1; let (status, new_address) = super::ALLOCATOR diff --git a/src/efi/boot_services.rs b/src/efi/boot_services.rs index 594a5944..26a93ec5 100644 --- a/src/efi/boot_services.rs +++ b/src/efi/boot_services.rs @@ -275,6 +275,7 @@ pub extern "efiapi" fn locate_handle( handles: *mut Handle, ) -> Status { if unsafe { *guid } == r_efi::protocols::block_io::PROTOCOL_GUID { + #[allow(static_mut_refs)] let count = unsafe { BLOCK_WRAPPERS.get_mut().count }; if unsafe { *size } < size_of::() * count { unsafe { *size = size_of::() * count }; @@ -286,7 +287,8 @@ pub extern "efiapi" fn locate_handle( let wrappers_as_handles: &[Handle] = unsafe { core::slice::from_raw_parts_mut( - BLOCK_WRAPPERS.get_mut().wrappers.as_mut_ptr() as *mut Handle, + (#[allow(static_mut_refs)] + BLOCK_WRAPPERS.get_mut().wrappers.as_mut_ptr()) as *mut Handle, count, ) }; @@ -310,7 +312,9 @@ pub extern "efiapi" fn locate_device_path( } pub extern "efiapi" fn install_configuration_table(guid: *mut Guid, table: *mut c_void) -> Status { + #[allow(static_mut_refs)] let st = unsafe { ST.get_mut() }; + #[allow(static_mut_refs)] let ct = unsafe { CT.get_mut() }; for entry in ct.iter_mut() { @@ -436,6 +440,7 @@ pub extern "efiapi" fn start_image( let ptr = address as *const (); let code: extern "efiapi" fn(Handle, *mut efi::SystemTable) -> Status = unsafe { core::mem::transmute(ptr) }; + #[allow(static_mut_refs)] (code)(image_handle, unsafe { ST.get() }) } @@ -521,7 +526,8 @@ pub extern "efiapi" fn open_protocol( { unsafe { if let Some(block_part_id) = (*(handle as *mut file::FileSystemWrapper)).block_part_id { - *out = (&mut (*(BLOCK_WRAPPERS.get_mut().wrappers[block_part_id as usize])) + *out = (&mut (*(#[allow(static_mut_refs)] + BLOCK_WRAPPERS.get_mut().wrappers[block_part_id as usize])) .controller_path) as *mut _ as *mut c_void; return Status::SUCCESS; diff --git a/src/efi/device_path.rs b/src/efi/device_path.rs index 3918171c..10d55b9b 100644 --- a/src/efi/device_path.rs +++ b/src/efi/device_path.rs @@ -53,7 +53,7 @@ impl DevicePath { error!("Unexpected end of device path"); return DevicePath::Unsupported; } - let len = unsafe { core::mem::transmute::<[u8; 2], u16>(dpp.length) }; + let len = u16::from_ne_bytes(dpp.length); dpp = unsafe { &*((dpp as *const _ as u64 + len as u64) as *const _) }; } } diff --git a/src/efi/mod.rs b/src/efi/mod.rs index 4db628b6..09297146 100644 --- a/src/efi/mod.rs +++ b/src/efi/mod.rs @@ -168,6 +168,7 @@ fn new_image_handle( proto: LoadedImageProtocol { revision: r_efi::protocols::loaded_image::REVISION, parent_handle, + #[allow(static_mut_refs)] system_table: unsafe { ST.get_mut() }, device_handle, file_path, @@ -195,6 +196,7 @@ pub fn efi_exec( ) { let vendor_data = 0u32; + #[allow(static_mut_refs)] let ct = unsafe { CT.get_mut() }; let mut ct_index = 0; @@ -250,24 +252,31 @@ pub fn efi_exec( let mut stdin = console::STDIN; let mut stdout = console::STDOUT; + #[allow(static_mut_refs)] let st = unsafe { ST.get_mut() }; st.con_in = &mut stdin; st.con_out = &mut stdout; st.std_err = &mut stdout; - st.runtime_services = unsafe { RS.get_mut() }; - st.boot_services = unsafe { BS.get_mut() }; + st.runtime_services = unsafe { + #[allow(static_mut_refs)] + RS.get_mut() + }; + st.boot_services = unsafe { + #[allow(static_mut_refs)] + BS.get_mut() + }; st.number_of_table_entries = 1; st.configuration_table = &mut ct[0]; populate_allocator(info, loaded_address, loaded_size); + #[allow(static_mut_refs)] let efi_part_id = unsafe { block::populate_block_wrappers(BLOCK_WRAPPERS.get_mut(), block) }; let wrapped_fs = file::FileSystemWrapper::new(fs, efi_part_id); let mut path = [0u8; 256]; - path[0..crate::efi::EFI_BOOT_PATH.as_bytes().len()] - .copy_from_slice(crate::efi::EFI_BOOT_PATH.as_bytes()); + path[0..crate::efi::EFI_BOOT_PATH.len()].copy_from_slice(crate::efi::EFI_BOOT_PATH.as_bytes()); let device_path = DevicePath::File(path); let image = new_image_handle( device_path.generate(), diff --git a/src/efi/runtime_services.rs b/src/efi/runtime_services.rs index 4e3449c1..fee334f1 100644 --- a/src/efi/runtime_services.rs +++ b/src/efi/runtime_services.rs @@ -46,7 +46,9 @@ pub static mut RS: SyncUnsafeCell = #[allow(clippy::missing_transmute_annotations)] unsafe fn fixup_at_virtual(descriptors: &[MemoryDescriptor]) { + #[allow(static_mut_refs)] let st = ST.get_mut(); + #[allow(static_mut_refs)] let rs = RS.get_mut(); let ptr = ALLOCATOR diff --git a/src/fat.rs b/src/fat.rs index f4199697..e717fe2e 100644 --- a/src/fat.rs +++ b/src/fat.rs @@ -6,7 +6,7 @@ use crate::{ mem::MemoryRegion, }; -#[repr(packed)] +#[repr(C, packed)] struct Header { _magic: [u8; 3], _identifier: [u8; 8], @@ -24,7 +24,7 @@ struct Header { sectors: u32, } -#[repr(packed)] +#[repr(C, packed)] struct Fat32Header { _header: Header, sectors_per_fat: u32, @@ -42,7 +42,7 @@ struct Fat32Header { _id: [u8; 8], } -#[repr(packed)] +#[repr(C, packed)] struct FatDirectory { name: [u8; 11], flags: u8, @@ -53,7 +53,7 @@ struct FatDirectory { size: u32, } -#[repr(packed)] +#[repr(C, packed)] struct FatLongNameEntry { seq: u8, name: [u16; 5], @@ -608,7 +608,7 @@ fn compare_short_name(name: &str, de: &DirectoryEntry) -> bool { } let b = de.name[i]; - if a.to_ascii_uppercase() != b.to_ascii_uppercase() { + if !a.eq_ignore_ascii_case(&b) { return false; } @@ -629,7 +629,7 @@ fn compare_name(name: &str, de: &DirectoryEntry) -> bool { } impl<'a> Filesystem<'a> { - pub fn new(device: &'a dyn SectorRead, start: u64, last: u64) -> Filesystem { + pub fn new(device: &'a dyn SectorRead, start: u64, last: u64) -> Filesystem<'a> { Filesystem { device, start, @@ -665,8 +665,7 @@ impl<'a> Filesystem<'a> { self.bytes_per_sector = u32::from(h.bytes_per_sector); self.fat_count = u32::from(h.fat_count); self.sectors_per_cluster = u32::from(h.sectors_per_cluster); - self.root_dir_sectors = ((u32::from(h.root_dir_count * 32)) + self.bytes_per_sector - 1) - / self.bytes_per_sector; + self.root_dir_sectors = (u32::from(h.root_dir_count * 32)).div_ceil(self.bytes_per_sector); self.sectors_per_fat = if h.legacy_sectors_per_fat == 0 { let h32 = unsafe { &*(data.as_bytes().as_ptr() as *const Fat32Header) }; @@ -856,7 +855,7 @@ impl<'a> Filesystem<'a> { let mut p = [0_u8; 256]; let mut residual = if !is_absolute_path(path) { p[0] = b'/'; - p[1..1 + len].clone_from_slice(path[..len].as_bytes()); + p[1..1 + len].clone_from_slice(&path.as_bytes()[..len]); core::str::from_utf8(&p).unwrap() } else { path diff --git a/src/integration.rs b/src/integration.rs index 4f8496ca..88ee636f 100644 --- a/src/integration.rs +++ b/src/integration.rs @@ -412,37 +412,33 @@ mod tests { let mut s = String::new(); let mut counter = 0; - loop { - if let Err(e) = (|| -> Result<(), SSHCommandError> { - let tcp = - TcpStream::connect(format!("{ip}:22")).map_err(SSHCommandError::Connection)?; - let mut sess = ssh2::Session::new().unwrap(); - sess.set_tcp_stream(tcp); - sess.handshake().map_err(SSHCommandError::Handshake)?; - - sess.userauth_password(&auth.username, &auth.password) - .map_err(SSHCommandError::Authentication)?; - assert!(sess.authenticated()); - - let mut channel = sess - .channel_session() - .map_err(SSHCommandError::ChannelSession)?; - channel.exec(command).map_err(SSHCommandError::Command)?; - - // Intentionally ignore these results here as their failure - // does not precipitate a repeat - let _ = channel.read_to_string(&mut s); - let _ = channel.close(); - let _ = channel.wait_close(); - Ok(()) - })() { - counter += 1; - if counter >= retries { - return Err(e); - } - } else { - break; - }; + while let Err(e) = (|| -> Result<(), SSHCommandError> { + let tcp = + TcpStream::connect(format!("{ip}:22")).map_err(SSHCommandError::Connection)?; + let mut sess = ssh2::Session::new().unwrap(); + sess.set_tcp_stream(tcp); + sess.handshake().map_err(SSHCommandError::Handshake)?; + + sess.userauth_password(&auth.username, &auth.password) + .map_err(SSHCommandError::Authentication)?; + assert!(sess.authenticated()); + + let mut channel = sess + .channel_session() + .map_err(SSHCommandError::ChannelSession)?; + channel.exec(command).map_err(SSHCommandError::Command)?; + + // Intentionally ignore these results here as their failure + // does not precipitate a repeat + let _ = channel.read_to_string(&mut s); + let _ = channel.close(); + let _ = channel.wait_close(); + Ok(()) + })() { + counter += 1; + if counter >= retries { + return Err(e); + } thread::sleep(std::time::Duration::new((timeout * counter).into(), 0)); } Ok(s) diff --git a/src/loader.rs b/src/loader.rs index f66ea31d..abf8d7d9 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -33,6 +33,7 @@ pub enum Error { File(fat::Error), BzImage(bzimage::Error), UnterminatedString, + InvalidPattern, } impl From for Error { @@ -110,7 +111,7 @@ fn find_entry(fs: &fat::Filesystem, pattern: &[u8]) -> Result<[u8; 255], Error> fn compare_entry(file_name: &[u8], pattern: &[u8]) -> Result { fn compare_entry_inner( mut name_iter: core::iter::Peekable, - mut pattern: &[u8], + pattern: &[u8], max_depth: usize, ) -> Result where @@ -119,14 +120,16 @@ fn compare_entry(file_name: &[u8], pattern: &[u8]) -> Result { if max_depth == 0 { return Ok(false); } - while let Some(p) = pattern.take_first() { + let mut idx = 0; + while let Some(p) = pattern.get(idx) { + idx += 1; let f = name_iter.peek().ok_or(Error::UnterminatedString)?; #[cfg(test)] println!("{} ~ {}", *p as char, *f as char); match p { b'\0' => return Ok(*f == b'\0'), b'\\' => { - match pattern.take_first() { + match pattern.get(idx) { // trailing escape Some(b'\0') | None => return Ok(false), // no match @@ -134,6 +137,7 @@ fn compare_entry(file_name: &[u8], pattern: &[u8]) -> Result { // continue _ => (), } + idx += 1; } b'?' => { if *f == b'\0' { @@ -142,16 +146,20 @@ fn compare_entry(file_name: &[u8], pattern: &[u8]) -> Result { } b'*' => { while name_iter.peek().is_some() { - if compare_entry_inner(name_iter.clone(), pattern, max_depth - 1)? { + if compare_entry_inner( + name_iter.clone(), + pattern.get(idx..).ok_or(Error::InvalidPattern)?, + max_depth - 1, + )? { return Ok(true); } name_iter.next().ok_or(Error::UnterminatedString)?; } - return Ok(*pattern.first().ok_or(Error::UnterminatedString)? == b'\0'); + return Ok(*pattern.get(idx).ok_or(Error::UnterminatedString)? == b'\0'); } // TODO b'[' => todo!("patterns containing `[...]` sets are not supported"), - _ if p != f => return Ok(false), + _ if *p != *f => return Ok(false), _ => (), } name_iter.next().ok_or(Error::UnterminatedString)?; diff --git a/src/main.rs b/src/main.rs index 599ab9e3..5928863d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright © 2019 Intel Corporation -#![feature(asm_const)] -#![feature(exposed_provenance)] -#![feature(slice_take)] #![feature(stmt_expr_attributes)] -#![feature(strict_provenance)] #![feature(sync_unsafe_cell)] #![cfg_attr(not(test), no_std)] #![cfg_attr(not(test), no_main)] @@ -61,7 +57,7 @@ mod mem; mod part; mod pci; mod pe; -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", not(feature = "coreboot")))] mod pvh; mod rtc; #[cfg(target_arch = "riscv64")] @@ -113,7 +109,7 @@ fn boot_from_device( info: &dyn bootinfo::Info, ) -> Result<(), Error> { if let Err(err) = device.init() { - error!("Error configuring block device: {:?}", err); + error!("Error configuring block device: {err:?}"); return Err(Error::Virtio(err)); } info!( @@ -124,7 +120,7 @@ fn boot_from_device( let (start, end) = match part::find_efi_partition(device) { Ok(p) => p, Err(err) => { - error!("Failed to find EFI partition: {:?}", err); + error!("Failed to find EFI partition: {err:?}"); return Err(Error::Partition(err)); } }; @@ -132,7 +128,7 @@ fn boot_from_device( let mut f = fat::Filesystem::new(device, start, end); if let Err(err) = f.init() { - error!("Failed to create filesystem: {:?}", err); + error!("Failed to create filesystem: {err:?}"); return Err(Error::Fat(err)); } info!("Filesystem ready"); @@ -144,7 +140,7 @@ fn boot_from_device( return Ok(()); } Err(err) => { - warn!("Error loading default entry: {:?}", err); + warn!("Error loading default entry: {err:?}"); // Fall through to EFI boot } } @@ -154,7 +150,7 @@ fn boot_from_device( let mut file = match f.open(efi::EFI_BOOT_PATH) { Ok(file) => file, Err(err) => { - error!("Failed to load default EFI binary: {:?}", err); + error!("Failed to load default EFI binary: {err:?}"); return Err(Error::Fat(err)); } }; @@ -165,7 +161,7 @@ fn boot_from_device( let (entry_addr, load_addr, size) = match l.load(info.kernel_load_addr()) { Ok(load_info) => load_info, Err(err) => { - error!("Error loading executable: {:?}", err); + error!("Error loading executable: {err:?}"); return Err(Error::Pe(err)); } }; diff --git a/src/part.rs b/src/part.rs index 0054ae11..ce9bc01b 100644 --- a/src/part.rs +++ b/src/part.rs @@ -3,7 +3,7 @@ use crate::block::{Error as BlockError, SectorBuf, SectorRead}; -#[repr(packed)] +#[repr(C, packed)] /// GPT header struct Header { signature: u64, @@ -22,7 +22,7 @@ struct Header { _part_crc: u32, } -#[repr(packed)] +#[repr(C, packed)] #[derive(Clone, Copy, Default)] pub struct PartitionEntry { pub type_guid: [u8; 16], diff --git a/src/pci.rs b/src/pci.rs index ad2e62c7..132b75a1 100644 --- a/src/pci.rs +++ b/src/pci.rs @@ -153,10 +153,7 @@ pub fn print_bus() { if vendor_id == INVALID_VENDOR_ID { continue; } - info!( - "Found PCI device vendor={:x} device={:x} in slot={}", - vendor_id, device_id, device - ); + info!("Found PCI device vendor={vendor_id:x} device={device_id:x} in slot={device}"); } } @@ -176,7 +173,7 @@ where } fn naturally_align(address: u64, size: u64) -> u64 { - ((address + size - 1) / size) * size + address.div_ceil(size) * size } #[derive(Default)] @@ -428,7 +425,6 @@ impl VirtioPciTransport { /// le64 queue_desc; // 0x20 // read-write /// le64 queue_avail; // 0x28 // read-write /// le64 queue_used; // 0x30 // read-write - impl VirtioTransport for VirtioPciTransport { fn init(&mut self, _device_type: u32) -> Result<(), VirtioError> { // Read status register diff --git a/src/pe.rs b/src/pe.rs index a1b91dbf..9a9023ab 100644 --- a/src/pe.rs +++ b/src/pe.rs @@ -16,7 +16,7 @@ pub enum Error { InvalidExecutable, } -#[repr(packed)] +#[repr(C, packed)] struct Section { _name: [u8; 8], virt_size: u32, @@ -42,7 +42,7 @@ impl<'a> Loader<'a> { ))] const OPTIONAL_HEADER_MAGIC: u16 = 0x20b; // PE32+ - pub fn new(file: &'a mut dyn crate::fat::Read) -> Loader { + pub fn new(file: &'a mut dyn crate::fat::Read) -> Loader<'a> { Loader { file, num_sections: 0, diff --git a/x86_64-unknown-none.json b/x86_64-unknown-none.json index dab5ec84..df66189a 100644 --- a/x86_64-unknown-none.json +++ b/x86_64-unknown-none.json @@ -8,13 +8,16 @@ "os": "none", "executables": true, "linker": "rust-lld", - "linker-flavor": "ld.lld", + "linker-flavor": "gnu-lld", "panic-strategy": "abort", "disable-redzone": true, "features": "-mmx,-sse,+soft-float", "code-model": "small", "relocation-model": "pic", + "rustc-abi": "x86-softfloat", "pre-link-args": { - "ld.lld": ["--script=x86_64-unknown-none.ld"] + "gnu-lld": [ + "--script=x86_64-unknown-none.ld" + ] } -} +} \ No newline at end of file diff --git a/x86_64-unknown-none.ld b/x86_64-unknown-none.ld index 8a5aa9a9..81a3f8d2 100644 --- a/x86_64-unknown-none.ld +++ b/x86_64-unknown-none.ld @@ -28,6 +28,7 @@ SECTIONS data_start = .; .data : { *(.data .data.*) } + .got : { *(.got .got.*) } /* The BSS section isn't mapped from file data. It is just zeroed in RAM. */ .bss : {