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