* [Qemu-devel] [PATCH 0/2] Fix armeb-linux-user disassembly
@ 2017-10-19 21:21 Richard Henderson
2017-10-19 21:21 ` [Qemu-devel] [PATCH 1/2] target/arm: Move BE32 disassembler fixup Richard Henderson
2017-10-19 21:21 ` [Qemu-devel] [PATCH 2/2] target/arm: Don't set INSN_ARM_BE32 for CONFIG_USER_ONLY Richard Henderson
0 siblings, 2 replies; 4+ messages in thread
From: Richard Henderson @ 2017-10-19 21:21 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Reported in
https://bugs.launchpad.net/qemu/+bug/1724485
There's one existing bug here, wrt setting INSN_ARM_BE32, and
another when it comes to the capstone disassembler patch set.
r~
Richard Henderson (2):
target/arm: Move BE32 disassembler fixup
target/arm: Don't set INSN_ARM_BE32 for CONFIG_USER_ONLY
include/disas/bfd.h | 7 -------
disas/arm.c | 21 ++++++++++++++++-----
target/arm/cpu.c | 28 +++++++---------------------
3 files changed, 23 insertions(+), 33 deletions(-)
--
2.13.6
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 1/2] target/arm: Move BE32 disassembler fixup
2017-10-19 21:21 [Qemu-devel] [PATCH 0/2] Fix armeb-linux-user disassembly Richard Henderson
@ 2017-10-19 21:21 ` Richard Henderson
2017-10-19 21:21 ` [Qemu-devel] [PATCH 2/2] target/arm: Don't set INSN_ARM_BE32 for CONFIG_USER_ONLY Richard Henderson
1 sibling, 0 replies; 4+ messages in thread
From: Richard Henderson @ 2017-10-19 21:21 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
The Capstone disassembler has its own big-endian fixup.
Doing this twice does not work, of course. Move our current
fixup from target/arm/cpu.c to disas/arm.c.
This makes read_memory_inner_func unused and can be removed.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/disas/bfd.h | 7 -------
disas/arm.c | 21 ++++++++++++++++-----
target/arm/cpu.c | 19 -------------------
3 files changed, 16 insertions(+), 31 deletions(-)
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 9b0657cfa9..1f88c9e9d5 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -307,12 +307,6 @@ typedef struct disassemble_info {
(bfd_vma memaddr, bfd_byte *myaddr, int length,
struct disassemble_info *info);
- /* A place to stash the real read_memory_func if read_memory_func wants to
- do some funky address arithmetic or similar (e.g. for ARM BE32 mode). */
- int (*read_memory_inner_func)
- (bfd_vma memaddr, bfd_byte *myaddr, int length,
- struct disassemble_info *info);
-
/* Function which should be called if we get an error that we can't
recover from. STATUS is the errno value from read_memory_func and
MEMADDR is the address that we were trying to read. INFO is a
@@ -483,7 +477,6 @@ int generic_symbol_at_address(bfd_vma, struct disassemble_info *);
(INFO).buffer_vma = 0, \
(INFO).buffer_length = 0, \
(INFO).read_memory_func = buffer_read_memory, \
- (INFO).read_memory_inner_func = NULL, \
(INFO).memory_error_func = perror_memory, \
(INFO).print_address_func = generic_print_address, \
(INFO).print_insn = NULL, \
diff --git a/disas/arm.c b/disas/arm.c
index 27396dd3e1..9967c45990 100644
--- a/disas/arm.c
+++ b/disas/arm.c
@@ -70,6 +70,17 @@ static void floatformat_to_double (unsigned char *data, double *dest)
*dest = u.f;
}
+static int arm_read_memory(bfd_vma memaddr, bfd_byte *b, int length,
+ struct disassemble_info *info)
+{
+ assert((info->flags & INSN_ARM_BE32) == 0 || length == 2 || length == 4);
+
+ if ((info->flags & INSN_ARM_BE32) != 0 && length == 2) {
+ memaddr ^= 2;
+ }
+ return info->read_memory_func(memaddr, b, length, info);
+}
+
/* End of qemu specific additions. */
struct opcode32
@@ -3810,7 +3821,7 @@ find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
return;
}
addr -= 2;
- status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
+ status = arm_read_memory (addr, (bfd_byte *)b, 2, info);
if (status)
return;
@@ -3882,7 +3893,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info)
info->bytes_per_chunk = size;
printer = print_insn_data;
- status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
+ status = arm_read_memory (pc, (bfd_byte *)b, size, info);
given = 0;
if (little)
for (i = size - 1; i >= 0; i--)
@@ -3899,7 +3910,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info)
info->bytes_per_chunk = 4;
size = 4;
- status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
+ status = arm_read_memory (pc, (bfd_byte *)b, 4, info);
if (little)
given = (b[0]) | (b[1] << 8) | (b[2] << 16) | ((unsigned)b[3] << 24);
else
@@ -3915,7 +3926,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info)
info->bytes_per_chunk = 2;
size = 2;
- status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
+ status = arm_read_memory (pc, (bfd_byte *)b, 2, info);
if (little)
given = (b[0]) | (b[1] << 8);
else
@@ -3929,7 +3940,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info)
|| (given & 0xF800) == 0xF000
|| (given & 0xF800) == 0xE800)
{
- status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
+ status = arm_read_memory (pc + 2, (bfd_byte *)b, 2, info);
if (little)
given = (b[0]) | (b[1] << 8) | (given << 16);
else
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1576a6d372..bc9d70df04 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -474,21 +474,6 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
return print_insn_arm(pc | 1, info);
}
-static int arm_read_memory_func(bfd_vma memaddr, bfd_byte *b,
- int length, struct disassemble_info *info)
-{
- assert(info->read_memory_inner_func);
- assert((info->flags & INSN_ARM_BE32) == 0 || length == 2 || length == 4);
-
- if ((info->flags & INSN_ARM_BE32) != 0 && length == 2) {
- assert(info->endian == BFD_ENDIAN_LITTLE);
- return info->read_memory_inner_func(memaddr ^ 2, (bfd_byte *)b, 2,
- info);
- } else {
- return info->read_memory_inner_func(memaddr, b, length, info);
- }
-}
-
static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
{
ARMCPU *ac = ARM_CPU(cpu);
@@ -528,10 +513,6 @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
info->endian = BFD_ENDIAN_BIG;
#endif
}
- if (info->read_memory_inner_func == NULL) {
- info->read_memory_inner_func = info->read_memory_func;
- info->read_memory_func = arm_read_memory_func;
- }
info->flags &= ~INSN_ARM_BE32;
if (arm_sctlr_b(env)) {
info->flags |= INSN_ARM_BE32;
--
2.13.6
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 2/2] target/arm: Don't set INSN_ARM_BE32 for CONFIG_USER_ONLY
2017-10-19 21:21 [Qemu-devel] [PATCH 0/2] Fix armeb-linux-user disassembly Richard Henderson
2017-10-19 21:21 ` [Qemu-devel] [PATCH 1/2] target/arm: Move BE32 disassembler fixup Richard Henderson
@ 2017-10-19 21:21 ` Richard Henderson
2017-10-20 3:38 ` Philippe Mathieu-Daudé
1 sibling, 1 reply; 4+ messages in thread
From: Richard Henderson @ 2017-10-19 21:21 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
This matches translator behaviour in arm_lduw_code.
Fixes: https://bugs.launchpad.net/qemu/+bug/1724485
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index bc9d70df04..a0ed11c9a5 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -478,6 +478,7 @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
{
ARMCPU *ac = ARM_CPU(cpu);
CPUARMState *env = &ac->env;
+ bool sctlr_b;
if (is_a64(env)) {
/* We might not be compiled with the A64 disassembler
@@ -506,7 +507,9 @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
info->cap_arch = CS_ARCH_ARM;
info->cap_mode = cap_mode;
}
- if (bswap_code(arm_sctlr_b(env))) {
+
+ sctlr_b = arm_sctlr_b(env);
+ if (bswap_code(sctlr_b)) {
#ifdef TARGET_WORDS_BIGENDIAN
info->endian = BFD_ENDIAN_LITTLE;
#else
@@ -514,9 +517,11 @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
#endif
}
info->flags &= ~INSN_ARM_BE32;
- if (arm_sctlr_b(env)) {
+#ifndef CONFIG_USER_ONLY
+ if (sctlr_b) {
info->flags |= INSN_ARM_BE32;
}
+#endif
}
uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
--
2.13.6
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH 2/2] target/arm: Don't set INSN_ARM_BE32 for CONFIG_USER_ONLY
2017-10-19 21:21 ` [Qemu-devel] [PATCH 2/2] target/arm: Don't set INSN_ARM_BE32 for CONFIG_USER_ONLY Richard Henderson
@ 2017-10-20 3:38 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 4+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-10-20 3:38 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: peter.maydell
On 10/19/2017 06:21 PM, Richard Henderson wrote:
> This matches translator behaviour in arm_lduw_code.
>
> Fixes: https://bugs.launchpad.net/qemu/+bug/1724485
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> target/arm/cpu.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index bc9d70df04..a0ed11c9a5 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -478,6 +478,7 @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
> {
> ARMCPU *ac = ARM_CPU(cpu);
> CPUARMState *env = &ac->env;
> + bool sctlr_b;
>
> if (is_a64(env)) {
> /* We might not be compiled with the A64 disassembler
> @@ -506,7 +507,9 @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
> info->cap_arch = CS_ARCH_ARM;
> info->cap_mode = cap_mode;
> }
> - if (bswap_code(arm_sctlr_b(env))) {
> +
> + sctlr_b = arm_sctlr_b(env);
> + if (bswap_code(sctlr_b)) {
> #ifdef TARGET_WORDS_BIGENDIAN
> info->endian = BFD_ENDIAN_LITTLE;
> #else
> @@ -514,9 +517,11 @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
> #endif
> }
> info->flags &= ~INSN_ARM_BE32;
> - if (arm_sctlr_b(env)) {
> +#ifndef CONFIG_USER_ONLY
> + if (sctlr_b) {
> info->flags |= INSN_ARM_BE32;
> }
> +#endif
> }
>
> uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-10-20 3:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-10-19 21:21 [Qemu-devel] [PATCH 0/2] Fix armeb-linux-user disassembly Richard Henderson
2017-10-19 21:21 ` [Qemu-devel] [PATCH 1/2] target/arm: Move BE32 disassembler fixup Richard Henderson
2017-10-19 21:21 ` [Qemu-devel] [PATCH 2/2] target/arm: Don't set INSN_ARM_BE32 for CONFIG_USER_ONLY Richard Henderson
2017-10-20 3:38 ` Philippe Mathieu-Daudé
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).