diff options
author | Andrew Waterman <waterman@s144.Millennium.Berkeley.EDU> | 2011-05-19 15:28:26 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@s144.Millennium.Berkeley.EDU> | 2011-05-19 15:28:26 -0700 |
commit | be22e4abd5fd8dad83068744a0d1497d50a2806c (patch) | |
tree | 41e7e210dd9f8e0dc35b7da36eb4f483d19734f7 /pk | |
parent | 92a8f05f5a2081deb086ad478c3ecbfd4e649002 (diff) | |
download | pk-be22e4abd5fd8dad83068744a0d1497d50a2806c.zip pk-be22e4abd5fd8dad83068744a0d1497d50a2806c.tar.gz pk-be22e4abd5fd8dad83068744a0d1497d50a2806c.tar.bz2 |
[pk] made PK smaller
Diffstat (limited to 'pk')
-rw-r--r-- | pk/elf.c | 21 | ||||
-rw-r--r-- | pk/file.c | 12 | ||||
-rw-r--r-- | pk/fp.c | 90 | ||||
-rw-r--r-- | pk/syscall.c | 9 |
4 files changed, 79 insertions, 53 deletions
@@ -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); } @@ -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) @@ -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]) |