xref: /qemu/semihosting/arm-compat-semi.c (revision dc293f60)
1 /*
2  *  Semihosting support for systems modeled on the Arm "Angel"
3  *  semihosting syscalls design. This includes Arm and RISC-V processors
4  *
5  *  Copyright (c) 2005, 2007 CodeSourcery.
6  *  Copyright (c) 2019 Linaro
7  *  Written by Paul Brook.
8  *
9  *  Copyright © 2020 by Keith Packard <keithp@keithp.com>
10  *  Adapted for systems other than ARM, including RISC-V, by Keith Packard
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
24  *
25  *  ARM Semihosting is documented in:
26  *     Semihosting for AArch32 and AArch64 Release 2.0
27  *     https://static.docs.arm.com/100863/0200/semihosting.pdf
28  *
29  *  RISC-V Semihosting is documented in:
30  *     RISC-V Semihosting
31  *     https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc
32  */
33 
34 #include "qemu/osdep.h"
35 
36 #include "cpu.h"
37 #include "semihosting/semihost.h"
38 #include "semihosting/console.h"
39 #include "semihosting/common-semi.h"
40 #include "qemu/log.h"
41 #include "qemu/timer.h"
42 #ifdef CONFIG_USER_ONLY
43 #include "qemu.h"
44 
45 #define COMMON_SEMI_HEAP_SIZE (128 * 1024 * 1024)
46 #else
47 #include "exec/gdbstub.h"
48 #include "qemu/cutils.h"
49 #ifdef TARGET_ARM
50 #include "hw/arm/boot.h"
51 #endif
52 #include "hw/boards.h"
53 #endif
54 
55 #define TARGET_SYS_OPEN        0x01
56 #define TARGET_SYS_CLOSE       0x02
57 #define TARGET_SYS_WRITEC      0x03
58 #define TARGET_SYS_WRITE0      0x04
59 #define TARGET_SYS_WRITE       0x05
60 #define TARGET_SYS_READ        0x06
61 #define TARGET_SYS_READC       0x07
62 #define TARGET_SYS_ISERROR     0x08
63 #define TARGET_SYS_ISTTY       0x09
64 #define TARGET_SYS_SEEK        0x0a
65 #define TARGET_SYS_FLEN        0x0c
66 #define TARGET_SYS_TMPNAM      0x0d
67 #define TARGET_SYS_REMOVE      0x0e
68 #define TARGET_SYS_RENAME      0x0f
69 #define TARGET_SYS_CLOCK       0x10
70 #define TARGET_SYS_TIME        0x11
71 #define TARGET_SYS_SYSTEM      0x12
72 #define TARGET_SYS_ERRNO       0x13
73 #define TARGET_SYS_GET_CMDLINE 0x15
74 #define TARGET_SYS_HEAPINFO    0x16
75 #define TARGET_SYS_EXIT        0x18
76 #define TARGET_SYS_SYNCCACHE   0x19
77 #define TARGET_SYS_EXIT_EXTENDED 0x20
78 #define TARGET_SYS_ELAPSED     0x30
79 #define TARGET_SYS_TICKFREQ    0x31
80 
81 /* ADP_Stopped_ApplicationExit is used for exit(0),
82  * anything else is implemented as exit(1) */
83 #define ADP_Stopped_ApplicationExit     (0x20026)
84 
85 #ifndef O_BINARY
86 #define O_BINARY 0
87 #endif
88 
89 #define GDB_O_RDONLY  0x000
90 #define GDB_O_WRONLY  0x001
91 #define GDB_O_RDWR    0x002
92 #define GDB_O_APPEND  0x008
93 #define GDB_O_CREAT   0x200
94 #define GDB_O_TRUNC   0x400
95 #define GDB_O_BINARY  0
96 
97 static int gdb_open_modeflags[12] = {
98     GDB_O_RDONLY,
99     GDB_O_RDONLY | GDB_O_BINARY,
100     GDB_O_RDWR,
101     GDB_O_RDWR | GDB_O_BINARY,
102     GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC,
103     GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY,
104     GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC,
105     GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY,
106     GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND,
107     GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY,
108     GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND,
109     GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY
110 };
111 
112 static int open_modeflags[12] = {
113     O_RDONLY,
114     O_RDONLY | O_BINARY,
115     O_RDWR,
116     O_RDWR | O_BINARY,
117     O_WRONLY | O_CREAT | O_TRUNC,
118     O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
119     O_RDWR | O_CREAT | O_TRUNC,
120     O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
121     O_WRONLY | O_CREAT | O_APPEND,
122     O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
123     O_RDWR | O_CREAT | O_APPEND,
124     O_RDWR | O_CREAT | O_APPEND | O_BINARY
125 };
126 
127 typedef enum GuestFDType {
128     GuestFDUnused = 0,
129     GuestFDHost = 1,
130     GuestFDGDB = 2,
131     GuestFDFeatureFile = 3,
132 } GuestFDType;
133 
134 /*
135  * Guest file descriptors are integer indexes into an array of
136  * these structures (we will dynamically resize as necessary).
137  */
138 typedef struct GuestFD {
139     GuestFDType type;
140     union {
141         int hostfd;
142         target_ulong featurefile_offset;
143     };
144 } GuestFD;
145 
146 static GArray *guestfd_array;
147 
148 #ifndef CONFIG_USER_ONLY
149 #include "exec/address-spaces.h"
150 /*
151  * Find the base of a RAM region containing the specified address
152  */
153 static inline hwaddr
154 common_semi_find_region_base(hwaddr addr)
155 {
156     MemoryRegion *subregion;
157 
158     /*
159      * Find the chunk of R/W memory containing the address.  This is
160      * used for the SYS_HEAPINFO semihosting call, which should
161      * probably be using information from the loaded application.
162      */
163     QTAILQ_FOREACH(subregion, &get_system_memory()->subregions,
164                    subregions_link) {
165         if (subregion->ram && !subregion->readonly) {
166             Int128 top128 = int128_add(int128_make64(subregion->addr),
167                                        subregion->size);
168             Int128 addr128 = int128_make64(addr);
169             if (subregion->addr <= addr && int128_lt(addr128, top128)) {
170                 return subregion->addr;
171             }
172         }
173     }
174     return 0;
175 }
176 #endif
177 
178 #ifdef TARGET_ARM
179 static inline target_ulong
180 common_semi_arg(CPUState *cs, int argno)
181 {
182     ARMCPU *cpu = ARM_CPU(cs);
183     CPUARMState *env = &cpu->env;
184     if (is_a64(env)) {
185         return env->xregs[argno];
186     } else {
187         return env->regs[argno];
188     }
189 }
190 
191 static inline void
192 common_semi_set_ret(CPUState *cs, target_ulong ret)
193 {
194     ARMCPU *cpu = ARM_CPU(cs);
195     CPUARMState *env = &cpu->env;
196     if (is_a64(env)) {
197         env->xregs[0] = ret;
198     } else {
199         env->regs[0] = ret;
200     }
201 }
202 
203 static inline bool
204 common_semi_sys_exit_extended(CPUState *cs, int nr)
205 {
206     return (nr == TARGET_SYS_EXIT_EXTENDED || is_a64(cs->env_ptr));
207 }
208 
209 #ifndef CONFIG_USER_ONLY
210 #include "hw/arm/boot.h"
211 static inline target_ulong
212 common_semi_rambase(CPUState *cs)
213 {
214     CPUArchState *env = cs->env_ptr;
215     const struct arm_boot_info *info = env->boot_info;
216     target_ulong sp;
217 
218     if (info) {
219         return info->loader_start;
220     }
221 
222     if (is_a64(env)) {
223         sp = env->xregs[31];
224     } else {
225         sp = env->regs[13];
226     }
227     return common_semi_find_region_base(sp);
228 }
229 #endif
230 
231 #endif /* TARGET_ARM */
232 
233 #ifdef TARGET_RISCV
234 static inline target_ulong
235 common_semi_arg(CPUState *cs, int argno)
236 {
237     RISCVCPU *cpu = RISCV_CPU(cs);
238     CPURISCVState *env = &cpu->env;
239     return env->gpr[xA0 + argno];
240 }
241 
242 static inline void
243 common_semi_set_ret(CPUState *cs, target_ulong ret)
244 {
245     RISCVCPU *cpu = RISCV_CPU(cs);
246     CPURISCVState *env = &cpu->env;
247     env->gpr[xA0] = ret;
248 }
249 
250 static inline bool
251 common_semi_sys_exit_extended(CPUState *cs, int nr)
252 {
253     return (nr == TARGET_SYS_EXIT_EXTENDED || sizeof(target_ulong) == 8);
254 }
255 
256 #ifndef CONFIG_USER_ONLY
257 
258 static inline target_ulong
259 common_semi_rambase(CPUState *cs)
260 {
261     RISCVCPU *cpu = RISCV_CPU(cs);
262     CPURISCVState *env = &cpu->env;
263     return common_semi_find_region_base(env->gpr[xSP]);
264 }
265 #endif
266 
267 #endif
268 
269 /*
270  * Allocate a new guest file descriptor and return it; if we
271  * couldn't allocate a new fd then return -1.
272  * This is a fairly simplistic implementation because we don't
273  * expect that most semihosting guest programs will make very
274  * heavy use of opening and closing fds.
275  */
276 static int alloc_guestfd(void)
277 {
278     guint i;
279 
280     if (!guestfd_array) {
281         /* New entries zero-initialized, i.e. type GuestFDUnused */
282         guestfd_array = g_array_new(FALSE, TRUE, sizeof(GuestFD));
283     }
284 
285     /* SYS_OPEN should return nonzero handle on success. Start guestfd from 1 */
286     for (i = 1; i < guestfd_array->len; i++) {
287         GuestFD *gf = &g_array_index(guestfd_array, GuestFD, i);
288 
289         if (gf->type == GuestFDUnused) {
290             return i;
291         }
292     }
293 
294     /* All elements already in use: expand the array */
295     g_array_set_size(guestfd_array, i + 1);
296     return i;
297 }
298 
299 /*
300  * Look up the guestfd in the data structure; return NULL
301  * for out of bounds, but don't check whether the slot is unused.
302  * This is used internally by the other guestfd functions.
303  */
304 static GuestFD *do_get_guestfd(int guestfd)
305 {
306     if (!guestfd_array) {
307         return NULL;
308     }
309 
310     if (guestfd <= 0 || guestfd >= guestfd_array->len) {
311         return NULL;
312     }
313 
314     return &g_array_index(guestfd_array, GuestFD, guestfd);
315 }
316 
317 /*
318  * Associate the specified guest fd (which must have been
319  * allocated via alloc_fd() and not previously used) with
320  * the specified host/gdb fd.
321  */
322 static void associate_guestfd(int guestfd, int hostfd)
323 {
324     GuestFD *gf = do_get_guestfd(guestfd);
325 
326     assert(gf);
327     gf->type = use_gdb_syscalls() ? GuestFDGDB : GuestFDHost;
328     gf->hostfd = hostfd;
329 }
330 
331 /*
332  * Deallocate the specified guest file descriptor. This doesn't
333  * close the host fd, it merely undoes the work of alloc_fd().
334  */
335 static void dealloc_guestfd(int guestfd)
336 {
337     GuestFD *gf = do_get_guestfd(guestfd);
338 
339     assert(gf);
340     gf->type = GuestFDUnused;
341 }
342 
343 /*
344  * Given a guest file descriptor, get the associated struct.
345  * If the fd is not valid, return NULL. This is the function
346  * used by the various semihosting calls to validate a handle
347  * from the guest.
348  * Note: calling alloc_guestfd() or dealloc_guestfd() will
349  * invalidate any GuestFD* obtained by calling this function.
350  */
351 static GuestFD *get_guestfd(int guestfd)
352 {
353     GuestFD *gf = do_get_guestfd(guestfd);
354 
355     if (!gf || gf->type == GuestFDUnused) {
356         return NULL;
357     }
358     return gf;
359 }
360 
361 /*
362  * The semihosting API has no concept of its errno being thread-safe,
363  * as the API design predates SMP CPUs and was intended as a simple
364  * real-hardware set of debug functionality. For QEMU, we make the
365  * errno be per-thread in linux-user mode; in softmmu it is a simple
366  * global, and we assume that the guest takes care of avoiding any races.
367  */
368 #ifndef CONFIG_USER_ONLY
369 static target_ulong syscall_err;
370 
371 #include "exec/softmmu-semi.h"
372 #endif
373 
374 static inline uint32_t set_swi_errno(CPUState *cs, uint32_t code)
375 {
376     if (code == (uint32_t)-1) {
377 #ifdef CONFIG_USER_ONLY
378         TaskState *ts = cs->opaque;
379 
380         ts->swi_errno = errno;
381 #else
382         syscall_err = errno;
383 #endif
384     }
385     return code;
386 }
387 
388 static inline uint32_t get_swi_errno(CPUState *cs)
389 {
390 #ifdef CONFIG_USER_ONLY
391     TaskState *ts = cs->opaque;
392 
393     return ts->swi_errno;
394 #else
395     return syscall_err;
396 #endif
397 }
398 
399 static target_ulong common_semi_syscall_len;
400 
401 static void common_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
402 {
403     target_ulong reg0 = common_semi_arg(cs, 0);
404 
405     if (ret == (target_ulong)-1) {
406         errno = err;
407         set_swi_errno(cs, -1);
408         reg0 = ret;
409     } else {
410         /* Fixup syscalls that use nonstardard return conventions.  */
411         switch (reg0) {
412         case TARGET_SYS_WRITE:
413         case TARGET_SYS_READ:
414             reg0 = common_semi_syscall_len - ret;
415             break;
416         case TARGET_SYS_SEEK:
417             reg0 = 0;
418             break;
419         default:
420             reg0 = ret;
421             break;
422         }
423     }
424     common_semi_set_ret(cs, reg0);
425 }
426 
427 static target_ulong common_semi_flen_buf(CPUState *cs)
428 {
429     target_ulong sp;
430 #ifdef TARGET_ARM
431     /* Return an address in target memory of 64 bytes where the remote
432      * gdb should write its stat struct. (The format of this structure
433      * is defined by GDB's remote protocol and is not target-specific.)
434      * We put this on the guest's stack just below SP.
435      */
436     ARMCPU *cpu = ARM_CPU(cs);
437     CPUARMState *env = &cpu->env;
438 
439     if (is_a64(env)) {
440         sp = env->xregs[31];
441     } else {
442         sp = env->regs[13];
443     }
444 #endif
445 #ifdef TARGET_RISCV
446     RISCVCPU *cpu = RISCV_CPU(cs);
447     CPURISCVState *env = &cpu->env;
448 
449     sp = env->gpr[xSP];
450 #endif
451 
452     return sp - 64;
453 }
454 
455 static void
456 common_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
457 {
458     /* The size is always stored in big-endian order, extract
459        the value. We assume the size always fit in 32 bits.  */
460     uint32_t size;
461     cpu_memory_rw_debug(cs, common_semi_flen_buf(cs) + 32,
462                         (uint8_t *)&size, 4, 0);
463     size = be32_to_cpu(size);
464     common_semi_set_ret(cs, size);
465     errno = err;
466     set_swi_errno(cs, -1);
467 }
468 
469 static int common_semi_open_guestfd;
470 
471 static void
472 common_semi_open_cb(CPUState *cs, target_ulong ret, target_ulong err)
473 {
474     if (ret == (target_ulong)-1) {
475         errno = err;
476         set_swi_errno(cs, -1);
477         dealloc_guestfd(common_semi_open_guestfd);
478     } else {
479         associate_guestfd(common_semi_open_guestfd, ret);
480         ret = common_semi_open_guestfd;
481     }
482     common_semi_set_ret(cs, ret);
483 }
484 
485 static target_ulong
486 common_semi_gdb_syscall(CPUState *cs, gdb_syscall_complete_cb cb,
487                         const char *fmt, ...)
488 {
489     va_list va;
490 
491     va_start(va, fmt);
492     gdb_do_syscallv(cb, fmt, va);
493     va_end(va);
494 
495     /*
496      * FIXME: in softmmu mode, the gdbstub will schedule our callback
497      * to occur, but will not actually call it to complete the syscall
498      * until after this function has returned and we are back in the
499      * CPU main loop. Therefore callers to this function must not
500      * do anything with its return value, because it is not necessarily
501      * the result of the syscall, but could just be the old value of X0.
502      * The only thing safe to do with this is that the callers of
503      * do_common_semihosting() will write it straight back into X0.
504      * (In linux-user mode, the callback will have happened before
505      * gdb_do_syscallv() returns.)
506      *
507      * We should tidy this up so neither this function nor
508      * do_common_semihosting() return a value, so the mistake of
509      * doing something with the return value is not possible to make.
510      */
511 
512     return common_semi_arg(cs, 0);
513 }
514 
515 /*
516  * Types for functions implementing various semihosting calls
517  * for specific types of guest file descriptor. These must all
518  * do the work and return the required return value for the guest,
519  * setting the guest errno if appropriate.
520  */
521 typedef uint32_t sys_closefn(CPUState *cs, GuestFD *gf);
522 typedef uint32_t sys_writefn(CPUState *cs, GuestFD *gf,
523                              target_ulong buf, uint32_t len);
524 typedef uint32_t sys_readfn(CPUState *cs, GuestFD *gf,
525                             target_ulong buf, uint32_t len);
526 typedef uint32_t sys_isattyfn(CPUState *cs, GuestFD *gf);
527 typedef uint32_t sys_seekfn(CPUState *cs, GuestFD *gf,
528                             target_ulong offset);
529 typedef uint32_t sys_flenfn(CPUState *cs, GuestFD *gf);
530 
531 static uint32_t host_closefn(CPUState *cs, GuestFD *gf)
532 {
533     /*
534      * Only close the underlying host fd if it's one we opened on behalf
535      * of the guest in SYS_OPEN.
536      */
537     if (gf->hostfd == STDIN_FILENO ||
538         gf->hostfd == STDOUT_FILENO ||
539         gf->hostfd == STDERR_FILENO) {
540         return 0;
541     }
542     return set_swi_errno(cs, close(gf->hostfd));
543 }
544 
545 static uint32_t host_writefn(CPUState *cs, GuestFD *gf,
546                              target_ulong buf, uint32_t len)
547 {
548     CPUArchState *env = cs->env_ptr;
549     uint32_t ret;
550     char *s = lock_user(VERIFY_READ, buf, len, 1);
551     (void) env; /* Used in arm softmmu lock_user implicitly */
552     if (!s) {
553         /* Return bytes not written on error */
554         return len;
555     }
556     ret = set_swi_errno(cs, write(gf->hostfd, s, len));
557     unlock_user(s, buf, 0);
558     if (ret == (uint32_t)-1) {
559         ret = 0;
560     }
561     /* Return bytes not written */
562     return len - ret;
563 }
564 
565 static uint32_t host_readfn(CPUState *cs, GuestFD *gf,
566                             target_ulong buf, uint32_t len)
567 {
568     CPUArchState *env = cs->env_ptr;
569     uint32_t ret;
570     char *s = lock_user(VERIFY_WRITE, buf, len, 0);
571     (void) env; /* Used in arm softmmu lock_user implicitly */
572     if (!s) {
573         /* return bytes not read */
574         return len;
575     }
576     do {
577         ret = set_swi_errno(cs, read(gf->hostfd, s, len));
578     } while (ret == -1 && errno == EINTR);
579     unlock_user(s, buf, len);
580     if (ret == (uint32_t)-1) {
581         ret = 0;
582     }
583     /* Return bytes not read */
584     return len - ret;
585 }
586 
587 static uint32_t host_isattyfn(CPUState *cs, GuestFD *gf)
588 {
589     return isatty(gf->hostfd);
590 }
591 
592 static uint32_t host_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset)
593 {
594     uint32_t ret = set_swi_errno(cs, lseek(gf->hostfd, offset, SEEK_SET));
595     if (ret == (uint32_t)-1) {
596         return -1;
597     }
598     return 0;
599 }
600 
601 static uint32_t host_flenfn(CPUState *cs, GuestFD *gf)
602 {
603     struct stat buf;
604     uint32_t ret = set_swi_errno(cs, fstat(gf->hostfd, &buf));
605     if (ret == (uint32_t)-1) {
606         return -1;
607     }
608     return buf.st_size;
609 }
610 
611 static uint32_t gdb_closefn(CPUState *cs, GuestFD *gf)
612 {
613     return common_semi_gdb_syscall(cs, common_semi_cb, "close,%x", gf->hostfd);
614 }
615 
616 static uint32_t gdb_writefn(CPUState *cs, GuestFD *gf,
617                             target_ulong buf, uint32_t len)
618 {
619     common_semi_syscall_len = len;
620     return common_semi_gdb_syscall(cs, common_semi_cb, "write,%x,%x,%x",
621                                    gf->hostfd, buf, len);
622 }
623 
624 static uint32_t gdb_readfn(CPUState *cs, GuestFD *gf,
625                            target_ulong buf, uint32_t len)
626 {
627     common_semi_syscall_len = len;
628     return common_semi_gdb_syscall(cs, common_semi_cb, "read,%x,%x,%x",
629                                    gf->hostfd, buf, len);
630 }
631 
632 static uint32_t gdb_isattyfn(CPUState *cs, GuestFD *gf)
633 {
634     return common_semi_gdb_syscall(cs, common_semi_cb, "isatty,%x", gf->hostfd);
635 }
636 
637 static uint32_t gdb_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset)
638 {
639     return common_semi_gdb_syscall(cs, common_semi_cb, "lseek,%x,%x,0",
640                                    gf->hostfd, offset);
641 }
642 
643 static uint32_t gdb_flenfn(CPUState *cs, GuestFD *gf)
644 {
645     return common_semi_gdb_syscall(cs, common_semi_flen_cb, "fstat,%x,%x",
646                                    gf->hostfd, common_semi_flen_buf(cs));
647 }
648 
649 #define SHFB_MAGIC_0 0x53
650 #define SHFB_MAGIC_1 0x48
651 #define SHFB_MAGIC_2 0x46
652 #define SHFB_MAGIC_3 0x42
653 
654 /* Feature bits reportable in feature byte 0 */
655 #define SH_EXT_EXIT_EXTENDED (1 << 0)
656 #define SH_EXT_STDOUT_STDERR (1 << 1)
657 
658 static const uint8_t featurefile_data[] = {
659     SHFB_MAGIC_0,
660     SHFB_MAGIC_1,
661     SHFB_MAGIC_2,
662     SHFB_MAGIC_3,
663     SH_EXT_EXIT_EXTENDED | SH_EXT_STDOUT_STDERR, /* Feature byte 0 */
664 };
665 
666 static void init_featurefile_guestfd(int guestfd)
667 {
668     GuestFD *gf = do_get_guestfd(guestfd);
669 
670     assert(gf);
671     gf->type = GuestFDFeatureFile;
672     gf->featurefile_offset = 0;
673 }
674 
675 static uint32_t featurefile_closefn(CPUState *cs, GuestFD *gf)
676 {
677     /* Nothing to do */
678     return 0;
679 }
680 
681 static uint32_t featurefile_writefn(CPUState *cs, GuestFD *gf,
682                                     target_ulong buf, uint32_t len)
683 {
684     /* This fd can never be open for writing */
685 
686     errno = EBADF;
687     return set_swi_errno(cs, -1);
688 }
689 
690 static uint32_t featurefile_readfn(CPUState *cs, GuestFD *gf,
691                                    target_ulong buf, uint32_t len)
692 {
693     CPUArchState *env = cs->env_ptr;
694     uint32_t i;
695     char *s;
696 
697     (void) env; /* Used in arm softmmu lock_user implicitly */
698     s = lock_user(VERIFY_WRITE, buf, len, 0);
699     if (!s) {
700         return len;
701     }
702 
703     for (i = 0; i < len; i++) {
704         if (gf->featurefile_offset >= sizeof(featurefile_data)) {
705             break;
706         }
707         s[i] = featurefile_data[gf->featurefile_offset];
708         gf->featurefile_offset++;
709     }
710 
711     unlock_user(s, buf, len);
712 
713     /* Return number of bytes not read */
714     return len - i;
715 }
716 
717 static uint32_t featurefile_isattyfn(CPUState *cs, GuestFD *gf)
718 {
719     return 0;
720 }
721 
722 static uint32_t featurefile_seekfn(CPUState *cs, GuestFD *gf,
723                                    target_ulong offset)
724 {
725     gf->featurefile_offset = offset;
726     return 0;
727 }
728 
729 static uint32_t featurefile_flenfn(CPUState *cs, GuestFD *gf)
730 {
731     return sizeof(featurefile_data);
732 }
733 
734 typedef struct GuestFDFunctions {
735     sys_closefn *closefn;
736     sys_writefn *writefn;
737     sys_readfn *readfn;
738     sys_isattyfn *isattyfn;
739     sys_seekfn *seekfn;
740     sys_flenfn *flenfn;
741 } GuestFDFunctions;
742 
743 static const GuestFDFunctions guestfd_fns[] = {
744     [GuestFDHost] = {
745         .closefn = host_closefn,
746         .writefn = host_writefn,
747         .readfn = host_readfn,
748         .isattyfn = host_isattyfn,
749         .seekfn = host_seekfn,
750         .flenfn = host_flenfn,
751     },
752     [GuestFDGDB] = {
753         .closefn = gdb_closefn,
754         .writefn = gdb_writefn,
755         .readfn = gdb_readfn,
756         .isattyfn = gdb_isattyfn,
757         .seekfn = gdb_seekfn,
758         .flenfn = gdb_flenfn,
759     },
760     [GuestFDFeatureFile] = {
761         .closefn = featurefile_closefn,
762         .writefn = featurefile_writefn,
763         .readfn = featurefile_readfn,
764         .isattyfn = featurefile_isattyfn,
765         .seekfn = featurefile_seekfn,
766         .flenfn = featurefile_flenfn,
767     },
768 };
769 
770 /* Read the input value from the argument block; fail the semihosting
771  * call if the memory read fails.
772  */
773 #ifdef TARGET_ARM
774 #define GET_ARG(n) do {                                 \
775     if (is_a64(env)) {                                  \
776         if (get_user_u64(arg ## n, args + (n) * 8)) {   \
777             errno = EFAULT;                             \
778             return set_swi_errno(cs, -1);              \
779         }                                               \
780     } else {                                            \
781         if (get_user_u32(arg ## n, args + (n) * 4)) {   \
782             errno = EFAULT;                             \
783             return set_swi_errno(cs, -1);              \
784         }                                               \
785     }                                                   \
786 } while (0)
787 
788 #define SET_ARG(n, val)                                 \
789     (is_a64(env) ?                                      \
790      put_user_u64(val, args + (n) * 8) :                \
791      put_user_u32(val, args + (n) * 4))
792 #endif
793 
794 #ifdef TARGET_RISCV
795 
796 /*
797  * get_user_ual is defined as get_user_u32 in softmmu-semi.h,
798  * we need a macro that fetches a target_ulong
799  */
800 #define get_user_utl(arg, p)                    \
801     ((sizeof(target_ulong) == 8) ?              \
802      get_user_u64(arg, p) :                     \
803      get_user_u32(arg, p))
804 
805 /*
806  * put_user_ual is defined as put_user_u32 in softmmu-semi.h,
807  * we need a macro that stores a target_ulong
808  */
809 #define put_user_utl(arg, p)                    \
810     ((sizeof(target_ulong) == 8) ?              \
811      put_user_u64(arg, p) :                     \
812      put_user_u32(arg, p))
813 
814 #define GET_ARG(n) do {                                                 \
815         if (get_user_utl(arg ## n, args + (n) * sizeof(target_ulong))) { \
816             errno = EFAULT;                                             \
817             return set_swi_errno(cs, -1);                              \
818         }                                                               \
819     } while (0)
820 
821 #define SET_ARG(n, val)                                 \
822     put_user_utl(val, args + (n) * sizeof(target_ulong))
823 #endif
824 
825 /*
826  * Do a semihosting call.
827  *
828  * The specification always says that the "return register" either
829  * returns a specific value or is corrupted, so we don't need to
830  * report to our caller whether we are returning a value or trying to
831  * leave the register unchanged. We use 0xdeadbeef as the return value
832  * when there isn't a defined return value for the call.
833  */
834 target_ulong do_common_semihosting(CPUState *cs)
835 {
836     CPUArchState *env = cs->env_ptr;
837     target_ulong args;
838     target_ulong arg0, arg1, arg2, arg3;
839     target_ulong ul_ret;
840     char * s;
841     int nr;
842     uint32_t ret;
843     uint32_t len;
844     GuestFD *gf;
845     int64_t elapsed;
846 
847     (void) env; /* Used implicitly by arm lock_user macro */
848     nr = common_semi_arg(cs, 0) & 0xffffffffU;
849     args = common_semi_arg(cs, 1);
850 
851     switch (nr) {
852     case TARGET_SYS_OPEN:
853     {
854         int guestfd;
855 
856         GET_ARG(0);
857         GET_ARG(1);
858         GET_ARG(2);
859         s = lock_user_string(arg0);
860         if (!s) {
861             errno = EFAULT;
862             return set_swi_errno(cs, -1);
863         }
864         if (arg1 >= 12) {
865             unlock_user(s, arg0, 0);
866             errno = EINVAL;
867             return set_swi_errno(cs, -1);
868         }
869 
870         guestfd = alloc_guestfd();
871         if (guestfd < 0) {
872             unlock_user(s, arg0, 0);
873             errno = EMFILE;
874             return set_swi_errno(cs, -1);
875         }
876 
877         if (strcmp(s, ":tt") == 0) {
878             int result_fileno;
879 
880             /*
881              * We implement SH_EXT_STDOUT_STDERR, so:
882              *  open for read == stdin
883              *  open for write == stdout
884              *  open for append == stderr
885              */
886             if (arg1 < 4) {
887                 result_fileno = STDIN_FILENO;
888             } else if (arg1 < 8) {
889                 result_fileno = STDOUT_FILENO;
890             } else {
891                 result_fileno = STDERR_FILENO;
892             }
893             associate_guestfd(guestfd, result_fileno);
894             unlock_user(s, arg0, 0);
895             return guestfd;
896         }
897         if (strcmp(s, ":semihosting-features") == 0) {
898             unlock_user(s, arg0, 0);
899             /* We must fail opens for modes other than 0 ('r') or 1 ('rb') */
900             if (arg1 != 0 && arg1 != 1) {
901                 dealloc_guestfd(guestfd);
902                 errno = EACCES;
903                 return set_swi_errno(cs, -1);
904             }
905             init_featurefile_guestfd(guestfd);
906             return guestfd;
907         }
908 
909         if (use_gdb_syscalls()) {
910             common_semi_open_guestfd = guestfd;
911             ret = common_semi_gdb_syscall(cs, common_semi_open_cb,
912                                           "open,%s,%x,1a4", arg0, (int)arg2 + 1,
913                                           gdb_open_modeflags[arg1]);
914         } else {
915             ret = set_swi_errno(cs, open(s, open_modeflags[arg1], 0644));
916             if (ret == (uint32_t)-1) {
917                 dealloc_guestfd(guestfd);
918             } else {
919                 associate_guestfd(guestfd, ret);
920                 ret = guestfd;
921             }
922         }
923         unlock_user(s, arg0, 0);
924         return ret;
925     }
926     case TARGET_SYS_CLOSE:
927         GET_ARG(0);
928 
929         gf = get_guestfd(arg0);
930         if (!gf) {
931             errno = EBADF;
932             return set_swi_errno(cs, -1);
933         }
934 
935         ret = guestfd_fns[gf->type].closefn(cs, gf);
936         dealloc_guestfd(arg0);
937         return ret;
938     case TARGET_SYS_WRITEC:
939         qemu_semihosting_console_outc(cs->env_ptr, args);
940         return 0xdeadbeef;
941     case TARGET_SYS_WRITE0:
942         return qemu_semihosting_console_outs(cs->env_ptr, args);
943     case TARGET_SYS_WRITE:
944         GET_ARG(0);
945         GET_ARG(1);
946         GET_ARG(2);
947         len = arg2;
948 
949         gf = get_guestfd(arg0);
950         if (!gf) {
951             errno = EBADF;
952             return set_swi_errno(cs, -1);
953         }
954 
955         return guestfd_fns[gf->type].writefn(cs, gf, arg1, len);
956     case TARGET_SYS_READ:
957         GET_ARG(0);
958         GET_ARG(1);
959         GET_ARG(2);
960         len = arg2;
961 
962         gf = get_guestfd(arg0);
963         if (!gf) {
964             errno = EBADF;
965             return set_swi_errno(cs, -1);
966         }
967 
968         return guestfd_fns[gf->type].readfn(cs, gf, arg1, len);
969     case TARGET_SYS_READC:
970         return qemu_semihosting_console_inc(cs->env_ptr);
971     case TARGET_SYS_ISERROR:
972         GET_ARG(0);
973         return (target_long) arg0 < 0 ? 1 : 0;
974     case TARGET_SYS_ISTTY:
975         GET_ARG(0);
976 
977         gf = get_guestfd(arg0);
978         if (!gf) {
979             errno = EBADF;
980             return set_swi_errno(cs, -1);
981         }
982 
983         return guestfd_fns[gf->type].isattyfn(cs, gf);
984     case TARGET_SYS_SEEK:
985         GET_ARG(0);
986         GET_ARG(1);
987 
988         gf = get_guestfd(arg0);
989         if (!gf) {
990             errno = EBADF;
991             return set_swi_errno(cs, -1);
992         }
993 
994         return guestfd_fns[gf->type].seekfn(cs, gf, arg1);
995     case TARGET_SYS_FLEN:
996         GET_ARG(0);
997 
998         gf = get_guestfd(arg0);
999         if (!gf) {
1000             errno = EBADF;
1001             return set_swi_errno(cs, -1);
1002         }
1003 
1004         return guestfd_fns[gf->type].flenfn(cs, gf);
1005     case TARGET_SYS_TMPNAM:
1006         GET_ARG(0);
1007         GET_ARG(1);
1008         GET_ARG(2);
1009         if (asprintf(&s, "/tmp/qemu-%x%02x", getpid(),
1010                      (int) (arg1 & 0xff)) < 0) {
1011             return -1;
1012         }
1013         ul_ret = (target_ulong) -1;
1014 
1015         /* Make sure there's enough space in the buffer */
1016         if (strlen(s) < arg2) {
1017             char *output = lock_user(VERIFY_WRITE, arg0, arg2, 0);
1018             strcpy(output, s);
1019             unlock_user(output, arg0, arg2);
1020             ul_ret = 0;
1021         }
1022         free(s);
1023         return ul_ret;
1024     case TARGET_SYS_REMOVE:
1025         GET_ARG(0);
1026         GET_ARG(1);
1027         if (use_gdb_syscalls()) {
1028             ret = common_semi_gdb_syscall(cs, common_semi_cb, "unlink,%s",
1029                                           arg0, (int)arg1 + 1);
1030         } else {
1031             s = lock_user_string(arg0);
1032             if (!s) {
1033                 errno = EFAULT;
1034                 return set_swi_errno(cs, -1);
1035             }
1036             ret =  set_swi_errno(cs, remove(s));
1037             unlock_user(s, arg0, 0);
1038         }
1039         return ret;
1040     case TARGET_SYS_RENAME:
1041         GET_ARG(0);
1042         GET_ARG(1);
1043         GET_ARG(2);
1044         GET_ARG(3);
1045         if (use_gdb_syscalls()) {
1046             return common_semi_gdb_syscall(cs, common_semi_cb, "rename,%s,%s",
1047                                            arg0, (int)arg1 + 1, arg2,
1048                                            (int)arg3 + 1);
1049         } else {
1050             char *s2;
1051             s = lock_user_string(arg0);
1052             s2 = lock_user_string(arg2);
1053             if (!s || !s2) {
1054                 errno = EFAULT;
1055                 ret = set_swi_errno(cs, -1);
1056             } else {
1057                 ret = set_swi_errno(cs, rename(s, s2));
1058             }
1059             if (s2)
1060                 unlock_user(s2, arg2, 0);
1061             if (s)
1062                 unlock_user(s, arg0, 0);
1063             return ret;
1064         }
1065     case TARGET_SYS_CLOCK:
1066         return clock() / (CLOCKS_PER_SEC / 100);
1067     case TARGET_SYS_TIME:
1068         return set_swi_errno(cs, time(NULL));
1069     case TARGET_SYS_SYSTEM:
1070         GET_ARG(0);
1071         GET_ARG(1);
1072         if (use_gdb_syscalls()) {
1073             return common_semi_gdb_syscall(cs, common_semi_cb, "system,%s",
1074                                            arg0, (int)arg1 + 1);
1075         } else {
1076             s = lock_user_string(arg0);
1077             if (!s) {
1078                 errno = EFAULT;
1079                 return set_swi_errno(cs, -1);
1080             }
1081             ret = set_swi_errno(cs, system(s));
1082             unlock_user(s, arg0, 0);
1083             return ret;
1084         }
1085     case TARGET_SYS_ERRNO:
1086         return get_swi_errno(cs);
1087     case TARGET_SYS_GET_CMDLINE:
1088         {
1089             /* Build a command-line from the original argv.
1090              *
1091              * The inputs are:
1092              *     * arg0, pointer to a buffer of at least the size
1093              *               specified in arg1.
1094              *     * arg1, size of the buffer pointed to by arg0 in
1095              *               bytes.
1096              *
1097              * The outputs are:
1098              *     * arg0, pointer to null-terminated string of the
1099              *               command line.
1100              *     * arg1, length of the string pointed to by arg0.
1101              */
1102 
1103             char *output_buffer;
1104             size_t input_size;
1105             size_t output_size;
1106             int status = 0;
1107 #if !defined(CONFIG_USER_ONLY)
1108             const char *cmdline;
1109 #else
1110             TaskState *ts = cs->opaque;
1111 #endif
1112             GET_ARG(0);
1113             GET_ARG(1);
1114             input_size = arg1;
1115             /* Compute the size of the output string.  */
1116 #if !defined(CONFIG_USER_ONLY)
1117             cmdline = semihosting_get_cmdline();
1118             if (cmdline == NULL) {
1119                 cmdline = ""; /* Default to an empty line. */
1120             }
1121             output_size = strlen(cmdline) + 1; /* Count terminating 0. */
1122 #else
1123             unsigned int i;
1124 
1125             output_size = ts->info->arg_end - ts->info->arg_start;
1126             if (!output_size) {
1127                 /*
1128                  * We special-case the "empty command line" case (argc==0).
1129                  * Just provide the terminating 0.
1130                  */
1131                 output_size = 1;
1132             }
1133 #endif
1134 
1135             if (output_size > input_size) {
1136                 /* Not enough space to store command-line arguments.  */
1137                 errno = E2BIG;
1138                 return set_swi_errno(cs, -1);
1139             }
1140 
1141             /* Adjust the command-line length.  */
1142             if (SET_ARG(1, output_size - 1)) {
1143                 /* Couldn't write back to argument block */
1144                 errno = EFAULT;
1145                 return set_swi_errno(cs, -1);
1146             }
1147 
1148             /* Lock the buffer on the ARM side.  */
1149             output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0);
1150             if (!output_buffer) {
1151                 errno = EFAULT;
1152                 return set_swi_errno(cs, -1);
1153             }
1154 
1155             /* Copy the command-line arguments.  */
1156 #if !defined(CONFIG_USER_ONLY)
1157             pstrcpy(output_buffer, output_size, cmdline);
1158 #else
1159             if (output_size == 1) {
1160                 /* Empty command-line.  */
1161                 output_buffer[0] = '\0';
1162                 goto out;
1163             }
1164 
1165             if (copy_from_user(output_buffer, ts->info->arg_start,
1166                                output_size)) {
1167                 errno = EFAULT;
1168                 status = set_swi_errno(cs, -1);
1169                 goto out;
1170             }
1171 
1172             /* Separate arguments by white spaces.  */
1173             for (i = 0; i < output_size - 1; i++) {
1174                 if (output_buffer[i] == 0) {
1175                     output_buffer[i] = ' ';
1176                 }
1177             }
1178         out:
1179 #endif
1180             /* Unlock the buffer on the ARM side.  */
1181             unlock_user(output_buffer, arg0, output_size);
1182 
1183             return status;
1184         }
1185     case TARGET_SYS_HEAPINFO:
1186         {
1187             target_ulong retvals[4];
1188             target_ulong limit;
1189             int i;
1190 #ifdef CONFIG_USER_ONLY
1191             TaskState *ts = cs->opaque;
1192 #else
1193             target_ulong rambase = common_semi_rambase(cs);
1194 #endif
1195 
1196             GET_ARG(0);
1197 
1198 #ifdef CONFIG_USER_ONLY
1199             /*
1200              * Some C libraries assume the heap immediately follows .bss, so
1201              * allocate it using sbrk.
1202              */
1203             if (!ts->heap_limit) {
1204                 abi_ulong ret;
1205 
1206                 ts->heap_base = do_brk(0);
1207                 limit = ts->heap_base + COMMON_SEMI_HEAP_SIZE;
1208                 /* Try a big heap, and reduce the size if that fails.  */
1209                 for (;;) {
1210                     ret = do_brk(limit);
1211                     if (ret >= limit) {
1212                         break;
1213                     }
1214                     limit = (ts->heap_base >> 1) + (limit >> 1);
1215                 }
1216                 ts->heap_limit = limit;
1217             }
1218 
1219             retvals[0] = ts->heap_base;
1220             retvals[1] = ts->heap_limit;
1221             retvals[2] = ts->stack_base;
1222             retvals[3] = 0; /* Stack limit.  */
1223 #else
1224             limit = current_machine->ram_size;
1225             /* TODO: Make this use the limit of the loaded application.  */
1226             retvals[0] = rambase + limit / 2;
1227             retvals[1] = rambase + limit;
1228             retvals[2] = rambase + limit; /* Stack base */
1229             retvals[3] = rambase; /* Stack limit.  */
1230 #endif
1231 
1232             for (i = 0; i < ARRAY_SIZE(retvals); i++) {
1233                 bool fail;
1234 
1235                 fail = SET_ARG(i, retvals[i]);
1236 
1237                 if (fail) {
1238                     /* Couldn't write back to argument block */
1239                     errno = EFAULT;
1240                     return set_swi_errno(cs, -1);
1241                 }
1242             }
1243             return 0;
1244         }
1245     case TARGET_SYS_EXIT:
1246     case TARGET_SYS_EXIT_EXTENDED:
1247         if (common_semi_sys_exit_extended(cs, nr)) {
1248             /*
1249              * The A64 version of SYS_EXIT takes a parameter block,
1250              * so the application-exit type can return a subcode which
1251              * is the exit status code from the application.
1252              * SYS_EXIT_EXTENDED is an a new-in-v2.0 optional function
1253              * which allows A32/T32 guests to also provide a status code.
1254              */
1255             GET_ARG(0);
1256             GET_ARG(1);
1257 
1258             if (arg0 == ADP_Stopped_ApplicationExit) {
1259                 ret = arg1;
1260             } else {
1261                 ret = 1;
1262             }
1263         } else {
1264             /*
1265              * The A32/T32 version of SYS_EXIT specifies only
1266              * Stopped_ApplicationExit as normal exit, but does not
1267              * allow the guest to specify the exit status code.
1268              * Everything else is considered an error.
1269              */
1270             ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;
1271         }
1272         gdb_exit(ret);
1273         exit(ret);
1274     case TARGET_SYS_ELAPSED:
1275         elapsed = get_clock() - clock_start;
1276         if (sizeof(target_ulong) == 8) {
1277             SET_ARG(0, elapsed);
1278         } else {
1279             SET_ARG(0, (uint32_t) elapsed);
1280             SET_ARG(1, (uint32_t) (elapsed >> 32));
1281         }
1282         return 0;
1283     case TARGET_SYS_TICKFREQ:
1284         /* qemu always uses nsec */
1285         return 1000000000;
1286     case TARGET_SYS_SYNCCACHE:
1287         /*
1288          * Clean the D-cache and invalidate the I-cache for the specified
1289          * virtual address range. This is a nop for us since we don't
1290          * implement caches. This is only present on A64.
1291          */
1292 #ifdef TARGET_ARM
1293         if (is_a64(cs->env_ptr)) {
1294             return 0;
1295         }
1296 #endif
1297 #ifdef TARGET_RISCV
1298         return 0;
1299 #endif
1300         /* fall through -- invalid for A32/T32 */
1301     default:
1302         fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
1303         cpu_dump_state(cs, stderr, 0);
1304         abort();
1305     }
1306 }
1307