elf_loader: add generic callback-based loader

Change-Id: I1dd972a585bc7c805e32c9665d13e248663ccc73
This commit is contained in:
Aidan MacDonald 2026-01-10 22:00:59 +00:00
parent a610998ea4
commit 843322f898
2 changed files with 35 additions and 16 deletions

View file

@ -101,17 +101,16 @@ static int elf_validate_phdr(const struct elf_phdr *phdr,
return ELF_ERR_MEM_UNMAPPED;
}
int elf_loadfd(int fd,
const struct elf_load_context *ctx,
void **entrypoint)
int elf_load(elf_read_callback_t read_cb,
intptr_t read_arg,
const struct elf_load_context *ctx,
void **entrypoint)
{
struct elf_header ehdr;
struct elf_phdr phdr;
ssize_t nread;
int err;
nread = read(fd, &ehdr, sizeof(ehdr));
if (nread != (ssize_t)sizeof(ehdr))
if (read_cb(read_arg, 0, &ehdr, sizeof(ehdr)))
return ELF_ERR_IO;
err = elf_validate_header(&ehdr);
@ -124,11 +123,7 @@ int elf_loadfd(int fd,
for (size_t ph_index = 0; ph_index < ehdr.e_phnum; ++ph_index)
{
off_t ph_off = ehdr.e_phoff + (ph_index * ehdr.e_phentsize);
if (lseek(fd, ph_off, SEEK_SET) == (off_t)-1)
return ELF_ERR_IO;
nread = read(fd, &phdr, sizeof(phdr));
if (nread != (ssize_t)sizeof(phdr))
if (read_cb(read_arg, ph_off, &phdr, sizeof(phdr)))
return ELF_ERR_IO;
err = elf_validate_phdr(&phdr, ctx);
@ -138,11 +133,7 @@ int elf_loadfd(int fd,
/* Load file data to memory if needed */
if (phdr.p_filesz > 0)
{
if (lseek(fd, phdr.p_offset, SEEK_SET) == (off_t)-1)
return ELF_ERR_IO;
nread = read(fd, (void *)phdr.p_vaddr, phdr.p_filesz);
if (nread < 0 || (uint32_t)nread != phdr.p_filesz)
if (read_cb(read_arg, phdr.p_offset, (void *)phdr.p_vaddr, phdr.p_filesz))
return ELF_ERR_IO;
}
@ -160,6 +151,25 @@ int elf_loadfd(int fd,
return ELF_OK;
}
int elf_loadfd(int fd,
const struct elf_load_context *ctx,
void **entrypoint)
{
return elf_load(elf_read_fd_callback, fd, ctx, entrypoint);
}
int elf_read_fd_callback(intptr_t fd, off_t pos, void *buf, size_t size)
{
if (lseek(fd, pos, SEEK_SET) == (off_t)-1)
return -1;
ssize_t nread = read(fd, buf, size);
if (nread < 0 || (size_t)nread != size)
return -1;
return 0;
}
int elf_loadpath(const char *filename,
const struct elf_load_context *ctx,
void **entrypoint)

View file

@ -38,6 +38,7 @@
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
enum elf_error
{
@ -83,9 +84,17 @@ struct elf_load_context
size_t num_mmap;
};
typedef int (*elf_read_callback_t) (intptr_t arg, off_t pos, void *buf, size_t size);
int elf_load(elf_read_callback_t read_cb,
intptr_t read_arg,
const struct elf_load_context *ctx,
void **entrypoint);
int elf_loadfd(int fd,
const struct elf_load_context *ctx,
void **entrypoint);
int elf_read_fd_callback(intptr_t fd, off_t pos, void *buf, size_t size);
int elf_loadpath(const char *filename,
const struct elf_load_context *ctx,