Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
4f64f80
include/exec: Move gdb open flags to gdbstub.h
rth7680 Apr 28, 2022
d7079b9
include/exec: Move gdb_stat and gdb_timeval to gdbstub.h
rth7680 Apr 29, 2022
ed41ae2
include/exec: Define errno values in gdbstub.h
rth7680 May 2, 2022
3dc7459
linux-user: Clean up arg_start/arg_end confusion
rth7680 Apr 27, 2022
3ea3a0b
semihosting/config: Merge --semihosting-config option groups
pm215 Jun 10, 2022
f4c2410
semihosting: Move exec/softmmu-semi.h to semihosting/softmmu-uaccess.h
rth7680 Apr 28, 2022
0bce208
target/mips: Use an exception for semihosting
rth7680 May 2, 2022
71768ac
target/mips: Add UHI errno values
rth7680 May 2, 2022
f358c75
target/mips: Drop pread and pwrite syscalls from semihosting
rth7680 May 3, 2022
67ba5c5
semihosting: Improve condition for config.c and console.c
rth7680 Apr 30, 2022
7a54871
semihosting: Move softmmu-uaccess.h functions out of line
rth7680 Apr 28, 2022
3563e08
semihosting: Add target_strlen for softmmu-uaccess.h
rth7680 Apr 28, 2022
429fbcd
semihosting: Simplify softmmu_lock_user_string
rth7680 Apr 28, 2022
a968d75
semihosting: Split out guestfd.c
rth7680 Apr 28, 2022
bef0a54
semihosting: Inline set_swi_errno into common_semi_cb
rth7680 May 17, 2022
e0c6436
semihosting: Adjust error checking in common_semi_cb
rth7680 Apr 29, 2022
3ae94d4
semihosting: Clean up common_semi_flen_cb
rth7680 May 17, 2022
3f124bc
semihosting: Clean up common_semi_open_cb
rth7680 May 17, 2022
7874a10
semihosting: Return void from do_common_semihosting
rth7680 Apr 28, 2022
29bf17c
semihosting: Move common-semi.h to include/semihosting/
rth7680 Apr 28, 2022
ee22924
semihosting: Remove GDB_O_BINARY
rth7680 Jun 7, 2022
43bf93a
semihosting: Use struct gdb_stat in common_semi_flen_cb
rth7680 Apr 29, 2022
6303351
semihosting: Split is_64bit_semihosting per target
rth7680 Apr 28, 2022
ecfc470
semihosting: Split common_semi_flen_buf per target
rth7680 Apr 29, 2022
3684c3f
semihosting: Split out common_semi_has_synccache
rth7680 Apr 29, 2022
7692147
semihosting: Split out common-semi-target.h
rth7680 Jun 7, 2022
4e212d0
semihosting: Use env more often in do_common_semihosting
rth7680 Apr 29, 2022
ea78f82
semihosting: Move GET_ARG/SET_ARG earlier in the file
rth7680 Apr 28, 2022
f3fffa6
semihosting: Split out semihost_sys_open
rth7680 Apr 28, 2022
5d40eb1
semihosting: Split out semihost_sys_close
rth7680 Apr 28, 2022
f81f3af
semihosting: Split out semihost_sys_read
rth7680 Apr 28, 2022
9872855
semihosting: Split out semihost_sys_write
rth7680 Apr 28, 2022
099eb21
semihosting: Bound length for semihost_sys_{read,write}
rth7680 Apr 29, 2022
2608e6d
semihosting: Split out semihost_sys_lseek
rth7680 Apr 28, 2022
6a0d861
semihosting: Split out semihost_sys_isatty
rth7680 Apr 28, 2022
3e4baa0
semihosting: Split out semihost_sys_flen
rth7680 Apr 29, 2022
f25db3b
semihosting: Split out semihost_sys_remove
rth7680 Apr 29, 2022
5a0d1b1
semihosting: Split out semihost_sys_rename
rth7680 Apr 29, 2022
60bdfa9
semihosting: Split out semihost_sys_system
rth7680 Apr 29, 2022
3b7f4ee
semihosting: Create semihost_sys_{stat,fstat}
rth7680 Apr 29, 2022
08530d4
semihosting: Create semihost_sys_gettimeofday
rth7680 Apr 29, 2022
ec9f291
gdbstub: Adjust gdb_syscall_complete_cb declaration
rth7680 Apr 29, 2022
84cffff
semihosting: Pass CPUState to qemu_semihosting_console_inc
rth7680 May 1, 2022
581a9a4
semihosting: Expand qemu_semihosting_console_inc to read
rth7680 May 1, 2022
f799064
semihosting: Cleanup chardev init
rth7680 May 1, 2022
d8e8d59
semihosting: Create qemu_semihosting_console_write
rth7680 May 1, 2022
3c14324
semihosting: Add GuestFDConsole
rth7680 May 1, 2022
7f2d817
semihosting: Create qemu_semihosting_guestfd_init
rth7680 May 2, 2022
ae0340e
semihosting: Use console_in_gf for SYS_READC
rth7680 May 2, 2022
3dd03d5
semihosting: Use console_out_gf for SYS_WRITEC
rth7680 May 2, 2022
00e8e59
semihosting: Remove qemu_semihosting_console_outc
rth7680 May 2, 2022
3f4d7c5
semihosting: Use console_out_gf for SYS_WRITE0
rth7680 May 2, 2022
85e87ed
semihosting: Remove qemu_semihosting_console_outs
rth7680 May 2, 2022
6f321b1
semihosting: Create semihost_sys_poll_one
rth7680 May 2, 2022
7258d7d
semihosting: Remove qemu_semihosting_log_out
rth7680 Jun 28, 2022
e02adaf
target/mips: Create report_fault for semihosting
rth7680 Jun 28, 2022
ed685a5
target/mips: Drop link syscall from semihosting
rth7680 Jun 28, 2022
4a00c99
target/mips: Use semihosting/syscalls.h
rth7680 Jun 28, 2022
2149810
target/mips: Avoid qemu_semihosting_log_out for UHI_plog
rth7680 Jun 28, 2022
070a909
semihosting: Don't return negative values on qemu_semihosting_console…
pm215 Jul 25, 2022
05e8dc8
semihosting: Don't copy buffer after console_write()
pm215 Jul 25, 2022
925e450
semihosting: Check for errors on SET_ARG()
pm215 Jul 25, 2022
50c3ca1
semihosting: Fix handling of buffer in TARGET_SYS_TMPNAM
pm215 Jul 25, 2022
1520b5d
semihosting: Allow optional use of semihosting from userspace
pm215 Aug 22, 2022
67fb26b
target/mips: Honour -semihosting-config userspace=on
pm215 Aug 22, 2022
7febad6
semihosting: update link to spec
stsquad Sep 29, 2022
95c951e
semihosting/arm-compat-semi: Avoid using hardcoded /tmp
lbmeng Oct 27, 2022
157cd1b
target/nios2: Create EXCP_SEMIHOST for semi-hosting
rth7680 Apr 21, 2022
b2a5fad
target/nios2: Honour -semihosting-config userspace=on
pm215 Aug 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configs/targets/aarch64-linux-user.mak
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
1 change: 1 addition & 0 deletions configs/targets/aarch64_be-linux-user.mak
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ TARGET_BASE_ARCH=arm
TARGET_WORDS_BIGENDIAN=y
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
1 change: 1 addition & 0 deletions configs/targets/arm-linux-user.mak
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ TARGET_SYSTBL_ABI=common,oabi
TARGET_SYSTBL=syscall.tbl
TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
1 change: 1 addition & 0 deletions configs/targets/armeb-linux-user.mak
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ TARGET_SYSTBL=syscall.tbl
TARGET_WORDS_BIGENDIAN=y
TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
1 change: 1 addition & 0 deletions configs/targets/riscv32-linux-user.mak
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ TARGET_ARCH=riscv32
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-virtual.xml
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
1 change: 1 addition & 0 deletions configs/targets/riscv64-linux-user.mak
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ TARGET_ARCH=riscv64
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-virtual.xml
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
7 changes: 4 additions & 3 deletions gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1863,11 +1863,12 @@ static void handle_read_all_regs(GArray *params, void *user_ctx)
static void handle_file_io(GArray *params, void *user_ctx)
{
if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
target_ulong ret, err;
uint64_t ret;
int err;

ret = (target_ulong)get_param(params, 0)->val_ull;
ret = get_param(params, 0)->val_ull;
if (params->len >= 2) {
err = (target_ulong)get_param(params, 1)->val_ull;
err = get_param(params, 1)->val_ull;
} else {
err = 0;
}
Expand Down
64 changes: 62 additions & 2 deletions include/exec/gdbstub.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,71 @@
#define GDB_WATCHPOINT_READ 3
#define GDB_WATCHPOINT_ACCESS 4

/* For gdb file i/o remote protocol open flags. */
#define GDB_O_RDONLY 0
#define GDB_O_WRONLY 1
#define GDB_O_RDWR 2
#define GDB_O_APPEND 8
#define GDB_O_CREAT 0x200
#define GDB_O_TRUNC 0x400
#define GDB_O_EXCL 0x800

/* For gdb file i/o remote protocol errno values */
#define GDB_EPERM 1
#define GDB_ENOENT 2
#define GDB_EINTR 4
#define GDB_EBADF 9
#define GDB_EACCES 13
#define GDB_EFAULT 14
#define GDB_EBUSY 16
#define GDB_EEXIST 17
#define GDB_ENODEV 19
#define GDB_ENOTDIR 20
#define GDB_EISDIR 21
#define GDB_EINVAL 22
#define GDB_ENFILE 23
#define GDB_EMFILE 24
#define GDB_EFBIG 27
#define GDB_ENOSPC 28
#define GDB_ESPIPE 29
#define GDB_EROFS 30
#define GDB_ENAMETOOLONG 91
#define GDB_EUNKNOWN 9999

/* For gdb file i/o remote protocol lseek whence. */
#define GDB_SEEK_SET 0
#define GDB_SEEK_CUR 1
#define GDB_SEEK_END 2

/* For gdb file i/o stat/fstat. */
typedef uint32_t gdb_mode_t;
typedef uint32_t gdb_time_t;

struct gdb_stat {
uint32_t gdb_st_dev; /* device */
uint32_t gdb_st_ino; /* inode */
gdb_mode_t gdb_st_mode; /* protection */
uint32_t gdb_st_nlink; /* number of hard links */
uint32_t gdb_st_uid; /* user ID of owner */
uint32_t gdb_st_gid; /* group ID of owner */
uint32_t gdb_st_rdev; /* device type (if inode device) */
uint64_t gdb_st_size; /* total size, in bytes */
uint64_t gdb_st_blksize; /* blocksize for filesystem I/O */
uint64_t gdb_st_blocks; /* number of blocks allocated */
gdb_time_t gdb_st_atime; /* time of last access */
gdb_time_t gdb_st_mtime; /* time of last modification */
gdb_time_t gdb_st_ctime; /* time of last change */
} QEMU_PACKED;

struct gdb_timeval {
gdb_time_t tv_sec; /* second */
uint64_t tv_usec; /* microsecond */
} QEMU_PACKED;

#ifdef NEED_CPU_H
#include "cpu.h"

typedef void (*gdb_syscall_complete_cb)(CPUState *cpu,
target_ulong ret, target_ulong err);
typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, uint64_t ret, int err);

/**
* gdb_do_syscall:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@
#ifndef COMMON_SEMI_H
#define COMMON_SEMI_H

target_ulong do_common_semihosting(CPUState *cs);
void do_common_semihosting(CPUState *cs);

#endif /* COMMON_SEMI_H */
66 changes: 28 additions & 38 deletions include/semihosting/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,58 +12,48 @@
#include "cpu.h"

/**
* qemu_semihosting_console_outs:
* @env: CPUArchState
* @s: host address of null terminated guest string
* qemu_semihosting_console_read:
* @cs: CPUState
* @buf: host buffer
* @len: buffer size
*
* Send a null terminated guest string to the debug console. This may
* be the remote gdb session if a softmmu guest is currently being
* debugged.
* Receive at least one character from debug console. As this call may
* block if no data is available we suspend the CPU and will re-execute the
* instruction when data is there. Therefore two conditions must be met:
*
* Returns: number of bytes written.
* - CPUState is synchronized before calling this function
* - pc is only updated once the character is successfully returned
*
* Returns: number of characters read, OR cpu_loop_exit!
*/
int qemu_semihosting_console_outs(CPUArchState *env, target_ulong s);
int qemu_semihosting_console_read(CPUState *cs, void *buf, int len);

/**
* qemu_semihosting_console_outc:
* @env: CPUArchState
* @s: host address of null terminated guest string
* qemu_semihosting_console_write:
* @buf: host buffer
* @len: buffer size
*
* Send single character from guest memory to the debug console. This
* may be the remote gdb session if a softmmu guest is currently being
* debugged.
* Write len bytes from buf to the debug console.
*
* Returns: nothing
* Returns: number of bytes written -- this should only ever be short
* on some sort of i/o error.
*/
void qemu_semihosting_console_outc(CPUArchState *env, target_ulong c);
int qemu_semihosting_console_write(void *buf, int len);

/**
* qemu_semihosting_console_inc:
* @env: CPUArchState
*
* Receive single character from debug console. This may be the remote
* gdb session if a softmmu guest is currently being debugged. As this
* call may block if no data is available we suspend the CPU and will
* re-execute the instruction when data is there. Therefore two
* conditions must be met:
* - CPUState is synchronized before calling this function
* - pc is only updated once the character is successfully returned
/*
* qemu_semihosting_console_block_until_ready:
* @cs: CPUState
*
* Returns: character read OR cpu_loop_exit!
* If no data is available we suspend the CPU and will re-execute the
* instruction when data is available.
*/
target_ulong qemu_semihosting_console_inc(CPUArchState *env);
void qemu_semihosting_console_block_until_ready(CPUState *cs);

/**
* qemu_semihosting_log_out:
* @s: pointer to string
* @len: length of string
*
* Send a string to the debug output. Unlike console_out these strings
* can't be sent to a remote gdb instance as they don't exist in guest
* memory.
* qemu_semihosting_console_ready:
*
* Returns: number of bytes written
* Return true if characters are available for read; does not block.
*/
int qemu_semihosting_log_out(const char *s, int len);
bool qemu_semihosting_console_ready(void);

#endif /* SEMIHOST_CONSOLE_H */
91 changes: 91 additions & 0 deletions include/semihosting/guestfd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Hosted file support for semihosting syscalls.
*
* Copyright (c) 2005, 2007 CodeSourcery.
* Copyright (c) 2019 Linaro
* Copyright © 2020 by Keith Packard <[email protected]>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef SEMIHOSTING_GUESTFD_H
#define SEMIHOSTING_GUESTFD_H

typedef enum GuestFDType {
GuestFDUnused = 0,
GuestFDHost,
GuestFDGDB,
GuestFDStatic,
GuestFDConsole,
} GuestFDType;

/*
* Guest file descriptors are integer indexes into an array of
* these structures (we will dynamically resize as necessary).
*/
typedef struct GuestFD {
GuestFDType type;
union {
int hostfd;
struct {
const uint8_t *data;
size_t len;
size_t off;
} staticfile;
};
} GuestFD;

/*
* For ARM semihosting, we have a separate structure for routing
* data for the console which is outside the guest fd address space.
*/
extern GuestFD console_in_gf;
extern GuestFD console_out_gf;

/**
* alloc_guestfd:
*
* Allocate an unused GuestFD index. The associated guestfd index
* will still be GuestFDUnused until it is initialized.
*/
int alloc_guestfd(void);

/**
* dealloc_guestfd:
* @guestfd: GuestFD index
*
* Deallocate a GuestFD index. The associated GuestFD structure
* will be recycled for a subsequent allocation.
*/
void dealloc_guestfd(int guestfd);

/**
* get_guestfd:
* @guestfd: GuestFD index
*
* Return the GuestFD structure associated with an initialized @guestfd,
* or NULL if it has not been allocated, or hasn't been initialized.
*/
GuestFD *get_guestfd(int guestfd);

/**
* associate_guestfd:
* @guestfd: GuestFD index
* @hostfd: host file descriptor
*
* Initialize the GuestFD for @guestfd to GuestFDHost using @hostfd.
*/
void associate_guestfd(int guestfd, int hostfd);

/**
* staticfile_guestfd:
* @guestfd: GuestFD index
* @data: data to be read
* @len: length of @data
*
* Initialize the GuestFD for @guestfd to GuestFDStatic.
* The @len bytes at @data will be returned to the guest on reads.
*/
void staticfile_guestfd(int guestfd, const uint8_t *data, size_t len);

#endif /* SEMIHOSTING_GUESTFD_H */
24 changes: 11 additions & 13 deletions include/semihosting/semihost.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ typedef enum SemihostingTarget {
} SemihostingTarget;

#ifdef CONFIG_USER_ONLY
static inline bool semihosting_enabled(void)
static inline bool semihosting_enabled(bool is_user)
{
return true;
}
Expand All @@ -51,27 +51,25 @@ static inline const char *semihosting_get_cmdline(void)
{
return NULL;
}

static inline Chardev *semihosting_get_chardev(void)
{
return NULL;
}
static inline void qemu_semihosting_console_init(void)
{
}
#else /* !CONFIG_USER_ONLY */
bool semihosting_enabled(void);
/**
* semihosting_enabled:
* @is_user: true if guest code is in usermode (i.e. not privileged)
*
* Return true if guest code is allowed to make semihosting calls.
*/
bool semihosting_enabled(bool is_user);
SemihostingTarget semihosting_get_target(void);
const char *semihosting_get_arg(int i);
int semihosting_get_argc(void);
const char *semihosting_get_cmdline(void);
void semihosting_arg_fallback(const char *file, const char *cmd);
Chardev *semihosting_get_chardev(void);
/* for vl.c hooks */
void qemu_semihosting_enable(void);
int qemu_semihosting_config_options(const char *opt);
void qemu_semihosting_connect_chardevs(void);
void qemu_semihosting_console_init(void);
void qemu_semihosting_chardev_init(void);
void qemu_semihosting_console_init(Chardev *);
#endif /* CONFIG_USER_ONLY */
void qemu_semihosting_guestfd_init(void);

#endif /* SEMIHOST_H */
Loading