X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=arm-semi.c;h=a33b8e5c3a924e9af70dd0e1fa826694bf351f92;hb=bf9b48af99a75a1f7d76c8b3d92a82a0a41cb707;hp=aaad1c99f82280c83cd657eaa988eb9c8c9b8559;hpb=33d9cc8a9691157fd99b681a5122f734522fc63a;p=qemu diff --git a/arm-semi.c b/arm-semi.c index aaad1c9..a33b8e5 100644 --- a/arm-semi.c +++ b/arm-semi.c @@ -1,6 +1,6 @@ /* * Arm "Angel" semihosting syscalls - * + * * Copyright (c) 2005, 2007 CodeSourcery. * Written by Paul Brook. * @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + * MA 02110-1301, USA. */ #include @@ -33,7 +34,9 @@ #define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024) #else -#include "vl.h" +#include "qemu-common.h" +#include "sysemu.h" +#include "gdbstub.h" #endif #define SYS_OPEN 0x01 @@ -165,8 +168,14 @@ static void arm_semi_flen_cb(CPUState *env, target_ulong ret, target_ulong err) #endif } -#define ARG(n) tget32(args + (n) * 4) -#define SET_ARG(n, val) tput32(args + (n) * 4,val) +#define ARG(n) \ +({ \ + target_ulong __arg; \ + /* FIXME - handle get_user() failure */ \ + get_user_ual(__arg, args + (n) * 4); \ + __arg; \ +}) +#define SET_ARG(n, val) put_user_ual(val, args + (n) * 4) uint32_t do_arm_semihosting(CPUState *env) { target_ulong args; @@ -184,9 +193,11 @@ uint32_t do_arm_semihosting(CPUState *env) args = env->regs[1]; switch (nr) { case SYS_OPEN: - s = lock_user_string(ARG(0)); + if (!(s = lock_user_string(ARG(0)))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; if (ARG(1) >= 12) - return (uint32_t)-1; + return (uint32_t)-1; if (strcmp(s, ":tt") == 0) { if (ARG(1) < 4) return STDIN_FILENO; @@ -194,7 +205,7 @@ uint32_t do_arm_semihosting(CPUState *env) return STDOUT_FILENO; } if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0), + gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0), (int)ARG(2)+1, gdb_open_modeflags[ARG(1)]); return env->regs[0]; } else { @@ -211,7 +222,11 @@ uint32_t do_arm_semihosting(CPUState *env) } case SYS_WRITEC: { - char c = tget8(args); + char c; + + if (get_user_u8(c, args)) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; /* Write to debug console. stderr is near enough. */ if (use_gdb_syscalls()) { gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args); @@ -221,7 +236,9 @@ uint32_t do_arm_semihosting(CPUState *env) } } case SYS_WRITE0: - s = lock_user_string(args); + if (!(s = lock_user_string(args))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; len = strlen(s); if (use_gdb_syscalls()) { gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len); @@ -238,7 +255,9 @@ uint32_t do_arm_semihosting(CPUState *env) gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len); return env->regs[0]; } else { - s = lock_user(ARG(1), len, 1); + if (!(s = lock_user(VERIFY_READ, ARG(1), len, 1))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; ret = set_swi_errno(ts, write(ARG(0), s, len)); unlock_user(s, ARG(1), 0); if (ret == (uint32_t)-1) @@ -252,7 +271,9 @@ uint32_t do_arm_semihosting(CPUState *env) gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len); return env->regs[0]; } else { - s = lock_user(ARG(1), len, 0); + if (!(s = lock_user(VERIFY_WRITE, ARG(1), len, 0))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; do ret = set_swi_errno(ts, read(ARG(0), s, len)); while (ret == -1 && errno == EINTR); @@ -283,7 +304,7 @@ uint32_t do_arm_semihosting(CPUState *env) } case SYS_FLEN: if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x", + gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x", ARG(0), env->regs[13]-64); return env->regs[0]; } else { @@ -301,7 +322,9 @@ uint32_t do_arm_semihosting(CPUState *env) gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1); ret = env->regs[0]; } else { - s = lock_user_string(ARG(0)); + if (!(s = lock_user_string(ARG(0)))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; ret = set_swi_errno(ts, remove(s)); unlock_user(s, ARG(0), 0); } @@ -315,9 +338,15 @@ uint32_t do_arm_semihosting(CPUState *env) char *s2; s = lock_user_string(ARG(0)); s2 = lock_user_string(ARG(2)); - ret = set_swi_errno(ts, rename(s, s2)); - unlock_user(s2, ARG(2), 0); - unlock_user(s, ARG(0), 0); + if (!s || !s2) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + ret = (uint32_t)-1; + else + ret = set_swi_errno(ts, rename(s, s2)); + if (s2) + unlock_user(s2, ARG(2), 0); + if (s) + unlock_user(s, ARG(0), 0); return ret; } case SYS_CLOCK: @@ -329,9 +358,12 @@ uint32_t do_arm_semihosting(CPUState *env) gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1); return env->regs[0]; } else { - s = lock_user_string(ARG(0)); + if (!(s = lock_user_string(ARG(0)))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; ret = set_swi_errno(ts, system(s)); unlock_user(s, ARG(0), 0); + return ret; } case SYS_ERRNO: #ifdef CONFIG_USER_ONLY @@ -346,7 +378,11 @@ uint32_t do_arm_semihosting(CPUState *env) char **arg = ts->info->host_argv; int len = ARG(1); /* lock the buffer on the ARM side */ - char *cmdline_buffer = (char*)lock_user(ARG(0), len, 0); + char *cmdline_buffer = (char*)lock_user(VERIFY_WRITE, ARG(0), len, 0); + + if (!cmdline_buffer) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; s = cmdline_buffer; while (*arg && len > 2) { @@ -401,8 +437,10 @@ uint32_t do_arm_semihosting(CPUState *env) } ts->heap_limit = limit; } - - ptr = lock_user(ARG(0), 16, 0); + + if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; ptr[0] = tswap32(ts->heap_base); ptr[1] = tswap32(ts->heap_limit); ptr[2] = tswap32(ts->stack_base); @@ -410,7 +448,9 @@ uint32_t do_arm_semihosting(CPUState *env) unlock_user(ptr, ARG(0), 16); #else limit = ram_size; - ptr = lock_user(ARG(0), 16, 0); + if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; /* TODO: Make this use the limit of the loaded application. */ ptr[0] = tswap32(limit / 2); ptr[1] = tswap32(limit);