X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=m68k-semi.c;h=3c76995151d5ce1c66d51f3b0b8c1c8075844905;hb=d33a1810d7f558dd1d486bc84f1cf8f96c982e2d;hp=27bdce8e2fb7f673822dbcc20b547b44cdf8f70d;hpb=a87295e8df0923dab9857c1a340d23fe3278a336;p=qemu diff --git a/m68k-semi.c b/m68k-semi.c index 27bdce8..3c76995 100644 --- a/m68k-semi.c +++ b/m68k-semi.c @@ -1,6 +1,6 @@ /* * m68k/ColdFire Semihosting syscall interface - * + * * Copyright (c) 2005-2007 CodeSourcery. * * This program is free software; you can redistribute it and/or modify @@ -15,7 +15,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 @@ #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 +110,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); @@ -116,8 +121,14 @@ static void translate_stat(CPUState *env, target_ulong addr, struct stat *s) p->gdb_st_gid = cpu_to_be32(s->st_gid); p->gdb_st_rdev = cpu_to_be32(s->st_rdev); p->gdb_st_size = cpu_to_be64(s->st_size); +#ifdef _WIN32 + /* Windows stat is missing some fields. */ + p->gdb_st_blksize = 0; + p->gdb_st_blocks = 0; +#else p->gdb_st_blksize = cpu_to_be64(s->st_blksize); p->gdb_st_blocks = cpu_to_be64(s->st_blocks); +#endif p->gdb_st_atime = cpu_to_be32(s->st_atime); p->gdb_st_mtime = cpu_to_be32(s->st_mtime); p->gdb_st_ctime = cpu_to_be32(s->st_ctime); @@ -134,15 +145,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) { @@ -162,9 +181,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: @@ -190,9 +213,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: @@ -202,9 +229,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: @@ -217,21 +248,27 @@ 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; } case HOSTED_RENAME: if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "rename,%s,%s", + gdb_do_syscall(m68k_semi_cb, "rename,%s,%s", ARG(0), (int)ARG(1), ARG(2), (int)ARG(3)); return; } 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); } @@ -242,9 +279,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: @@ -254,9 +295,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); } @@ -281,14 +326,19 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) ARG(0), ARG(1)); return; } else { - struct timeval tv; + qemu_timeval tv; struct gdb_timeval *p; - result = gettimeofday(&tv, NULL); + 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; @@ -306,9 +356,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: @@ -348,6 +402,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); }