diff options
Diffstat (limited to 'm68k-semi.c')
-rw-r--r-- | m68k-semi.c | 116 |
1 files changed, 82 insertions, 34 deletions
diff --git a/m68k-semi.c b/m68k-semi.c index fc033a163..b083b4828 100644 --- a/m68k-semi.c +++ b/m68k-semi.c @@ -33,7 +33,9 @@ #include "qemu.h" #define SEMIHOSTING_HEAP_SIZE (128 * 1024 * 1024) #else -#include "vl.h" +#include "qemu-common.h" +#include "sysemu.h" +#include "gdbstub.h" #include "softmmu-semi.h" #endif @@ -107,7 +109,9 @@ static void translate_stat(CPUState *env, target_ulong addr, struct stat *s) { struct m68k_gdb_stat *p; - p = lock_user(addr, sizeof(struct m68k_gdb_stat), 0); + if (!(p = lock_user(VERIFY_WRITE, addr, sizeof(struct m68k_gdb_stat), 0))) + /* FIXME - should this return an error code? */ + return; p->gdb_st_dev = cpu_to_be32(s->st_dev); p->gdb_st_ino = cpu_to_be32(s->st_ino); p->gdb_st_mode = cpu_to_be32(s->st_mode); @@ -140,15 +144,23 @@ static void m68k_semi_cb(CPUState *env, target_ulong ret, target_ulong err) if (m68k_semi_is_fseek) { /* FIXME: We've already lost the high bits of the fseek return value. */ - tput32(args, 0); + /* FIXME - handle put_user() failure */ + put_user_u32(0, args); args += 4; m68k_semi_is_fseek = 0; } - tput32(args, ret); - tput32(args + 4, errno); + /* FIXME - handle put_user() failure */ + put_user_u32(ret, args); + put_user_u32(errno, args + 4); } -#define ARG(x) tget32(args + (x) * 4) +#define ARG(n) \ +({ \ + target_ulong __arg; \ + /* FIXME - handle get_user() failure */ \ + get_user_ual(__arg, args + (n) * 4); \ + __arg; \ +}) #define PARG(x) ((unsigned long)ARG(x)) void do_m68k_semihosting(CPUM68KState *env, int nr) { @@ -168,9 +180,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) ARG(2), ARG(3)); return; } else { - p = lock_user_string(ARG(0)); - result = open(p, translate_openflags(ARG(2)), ARG(3)); - unlock_user(p, ARG(0), 0); + if (!(p = lock_user_string(ARG(0)))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = open(p, translate_openflags(ARG(2)), ARG(3)); + unlock_user(p, ARG(0), 0); + } } break; case HOSTED_CLOSE: @@ -196,9 +212,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) ARG(0), ARG(1), len); return; } else { - p = lock_user(ARG(1), len, 0); - result = read(ARG(0), p, len); - unlock_user(p, ARG(1), len); + if (!(p = lock_user(VERIFY_WRITE, ARG(1), len, 0))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = read(ARG(0), p, len); + unlock_user(p, ARG(1), len); + } } break; case HOSTED_WRITE: @@ -208,9 +228,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) ARG(0), ARG(1), len); return; } else { - p = lock_user(ARG(1), len, 1); - result = write(ARG(0), p, len); - unlock_user(p, ARG(0), 0); + if (!(p = lock_user(VERIFY_READ, ARG(1), len, 1))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = write(ARG(0), p, len); + unlock_user(p, ARG(0), 0); + } } break; case HOSTED_LSEEK: @@ -223,9 +247,10 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) ARG(0), off, ARG(3)); } else { off = lseek(ARG(0), off, ARG(3)); - tput32(args, off >> 32); - tput32(args + 4, off); - tput32(args + 8, errno); + /* FIXME - handle put_user() failure */ + put_user_u32(off >> 32, args); + put_user_u32(off, args + 4); + put_user_u32(errno, args + 8); } return; } @@ -237,7 +262,12 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) } else { p = lock_user_string(ARG(0)); q = lock_user_string(ARG(2)); - result = rename(p, q); + if (!p || !q) { + /* FIXME - check error code? */ + result = -1; + } else { + result = rename(p, q); + } unlock_user(p, ARG(0), 0); unlock_user(q, ARG(2), 0); } @@ -248,9 +278,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) ARG(0), (int)ARG(1)); return; } else { - p = lock_user_string(ARG(0)); - result = unlink(p); - unlock_user(p, ARG(0), 0); + if (!(p = lock_user_string(ARG(0)))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = unlink(p); + unlock_user(p, ARG(0), 0); + } } break; case HOSTED_STAT: @@ -260,9 +294,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) return; } else { struct stat s; - p = lock_user_string(ARG(0)); - result = stat(p, &s); - unlock_user(p, ARG(0), 0); + if (!(p = lock_user_string(ARG(0)))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = stat(p, &s); + unlock_user(p, ARG(0), 0); + } if (result == 0) { translate_stat(env, ARG(2), &s); } @@ -291,10 +329,15 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) struct gdb_timeval *p; result = qemu_gettimeofday(&tv); if (result != 0) { - p = lock_user(ARG(0), sizeof(struct gdb_timeval), 0); - p->tv_sec = cpu_to_be32(tv.tv_sec); - p->tv_usec = cpu_to_be64(tv.tv_usec); - unlock_user(p, ARG(0), sizeof(struct gdb_timeval)); + if (!(p = lock_user(VERIFY_WRITE, + ARG(0), sizeof(struct gdb_timeval), 0))) { + /* FIXME - check error code? */ + result = -1; + } else { + p->tv_sec = cpu_to_be32(tv.tv_sec); + p->tv_usec = cpu_to_be64(tv.tv_usec); + unlock_user(p, ARG(0), sizeof(struct gdb_timeval)); + } } } break; @@ -312,9 +355,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) ARG(0), (int)ARG(1)); return; } else { - p = lock_user_string(ARG(0)); - result = system(p); - unlock_user(p, ARG(0), 0); + if (!(p = lock_user_string(ARG(0)))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = system(p); + unlock_user(p, ARG(0), 0); + } } break; case HOSTED_INIT_SIM: @@ -354,6 +401,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) cpu_abort(env, "Unsupported semihosting syscall %d\n", nr); result = 0; } - tput32(args, result); - tput32(args + 4, errno); + /* FIXME - handle put_user() failure */ + put_user_u32(result, args); + put_user_u32(errno, args + 4); } |