aboutsummaryrefslogtreecommitdiff
path: root/semihosting/arm-compat-semi.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-04-28 12:04:44 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-06-28 04:35:52 +0530
commit9a89470449a5171eb1bd06f681361e0888d15cf7 (patch)
treeb7b7537fe55caf844a34969fc229ded15d46998e /semihosting/arm-compat-semi.c
parent40f1219a8b2f95808ed5a18798dbce1b57fef211 (diff)
semihosting: Split out semihost_sys_lseek
Split out the non-ARM specific portions of SYS_SEEK to a reusable function. This handles all GuestFD. Isolate the curious ARM-specific return value processing to a new callback, common_semi_seek_cb. Expand the internal type of the offset to int64_t, and provide the whence argument, which will be required by m68k and nios2 semihosting. Note that gdb_do_syscall %x reads target_ulong, not int. Reviewed-by: Luc Michel <lmichel@kalray.eu> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'semihosting/arm-compat-semi.c')
-rw-r--r--semihosting/arm-compat-semi.c51
1 files changed, 13 insertions, 38 deletions
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index d591fcd7c2..a117d180bc 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -224,16 +224,6 @@ static void common_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
#else
syscall_err = err;
#endif
- } else {
- /* Fixup syscalls that use nonstardard return conventions. */
- target_ulong reg0 = common_semi_arg(cs, 0);
- switch (reg0) {
- case TARGET_SYS_SEEK:
- ret = 0;
- break;
- default:
- break;
- }
}
common_semi_set_ret(cs, ret);
}
@@ -258,6 +248,18 @@ static void common_semi_rw_cb(CPUState *cs, target_ulong ret, target_ulong err)
}
/*
+ * SYS_SEEK returns 0 on success, not the resulting offset.
+ */
+static void common_semi_seek_cb(CPUState *cs, target_ulong ret,
+ target_ulong err)
+{
+ if (!err) {
+ ret = 0;
+ }
+ common_semi_cb(cs, ret, err);
+}
+
+/*
* Return an address in target memory of 64 bytes where the remote
* gdb should write its stat struct. (The format of this structure
* is defined by GDB's remote protocol and is not target-specific.)
@@ -290,7 +292,6 @@ common_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
* via common_semi_cb.
*/
typedef void sys_isattyfn(CPUState *cs, GuestFD *gf);
-typedef void sys_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset);
typedef void sys_flenfn(CPUState *cs, GuestFD *gf);
static void host_isattyfn(CPUState *cs, GuestFD *gf)
@@ -298,12 +299,6 @@ static void host_isattyfn(CPUState *cs, GuestFD *gf)
common_semi_cb(cs, isatty(gf->hostfd), 0);
}
-static void host_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset)
-{
- off_t ret = lseek(gf->hostfd, offset, SEEK_SET);
- common_semi_cb(cs, ret, ret == -1 ? errno : 0);
-}
-
static void host_flenfn(CPUState *cs, GuestFD *gf)
{
struct stat buf;
@@ -320,11 +315,6 @@ static void gdb_isattyfn(CPUState *cs, GuestFD *gf)
gdb_do_syscall(common_semi_cb, "isatty,%x", gf->hostfd);
}
-static void gdb_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset)
-{
- gdb_do_syscall(common_semi_cb, "lseek,%x,%x,0", gf->hostfd, offset);
-}
-
static void gdb_flenfn(CPUState *cs, GuestFD *gf)
{
gdb_do_syscall(common_semi_flen_cb, "fstat,%x,%x",
@@ -353,12 +343,6 @@ static void staticfile_isattyfn(CPUState *cs, GuestFD *gf)
common_semi_cb(cs, 0, 0);
}
-static void staticfile_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset)
-{
- gf->staticfile.off = offset;
- common_semi_cb(cs, 0, 0);
-}
-
static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
{
common_semi_cb(cs, gf->staticfile.len, 0);
@@ -366,24 +350,20 @@ static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
typedef struct GuestFDFunctions {
sys_isattyfn *isattyfn;
- sys_seekfn *seekfn;
sys_flenfn *flenfn;
} GuestFDFunctions;
static const GuestFDFunctions guestfd_fns[] = {
[GuestFDHost] = {
.isattyfn = host_isattyfn,
- .seekfn = host_seekfn,
.flenfn = host_flenfn,
},
[GuestFDGDB] = {
.isattyfn = gdb_isattyfn,
- .seekfn = gdb_seekfn,
.flenfn = gdb_flenfn,
},
[GuestFDStatic] = {
.isattyfn = staticfile_isattyfn,
- .seekfn = staticfile_seekfn,
.flenfn = staticfile_flenfn,
},
};
@@ -520,12 +500,7 @@ void do_common_semihosting(CPUState *cs)
case TARGET_SYS_SEEK:
GET_ARG(0);
GET_ARG(1);
-
- gf = get_guestfd(arg0);
- if (!gf) {
- goto do_badf;
- }
- guestfd_fns[gf->type].seekfn(cs, gf, arg1);
+ semihost_sys_lseek(cs, common_semi_seek_cb, arg0, arg1, GDB_SEEK_SET);
break;
case TARGET_SYS_FLEN: