sys/mod: aarch64 module loading

This commit is contained in:
Mark Poliakov 2024-04-09 11:59:23 +03:00
parent 39956dedb8
commit 8adc011281
5 changed files with 63 additions and 41 deletions

View File

@ -1,18 +1,20 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"disable-redzone": true,
"features": "+v8a,+strict-align,+neon,+fp-armv8",
"is-builtin": false,
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"arch": "aarch64",
"os": "none",
"llvm-target": "aarch64-unknown-none",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"max-atomic-width": 128,
"panic-strategy": "abort",
"relocation-model": "static",
"target-pointer-width": "64",
"features": "+v8a,+strict-align,+neon,+fp-armv8",
"disable-redzone": true,
"executables": true,
"panic-strategy": "abort",
"dynamic-linking": true,
"relocation-model": "pic",
"eh-frame-header": false,
"post-link-args": {
"ld.lld": ["-Tetc/aarch64-unknown-qemu.ld"]
}
"linker": "rust-lld",
"linker-flavor": "ld.lld"
}

View File

@ -5,7 +5,7 @@ KERNEL_VIRT_OFFSET = 0xFFFFFF8000000000;
SECTIONS {
. = KERNEL_PHYS_BASE;
PROVIDE(__kernel_phys_start = .);
PROVIDE(__kernel_start = . + KERNEL_VIRT_OFFSET);
.text.entry : {
*(.text.entry)
@ -37,7 +37,7 @@ SECTIONS {
. = ALIGN(4K);
.data : AT(. - KERNEL_VIRT_OFFSET) {
*(.data*)
/* *(.got*) */
*(.got*)
}
. = ALIGN(4K);
@ -49,5 +49,5 @@ SECTIONS {
. = ALIGN(4K);
PROVIDE(__bss_end_phys = . - KERNEL_VIRT_OFFSET);
PROVIDE(__kernel_size = . - KERNEL_VIRT_OFFSET - KERNEL_PHYS_BASE);
PROVIDE(__kernel_end = .);
};

View File

@ -7,11 +7,11 @@
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
"max-atomic-width": 64,
"target-pointer-width": "64",
"features": "-avx,-sse,+soft-float",
"disable-redzone": true,
"executables": true,
"panic-strategy": "abort",
"features": "-avx,-sse,+soft-float",
"dynamic-linking": true,
"relocation-model": "pic",

View File

@ -2,7 +2,11 @@ use core::mem::size_of;
use alloc::{string::String, vec, vec::Vec};
use bytemuck::{Pod, Zeroable};
use elf::io_traits::{InputStream, SeekFrom};
use elf::{
io_traits::{InputStream, SeekFrom},
relocation::Rela,
symbol::Symbol as ElfSymbol,
};
use libk_mm::PageBox;
use libk_util::{hash_table::DefaultHashTable, io::Read, sync::LockMethod, OneTimeInit};
use yggdrasil_abi::{
@ -157,30 +161,11 @@ pub fn load(file: FileRef) -> Result<LoadedModule, Error> {
for rela in rela_sections {
let rela = elf.section_data_as_relas(&rela).unwrap();
for rela in rela {
let value = match rela.r_type {
// Symbol + addend
elf::abi::R_X86_64_64 => {
if let Some(sym) = dynamic_symbols.get(rela.r_sym as usize) {
sym.st_value as i64 + rela.r_addend
} else {
return Err(Error::InvalidArgument);
}
}
// Image base + addend
elf::abi::R_X86_64_RELATIVE => image_data.as_ptr().addr() as i64 + rela.r_addend,
// Symbol value
elf::abi::R_X86_64_JUMP_SLOT | elf::abi::R_X86_64_GLOB_DAT => {
if let Some(sym) = dynamic_symbols.get(rela.r_sym as usize) {
sym.st_value as i64
} else {
return Err(Error::InvalidArgument);
}
}
_ => todo!("Unhandled relocation: {}", rela.r_type),
};
image_data[rela.r_offset as usize..rela.r_offset as usize + 8]
.copy_from_slice(&value.to_ne_bytes());
handle_relocation(&mut image_data, &rela, |idx| {
dynamic_symbols
.get(idx as usize)
.ok_or(Error::InvalidArgument)
})?;
}
}
@ -212,6 +197,41 @@ pub fn load_and_execute(file: FileRef) -> Result<(), Error> {
(module.info.init)()
}
fn handle_relocation<'a, F: FnOnce(u32) -> Result<&'a ElfSymbol, Error>>(
image_data: &mut PageBox<[u8]>,
rela: &Rela,
resolve_symbol: F,
) -> Result<(), Error> {
let value: i64 = match rela.r_type {
// Symbol + addend
#[cfg(target_arch = "x86_64")]
elf::abi::R_X86_64_64 => resolve_symbol(rela.r_sym)?.st_value as i64 + rela.r_addend,
elf::abi::R_AARCH64_ABS64 => resolve_symbol(rela.r_sym)?.st_value as i64 + rela.r_addend,
// Image base + addend
#[cfg(target_arch = "x86_64")]
elf::abi::R_X86_64_RELATIVE => image_data.as_ptr().addr() as i64 + rela.r_addend,
#[cfg(any(target_arch = "aarch64", rust_analyzer))]
elf::abi::R_AARCH64_RELATIVE => image_data.as_ptr().addr() as i64 + rela.r_addend,
// Symbol value
#[cfg(target_arch = "x86_64")]
elf::abi::R_X86_64_JUMP_SLOT | elf::abi::R_X86_64_GLOB_DAT => {
resolve_symbol(rela.r_sym)?.st_value as i64
}
#[cfg(any(target_arch = "aarch64", rust_analyzer))]
elf::abi::R_AARCH64_JUMP_SLOT | elf::abi::R_AARCH64_GLOB_DAT => {
resolve_symbol(rela.r_sym)?.st_value as i64
}
_ => todo!("Unhandled relocation: {}", rela.r_type),
};
image_data[rela.r_offset as usize..rela.r_offset as usize + 8]
.copy_from_slice(&value.to_ne_bytes());
Ok(())
}
// TODO roll own hashmap
static KERNEL_SYMBOL_TABLE: OneTimeInit<DefaultHashTable<String, usize, 128>> = OneTimeInit::new();
static MODULE_SYMBOL_TABLE: OneTimeInit<Mutex<DefaultHashTable<String, usize>>> =

View File

@ -20,6 +20,7 @@ use kernel_arch_aarch64::{
use libk::{arch::Cpu, device::external_interrupt_controller};
use libk_mm::{
address::{FromRaw, IntoRaw, PhysicalAddress},
heap,
phys::PhysicalMemoryRegion,
phys::{self, reserved::reserve_region},
pointer::PhysicalRef,
@ -33,7 +34,6 @@ use crate::{
debug,
device::{self, power::arm_psci::Psci},
fs::{Initrd, INITRD_DATA},
mem::heap,
};
use self::gic::Gic;