Lines Matching +full:cs +full:- +full:1

6  * SPDX-License-Identifier: GPL-2.0-or-later
25 static int validate_strlen(CPUState *cs, target_ulong str, target_ulong tlen) in validate_strlen() argument
27 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in validate_strlen()
34 return -EFAULT; in validate_strlen()
37 return -ENAMETOOLONG; in validate_strlen()
39 return slen + 1; in validate_strlen()
42 return -ENAMETOOLONG; in validate_strlen()
44 if (get_user_u8(c, str + tlen - 1)) { in validate_strlen()
45 return -EFAULT; in validate_strlen()
48 return -EINVAL; in validate_strlen()
53 static int validate_lock_user_string(char **pstr, CPUState *cs, in validate_lock_user_string() argument
56 int ret = validate_strlen(cs, tstr, tlen); in validate_lock_user_string()
57 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in validate_lock_user_string()
62 ret = str ? 0 : -EFAULT; in validate_lock_user_string()
69 * TODO: Note that gdb always stores the stat structure big-endian.
71 * big-endian. Until we do something with gdb, also produce the
72 * same big-endian result from the host.
74 static int copy_stat_to_user(CPUState *cs, target_ulong addr, in copy_stat_to_user() argument
77 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in copy_stat_to_user()
80 if (s->st_dev != (uint32_t)s->st_dev || in copy_stat_to_user()
81 s->st_ino != (uint32_t)s->st_ino) { in copy_stat_to_user()
82 return -EOVERFLOW; in copy_stat_to_user()
87 return -EFAULT; in copy_stat_to_user()
90 p->gdb_st_dev = cpu_to_be32(s->st_dev); in copy_stat_to_user()
91 p->gdb_st_ino = cpu_to_be32(s->st_ino); in copy_stat_to_user()
92 p->gdb_st_mode = cpu_to_be32(s->st_mode); in copy_stat_to_user()
93 p->gdb_st_nlink = cpu_to_be32(s->st_nlink); in copy_stat_to_user()
94 p->gdb_st_uid = cpu_to_be32(s->st_uid); in copy_stat_to_user()
95 p->gdb_st_gid = cpu_to_be32(s->st_gid); in copy_stat_to_user()
96 p->gdb_st_rdev = cpu_to_be32(s->st_rdev); in copy_stat_to_user()
97 p->gdb_st_size = cpu_to_be64(s->st_size); in copy_stat_to_user()
100 p->gdb_st_blksize = 0; in copy_stat_to_user()
101 p->gdb_st_blocks = 0; in copy_stat_to_user()
103 p->gdb_st_blksize = cpu_to_be64(s->st_blksize); in copy_stat_to_user()
104 p->gdb_st_blocks = cpu_to_be64(s->st_blocks); in copy_stat_to_user()
106 p->gdb_st_atime = cpu_to_be32(s->st_atime); in copy_stat_to_user()
107 p->gdb_st_mtime = cpu_to_be32(s->st_mtime); in copy_stat_to_user()
108 p->gdb_st_ctime = cpu_to_be32(s->st_ctime); in copy_stat_to_user()
120 static void gdb_open_cb(CPUState *cs, uint64_t ret, int err) in gdb_open_cb() argument
127 gdb_open_complete(cs, ret, err); in gdb_open_cb()
130 static void gdb_open(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_open() argument
134 int len = validate_strlen(cs, fname, fname_len); in gdb_open()
136 complete(cs, -1, -len); in gdb_open()
146 static void gdb_close(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_close() argument
149 gdb_do_syscall(complete, "close,%x", (uint32_t)gf->hostfd); in gdb_close()
152 static void gdb_read(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_read() argument
156 (uint32_t)gf->hostfd, (uint64_t)buf, (uint64_t)len); in gdb_read()
159 static void gdb_write(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_write() argument
163 (uint32_t)gf->hostfd, (uint64_t)buf, (uint64_t)len); in gdb_write()
166 static void gdb_lseek(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_lseek() argument
170 (uint32_t)gf->hostfd, off, (uint32_t)gdb_whence); in gdb_lseek()
173 static void gdb_isatty(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_isatty() argument
176 gdb_do_syscall(complete, "isatty,%x", (uint32_t)gf->hostfd); in gdb_isatty()
179 static void gdb_fstat(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_fstat() argument
183 (uint32_t)gf->hostfd, (uint64_t)addr); in gdb_fstat()
186 static void gdb_stat(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_stat() argument
190 int len = validate_strlen(cs, fname, fname_len); in gdb_stat()
192 complete(cs, -1, -len); in gdb_stat()
200 static void gdb_remove(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_remove() argument
203 int len = validate_strlen(cs, fname, fname_len); in gdb_remove()
205 complete(cs, -1, -len); in gdb_remove()
212 static void gdb_rename(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_rename() argument
218 olen = validate_strlen(cs, oname, oname_len); in gdb_rename()
220 complete(cs, -1, -olen); in gdb_rename()
223 nlen = validate_strlen(cs, nname, nname_len); in gdb_rename()
225 complete(cs, -1, -nlen); in gdb_rename()
234 static void gdb_system(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_system() argument
237 int len = validate_strlen(cs, cmd, cmd_len); in gdb_system()
239 complete(cs, -1, -len); in gdb_system()
246 static void gdb_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete, in gdb_gettimeofday() argument
257 static void host_open(CPUState *cs, gdb_syscall_complete_cb complete, in host_open() argument
261 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in host_open()
265 ret = validate_lock_user_string(&p, cs, fname, fname_len); in host_open()
267 complete(cs, -1, -ret); in host_open()
290 complete(cs, -1, errno); in host_open()
294 complete(cs, guestfd, 0); in host_open()
299 static void host_close(CPUState *cs, gdb_syscall_complete_cb complete, in host_close() argument
306 if (gf->hostfd != STDIN_FILENO && in host_close()
307 gf->hostfd != STDOUT_FILENO && in host_close()
308 gf->hostfd != STDERR_FILENO && in host_close()
309 close(gf->hostfd) < 0) { in host_close()
310 complete(cs, -1, errno); in host_close()
312 complete(cs, 0, 0); in host_close()
316 static void host_read(CPUState *cs, gdb_syscall_complete_cb complete, in host_read() argument
319 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in host_read()
324 complete(cs, -1, EFAULT); in host_read()
327 ret = RETRY_ON_EINTR(read(gf->hostfd, ptr, len)); in host_read()
328 if (ret == -1) { in host_read()
330 complete(cs, -1, errno); in host_read()
333 complete(cs, ret, 0); in host_read()
337 static void host_write(CPUState *cs, gdb_syscall_complete_cb complete, in host_write() argument
340 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in host_write()
341 void *ptr = lock_user(VERIFY_READ, buf, len, 1); in host_write()
345 complete(cs, -1, EFAULT); in host_write()
348 ret = write(gf->hostfd, ptr, len); in host_write()
350 complete(cs, ret, ret == -1 ? errno : 0); in host_write()
353 static void host_lseek(CPUState *cs, gdb_syscall_complete_cb complete, in host_lseek() argument
365 ret = lseek(gf->hostfd, ret, whence); in host_lseek()
366 if (ret == -1) { in host_lseek()
370 ret = -1; in host_lseek()
373 complete(cs, ret, err); in host_lseek()
376 static void host_isatty(CPUState *cs, gdb_syscall_complete_cb complete, in host_isatty() argument
379 int ret = isatty(gf->hostfd); in host_isatty()
380 complete(cs, ret, ret ? 0 : errno); in host_isatty()
383 static void host_flen(CPUState *cs, gdb_syscall_complete_cb complete, in host_flen() argument
388 if (fstat(gf->hostfd, &buf) < 0) { in host_flen()
389 complete(cs, -1, errno); in host_flen()
391 complete(cs, buf.st_size, 0); in host_flen()
395 static void host_fstat(CPUState *cs, gdb_syscall_complete_cb complete, in host_fstat() argument
401 ret = fstat(gf->hostfd, &buf); in host_fstat()
403 complete(cs, -1, errno); in host_fstat()
406 ret = copy_stat_to_user(cs, addr, &buf); in host_fstat()
407 complete(cs, ret ? -1 : 0, ret ? -ret : 0); in host_fstat()
410 static void host_stat(CPUState *cs, gdb_syscall_complete_cb complete, in host_stat() argument
414 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in host_stat()
419 ret = validate_lock_user_string(&name, cs, fname, fname_len); in host_stat()
421 complete(cs, -1, -ret); in host_stat()
429 ret = copy_stat_to_user(cs, addr, &buf); in host_stat()
432 err = -ret; in host_stat()
433 ret = -1; in host_stat()
437 complete(cs, ret, err); in host_stat()
440 static void host_remove(CPUState *cs, gdb_syscall_complete_cb complete, in host_remove() argument
443 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in host_remove()
447 ret = validate_lock_user_string(&p, cs, fname, fname_len); in host_remove()
449 complete(cs, -1, -ret); in host_remove()
455 complete(cs, ret, ret ? errno : 0); in host_remove()
458 static void host_rename(CPUState *cs, gdb_syscall_complete_cb complete, in host_rename() argument
462 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in host_rename()
466 ret = validate_lock_user_string(&ostr, cs, oname, oname_len); in host_rename()
468 complete(cs, -1, -ret); in host_rename()
471 ret = validate_lock_user_string(&nstr, cs, nname, nname_len); in host_rename()
474 complete(cs, -1, -ret); in host_rename()
481 complete(cs, ret, ret ? errno : 0); in host_rename()
484 static void host_system(CPUState *cs, gdb_syscall_complete_cb complete, in host_system() argument
487 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in host_system()
491 ret = validate_lock_user_string(&p, cs, cmd, cmd_len); in host_system()
493 complete(cs, -1, -ret); in host_system()
499 complete(cs, ret, ret == -1 ? errno : 0); in host_system()
502 static void host_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete, in host_gettimeofday() argument
505 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in host_gettimeofday()
509 /* GDB fails on non-null TZ, so be consistent. */ in host_gettimeofday()
511 complete(cs, -1, EINVAL); in host_gettimeofday()
517 complete(cs, -1, EFAULT); in host_gettimeofday()
521 /* TODO: Like stat, gdb always produces big-endian results; match it. */ in host_gettimeofday()
523 p->tv_sec = cpu_to_be32(rt / G_USEC_PER_SEC); in host_gettimeofday()
524 p->tv_usec = cpu_to_be64(rt % G_USEC_PER_SEC); in host_gettimeofday()
529 static void host_poll_one(CPUState *cs, gdb_syscall_complete_cb complete, in host_poll_one() argument
539 complete(cs, cond & (G_IO_IN | G_IO_OUT), 0); in host_poll_one()
547 static void staticfile_read(CPUState *cs, gdb_syscall_complete_cb complete, in staticfile_read() argument
550 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in staticfile_read()
551 target_ulong rest = gf->staticfile.len - gf->staticfile.off; in staticfile_read()
559 complete(cs, -1, EFAULT); in staticfile_read()
562 memcpy(ptr, gf->staticfile.data + gf->staticfile.off, len); in staticfile_read()
563 gf->staticfile.off += len; in staticfile_read()
565 complete(cs, len, 0); in staticfile_read()
568 static void staticfile_lseek(CPUState *cs, gdb_syscall_complete_cb complete, in staticfile_lseek() argument
578 ret = gf->staticfile.off + off; in staticfile_lseek()
581 ret = gf->staticfile.len + off; in staticfile_lseek()
584 ret = -1; in staticfile_lseek()
587 if (ret >= 0 && ret <= gf->staticfile.len) { in staticfile_lseek()
588 gf->staticfile.off = ret; in staticfile_lseek()
589 complete(cs, ret, 0); in staticfile_lseek()
591 complete(cs, -1, EINVAL); in staticfile_lseek()
595 static void staticfile_flen(CPUState *cs, gdb_syscall_complete_cb complete, in staticfile_flen() argument
598 complete(cs, gf->staticfile.len, 0); in staticfile_flen()
605 static void console_read(CPUState *cs, gdb_syscall_complete_cb complete, in console_read() argument
608 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in console_read()
614 complete(cs, -1, EFAULT); in console_read()
617 ret = qemu_semihosting_console_read(cs, ptr, len); in console_read()
619 complete(cs, ret, 0); in console_read()
622 static void console_write(CPUState *cs, gdb_syscall_complete_cb complete, in console_write() argument
625 CPUArchState *env G_GNUC_UNUSED = cpu_env(cs); in console_write()
626 char *ptr = lock_user(VERIFY_READ, buf, len, 1); in console_write()
630 complete(cs, -1, EFAULT); in console_write()
635 complete(cs, ret ? ret : -1, ret ? 0 : EIO); in console_write()
638 static void console_fstat(CPUState *cs, gdb_syscall_complete_cb complete, in console_fstat() argument
643 .st_rdev = 5, /* makedev(5, 0) -- linux /dev/tty */ in console_fstat()
647 ret = copy_stat_to_user(cs, addr, &tty_buf); in console_fstat()
648 complete(cs, ret ? -1 : 0, ret ? -ret : 0); in console_fstat()
652 static void console_poll_one(CPUState *cs, gdb_syscall_complete_cb complete, in console_poll_one() argument
660 * consider output always ready -- leave G_IO_OUT alone. in console_poll_one()
669 qemu_semihosting_console_block_until_ready(cs); in console_poll_one()
670 /* We returned -- input must be ready. */ in console_poll_one()
675 complete(cs, cond, 0); in console_poll_one()
683 void semihost_sys_open(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_open() argument
688 gdb_open(cs, complete, fname, fname_len, gdb_flags, mode); in semihost_sys_open()
690 host_open(cs, complete, fname, fname_len, gdb_flags, mode); in semihost_sys_open()
694 void semihost_sys_close(CPUState *cs, gdb_syscall_complete_cb complete, int fd) in semihost_sys_close() argument
699 complete(cs, -1, EBADF); in semihost_sys_close()
702 switch (gf->type) { in semihost_sys_close()
704 gdb_close(cs, complete, gf); in semihost_sys_close()
707 host_close(cs, complete, gf); in semihost_sys_close()
711 complete(cs, 0, 0); in semihost_sys_close()
719 void semihost_sys_read_gf(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_read_gf() argument
723 * Bound length for 64-bit guests on 32-bit hosts, not overflowing ssize_t. in semihost_sys_read_gf()
730 switch (gf->type) { in semihost_sys_read_gf()
732 gdb_read(cs, complete, gf, buf, len); in semihost_sys_read_gf()
735 host_read(cs, complete, gf, buf, len); in semihost_sys_read_gf()
738 staticfile_read(cs, complete, gf, buf, len); in semihost_sys_read_gf()
741 console_read(cs, complete, gf, buf, len); in semihost_sys_read_gf()
748 void semihost_sys_read(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_read() argument
754 semihost_sys_read_gf(cs, complete, gf, buf, len); in semihost_sys_read()
756 complete(cs, -1, EBADF); in semihost_sys_read()
760 void semihost_sys_write_gf(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_write_gf() argument
764 * Bound length for 64-bit guests on 32-bit hosts, not overflowing ssize_t. in semihost_sys_write_gf()
771 switch (gf->type) { in semihost_sys_write_gf()
773 gdb_write(cs, complete, gf, buf, len); in semihost_sys_write_gf()
776 host_write(cs, complete, gf, buf, len); in semihost_sys_write_gf()
779 console_write(cs, complete, gf, buf, len); in semihost_sys_write_gf()
783 complete(cs, -1, EBADF); in semihost_sys_write_gf()
790 void semihost_sys_write(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_write() argument
796 semihost_sys_write_gf(cs, complete, gf, buf, len); in semihost_sys_write()
798 complete(cs, -1, EBADF); in semihost_sys_write()
802 void semihost_sys_lseek(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_lseek() argument
808 complete(cs, -1, EBADF); in semihost_sys_lseek()
811 switch (gf->type) { in semihost_sys_lseek()
813 gdb_lseek(cs, complete, gf, off, gdb_whence); in semihost_sys_lseek()
816 host_lseek(cs, complete, gf, off, gdb_whence); in semihost_sys_lseek()
819 staticfile_lseek(cs, complete, gf, off, gdb_whence); in semihost_sys_lseek()
822 complete(cs, -1, ESPIPE); in semihost_sys_lseek()
829 void semihost_sys_isatty(CPUState *cs, gdb_syscall_complete_cb complete, int fd) in semihost_sys_isatty() argument
834 complete(cs, 0, EBADF); in semihost_sys_isatty()
837 switch (gf->type) { in semihost_sys_isatty()
839 gdb_isatty(cs, complete, gf); in semihost_sys_isatty()
842 host_isatty(cs, complete, gf); in semihost_sys_isatty()
845 complete(cs, 0, ENOTTY); in semihost_sys_isatty()
848 complete(cs, 1, 0); in semihost_sys_isatty()
855 void semihost_sys_flen(CPUState *cs, gdb_syscall_complete_cb fstat_cb, in semihost_sys_flen() argument
862 flen_cb(cs, -1, EBADF); in semihost_sys_flen()
865 switch (gf->type) { in semihost_sys_flen()
867 gdb_fstat(cs, fstat_cb, gf, fstat_addr); in semihost_sys_flen()
870 host_flen(cs, flen_cb, gf); in semihost_sys_flen()
873 staticfile_flen(cs, flen_cb, gf); in semihost_sys_flen()
881 void semihost_sys_fstat(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_fstat() argument
887 complete(cs, -1, EBADF); in semihost_sys_fstat()
890 switch (gf->type) { in semihost_sys_fstat()
892 gdb_fstat(cs, complete, gf, addr); in semihost_sys_fstat()
895 host_fstat(cs, complete, gf, addr); in semihost_sys_fstat()
898 console_fstat(cs, complete, gf, addr); in semihost_sys_fstat()
906 void semihost_sys_stat(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_stat() argument
911 gdb_stat(cs, complete, fname, fname_len, addr); in semihost_sys_stat()
913 host_stat(cs, complete, fname, fname_len, addr); in semihost_sys_stat()
917 void semihost_sys_remove(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_remove() argument
921 gdb_remove(cs, complete, fname, fname_len); in semihost_sys_remove()
923 host_remove(cs, complete, fname, fname_len); in semihost_sys_remove()
927 void semihost_sys_rename(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_rename() argument
932 gdb_rename(cs, complete, oname, oname_len, nname, nname_len); in semihost_sys_rename()
934 host_rename(cs, complete, oname, oname_len, nname, nname_len); in semihost_sys_rename()
938 void semihost_sys_system(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_system() argument
942 gdb_system(cs, complete, cmd, cmd_len); in semihost_sys_system()
944 host_system(cs, complete, cmd, cmd_len); in semihost_sys_system()
948 void semihost_sys_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_gettimeofday() argument
952 gdb_gettimeofday(cs, complete, tv_addr, tz_addr); in semihost_sys_gettimeofday()
954 host_gettimeofday(cs, complete, tv_addr, tz_addr); in semihost_sys_gettimeofday()
959 void semihost_sys_poll_one(CPUState *cs, gdb_syscall_complete_cb complete, in semihost_sys_poll_one() argument
965 complete(cs, G_IO_NVAL, 1); in semihost_sys_poll_one()
968 switch (gf->type) { in semihost_sys_poll_one()
970 complete(cs, G_IO_NVAL, 1); in semihost_sys_poll_one()
973 host_poll_one(cs, complete, gf, cond, timeout); in semihost_sys_poll_one()
976 console_poll_one(cs, complete, gf, cond, timeout); in semihost_sys_poll_one()