diff options
author | Ard Biesheuvel <ardb@kernel.org> | 2023-10-11 11:03:21 +0200 |
---|---|---|
committer | Ard Biesheuvel <ardb@kernel.org> | 2023-10-11 11:12:34 +0200 |
commit | 1f2833888dc054f01052cba0d857c3b5f3891ce6 (patch) | |
tree | ebf8d412e3c637b4f7d23b1a80a39fb3e06b6967 | |
parent | c3cb6e6084db14dbf29180bb0322223480eb177a (diff) | |
download | efilite-1f2833888dc054f01052cba0d857c3b5f3891ce6.tar.gz |
WIP peloader
-rw-r--r-- | src/efi/peloader.rs | 55 | ||||
-rw-r--r-- | src/main.rs | 4 |
2 files changed, 38 insertions, 21 deletions
diff --git a/src/efi/peloader.rs b/src/efi/peloader.rs index 50993f7..7a3af19 100644 --- a/src/efi/peloader.rs +++ b/src/efi/peloader.rs @@ -2,6 +2,7 @@ // Copyright 2023 Google LLC // Author: Ard Biesheuvel <ardb@google.com> +use crate::EFI_PAGE_MASK; use crate::efi::memmap; use crate::{FileLoader, MemoryType, Placement}; @@ -20,6 +21,9 @@ struct DosHeader { pe_offset: u32, } +#[cfg(target_arch = "aarch64")] +const ARCH_MACHINE_ID: u16 = 0xaa64; + #[derive(Copy, Clone, Debug)] #[repr(C)] struct PeHeader { @@ -142,6 +146,11 @@ impl<'a> PeLoader<'a> { pehdr ); + if pehdr.machine != ARCH_MACHINE_ID { + debug!("Unsupported machine type 0x{:x?}\n", pehdr.machine); + return None; + } + let section_offset = doshdr.pe_offset + 24 + pehdr.size_of_optional_header as u32; let section_count = pehdr.number_of_sections as usize; let sections_size = size_of::<PeSection>() * section_count; @@ -165,19 +174,21 @@ impl<'a> PeLoader<'a> { }; trace!("Section headers: {:x?}\n", sections); - // Insert a dummy section for the header region - sections.push(PeSection { - name: [0u8; 8], - virtual_size: pehdr.size_of_headers, - virtual_address: 0, - size_of_raw_data: pehdr.size_of_headers, - pointer_to_raw_data: 0, - pointer_to_relocations: 0, - pointer_to_line_numbers: 0, - number_of_relocations: 0, - number_of_line_numbers: 0, - characteristics: EFI_IMAGE_SCN_MEM_READ, - }); + // Insert a dummy RO+XP section for the header region + if pehdr.size_of_headers & EFI_PAGE_MASK as u32 == 0 { + sections.push(PeSection { + name: [0u8; 8], + virtual_size: pehdr.size_of_headers, + virtual_address: 0, + size_of_raw_data: pehdr.size_of_headers, + pointer_to_raw_data: 0, + pointer_to_relocations: 0, + pointer_to_line_numbers: 0, + number_of_relocations: 0, + number_of_line_numbers: 0, + characteristics: EFI_IMAGE_SCN_MEM_READ, + }); + } for s in sections.iter() { if (s.pointer_to_raw_data | s.size_of_raw_data) & (pehdr.file_alignment - 1) != 0 { @@ -223,19 +234,25 @@ impl<'a> PeLoader<'a> { )?; for s in self.sections.iter() { + let (va, vs, ra, rs) = ( + s.virtual_address as usize, + s.virtual_size as usize, + s.pointer_to_raw_data as usize, + s.size_of_raw_data as usize, + ); unsafe { self.file_loader - .load_range( - buf[s.virtual_address as usize].as_mut_ptr() as *mut (), - s.pointer_to_raw_data as usize, - s.size_of_raw_data as usize, - ) + .load_range(buf[va].as_mut_ptr() as *mut (), ra, vs.min(rs)) .ok()?; } - // TODO zero out remaining space + if vs > rs { + // Zero init remaining space + buf[va+rs..va+vs].fill(MaybeUninit::<u8>::zeroed()); + } } // TODO apply relocations + // TODO free pages on failure Some(PeImage { pe_loader: self, diff --git a/src/main.rs b/src/main.rs index 5ad6d02..accd4e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -175,7 +175,7 @@ extern "C" fn efilite_main(base: *mut u8, mapped: usize, used: isize, avail: usi }; let ldr = fwcfg.get_kernel_loader().expect("No kernel image provided"); - let pe_ldr = PeLoader::new(&ldr).unwrap(); + let pe_ldr = PeLoader::new(&ldr).expect("Unsupported kernel image"); let pe_image = pe_ldr.load(MemoryType::EfiLoaderCode, placement).unwrap(); for s in pe_image.sections() { @@ -195,7 +195,7 @@ extern "C" fn efilite_main(base: *mut u8, mapped: usize, used: isize, avail: usi idmap.map_range_(&s.0, f); idmap.activate(); } else { - warn!("Cannot remap range {:?}\n", s.0); + warn!("Cannot remap range {:x?}\n", s.0); } } } |