mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-04-11 16:37:45 -04:00
elf_loader: add generic callback-based loader
Change-Id: I1dd972a585bc7c805e32c9665d13e248663ccc73
This commit is contained in:
parent
a610998ea4
commit
843322f898
2 changed files with 35 additions and 16 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue