Commit Diff


commit - c791d5e82e697eff4e99ced039d29bd8d2029da3
commit + 80a2e72f5b5cd624675a0869774e5c2cff47a47c
blob - f8ced90bcaa3a38a746c653e9d44a09d2fd308c4
blob + a0baec7dd2d222cb9851c15e968d68c23e0ddede
--- .gitignore
+++ .gitignore
@@ -15,5 +15,5 @@ microcoreutils
 *.core
 *.pdf
 rootfs
-rvemu
+linurv
 config.mk.local
blob - 1919ea85b5986250356e8214c1ad812230ceb1d6
blob + a53351c28db4a20b91144e436234f89f1169f586
--- Makefile
+++ Makefile
@@ -12,7 +12,7 @@ COPT	= -g -O2
 CFLAGS	= ${CFLAGS_OS} ${COPT} -std=c2x
 LDFLAGS	= ${LDFLAGS_OS} -lpthread
 
-OBJ	= src/rvemu.o src/ecall.o src/cpu.o src/exec.o
+OBJ	= src/linurv.o src/ecall.o src/cpu.o src/exec.o
 T	= asm
 PROGS	= examples/test.elf	\
 	  examples/echo.elf	\
@@ -20,31 +20,31 @@ PROGS	= examples/test.elf	\
 	  examples/hello.elf	\
 	  examples/asm.elf
 
-all: rvemu ${PROGS}
+all: linurv ${PROGS}
 
 od: examples/$T.elf
 	${CROSS}-objdump -d examples/$T.elf | less
 
-run: rvemu ${PROGS}
+run: linurv ${PROGS}
 	mkdir -p rootfs/bin
-	cp -f rvemu rootfs/bin
+	cp -f linurv rootfs/bin
 	cp -f ${PROGS} rootfs/bin
 	cp -f test.txt rootfs/
-	${CHROOT} rootfs /bin/rvemu /bin/$T.elf
+	${CHROOT} rootfs /bin/linurv /bin/$T.elf
 
 distclean: clean
 	(cd tools; ${MAKE} distclean)
 
 clean:
-	rm -f rvemu src/*.o examples/*.elf *.core src/syscalls.h
+	rm -f linurv src/*.o examples/*.elf *.core src/syscalls.h
 	rm -rf rootfs
 
-install: rvemu
+install: linurv
 	mkdir -p ${DESTDIR}${PREFIX}/bin
-	cp -f rvemu ${DESTDIR}${PREFIX}/bin/
+	cp -f linurv ${DESTDIR}${PREFIX}/bin/
 
 
-rvemu: ${OBJ}
+linurv: ${OBJ}
 	${CC} -o $@ ${OBJ} ${LDFLAGS}
 
 src/ecall.o: src/syscalls.h
blob - 075f9f812a8cba378fee259e930a8050d929f4c7
blob + 6aab3a3a59ada2565b3f6779c303333bfcb266b6
--- src/cpu.c
+++ src/cpu.c
@@ -1,5 +1,5 @@
 #include <inttypes.h>
-#include "rvemu.h"
+#include "linurv.h"
 
 static u64 regs[31];
 u64 pc;
blob - 5c4a53f2813521dd056d4782dafd04e7c74dcae6
blob + 24edc75616e9d0e8c904863d33c37c7de7d42af7
--- src/ecall.c
+++ src/ecall.c
@@ -17,7 +17,7 @@
 #include <sched.h>
 #include <errno.h>
 #include "syscalls.h"
-#include "rvemu.h"
+#include "linurv.h"
 
 struct linux_stat64 {
 	u64 dev;
blob - 156608f9903fa2c229f72dc09bf641c0865a2f3a
blob + 45391396df92dfe98e982e147b7c07508a1ccd41
--- src/exec.c
+++ src/exec.c
@@ -4,7 +4,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <ctype.h>
-#include "rvemu.h"
+#include "linurv.h"
 
 
 int is_executable (const Elf64_Ehdr *ehdr)
@@ -65,11 +65,11 @@ int my_execve (const char *path, char **argv, char **e
 
 		old_env = environ;
 		environ = envp;
-		st = execvp ("rvemu", argv);
+		st = execvp ("linurv", argv);
 		environ = old_env;
 		return st;
 #else
-		return execvpe ("rvemu", argv, envp);
+		return execvpe ("linurv", argv, envp);
 #endif
 	}
 
blob - b2820cb92338ed9fca5224d5a138323dc27d6cf7 (mode 644)
blob + /dev/null
--- src/rvemu.c
+++ /dev/null
@@ -1,192 +0,0 @@
-#include <sys/resource.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <libgen.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "rvemu.h"
-
-u64 brkval = 0;
-
-static void load_segment (int fd, 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");
-
-	ps = getpagesize ();
-	addr = (void *)(phdr.p_vaddr & ~(ps - 1));
-	len = phdr.p_memsz + phdr.p_vaddr - (size_t)addr;
-
-	ptr = mmap (
-		addr,
-		len,
-		PROT_READ | PROT_WRITE,
-		MAP_PRIVATE | MAP_ANON | MAP_FIXED,
-		-1,
-		0
-	);
-	eprintf ("mmap (%p, %#zx) = %p;\n", addr, len, ptr);
-
-	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.p_flags & (PF_R | PF_X))
-		prot |= PROT_READ;
-	if (phdr.p_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);
-	if (end > brkval)
-		brkval = end;
-}
-
-static void load_image (const char *filename)
-{
-	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);
-
-	if (!is_executable (&ehdr))
-		errx (1, "Invalid argument");
-
-	pc = ehdr.e_entry;
-
-	for (unsigned i = 0; i < ehdr.e_phnum; ++i) {
-		Elf64_Phdr phdr;
-
-		lseek (fd, ehdr.e_phoff + i * ehdr.e_phentsize, SEEK_SET);
-		if (read (fd, &phdr, ehdr.e_phentsize) != ehdr.e_phentsize)
-			err (1, "failed to read program header %u", i);
-
-		switch (phdr.p_type) {
-		case PT_NULL:
-			break;
-		case PT_LOAD:
-			load_segment (fd, phdr);
-			break;
-		case PT_INTERP:
-		case PT_DYNAMIC:
-			errx (1, "shared objects not supported");
-		default:
-			//warnx ("%u: ignoring program header: %x",
-			//	i, (unsigned)phdr.p_type);
-			break;
-		}
-	}
-	close (fd);
-}
-
-static void cpu_push (u64 val)
-{
-	cpu_set (REG_sp, cpu_get (REG_sp) - 8);
-	write_u64 (cpu_get (REG_sp), val);
-}
-
-static void setup_stack (
-	u64 stack_size,
-	int argc,
-	char **argv,
-	int envc,
-	char **envp
-) {
-	void *ptr;
-	void *stack_bottom;
-
-	// set stack pointer
-	cpu_set (REG_sp, 0x80000000);
-
-	stack_bottom = (void *)(u64)(0x80000000 - stack_size);
-	ptr = mmap (
-		stack_bottom,
-		stack_size,
-		PROT_READ | PROT_WRITE,
-		MAP_PRIVATE | MAP_ANON | MAP_FIXED,
-		-1,
-		0
-	);
-
-	if (ptr != stack_bottom)
-		err (1, "failed to map stack");
-
-	// auxv
-	cpu_push (0);
-	cpu_push (0);
-	cpu_push (getegid ());
-	cpu_push (14);
-	cpu_push (getgid ());
-	cpu_push (13);
-	cpu_push (geteuid ());
-	cpu_push (12);
-	cpu_push (getuid ());
-	cpu_push (11);
-	cpu_push (getpagesize ());
-	cpu_push (6);
-
-	cpu_push (0);
-	for (int i = envc - 1; i >= 0; --i)
-		cpu_push ((u64)envp[i]);
-	cpu_push (0);
-	for (int i = argc - 1; i >= 0; --i)
-		cpu_push ((u64)argv[i]);
-	cpu_push (argc);
-}
-
-int main (int argc, char *argv[], char *envp[])
-{
-	const char *filename;
-	struct rlimit rl;
-	size_t stack_size;
-	int fd, envc;
-	char *base;
-	void *ptr;
-
-	base = basename (argv[0]);
-
-	if (strcmp (base, "rvemu") == 0) {
-		if (argc < 2)
-			errx (1, "usage: rvemu file");
-		++argv;
-		--argc;
-	}
-
-	filename = argv[0];
-	load_image (filename);
-
-	if (getrlimit (RLIMIT_STACK, &rl) == 0) {
-		stack_size = rl.rlim_cur;
-	} else {
-		stack_size = 1 << 20;
-	}
-
-	for (envc = 0; envp[envc] != NULL; ++envc);
-
-	setup_stack (stack_size, argc, argv, envc, envp);
-
-	while (1) {
-		const u32 instr = cpu_fetch ();
-		cpu_exec (instr);
-	}
-
-	return 0;
-}
blob - /dev/null
blob + 8528c3aaf97812d6a936b0ea33e916ab0ce836df (mode 644)
--- /dev/null
+++ src/linurv.c
@@ -0,0 +1,192 @@
+#include <sys/resource.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "linurv.h"
+
+u64 brkval = 0;
+
+static void load_segment (int fd, 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");
+
+	ps = getpagesize ();
+	addr = (void *)(phdr.p_vaddr & ~(ps - 1));
+	len = phdr.p_memsz + phdr.p_vaddr - (size_t)addr;
+
+	ptr = mmap (
+		addr,
+		len,
+		PROT_READ | PROT_WRITE,
+		MAP_PRIVATE | MAP_ANON | MAP_FIXED,
+		-1,
+		0
+	);
+	eprintf ("mmap (%p, %#zx) = %p;\n", addr, len, ptr);
+
+	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.p_flags & (PF_R | PF_X))
+		prot |= PROT_READ;
+	if (phdr.p_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);
+	if (end > brkval)
+		brkval = end;
+}
+
+static void load_image (const char *filename)
+{
+	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);
+
+	if (!is_executable (&ehdr))
+		errx (1, "Invalid argument");
+
+	pc = ehdr.e_entry;
+
+	for (unsigned i = 0; i < ehdr.e_phnum; ++i) {
+		Elf64_Phdr phdr;
+
+		lseek (fd, ehdr.e_phoff + i * ehdr.e_phentsize, SEEK_SET);
+		if (read (fd, &phdr, ehdr.e_phentsize) != ehdr.e_phentsize)
+			err (1, "failed to read program header %u", i);
+
+		switch (phdr.p_type) {
+		case PT_NULL:
+			break;
+		case PT_LOAD:
+			load_segment (fd, phdr);
+			break;
+		case PT_INTERP:
+		case PT_DYNAMIC:
+			errx (1, "shared objects not supported");
+		default:
+			//warnx ("%u: ignoring program header: %x",
+			//	i, (unsigned)phdr.p_type);
+			break;
+		}
+	}
+	close (fd);
+}
+
+static void cpu_push (u64 val)
+{
+	cpu_set (REG_sp, cpu_get (REG_sp) - 8);
+	write_u64 (cpu_get (REG_sp), val);
+}
+
+static void setup_stack (
+	u64 stack_size,
+	int argc,
+	char **argv,
+	int envc,
+	char **envp
+) {
+	void *ptr;
+	void *stack_bottom;
+
+	// set stack pointer
+	cpu_set (REG_sp, 0x80000000);
+
+	stack_bottom = (void *)(u64)(0x80000000 - stack_size);
+	ptr = mmap (
+		stack_bottom,
+		stack_size,
+		PROT_READ | PROT_WRITE,
+		MAP_PRIVATE | MAP_ANON | MAP_FIXED,
+		-1,
+		0
+	);
+
+	if (ptr != stack_bottom)
+		err (1, "failed to map stack");
+
+	// auxv
+	cpu_push (0);
+	cpu_push (0);
+	cpu_push (getegid ());
+	cpu_push (14);
+	cpu_push (getgid ());
+	cpu_push (13);
+	cpu_push (geteuid ());
+	cpu_push (12);
+	cpu_push (getuid ());
+	cpu_push (11);
+	cpu_push (getpagesize ());
+	cpu_push (6);
+
+	cpu_push (0);
+	for (int i = envc - 1; i >= 0; --i)
+		cpu_push ((u64)envp[i]);
+	cpu_push (0);
+	for (int i = argc - 1; i >= 0; --i)
+		cpu_push ((u64)argv[i]);
+	cpu_push (argc);
+}
+
+int main (int argc, char *argv[], char *envp[])
+{
+	const char *filename;
+	struct rlimit rl;
+	size_t stack_size;
+	int fd, envc;
+	char *base;
+	void *ptr;
+
+	base = basename (argv[0]);
+
+	if (strcmp (base, "linurv") == 0) {
+		if (argc < 2)
+			errx (1, "usage: linurv file");
+		++argv;
+		--argc;
+	}
+
+	filename = argv[0];
+	load_image (filename);
+
+	if (getrlimit (RLIMIT_STACK, &rl) == 0) {
+		stack_size = rl.rlim_cur;
+	} else {
+		stack_size = 1 << 20;
+	}
+
+	for (envc = 0; envp[envc] != NULL; ++envc);
+
+	setup_stack (stack_size, argc, argv, envc, envp);
+
+	while (1) {
+		const u32 instr = cpu_fetch ();
+		cpu_exec (instr);
+	}
+
+	return 0;
+}
blob - f1fa870f78600a53528abcc226d280124e392286 (mode 644)
blob + /dev/null
--- src/rvemu.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#include <stddef.h>
-#include <stdint.h>
-#include <libelf.h>
-#include <stdio.h>
-#include <err.h>
-
-#define DEBUG 0
-
-#if DEBUG
-# define eprintf(...) fprintf (stderr, __VA_ARGS__)
-#else
-# define eprintf(...)
-#endif
-
-enum {
-	REG_zero,
-	REG_ra,
-	REG_sp,
-	REG_gp,
-	REG_tp,
-	REG_t0,
-	REG_t1,
-	REG_t2,
-	REG_s0,
-	REG_s1,
-	REG_a0,
-	REG_a1,
-	REG_a2,
-	REG_a3,
-	REG_a4,
-	REG_a5,
-	REG_a6,
-	REG_a7,
-	REG_s2,
-	REG_s3,
-	REG_s4,
-	REG_s5,
-	REG_s6,
-	REG_s7,
-	REG_s8,
-	REG_s9,
-	REG_s10,
-	REG_s11,
-	REG_t3,
-	REG_t4,
-	REG_t5,
-	REG_t6,
-};
-
-typedef uint8_t  u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-
-typedef int8_t   i8;
-typedef int16_t  i16;
-typedef int32_t  i32;
-typedef int64_t  i64;
-
-typedef unsigned int uint;
-
-extern u64 pc;
-extern u64 brkval;
-extern const char *interpreter;
-
-u32 cpu_fetch (void);
-u64 cpu_get (size_t reg);
-void cpu_set (size_t reg, u64 val);
-void cpu_exec (u32 instr);
-void ecall (void);
-int my_execve (const char *path, char **argv, char **envp);
-int is_executable (const Elf64_Ehdr *);
-
-#define read_u8(ptr)		(*(const u8 *)(size_t)(ptr))
-#define read_u16(ptr)		(*(const u16 *)(size_t)(ptr))
-#define read_u32(ptr)		(*(const u32 *)(size_t)(ptr))
-#define read_u64(ptr)		(*(const u64 *)(size_t)(ptr))
-#define read_i8(ptr)		(*(const i8 *)(size_t)(ptr))
-#define read_i16(ptr)		(*(const i16 *)(size_t)(ptr))
-#define read_i32(ptr)		(*(const i32 *)(size_t)(ptr))
-#define read_i64(ptr)		(*(const i64 *)(size_t)(ptr))
-#define write_u8(ptr, val)	(*(u8 *)(size_t)(ptr) = (val))
-#define write_u16(ptr, val)	(*(u16 *)(size_t)(ptr) = (val))
-#define write_u32(ptr, val)	(*(u32 *)(size_t)(ptr) = (val))
-#define write_u64(ptr, val)	(*(u64 *)(size_t)(ptr) = (val))
blob - /dev/null
blob + f1fa870f78600a53528abcc226d280124e392286 (mode 644)
--- /dev/null
+++ src/linurv.h
@@ -0,0 +1,85 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <err.h>
+
+#define DEBUG 0
+
+#if DEBUG
+# define eprintf(...) fprintf (stderr, __VA_ARGS__)
+#else
+# define eprintf(...)
+#endif
+
+enum {
+	REG_zero,
+	REG_ra,
+	REG_sp,
+	REG_gp,
+	REG_tp,
+	REG_t0,
+	REG_t1,
+	REG_t2,
+	REG_s0,
+	REG_s1,
+	REG_a0,
+	REG_a1,
+	REG_a2,
+	REG_a3,
+	REG_a4,
+	REG_a5,
+	REG_a6,
+	REG_a7,
+	REG_s2,
+	REG_s3,
+	REG_s4,
+	REG_s5,
+	REG_s6,
+	REG_s7,
+	REG_s8,
+	REG_s9,
+	REG_s10,
+	REG_s11,
+	REG_t3,
+	REG_t4,
+	REG_t5,
+	REG_t6,
+};
+
+typedef uint8_t  u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef int8_t   i8;
+typedef int16_t  i16;
+typedef int32_t  i32;
+typedef int64_t  i64;
+
+typedef unsigned int uint;
+
+extern u64 pc;
+extern u64 brkval;
+extern const char *interpreter;
+
+u32 cpu_fetch (void);
+u64 cpu_get (size_t reg);
+void cpu_set (size_t reg, u64 val);
+void cpu_exec (u32 instr);
+void ecall (void);
+int my_execve (const char *path, char **argv, char **envp);
+int is_executable (const Elf64_Ehdr *);
+
+#define read_u8(ptr)		(*(const u8 *)(size_t)(ptr))
+#define read_u16(ptr)		(*(const u16 *)(size_t)(ptr))
+#define read_u32(ptr)		(*(const u32 *)(size_t)(ptr))
+#define read_u64(ptr)		(*(const u64 *)(size_t)(ptr))
+#define read_i8(ptr)		(*(const i8 *)(size_t)(ptr))
+#define read_i16(ptr)		(*(const i16 *)(size_t)(ptr))
+#define read_i32(ptr)		(*(const i32 *)(size_t)(ptr))
+#define read_i64(ptr)		(*(const i64 *)(size_t)(ptr))
+#define write_u8(ptr, val)	(*(u8 *)(size_t)(ptr) = (val))
+#define write_u16(ptr, val)	(*(u16 *)(size_t)(ptr) = (val))
+#define write_u32(ptr, val)	(*(u32 *)(size_t)(ptr) = (val))
+#define write_u64(ptr, val)	(*(u64 *)(size_t)(ptr) = (val))