Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [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