From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32440 invoked by alias); 4 Aug 2008 18:44:27 -0000 Received: (qmail 32429 invoked by uid 22791); 4 Aug 2008 18:44:25 -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 18:43:38 +0000 Received: from wpaz9.hot.corp.google.com (wpaz9.hot.corp.google.com [172.24.198.73]) by smtp-out3.google.com with ESMTP id m74IhQU0019084 for ; Mon, 4 Aug 2008 19:43:27 +0100 Received: from rv-out-0708.google.com (rvfc5.prod.google.com [10.140.180.5]) by wpaz9.hot.corp.google.com with ESMTP id m74Ign9q029491 for ; Mon, 4 Aug 2008 11:43:26 -0700 Received: by rv-out-0708.google.com with SMTP id c5so2210059rvf.24 for ; Mon, 04 Aug 2008 11:43:25 -0700 (PDT) Received: by 10.141.53.4 with SMTP id f4mr7708571rvk.82.1217875405745; Mon, 04 Aug 2008 11:43:25 -0700 (PDT) Received: by 10.141.99.20 with HTTP; Mon, 4 Aug 2008 11:43:25 -0700 (PDT) Message-ID: Date: Mon, 04 Aug 2008 18:44:00 -0000 From: "Doug Evans" To: "Stan Shebs" Subject: Re: [RFA] ARM BE8 support Cc: gdb-patches@sourceware.org In-Reply-To: <48973FA6.4010304@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> <48973FA6.4010304@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/msg00058.txt.bz2 On Mon, Aug 4, 2008 at 10:43 AM, Stan Shebs 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 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; >>> >>> >>> >>> >> >> > >