* [RFA] ARM BE8 support
@ 2008-08-04 15:11 Stan Shebs
2008-08-04 15:16 ` Doug Evans
2008-08-11 17:01 ` Daniel Jacobowitz
0 siblings, 2 replies; 5+ messages in thread
From: Stan Shebs @ 2008-08-04 15:11 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1517 bytes --]
ARM's BE8 format introduces yet another amusing variation on endianness,
in which the data is big-endian while the code is little-endian. The
bits for binutils went in a while ago, this patch extends GDB. In
theory, we should change functions like read_memory_unsigned_integer to
have forms for both code and data; in lieu of such a sweeping change for
what is rather a narrow use, I introduced macros to swap instruction
bytes after reading. Fortunately, GDB doesn't often need to examine
instructions! This was tested by passing --be8 to the linker and running
under a hacked qemu simulator, no hardware being available yet.
Review-wise, Richard Earnshaw is listed as ARM maintainer, not sure if
he's active here?
2008-08-04 Stan Shebs <stan@codesourcery.com>
ARM BE8 support.
* disasm.c (gdb_disassemble_info): Set endian_code.
* gdbarch.sh (gdbarch_info): New field byte_order_for_code.
* gdbarch.h, gdbarch.c: Regenerate.
* arch-utils.c (initialize_current_architecture): Set the
default byte_order_for_code.
(gdbarch_info_init): Ditto.
(gdbarch_info_fill): Ditto.
* arm-tdep.c (SWAP_INT, SWAP_SHORT): New macros.
(thumb_analyze_prologue): Swap halfword if code endianness is
different from general endianness.
(arm_skip_prologue): Similarly.
(arm_scan_prologue): Ditto.
(thumb_get_next_pc): Ditto.
(arm_get_next_pc): Ditto.
(arm_gdbarch_init): Set byte_order_for_code from BE8 flag,
choose correct endianness for breakpoints.
[-- Attachment #2: be8-gdb-patch-5 --]
[-- Type: text/plain, Size: 9226 bytes --]
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.169
diff -u -p -r1.169 arch-utils.c
--- arch-utils.c 4 May 2008 15:21:05 -0000 1.169
+++ arch-utils.c 4 Aug 2008 00:37:56 -0000
@@ -629,6 +629,7 @@ initialize_current_architecture (void)
}
info.byte_order = default_byte_order;
+ info.byte_order_for_code = info.byte_order;
if (! gdbarch_update_p (info))
internal_error (__FILE__, __LINE__,
@@ -667,6 +668,7 @@ gdbarch_info_init (struct gdbarch_info *
{
memset (info, 0, sizeof (struct gdbarch_info));
info->byte_order = BFD_ENDIAN_UNKNOWN;
+ info->byte_order_for_code = info->byte_order;
info->osabi = GDB_OSABI_UNINITIALIZED;
}
@@ -708,6 +710,7 @@ gdbarch_info_fill (struct gdbarch_info *
/* From the default. */
if (info->byte_order == BFD_ENDIAN_UNKNOWN)
info->byte_order = default_byte_order;
+ info->byte_order_for_code = info->byte_order;
/* "(gdb) set osabi ...". Handled by gdbarch_lookup_osabi. */
if (info->osabi == GDB_OSABI_UNINITIALIZED)
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.266
diff -u -p -r1.266 arm-tdep.c
--- arm-tdep.c 19 May 2008 15:50:09 -0000 1.266
+++ arm-tdep.c 4 Aug 2008 00:37:57 -0000
@@ -69,6 +69,19 @@ static int arm_debug;
#define MSYMBOL_IS_SPECIAL(msym) \
(((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
+/* Macros for swapping shorts and ints. In the unlikely case that anybody else needs these,
+ move to a general header. (A better solution might be to define memory read routines that
+ know whether they are reading code or data.) */
+
+#define SWAP_SHORT(x) \
+ ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8));
+
+#define SWAP_INT(x) \
+ ( ((x & 0xff000000) >> 24) \
+ | ((x & 0x00ff0000) >> 8) \
+ | ((x & 0x0000ff00) << 8) \
+ | ((x & 0x000000ff) << 24))
+
/* Per-objfile data used for mapping symbols. */
static const struct objfile_data *arm_objfile_data_key;
@@ -391,6 +404,9 @@ thumb_analyze_prologue (struct gdbarch *
insn = read_memory_unsigned_integer (start, 2);
+ if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order (gdbarch))
+ insn = SWAP_SHORT (insn);
+
if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
{
int regno;
@@ -559,6 +575,9 @@ arm_skip_prologue (struct gdbarch *gdbar
{
inst = read_memory_unsigned_integer (skip_pc, 4);
+ if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order (gdbarch))
+ inst = SWAP_INT (inst);
+
/* "mov ip, sp" is no longer a required part of the prologue. */
if (inst == 0xe1a0c00d) /* mov ip, sp */
continue;
@@ -855,6 +874,9 @@ arm_scan_prologue (struct frame_info *th
{
unsigned int insn = read_memory_unsigned_integer (current_pc, 4);
+ if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order (gdbarch))
+ insn = SWAP_INT (insn);
+
if (insn == 0xe1a0c00d) /* mov ip, sp */
{
regs[ARM_IP_REGNUM] = regs[ARM_SP_REGNUM];
@@ -1812,6 +1834,9 @@ thumb_get_next_pc (struct frame_info *fr
CORE_ADDR nextpc = pc + 2; /* default is next instruction */
unsigned long offset;
+ if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order (gdbarch))
+ inst1 = SWAP_SHORT (inst1);
+
if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */
{
CORE_ADDR sp;
@@ -1839,6 +1864,8 @@ thumb_get_next_pc (struct frame_info *fr
else if ((inst1 & 0xf800) == 0xf000) /* long branch with link, and blx */
{
unsigned short inst2 = read_memory_unsigned_integer (pc + 2, 2);
+ if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order (gdbarch))
+ inst2 = SWAP_SHORT (inst2);
offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
nextpc = pc_val + offset;
/* For BLX make sure to clear the low bits. */
@@ -1874,6 +1901,10 @@ arm_get_next_pc (struct frame_info *fram
pc_val = (unsigned long) pc;
this_instr = read_memory_unsigned_integer (pc, 4);
+
+ if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order (gdbarch))
+ this_instr = SWAP_INT (this_instr);
+
status = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
@@ -3150,6 +3181,10 @@ arm_gdbarch_init (struct gdbarch_info in
break;
}
}
+
+ if (e_flags & EF_ARM_BE8)
+ info.byte_order_for_code = BFD_ENDIAN_LITTLE;
+
break;
default:
@@ -3192,7 +3227,7 @@ arm_gdbarch_init (struct gdbarch_info in
tdep->have_fpa_registers = have_fpa_registers;
/* Breakpoints. */
- switch (info.byte_order)
+ switch (info.byte_order_for_code)
{
case BFD_ENDIAN_BIG:
tdep->arm_breakpoint = arm_default_arm_be_breakpoint;
Index: disasm.c
===================================================================
RCS file: /cvs/src/src/gdb/disasm.c,v
retrieving revision 1.27
diff -u -p -r1.27 disasm.c
--- disasm.c 1 Jan 2008 22:53:09 -0000 1.27
+++ disasm.c 4 Aug 2008 00:37:57 -0000
@@ -343,6 +343,7 @@ gdb_disassemble_info (struct gdbarch *gd
di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
di.endian = gdbarch_byte_order (gdbarch);
+ di.endian_code = gdbarch_byte_order_for_code (gdbarch);
disassemble_init_for_target (&di);
return di;
}
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.431
diff -u -p -r1.431 gdbarch.c
--- gdbarch.c 25 Jul 2008 16:12:03 -0000 1.431
+++ gdbarch.c 4 Aug 2008 00:37:57 -0000
@@ -90,6 +90,7 @@ struct gdbarch
/* basic architectural information */
const struct bfd_arch_info * bfd_arch_info;
int byte_order;
+ int byte_order_for_code;
enum gdb_osabi osabi;
const struct target_desc * target_desc;
@@ -254,6 +255,7 @@ struct gdbarch startup_gdbarch =
/* basic architecture information */
&bfd_default_arch_struct, /* bfd_arch_info */
BFD_ENDIAN_BIG, /* byte_order */
+ BFD_ENDIAN_BIG, /* byte_order_for_code */
GDB_OSABI_UNKNOWN, /* osabi */
0, /* target_desc */
/* target specific vector and its dump routine */
@@ -398,6 +400,7 @@ gdbarch_alloc (const struct gdbarch_info
gdbarch->bfd_arch_info = info->bfd_arch_info;
gdbarch->byte_order = info->byte_order;
+ gdbarch->byte_order_for_code = info->byte_order_for_code;
gdbarch->osabi = info->osabi;
gdbarch->target_desc = info->target_desc;
@@ -693,6 +696,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s
"gdbarch_dump: byte_order = %s\n",
paddr_d (gdbarch->byte_order));
fprintf_unfiltered (file,
+ "gdbarch_dump: byte_order_for_code = %s\n",
+ paddr_d (gdbarch->byte_order_for_code));
+ fprintf_unfiltered (file,
"gdbarch_dump: call_dummy_location = %s\n",
paddr_d (gdbarch->call_dummy_location));
fprintf_unfiltered (file,
@@ -1122,6 +1128,15 @@ gdbarch_byte_order (struct gdbarch *gdba
return gdbarch->byte_order;
}
+int
+gdbarch_byte_order_for_code (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_byte_order_for_code called\n");
+ return gdbarch->byte_order_for_code;
+}
+
enum gdb_osabi
gdbarch_osabi (struct gdbarch *gdbarch)
{
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.385
diff -u -p -r1.385 gdbarch.h
--- gdbarch.h 22 Jul 2008 02:10:13 -0000 1.385
+++ gdbarch.h 4 Aug 2008 00:37:58 -0000
@@ -64,6 +64,9 @@ extern const struct bfd_arch_info * gdba
extern int gdbarch_byte_order (struct gdbarch *gdbarch);
/* set_gdbarch_byte_order() - not applicable - pre-initialized. */
+extern int gdbarch_byte_order_for_code (struct gdbarch *gdbarch);
+/* set_gdbarch_byte_order_for_code() - not applicable - pre-initialized. */
+
extern enum gdb_osabi gdbarch_osabi (struct gdbarch *gdbarch);
/* set_gdbarch_osabi() - not applicable - pre-initialized. */
@@ -885,6 +888,8 @@ struct gdbarch_info
/* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
int byte_order;
+ int byte_order_for_code;
+
/* Use default: NULL (ZERO). */
bfd *abfd;
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.472
diff -u -p -r1.472 gdbarch.sh
--- gdbarch.sh 25 Jul 2008 16:12:03 -0000 1.472
+++ gdbarch.sh 4 Aug 2008 00:37:58 -0000
@@ -339,6 +339,7 @@ function_list ()
i:const struct bfd_arch_info *:bfd_arch_info:::&bfd_default_arch_struct::::gdbarch_bfd_arch_info (gdbarch)->printable_name
#
i:int:byte_order:::BFD_ENDIAN_BIG
+i:int:byte_order_for_code:::BFD_ENDIAN_BIG
#
i:enum gdb_osabi:osabi:::GDB_OSABI_UNKNOWN
#
@@ -962,6 +963,8 @@ struct gdbarch_info
/* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
int byte_order;
+ int byte_order_for_code;
+
/* Use default: NULL (ZERO). */
bfd *abfd;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFA] ARM BE8 support
2008-08-04 15:11 [RFA] ARM BE8 support Stan Shebs
@ 2008-08-04 15:16 ` Doug Evans
2008-08-04 17:44 ` Stan Shebs
2008-08-11 17:01 ` Daniel Jacobowitz
1 sibling, 1 reply; 5+ messages in thread
From: Doug Evans @ 2008-08-04 15:16 UTC (permalink / raw)
To: Stan Shebs; +Cc: gdb-patches
Just bite the bullet and add address spaces.
1/2 :-)
On Mon, Aug 4, 2008 at 8:10 AM, Stan Shebs <stan@codesourcery.com> wrote:
> ARM's BE8 format introduces yet another amusing variation on endianness, in
> which the data is big-endian while the code is little-endian. The bits for
> binutils went in a while ago, this patch extends GDB. In theory, we should
> change functions like read_memory_unsigned_integer to have forms for both
> code and data; in lieu of such a sweeping change for what is rather a narrow
> use, I introduced macros to swap instruction bytes after reading.
> Fortunately, GDB doesn't often need to examine instructions! This was tested
> by passing --be8 to the linker and running under a hacked qemu simulator, no
> hardware being available yet.
>
> Review-wise, Richard Earnshaw is listed as ARM maintainer, not sure if he's
> active here?
>
> 2008-08-04 Stan Shebs <stan@codesourcery.com>
>
> ARM BE8 support.
> * disasm.c (gdb_disassemble_info): Set endian_code.
> * gdbarch.sh (gdbarch_info): New field byte_order_for_code.
> * gdbarch.h, gdbarch.c: Regenerate.
> * arch-utils.c (initialize_current_architecture): Set the
> default byte_order_for_code.
> (gdbarch_info_init): Ditto.
> (gdbarch_info_fill): Ditto.
> * arm-tdep.c (SWAP_INT, SWAP_SHORT): New macros.
> (thumb_analyze_prologue): Swap halfword if code endianness is
> different from general endianness.
> (arm_skip_prologue): Similarly.
> (arm_scan_prologue): Ditto.
> (thumb_get_next_pc): Ditto.
> (arm_get_next_pc): Ditto.
> (arm_gdbarch_init): Set byte_order_for_code from BE8 flag,
> choose correct endianness for breakpoints.
>
>
>
>
> Index: arch-utils.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/arch-utils.c,v
> retrieving revision 1.169
> diff -u -p -r1.169 arch-utils.c
> --- arch-utils.c 4 May 2008 15:21:05 -0000 1.169
> +++ arch-utils.c 4 Aug 2008 00:37:56 -0000
> @@ -629,6 +629,7 @@ initialize_current_architecture (void)
> }
>
> info.byte_order = default_byte_order;
> + info.byte_order_for_code = info.byte_order;
>
> if (! gdbarch_update_p (info))
> internal_error (__FILE__, __LINE__,
> @@ -667,6 +668,7 @@ gdbarch_info_init (struct gdbarch_info *
> {
> memset (info, 0, sizeof (struct gdbarch_info));
> info->byte_order = BFD_ENDIAN_UNKNOWN;
> + info->byte_order_for_code = info->byte_order;
> info->osabi = GDB_OSABI_UNINITIALIZED;
> }
>
> @@ -708,6 +710,7 @@ gdbarch_info_fill (struct gdbarch_info *
> /* From the default. */
> if (info->byte_order == BFD_ENDIAN_UNKNOWN)
> info->byte_order = default_byte_order;
> + info->byte_order_for_code = info->byte_order;
>
> /* "(gdb) set osabi ...". Handled by gdbarch_lookup_osabi. */
> if (info->osabi == GDB_OSABI_UNINITIALIZED)
> Index: arm-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/arm-tdep.c,v
> retrieving revision 1.266
> diff -u -p -r1.266 arm-tdep.c
> --- arm-tdep.c 19 May 2008 15:50:09 -0000 1.266
> +++ arm-tdep.c 4 Aug 2008 00:37:57 -0000
> @@ -69,6 +69,19 @@ static int arm_debug;
> #define MSYMBOL_IS_SPECIAL(msym) \
> (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
>
> +/* Macros for swapping shorts and ints. In the unlikely case that anybody
> else needs these,
> + move to a general header. (A better solution might be to define memory
> read routines that
> + know whether they are reading code or data.) */
> +
> +#define SWAP_SHORT(x) \
> + ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8));
> +
> +#define SWAP_INT(x) \
> + ( ((x & 0xff000000) >> 24) \
> + | ((x & 0x00ff0000) >> 8) \
> + | ((x & 0x0000ff00) << 8) \
> + | ((x & 0x000000ff) << 24))
> +
> /* Per-objfile data used for mapping symbols. */
> static const struct objfile_data *arm_objfile_data_key;
>
> @@ -391,6 +404,9 @@ thumb_analyze_prologue (struct gdbarch *
>
> insn = read_memory_unsigned_integer (start, 2);
>
> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
> (gdbarch))
> + insn = SWAP_SHORT (insn);
> +
> if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
> {
> int regno;
> @@ -559,6 +575,9 @@ arm_skip_prologue (struct gdbarch *gdbar
> {
> inst = read_memory_unsigned_integer (skip_pc, 4);
>
> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
> (gdbarch))
> + inst = SWAP_INT (inst);
> +
> /* "mov ip, sp" is no longer a required part of the prologue. */
> if (inst == 0xe1a0c00d) /* mov ip, sp */
> continue;
> @@ -855,6 +874,9 @@ arm_scan_prologue (struct frame_info *th
> {
> unsigned int insn = read_memory_unsigned_integer (current_pc, 4);
>
> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
> (gdbarch))
> + insn = SWAP_INT (insn);
> +
> if (insn == 0xe1a0c00d) /* mov ip, sp */
> {
> regs[ARM_IP_REGNUM] = regs[ARM_SP_REGNUM];
> @@ -1812,6 +1834,9 @@ thumb_get_next_pc (struct frame_info *fr
> CORE_ADDR nextpc = pc + 2; /* default is next instruction */
> unsigned long offset;
>
> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
> (gdbarch))
> + inst1 = SWAP_SHORT (inst1);
> +
> if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */
> {
> CORE_ADDR sp;
> @@ -1839,6 +1864,8 @@ thumb_get_next_pc (struct frame_info *fr
> else if ((inst1 & 0xf800) == 0xf000) /* long branch with link, and blx */
> {
> unsigned short inst2 = read_memory_unsigned_integer (pc + 2, 2);
> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
> (gdbarch))
> + inst2 = SWAP_SHORT (inst2);
> offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
> nextpc = pc_val + offset;
> /* For BLX make sure to clear the low bits. */
> @@ -1874,6 +1901,10 @@ arm_get_next_pc (struct frame_info *fram
>
> pc_val = (unsigned long) pc;
> this_instr = read_memory_unsigned_integer (pc, 4);
> +
> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
> (gdbarch))
> + this_instr = SWAP_INT (this_instr);
> +
> status = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
> nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
>
> @@ -3150,6 +3181,10 @@ arm_gdbarch_init (struct gdbarch_info in
> break;
> }
> }
> +
> + if (e_flags & EF_ARM_BE8)
> + info.byte_order_for_code = BFD_ENDIAN_LITTLE;
> +
> break;
>
> default:
> @@ -3192,7 +3227,7 @@ arm_gdbarch_init (struct gdbarch_info in
> tdep->have_fpa_registers = have_fpa_registers;
>
> /* Breakpoints. */
> - switch (info.byte_order)
> + switch (info.byte_order_for_code)
> {
> case BFD_ENDIAN_BIG:
> tdep->arm_breakpoint = arm_default_arm_be_breakpoint;
> Index: disasm.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/disasm.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 disasm.c
> --- disasm.c 1 Jan 2008 22:53:09 -0000 1.27
> +++ disasm.c 4 Aug 2008 00:37:57 -0000
> @@ -343,6 +343,7 @@ gdb_disassemble_info (struct gdbarch *gd
> di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
> di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
> di.endian = gdbarch_byte_order (gdbarch);
> + di.endian_code = gdbarch_byte_order_for_code (gdbarch);
> disassemble_init_for_target (&di);
> return di;
> }
> Index: gdbarch.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.c,v
> retrieving revision 1.431
> diff -u -p -r1.431 gdbarch.c
> --- gdbarch.c 25 Jul 2008 16:12:03 -0000 1.431
> +++ gdbarch.c 4 Aug 2008 00:37:57 -0000
> @@ -90,6 +90,7 @@ struct gdbarch
> /* basic architectural information */
> const struct bfd_arch_info * bfd_arch_info;
> int byte_order;
> + int byte_order_for_code;
> enum gdb_osabi osabi;
> const struct target_desc * target_desc;
>
> @@ -254,6 +255,7 @@ struct gdbarch startup_gdbarch =
> /* basic architecture information */
> &bfd_default_arch_struct, /* bfd_arch_info */
> BFD_ENDIAN_BIG, /* byte_order */
> + BFD_ENDIAN_BIG, /* byte_order_for_code */
> GDB_OSABI_UNKNOWN, /* osabi */
> 0, /* target_desc */
> /* target specific vector and its dump routine */
> @@ -398,6 +400,7 @@ gdbarch_alloc (const struct gdbarch_info
>
> gdbarch->bfd_arch_info = info->bfd_arch_info;
> gdbarch->byte_order = info->byte_order;
> + gdbarch->byte_order_for_code = info->byte_order_for_code;
> gdbarch->osabi = info->osabi;
> gdbarch->target_desc = info->target_desc;
>
> @@ -693,6 +696,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s
> "gdbarch_dump: byte_order = %s\n",
> paddr_d (gdbarch->byte_order));
> fprintf_unfiltered (file,
> + "gdbarch_dump: byte_order_for_code = %s\n",
> + paddr_d (gdbarch->byte_order_for_code));
> + fprintf_unfiltered (file,
> "gdbarch_dump: call_dummy_location = %s\n",
> paddr_d (gdbarch->call_dummy_location));
> fprintf_unfiltered (file,
> @@ -1122,6 +1128,15 @@ gdbarch_byte_order (struct gdbarch *gdba
> return gdbarch->byte_order;
> }
>
> +int
> +gdbarch_byte_order_for_code (struct gdbarch *gdbarch)
> +{
> + gdb_assert (gdbarch != NULL);
> + if (gdbarch_debug >= 2)
> + fprintf_unfiltered (gdb_stdlog, "gdbarch_byte_order_for_code
> called\n");
> + return gdbarch->byte_order_for_code;
> +}
> +
> enum gdb_osabi
> gdbarch_osabi (struct gdbarch *gdbarch)
> {
> Index: gdbarch.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.h,v
> retrieving revision 1.385
> diff -u -p -r1.385 gdbarch.h
> --- gdbarch.h 22 Jul 2008 02:10:13 -0000 1.385
> +++ gdbarch.h 4 Aug 2008 00:37:58 -0000
> @@ -64,6 +64,9 @@ extern const struct bfd_arch_info * gdba
> extern int gdbarch_byte_order (struct gdbarch *gdbarch);
> /* set_gdbarch_byte_order() - not applicable - pre-initialized. */
>
> +extern int gdbarch_byte_order_for_code (struct gdbarch *gdbarch);
> +/* set_gdbarch_byte_order_for_code() - not applicable - pre-initialized. */
> +
> extern enum gdb_osabi gdbarch_osabi (struct gdbarch *gdbarch);
> /* set_gdbarch_osabi() - not applicable - pre-initialized. */
>
> @@ -885,6 +888,8 @@ struct gdbarch_info
> /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
> int byte_order;
>
> + int byte_order_for_code;
> +
> /* Use default: NULL (ZERO). */
> bfd *abfd;
>
> Index: gdbarch.sh
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.sh,v
> retrieving revision 1.472
> diff -u -p -r1.472 gdbarch.sh
> --- gdbarch.sh 25 Jul 2008 16:12:03 -0000 1.472
> +++ gdbarch.sh 4 Aug 2008 00:37:58 -0000
> @@ -339,6 +339,7 @@ function_list ()
> i:const struct bfd_arch_info
> *:bfd_arch_info:::&bfd_default_arch_struct::::gdbarch_bfd_arch_info
> (gdbarch)->printable_name
> #
> i:int:byte_order:::BFD_ENDIAN_BIG
> +i:int:byte_order_for_code:::BFD_ENDIAN_BIG
> #
> i:enum gdb_osabi:osabi:::GDB_OSABI_UNKNOWN
> #
> @@ -962,6 +963,8 @@ struct gdbarch_info
> /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
> int byte_order;
>
> + int byte_order_for_code;
> +
> /* Use default: NULL (ZERO). */
> bfd *abfd;
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFA] ARM BE8 support
2008-08-04 15:16 ` Doug Evans
@ 2008-08-04 17:44 ` Stan Shebs
2008-08-04 18:44 ` Doug Evans
0 siblings, 1 reply; 5+ messages in thread
From: Stan Shebs @ 2008-08-04 17:44 UTC (permalink / raw)
To: Doug Evans; +Cc: Stan Shebs, gdb-patches
Doug Evans wrote:
> Just bite the bullet and add address spaces.
> 1/2 :-)
>
>
Heh, although in this case address spaces probably can't help; on ARM
code and data can easily be mixed down to a per-word level by using the
$a etc symbols. Having two "address spaces" with exactly matching ranges
might be made to work - but that solution seems more horrible than the
problem it is solving!
Stan
> On Mon, Aug 4, 2008 at 8:10 AM, Stan Shebs <stan@codesourcery.com> wrote:
>
>> ARM's BE8 format introduces yet another amusing variation on endianness, in
>> which the data is big-endian while the code is little-endian. The bits for
>> binutils went in a while ago, this patch extends GDB. In theory, we should
>> change functions like read_memory_unsigned_integer to have forms for both
>> code and data; in lieu of such a sweeping change for what is rather a narrow
>> use, I introduced macros to swap instruction bytes after reading.
>> Fortunately, GDB doesn't often need to examine instructions! This was tested
>> by passing --be8 to the linker and running under a hacked qemu simulator, no
>> hardware being available yet.
>>
>> Review-wise, Richard Earnshaw is listed as ARM maintainer, not sure if he's
>> active here?
>>
>> 2008-08-04 Stan Shebs <stan@codesourcery.com>
>>
>> ARM BE8 support.
>> * disasm.c (gdb_disassemble_info): Set endian_code.
>> * gdbarch.sh (gdbarch_info): New field byte_order_for_code.
>> * gdbarch.h, gdbarch.c: Regenerate.
>> * arch-utils.c (initialize_current_architecture): Set the
>> default byte_order_for_code.
>> (gdbarch_info_init): Ditto.
>> (gdbarch_info_fill): Ditto.
>> * arm-tdep.c (SWAP_INT, SWAP_SHORT): New macros.
>> (thumb_analyze_prologue): Swap halfword if code endianness is
>> different from general endianness.
>> (arm_skip_prologue): Similarly.
>> (arm_scan_prologue): Ditto.
>> (thumb_get_next_pc): Ditto.
>> (arm_get_next_pc): Ditto.
>> (arm_gdbarch_init): Set byte_order_for_code from BE8 flag,
>> choose correct endianness for breakpoints.
>>
>>
>>
>>
>> Index: arch-utils.c
>> ===================================================================
>> RCS file: /cvs/src/src/gdb/arch-utils.c,v
>> retrieving revision 1.169
>> diff -u -p -r1.169 arch-utils.c
>> --- arch-utils.c 4 May 2008 15:21:05 -0000 1.169
>> +++ arch-utils.c 4 Aug 2008 00:37:56 -0000
>> @@ -629,6 +629,7 @@ initialize_current_architecture (void)
>> }
>>
>> info.byte_order = default_byte_order;
>> + info.byte_order_for_code = info.byte_order;
>>
>> if (! gdbarch_update_p (info))
>> internal_error (__FILE__, __LINE__,
>> @@ -667,6 +668,7 @@ gdbarch_info_init (struct gdbarch_info *
>> {
>> memset (info, 0, sizeof (struct gdbarch_info));
>> info->byte_order = BFD_ENDIAN_UNKNOWN;
>> + info->byte_order_for_code = info->byte_order;
>> info->osabi = GDB_OSABI_UNINITIALIZED;
>> }
>>
>> @@ -708,6 +710,7 @@ gdbarch_info_fill (struct gdbarch_info *
>> /* From the default. */
>> if (info->byte_order == BFD_ENDIAN_UNKNOWN)
>> info->byte_order = default_byte_order;
>> + info->byte_order_for_code = info->byte_order;
>>
>> /* "(gdb) set osabi ...". Handled by gdbarch_lookup_osabi. */
>> if (info->osabi == GDB_OSABI_UNINITIALIZED)
>> Index: arm-tdep.c
>> ===================================================================
>> RCS file: /cvs/src/src/gdb/arm-tdep.c,v
>> retrieving revision 1.266
>> diff -u -p -r1.266 arm-tdep.c
>> --- arm-tdep.c 19 May 2008 15:50:09 -0000 1.266
>> +++ arm-tdep.c 4 Aug 2008 00:37:57 -0000
>> @@ -69,6 +69,19 @@ static int arm_debug;
>> #define MSYMBOL_IS_SPECIAL(msym) \
>> (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
>>
>> +/* Macros for swapping shorts and ints. In the unlikely case that anybody
>> else needs these,
>> + move to a general header. (A better solution might be to define memory
>> read routines that
>> + know whether they are reading code or data.) */
>> +
>> +#define SWAP_SHORT(x) \
>> + ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8));
>> +
>> +#define SWAP_INT(x) \
>> + ( ((x & 0xff000000) >> 24) \
>> + | ((x & 0x00ff0000) >> 8) \
>> + | ((x & 0x0000ff00) << 8) \
>> + | ((x & 0x000000ff) << 24))
>> +
>> /* Per-objfile data used for mapping symbols. */
>> static const struct objfile_data *arm_objfile_data_key;
>>
>> @@ -391,6 +404,9 @@ thumb_analyze_prologue (struct gdbarch *
>>
>> insn = read_memory_unsigned_integer (start, 2);
>>
>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>> (gdbarch))
>> + insn = SWAP_SHORT (insn);
>> +
>> if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
>> {
>> int regno;
>> @@ -559,6 +575,9 @@ arm_skip_prologue (struct gdbarch *gdbar
>> {
>> inst = read_memory_unsigned_integer (skip_pc, 4);
>>
>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>> (gdbarch))
>> + inst = SWAP_INT (inst);
>> +
>> /* "mov ip, sp" is no longer a required part of the prologue. */
>> if (inst == 0xe1a0c00d) /* mov ip, sp */
>> continue;
>> @@ -855,6 +874,9 @@ arm_scan_prologue (struct frame_info *th
>> {
>> unsigned int insn = read_memory_unsigned_integer (current_pc, 4);
>>
>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>> (gdbarch))
>> + insn = SWAP_INT (insn);
>> +
>> if (insn == 0xe1a0c00d) /* mov ip, sp */
>> {
>> regs[ARM_IP_REGNUM] = regs[ARM_SP_REGNUM];
>> @@ -1812,6 +1834,9 @@ thumb_get_next_pc (struct frame_info *fr
>> CORE_ADDR nextpc = pc + 2; /* default is next instruction */
>> unsigned long offset;
>>
>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>> (gdbarch))
>> + inst1 = SWAP_SHORT (inst1);
>> +
>> if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */
>> {
>> CORE_ADDR sp;
>> @@ -1839,6 +1864,8 @@ thumb_get_next_pc (struct frame_info *fr
>> else if ((inst1 & 0xf800) == 0xf000) /* long branch with link, and blx */
>> {
>> unsigned short inst2 = read_memory_unsigned_integer (pc + 2, 2);
>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>> (gdbarch))
>> + inst2 = SWAP_SHORT (inst2);
>> offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
>> nextpc = pc_val + offset;
>> /* For BLX make sure to clear the low bits. */
>> @@ -1874,6 +1901,10 @@ arm_get_next_pc (struct frame_info *fram
>>
>> pc_val = (unsigned long) pc;
>> this_instr = read_memory_unsigned_integer (pc, 4);
>> +
>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>> (gdbarch))
>> + this_instr = SWAP_INT (this_instr);
>> +
>> status = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
>> nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
>>
>> @@ -3150,6 +3181,10 @@ arm_gdbarch_init (struct gdbarch_info in
>> break;
>> }
>> }
>> +
>> + if (e_flags & EF_ARM_BE8)
>> + info.byte_order_for_code = BFD_ENDIAN_LITTLE;
>> +
>> break;
>>
>> default:
>> @@ -3192,7 +3227,7 @@ arm_gdbarch_init (struct gdbarch_info in
>> tdep->have_fpa_registers = have_fpa_registers;
>>
>> /* Breakpoints. */
>> - switch (info.byte_order)
>> + switch (info.byte_order_for_code)
>> {
>> case BFD_ENDIAN_BIG:
>> tdep->arm_breakpoint = arm_default_arm_be_breakpoint;
>> Index: disasm.c
>> ===================================================================
>> RCS file: /cvs/src/src/gdb/disasm.c,v
>> retrieving revision 1.27
>> diff -u -p -r1.27 disasm.c
>> --- disasm.c 1 Jan 2008 22:53:09 -0000 1.27
>> +++ disasm.c 4 Aug 2008 00:37:57 -0000
>> @@ -343,6 +343,7 @@ gdb_disassemble_info (struct gdbarch *gd
>> di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
>> di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
>> di.endian = gdbarch_byte_order (gdbarch);
>> + di.endian_code = gdbarch_byte_order_for_code (gdbarch);
>> disassemble_init_for_target (&di);
>> return di;
>> }
>> Index: gdbarch.c
>> ===================================================================
>> RCS file: /cvs/src/src/gdb/gdbarch.c,v
>> retrieving revision 1.431
>> diff -u -p -r1.431 gdbarch.c
>> --- gdbarch.c 25 Jul 2008 16:12:03 -0000 1.431
>> +++ gdbarch.c 4 Aug 2008 00:37:57 -0000
>> @@ -90,6 +90,7 @@ struct gdbarch
>> /* basic architectural information */
>> const struct bfd_arch_info * bfd_arch_info;
>> int byte_order;
>> + int byte_order_for_code;
>> enum gdb_osabi osabi;
>> const struct target_desc * target_desc;
>>
>> @@ -254,6 +255,7 @@ struct gdbarch startup_gdbarch =
>> /* basic architecture information */
>> &bfd_default_arch_struct, /* bfd_arch_info */
>> BFD_ENDIAN_BIG, /* byte_order */
>> + BFD_ENDIAN_BIG, /* byte_order_for_code */
>> GDB_OSABI_UNKNOWN, /* osabi */
>> 0, /* target_desc */
>> /* target specific vector and its dump routine */
>> @@ -398,6 +400,7 @@ gdbarch_alloc (const struct gdbarch_info
>>
>> gdbarch->bfd_arch_info = info->bfd_arch_info;
>> gdbarch->byte_order = info->byte_order;
>> + gdbarch->byte_order_for_code = info->byte_order_for_code;
>> gdbarch->osabi = info->osabi;
>> gdbarch->target_desc = info->target_desc;
>>
>> @@ -693,6 +696,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s
>> "gdbarch_dump: byte_order = %s\n",
>> paddr_d (gdbarch->byte_order));
>> fprintf_unfiltered (file,
>> + "gdbarch_dump: byte_order_for_code = %s\n",
>> + paddr_d (gdbarch->byte_order_for_code));
>> + fprintf_unfiltered (file,
>> "gdbarch_dump: call_dummy_location = %s\n",
>> paddr_d (gdbarch->call_dummy_location));
>> fprintf_unfiltered (file,
>> @@ -1122,6 +1128,15 @@ gdbarch_byte_order (struct gdbarch *gdba
>> return gdbarch->byte_order;
>> }
>>
>> +int
>> +gdbarch_byte_order_for_code (struct gdbarch *gdbarch)
>> +{
>> + gdb_assert (gdbarch != NULL);
>> + if (gdbarch_debug >= 2)
>> + fprintf_unfiltered (gdb_stdlog, "gdbarch_byte_order_for_code
>> called\n");
>> + return gdbarch->byte_order_for_code;
>> +}
>> +
>> enum gdb_osabi
>> gdbarch_osabi (struct gdbarch *gdbarch)
>> {
>> Index: gdbarch.h
>> ===================================================================
>> RCS file: /cvs/src/src/gdb/gdbarch.h,v
>> retrieving revision 1.385
>> diff -u -p -r1.385 gdbarch.h
>> --- gdbarch.h 22 Jul 2008 02:10:13 -0000 1.385
>> +++ gdbarch.h 4 Aug 2008 00:37:58 -0000
>> @@ -64,6 +64,9 @@ extern const struct bfd_arch_info * gdba
>> extern int gdbarch_byte_order (struct gdbarch *gdbarch);
>> /* set_gdbarch_byte_order() - not applicable - pre-initialized. */
>>
>> +extern int gdbarch_byte_order_for_code (struct gdbarch *gdbarch);
>> +/* set_gdbarch_byte_order_for_code() - not applicable - pre-initialized. */
>> +
>> extern enum gdb_osabi gdbarch_osabi (struct gdbarch *gdbarch);
>> /* set_gdbarch_osabi() - not applicable - pre-initialized. */
>>
>> @@ -885,6 +888,8 @@ struct gdbarch_info
>> /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
>> int byte_order;
>>
>> + int byte_order_for_code;
>> +
>> /* Use default: NULL (ZERO). */
>> bfd *abfd;
>>
>> Index: gdbarch.sh
>> ===================================================================
>> RCS file: /cvs/src/src/gdb/gdbarch.sh,v
>> retrieving revision 1.472
>> diff -u -p -r1.472 gdbarch.sh
>> --- gdbarch.sh 25 Jul 2008 16:12:03 -0000 1.472
>> +++ gdbarch.sh 4 Aug 2008 00:37:58 -0000
>> @@ -339,6 +339,7 @@ function_list ()
>> i:const struct bfd_arch_info
>> *:bfd_arch_info:::&bfd_default_arch_struct::::gdbarch_bfd_arch_info
>> (gdbarch)->printable_name
>> #
>> i:int:byte_order:::BFD_ENDIAN_BIG
>> +i:int:byte_order_for_code:::BFD_ENDIAN_BIG
>> #
>> i:enum gdb_osabi:osabi:::GDB_OSABI_UNKNOWN
>> #
>> @@ -962,6 +963,8 @@ struct gdbarch_info
>> /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
>> int byte_order;
>>
>> + int byte_order_for_code;
>> +
>> /* Use default: NULL (ZERO). */
>> bfd *abfd;
>>
>>
>>
>>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFA] ARM BE8 support
2008-08-04 17:44 ` Stan Shebs
@ 2008-08-04 18:44 ` Doug Evans
0 siblings, 0 replies; 5+ messages in thread
From: Doug Evans @ 2008-08-04 18:44 UTC (permalink / raw)
To: Stan Shebs; +Cc: gdb-patches
On Mon, Aug 4, 2008 at 10:43 AM, Stan Shebs <stan@codesourcery.com> wrote:
> Doug Evans wrote:
>>
>> Just bite the bullet and add address spaces.
>> 1/2 :-)
>>
>>
>
> Heh, although in this case address spaces probably can't help; on ARM code
> and data can easily be mixed down to a per-word level by using the $a etc
> symbols. Having two "address spaces" with exactly matching ranges might be
> made to work - but that solution seems more horrible than the problem it is
> solving!
I was just kibitzing, but for reference sake since you mention it,
there are targets (x86 even) where there is a range of addresses where
it matters whether you are doing an instruction fetch or a "normal"
memory read, and the answer you get back depends on what kind of
memory read you are doing. I forget the details, but the APIC rings a
bell. A colleague tells me SMRAM has a similar property.
>> On Mon, Aug 4, 2008 at 8:10 AM, Stan Shebs <stan@codesourcery.com> wrote:
>>
>>>
>>> ARM's BE8 format introduces yet another amusing variation on endianness,
>>> in
>>> which the data is big-endian while the code is little-endian. The bits
>>> for
>>> binutils went in a while ago, this patch extends GDB. In theory, we
>>> should
>>> change functions like read_memory_unsigned_integer to have forms for both
>>> code and data; in lieu of such a sweeping change for what is rather a
>>> narrow
>>> use, I introduced macros to swap instruction bytes after reading.
>>> Fortunately, GDB doesn't often need to examine instructions! This was
>>> tested
>>> by passing --be8 to the linker and running under a hacked qemu simulator,
>>> no
>>> hardware being available yet.
>>>
>>> Review-wise, Richard Earnshaw is listed as ARM maintainer, not sure if
>>> he's
>>> active here?
>>>
>>> 2008-08-04 Stan Shebs <stan@codesourcery.com>
>>>
>>> ARM BE8 support.
>>> * disasm.c (gdb_disassemble_info): Set endian_code.
>>> * gdbarch.sh (gdbarch_info): New field byte_order_for_code.
>>> * gdbarch.h, gdbarch.c: Regenerate.
>>> * arch-utils.c (initialize_current_architecture): Set the
>>> default byte_order_for_code.
>>> (gdbarch_info_init): Ditto.
>>> (gdbarch_info_fill): Ditto.
>>> * arm-tdep.c (SWAP_INT, SWAP_SHORT): New macros.
>>> (thumb_analyze_prologue): Swap halfword if code endianness is
>>> different from general endianness.
>>> (arm_skip_prologue): Similarly.
>>> (arm_scan_prologue): Ditto.
>>> (thumb_get_next_pc): Ditto.
>>> (arm_get_next_pc): Ditto.
>>> (arm_gdbarch_init): Set byte_order_for_code from BE8 flag,
>>> choose correct endianness for breakpoints.
>>>
>>>
>>>
>>>
>>> Index: arch-utils.c
>>> ===================================================================
>>> RCS file: /cvs/src/src/gdb/arch-utils.c,v
>>> retrieving revision 1.169
>>> diff -u -p -r1.169 arch-utils.c
>>> --- arch-utils.c 4 May 2008 15:21:05 -0000 1.169
>>> +++ arch-utils.c 4 Aug 2008 00:37:56 -0000
>>> @@ -629,6 +629,7 @@ initialize_current_architecture (void)
>>> }
>>>
>>> info.byte_order = default_byte_order;
>>> + info.byte_order_for_code = info.byte_order;
>>>
>>> if (! gdbarch_update_p (info))
>>> internal_error (__FILE__, __LINE__,
>>> @@ -667,6 +668,7 @@ gdbarch_info_init (struct gdbarch_info *
>>> {
>>> memset (info, 0, sizeof (struct gdbarch_info));
>>> info->byte_order = BFD_ENDIAN_UNKNOWN;
>>> + info->byte_order_for_code = info->byte_order;
>>> info->osabi = GDB_OSABI_UNINITIALIZED;
>>> }
>>>
>>> @@ -708,6 +710,7 @@ gdbarch_info_fill (struct gdbarch_info *
>>> /* From the default. */
>>> if (info->byte_order == BFD_ENDIAN_UNKNOWN)
>>> info->byte_order = default_byte_order;
>>> + info->byte_order_for_code = info->byte_order;
>>>
>>> /* "(gdb) set osabi ...". Handled by gdbarch_lookup_osabi. */
>>> if (info->osabi == GDB_OSABI_UNINITIALIZED)
>>> Index: arm-tdep.c
>>> ===================================================================
>>> RCS file: /cvs/src/src/gdb/arm-tdep.c,v
>>> retrieving revision 1.266
>>> diff -u -p -r1.266 arm-tdep.c
>>> --- arm-tdep.c 19 May 2008 15:50:09 -0000 1.266
>>> +++ arm-tdep.c 4 Aug 2008 00:37:57 -0000
>>> @@ -69,6 +69,19 @@ static int arm_debug;
>>> #define MSYMBOL_IS_SPECIAL(msym) \
>>> (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
>>>
>>> +/* Macros for swapping shorts and ints. In the unlikely case that
>>> anybody
>>> else needs these,
>>> + move to a general header. (A better solution might be to define
>>> memory
>>> read routines that
>>> + know whether they are reading code or data.) */
>>> +
>>> +#define SWAP_SHORT(x) \
>>> + ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8));
>>> +
>>> +#define SWAP_INT(x) \
>>> + ( ((x & 0xff000000) >> 24) \
>>> + | ((x & 0x00ff0000) >> 8) \
>>> + | ((x & 0x0000ff00) << 8) \
>>> + | ((x & 0x000000ff) << 24))
>>> +
>>> /* Per-objfile data used for mapping symbols. */
>>> static const struct objfile_data *arm_objfile_data_key;
>>>
>>> @@ -391,6 +404,9 @@ thumb_analyze_prologue (struct gdbarch *
>>>
>>> insn = read_memory_unsigned_integer (start, 2);
>>>
>>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>>> (gdbarch))
>>> + insn = SWAP_SHORT (insn);
>>> +
>>> if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
>>> {
>>> int regno;
>>> @@ -559,6 +575,9 @@ arm_skip_prologue (struct gdbarch *gdbar
>>> {
>>> inst = read_memory_unsigned_integer (skip_pc, 4);
>>>
>>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>>> (gdbarch))
>>> + inst = SWAP_INT (inst);
>>> +
>>> /* "mov ip, sp" is no longer a required part of the prologue. */
>>> if (inst == 0xe1a0c00d) /* mov ip, sp */
>>> continue;
>>> @@ -855,6 +874,9 @@ arm_scan_prologue (struct frame_info *th
>>> {
>>> unsigned int insn = read_memory_unsigned_integer (current_pc, 4);
>>>
>>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>>> (gdbarch))
>>> + insn = SWAP_INT (insn);
>>> +
>>> if (insn == 0xe1a0c00d) /* mov ip, sp */
>>> {
>>> regs[ARM_IP_REGNUM] = regs[ARM_SP_REGNUM];
>>> @@ -1812,6 +1834,9 @@ thumb_get_next_pc (struct frame_info *fr
>>> CORE_ADDR nextpc = pc + 2; /* default is next instruction */
>>> unsigned long offset;
>>>
>>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>>> (gdbarch))
>>> + inst1 = SWAP_SHORT (inst1);
>>> +
>>> if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */
>>> {
>>> CORE_ADDR sp;
>>> @@ -1839,6 +1864,8 @@ thumb_get_next_pc (struct frame_info *fr
>>> else if ((inst1 & 0xf800) == 0xf000) /* long branch with link, and blx
>>> */
>>> {
>>> unsigned short inst2 = read_memory_unsigned_integer (pc + 2, 2);
>>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>>> (gdbarch))
>>> + inst2 = SWAP_SHORT (inst2);
>>> offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
>>> nextpc = pc_val + offset;
>>> /* For BLX make sure to clear the low bits. */
>>> @@ -1874,6 +1901,10 @@ arm_get_next_pc (struct frame_info *fram
>>>
>>> pc_val = (unsigned long) pc;
>>> this_instr = read_memory_unsigned_integer (pc, 4);
>>> +
>>> + if (gdbarch_byte_order_for_code (gdbarch) != gdbarch_byte_order
>>> (gdbarch))
>>> + this_instr = SWAP_INT (this_instr);
>>> +
>>> status = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
>>> nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
>>>
>>> @@ -3150,6 +3181,10 @@ arm_gdbarch_init (struct gdbarch_info in
>>> break;
>>> }
>>> }
>>> +
>>> + if (e_flags & EF_ARM_BE8)
>>> + info.byte_order_for_code = BFD_ENDIAN_LITTLE;
>>> +
>>> break;
>>>
>>> default:
>>> @@ -3192,7 +3227,7 @@ arm_gdbarch_init (struct gdbarch_info in
>>> tdep->have_fpa_registers = have_fpa_registers;
>>>
>>> /* Breakpoints. */
>>> - switch (info.byte_order)
>>> + switch (info.byte_order_for_code)
>>> {
>>> case BFD_ENDIAN_BIG:
>>> tdep->arm_breakpoint = arm_default_arm_be_breakpoint;
>>> Index: disasm.c
>>> ===================================================================
>>> RCS file: /cvs/src/src/gdb/disasm.c,v
>>> retrieving revision 1.27
>>> diff -u -p -r1.27 disasm.c
>>> --- disasm.c 1 Jan 2008 22:53:09 -0000 1.27
>>> +++ disasm.c 4 Aug 2008 00:37:57 -0000
>>> @@ -343,6 +343,7 @@ gdb_disassemble_info (struct gdbarch *gd
>>> di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
>>> di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
>>> di.endian = gdbarch_byte_order (gdbarch);
>>> + di.endian_code = gdbarch_byte_order_for_code (gdbarch);
>>> disassemble_init_for_target (&di);
>>> return di;
>>> }
>>> Index: gdbarch.c
>>> ===================================================================
>>> RCS file: /cvs/src/src/gdb/gdbarch.c,v
>>> retrieving revision 1.431
>>> diff -u -p -r1.431 gdbarch.c
>>> --- gdbarch.c 25 Jul 2008 16:12:03 -0000 1.431
>>> +++ gdbarch.c 4 Aug 2008 00:37:57 -0000
>>> @@ -90,6 +90,7 @@ struct gdbarch
>>> /* basic architectural information */
>>> const struct bfd_arch_info * bfd_arch_info;
>>> int byte_order;
>>> + int byte_order_for_code;
>>> enum gdb_osabi osabi;
>>> const struct target_desc * target_desc;
>>>
>>> @@ -254,6 +255,7 @@ struct gdbarch startup_gdbarch =
>>> /* basic architecture information */
>>> &bfd_default_arch_struct, /* bfd_arch_info */
>>> BFD_ENDIAN_BIG, /* byte_order */
>>> + BFD_ENDIAN_BIG, /* byte_order_for_code */
>>> GDB_OSABI_UNKNOWN, /* osabi */
>>> 0, /* target_desc */
>>> /* target specific vector and its dump routine */
>>> @@ -398,6 +400,7 @@ gdbarch_alloc (const struct gdbarch_info
>>>
>>> gdbarch->bfd_arch_info = info->bfd_arch_info;
>>> gdbarch->byte_order = info->byte_order;
>>> + gdbarch->byte_order_for_code = info->byte_order_for_code;
>>> gdbarch->osabi = info->osabi;
>>> gdbarch->target_desc = info->target_desc;
>>>
>>> @@ -693,6 +696,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s
>>> "gdbarch_dump: byte_order = %s\n",
>>> paddr_d (gdbarch->byte_order));
>>> fprintf_unfiltered (file,
>>> + "gdbarch_dump: byte_order_for_code = %s\n",
>>> + paddr_d (gdbarch->byte_order_for_code));
>>> + fprintf_unfiltered (file,
>>> "gdbarch_dump: call_dummy_location = %s\n",
>>> paddr_d (gdbarch->call_dummy_location));
>>> fprintf_unfiltered (file,
>>> @@ -1122,6 +1128,15 @@ gdbarch_byte_order (struct gdbarch *gdba
>>> return gdbarch->byte_order;
>>> }
>>>
>>> +int
>>> +gdbarch_byte_order_for_code (struct gdbarch *gdbarch)
>>> +{
>>> + gdb_assert (gdbarch != NULL);
>>> + if (gdbarch_debug >= 2)
>>> + fprintf_unfiltered (gdb_stdlog, "gdbarch_byte_order_for_code
>>> called\n");
>>> + return gdbarch->byte_order_for_code;
>>> +}
>>> +
>>> enum gdb_osabi
>>> gdbarch_osabi (struct gdbarch *gdbarch)
>>> {
>>> Index: gdbarch.h
>>> ===================================================================
>>> RCS file: /cvs/src/src/gdb/gdbarch.h,v
>>> retrieving revision 1.385
>>> diff -u -p -r1.385 gdbarch.h
>>> --- gdbarch.h 22 Jul 2008 02:10:13 -0000 1.385
>>> +++ gdbarch.h 4 Aug 2008 00:37:58 -0000
>>> @@ -64,6 +64,9 @@ extern const struct bfd_arch_info * gdba
>>> extern int gdbarch_byte_order (struct gdbarch *gdbarch);
>>> /* set_gdbarch_byte_order() - not applicable - pre-initialized. */
>>>
>>> +extern int gdbarch_byte_order_for_code (struct gdbarch *gdbarch);
>>> +/* set_gdbarch_byte_order_for_code() - not applicable - pre-initialized.
>>> */
>>> +
>>> extern enum gdb_osabi gdbarch_osabi (struct gdbarch *gdbarch);
>>> /* set_gdbarch_osabi() - not applicable - pre-initialized. */
>>>
>>> @@ -885,6 +888,8 @@ struct gdbarch_info
>>> /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
>>> int byte_order;
>>>
>>> + int byte_order_for_code;
>>> +
>>> /* Use default: NULL (ZERO). */
>>> bfd *abfd;
>>>
>>> Index: gdbarch.sh
>>> ===================================================================
>>> RCS file: /cvs/src/src/gdb/gdbarch.sh,v
>>> retrieving revision 1.472
>>> diff -u -p -r1.472 gdbarch.sh
>>> --- gdbarch.sh 25 Jul 2008 16:12:03 -0000 1.472
>>> +++ gdbarch.sh 4 Aug 2008 00:37:58 -0000
>>> @@ -339,6 +339,7 @@ function_list ()
>>> i:const struct bfd_arch_info
>>> *:bfd_arch_info:::&bfd_default_arch_struct::::gdbarch_bfd_arch_info
>>> (gdbarch)->printable_name
>>> #
>>> i:int:byte_order:::BFD_ENDIAN_BIG
>>> +i:int:byte_order_for_code:::BFD_ENDIAN_BIG
>>> #
>>> i:enum gdb_osabi:osabi:::GDB_OSABI_UNKNOWN
>>> #
>>> @@ -962,6 +963,8 @@ struct gdbarch_info
>>> /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
>>> int byte_order;
>>>
>>> + int byte_order_for_code;
>>> +
>>> /* Use default: NULL (ZERO). */
>>> bfd *abfd;
>>>
>>>
>>>
>>>
>>
>>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFA] ARM BE8 support
2008-08-04 15:11 [RFA] ARM BE8 support Stan Shebs
2008-08-04 15:16 ` Doug Evans
@ 2008-08-11 17:01 ` Daniel Jacobowitz
1 sibling, 0 replies; 5+ messages in thread
From: Daniel Jacobowitz @ 2008-08-11 17:01 UTC (permalink / raw)
To: Stan Shebs; +Cc: gdb-patches
On Mon, Aug 04, 2008 at 08:10:09AM -0700, Stan Shebs wrote:
> ARM's BE8 format introduces yet another amusing variation on endianness,
> in which the data is big-endian while the code is little-endian. The bits
> for binutils went in a while ago, this patch extends GDB. In theory, we
> should change functions like read_memory_unsigned_integer to have forms
> for both code and data; in lieu of such a sweeping change for what is
> rather a narrow use, I introduced macros to swap instruction bytes after
> reading. Fortunately, GDB doesn't often need to examine instructions! This
> was tested by passing --be8 to the linker and running under a hacked qemu
> simulator, no hardware being available yet.
FWIW, this looks good to me.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-08-11 17:01 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-04 15:11 [RFA] ARM BE8 support Stan Shebs
2008-08-04 15:16 ` Doug Evans
2008-08-04 17:44 ` Stan Shebs
2008-08-04 18:44 ` Doug Evans
2008-08-11 17:01 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox