commit - cd0438ce5c0e5285e02b003de77438a71492de5d
commit + 764c56209e6f7ec63ac1a15059bd6a40fcae272d
blob - 4124e1203a82d28f1fc7418e37d6e6d3c628c626
blob + b245057f1e7392bdab164569fe3ae073316b2922
--- Makefile
+++ Makefile
linurv: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
+${OBJ}: src/linurv.h src/data.h
src/ecall.o: src/syscalls.h
src/cpu.o: src/signal-bootstrap-code.h
blob - c2f091bc7b9f67ffb6c76e1b9e89e6b274ba28d1
blob + ad3b92558169ad5a4f69fdba5a972d750e48c16f
--- src/data.dst
+++ src/data.dst
type: u16,
machine: u16,
version: u32,
+ entry: u64,
phoff: u64,
shoff: u64,
flags: u32,
blob - cb238ae4659091f4c53a5e07cf31b2bb9ecc5897
blob + 0fdb8431581673d815c4611a6f56838ddaf0b614
--- src/exec.c
+++ src/exec.c
#include <errno.h>
#include <ctype.h>
#include "linurv.h"
+#include "data.h"
-
-int is_executable (const Elf64_Ehdr *ehdr)
+int is_executable (const struct elf64_ehdr *ehdr)
{
- return ehdr->e_ident[EI_MAG0] == ELFMAG0
- && ehdr->e_ident[EI_MAG1] == ELFMAG1
- && ehdr->e_ident[EI_MAG2] == ELFMAG2
- && ehdr->e_ident[EI_MAG3] == ELFMAG3
- && ehdr->e_ident[EI_CLASS] == ELFCLASS64
- && ehdr->e_ident[EI_DATA] == ELFDATA2LSB
- && ehdr->e_machine == EM_RISCV
+ return ehdr->ident[EI_MAG0] == ELFMAG0
+ && ehdr->ident[EI_MAG1] == ELFMAG1
+ && ehdr->ident[EI_MAG2] == ELFMAG2
+ && ehdr->ident[EI_MAG3] == ELFMAG3
+ && ehdr->ident[EI_CLASS] == ELFCLASS64
+ && ehdr->ident[EI_DATA] == ELFDATA2LSB
+ && ehdr->machine == EM_RISCV
;
}
+void read_elf_ehdr (int fd, struct elf64_ehdr *ehdr)
+{
+ char buffer[sizeof (*ehdr)];
+ if (read (fd, buffer, sizeof (buffer)) != sizeof (buffer))
+ err (1, "read_elf_ehdr()");
+ decode_elf64_ehdr (ehdr, buffer);
+}
+
int my_execve (const char *path, char **argv, char **envp)
{
- Elf64_Ehdr ehdr;
+ struct elf64_ehdr ehdr;
char buffer[256], *nl, *s;
int fd;
return my_execve (s, argv, envp);
}
- memset (&ehdr, 0, sizeof (ehdr));
+ memset (buffer, 0, sizeof (ehdr));
lseek (fd, 0, SEEK_SET);
- read (fd, &ehdr, sizeof (ehdr));
+ read_elf_ehdr (fd, &ehdr);
close (fd);
if (is_executable (&ehdr)) {
blob - aba351c137c52352baa240f38588b05c79aec9b1
blob + 4c367bd11bfe114032fcf6f6573f29b1054327f4
--- src/linurv.c
+++ src/linurv.c
enum log_level curlevel;
u64 brkval = 0;
-static void load_segment (int fd, Elf64_Phdr phdr)
+static void load_segment (int fd, const struct elf64_phdr *phdr)
{
size_t end, len, ps;
int prot = 0;
void *addr, *ptr;
- if (phdr.p_filesz > phdr.p_memsz)
- errx (1, "invalid program header: p_filesz > p_memsz");
+ if (phdr->filesz > phdr->memsz)
+ errx (1, "invalid program header: filesz > memsz");
ps = getpagesize ();
- addr = (void *)(phdr.p_vaddr & ~(ps - 1));
- len = phdr.p_memsz + phdr.p_vaddr - (size_t)addr;
+ addr = (void *)(phdr->vaddr & ~(ps - 1));
+ len = phdr->memsz + phdr->vaddr - (size_t)addr;
ptr = mmap (
addr,
if (ptr == NULL)
err (1, "mmap()");
- if (phdr.p_filesz > 0) {
- lseek (fd, phdr.p_offset, SEEK_SET);
- read (fd, (void *)phdr.p_vaddr, phdr.p_filesz);
+ if (phdr->filesz > 0) {
+ lseek (fd, phdr->offset, SEEK_SET);
+ read (fd, (void *)phdr->vaddr, phdr->filesz);
}
- if (phdr.p_flags & (PF_R | PF_X))
+ if (phdr->flags & (PF_R | PF_X))
prot |= PROT_READ;
- if (phdr.p_flags & PF_W)
+ if (phdr->flags & PF_W)
prot |= PROT_WRITE;
if (mprotect (addr, len, prot) != 0)
err (1, "mprotect()");
- end = (phdr.p_vaddr + phdr.p_memsz + ps - 1) & ~(ps - 1);
+ end = (phdr->vaddr + phdr->memsz + ps - 1) & ~(ps - 1);
if (end > brkval)
brkval = end;
}
static void load_image (const char *filename)
{
- Elf64_Ehdr ehdr;
+ struct elf64_ehdr ehdr;
int fd;
fd = open (filename, O_RDONLY);
if (fd < 0)
err (1, "open('%s')", filename);
- if (read (fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
- err (1, "read('%s')", filename);
+ read_elf_ehdr (fd, &ehdr);
if (!is_executable (&ehdr))
errx (1, "Invalid argument");
- pc = ehdr.e_entry;
+ pc = ehdr.entry;
- for (unsigned i = 0; i < ehdr.e_phnum; ++i) {
- Elf64_Phdr phdr;
+ for (unsigned i = 0; i < ehdr.phnum; ++i) {
+ struct elf64_phdr phdr;
+ char buffer[sizeof (phdr)];
- lseek (fd, ehdr.e_phoff + i * ehdr.e_phentsize, SEEK_SET);
- if (read (fd, &phdr, ehdr.e_phentsize) != ehdr.e_phentsize)
+ lseek (fd, ehdr.phoff + i * ehdr.phentsize, SEEK_SET);
+ if (read (fd, buffer, ehdr.phentsize) != sizeof (buffer))
err (1, "failed to read program header %u", i);
- switch (phdr.p_type) {
+ decode_elf64_phdr (&phdr, buffer);
+
+ switch (phdr.type) {
case PT_NULL:
break;
case PT_LOAD:
- load_segment (fd, phdr);
+ load_segment (fd, &phdr);
break;
case PT_INTERP:
case PT_DYNAMIC:
blob - d565fc7a8b030875463a30066c3c5a63ca5fe009
blob + 9474a14e270beffd34ffdb1cb058ab2a21253438
--- src/linurv.h
+++ src/linurv.h
#include <libelf.h>
#include <stdio.h>
#include <err.h>
+#include "data.h"
enum log_level {
LOG_SILENT, // don't print anything
void cpu_exec (u32 instr);
void ecall (void);
int my_execve (const char *path, char **argv, char **envp);
-int is_executable (const Elf64_Ehdr *);
+int is_executable (const struct elf64_ehdr *);
+void read_elf_ehdr (int fd, struct elf64_ehdr *);
void logger (enum log_level, const char *, int, const char *, ...);
void cpu_enter_signal (int sig, u64 handler);