aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>2011-05-19 15:28:26 -0700
committerAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>2011-05-19 15:28:26 -0700
commitbe22e4abd5fd8dad83068744a0d1497d50a2806c (patch)
tree41e7e210dd9f8e0dc35b7da36eb4f483d19734f7
parent92a8f05f5a2081deb086ad478c3ecbfd4e649002 (diff)
downloadpk-be22e4abd5fd8dad83068744a0d1497d50a2806c.zip
pk-be22e4abd5fd8dad83068744a0d1497d50a2806c.tar.gz
pk-be22e4abd5fd8dad83068744a0d1497d50a2806c.tar.bz2
[pk] made PK smaller
-rw-r--r--pk/elf.c21
-rw-r--r--pk/file.c12
-rw-r--r--pk/fp.c90
-rw-r--r--pk/syscall.c9
4 files changed, 79 insertions, 53 deletions
diff --git a/pk/elf.c b/pk/elf.c
index ab56b58..f61f1da 100644
--- a/pk/elf.c
+++ b/pk/elf.c
@@ -10,15 +10,17 @@ long load_elf(const char* fn, int* user64)
sysret_t ret = file_open(fn, strlen(fn)+1, O_RDONLY, 0);
file_t* file = (file_t*)ret.result;
if(ret.result == -1)
- panic("couldn't open %s!", fn);
+ goto fail;
char buf[2048]; // XXX
int header_size = file_read(file, buf, sizeof(buf)).result;
- kassert(header_size >= (int)sizeof(Elf64_Ehdr));
+ if(header_size >= (int)sizeof(Elf64_Ehdr))
+ goto fail;
const Elf64_Ehdr* eh64 = (const Elf64_Ehdr*)buf;
- kassert(eh64->e_ident[0] == '\177' && eh64->e_ident[1] == 'E' &&
- eh64->e_ident[2] == 'L' && eh64->e_ident[3] == 'F');
+ if(!(eh64->e_ident[0] == '\177' && eh64->e_ident[1] == 'E' &&
+ eh64->e_ident[2] == 'L' && eh64->e_ident[3] == 'F'))
+ goto fail;
#define LOAD_ELF do { \
eh = (typeof(eh))buf; \
@@ -26,7 +28,8 @@ long load_elf(const char* fn, int* user64)
ph = (typeof(ph))(buf+eh->e_phoff); \
for(int i = 0; i < eh->e_phnum; i++, ph++) { \
if(ph->p_type == SHT_PROGBITS && ph->p_memsz) { \
- kassert(file_pread(file, (char*)(long)ph->p_vaddr, ph->p_filesz, ph->p_offset).result == ph->p_filesz); \
+ if(file_pread(file, (char*)(long)ph->p_vaddr, ph->p_filesz, ph->p_offset).result != ph->p_filesz) \
+ goto fail; \
memset((char*)(long)ph->p_vaddr+ph->p_filesz, 0, ph->p_memsz-ph->p_filesz); \
} \
} \
@@ -40,18 +43,22 @@ long load_elf(const char* fn, int* user64)
LOAD_ELF;
entry = eh->e_entry;
}
- else
+ else if(eh64->e_ident[EI_CLASS] == ELFCLASS64)
{
- kassert(eh64->e_ident[EI_CLASS] == ELFCLASS64);
Elf64_Ehdr* eh;
Elf64_Phdr* ph;
LOAD_ELF;
entry = eh->e_entry;
}
+ else
+ goto fail;
*user64 = eh64->e_ident[EI_CLASS] == ELFCLASS64;
file_decref(file);
return entry;
+
+fail:
+ panic("couldn't open ELF program: %s!", fn);
}
diff --git a/pk/file.c b/pk/file.c
index 3a465ad..cf370b5 100644
--- a/pk/file.c
+++ b/pk/file.c
@@ -5,9 +5,9 @@
#include "frontend.h"
#include "pcr.h"
-#define MAX_FDS 128
+#define MAX_FDS 32
file_t* fds[MAX_FDS];
-#define MAX_FILES 128
+#define MAX_FILES 32
file_t files[MAX_FILES] = {[0 ... MAX_FILES-1] = {-1,{0}}};
file_t *stdout, *stdin, *stderr;
@@ -69,15 +69,15 @@ void file_init()
stdin = file_get_free();
stdout = file_get_free();
stderr = file_get_free();
- kassert(stdin && stdout && stderr);
stdin->kfd = 0;
stdout->kfd = 1;
stderr->kfd = 2;
- kassert(file_dup(stdin) == 0);
- kassert(file_dup(stdout) == 1);
- kassert(file_dup(stderr) == 2);
+ // create user FDs 0, 1, and 2
+ file_dup(stdin);
+ file_dup(stdout);
+ file_dup(stderr);
}
file_t* file_get(int fd)
diff --git a/pk/fp.c b/pk/fp.c
index 7cc929b..794755d 100644
--- a/pk/fp.c
+++ b/pk/fp.c
@@ -65,15 +65,22 @@ int emulate_fp(trapframe_t* tf)
#define IS_INSN(x) ((tf->insn & MASK_ ## x) == MATCH_ ## x)
+ int do_writeback = 0;
+ int writeback_dp;
+ uint64_t writeback_value;
+ #define DO_WRITEBACK(dp, value) \
+ do { do_writeback = 1; writeback_dp = (dp); writeback_value = (value); } \
+ while(0)
+
if(IS_INSN(FLW))
{
validate_address(tf, effective_address_load, 4, 0);
- set_fp_reg(RRD, 0, *(uint32_t*)effective_address_load);
+ DO_WRITEBACK(0, *(uint32_t*)effective_address_load);
}
else if(IS_INSN(FLD))
{
validate_address(tf, effective_address_load, 8, 0);
- set_fp_reg(RRD, 1, *(uint64_t*)effective_address_load);
+ DO_WRITEBACK(1, *(uint64_t*)effective_address_load);
}
else if(IS_INSN(FSW))
{
@@ -90,89 +97,89 @@ int emulate_fp(trapframe_t* tf)
else if(IS_INSN(MFTX_D))
XRDR = frs2d;
else if(IS_INSN(MXTF_S))
- set_fp_reg(RRD, 0, XRS1);
+ DO_WRITEBACK(0, XRS1);
else if(IS_INSN(MXTF_D))
- set_fp_reg(RRD, 1, XRS1);
+ DO_WRITEBACK(1, XRS1);
else if(IS_INSN(FSGNJ_S))
- set_fp_reg(RRD, 0, (frs1s &~ (uint32_t)INT32_MIN) | (frs2s & (uint32_t)INT32_MIN));
+ DO_WRITEBACK(0, (frs1s &~ (uint32_t)INT32_MIN) | (frs2s & (uint32_t)INT32_MIN));
else if(IS_INSN(FSGNJ_D))
- set_fp_reg(RRD, 1, (frs1d &~ INT64_MIN) | (frs2d & INT64_MIN));
+ DO_WRITEBACK(1, (frs1d &~ INT64_MIN) | (frs2d & INT64_MIN));
else if(IS_INSN(FSGNJN_S))
- set_fp_reg(RRD, 0, (frs1s &~ (uint32_t)INT32_MIN) | ((~frs2s) & (uint32_t)INT32_MIN));
+ DO_WRITEBACK(0, (frs1s &~ (uint32_t)INT32_MIN) | ((~frs2s) & (uint32_t)INT32_MIN));
else if(IS_INSN(FSGNJN_D))
- set_fp_reg(RRD, 1, (frs1d &~ INT64_MIN) | ((~frs2d) & INT64_MIN));
+ DO_WRITEBACK(1, (frs1d &~ INT64_MIN) | ((~frs2d) & INT64_MIN));
else if(IS_INSN(FSGNJX_S))
- set_fp_reg(RRD, 0, frs1s ^ (frs2s & (uint32_t)INT32_MIN));
+ DO_WRITEBACK(0, frs1s ^ (frs2s & (uint32_t)INT32_MIN));
else if(IS_INSN(FSGNJX_D))
- set_fp_reg(RRD, 1, frs1d ^ (frs2d & INT64_MIN));
+ DO_WRITEBACK(1, frs1d ^ (frs2d & INT64_MIN));
else if(IS_INSN(FEQ_S))
XRDR = f32_eq(frs1s, frs2s);
else if(IS_INSN(FEQ_D))
XRDR = f64_eq(frs1d, frs2d);
else if(IS_INSN(FLE_S))
- XRDR = f32_le(frs1s, frs2s);
+ XRDR = f32_eq(frs1s, frs2s) || f32_lt(frs1s, frs2s);
else if(IS_INSN(FLE_D))
- XRDR = f64_le(frs1d, frs2d);
+ XRDR = f64_eq(frs1d, frs2d) || f64_lt(frs1s, frs2s);
else if(IS_INSN(FLT_S))
XRDR = f32_lt(frs1s, frs2s);
else if(IS_INSN(FLT_D))
XRDR = f64_lt(frs1d, frs2d);
else if(IS_INSN(FCVT_S_W))
- set_fp_reg(RRD, 0, i32_to_f32(XRS1));
+ DO_WRITEBACK(0, i64_to_f32((int64_t)(int32_t)XRS1));
else if(IS_INSN(FCVT_S_L))
- set_fp_reg(RRD, 0, i64_to_f32(XRS1));
+ DO_WRITEBACK(0, i64_to_f32(XRS1));
else if(IS_INSN(FCVT_S_D))
- set_fp_reg(RRD, 0, f64_to_f32(frs1d));
+ DO_WRITEBACK(0, f64_to_f32(frs1d));
else if(IS_INSN(FCVT_D_W))
- set_fp_reg(RRD, 1, i32_to_f64(XRS1));
+ DO_WRITEBACK(1, i64_to_f64((int64_t)(int32_t)XRS1));
else if(IS_INSN(FCVT_D_L))
- set_fp_reg(RRD, 1, i64_to_f64(XRS1));
+ DO_WRITEBACK(1, i64_to_f64(XRS1));
else if(IS_INSN(FCVT_D_S))
- set_fp_reg(RRD, 1, f32_to_f64(frs1s));
+ DO_WRITEBACK(1, f32_to_f64(frs1s));
else if(IS_INSN(FCVT_S_WU))
- set_fp_reg(RRD, 0, ui32_to_f32(XRS1));
+ DO_WRITEBACK(0, ui64_to_f32((uint64_t)(uint32_t)XRS1));
else if(IS_INSN(FCVT_S_LU))
- set_fp_reg(RRD, 0, ui64_to_f32(XRS1));
+ DO_WRITEBACK(0, ui64_to_f32(XRS1));
else if(IS_INSN(FCVT_D_WU))
- set_fp_reg(RRD, 1, ui32_to_f64(XRS1));
+ DO_WRITEBACK(1, ui64_to_f64((uint64_t)(uint32_t)XRS1));
else if(IS_INSN(FCVT_D_LU))
- set_fp_reg(RRD, 1, ui64_to_f64(XRS1));
+ DO_WRITEBACK(1, ui64_to_f64(XRS1));
else if(IS_INSN(FADD_S))
- set_fp_reg(RRD, 0, f32_add(frs1s, frs2s));
+ DO_WRITEBACK(0, f32_mulAdd(frs1s, 0x3f800000, frs2s));
else if(IS_INSN(FADD_D))
- set_fp_reg(RRD, 1, f64_add(frs1d, frs2d));
+ DO_WRITEBACK(1, f64_mulAdd(frs1d, 0x3ff0000000000000LL, frs2d));
else if(IS_INSN(FSUB_S))
- set_fp_reg(RRD, 0, f32_sub(frs1s, frs2s));
+ DO_WRITEBACK(0, f32_mulAdd(frs1s, 0x3f800000, frs2s ^ (uint32_t)INT32_MIN));
else if(IS_INSN(FSUB_D))
- set_fp_reg(RRD, 1, f64_sub(frs1d, frs2d));
+ DO_WRITEBACK(1, f64_mulAdd(frs1d, 0x3ff0000000000000LL, frs2d ^ INT64_MIN));
else if(IS_INSN(FMUL_S))
- set_fp_reg(RRD, 0, f32_mul(frs1s, frs2s));
+ DO_WRITEBACK(0, f32_mulAdd(frs1s, frs2s, 0));
else if(IS_INSN(FMUL_D))
- set_fp_reg(RRD, 1, f64_mul(frs1d, frs2d));
+ DO_WRITEBACK(1, f64_mulAdd(frs1d, frs2d, 0));
else if(IS_INSN(FMADD_S))
- set_fp_reg(RRD, 0, f32_mulAdd(frs1s, frs2s, frs3s));
+ DO_WRITEBACK(0, f32_mulAdd(frs1s, frs2s, frs3s));
else if(IS_INSN(FMADD_D))
- set_fp_reg(RRD, 1, f64_mulAdd(frs1d, frs2d, frs3d));
+ DO_WRITEBACK(1, f64_mulAdd(frs1d, frs2d, frs3d));
else if(IS_INSN(FMSUB_S))
- set_fp_reg(RRD, 0, f32_mulAdd(frs1s, frs2s, frs3s ^ (uint32_t)INT32_MIN));
+ DO_WRITEBACK(0, f32_mulAdd(frs1s, frs2s, frs3s ^ (uint32_t)INT32_MIN));
else if(IS_INSN(FMSUB_D))
- set_fp_reg(RRD, 1, f64_mulAdd(frs1d, frs2d, frs3d ^ INT64_MIN));
+ DO_WRITEBACK(1, f64_mulAdd(frs1d, frs2d, frs3d ^ INT64_MIN));
else if(IS_INSN(FNMADD_S))
- set_fp_reg(RRD, 0, f32_mulAdd(frs1s, frs2s, frs3s) ^ (uint32_t)INT32_MIN);
+ DO_WRITEBACK(0, f32_mulAdd(frs1s, frs2s, frs3s) ^ (uint32_t)INT32_MIN);
else if(IS_INSN(FNMADD_D))
- set_fp_reg(RRD, 1, f64_mulAdd(frs1d, frs2d, frs3d) ^ INT64_MIN);
+ DO_WRITEBACK(1, f64_mulAdd(frs1d, frs2d, frs3d) ^ INT64_MIN);
else if(IS_INSN(FNMSUB_S))
- set_fp_reg(RRD, 0, f32_mulAdd(frs1s, frs2s, frs3s ^ (uint32_t)INT32_MIN) ^ (uint32_t)INT32_MIN);
+ DO_WRITEBACK(0, f32_mulAdd(frs1s, frs2s, frs3s ^ (uint32_t)INT32_MIN) ^ (uint32_t)INT32_MIN);
else if(IS_INSN(FNMSUB_D))
- set_fp_reg(RRD, 1, f64_mulAdd(frs1d, frs2d, frs3d ^ INT64_MIN) ^ INT64_MIN);
+ DO_WRITEBACK(1, f64_mulAdd(frs1d, frs2d, frs3d ^ INT64_MIN) ^ INT64_MIN);
else if(IS_INSN(FDIV_S))
- set_fp_reg(RRD, 0, f32_div(frs1s, frs2s));
+ DO_WRITEBACK(0, f32_div(frs1s, frs2s));
else if(IS_INSN(FDIV_D))
- set_fp_reg(RRD, 1, f64_div(frs1d, frs2d));
+ DO_WRITEBACK(1, f64_div(frs1d, frs2d));
else if(IS_INSN(FSQRT_S))
- set_fp_reg(RRD, 0, f32_sqrt(frs1s));
+ DO_WRITEBACK(0, f32_sqrt(frs1s));
else if(IS_INSN(FSQRT_D))
- set_fp_reg(RRD, 1, f64_sqrt(frs1d));
+ DO_WRITEBACK(1, f64_sqrt(frs1d));
else if(IS_INSN(FCVT_W_S))
XRDR = f32_to_i32_r_minMag(frs1s,true);
else if(IS_INSN(FCVT_W_D))
@@ -192,6 +199,9 @@ int emulate_fp(trapframe_t* tf)
else
return -1;
+ if(do_writeback)
+ set_fp_reg(RRD, writeback_dp, writeback_value);
+
if(have_fp)
put_fp_state(fp_state.fpr,fp_state.fsr);
diff --git a/pk/syscall.c b/pk/syscall.c
index 9482378..85c853b 100644
--- a/pk/syscall.c
+++ b/pk/syscall.c
@@ -2,6 +2,7 @@
#include <string.h>
#include <errno.h>
#include "pk.h"
+#include "pcr.h"
#include "file.h"
#include "frontend.h"
@@ -92,6 +93,13 @@ sysret_t sys_unlink(const char* name, size_t len)
return frontend_syscall(SYS_unlink,(long)name,len,0,0);
}
+sysret_t sys_brk(size_t pos)
+{
+ if(pos > (mfpcr(PCR_MEMSIZE) << MEMSIZE_SHIFT))
+ return (sysret_t){-1, ENOMEM};
+ return (sysret_t){0,0};
+}
+
sysret_t syscall(long a0, long a1, long a2, long a3, long n)
{
const static void* syscall_table[] = {
@@ -106,6 +114,7 @@ sysret_t syscall(long a0, long a1, long a2, long a3, long n)
[SYS_lstat] = sys_lstat,
[SYS_link] = sys_link,
[SYS_unlink] = sys_unlink,
+ [SYS_brk] = sys_brk,
};
if(n >= ARRAY_SIZE(syscall_table) || !syscall_table[n])