/*
* m68k/ColdFire Semihosting syscall interface
- *
+ *
* Copyright (c) 2005-2007 CodeSourcery.
*
* This program is free software; you can redistribute it and/or modify
* GNU General Public License for more details.
*
* 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.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#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
{
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);
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)
{
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:
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:
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:
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);
}
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:
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);
}
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;
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:
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);
}