diff options
-rw-r--r-- | hw/semihosting/arm-compat-semi.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/hw/semihosting/arm-compat-semi.c b/hw/semihosting/arm-compat-semi.c index 3d6604dcdd..a631904fb0 100644 --- a/hw/semihosting/arm-compat-semi.c +++ b/hw/semihosting/arm-compat-semi.c @@ -835,6 +835,7 @@ target_ulong do_common_semihosting(CPUState *cs) CPUArchState *env = cs->env_ptr; target_ulong args; target_ulong arg0, arg1, arg2, arg3; + target_ulong ul_ret; char * s; int nr; uint32_t ret; @@ -998,8 +999,24 @@ target_ulong do_common_semihosting(CPUState *cs) return guestfd_fns[gf->type].flenfn(cs, gf); case TARGET_SYS_TMPNAM: - qemu_log_mask(LOG_UNIMP, "%s: SYS_TMPNAM not implemented", __func__); - return -1; + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + if (asprintf(&s, "/tmp/qemu-%x%02x", getpid(), + (int) (arg1 & 0xff)) < 0) { + return -1; + } + ul_ret = (target_ulong) -1; + + /* Make sure there's enough space in the buffer */ + if (strlen(s) < arg2) { + char *output = lock_user(VERIFY_WRITE, arg0, arg2, 0); + strcpy(output, s); + unlock_user(output, arg0, arg2); + ul_ret = 0; + } + free(s); + return ul_ret; case TARGET_SYS_REMOVE: GET_ARG(0); GET_ARG(1); |