From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29076 invoked by alias); 4 Aug 2008 15:16:07 -0000 Received: (qmail 29059 invoked by uid 22791); 4 Aug 2008 15:16:03 -0000 X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.33.17) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 04 Aug 2008 15:15:18 +0000 Received: from zps77.corp.google.com (zps77.corp.google.com [172.25.146.77]) by smtp-out.google.com with ESMTP id m74FEwlv016617 for ; Mon, 4 Aug 2008 16:14:58 +0100 Received: from rv-out-0506.google.com (rvbk40.prod.google.com [10.140.87.40]) by zps77.corp.google.com with ESMTP id m74FEvAF026664 for ; Mon, 4 Aug 2008 08:14:57 -0700 Received: by rv-out-0506.google.com with SMTP id k40so2142476rvb.1 for ; Mon, 04 Aug 2008 08:14:57 -0700 (PDT) Received: by 10.141.204.20 with SMTP id g20mr7584389rvq.230.1217862896864; Mon, 04 Aug 2008 08:14:56 -0700 (PDT) Received: by 10.141.99.20 with HTTP; Mon, 4 Aug 2008 08:14:56 -0700 (PDT) Message-ID: Date: Mon, 04 Aug 2008 15:16:00 -0000 From: "Doug Evans" To: "Stan Shebs" Subject: Re: [RFA] ARM BE8 support Cc: gdb-patches@sourceware.org In-Reply-To: <48971BD1.5020907@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <48971BD1.5020907@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-08/txt/msg00053.txt.bz2 Just bite the bullet and add address spaces. 1/2 :-) On Mon, Aug 4, 2008 at 8:10 AM, 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. > > Review-wise, Richard Earnshaw is listed as ARM maintainer, not sure if he's > active here? > > 2008-08-04 Stan Shebs > > 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; > > >