target/mips: Avoid qemu_semihosting_log_out for UHI_plog

Use semihost_sys_write and/or qemu_semihosting_console_write
for implementing plog.  When using gdbstub, copy the temp
string below the stack so that gdb has a guest address from
which to perform the log.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20220628111701.677216-5-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
This commit is contained in:
Richard Henderson 2022-06-28 16:46:57 +05:30 committed by Philippe Mathieu-Daudé
parent 18639a28bb
commit ea4210600d
1 changed files with 41 additions and 11 deletions

View File

@ -310,20 +310,50 @@ void mips_semihosting(CPUMIPSState *env)
}
gpr[2] = copy_argn_to_target(env, gpr[4], gpr[5]);
break;
case UHI_plog:
GET_TARGET_STRING(p, gpr[4]);
p2 = strstr(p, "%d");
if (p2) {
int char_num = p2 - p;
GString *s = g_string_new_len(p, char_num);
g_string_append_printf(s, "%d%s", (int)gpr[5], p2 + 2);
gpr[2] = qemu_semihosting_log_out(s->str, s->len);
g_string_free(s, true);
} else {
gpr[2] = qemu_semihosting_log_out(p, strlen(p));
{
target_ulong addr = gpr[4];
ssize_t len = target_strlen(addr);
GString *str;
char *pct_d;
if (len < 0) {
report_fault(env);
}
p = lock_user(VERIFY_READ, addr, len, 1);
if (!p) {
report_fault(env);
}
pct_d = strstr(p, "%d");
if (!pct_d) {
FREE_TARGET_STRING(p, addr);
semihost_sys_write(cs, uhi_cb, 2, addr, len);
break;
}
str = g_string_new_len(p, pct_d - p);
g_string_append_printf(str, "%d%s", (int)gpr[5], pct_d + 2);
FREE_TARGET_STRING(p, addr);
/*
* When we're using gdb, we need a guest address, so
* drop the string onto the stack below the stack pointer.
*/
if (use_gdb_syscalls()) {
addr = gpr[29] - str->len;
p = lock_user(VERIFY_WRITE, addr, str->len, 0);
memcpy(p, str->str, str->len);
unlock_user(p, addr, str->len);
semihost_sys_write(cs, uhi_cb, 2, addr, str->len);
} else {
gpr[2] = qemu_semihosting_console_write(str->str, str->len);
}
g_string_free(str, true);
}
FREE_TARGET_STRING(p, gpr[4]);
break;
case UHI_assert:
GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
printf("assertion '");