A bit more ABI work

This commit is contained in:
Artemis Tosini 2024-07-29 22:54:36 +00:00
parent 15bb412b83
commit bf71132cd0
Signed by: artemist
GPG key ID: EE5227935FE3FF18

View file

@ -17,8 +17,8 @@ impl EFIFramebufferParams {
pub fn from_graphics_output(graphics_output: &mut GraphicsOutput) -> Option<Self> {
let mode = graphics_output.current_mode_info();
let (mask_red, mask_green, mask_blue, mask_reserved) = match mode.pixel_format() {
PixelFormat::Rgb => (0x0000_00ff, 0x0000_ff00, 0x00ff_0000, 0xff00_000),
PixelFormat::Bgr => (0x00ff_0000, 0x0000_ff00, 0x0000_00ff, 0xff00_000),
PixelFormat::Rgb => (0x0000_00ff, 0x0000_ff00, 0x00ff_0000, 0xff00_0000),
PixelFormat::Bgr => (0x00ff_0000, 0x0000_ff00, 0x0000_00ff, 0xff00_0000),
PixelFormat::Bitmask => {
let bitmask = mode.pixel_bitmask()?;
(bitmask.red, bitmask.green, bitmask.blue, bitmask.reserved)
@ -45,34 +45,64 @@ impl EFIFramebufferParams {
}
}
#[cfg_attr(target_pointer_width = "64", repr(C, align(8)))]
#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
pub struct ModuleDirectoryElem<T> {
ident: ModInfo,
size: u32,
data: T,
/// Single TLV in the metadata buffer.
/// In the FreeBSD kernel would be placed in `preload_metadata`
pub enum PreloadDirectoryElem<'a> {
/// Module name (MOD_NAME)
Name(&'a str),
/// Module type (MOD_TYPE)
Type(&'a str),
/// Module parameters (MOD_ARGS)
Args(&'a str),
// TODO: figure out how to make this pointer safer
/// Module address (MOD_ADDR)
LoadAddress(*const u8),
/// Module size (MOD_SIZE)
Size(usize),
/// Type-speicfic metadata (MOD_METADATA)
Metadata(FileMetadataType, &'a [u8]),
End,
}
impl<'a> PreloadDirectoryElem<'a> {
fn copy_str(data: &str, output: &mut [u8]) -> Option<u32> {
output[..data.len()].copy_from_slice(data.as_bytes());
output[data.len()] = 0;
data.len().checked_add(1)?.try_into().ok()
}
#[repr(C)]
pub struct FileMetadataElem<T> {
size: usize,
typ: FileMetadataType,
addr: *const T,
next: Option<*const FileMetadataElem<T>>,
data: T,
}
#[repr(u32)]
pub enum ModInfo {
End = 0,
Name = 1,
Type = 2,
Addr = 3,
Size = 4,
Args = 6,
pub fn copy_to_output<'b>(&'a self, output: &'b mut [u8]) -> Option<&'b mut [u8]> {
let usize_size = core::mem::size_of::<usize>();
let (tag, length) = match self {
Self::Name(name) => (1u32, Self::copy_str(name, &mut output[8..])?),
Self::Type(typ) => (2u32, Self::copy_str(typ, &mut output[8..])?),
Self::Args(args) => (6u32, Self::copy_str(args, &mut output[8..])?),
Self::LoadAddress(addr) => {
output[8..(8 + usize_size)].copy_from_slice(&(*addr as usize).to_ne_bytes());
(3u32, usize_size as u32)
}
Self::Size(size) => {
output[8..(8 + usize_size)].copy_from_slice(&size.to_ne_bytes());
(4u32, usize_size as u32)
}
Self::Metadata(typ, metadata) => {
output[8..(8 + metadata.len())].copy_from_slice(metadata);
(0x8000 | (*typ as u32), metadata.len() as u32)
}
Self::End => (0u32, 0u32),
};
output[..4].copy_from_slice(&tag.to_ne_bytes());
output[4..8].copy_from_slice(&length.to_ne_bytes());
let aligned_length = ((length as usize + usize_size - 1) / usize_size) * usize_size;
Some(&mut output[(aligned_length + 8)..])
}
}
#[derive(Debug, Copy, Clone)]
#[repr(u16)]
pub enum FileMetadataType {
AoutExecHeader = 1,