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