RISC_OS_Linux_Source
RISC_OS_Linux_Source copied to clipboard
patch for qemu version 7.0.50 (v7.0.0-2807-gf6cce6bcb2-dirty)
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index c0790f3246..ead6faa0eb 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -313,6 +313,9 @@ static bool emulate_arm_fpa11(CPUARMState *env, uint32_t opcode)
void cpu_loop(CPUARMState *env)
{
+ static bool use_nwfpe = true;
+ static abi_ulong sys_base = 0;
+ static abi_ulong sys_limit = 0xFFFFFFFF;
CPUState *cs = env_cpu(env);
int trapnr, si_signo, si_code;
unsigned int n, insn;
@@ -346,7 +349,7 @@ void cpu_loop(CPUARMState *env)
goto excp_debug;
}
- if (!env->thumb && emulate_arm_fpa11(env, opcode)) {
+ if (!env->thumb && use_nwfpe && emulate_arm_fpa11(env, opcode)) {
break;
}
@@ -358,6 +361,14 @@ void cpu_loop(CPUARMState *env)
{
env->eabi = 1;
/* system call */
+ if (env->regs[15] < sys_base || env->regs[15] > sys_limit) {
+ //si_signo = TARGET_SIGSYS;
+ //info.si_call_addr = env->regs[15];
+ //queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGSYS, QEMU_SI_FAULT, env->regs[15]);
+ break;
+ }
+
if (env->thumb) {
/* Thumb is always EABI style with syscall number in r7 */
n = env->regs[7];
@@ -402,7 +413,12 @@ void cpu_loop(CPUARMState *env)
env->regs[0] = cpu_get_tls(env);
break;
default:
- if (n < 0xf0800) {
+ if (n == (0xC0001 ^ ARM_SYSCALL_BASE)) {
+ /* RISC OS: Control SWI Intercept and FPA */
+ sys_base = env->regs[0];
+ sys_limit = env->regs[1];
+ use_nwfpe = env->regs[2];
+ } else if (n < 0xf0800) {
/*
* Syscalls 0xf0000..0xf07ff (or 0x9f0000..
* 0x9f07ff in OABI numbering) are defined
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 8d29bfaa6b..27b5180f12 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -570,8 +570,8 @@ static void signal_table_init(void)
* Attempts for configure "missing" signals via sigaction will be
* silently ignored.
*/
- for (host_sig = SIGRTMIN; host_sig <= SIGRTMAX; host_sig++) {
- target_sig = host_sig - SIGRTMIN + TARGET_SIGRTMIN;
+ for (host_sig = SIGRTMAX + TARGET_SIGRTMIN - SIGRTMIN, target_sig = TARGET_SIGRTMIN;
+ host_sig <= SIGRTMAX; host_sig++, target_sig++) {
if (target_sig <= TARGET_NSIG) {
host_to_target_signal_table[host_sig] = target_sig;
}
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 85b0f33e91..c49271095b 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -649,6 +649,14 @@ typedef struct target_siginfo {
int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
int _fd;
} _sigpoll;
+
+ /* SIGSYS */
+ struct {
+ abi_ulong _call_addr; /* calling user insn */
+ int _syscall; /* triggering system call number */
+ unsigned int _arch; /* AUDIT_ARCH_* of syscall */
+ } _sigsys;
+
} _sifields;
} target_siginfo_t;
As far as I can see this works with qemu version 7.0.50 (v7.0.0-2807-gf6cce6bcb2-dirty) The dirty is because I added the patch. I don't know if there is much benefit to got to QEMU 7.0 but it may prove a bit more efficient and compatible.