Message ID | 3787ef677853c10ae60beb867c4b3d170391ad2d.1484929304.git.julian@codesourcery.com |
---|---|
State | New |
Headers | show |
On 20 January 2017 at 16:32, Julian Brown <julian@codesourcery.com> wrote: > When debugging a big-endian (either BE8 or BE32) executable, GDB uses > a big-endian byte ordering for its remote protocol. The gdb stub > code in QEMU needs to interpret data in host (little-endian) order in > arm_cpu_gdb_read_register and arm_cpu_gdb_write_register, so this patch > arranges to byte-swap the data to/from GDB in those cases. > > Signed-off-by: Julian Brown <julian@codesourcery.com> > --- > target/arm/gdbstub.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c > index 04c1208..1e9fe68 100644 > --- a/target/arm/gdbstub.c > +++ b/target/arm/gdbstub.c > @@ -21,6 +21,7 @@ > #include "qemu-common.h" > #include "cpu.h" > #include "exec/gdbstub.h" > +#include "exec/softmmu-arm-semi.h" > > /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect > whatever the target description contains. Due to a historical mishap > @@ -32,10 +33,22 @@ int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) > { > ARMCPU *cpu = ARM_CPU(cs); > CPUARMState *env = &cpu->env; > +#ifndef CONFIG_USER_ONLY > + bool targ_bigendian = arm_bswap_needed(env); > +#endif This is a "what is the state of the CPU right this instant" test, but surely gdb doesn't flip its protocol definition as the CPU flips between big and little endian at runtime? I'm not sure what the right check is but it probably isn't this. > > if (n < 16) { > /* Core integer register. */ > +#ifdef CONFIG_USER_ONLY > return gdb_get_reg32(mem_buf, env->regs[n]); > +#else > + if (targ_bigendian) { > + stl_be_p(mem_buf, env->regs[n]); > + } else { > + stl_le_p(mem_buf, env->regs[n]); > + } > + return 4; > +#endif There's probably a phrasing here that avoids the ifdeffery... thanks -- PMM
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 04c1208..1e9fe68 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -21,6 +21,7 @@ #include "qemu-common.h" #include "cpu.h" #include "exec/gdbstub.h" +#include "exec/softmmu-arm-semi.h" /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect whatever the target description contains. Due to a historical mishap @@ -32,10 +33,22 @@ int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; +#ifndef CONFIG_USER_ONLY + bool targ_bigendian = arm_bswap_needed(env); +#endif if (n < 16) { /* Core integer register. */ +#ifdef CONFIG_USER_ONLY return gdb_get_reg32(mem_buf, env->regs[n]); +#else + if (targ_bigendian) { + stl_be_p(mem_buf, env->regs[n]); + } else { + stl_le_p(mem_buf, env->regs[n]); + } + return 4; +#endif } if (n < 24) { /* FPA registers. */ @@ -51,10 +64,28 @@ int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) if (gdb_has_xml) { return 0; } +#ifdef CONFIG_USER_ONLY return gdb_get_reg32(mem_buf, 0); +#else + if (targ_bigendian) { + stl_be_p(mem_buf, 0); + } else { + stl_le_p(mem_buf, 0); + } + return 4; +#endif case 25: /* CPSR */ +#ifdef CONFIG_USER_ONLY return gdb_get_reg32(mem_buf, cpsr_read(env)); +#else + if (targ_bigendian) { + stl_be_p(mem_buf, cpsr_read(env)); + } else { + stl_le_p(mem_buf, cpsr_read(env)); + } + return 4; +#endif } /* Unknown register. */ return 0; @@ -65,8 +96,19 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; uint32_t tmp; +#ifndef CONFIG_USER_ONLY + bool targ_bigendian = arm_bswap_needed(env); +#endif +#ifdef CONFIG_USER_ONLY tmp = ldl_p(mem_buf); +#else + if (targ_bigendian) { + tmp = ldl_be_p(mem_buf); + } else { + tmp = ldl_le_p(mem_buf); + } +#endif /* Mask out low bit of PC to workaround gdb bugs. This will probably cause problems if we ever implement the Jazelle DBX extensions. */
When debugging a big-endian (either BE8 or BE32) executable, GDB uses a big-endian byte ordering for its remote protocol. The gdb stub code in QEMU needs to interpret data in host (little-endian) order in arm_cpu_gdb_read_register and arm_cpu_gdb_write_register, so this patch arranges to byte-swap the data to/from GDB in those cases. Signed-off-by: Julian Brown <julian@codesourcery.com> --- target/arm/gdbstub.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)