xref: /qemu/target/mips/tcg/sysemu/mips-semi.c (revision b10ccec1)
1ad520a97SPhilippe Mathieu-Daudé /*
2ad520a97SPhilippe Mathieu-Daudé  * Unified Hosting Interface syscalls.
3ad520a97SPhilippe Mathieu-Daudé  *
4ad520a97SPhilippe Mathieu-Daudé  * Copyright (c) 2015 Imagination Technologies
5ad520a97SPhilippe Mathieu-Daudé  *
6ad520a97SPhilippe Mathieu-Daudé  * This library is free software; you can redistribute it and/or
7ad520a97SPhilippe Mathieu-Daudé  * modify it under the terms of the GNU Lesser General Public
8ad520a97SPhilippe Mathieu-Daudé  * License as published by the Free Software Foundation; either
9ad520a97SPhilippe Mathieu-Daudé  * version 2.1 of the License, or (at your option) any later version.
10ad520a97SPhilippe Mathieu-Daudé  *
11ad520a97SPhilippe Mathieu-Daudé  * This library is distributed in the hope that it will be useful,
12ad520a97SPhilippe Mathieu-Daudé  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13ad520a97SPhilippe Mathieu-Daudé  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14ad520a97SPhilippe Mathieu-Daudé  * Lesser General Public License for more details.
15ad520a97SPhilippe Mathieu-Daudé  *
16ad520a97SPhilippe Mathieu-Daudé  * You should have received a copy of the GNU Lesser General Public
17ad520a97SPhilippe Mathieu-Daudé  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18ad520a97SPhilippe Mathieu-Daudé  */
19ad520a97SPhilippe Mathieu-Daudé 
20ad520a97SPhilippe Mathieu-Daudé #include "qemu/osdep.h"
21ad520a97SPhilippe Mathieu-Daudé #include "cpu.h"
22ad520a97SPhilippe Mathieu-Daudé #include "qemu/log.h"
2318639a28SRichard Henderson #include "exec/gdbstub.h"
24c89a14adSRichard Henderson #include "semihosting/softmmu-uaccess.h"
25ad520a97SPhilippe Mathieu-Daudé #include "semihosting/semihost.h"
26ad520a97SPhilippe Mathieu-Daudé #include "semihosting/console.h"
2718639a28SRichard Henderson #include "semihosting/syscalls.h"
288ec7e3c5SRichard Henderson #include "internal.h"
29ad520a97SPhilippe Mathieu-Daudé 
30ad520a97SPhilippe Mathieu-Daudé typedef enum UHIOp {
31ad520a97SPhilippe Mathieu-Daudé     UHI_exit = 1,
32ad520a97SPhilippe Mathieu-Daudé     UHI_open = 2,
33ad520a97SPhilippe Mathieu-Daudé     UHI_close = 3,
34ad520a97SPhilippe Mathieu-Daudé     UHI_read = 4,
35ad520a97SPhilippe Mathieu-Daudé     UHI_write = 5,
36ad520a97SPhilippe Mathieu-Daudé     UHI_lseek = 6,
37ad520a97SPhilippe Mathieu-Daudé     UHI_unlink = 7,
38ad520a97SPhilippe Mathieu-Daudé     UHI_fstat = 8,
39ad520a97SPhilippe Mathieu-Daudé     UHI_argc = 9,
40ad520a97SPhilippe Mathieu-Daudé     UHI_argnlen = 10,
41ad520a97SPhilippe Mathieu-Daudé     UHI_argn = 11,
42ad520a97SPhilippe Mathieu-Daudé     UHI_plog = 13,
43ad520a97SPhilippe Mathieu-Daudé     UHI_assert = 14,
44ad520a97SPhilippe Mathieu-Daudé     UHI_pread = 19,
45ad520a97SPhilippe Mathieu-Daudé     UHI_pwrite = 20,
46ad520a97SPhilippe Mathieu-Daudé     UHI_link = 22
47ad520a97SPhilippe Mathieu-Daudé } UHIOp;
48ad520a97SPhilippe Mathieu-Daudé 
49ad520a97SPhilippe Mathieu-Daudé typedef struct UHIStat {
50ad520a97SPhilippe Mathieu-Daudé     int16_t uhi_st_dev;
51ad520a97SPhilippe Mathieu-Daudé     uint16_t uhi_st_ino;
52ad520a97SPhilippe Mathieu-Daudé     uint32_t uhi_st_mode;
53ad520a97SPhilippe Mathieu-Daudé     uint16_t uhi_st_nlink;
54ad520a97SPhilippe Mathieu-Daudé     uint16_t uhi_st_uid;
55ad520a97SPhilippe Mathieu-Daudé     uint16_t uhi_st_gid;
56ad520a97SPhilippe Mathieu-Daudé     int16_t uhi_st_rdev;
57ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_size;
58ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_atime;
59ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_spare1;
60ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_mtime;
61ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_spare2;
62ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_ctime;
63ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_spare3;
64ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_blksize;
65ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_blocks;
66ad520a97SPhilippe Mathieu-Daudé     uint64_t uhi_st_spare4[2];
67ad520a97SPhilippe Mathieu-Daudé } UHIStat;
68ad520a97SPhilippe Mathieu-Daudé 
69ad520a97SPhilippe Mathieu-Daudé enum UHIOpenFlags {
70ad520a97SPhilippe Mathieu-Daudé     UHIOpen_RDONLY = 0x0,
71ad520a97SPhilippe Mathieu-Daudé     UHIOpen_WRONLY = 0x1,
72ad520a97SPhilippe Mathieu-Daudé     UHIOpen_RDWR   = 0x2,
73ad520a97SPhilippe Mathieu-Daudé     UHIOpen_APPEND = 0x8,
74ad520a97SPhilippe Mathieu-Daudé     UHIOpen_CREAT  = 0x200,
75ad520a97SPhilippe Mathieu-Daudé     UHIOpen_TRUNC  = 0x400,
76ad520a97SPhilippe Mathieu-Daudé     UHIOpen_EXCL   = 0x800
77ad520a97SPhilippe Mathieu-Daudé };
78ad520a97SPhilippe Mathieu-Daudé 
797ba6e53aSRichard Henderson enum UHIErrno {
807ba6e53aSRichard Henderson     UHI_EACCESS         = 13,
817ba6e53aSRichard Henderson     UHI_EAGAIN          = 11,
827ba6e53aSRichard Henderson     UHI_EBADF           = 9,
837ba6e53aSRichard Henderson     UHI_EBADMSG         = 77,
847ba6e53aSRichard Henderson     UHI_EBUSY           = 16,
857ba6e53aSRichard Henderson     UHI_ECONNRESET      = 104,
867ba6e53aSRichard Henderson     UHI_EEXIST          = 17,
877ba6e53aSRichard Henderson     UHI_EFBIG           = 27,
887ba6e53aSRichard Henderson     UHI_EINTR           = 4,
897ba6e53aSRichard Henderson     UHI_EINVAL          = 22,
907ba6e53aSRichard Henderson     UHI_EIO             = 5,
917ba6e53aSRichard Henderson     UHI_EISDIR          = 21,
927ba6e53aSRichard Henderson     UHI_ELOOP           = 92,
937ba6e53aSRichard Henderson     UHI_EMFILE          = 24,
947ba6e53aSRichard Henderson     UHI_EMLINK          = 31,
957ba6e53aSRichard Henderson     UHI_ENAMETOOLONG    = 91,
967ba6e53aSRichard Henderson     UHI_ENETDOWN        = 115,
977ba6e53aSRichard Henderson     UHI_ENETUNREACH     = 114,
987ba6e53aSRichard Henderson     UHI_ENFILE          = 23,
997ba6e53aSRichard Henderson     UHI_ENOBUFS         = 105,
1007ba6e53aSRichard Henderson     UHI_ENOENT          = 2,
1017ba6e53aSRichard Henderson     UHI_ENOMEM          = 12,
1027ba6e53aSRichard Henderson     UHI_ENOSPC          = 28,
1037ba6e53aSRichard Henderson     UHI_ENOSR           = 63,
1047ba6e53aSRichard Henderson     UHI_ENOTCONN        = 128,
1057ba6e53aSRichard Henderson     UHI_ENOTDIR         = 20,
1067ba6e53aSRichard Henderson     UHI_ENXIO           = 6,
1077ba6e53aSRichard Henderson     UHI_EOVERFLOW       = 139,
1087ba6e53aSRichard Henderson     UHI_EPERM           = 1,
1097ba6e53aSRichard Henderson     UHI_EPIPE           = 32,
1107ba6e53aSRichard Henderson     UHI_ERANGE          = 34,
1117ba6e53aSRichard Henderson     UHI_EROFS           = 30,
1127ba6e53aSRichard Henderson     UHI_ESPIPE          = 29,
1137ba6e53aSRichard Henderson     UHI_ETIMEDOUT       = 116,
1147ba6e53aSRichard Henderson     UHI_ETXTBSY         = 26,
1157ba6e53aSRichard Henderson     UHI_EWOULDBLOCK     = 11,
1167ba6e53aSRichard Henderson     UHI_EXDEV           = 18,
1177ba6e53aSRichard Henderson };
1187ba6e53aSRichard Henderson 
119d53a3ed4SRichard Henderson static void report_fault(CPUMIPSState *env)
120d53a3ed4SRichard Henderson {
121d53a3ed4SRichard Henderson     int op = env->active_tc.gpr[25];
122d53a3ed4SRichard Henderson     error_report("Fault during UHI operation %d", op);
123d53a3ed4SRichard Henderson     abort();
124d53a3ed4SRichard Henderson }
125d53a3ed4SRichard Henderson 
12618639a28SRichard Henderson static void uhi_cb(CPUState *cs, uint64_t ret, int err)
127d859a77dSPhilippe Mathieu-Daudé {
12818639a28SRichard Henderson     CPUMIPSState *env = cs->env_ptr;
12918639a28SRichard Henderson 
13018639a28SRichard Henderson #define E(N) case E##N: err = UHI_E##N; break
13118639a28SRichard Henderson 
13218639a28SRichard Henderson     switch (err) {
13318639a28SRichard Henderson     case 0:
13418639a28SRichard Henderson         break;
13518639a28SRichard Henderson     E(PERM);
13618639a28SRichard Henderson     E(NOENT);
13718639a28SRichard Henderson     E(INTR);
13818639a28SRichard Henderson     E(BADF);
13918639a28SRichard Henderson     E(BUSY);
14018639a28SRichard Henderson     E(EXIST);
14118639a28SRichard Henderson     E(NOTDIR);
14218639a28SRichard Henderson     E(ISDIR);
14318639a28SRichard Henderson     E(INVAL);
14418639a28SRichard Henderson     E(NFILE);
14518639a28SRichard Henderson     E(MFILE);
14618639a28SRichard Henderson     E(FBIG);
14718639a28SRichard Henderson     E(NOSPC);
14818639a28SRichard Henderson     E(SPIPE);
14918639a28SRichard Henderson     E(ROFS);
15018639a28SRichard Henderson     E(NAMETOOLONG);
15118639a28SRichard Henderson     default:
15218639a28SRichard Henderson         err = UHI_EINVAL;
15318639a28SRichard Henderson         break;
15418639a28SRichard Henderson     case EFAULT:
15518639a28SRichard Henderson         report_fault(env);
156ad520a97SPhilippe Mathieu-Daudé     }
157ad520a97SPhilippe Mathieu-Daudé 
15818639a28SRichard Henderson #undef E
15918639a28SRichard Henderson 
16018639a28SRichard Henderson     env->active_tc.gpr[2] = ret;
16118639a28SRichard Henderson     env->active_tc.gpr[3] = err;
16218639a28SRichard Henderson }
16318639a28SRichard Henderson 
16418639a28SRichard Henderson static void uhi_fstat_cb(CPUState *cs, uint64_t ret, int err)
165ad520a97SPhilippe Mathieu-Daudé {
16618639a28SRichard Henderson     QEMU_BUILD_BUG_ON(sizeof(UHIStat) < sizeof(struct gdb_stat));
16718639a28SRichard Henderson 
16818639a28SRichard Henderson     if (!err) {
16918639a28SRichard Henderson         CPUMIPSState *env = cs->env_ptr;
17018639a28SRichard Henderson         target_ulong addr = env->active_tc.gpr[5];
17118639a28SRichard Henderson         UHIStat *dst = lock_user(VERIFY_WRITE, addr, sizeof(UHIStat), 1);
17218639a28SRichard Henderson         struct gdb_stat s;
17318639a28SRichard Henderson 
174ad520a97SPhilippe Mathieu-Daudé         if (!dst) {
175d53a3ed4SRichard Henderson             report_fault(env);
176ad520a97SPhilippe Mathieu-Daudé         }
177ad520a97SPhilippe Mathieu-Daudé 
17818639a28SRichard Henderson         memcpy(&s, dst, sizeof(struct gdb_stat));
17918639a28SRichard Henderson         memset(dst, 0, sizeof(UHIStat));
18018639a28SRichard Henderson 
18118639a28SRichard Henderson         dst->uhi_st_dev = tswap16(be32_to_cpu(s.gdb_st_dev));
18218639a28SRichard Henderson         dst->uhi_st_ino = tswap16(be32_to_cpu(s.gdb_st_ino));
18318639a28SRichard Henderson         dst->uhi_st_mode = tswap32(be32_to_cpu(s.gdb_st_mode));
18418639a28SRichard Henderson         dst->uhi_st_nlink = tswap16(be32_to_cpu(s.gdb_st_nlink));
18518639a28SRichard Henderson         dst->uhi_st_uid = tswap16(be32_to_cpu(s.gdb_st_uid));
18618639a28SRichard Henderson         dst->uhi_st_gid = tswap16(be32_to_cpu(s.gdb_st_gid));
18718639a28SRichard Henderson         dst->uhi_st_rdev = tswap16(be32_to_cpu(s.gdb_st_rdev));
18818639a28SRichard Henderson         dst->uhi_st_size = tswap64(be64_to_cpu(s.gdb_st_size));
18918639a28SRichard Henderson         dst->uhi_st_atime = tswap64(be32_to_cpu(s.gdb_st_atime));
19018639a28SRichard Henderson         dst->uhi_st_mtime = tswap64(be32_to_cpu(s.gdb_st_mtime));
19118639a28SRichard Henderson         dst->uhi_st_ctime = tswap64(be32_to_cpu(s.gdb_st_ctime));
19218639a28SRichard Henderson         dst->uhi_st_blksize = tswap64(be64_to_cpu(s.gdb_st_blksize));
19318639a28SRichard Henderson         dst->uhi_st_blocks = tswap64(be64_to_cpu(s.gdb_st_blocks));
19418639a28SRichard Henderson 
19518639a28SRichard Henderson         unlock_user(dst, addr, sizeof(UHIStat));
196ad520a97SPhilippe Mathieu-Daudé     }
197ad520a97SPhilippe Mathieu-Daudé 
19818639a28SRichard Henderson     uhi_cb(cs, ret, err);
199ad520a97SPhilippe Mathieu-Daudé }
200ad520a97SPhilippe Mathieu-Daudé 
2018ec7e3c5SRichard Henderson void mips_semihosting(CPUMIPSState *env)
202ad520a97SPhilippe Mathieu-Daudé {
20318639a28SRichard Henderson     CPUState *cs = env_cpu(env);
204ad520a97SPhilippe Mathieu-Daudé     target_ulong *gpr = env->active_tc.gpr;
205ad520a97SPhilippe Mathieu-Daudé     const UHIOp op = gpr[25];
206412411b3SRichard Henderson     char *p;
207ad520a97SPhilippe Mathieu-Daudé 
208ad520a97SPhilippe Mathieu-Daudé     switch (op) {
209ad520a97SPhilippe Mathieu-Daudé     case UHI_exit:
21018639a28SRichard Henderson         gdb_exit(gpr[4]);
211ad520a97SPhilippe Mathieu-Daudé         exit(gpr[4]);
21218639a28SRichard Henderson 
213ad520a97SPhilippe Mathieu-Daudé     case UHI_open:
21418639a28SRichard Henderson         {
215b10ccec1SRichard Henderson             target_ulong fname = gpr[4];
21618639a28SRichard Henderson             int ret = -1;
21718639a28SRichard Henderson 
218b10ccec1SRichard Henderson             p = lock_user_string(fname);
219b10ccec1SRichard Henderson             if (!p) {
220b10ccec1SRichard Henderson                 report_fault(env);
221b10ccec1SRichard Henderson             }
222ad520a97SPhilippe Mathieu-Daudé             if (!strcmp("/dev/stdin", p)) {
22318639a28SRichard Henderson                 ret = 0;
224ad520a97SPhilippe Mathieu-Daudé             } else if (!strcmp("/dev/stdout", p)) {
22518639a28SRichard Henderson                 ret = 1;
226ad520a97SPhilippe Mathieu-Daudé             } else if (!strcmp("/dev/stderr", p)) {
22718639a28SRichard Henderson                 ret = 2;
228ad520a97SPhilippe Mathieu-Daudé             }
229b10ccec1SRichard Henderson             unlock_user(p, fname, 0);
23018639a28SRichard Henderson 
23118639a28SRichard Henderson             /* FIXME: reusing a guest fd doesn't seem correct. */
23218639a28SRichard Henderson             if (ret >= 0) {
23318639a28SRichard Henderson                 gpr[2] = ret;
234ad520a97SPhilippe Mathieu-Daudé                 break;
235ad520a97SPhilippe Mathieu-Daudé             }
23618639a28SRichard Henderson 
237b10ccec1SRichard Henderson             semihost_sys_open(cs, uhi_cb, fname, 0, gpr[5], gpr[6]);
23818639a28SRichard Henderson         }
23918639a28SRichard Henderson         break;
24018639a28SRichard Henderson 
24118639a28SRichard Henderson     case UHI_close:
24218639a28SRichard Henderson         semihost_sys_close(cs, uhi_cb, gpr[4]);
243ad520a97SPhilippe Mathieu-Daudé         break;
244ad520a97SPhilippe Mathieu-Daudé     case UHI_read:
24518639a28SRichard Henderson         semihost_sys_read(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
246ad520a97SPhilippe Mathieu-Daudé         break;
247ad520a97SPhilippe Mathieu-Daudé     case UHI_write:
24818639a28SRichard Henderson         semihost_sys_write(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
249ad520a97SPhilippe Mathieu-Daudé         break;
250ad520a97SPhilippe Mathieu-Daudé     case UHI_lseek:
25118639a28SRichard Henderson         semihost_sys_lseek(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
252ad520a97SPhilippe Mathieu-Daudé         break;
253ad520a97SPhilippe Mathieu-Daudé     case UHI_unlink:
25418639a28SRichard Henderson         semihost_sys_remove(cs, uhi_cb, gpr[4], 0);
255ad520a97SPhilippe Mathieu-Daudé         break;
256ad520a97SPhilippe Mathieu-Daudé     case UHI_fstat:
25718639a28SRichard Henderson         semihost_sys_fstat(cs, uhi_fstat_cb, gpr[4], gpr[5]);
258ad520a97SPhilippe Mathieu-Daudé         break;
25918639a28SRichard Henderson 
260ad520a97SPhilippe Mathieu-Daudé     case UHI_argc:
261ad520a97SPhilippe Mathieu-Daudé         gpr[2] = semihosting_get_argc();
262ad520a97SPhilippe Mathieu-Daudé         break;
263ad520a97SPhilippe Mathieu-Daudé     case UHI_argnlen:
2643bb45bbcSRichard Henderson         {
2653bb45bbcSRichard Henderson             const char *s = semihosting_get_arg(gpr[4]);
2663bb45bbcSRichard Henderson             gpr[2] = s ? strlen(s) : -1;
267ad520a97SPhilippe Mathieu-Daudé         }
268ad520a97SPhilippe Mathieu-Daudé         break;
269ad520a97SPhilippe Mathieu-Daudé     case UHI_argn:
2703bb45bbcSRichard Henderson         {
2713bb45bbcSRichard Henderson             const char *s = semihosting_get_arg(gpr[4]);
2723bb45bbcSRichard Henderson             target_ulong addr;
2733bb45bbcSRichard Henderson             size_t len;
2743bb45bbcSRichard Henderson 
2753bb45bbcSRichard Henderson             if (!s) {
276ad520a97SPhilippe Mathieu-Daudé                 gpr[2] = -1;
2773bb45bbcSRichard Henderson                 break;
278ad520a97SPhilippe Mathieu-Daudé             }
2793bb45bbcSRichard Henderson             len = strlen(s) + 1;
2803bb45bbcSRichard Henderson             addr = gpr[5];
2813bb45bbcSRichard Henderson             p = lock_user(VERIFY_WRITE, addr, len, 0);
2823bb45bbcSRichard Henderson             if (!p) {
2833bb45bbcSRichard Henderson                 report_fault(env);
2843bb45bbcSRichard Henderson             }
2853bb45bbcSRichard Henderson             memcpy(p, s, len);
2863bb45bbcSRichard Henderson             unlock_user(p, addr, len);
2873bb45bbcSRichard Henderson             gpr[2] = 0;
2883bb45bbcSRichard Henderson         }
289ad520a97SPhilippe Mathieu-Daudé         break;
290ea421060SRichard Henderson 
291ad520a97SPhilippe Mathieu-Daudé     case UHI_plog:
292ea421060SRichard Henderson         {
293ea421060SRichard Henderson             target_ulong addr = gpr[4];
294ea421060SRichard Henderson             ssize_t len = target_strlen(addr);
295ea421060SRichard Henderson             GString *str;
296ea421060SRichard Henderson             char *pct_d;
297ea421060SRichard Henderson 
298ea421060SRichard Henderson             if (len < 0) {
299ea421060SRichard Henderson                 report_fault(env);
300ad520a97SPhilippe Mathieu-Daudé             }
301ea421060SRichard Henderson             p = lock_user(VERIFY_READ, addr, len, 1);
302ea421060SRichard Henderson             if (!p) {
303ea421060SRichard Henderson                 report_fault(env);
304ea421060SRichard Henderson             }
305ea421060SRichard Henderson 
306ea421060SRichard Henderson             pct_d = strstr(p, "%d");
307ea421060SRichard Henderson             if (!pct_d) {
308b10ccec1SRichard Henderson                 unlock_user(p, addr, 0);
309ea421060SRichard Henderson                 semihost_sys_write(cs, uhi_cb, 2, addr, len);
310ad520a97SPhilippe Mathieu-Daudé                 break;
311ea421060SRichard Henderson             }
312ea421060SRichard Henderson 
313ea421060SRichard Henderson             str = g_string_new_len(p, pct_d - p);
314ea421060SRichard Henderson             g_string_append_printf(str, "%d%s", (int)gpr[5], pct_d + 2);
315b10ccec1SRichard Henderson             unlock_user(p, addr, 0);
316ea421060SRichard Henderson 
317ea421060SRichard Henderson             /*
318ea421060SRichard Henderson              * When we're using gdb, we need a guest address, so
319ea421060SRichard Henderson              * drop the string onto the stack below the stack pointer.
320ea421060SRichard Henderson              */
321ea421060SRichard Henderson             if (use_gdb_syscalls()) {
322ea421060SRichard Henderson                 addr = gpr[29] - str->len;
323ea421060SRichard Henderson                 p = lock_user(VERIFY_WRITE, addr, str->len, 0);
324ea421060SRichard Henderson                 memcpy(p, str->str, str->len);
325ea421060SRichard Henderson                 unlock_user(p, addr, str->len);
326ea421060SRichard Henderson                 semihost_sys_write(cs, uhi_cb, 2, addr, str->len);
327ea421060SRichard Henderson             } else {
328ea421060SRichard Henderson                 gpr[2] = qemu_semihosting_console_write(str->str, str->len);
329ea421060SRichard Henderson             }
330ea421060SRichard Henderson             g_string_free(str, true);
331ea421060SRichard Henderson         }
332ea421060SRichard Henderson         break;
333ea421060SRichard Henderson 
334ad520a97SPhilippe Mathieu-Daudé     case UHI_assert:
335412411b3SRichard Henderson         {
336412411b3SRichard Henderson             const char *msg, *file;
337412411b3SRichard Henderson 
338412411b3SRichard Henderson             msg = lock_user_string(gpr[4]);
339412411b3SRichard Henderson             if (!msg) {
340412411b3SRichard Henderson                 msg = "<EFAULT>";
341412411b3SRichard Henderson             }
342412411b3SRichard Henderson             file = lock_user_string(gpr[5]);
343412411b3SRichard Henderson             if (!file) {
344412411b3SRichard Henderson                 file = "<EFAULT>";
345412411b3SRichard Henderson             }
346412411b3SRichard Henderson 
347412411b3SRichard Henderson             error_report("UHI assertion \"%s\": file \"%s\", line %d",
348412411b3SRichard Henderson                          msg, file, (int)gpr[6]);
349ad520a97SPhilippe Mathieu-Daudé             abort();
350412411b3SRichard Henderson         }
351412411b3SRichard Henderson 
352ad520a97SPhilippe Mathieu-Daudé     default:
353d53a3ed4SRichard Henderson         error_report("Unknown UHI operation %d", op);
354ad520a97SPhilippe Mathieu-Daudé         abort();
355ad520a97SPhilippe Mathieu-Daudé     }
356ad520a97SPhilippe Mathieu-Daudé     return;
357ad520a97SPhilippe Mathieu-Daudé }
358