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