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 /*
771  * Read the input value from the argument block; fail the semihosting
772  * call if the memory read fails. Eventually we could use a generic
773  * CPUState helper function here.
774  */
775 static inline bool is_64bit_semihosting(CPUArchState *env)
776 {
777 #if defined(TARGET_ARM)
778     return is_a64(env);
779 #elif defined(TARGET_RISCV)
780     return !riscv_cpu_is_32bit(env);
781 #else
782 #error un-handled architecture
783 #endif
784 }
785 
786 
787 #define GET_ARG(n) do {                                 \
788     if (is_64bit_semihosting(env)) {                    \
789         if (get_user_u64(arg ## n, args + (n) * 8)) {   \
790             errno = EFAULT;                             \
791             return set_swi_errno(cs, -1);               \
792         }                                               \
793     } else {                                            \
794         if (get_user_u32(arg ## n, args + (n) * 4)) {   \
795             errno = EFAULT;                             \
796             return set_swi_errno(cs, -1);              \
797         }                                               \
798     }                                                   \
799 } while (0)
800 
801 #define SET_ARG(n, val)                                 \
802     (is_64bit_semihosting(env) ?                        \
803      put_user_u64(val, args + (n) * 8) :                \
804      put_user_u32(val, args + (n) * 4))
805 
806 
807 /*
808  * Do a semihosting call.
809  *
810  * The specification always says that the "return register" either
811  * returns a specific value or is corrupted, so we don't need to
812  * report to our caller whether we are returning a value or trying to
813  * leave the register unchanged. We use 0xdeadbeef as the return value
814  * when there isn't a defined return value for the call.
815  */
816 target_ulong do_common_semihosting(CPUState *cs)
817 {
818     CPUArchState *env = cs->env_ptr;
819     target_ulong args;
820     target_ulong arg0, arg1, arg2, arg3;
821     target_ulong ul_ret;
822     char * s;
823     int nr;
824     uint32_t ret;
825     uint32_t len;
826     GuestFD *gf;
827     int64_t elapsed;
828 
829     (void) env; /* Used implicitly by arm lock_user macro */
830     nr = common_semi_arg(cs, 0) & 0xffffffffU;
831     args = common_semi_arg(cs, 1);
832 
833     switch (nr) {
834     case TARGET_SYS_OPEN:
835     {
836         int guestfd;
837 
838         GET_ARG(0);
839         GET_ARG(1);
840         GET_ARG(2);
841         s = lock_user_string(arg0);
842         if (!s) {
843             errno = EFAULT;
844             return set_swi_errno(cs, -1);
845         }
846         if (arg1 >= 12) {
847             unlock_user(s, arg0, 0);
848             errno = EINVAL;
849             return set_swi_errno(cs, -1);
850         }
851 
852         guestfd = alloc_guestfd();
853         if (guestfd < 0) {
854             unlock_user(s, arg0, 0);
855             errno = EMFILE;
856             return set_swi_errno(cs, -1);
857         }
858 
859         if (strcmp(s, ":tt") == 0) {
860             int result_fileno;
861 
862             /*
863              * We implement SH_EXT_STDOUT_STDERR, so:
864              *  open for read == stdin
865              *  open for write == stdout
866              *  open for append == stderr
867              */
868             if (arg1 < 4) {
869                 result_fileno = STDIN_FILENO;
870             } else if (arg1 < 8) {
871                 result_fileno = STDOUT_FILENO;
872             } else {
873                 result_fileno = STDERR_FILENO;
874             }
875             associate_guestfd(guestfd, result_fileno);
876             unlock_user(s, arg0, 0);
877             return guestfd;
878         }
879         if (strcmp(s, ":semihosting-features") == 0) {
880             unlock_user(s, arg0, 0);
881             /* We must fail opens for modes other than 0 ('r') or 1 ('rb') */
882             if (arg1 != 0 && arg1 != 1) {
883                 dealloc_guestfd(guestfd);
884                 errno = EACCES;
885                 return set_swi_errno(cs, -1);
886             }
887             init_featurefile_guestfd(guestfd);
888             return guestfd;
889         }
890 
891         if (use_gdb_syscalls()) {
892             common_semi_open_guestfd = guestfd;
893             ret = common_semi_gdb_syscall(cs, common_semi_open_cb,
894                                           "open,%s,%x,1a4", arg0, (int)arg2 + 1,
895                                           gdb_open_modeflags[arg1]);
896         } else {
897             ret = set_swi_errno(cs, open(s, open_modeflags[arg1], 0644));
898             if (ret == (uint32_t)-1) {
899                 dealloc_guestfd(guestfd);
900             } else {
901                 associate_guestfd(guestfd, ret);
902                 ret = guestfd;
903             }
904         }
905         unlock_user(s, arg0, 0);
906         return ret;
907     }
908     case TARGET_SYS_CLOSE:
909         GET_ARG(0);
910 
911         gf = get_guestfd(arg0);
912         if (!gf) {
913             errno = EBADF;
914             return set_swi_errno(cs, -1);
915         }
916 
917         ret = guestfd_fns[gf->type].closefn(cs, gf);
918         dealloc_guestfd(arg0);
919         return ret;
920     case TARGET_SYS_WRITEC:
921         qemu_semihosting_console_outc(cs->env_ptr, args);
922         return 0xdeadbeef;
923     case TARGET_SYS_WRITE0:
924         return qemu_semihosting_console_outs(cs->env_ptr, args);
925     case TARGET_SYS_WRITE:
926         GET_ARG(0);
927         GET_ARG(1);
928         GET_ARG(2);
929         len = arg2;
930 
931         gf = get_guestfd(arg0);
932         if (!gf) {
933             errno = EBADF;
934             return set_swi_errno(cs, -1);
935         }
936 
937         return guestfd_fns[gf->type].writefn(cs, gf, arg1, len);
938     case TARGET_SYS_READ:
939         GET_ARG(0);
940         GET_ARG(1);
941         GET_ARG(2);
942         len = arg2;
943 
944         gf = get_guestfd(arg0);
945         if (!gf) {
946             errno = EBADF;
947             return set_swi_errno(cs, -1);
948         }
949 
950         return guestfd_fns[gf->type].readfn(cs, gf, arg1, len);
951     case TARGET_SYS_READC:
952         return qemu_semihosting_console_inc(cs->env_ptr);
953     case TARGET_SYS_ISERROR:
954         GET_ARG(0);
955         return (target_long) arg0 < 0 ? 1 : 0;
956     case TARGET_SYS_ISTTY:
957         GET_ARG(0);
958 
959         gf = get_guestfd(arg0);
960         if (!gf) {
961             errno = EBADF;
962             return set_swi_errno(cs, -1);
963         }
964 
965         return guestfd_fns[gf->type].isattyfn(cs, gf);
966     case TARGET_SYS_SEEK:
967         GET_ARG(0);
968         GET_ARG(1);
969 
970         gf = get_guestfd(arg0);
971         if (!gf) {
972             errno = EBADF;
973             return set_swi_errno(cs, -1);
974         }
975 
976         return guestfd_fns[gf->type].seekfn(cs, gf, arg1);
977     case TARGET_SYS_FLEN:
978         GET_ARG(0);
979 
980         gf = get_guestfd(arg0);
981         if (!gf) {
982             errno = EBADF;
983             return set_swi_errno(cs, -1);
984         }
985 
986         return guestfd_fns[gf->type].flenfn(cs, gf);
987     case TARGET_SYS_TMPNAM:
988         GET_ARG(0);
989         GET_ARG(1);
990         GET_ARG(2);
991         if (asprintf(&s, "/tmp/qemu-%x%02x", getpid(),
992                      (int) (arg1 & 0xff)) < 0) {
993             return -1;
994         }
995         ul_ret = (target_ulong) -1;
996 
997         /* Make sure there's enough space in the buffer */
998         if (strlen(s) < arg2) {
999             char *output = lock_user(VERIFY_WRITE, arg0, arg2, 0);
1000             strcpy(output, s);
1001             unlock_user(output, arg0, arg2);
1002             ul_ret = 0;
1003         }
1004         free(s);
1005         return ul_ret;
1006     case TARGET_SYS_REMOVE:
1007         GET_ARG(0);
1008         GET_ARG(1);
1009         if (use_gdb_syscalls()) {
1010             ret = common_semi_gdb_syscall(cs, common_semi_cb, "unlink,%s",
1011                                           arg0, (int)arg1 + 1);
1012         } else {
1013             s = lock_user_string(arg0);
1014             if (!s) {
1015                 errno = EFAULT;
1016                 return set_swi_errno(cs, -1);
1017             }
1018             ret =  set_swi_errno(cs, remove(s));
1019             unlock_user(s, arg0, 0);
1020         }
1021         return ret;
1022     case TARGET_SYS_RENAME:
1023         GET_ARG(0);
1024         GET_ARG(1);
1025         GET_ARG(2);
1026         GET_ARG(3);
1027         if (use_gdb_syscalls()) {
1028             return common_semi_gdb_syscall(cs, common_semi_cb, "rename,%s,%s",
1029                                            arg0, (int)arg1 + 1, arg2,
1030                                            (int)arg3 + 1);
1031         } else {
1032             char *s2;
1033             s = lock_user_string(arg0);
1034             s2 = lock_user_string(arg2);
1035             if (!s || !s2) {
1036                 errno = EFAULT;
1037                 ret = set_swi_errno(cs, -1);
1038             } else {
1039                 ret = set_swi_errno(cs, rename(s, s2));
1040             }
1041             if (s2)
1042                 unlock_user(s2, arg2, 0);
1043             if (s)
1044                 unlock_user(s, arg0, 0);
1045             return ret;
1046         }
1047     case TARGET_SYS_CLOCK:
1048         return clock() / (CLOCKS_PER_SEC / 100);
1049     case TARGET_SYS_TIME:
1050         return set_swi_errno(cs, time(NULL));
1051     case TARGET_SYS_SYSTEM:
1052         GET_ARG(0);
1053         GET_ARG(1);
1054         if (use_gdb_syscalls()) {
1055             return common_semi_gdb_syscall(cs, common_semi_cb, "system,%s",
1056                                            arg0, (int)arg1 + 1);
1057         } else {
1058             s = lock_user_string(arg0);
1059             if (!s) {
1060                 errno = EFAULT;
1061                 return set_swi_errno(cs, -1);
1062             }
1063             ret = set_swi_errno(cs, system(s));
1064             unlock_user(s, arg0, 0);
1065             return ret;
1066         }
1067     case TARGET_SYS_ERRNO:
1068         return get_swi_errno(cs);
1069     case TARGET_SYS_GET_CMDLINE:
1070         {
1071             /* Build a command-line from the original argv.
1072              *
1073              * The inputs are:
1074              *     * arg0, pointer to a buffer of at least the size
1075              *               specified in arg1.
1076              *     * arg1, size of the buffer pointed to by arg0 in
1077              *               bytes.
1078              *
1079              * The outputs are:
1080              *     * arg0, pointer to null-terminated string of the
1081              *               command line.
1082              *     * arg1, length of the string pointed to by arg0.
1083              */
1084 
1085             char *output_buffer;
1086             size_t input_size;
1087             size_t output_size;
1088             int status = 0;
1089 #if !defined(CONFIG_USER_ONLY)
1090             const char *cmdline;
1091 #else
1092             TaskState *ts = cs->opaque;
1093 #endif
1094             GET_ARG(0);
1095             GET_ARG(1);
1096             input_size = arg1;
1097             /* Compute the size of the output string.  */
1098 #if !defined(CONFIG_USER_ONLY)
1099             cmdline = semihosting_get_cmdline();
1100             if (cmdline == NULL) {
1101                 cmdline = ""; /* Default to an empty line. */
1102             }
1103             output_size = strlen(cmdline) + 1; /* Count terminating 0. */
1104 #else
1105             unsigned int i;
1106 
1107             output_size = ts->info->arg_end - ts->info->arg_start;
1108             if (!output_size) {
1109                 /*
1110                  * We special-case the "empty command line" case (argc==0).
1111                  * Just provide the terminating 0.
1112                  */
1113                 output_size = 1;
1114             }
1115 #endif
1116 
1117             if (output_size > input_size) {
1118                 /* Not enough space to store command-line arguments.  */
1119                 errno = E2BIG;
1120                 return set_swi_errno(cs, -1);
1121             }
1122 
1123             /* Adjust the command-line length.  */
1124             if (SET_ARG(1, output_size - 1)) {
1125                 /* Couldn't write back to argument block */
1126                 errno = EFAULT;
1127                 return set_swi_errno(cs, -1);
1128             }
1129 
1130             /* Lock the buffer on the ARM side.  */
1131             output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0);
1132             if (!output_buffer) {
1133                 errno = EFAULT;
1134                 return set_swi_errno(cs, -1);
1135             }
1136 
1137             /* Copy the command-line arguments.  */
1138 #if !defined(CONFIG_USER_ONLY)
1139             pstrcpy(output_buffer, output_size, cmdline);
1140 #else
1141             if (output_size == 1) {
1142                 /* Empty command-line.  */
1143                 output_buffer[0] = '\0';
1144                 goto out;
1145             }
1146 
1147             if (copy_from_user(output_buffer, ts->info->arg_start,
1148                                output_size)) {
1149                 errno = EFAULT;
1150                 status = set_swi_errno(cs, -1);
1151                 goto out;
1152             }
1153 
1154             /* Separate arguments by white spaces.  */
1155             for (i = 0; i < output_size - 1; i++) {
1156                 if (output_buffer[i] == 0) {
1157                     output_buffer[i] = ' ';
1158                 }
1159             }
1160         out:
1161 #endif
1162             /* Unlock the buffer on the ARM side.  */
1163             unlock_user(output_buffer, arg0, output_size);
1164 
1165             return status;
1166         }
1167     case TARGET_SYS_HEAPINFO:
1168         {
1169             target_ulong retvals[4];
1170             target_ulong limit;
1171             int i;
1172 #ifdef CONFIG_USER_ONLY
1173             TaskState *ts = cs->opaque;
1174 #else
1175             target_ulong rambase = common_semi_rambase(cs);
1176 #endif
1177 
1178             GET_ARG(0);
1179 
1180 #ifdef CONFIG_USER_ONLY
1181             /*
1182              * Some C libraries assume the heap immediately follows .bss, so
1183              * allocate it using sbrk.
1184              */
1185             if (!ts->heap_limit) {
1186                 abi_ulong ret;
1187 
1188                 ts->heap_base = do_brk(0);
1189                 limit = ts->heap_base + COMMON_SEMI_HEAP_SIZE;
1190                 /* Try a big heap, and reduce the size if that fails.  */
1191                 for (;;) {
1192                     ret = do_brk(limit);
1193                     if (ret >= limit) {
1194                         break;
1195                     }
1196                     limit = (ts->heap_base >> 1) + (limit >> 1);
1197                 }
1198                 ts->heap_limit = limit;
1199             }
1200 
1201             retvals[0] = ts->heap_base;
1202             retvals[1] = ts->heap_limit;
1203             retvals[2] = ts->stack_base;
1204             retvals[3] = 0; /* Stack limit.  */
1205 #else
1206             limit = current_machine->ram_size;
1207             /* TODO: Make this use the limit of the loaded application.  */
1208             retvals[0] = rambase + limit / 2;
1209             retvals[1] = rambase + limit;
1210             retvals[2] = rambase + limit; /* Stack base */
1211             retvals[3] = rambase; /* Stack limit.  */
1212 #endif
1213 
1214             for (i = 0; i < ARRAY_SIZE(retvals); i++) {
1215                 bool fail;
1216 
1217                 if (is_64bit_semihosting(env)) {
1218                     fail = put_user_u64(retvals[i], arg0 + i * 8);
1219                 } else {
1220                     fail = put_user_u32(retvals[i], arg0 + i * 4);
1221                 }
1222 
1223                 if (fail) {
1224                     /* Couldn't write back to argument block */
1225                     errno = EFAULT;
1226                     return set_swi_errno(cs, -1);
1227                 }
1228             }
1229             return 0;
1230         }
1231     case TARGET_SYS_EXIT:
1232     case TARGET_SYS_EXIT_EXTENDED:
1233         if (common_semi_sys_exit_extended(cs, nr)) {
1234             /*
1235              * The A64 version of SYS_EXIT takes a parameter block,
1236              * so the application-exit type can return a subcode which
1237              * is the exit status code from the application.
1238              * SYS_EXIT_EXTENDED is an a new-in-v2.0 optional function
1239              * which allows A32/T32 guests to also provide a status code.
1240              */
1241             GET_ARG(0);
1242             GET_ARG(1);
1243 
1244             if (arg0 == ADP_Stopped_ApplicationExit) {
1245                 ret = arg1;
1246             } else {
1247                 ret = 1;
1248             }
1249         } else {
1250             /*
1251              * The A32/T32 version of SYS_EXIT specifies only
1252              * Stopped_ApplicationExit as normal exit, but does not
1253              * allow the guest to specify the exit status code.
1254              * Everything else is considered an error.
1255              */
1256             ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;
1257         }
1258         gdb_exit(ret);
1259         exit(ret);
1260     case TARGET_SYS_ELAPSED:
1261         elapsed = get_clock() - clock_start;
1262         if (sizeof(target_ulong) == 8) {
1263             SET_ARG(0, elapsed);
1264         } else {
1265             SET_ARG(0, (uint32_t) elapsed);
1266             SET_ARG(1, (uint32_t) (elapsed >> 32));
1267         }
1268         return 0;
1269     case TARGET_SYS_TICKFREQ:
1270         /* qemu always uses nsec */
1271         return 1000000000;
1272     case TARGET_SYS_SYNCCACHE:
1273         /*
1274          * Clean the D-cache and invalidate the I-cache for the specified
1275          * virtual address range. This is a nop for us since we don't
1276          * implement caches. This is only present on A64.
1277          */
1278 #ifdef TARGET_ARM
1279         if (is_a64(cs->env_ptr)) {
1280             return 0;
1281         }
1282 #endif
1283 #ifdef TARGET_RISCV
1284         return 0;
1285 #endif
1286         /* fall through -- invalid for A32/T32 */
1287     default:
1288         fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
1289         cpu_dump_state(cs, stderr, 0);
1290         abort();
1291     }
1292 }
1293