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