Message ID | 1401392813-29645-3-git-send-email-pbonzini@redhat.com |
---|---|
State | New |
Headers | show |
On 29 May 2014 20:46, Paolo Bonzini <pbonzini@redhat.com> wrote: > Set it on startup and in signal handler frames. > > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > --- > linux-user/main.c | 1 + > linux-user/signal.c | 5 +++++ > 2 files changed, 6 insertions(+) > > diff --git a/linux-user/main.c b/linux-user/main.c > index 882186e..2a04446 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -4191,6 +4191,7 @@ int main(int argc, char **argv, char **envp) > if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4 > && (info->elf_flags & EF_ARM_BE8)) { > env->bswap_code = 1; > + env->uncached_cpsr |= CPSR_E; > } > } > #elif defined(TARGET_UNICORE32) > diff --git a/linux-user/signal.c b/linux-user/signal.c > index c652829..048ffac 100644 > --- a/linux-user/signal.c > +++ b/linux-user/signal.c > @@ -1633,6 +1633,11 @@ setup_return(CPUARMState *env, struct target_sigaction *ka, > } else { > cpsr &= ~CPSR_T; > } > +#ifdef TARGET_WORDS_BIGENDIAN > + cpsr |= CPSR_E; This is wrong for BE32, where CPSR_E doesn't exist and both code and data accesses are big-endian. > +#else > + cpsr &= ~CPSR_E; > +#endif > > if (ka->sa_flags & TARGET_SA_RESTORER) { > retcode = ka->sa_restorer; > -- > 1.9.3 thanks -- PMM
Il 29/05/2014 22:38, Peter Maydell ha scritto: >> > +#ifdef TARGET_WORDS_BIGENDIAN >> > + cpsr |= CPSR_E; > This is wrong for BE32, where CPSR_E doesn't exist and both code > and data accesses are big-endian. > Is it okay for simplicity to treat CPSR.E = 1 as "big-endian code, little-endian data" in BE32 mode? The architecture manual leaves it undefined. Paolo
On 30 May 2014 07:46, Paolo Bonzini <pbonzini@redhat.com> wrote: > Il 29/05/2014 22:38, Peter Maydell ha scritto: > >>> > +#ifdef TARGET_WORDS_BIGENDIAN >>> > + cpsr |= CPSR_E; >> >> This is wrong for BE32, where CPSR_E doesn't exist and both code >> and data accesses are big-endian. >> > > Is it okay for simplicity to treat CPSR.E = 1 as "big-endian code, > little-endian data" in BE32 mode? The architecture manual leaves it > undefined. Actually the ARM ARM does define it: (DDI0406C.c section D12.6.1) "When SCTLR.B is set, SCTLR.EE and CPSR.E must be clear, or else the endianness behaviour is UNPREDICTABLE." So if the guest does set CPSR.E in a BE32 binary you can do whatever's convenient as long as it's not a security hole, basically. thanks -- PMM
diff --git a/linux-user/main.c b/linux-user/main.c index 882186e..2a04446 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -4191,6 +4191,7 @@ int main(int argc, char **argv, char **envp) if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4 && (info->elf_flags & EF_ARM_BE8)) { env->bswap_code = 1; + env->uncached_cpsr |= CPSR_E; } } #elif defined(TARGET_UNICORE32) diff --git a/linux-user/signal.c b/linux-user/signal.c index c652829..048ffac 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -1633,6 +1633,11 @@ setup_return(CPUARMState *env, struct target_sigaction *ka, } else { cpsr &= ~CPSR_T; } +#ifdef TARGET_WORDS_BIGENDIAN + cpsr |= CPSR_E; +#else + cpsr &= ~CPSR_E; +#endif if (ka->sa_flags & TARGET_SA_RESTORER) { retcode = ka->sa_restorer;
Set it on startup and in signal handler frames. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- linux-user/main.c | 1 + linux-user/signal.c | 5 +++++ 2 files changed, 6 insertions(+)