Skip to content

Commit

Permalink
Get busybox cat to work
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Jun 18, 2017
1 parent 559ae4c commit 65667d5
Show file tree
Hide file tree
Showing 20 changed files with 272 additions and 62 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build
llvm
build-gcc/
95 changes: 62 additions & 33 deletions emu/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// instructions defined as macros
#include "emu/instructions.h"
#include "emu/sse.h"

#define OP_SIZE 32
#define cpu_step CONCAT(cpu_step, OP_SIZE)
Expand Down Expand Up @@ -74,18 +75,21 @@ int cpu_step(struct cpu_state *cpu) {
dword_t addr = 0;
#define READMODRM modrm_decode32(cpu, &addr, &modrm)
#define modrm_val_(size) \
*(modrm.type == mod_reg ? &REGPTR_(modrm.modrm_regid, size) : &MEM_(addr, size))
(*(modrm.type == mod_reg ? &REGPTR_(modrm.modrm_regid, size) : &MEM_(addr, size)))
#define modrm_val_w_(size) \
*(modrm.type == mod_reg ? &REGPTR_(modrm.modrm_regid, size) : &MEM_W_(addr, size))
(*(modrm.type == mod_reg ? &REGPTR_(modrm.modrm_regid, size) : &MEM_W_(addr, size)))
#define modrm_val modrm_val_(OP_SIZE)
#define modrm_val_w modrm_val_w_(OP_SIZE)
#define modrm_val8 modrm_val_(8)
#define modrm_val8_w modrm_val_w_(8)
#define modrm_val16 modrm_val_(16)
#define modrm_val32 modrm_val_(32)
#define modrm_val64 modrm_val_(64)
#define modrm_val_sse ((union xmm_reg *) &modrm_val_(64))
#define modrm_reg REGPTR(modrm.reg)
#define modrm_reg8 REGPTR8(modrm.reg)
#define modrm_reg64 REGPTR64(modrm.reg)
#define modrm_reg_sse ((union xmm_reg *) &REGPTR_(modrm.reg, 64))

#undef imm
byte_t imm8;
Expand Down Expand Up @@ -141,56 +145,56 @@ int cpu_step(struct cpu_state *cpu) {
READINSN;
switch (insn) {
case 0x1f: TRACEI("nop modrm\t"); READMODRM; break;

case 0x28: TRACEI("movp modrm, reg");
READMODRM; MOVP(modrm_val_sse, modrm_reg_sse); break;

case 0x31: TRACEI("rdtsc");
// TODO there's a clang builtin for this
__asm__("rdtsc" : "=a" (cpu->eax), "=d" (cpu->edx)); break;

case 0x40: TRACEI("cmovo modrm, reg\t");
case 0x40: TRACEI("cmovo modrm, reg");
READMODRM; CMOV(O, modrm_val_w, modrm_reg); break;
case 0x41: TRACEI("cmovno modrm, reg\t");
case 0x41: TRACEI("cmovno modrm, reg");
READMODRM; CMOV(!O, modrm_val_w, modrm_reg); break;
case 0x42: TRACEI("cmovb modrm, reg\t");
case 0x42: TRACEI("cmovb modrm, reg");
READMODRM; CMOV(B, modrm_val_w, modrm_reg); break;
case 0x43: TRACEI("cmovnb modrm, reg\t");
case 0x43: TRACEI("cmovnb modrm, reg");
READMODRM; CMOV(!B, modrm_val_w, modrm_reg); break;
case 0x44: TRACEI("cmove modrm, reg\t");
case 0x44: TRACEI("cmove modrm, reg");
READMODRM; CMOV(E, modrm_val_w, modrm_reg); break;
case 0x45: TRACEI("cmovne modrm, reg\t");
case 0x45: TRACEI("cmovne modrm, reg");
READMODRM; CMOV(!E, modrm_val_w, modrm_reg); break;
case 0x46: TRACEI("cmovbe modrm, reg\t");
case 0x46: TRACEI("cmovbe modrm, reg");
READMODRM; CMOV(BE, modrm_val_w, modrm_reg); break;
case 0x47: TRACEI("cmova modrm, reg\t");
case 0x47: TRACEI("cmova modrm, reg");
READMODRM; CMOV(!BE, modrm_val_w, modrm_reg); break;
case 0x48: TRACEI("cmovs modrm, reg\t");
case 0x48: TRACEI("cmovs modrm, reg");
READMODRM; CMOV(S, modrm_val_w, modrm_reg); break;
case 0x49: TRACEI("cmovns modrm, reg\t");
case 0x49: TRACEI("cmovns modrm, reg");
READMODRM; CMOV(!S, modrm_val_w, modrm_reg); break;
case 0x4a: TRACEI("cmovp modrm, reg\t");
case 0x4a: TRACEI("cmovp modrm, reg");
READMODRM; CMOV(P, modrm_val_w, modrm_reg); break;
case 0x4b: TRACEI("cmovnp modrm, reg\t");
case 0x4b: TRACEI("cmovnp modrm, reg");
READMODRM; CMOV(!P, modrm_val_w, modrm_reg); break;
case 0x4c: TRACEI("cmovl modrm, reg\t");
case 0x4c: TRACEI("cmovl modrm, reg");
READMODRM; CMOV(L, modrm_val_w, modrm_reg); break;
case 0x4d: TRACEI("cmovnl modrm, reg\t");
case 0x4d: TRACEI("cmovnl modrm, reg");
READMODRM; CMOV(!L, modrm_val_w, modrm_reg); break;
case 0x4e: TRACEI("cmovle modrm, reg\t");
case 0x4e: TRACEI("cmovle modrm, reg");
READMODRM; CMOV(LE, modrm_val_w, modrm_reg); break;
case 0x4f: TRACEI("cmovnle modrm, reg\t");
case 0x4f: TRACEI("cmovnle modrm, reg");
READMODRM; CMOV(!LE, modrm_val_w, modrm_reg); break;

case 0xa2:
TRACEI("cpuid");
do_cpuid(&cpu->eax, &cpu->ebx, &cpu->ecx, &cpu->edx);
break;

case 0xa3: TRACEI("bt reg, modrm\t");
READMODRM; BT(modrm_reg, modrm_val); break;

case 0xa5: TRACEI("shld cl, reg, modrm");
READMODRM; SHLD(cpu->cl, modrm_reg, modrm_val); break;

case 0xac: TRACEI("shrd imm8, reg, modrm");
READMODRM; READIMM8; SHRD(imm8, modrm_reg, modrm_val); break;
case 0x57: TRACEI("xorps modrm, reg");
READMODRM; XORP(modrm_val_sse, modrm_reg_sse); break;
case 0x73: TRACEI("psrlq imm8, reg");
// TODO I think this is actually a group
READMODRM; READIMM8; PSRLQ(imm8, modrm_val_sse); break;
case 0x76: TRACEI("pcmpeqd reg, modrm");
READMODRM; PCMPEQD(modrm_reg_sse, modrm_val_sse); break;
case 0x7e: TRACEI("movd reg, modrm32");
READMODRM; MOV(modrm_reg_sse->dw[0], modrm_val32); break;

case 0x80: TRACEI("jo rel\t");
READIMM; J_REL(O, imm); break;
Expand Down Expand Up @@ -233,6 +237,20 @@ int cpu_step(struct cpu_state *cpu) {
case 0x95: TRACEI("setne\t");
READMODRM; SET(!E, modrm_val8_w); break;

case 0xa2:
TRACEI("cpuid");
do_cpuid(&cpu->eax, &cpu->ebx, &cpu->ecx, &cpu->edx);
break;

case 0xa3: TRACEI("bt reg, modrm");
READMODRM; BT(modrm_reg, modrm_val); break;

case 0xa5: TRACEI("shld cl, reg, modrm");
READMODRM; SHLD(cpu->cl, modrm_reg, modrm_val); break;

case 0xac: TRACEI("shrd imm8, reg, modrm");
READMODRM; READIMM8; SHRD(imm8, modrm_reg, modrm_val); break;

case 0xaf: TRACEI("imul modrm, reg");
READMODRM; MUL2((int32_t) modrm_val, modrm_reg); break;

Expand All @@ -248,11 +266,15 @@ int cpu_step(struct cpu_state *cpu) {
case 0xbf: TRACEI("movs modrm16, reg");
READMODRM; MOV((int16_t) modrm_val16, modrm_reg); break;

case 0xd4: TRACEI("paddq modrm, reg");
READMODRM; PADD(modrm_val_sse, modrm_reg_sse); break;
case 0xd6:
// someone tell intel to get a life
if (OP_SIZE == 16) {
TRACEI("movq xmm, modrm");
READMODRM; MOV(modrm_reg64, modrm_reg64);
TRACEI("movq reg, modrm");
READMODRM; MOV(modrm_reg64, modrm_val64);
} else {
return INT_UNDEFINED;
}
break;

Expand Down Expand Up @@ -435,6 +457,11 @@ int cpu_step(struct cpu_state *cpu) {
case 0x85: TRACEI("test reg, modrm");
READMODRM; TEST(modrm_reg, modrm_val); break;

case 0x86: TRACEI("xchg reg8, modrm8");
READMODRM; XCHG(modrm_reg8, modrm_val8); break;
case 0x87: TRACEI("xchg reg, modrm");
READMODRM; XCHG(modrm_reg, modrm_val); break;

case 0x88: TRACEI("mov reg8, modrm8");
READMODRM; MOV(modrm_reg8, modrm_val8_w); break;
case 0x89: TRACEI("mov reg, modrm");
Expand Down Expand Up @@ -472,6 +499,8 @@ int cpu_step(struct cpu_state *cpu) {

case 0xa1: TRACEI("mov mem, eax\t");
READADDR; MOV(MEM(addr), ax); break;
case 0xa2: TRACEI("mov al, mem\t");
READADDR; MOV(cpu->al, MEM8_W(addr)); break;
case 0xa3: TRACEI("mov eax, mem\t");
READADDR; MOV(ax, MEM_W(addr)); break;
case 0xa4: TRACEI("movsb"); MOVSB; break;
Expand Down
5 changes: 2 additions & 3 deletions emu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ int cpu_step32(struct cpu_state *cpu);
int cpu_step16(struct cpu_state *cpu);

union xmm_reg {
struct {
qword_t qhigh, qlow;
};
qword_t qw[2];
dword_t dw[4];
// TODO more forms
};

Expand Down
2 changes: 1 addition & 1 deletion emu/instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@
}

#define BT(bit, val) \
cpu->cf = (val) & (1 << bit)
cpu->cf = ((val) & (1 << bit)) ? 1 : 0;

#define BUMP_SI(size) \
if (!cpu->df) \
Expand Down
3 changes: 1 addition & 2 deletions emu/modrm.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
.reg32_id = REG_ID(r32), \
.reg16_id = REG_ID(r16), \
.reg8_id = REG_ID(r8), \
.reg64_id = REG_ID(xmm.qlow), \
.reg64_high_id = REG_ID(xmm.qhigh) \
.reg64_id = REG_ID(xmm), \
})

static inline struct regptr decode_reg(byte_t reg) {
Expand Down
1 change: 0 additions & 1 deletion emu/modrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ struct regptr {
reg_id_t reg16_id;
reg_id_t reg32_id;
reg_id_t reg64_id;
reg_id_t reg64_high_id;
};
static const char *regptr_name(struct regptr regptr) {
static char buf[15];
Expand Down
2 changes: 2 additions & 0 deletions emu/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ struct process {

dword_t pid;

dword_t uid, gid;

addr_t start_brk;
addr_t brk;

Expand Down
25 changes: 25 additions & 0 deletions emu/sse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#define CMPEQ(src, dst) \
dst = dst == src ? (typeof(dst)) -1 : src
#define PCMPEQD(src, dst) \
CMPEQ(src->dw[0], dst->dw[0]); \
CMPEQ(src->dw[1], dst->dw[1]); \
CMPEQ(src->dw[2], dst->dw[2]); \
CMPEQ(src->dw[3], dst->dw[3])

#define SRL(count, dst) \
dst >>= count
#define PSRLQ(count, dst) \
SRL(count, dst->qw[0]); \
SRL(count, dst->qw[1]); \

#define MOVP(src, dst) \
dst->qw[0] = src->qw[0]; \
dst->qw[1] = src->qw[1]

#define XORP(src, dst) \
dst->qw[0] ^= src->qw[0]; \
dst->qw[1] ^= src->qw[1]

#define PADD(src, dst) \
dst->qw[0] += src->qw[0]; \
dst->qw[1] += src->qw[1]
5 changes: 5 additions & 0 deletions fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ struct fd_ops {
ssize_t (*write)(struct fd *fd, char *buf, size_t bufsize);
int (*mmap)(struct fd *fd, off_t offset, size_t len, int prot, int flags, void **mem_out);
int (*stat)(struct fd *fd, struct statbuf *stat);
// returns the size needed for the output of ioctl, 0 if the arg is not a
// pointer, -1 for invalid command
ssize_t (*ioctl_size)(struct fd *fd, int cmd);
// if ioctl_size returns non-zero, arg must point to ioctl_size valid bytes
int (*ioctl)(struct fd *fd, int cmd, void *arg);
int (*close)(struct fd *fd);
};

Expand Down
26 changes: 25 additions & 1 deletion fs/real.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include "sys/errno.h"
Expand Down Expand Up @@ -98,6 +99,27 @@ static int realfs_mmap(struct fd *fd, off_t offset, size_t len, int prot, int fl
return 0;
}

struct win_size {
word_t row;
word_t col;
word_t xpixel;
word_t ypixel;
};

static ssize_t realfs_ioctl_size(struct fd *fd, int cmd) {
switch (cmd) {
case TIOCGWINSZ: return sizeof(struct win_size);
}
return -1;
}

static int realfs_ioctl(struct fd *fd, int cmd, void *arg) {
int res = ioctl(fd->real_fd, cmd, arg);
if (res < 0)
return err_map(errno);
return res;
}

static ssize_t realfs_readlink(char *path, char *buf, size_t bufsize) {
ssize_t size = readlink(path, buf, bufsize);
if (size < 0)
Expand All @@ -117,5 +139,7 @@ const struct fd_ops realfs_fdops = {
.write = realfs_write,
.mmap = realfs_mmap,
.stat = realfs_fstat,
.ioctl_size = realfs_ioctl_size,
.ioctl = realfs_ioctl,
.close = realfs_close,
};
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ sys_src = [
'sys/uname.c',
'sys/tls.c',
'sys/fs.c',
'sys/getid.c',

'fs/fs.c',
'fs/path.c',
Expand Down
1 change: 1 addition & 0 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
void setup() {
// god help us
current = process_create();
current->uid = current->gid = 0;
mount_root();
current->pwd = getcwd(NULL, 0);
current->files[0] = malloc(sizeof(struct fd));
Expand Down
8 changes: 8 additions & 0 deletions sys/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,25 @@ syscall_t syscall_table[] = {
[5] = (syscall_t) sys_open,
[6] = (syscall_t) sys_close,
[11] = (syscall_t) _sys_execve,
[24] = (syscall_t) sys_getuid,
[47] = (syscall_t) sys_getgid,
[33] = (syscall_t) sys_access,
[41] = (syscall_t) sys_dup,
[45] = (syscall_t) sys_brk,
[54] = (syscall_t) sys_ioctl,
[63] = (syscall_t) sys_dup2,
[85] = (syscall_t) sys_readlink,
[90] = (syscall_t) sys_mmap,
[91] = (syscall_t) sys_munmap,
[122] = (syscall_t) _sys_uname,
[125] = (syscall_t) sys_mprotect,
[146] = (syscall_t) sys_writev,
[187] = (syscall_t) sys_sendfile,
[192] = (syscall_t) sys_mmap2,
[197] = (syscall_t) sys_fstat64,
[199] = (syscall_t) sys_getuid32,
/* [200] = (syscall_t) sys_getgid32, */
[239] = (syscall_t) sys_sendfile64,
[243] = (syscall_t) sys_set_thread_area,
[252] = (syscall_t) sys_exit_group,

Expand Down
9 changes: 9 additions & 0 deletions sys/calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ dword_t sys_close(fd_t fd);
dword_t sys_fstat64(fd_t fd_no, addr_t statbuf_addr);
dword_t sys_access(addr_t pathname_addr, dword_t mode);
dword_t sys_readlink(addr_t pathname, addr_t buf, dword_t bufsize);
dword_t sys_sendfile(fd_t out_fd, fd_t in_fd, addr_t offset_addr, dword_t count);
dword_t sys_sendfile64(fd_t out_fd, fd_t in_fd, addr_t offset_addr, dword_t count);

dword_t sys_getuid32();
dword_t sys_getuid();
dword_t sys_getgid32();
dword_t sys_getgid();

struct io_vec {
addr_t base;
Expand All @@ -34,8 +41,10 @@ struct io_vec {
dword_t sys_read(fd_t fd_no, addr_t buf_addr, dword_t size);
dword_t sys_write(fd_t fd_no, addr_t buf_addr, dword_t size);
dword_t sys_writev(fd_t fd_no, addr_t iovec_addr, dword_t iovec_count);
dword_t sys_ioctl(fd_t f, dword_t cmd, dword_t arg);

dword_t sys_dup(fd_t fd);
dword_t sys_dup2(fd_t fd, fd_t new_fd);

addr_t sys_brk(addr_t new_brk);
int handle_pagefault(addr_t addr);
Expand Down
Loading

0 comments on commit 65667d5

Please sign in to comment.