aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/Makefile.objs2
-rw-r--r--linux-user/arm/semihost.c24
-rw-r--r--linux-user/riscv/target_elf.h1
-rw-r--r--linux-user/syscall.c24
4 files changed, 43 insertions, 8 deletions
diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
index 769b8d8336..285c5dfa17 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -6,4 +6,6 @@ obj-y = main.o syscall.o strace.o mmap.o signal.o \
obj-$(TARGET_HAS_BFLT) += flatload.o
obj-$(TARGET_I386) += vm86.o
obj-$(TARGET_ARM) += arm/nwfpe/
+obj-$(TARGET_ARM) += arm/semihost.o
+obj-$(TARGET_AARCH64) += arm/semihost.o
obj-$(TARGET_M68K) += m68k-sim.o
diff --git a/linux-user/arm/semihost.c b/linux-user/arm/semihost.c
new file mode 100644
index 0000000000..9554102a85
--- /dev/null
+++ b/linux-user/arm/semihost.c
@@ -0,0 +1,24 @@
+/*
+ * ARM Semihosting Console Support
+ *
+ * Copyright (c) 2019 Linaro Ltd
+ *
+ * Currently ARM is unique in having support for semihosting support
+ * in linux-user. So for now we implement the common console API but
+ * just for arm linux-user.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/semihosting/console.h"
+#include "qemu.h"
+
+int qemu_semihosting_console_out(CPUArchState *env, target_ulong addr, int len)
+{
+ void *s = lock_user_string(addr);
+ len = write(STDERR_FILENO, s, len ? len : strlen(s));
+ unlock_user(s, addr, 0);
+ return len;
+}
diff --git a/linux-user/riscv/target_elf.h b/linux-user/riscv/target_elf.h
index a6716a6aac..9dd65652ee 100644
--- a/linux-user/riscv/target_elf.h
+++ b/linux-user/riscv/target_elf.h
@@ -9,6 +9,7 @@
#define RISCV_TARGET_ELF_H
static inline const char *cpu_get_model(uint32_t eflags)
{
+ /* TYPE_RISCV_CPU_ANY */
return "any";
}
#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 55212585e0..5e29e675e9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -763,14 +763,7 @@ safe_syscall2(int, nanosleep, const struct timespec *, req,
safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
const struct timespec *, req, struct timespec *, rem)
#endif
-#ifdef __NR_msgsnd
-safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
- int, flags)
-safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
- long, msgtype, int, flags)
-safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
- unsigned, nsops, const struct timespec *, timeout)
-#else
+#if !defined(__NR_msgsnd) || !defined(__NR_msgrcv) || !defined(__NR_semtimedop)
/* This host kernel architecture uses a single ipc syscall; fake up
* wrappers for the sub-operations to hide this implementation detail.
* Annoyingly we can't include linux/ipc.h to get the constant definitions
@@ -785,14 +778,29 @@ safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
void *, ptr, long, fifth)
+#endif
+#ifdef __NR_msgsnd
+safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
+ int, flags)
+#else
static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
{
return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0);
}
+#endif
+#ifdef __NR_msgrcv
+safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
+ long, msgtype, int, flags)
+#else
static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags)
{
return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
}
+#endif
+#ifdef __NR_semtimedop
+safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
+ unsigned, nsops, const struct timespec *, timeout)
+#else
static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
const struct timespec *timeout)
{