From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10203 invoked by alias); 4 Aug 2008 17:44:00 -0000 Received: (qmail 10191 invoked by uid 22791); 4 Aug 2008 17:43:57 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 04 Aug 2008 17:43:11 +0000 Received: (qmail 9095 invoked from network); 4 Aug 2008 17:43:09 -0000 Received: from unknown (HELO macbook-2.local) (stan@127.0.0.2) by mail.codesourcery.com with ESMTPA; 4 Aug 2008 17:43:09 -0000 Message-ID: <48973FA6.4010304@codesourcery.com> Date: Mon, 04 Aug 2008 17:44:00 -0000 From: Stan Shebs User-Agent: Thunderbird 2.0.0.16 (Macintosh/20080707) MIME-Version: 1.0 To: Doug Evans CC: Stan Shebs , gdb-patches@sourceware.org Subject: Re: [RFA] ARM BE8 support References: <48971BD1.5020907@codesourcery.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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/msg00055.txt.bz2 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 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; >> >> >> >> > >