Skip to content

Commit

Permalink
Support putting the root filesystem in a directory
Browse files Browse the repository at this point in the history
Also added repz cmpsb, support for executing dynamic libraries,
set_tid_address stub, and found an alternative to setup.c.
  • Loading branch information
Theodore Dubois committed Jul 24, 2017
1 parent bb38231 commit 3e590e9
Show file tree
Hide file tree
Showing 23 changed files with 326 additions and 171 deletions.
2 changes: 2 additions & 0 deletions emu/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,8 @@ int CONCAT(decoder_name, OP_SIZE)(struct cpu_state *cpu) {
case 0xa4: TRACEI("rep movsb"); REP(MOVS(8)); break;
case 0xa5: TRACEI("rep movs"); REP(MOVS(OP_SIZE)); break;

case 0xa6: TRACEI("repz cmpsb"); REPZ(CMPS(8)); break;

case 0xaa: TRACEI("rep stosb"); REP(STOS(8)); break;
case 0xab: TRACEI("rep stos"); REP(STOS(OP_SIZE)); break;

Expand Down
18 changes: 17 additions & 1 deletion emu/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@
#define get_mem_addr(size) mem_read(addr, size)
#define set_mem_addr(to, size) mem_write(addr, to, size)

#define get_mem_si(size) mem_read(cpu->osi, size)
#define set_mem_si(size) mem_write(cpu->osi, size)
#define get_mem_di(size) mem_read(cpu->odi, size)
#define set_mem_di(size) mem_write(cpu->osi, size)

// DEFINE ALL THE MACROS
#define get_oax(size) cpu->oax
#define get_obx(size) cpu->obx
Expand Down Expand Up @@ -439,9 +444,13 @@

// TODO find an alternative to al here
#define SCAS(z) \
addr = cpu->edi; CMP(al, mem_addr,z); \
CMP(al, mem_di,z); \
BUMP_DI(z)

#define CMPS(z) \
CMP(mem_di, mem_si,z); \
BUMP_SI_DI(z)

#define REP(OP) \
while (cpu->ocx != 0) { \
OP; \
Expand All @@ -455,6 +464,13 @@
if (ZF) break; \
}

#define REPZ(OP) \
while (cpu->ocx != 0) { \
OP; \
cpu->ocx--; \
if (!ZF) break; \
}

#define CMPXCHG(src, dst,z) \
CMP(oax, dst,z); \
if (E) { \
Expand Down
37 changes: 18 additions & 19 deletions fs/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,34 @@
#include "sys/fs.h"
#include "sys/process.h"

struct mount *find_mount(char *pathname) {
static struct mount *find_mount(char *pathname) {
struct mount *mount;
for (mount = mounts; mount != NULL; mount = mount->next) {
if (strncmp(pathname, mount->mount_point, strlen(mount->mount_point)) == 0) {
if (strncmp(pathname, mount->point, strlen(mount->point)) == 0) {
break;
}
}
assert(mount != NULL); // this would mean there's no root FS mounted
return mount;
}

char *path_in_mount(char *path, struct mount *mount) {
return path + strlen(mount->mount_point);
struct mount *find_mount_and_trim_path(char *path) {
struct mount *mount = find_mount(path);
char *dst = path;
const char *src = path + strlen(mount->point);
while (*src != '\0')
*dst++ = *src++;
*dst = '\0';
return mount;
}

int generic_open(const char *pathname, struct fd *fd, int flags, int mode) {
char path[MAX_PATH];
int err = path_normalize(pathname, path);
if (err < 0)
return err;
struct mount *mount = find_mount(path);
return mount->fs->open(path_in_mount(path, mount), fd, flags, mode);
struct mount *mount = find_mount_and_trim_path(path);
return mount->fs->open(mount, path, fd, flags, mode);
}

// TODO I bet this can be shorter
Expand All @@ -34,8 +40,8 @@ int generic_access(const char *pathname, int mode) {
int err = path_normalize(pathname, path);
if (err < 0)
return err;
struct mount *mount = find_mount(path);
return mount->fs->access(path_in_mount(path, mount), mode);
struct mount *mount = find_mount_and_trim_path(path);
return mount->fs->access(mount, path, mode);
}

// TODO I bet this can be shorter
Expand All @@ -44,22 +50,15 @@ int generic_unlink(const char *pathname) {
int err = path_normalize(pathname, path);
if (err < 0)
return err;
struct mount *mount = find_mount(path);
return mount->fs->unlink(path_in_mount(path, mount));
struct mount *mount = find_mount_and_trim_path(path);
return mount->fs->unlink(mount, path);
}

ssize_t generic_readlink(const char *pathname, char *buf, size_t bufsize) {
char path[MAX_PATH];
int err = path_normalize(pathname, path);
if (err < 0)
return err;
struct mount *mount = find_mount(path);
return mount->fs->readlink(path_in_mount(path, mount), buf, bufsize);
}

void mount_root() {
mounts = malloc(sizeof(struct mount));
mounts->mount_point = strdup("");
mounts->fs = &realfs;
mounts->next = NULL;
struct mount *mount = find_mount_and_trim_path(path);
return mount->fs->readlink(mount, path, buf, bufsize);
}
52 changes: 43 additions & 9 deletions fs/real.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,27 @@
#include "sys/calls.h"
#include "sys/fs.h"

char *strnprepend(char *str, const char *prefix, int max) {
if (strlen(str) + strlen(prefix) + 1 > max)
return NULL;
const char *src = str + strlen(str) + 1;
char *dst = (char *) src + strlen(prefix);
while (src != str)
*dst-- = *src--;
*dst = *src;
src = prefix;
dst = str;
while (*src != '\0')
*dst++ = *src++;
return str;
}

// TODO translate goddamn flags

static int realfs_open(char *path, struct fd *fd, int flags, int mode) {
/* debugger; */
static int realfs_open(struct mount *mount, char *path, struct fd *fd, int flags, int mode) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

int fd_no = open(path, flags, mode);
if (fd_no < 0)
return err_map(errno);
Expand Down Expand Up @@ -80,9 +97,17 @@ static void copy_xattr_stat(struct statbuf *fake_stat, struct xattr_stat *xstat)
fake_stat->rdev = xstat->rdev;
}

static int realfs_stat(const char *path, struct statbuf *fake_stat, bool follow_links) {
static int realfs_stat(struct mount *mount, char *path, struct statbuf *fake_stat, bool follow_links) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

struct stat real_stat;
if ((follow_links ? lstat : stat)(path, &real_stat) < 0)
int (*stat_fn)(const char *path, struct stat *buf);
if (follow_links)
stat_fn = lstat;
else
stat_fn = stat;
if (stat_fn(path, &real_stat) < 0)
return err_map(errno);
copy_stat(fake_stat, &real_stat);

Expand All @@ -104,14 +129,20 @@ static int realfs_fstat(struct fd *fd, struct statbuf *fake_stat) {
return 0;
}

static int realfs_unlink(const char *path) {
static int realfs_unlink(struct mount *mount, char *path) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

int res = unlink(path);
if (res < 0)
return err_map(errno);
return res;
}

static int realfs_access(const char *path, int mode) {
static int realfs_access(struct mount *mount, char *path, int mode) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

int real_mode = 0;
if (mode & AC_F) real_mode |= F_OK;
if (mode & AC_R) real_mode |= R_OK;
Expand All @@ -123,14 +154,14 @@ static int realfs_access(const char *path, int mode) {
return res;
}

static ssize_t realfs_read(struct fd *fd, char *buf, size_t bufsize) {
static ssize_t realfs_read(struct fd *fd, void *buf, size_t bufsize) {
ssize_t res = read(fd->real_fd, buf, bufsize);
if (res < 0)
return err_map(errno);
return res;
}

static ssize_t realfs_write(struct fd *fd, char *buf, size_t bufsize) {
static ssize_t realfs_write(struct fd *fd, void *buf, size_t bufsize) {
ssize_t res = write(fd->real_fd, buf, bufsize);
if (res < 0)
return err_map(errno);
Expand Down Expand Up @@ -252,7 +283,10 @@ static int realfs_ioctl(struct fd *fd, int cmd, void *arg) {
return res;
}

static ssize_t realfs_readlink(char *path, char *buf, size_t bufsize) {
static ssize_t realfs_readlink(struct mount *mount, char *path, char *buf, size_t bufsize) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

ssize_t size = readlink(path, buf, bufsize);
if (size < 0)
return err_map(errno);
Expand Down
4 changes: 2 additions & 2 deletions fs/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ int generic_stat(const char *pathname, struct statbuf *stat, bool follow_links)
int err = path_normalize(pathname, path);
if (err < 0)
return err;
struct mount *mount = find_mount(path);
return mount->fs->stat(path_in_mount(path, mount), stat, follow_links);
struct mount *mount = find_mount_and_trim_path(path);
return mount->fs->stat(mount, path, stat, follow_links);
}

static dword_t sys_stat_path(addr_t pathname_addr, addr_t statbuf_addr, bool follow_links) {
Expand Down
10 changes: 4 additions & 6 deletions main.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#include <stdlib.h>
#include "sys/calls.h"
#include "sys/process.h"
#include "xX_main_Xx.h"

int main(int argc, char *const argv[]) {
int err;
setup();
char *envp[] = {NULL};
if ((err = sys_execve(argv[1], argv + 1, envp)) < 0) {
return -err;
}
int err = xX_main_Xx(argc, argv);
if (err < 0)
return err;
cpu_run(&current->cpu);
}
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ emu_src = [

threads = dependency('threads')

libish = library('ish', sys_src + emu_src + ['setup.c'],
libish = library('ish', sys_src + emu_src,
include_directories: includes)
ish = declare_dependency(
link_with: libish,
Expand Down
2 changes: 0 additions & 2 deletions misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,4 @@ typedef sdword_t int_t;
#define uint(size) CONCAT3(uint,size,_t)
#define sint(size) CONCAT3(int,size,_t)

void setup();

#endif
26 changes: 0 additions & 26 deletions setup.c

This file was deleted.

1 change: 1 addition & 0 deletions sys/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ syscall_t syscall_table[] = {
[239] = (syscall_t) sys_sendfile64,
[243] = (syscall_t) sys_set_thread_area,
[252] = (syscall_t) sys_exit_group,
[258] = (syscall_t) sys_set_tid_address,
[265] = (syscall_t) sys_clock_gettime,

// stubs
Expand Down
1 change: 1 addition & 0 deletions sys/calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ dword_t sys_getgid32();
dword_t sys_getgid();
dword_t sys_getcwd(addr_t buf_addr, dword_t size);
int sys_set_thread_area(addr_t u_info);
int sys_set_tid_address(addr_t blahblahblah);

// system information
#define UNAME_LENGTH 65
Expand Down
1 change: 1 addition & 0 deletions sys/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define ELF_BIGENDIAN 2
#define ELF_LINUX_ABI 3
#define ELF_EXECUTABLE 2
#define ELF_DYNAMIC 3
#define ELF_X86 3

struct elf_header {
Expand Down
2 changes: 1 addition & 1 deletion sys/errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#define _EINTR -4 /* Interrupted system call */
#define _EIO -5 /* I/O error */
#define _ENXIO -6 /* No such device or address */
#define _E2BIG -7 /* Argument list too long */
#define _E2BIG -7 /* That's what she said */
#define _ENOEXEC -8 /* Exec format error */
#define _EBADF -9 /* Bad file number */
#define _ECHILD -10 /* No child processes */
Expand Down
Loading

0 comments on commit 3e590e9

Please sign in to comment.