61 lines
1.5 KiB
C
61 lines
1.5 KiB
C
//---
|
|
// fxBoot:loader:entry - ELF Loader entry
|
|
//---
|
|
#include "fxBoot/hypervisor.h"
|
|
#include "fxBoot/fs/smemfs.h"
|
|
#include "fxBoot/elf.h"
|
|
|
|
#include "./src/hypervisor/internal/elf.h"
|
|
|
|
//---
|
|
// Internal helpers
|
|
//---
|
|
/* reloc_section(): Relocalise section's symbols */
|
|
static int reloc_section(struct hworld *world,
|
|
struct smemfs_inode *inode, Elf32_Shdr *shdr)
|
|
{
|
|
Elf32_Rela rela;
|
|
uint32_t *prog;
|
|
off_t offset;
|
|
|
|
/* List symbols */
|
|
prog = (void*)world->memory.program.start;
|
|
for (uint32_t i = 0 ; i < shdr->sh_size / shdr->sh_entsize ; ++i) {
|
|
/* Get relocatable symbol information */
|
|
offset = shdr->sh_offset + (i * shdr->sh_entsize);
|
|
if (smemfs_pread(inode, &rela, shdr->sh_entsize, offset)
|
|
!= (ssize_t)shdr->sh_entsize) {
|
|
return (hel_reloc_size_error);
|
|
}
|
|
|
|
/* Relocalise the symbol */
|
|
prog[rela.r_offset >> 2] +=
|
|
(uintptr_t)world->memory.program.start;
|
|
}
|
|
return (hel_reloc_success);
|
|
}
|
|
|
|
//---
|
|
// Public helpers
|
|
//---
|
|
/* loader_reloc_sym(): Relocalise all symbols */
|
|
int hypervisor_elf_loader_reloc_sym(struct hworld *world,
|
|
struct smemfs_inode *inode, Elf32_Ehdr *header)
|
|
{
|
|
Elf32_Shdr shdr;
|
|
off_t offset;
|
|
|
|
for (int i = 1 ; i < header->e_shnum ; ++i) {
|
|
offset = header->e_shoff + (i * header->e_shentsize);
|
|
if (smemfs_pread(inode, &shdr, header->e_shentsize, offset)
|
|
!= header->e_shentsize) {
|
|
return (hel_reloc_size_error);
|
|
}
|
|
if (shdr.sh_type != SHT_RELA)
|
|
continue;
|
|
if (reloc_section(world, inode, &shdr) != hel_reloc_success)
|
|
return (hel_reloc_error);
|
|
}
|
|
return (hel_reloc_success);
|
|
}
|