X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fcris-tdep.c;h=f79e84cd2e199f489cf90577db1a611ee35a30d3;hb=9ac4176b6d170664f13074e4dd69b8f110fdb931;hp=731d51601310abc88af864d207d0ecf3862987e0;hpb=9ab9195f183692346cff01bbe15e77774ef1d608;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index 731d516013..f79e84cd2e 100644 --- a/gdb/cris-tdep.c +++ b/gdb/cris-tdep.c @@ -1,28 +1,32 @@ /* Target dependent code for CRIS, for GDB, the GNU debugger. - Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011 Free Software Foundation, Inc. Contributed by Axis Communications AB. Written by Hendrik Ruijter, Stefan Andersson, and Orjan Friberg. -This file is part of GDB. + This file is part of GDB. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "defs.h" #include "frame.h" +#include "frame-unwind.h" +#include "frame-base.h" +#include "trad-frame.h" +#include "dwarf2-frame.h" #include "symtab.h" #include "inferior.h" #include "gdbtypes.h" @@ -35,15 +39,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "regcache.h" #include "gdb_assert.h" -/* To get entry_point_address. */ #include "objfiles.h" -#include "solib.h" /* Support for shared libraries. */ -#include "solib-svr4.h" /* For struct link_map_offsets. */ +#include "solib.h" /* Support for shared libraries. */ +#include "solib-svr4.h" #include "gdb_string.h" #include "dis-asm.h" - enum cris_num_regs { /* There are no floating point registers. Used in gdbserver low-linux.c. */ @@ -53,29 +55,33 @@ enum cris_num_regs NUM_GENREGS = 16, /* There are 16 special registers. */ - NUM_SPECREGS = 16 + NUM_SPECREGS = 16, + + /* CRISv32 has a pseudo PC register, not noted here. */ + + /* CRISv32 has 16 support registers. */ + NUM_SUPPREGS = 16 }; /* Register numbers of various important registers. - DEPRECATED_FP_REGNUM Contains address of executing stack frame. + CRIS_FP_REGNUM Contains address of executing stack frame. STR_REGNUM Contains the address of structure return values. RET_REGNUM Contains the return value when shorter than or equal to 32 bits ARG1_REGNUM Contains the first parameter to a function. ARG2_REGNUM Contains the second parameter to a function. ARG3_REGNUM Contains the third parameter to a function. - ARG4_REGNUM Contains the fourth parameter to a function. Rest on stack. - SP_REGNUM Contains address of top of stack. - PC_REGNUM Contains address of next instruction. + ARG4_REGNUM Contains the fourth parameter to a function. Rest on stack. + gdbarch_sp_regnum Contains address of top of stack. + gdbarch_pc_regnum Contains address of next instruction. SRP_REGNUM Subroutine return pointer register. BRP_REGNUM Breakpoint return pointer register. */ -/* DEPRECATED_FP_REGNUM = 8, SP_REGNUM = 14, and PC_REGNUM = 15 have - been incorporated into the multi-arch framework. */ - enum cris_regnums { /* Enums with respect to the general registers, valid for all - CRIS versions. */ + CRIS versions. The frame pointer is always in R8. */ + CRIS_FP_REGNUM = 8, + /* ABI related registers. */ STR_REGNUM = 9, RET_REGNUM = 10, ARG1_REGNUM = 10, @@ -83,102 +89,439 @@ enum cris_regnums ARG3_REGNUM = 12, ARG4_REGNUM = 13, - /* Enums with respect to the special registers, some of which may not be - applicable to all CRIS versions. */ - P0_REGNUM = 16, + /* Registers which happen to be common. */ VR_REGNUM = 17, - P2_REGNUM = 18, - P3_REGNUM = 19, + MOF_REGNUM = 23, + SRP_REGNUM = 27, + + /* CRISv10 et al. specific registers. */ + P0_REGNUM = 16, P4_REGNUM = 20, CCR_REGNUM = 21, - MOF_REGNUM = 23, P8_REGNUM = 24, IBR_REGNUM = 25, IRP_REGNUM = 26, - SRP_REGNUM = 27, BAR_REGNUM = 28, DCCR_REGNUM = 29, BRP_REGNUM = 30, - USP_REGNUM = 31 + USP_REGNUM = 31, + + /* CRISv32 specific registers. */ + ACR_REGNUM = 15, + BZ_REGNUM = 16, + PID_REGNUM = 18, + SRS_REGNUM = 19, + WZ_REGNUM = 20, + EXS_REGNUM = 21, + EDA_REGNUM = 22, + DZ_REGNUM = 24, + EBP_REGNUM = 25, + ERP_REGNUM = 26, + NRP_REGNUM = 28, + CCS_REGNUM = 29, + CRISV32USP_REGNUM = 30, /* Shares name but not number with CRISv10. */ + SPC_REGNUM = 31, + CRISV32PC_REGNUM = 32, /* Shares name but not number with CRISv10. */ + + S0_REGNUM = 33, + S1_REGNUM = 34, + S2_REGNUM = 35, + S3_REGNUM = 36, + S4_REGNUM = 37, + S5_REGNUM = 38, + S6_REGNUM = 39, + S7_REGNUM = 40, + S8_REGNUM = 41, + S9_REGNUM = 42, + S10_REGNUM = 43, + S11_REGNUM = 44, + S12_REGNUM = 45, + S13_REGNUM = 46, + S14_REGNUM = 47, + S15_REGNUM = 48, }; extern const struct cris_spec_reg cris_spec_regs[]; /* CRIS version, set via the user command 'set cris-version'. Affects - register names and sizes.*/ + register names and sizes. */ static int usr_cmd_cris_version; /* Indicates whether to trust the above variable. */ static int usr_cmd_cris_version_valid = 0; -/* CRIS mode, set via the user command 'set cris-mode'. Affects availability - of some registers. */ -static const char *usr_cmd_cris_mode; +static const char cris_mode_normal[] = "normal"; +static const char cris_mode_guru[] = "guru"; +static const char *cris_modes[] = { + cris_mode_normal, + cris_mode_guru, + 0 +}; + +/* CRIS mode, set via the user command 'set cris-mode'. Affects + type of break instruction among other things. */ +static const char *usr_cmd_cris_mode = cris_mode_normal; -/* Indicates whether to trust the above variable. */ -static int usr_cmd_cris_mode_valid = 0; +/* Whether to make use of Dwarf-2 CFI (default on). */ +static int usr_cmd_cris_dwarf2_cfi = 1; -static const char CRIS_MODE_USER[] = "CRIS_MODE_USER"; -static const char CRIS_MODE_SUPERVISOR[] = "CRIS_MODE_SUPERVISOR"; -static const char *cris_mode_enums[] = +/* CRIS architecture specific information. */ +struct gdbarch_tdep { - CRIS_MODE_USER, - CRIS_MODE_SUPERVISOR, - 0 + int cris_version; + const char *cris_mode; + int cris_dwarf2_cfi; }; -/* CRIS ABI, set via the user command 'set cris-abi'. - There are two flavours: - 1. Original ABI with 32-bit doubles, where arguments <= 4 bytes are - passed by value. - 2. New ABI with 64-bit doubles, where arguments <= 8 bytes are passed by - value. */ -static const char *usr_cmd_cris_abi; +/* Sigtramp identification code copied from i386-linux-tdep.c. */ -/* Indicates whether to trust the above variable. */ -static int usr_cmd_cris_abi_valid = 0; +#define SIGTRAMP_INSN0 0x9c5f /* movu.w 0xXX, $r9 */ +#define SIGTRAMP_OFFSET0 0 +#define SIGTRAMP_INSN1 0xe93d /* break 13 */ +#define SIGTRAMP_OFFSET1 4 -/* These variables are strings instead of enums to make them usable as - parameters to add_set_enum_cmd. */ -static const char CRIS_ABI_ORIGINAL[] = "CRIS_ABI_ORIGINAL"; -static const char CRIS_ABI_V2[] = "CRIS_ABI_V2"; -static const char CRIS_ABI_SYMBOL[] = ".$CRIS_ABI_V2"; -static const char *cris_abi_enums[] = +static const unsigned short sigtramp_code[] = { - CRIS_ABI_ORIGINAL, - CRIS_ABI_V2, - 0 + SIGTRAMP_INSN0, 0x0077, /* movu.w $0x77, $r9 */ + SIGTRAMP_INSN1 /* break 13 */ }; -/* CRIS architecture specific information. */ -struct gdbarch_tdep +#define SIGTRAMP_LEN (sizeof sigtramp_code) + +/* Note: same length as normal sigtramp code. */ + +static const unsigned short rt_sigtramp_code[] = { - int cris_version; - const char *cris_mode; - const char *cris_abi; + SIGTRAMP_INSN0, 0x00ad, /* movu.w $0xad, $r9 */ + SIGTRAMP_INSN1 /* break 13 */ }; -/* Functions for accessing target dependent data. */ +/* If PC is in a sigtramp routine, return the address of the start of + the routine. Otherwise, return 0. */ -static int -cris_version (void) +static CORE_ADDR +cris_sigtramp_start (struct frame_info *this_frame) +{ + CORE_ADDR pc = get_frame_pc (this_frame); + gdb_byte buf[SIGTRAMP_LEN]; + + if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN)) + return 0; + + if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN0) + { + if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN1) + return 0; + + pc -= SIGTRAMP_OFFSET1; + if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN)) + return 0; + } + + if (memcmp (buf, sigtramp_code, SIGTRAMP_LEN) != 0) + return 0; + + return pc; +} + +/* If PC is in a RT sigtramp routine, return the address of the start of + the routine. Otherwise, return 0. */ + +static CORE_ADDR +cris_rt_sigtramp_start (struct frame_info *this_frame) { - return (gdbarch_tdep (current_gdbarch)->cris_version); + CORE_ADDR pc = get_frame_pc (this_frame); + gdb_byte buf[SIGTRAMP_LEN]; + + if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN)) + return 0; + + if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN0) + { + if (((buf[1] << 8) + buf[0]) != SIGTRAMP_INSN1) + return 0; + + pc -= SIGTRAMP_OFFSET1; + if (!safe_frame_unwind_memory (this_frame, pc, buf, SIGTRAMP_LEN)) + return 0; + } + + if (memcmp (buf, rt_sigtramp_code, SIGTRAMP_LEN) != 0) + return 0; + + return pc; } -static const char * -cris_mode (void) +/* Assuming THIS_FRAME is a frame for a GNU/Linux sigtramp routine, + return the address of the associated sigcontext structure. */ + +static CORE_ADDR +cris_sigcontext_addr (struct frame_info *this_frame) { - return (gdbarch_tdep (current_gdbarch)->cris_mode); + struct gdbarch *gdbarch = get_frame_arch (this_frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + CORE_ADDR pc; + CORE_ADDR sp; + char buf[4]; + + get_frame_register (this_frame, gdbarch_sp_regnum (gdbarch), buf); + sp = extract_unsigned_integer (buf, 4, byte_order); + + /* Look for normal sigtramp frame first. */ + pc = cris_sigtramp_start (this_frame); + if (pc) + { + /* struct signal_frame (arch/cris/kernel/signal.c) contains + struct sigcontext as its first member, meaning the SP points to + it already. */ + return sp; + } + + pc = cris_rt_sigtramp_start (this_frame); + if (pc) + { + /* struct rt_signal_frame (arch/cris/kernel/signal.c) contains + a struct ucontext, which in turn contains a struct sigcontext. + Magic digging: + 4 + 4 + 128 to struct ucontext, then + 4 + 4 + 12 to struct sigcontext. */ + return (sp + 156); + } + + error (_("Couldn't recognize signal trampoline.")); + return 0; } -struct frame_extra_info +struct cris_unwind_cache { + /* The previous frame's inner most stack address. Used as this + frame ID's stack_addr. */ + CORE_ADDR prev_sp; + /* The frame's base, optionally used by the high-level debug info. */ + CORE_ADDR base; + int size; + /* How far the SP and r8 (FP) have been offset from the start of + the stack frame (as defined by the previous frame's stack + pointer). */ + LONGEST sp_offset; + LONGEST r8_offset; + int uses_frame; + + /* From old frame_extra_info struct. */ CORE_ADDR return_pc; int leaf_function; + + /* Table indicating the location of each and every register. */ + struct trad_frame_saved_reg *saved_regs; +}; + +static struct cris_unwind_cache * +cris_sigtramp_frame_unwind_cache (struct frame_info *this_frame, + void **this_cache) +{ + struct gdbarch *gdbarch = get_frame_arch (this_frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + struct cris_unwind_cache *info; + CORE_ADDR pc; + CORE_ADDR sp; + CORE_ADDR addr; + char buf[4]; + int i; + + if ((*this_cache)) + return (*this_cache); + + info = FRAME_OBSTACK_ZALLOC (struct cris_unwind_cache); + (*this_cache) = info; + info->saved_regs = trad_frame_alloc_saved_regs (this_frame); + + /* Zero all fields. */ + info->prev_sp = 0; + info->base = 0; + info->size = 0; + info->sp_offset = 0; + info->r8_offset = 0; + info->uses_frame = 0; + info->return_pc = 0; + info->leaf_function = 0; + + get_frame_register (this_frame, gdbarch_sp_regnum (gdbarch), buf); + info->base = extract_unsigned_integer (buf, 4, byte_order); + + addr = cris_sigcontext_addr (this_frame); + + /* Layout of the sigcontext struct: + struct sigcontext { + struct pt_regs regs; + unsigned long oldmask; + unsigned long usp; + }; */ + + if (tdep->cris_version == 10) + { + /* R0 to R13 are stored in reverse order at offset (2 * 4) in + struct pt_regs. */ + for (i = 0; i <= 13; i++) + info->saved_regs[i].addr = addr + ((15 - i) * 4); + + info->saved_regs[MOF_REGNUM].addr = addr + (16 * 4); + info->saved_regs[DCCR_REGNUM].addr = addr + (17 * 4); + info->saved_regs[SRP_REGNUM].addr = addr + (18 * 4); + /* Note: IRP is off by 2 at this point. There's no point in correcting + it though since that will mean that the backtrace will show a PC + different from what is shown when stopped. */ + info->saved_regs[IRP_REGNUM].addr = addr + (19 * 4); + info->saved_regs[gdbarch_pc_regnum (gdbarch)] + = info->saved_regs[IRP_REGNUM]; + info->saved_regs[gdbarch_sp_regnum (gdbarch)].addr = addr + (24 * 4); + } + else + { + /* CRISv32. */ + /* R0 to R13 are stored in order at offset (1 * 4) in + struct pt_regs. */ + for (i = 0; i <= 13; i++) + info->saved_regs[i].addr = addr + ((i + 1) * 4); + + info->saved_regs[ACR_REGNUM].addr = addr + (15 * 4); + info->saved_regs[SRS_REGNUM].addr = addr + (16 * 4); + info->saved_regs[MOF_REGNUM].addr = addr + (17 * 4); + info->saved_regs[SPC_REGNUM].addr = addr + (18 * 4); + info->saved_regs[CCS_REGNUM].addr = addr + (19 * 4); + info->saved_regs[SRP_REGNUM].addr = addr + (20 * 4); + info->saved_regs[ERP_REGNUM].addr = addr + (21 * 4); + info->saved_regs[EXS_REGNUM].addr = addr + (22 * 4); + info->saved_regs[EDA_REGNUM].addr = addr + (23 * 4); + + /* FIXME: If ERP is in a delay slot at this point then the PC will + be wrong at this point. This problem manifests itself in the + sigaltstack.exp test case, which occasionally generates FAILs when + the signal is received while in a delay slot. + + This could be solved by a couple of read_memory_unsigned_integer and a + trad_frame_set_value. */ + info->saved_regs[gdbarch_pc_regnum (gdbarch)] + = info->saved_regs[ERP_REGNUM]; + + info->saved_regs[gdbarch_sp_regnum (gdbarch)].addr + = addr + (25 * 4); + } + + return info; +} + +static void +cris_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache, + struct frame_id *this_id) +{ + struct cris_unwind_cache *cache = + cris_sigtramp_frame_unwind_cache (this_frame, this_cache); + (*this_id) = frame_id_build (cache->base, get_frame_pc (this_frame)); +} + +/* Forward declaration. */ + +static struct value *cris_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum); +static struct value * +cris_sigtramp_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum) +{ + /* Make sure we've initialized the cache. */ + cris_sigtramp_frame_unwind_cache (this_frame, this_cache); + return cris_frame_prev_register (this_frame, this_cache, regnum); +} + +static int +cris_sigtramp_frame_sniffer (const struct frame_unwind *self, + struct frame_info *this_frame, + void **this_cache) +{ + if (cris_sigtramp_start (this_frame) + || cris_rt_sigtramp_start (this_frame)) + return 1; + + return 0; +} + +static const struct frame_unwind cris_sigtramp_frame_unwind = +{ + SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, + cris_sigtramp_frame_this_id, + cris_sigtramp_frame_prev_register, + NULL, + cris_sigtramp_frame_sniffer }; +static int +crisv32_single_step_through_delay (struct gdbarch *gdbarch, + struct frame_info *this_frame) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ULONGEST erp; + int ret = 0; + + if (tdep->cris_mode == cris_mode_guru) + erp = get_frame_register_unsigned (this_frame, NRP_REGNUM); + else + erp = get_frame_register_unsigned (this_frame, ERP_REGNUM); + + if (erp & 0x1) + { + /* In delay slot - check if there's a breakpoint at the preceding + instruction. */ + if (breakpoint_here_p (get_frame_address_space (this_frame), erp & ~0x1)) + ret = 1; + } + return ret; +} + +/* Hardware watchpoint support. */ + +/* We support 6 hardware data watchpoints, but cannot trigger on execute + (any combination of read/write is fine). */ + +int +cris_can_use_hardware_watchpoint (int type, int count, int other) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (target_gdbarch); + + /* No bookkeeping is done here; it is handled by the remote debug agent. */ + + if (tdep->cris_version != 32) + return 0; + else + /* CRISv32: Six data watchpoints, one for instructions. */ + return (((type == bp_read_watchpoint || type == bp_access_watchpoint + || type == bp_hardware_watchpoint) && count <= 6) + || (type == bp_hardware_breakpoint && count <= 1)); +} + +/* The CRISv32 hardware data watchpoints work by specifying ranges, + which have no alignment or length restrictions. */ + +int +cris_region_ok_for_watchpoint (CORE_ADDR addr, int len) +{ + return 1; +} + +/* If the inferior has some watchpoint that triggered, return the + address associated with that watchpoint. Otherwise, return + zero. */ + +CORE_ADDR +cris_stopped_data_address (void) +{ + CORE_ADDR eda; + eda = get_frame_register_unsigned (get_current_frame (), EDA_REGNUM); + return eda; +} + /* The instruction environment needed to find single-step breakpoints. */ + typedef struct instruction_environment { @@ -194,17 +537,9 @@ struct instruction_environment int delay_slot_pc_active; int xflag_found; int disable_interrupt; + int byte_order; } inst_env_type; -/* Save old breakpoints in order to restore the state before a single_step. - At most, two breakpoints will have to be remembered. */ -typedef -char binsn_quantum[BREAKPOINT_MAX]; -static binsn_quantum break_mem[2]; -static CORE_ADDR next_pc = 0; -static CORE_ADDR branch_target_address = 0; -static unsigned char branch_break_inserted = 0; - /* Machine-dependencies in CRIS for opcodes. */ /* Instruction sizes. */ @@ -343,201 +678,519 @@ cris_get_signed_offset (unsigned short insn) /* Calls an op function given the op-type, working on the insn and the inst_env. */ -static void cris_gdb_func (enum cris_op_type, unsigned short, inst_env_type *); - -static CORE_ADDR cris_skip_prologue_main (CORE_ADDR pc, int frameless_p); +static void cris_gdb_func (struct gdbarch *, enum cris_op_type, unsigned short, + inst_env_type *); static struct gdbarch *cris_gdbarch_init (struct gdbarch_info, struct gdbarch_list *); static void cris_dump_tdep (struct gdbarch *, struct ui_file *); -static void cris_version_update (char *ignore_args, int from_tty, - struct cmd_list_element *c); - -static void cris_mode_update (char *ignore_args, int from_tty, - struct cmd_list_element *c); +static void set_cris_version (char *ignore_args, int from_tty, + struct cmd_list_element *c); -static void cris_abi_update (char *ignore_args, int from_tty, - struct cmd_list_element *c); +static void set_cris_mode (char *ignore_args, int from_tty, + struct cmd_list_element *c); -static CORE_ADDR bfd_lookup_symbol (bfd *, const char *); +static void set_cris_dwarf2_cfi (char *ignore_args, int from_tty, + struct cmd_list_element *c); -/* Frames information. The definition of the struct frame_info is +static CORE_ADDR cris_scan_prologue (CORE_ADDR pc, + struct frame_info *this_frame, + struct cris_unwind_cache *info); - CORE_ADDR frame - CORE_ADDR pc - enum frame_type type; - CORE_ADDR return_pc - int leaf_function +static CORE_ADDR crisv32_scan_prologue (CORE_ADDR pc, + struct frame_info *this_frame, + struct cris_unwind_cache *info); - If the compilation option -fno-omit-frame-pointer is present the - variable frame will be set to the content of R8 which is the frame - pointer register. +static CORE_ADDR cris_unwind_pc (struct gdbarch *gdbarch, + struct frame_info *next_frame); - The variable pc contains the address where execution is performed - in the present frame. The innermost frame contains the current content - of the register PC. All other frames contain the content of the - register PC in the next frame. +static CORE_ADDR cris_unwind_sp (struct gdbarch *gdbarch, + struct frame_info *next_frame); - The variable `type' indicates the frame's type: normal, SIGTRAMP - (associated with a signal handler), dummy (associated with a dummy - frame). +/* When arguments must be pushed onto the stack, they go on in reverse + order. The below implements a FILO (stack) to do this. + Copied from d10v-tdep.c. */ - The variable return_pc contains the address where execution should be - resumed when the present frame has finished, the return address. +struct stack_item +{ + int len; + struct stack_item *prev; + void *data; +}; - The variable leaf_function is 1 if the return address is in the register - SRP, and 0 if it is on the stack. +static struct stack_item * +push_stack_item (struct stack_item *prev, void *contents, int len) +{ + struct stack_item *si; + si = xmalloc (sizeof (struct stack_item)); + si->data = xmalloc (len); + si->len = len; + si->prev = prev; + memcpy (si->data, contents, len); + return si; +} - Prologue instructions C-code. - The prologue may consist of (-fno-omit-frame-pointer) - 1) 2) - push srp - push r8 push r8 - move.d sp,r8 move.d sp,r8 - subq X,sp subq X,sp - movem rY,[sp] movem rY,[sp] - move.S rZ,[r8-U] move.S rZ,[r8-U] +static struct stack_item * +pop_stack_item (struct stack_item *si) +{ + struct stack_item *dead = si; + si = si->prev; + xfree (dead->data); + xfree (dead); + return si; +} - where 1 is a non-terminal function, and 2 is a leaf-function. +/* Put here the code to store, into fi->saved_regs, the addresses of + the saved registers of frame described by FRAME_INFO. This + includes special registers such as pc and fp saved in special ways + in the stack frame. sp is even more special: the address we return + for it IS the sp for the next frame. */ - Note that this assumption is extremely brittle, and will break at the - slightest change in GCC's prologue. +static struct cris_unwind_cache * +cris_frame_unwind_cache (struct frame_info *this_frame, + void **this_prologue_cache) +{ + struct gdbarch *gdbarch = get_frame_arch (this_frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + CORE_ADDR pc; + struct cris_unwind_cache *info; + int i; - If local variables are declared or register contents are saved on stack - the subq-instruction will be present with X as the number of bytes - needed for storage. The reshuffle with respect to r8 may be performed - with any size S (b, w, d) and any of the general registers Z={0..13}. - The offset U should be representable by a signed 8-bit value in all cases. - Thus, the prefix word is assumed to be immediate byte offset mode followed - by another word containing the instruction. + if ((*this_prologue_cache)) + return (*this_prologue_cache); + + info = FRAME_OBSTACK_ZALLOC (struct cris_unwind_cache); + (*this_prologue_cache) = info; + info->saved_regs = trad_frame_alloc_saved_regs (this_frame); + + /* Zero all fields. */ + info->prev_sp = 0; + info->base = 0; + info->size = 0; + info->sp_offset = 0; + info->r8_offset = 0; + info->uses_frame = 0; + info->return_pc = 0; + info->leaf_function = 0; + + /* Prologue analysis does the rest... */ + if (tdep->cris_version == 32) + crisv32_scan_prologue (get_frame_func (this_frame), this_frame, info); + else + cris_scan_prologue (get_frame_func (this_frame), this_frame, info); - Degenerate cases: - 3) - push r8 - move.d sp,r8 - move.d r8,sp - pop r8 + return info; +} - Prologue instructions C++-code. - Case 1) and 2) in the C-code may be followed by +/* Given a GDB frame, determine the address of the calling function's + frame. This will be used to create a new GDB frame struct. */ - move.d r10,rS ; this - move.d r11,rT ; P1 - move.d r12,rU ; P2 - move.d r13,rV ; P3 - move.S [r8+U],rZ ; P4 +static void +cris_frame_this_id (struct frame_info *this_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + struct cris_unwind_cache *info + = cris_frame_unwind_cache (this_frame, this_prologue_cache); + CORE_ADDR base; + CORE_ADDR func; + struct frame_id id; + + /* The FUNC is easy. */ + func = get_frame_func (this_frame); + + /* Hopefully the prologue analysis either correctly determined the + frame's base (which is the SP from the previous frame), or set + that base to "NULL". */ + base = info->prev_sp; + if (base == 0) + return; - if any of the call parameters are stored. The host expects these - instructions to be executed in order to get the call parameters right. */ + id = frame_id_build (base, func); -/* Examine the prologue of a function. The variable ip is the address of - the first instruction of the prologue. The variable limit is the address - of the first instruction after the prologue. The variable fi contains the - information in struct frame_info. The variable frameless_p controls whether - the entire prologue is examined (0) or just enough instructions to - determine that it is a prologue (1). */ + (*this_id) = id; +} -static CORE_ADDR -cris_examine (CORE_ADDR ip, CORE_ADDR limit, struct frame_info *fi, - int frameless_p) +static struct value * +cris_frame_prev_register (struct frame_info *this_frame, + void **this_prologue_cache, int regnum) { - /* Present instruction. */ - unsigned short insn; + struct cris_unwind_cache *info + = cris_frame_unwind_cache (this_frame, this_prologue_cache); + return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); +} - /* Next instruction, lookahead. */ - unsigned short insn_next; - int regno; +/* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy + frame. The frame ID's base needs to match the TOS value saved by + save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint. */ - /* Is there a push fp? */ - int have_fp; +static struct frame_id +cris_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) +{ + CORE_ADDR sp; + sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); + return frame_id_build (sp, get_frame_pc (this_frame)); +} - /* Number of byte on stack used for local variables and movem. */ - int val; +static CORE_ADDR +cris_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) +{ + /* Align to the size of an instruction (so that they can safely be + pushed onto the stack). */ + return sp & ~3; +} - /* Highest register number in a movem. */ - int regsave; +static CORE_ADDR +cris_push_dummy_code (struct gdbarch *gdbarch, + CORE_ADDR sp, CORE_ADDR funaddr, + struct value **args, int nargs, + struct type *value_type, + CORE_ADDR *real_pc, CORE_ADDR *bp_addr, + struct regcache *regcache) +{ + /* Allocate space sufficient for a breakpoint. */ + sp = (sp - 4) & ~3; + /* Store the address of that breakpoint */ + *bp_addr = sp; + /* CRIS always starts the call at the callee's entry point. */ + *real_pc = funaddr; + return sp; +} - /* move.d r,rS */ - short source_register; +static CORE_ADDR +cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) +{ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + int stack_alloc; + int stack_offset; + int argreg; + int argnum; - /* This frame is with respect to a leaf until a push srp is found. */ - get_frame_extra_info (fi)->leaf_function = 1; + CORE_ADDR regval; - /* This frame is without the FP until a push fp is found. */ - have_fp = 0; + /* The function's arguments and memory allocated by gdb for the arguments to + point at reside in separate areas on the stack. + Both frame pointers grow toward higher addresses. */ + CORE_ADDR fp_arg; + CORE_ADDR fp_mem; - /* Assume nothing on stack. */ - val = 0; - regsave = -1; + struct stack_item *si = NULL; - /* No information about register contents so far. */ + /* Push the return address. */ + regcache_cooked_write_unsigned (regcache, SRP_REGNUM, bp_addr); - /* We only want to know the end of the prologue when fi->saved_regs == 0. - When the saved registers are allocated full information is required. */ - if (deprecated_get_frame_saved_regs (fi)) + /* Are we returning a value using a structure return or a normal value + return? struct_addr is the address of the reserved space for the return + structure to be written on the stack. */ + if (struct_return) { - for (regno = 0; regno < NUM_REGS; regno++) - deprecated_get_frame_saved_regs (fi)[regno] = 0; + regcache_cooked_write_unsigned (regcache, STR_REGNUM, struct_addr); } - - /* Find the prologue instructions. */ - do - { - insn = read_memory_unsigned_integer (ip, sizeof (short)); - ip += sizeof (short); - if (insn == 0xE1FC) - { - /* push 32 bit instruction */ - insn_next = read_memory_unsigned_integer (ip, sizeof (short)); - ip += sizeof (short); - regno = cris_get_operand2 (insn_next); - /* This check, meant to recognize srp, used to be regno == - (SRP_REGNUM - NUM_GENREGS), but that covers r11 also. */ - if (insn_next == 0xBE7E) + /* Now load as many as possible of the first arguments into registers, + and push the rest onto the stack. */ + argreg = ARG1_REGNUM; + stack_offset = 0; + + for (argnum = 0; argnum < nargs; argnum++) + { + int len; + char *val; + int reg_demand; + int i; + + len = TYPE_LENGTH (value_type (args[argnum])); + val = (char *) value_contents (args[argnum]); + + /* How may registers worth of storage do we need for this argument? */ + reg_demand = (len / 4) + (len % 4 != 0 ? 1 : 0); + + if (len <= (2 * 4) && (argreg + reg_demand - 1 <= ARG4_REGNUM)) + { + /* Data passed by value. Fits in available register(s). */ + for (i = 0; i < reg_demand; i++) + { + regcache_cooked_write (regcache, argreg, val); + argreg++; + val += 4; + } + } + else if (len <= (2 * 4) && argreg <= ARG4_REGNUM) + { + /* Data passed by value. Does not fit in available register(s). + Use the register(s) first, then the stack. */ + for (i = 0; i < reg_demand; i++) { - if (frameless_p) + if (argreg <= ARG4_REGNUM) + { + regcache_cooked_write (regcache, argreg, val); + argreg++; + val += 4; + } + else { - return ip; + /* Push item for later so that pushed arguments + come in the right order. */ + si = push_stack_item (si, val, 4); + val += 4; } - get_frame_extra_info (fi)->leaf_function = 0; } - else if (regno == DEPRECATED_FP_REGNUM) + } + else if (len > (2 * 4)) + { + /* Data passed by reference. Push copy of data onto stack + and pass pointer to this copy as argument. */ + sp = (sp - len) & ~3; + write_memory (sp, val, len); + + if (argreg <= ARG4_REGNUM) + { + regcache_cooked_write_unsigned (regcache, argreg, sp); + argreg++; + } + else + { + gdb_byte buf[4]; + store_unsigned_integer (buf, 4, byte_order, sp); + si = push_stack_item (si, buf, 4); + } + } + else + { + /* Data passed by value. No available registers. Put it on + the stack. */ + si = push_stack_item (si, val, len); + } + } + + while (si) + { + /* fp_arg must be word-aligned (i.e., don't += len) to match + the function prologue. */ + sp = (sp - si->len) & ~3; + write_memory (sp, si->data, si->len); + si = pop_stack_item (si); + } + + /* Finally, update the SP register. */ + regcache_cooked_write_unsigned (regcache, gdbarch_sp_regnum (gdbarch), sp); + + return sp; +} + +static const struct frame_unwind cris_frame_unwind = +{ + NORMAL_FRAME, + default_frame_unwind_stop_reason, + cris_frame_this_id, + cris_frame_prev_register, + NULL, + default_frame_sniffer +}; + +static CORE_ADDR +cris_frame_base_address (struct frame_info *this_frame, void **this_cache) +{ + struct cris_unwind_cache *info + = cris_frame_unwind_cache (this_frame, this_cache); + return info->base; +} + +static const struct frame_base cris_frame_base = +{ + &cris_frame_unwind, + cris_frame_base_address, + cris_frame_base_address, + cris_frame_base_address +}; + +/* Frames information. The definition of the struct frame_info is + + CORE_ADDR frame + CORE_ADDR pc + enum frame_type type; + CORE_ADDR return_pc + int leaf_function + + If the compilation option -fno-omit-frame-pointer is present the + variable frame will be set to the content of R8 which is the frame + pointer register. + + The variable pc contains the address where execution is performed + in the present frame. The innermost frame contains the current content + of the register PC. All other frames contain the content of the + register PC in the next frame. + + The variable `type' indicates the frame's type: normal, SIGTRAMP + (associated with a signal handler), dummy (associated with a dummy + frame). + + The variable return_pc contains the address where execution should be + resumed when the present frame has finished, the return address. + + The variable leaf_function is 1 if the return address is in the register + SRP, and 0 if it is on the stack. + + Prologue instructions C-code. + The prologue may consist of (-fno-omit-frame-pointer) + 1) 2) + push srp + push r8 push r8 + move.d sp,r8 move.d sp,r8 + subq X,sp subq X,sp + movem rY,[sp] movem rY,[sp] + move.S rZ,[r8-U] move.S rZ,[r8-U] + + where 1 is a non-terminal function, and 2 is a leaf-function. + + Note that this assumption is extremely brittle, and will break at the + slightest change in GCC's prologue. + + If local variables are declared or register contents are saved on stack + the subq-instruction will be present with X as the number of bytes + needed for storage. The reshuffle with respect to r8 may be performed + with any size S (b, w, d) and any of the general registers Z={0..13}. + The offset U should be representable by a signed 8-bit value in all cases. + Thus, the prefix word is assumed to be immediate byte offset mode followed + by another word containing the instruction. + + Degenerate cases: + 3) + push r8 + move.d sp,r8 + move.d r8,sp + pop r8 + + Prologue instructions C++-code. + Case 1) and 2) in the C-code may be followed by + + move.d r10,rS ; this + move.d r11,rT ; P1 + move.d r12,rU ; P2 + move.d r13,rV ; P3 + move.S [r8+U],rZ ; P4 + + if any of the call parameters are stored. The host expects these + instructions to be executed in order to get the call parameters right. */ + +/* Examine the prologue of a function. The variable ip is the address of + the first instruction of the prologue. The variable limit is the address + of the first instruction after the prologue. The variable fi contains the + information in struct frame_info. The variable frameless_p controls whether + the entire prologue is examined (0) or just enough instructions to + determine that it is a prologue (1). */ + +static CORE_ADDR +cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame, + struct cris_unwind_cache *info) +{ + struct gdbarch *gdbarch = get_frame_arch (this_frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + + /* Present instruction. */ + unsigned short insn; + + /* Next instruction, lookahead. */ + unsigned short insn_next; + int regno; + + /* Is there a push fp? */ + int have_fp; + + /* Number of byte on stack used for local variables and movem. */ + int val; + + /* Highest register number in a movem. */ + int regsave; + + /* move.d r,rS */ + short source_register; + + /* Scan limit. */ + int limit; + + /* This frame is with respect to a leaf until a push srp is found. */ + if (info) + { + info->leaf_function = 1; + } + + /* Assume nothing on stack. */ + val = 0; + regsave = -1; + + /* If we were called without a this_frame, that means we were called + from cris_skip_prologue which already tried to find the end of the + prologue through the symbol information. 64 instructions past current + pc is arbitrarily chosen, but at least it means we'll stop eventually. */ + limit = this_frame ? get_frame_pc (this_frame) : pc + 64; + + /* Find the prologue instructions. */ + while (pc > 0 && pc < limit) + { + insn = read_memory_unsigned_integer (pc, 2, byte_order); + pc += 2; + if (insn == 0xE1FC) + { + /* push 32 bit instruction. */ + insn_next = read_memory_unsigned_integer (pc, 2, byte_order); + pc += 2; + regno = cris_get_operand2 (insn_next); + if (info) + { + info->sp_offset += 4; + } + /* This check, meant to recognize srp, used to be regno == + (SRP_REGNUM - NUM_GENREGS), but that covers r11 also. */ + if (insn_next == 0xBE7E) + { + if (info) + { + info->leaf_function = 0; + } + } + else if (insn_next == 0x8FEE) { - have_fp = 1; + /* push $r8 */ + if (info) + { + info->r8_offset = info->sp_offset; + } } } else if (insn == 0x866E) { /* move.d sp,r8 */ - if (frameless_p) - { - return ip; - } + if (info) + { + info->uses_frame = 1; + } continue; } - else if (cris_get_operand2 (insn) == SP_REGNUM + else if (cris_get_operand2 (insn) == gdbarch_sp_regnum (gdbarch) && cris_get_mode (insn) == 0x0000 && cris_get_opcode (insn) == 0x000A) { /* subq ,sp */ - val = cris_get_quick_value (insn); + if (info) + { + info->sp_offset += cris_get_quick_value (insn); + } } else if (cris_get_mode (insn) == 0x0002 && cris_get_opcode (insn) == 0x000F && cris_get_size (insn) == 0x0003 - && cris_get_operand1 (insn) == SP_REGNUM) + && cris_get_operand1 (insn) == gdbarch_sp_regnum (gdbarch)) { /* movem r,[sp] */ - if (frameless_p) - { - return ip; - } regsave = cris_get_operand2 (insn); } - else if (cris_get_operand2 (insn) == SP_REGNUM + else if (cris_get_operand2 (insn) == gdbarch_sp_regnum (gdbarch) && ((insn & 0x0F00) >> 8) == 0x0001 && (cris_get_signed_offset (insn) < 0)) { @@ -545,24 +1198,24 @@ cris_examine (CORE_ADDR ip, CORE_ADDR limit, struct frame_info *fi, register. Used for CRIS v8 i.e. ETRAX 100 and newer if is between 64 and 128. movem r,[sp=sp-] */ - val = -cris_get_signed_offset (insn); - insn_next = read_memory_unsigned_integer (ip, sizeof (short)); - ip += sizeof (short); + if (info) + { + info->sp_offset += -cris_get_signed_offset (insn); + } + insn_next = read_memory_unsigned_integer (pc, 2, byte_order); + pc += 2; if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE && cris_get_opcode (insn_next) == 0x000F && cris_get_size (insn_next) == 0x0003 - && cris_get_operand1 (insn_next) == SP_REGNUM) + && cris_get_operand1 (insn_next) == gdbarch_sp_regnum + (gdbarch)) { - if (frameless_p) - { - return ip; - } regsave = cris_get_operand2 (insn_next); } else { /* The prologue ended before the limit was reached. */ - ip -= 2 * sizeof (short); + pc -= 4; break; } } @@ -571,10 +1224,6 @@ cris_examine (CORE_ADDR ip, CORE_ADDR limit, struct frame_info *fi, && cris_get_size (insn) == 0x0002) { /* move.d r<10..13>,r<0..15> */ - if (frameless_p) - { - return ip; - } source_register = cris_get_operand1 (insn); /* FIXME? In the glibc solibs, the prologue might contain something @@ -587,21 +1236,21 @@ cris_examine (CORE_ADDR ip, CORE_ADDR limit, struct frame_info *fi, if (source_register < ARG1_REGNUM || source_register > ARG4_REGNUM) { /* The prologue ended before the limit was reached. */ - ip -= sizeof (short); + pc -= 2; break; } } - else if (cris_get_operand2 (insn) == DEPRECATED_FP_REGNUM + else if (cris_get_operand2 (insn) == CRIS_FP_REGNUM /* The size is a fixed-size. */ && ((insn & 0x0F00) >> 8) == 0x0001 /* A negative offset. */ && (cris_get_signed_offset (insn) < 0)) { /* move.S rZ,[r8-U] (?) */ - insn_next = read_memory_unsigned_integer (ip, sizeof (short)); - ip += sizeof (short); + insn_next = read_memory_unsigned_integer (pc, 2, byte_order); + pc += 2; regno = cris_get_operand2 (insn_next); - if ((regno >= 0 && regno < SP_REGNUM) + if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch)) && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE && cris_get_opcode (insn_next) == 0x000F) { @@ -611,21 +1260,21 @@ cris_examine (CORE_ADDR ip, CORE_ADDR limit, struct frame_info *fi, else { /* The prologue ended before the limit was reached. */ - ip -= 2 * sizeof (short); + pc -= 4; break; } } - else if (cris_get_operand2 (insn) == DEPRECATED_FP_REGNUM + else if (cris_get_operand2 (insn) == CRIS_FP_REGNUM /* The size is a fixed-size. */ && ((insn & 0x0F00) >> 8) == 0x0001 /* A positive offset. */ && (cris_get_signed_offset (insn) > 0)) { /* move.S [r8+U],rZ (?) */ - insn_next = read_memory_unsigned_integer (ip, sizeof (short)); - ip += sizeof (short); + insn_next = read_memory_unsigned_integer (pc, 2, byte_order); + pc += 2; regno = cris_get_operand2 (insn_next); - if ((regno >= 0 && regno < SP_REGNUM) + if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch)) && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE && cris_get_opcode (insn_next) == 0x0009 && cris_get_operand1 (insn_next) == regno) @@ -636,92 +1285,181 @@ cris_examine (CORE_ADDR ip, CORE_ADDR limit, struct frame_info *fi, else { /* The prologue ended before the limit was reached. */ - ip -= 2 * sizeof (short); + pc -= 4; break; } } else { /* The prologue ended before the limit was reached. */ - ip -= sizeof (short); + pc -= 2; break; } } - while (ip < limit); - /* We only want to know the end of the prologue when - fi->saved_regs == 0. */ - if (!deprecated_get_frame_saved_regs (fi)) - return ip; + /* We only want to know the end of the prologue when this_frame and info + are NULL (called from cris_skip_prologue i.e.). */ + if (this_frame == NULL && info == NULL) + { + return pc; + } + + info->size = info->sp_offset; - if (have_fp) + /* Compute the previous frame's stack pointer (which is also the + frame's ID's stack address), and this frame's base pointer. */ + if (info->uses_frame) + { + ULONGEST this_base; + /* The SP was moved to the FP. This indicates that a new frame + was created. Get THIS frame's FP value by unwinding it from + the next frame. */ + this_base = get_frame_register_unsigned (this_frame, CRIS_FP_REGNUM); + info->base = this_base; + info->saved_regs[CRIS_FP_REGNUM].addr = info->base; + + /* The FP points at the last saved register. Adjust the FP back + to before the first saved register giving the SP. */ + info->prev_sp = info->base + info->r8_offset; + } + else { - deprecated_get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM] = get_frame_base (fi); + ULONGEST this_base; + /* Assume that the FP is this frame's SP but with that pushed + stack space added back. */ + this_base = get_frame_register_unsigned (this_frame, + gdbarch_sp_regnum (gdbarch)); + info->base = this_base; + info->prev_sp = info->base + info->size; + } - /* Calculate the addresses. */ - for (regno = regsave; regno >= 0; regno--) - { - deprecated_get_frame_saved_regs (fi)[regno] = get_frame_base (fi) - val; - val -= 4; - } - if (get_frame_extra_info (fi)->leaf_function) - { - /* Set the register SP to contain the stack pointer of - the caller. */ - deprecated_get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) + 4; - } + /* Calculate the addresses for the saved registers on the stack. */ + /* FIXME: The address calculation should really be done on the fly while + we're analyzing the prologue (we only hold one regsave value as it is + now). */ + val = info->sp_offset; + + for (regno = regsave; regno >= 0; regno--) + { + info->saved_regs[regno].addr = info->base + info->r8_offset - val; + val -= 4; + } + + /* The previous frame's SP needed to be computed. Save the computed + value. */ + trad_frame_set_value (info->saved_regs, + gdbarch_sp_regnum (gdbarch), info->prev_sp); + + if (!info->leaf_function) + { + /* SRP saved on the stack. But where? */ + if (info->r8_offset == 0) + { + /* R8 not pushed yet. */ + info->saved_regs[SRP_REGNUM].addr = info->base; + } else - { - /* Set the register SP to contain the stack pointer of - the caller. */ - deprecated_get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) + 8; - - /* Set the register SRP to contain the return address of - the caller. */ - deprecated_get_frame_saved_regs (fi)[SRP_REGNUM] = get_frame_base (fi) + 4; - } + { + /* R8 pushed, but SP may or may not be moved to R8 yet. */ + info->saved_regs[SRP_REGNUM].addr = info->base + 4; + } } - return ip; -} -/* Advance pc beyond any function entry prologue instructions at pc - to reach some "real" code. */ + /* The PC is found in SRP (the actual register or located on the stack). */ + info->saved_regs[gdbarch_pc_regnum (gdbarch)] + = info->saved_regs[SRP_REGNUM]; -static CORE_ADDR -cris_skip_prologue (CORE_ADDR pc) + return pc; +} + +static CORE_ADDR +crisv32_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame, + struct cris_unwind_cache *info) { - return cris_skip_prologue_main (pc, 0); + struct gdbarch *gdbarch = get_frame_arch (this_frame); + ULONGEST this_base; + + /* Unlike the CRISv10 prologue scanner (cris_scan_prologue), this is not + meant to be a full-fledged prologue scanner. It is only needed for + the cases where we end up in code always lacking DWARF-2 CFI, notably: + + * PLT stubs (library calls) + * call dummys + * signal trampolines + + For those cases, it is assumed that there is no actual prologue; that + the stack pointer is not adjusted, and (as a consequence) the return + address is not pushed onto the stack. */ + + /* We only want to know the end of the prologue when this_frame and info + are NULL (called from cris_skip_prologue i.e.). */ + if (this_frame == NULL && info == NULL) + { + return pc; + } + + /* The SP is assumed to be unaltered. */ + this_base = get_frame_register_unsigned (this_frame, + gdbarch_sp_regnum (gdbarch)); + info->base = this_base; + info->prev_sp = this_base; + + /* The PC is assumed to be found in SRP. */ + info->saved_regs[gdbarch_pc_regnum (gdbarch)] + = info->saved_regs[SRP_REGNUM]; + + return pc; } +/* Advance pc beyond any function entry prologue instructions at pc + to reach some "real" code. */ + /* Given a PC value corresponding to the start of a function, return the PC of the first instruction after the function prologue. */ static CORE_ADDR -cris_skip_prologue_main (CORE_ADDR pc, int frameless_p) +cris_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); - struct frame_info *fi; - struct symtab_and_line sal = find_pc_line (pc, 0); - int best_limit; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + CORE_ADDR func_addr, func_end; + struct symtab_and_line sal; CORE_ADDR pc_after_prologue; - /* frame_info now contains dynamic memory. Since fi is a dummy - here, I don't bother allocating memory for saved_regs. */ - fi = deprecated_frame_xmalloc_with_cleanup (0, sizeof (struct frame_extra_info)); - - /* If there is no symbol information then sal.end == 0, and we end up - examining only the first instruction in the function prologue. - Exaggerating the limit seems to be harmless. */ - if (sal.end > 0) - best_limit = sal.end; + /* If we have line debugging information, then the end of the prologue + should the first assembly instruction of the first source line. */ + if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) + { + sal = find_pc_line (func_addr, 0); + if (sal.end > 0 && sal.end < func_end) + return sal.end; + } + + if (tdep->cris_version == 32) + pc_after_prologue = crisv32_scan_prologue (pc, NULL, NULL); else - best_limit = pc + 100; + pc_after_prologue = cris_scan_prologue (pc, NULL, NULL); - pc_after_prologue = cris_examine (pc, best_limit, fi, frameless_p); - do_cleanups (old_chain); return pc_after_prologue; } +static CORE_ADDR +cris_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + ULONGEST pc; + pc = frame_unwind_register_unsigned (next_frame, + gdbarch_pc_regnum (gdbarch)); + return pc; +} + +static CORE_ADDR +cris_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + ULONGEST sp; + sp = frame_unwind_register_unsigned (next_frame, + gdbarch_sp_regnum (gdbarch)); + return sp; +} + /* Use the program counter to determine the contents and size of a breakpoint instruction. It returns a pointer to a string of bytes that encode a breakpoint instruction, stores the length of the string to *lenptr, and @@ -729,30 +1467,29 @@ cris_skip_prologue_main (CORE_ADDR pc, int frameless_p) the breakpoint should be inserted. */ static const unsigned char * -cris_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +cris_breakpoint_from_pc (struct gdbarch *gdbarch, + CORE_ADDR *pcptr, int *lenptr) { - static unsigned char break_insn[] = {0x38, 0xe9}; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + static unsigned char break8_insn[] = {0x38, 0xe9}; + static unsigned char break15_insn[] = {0x3f, 0xe9}; *lenptr = 2; - return break_insn; -} - -/* Returns the register SRP (subroutine return pointer) which must contain - the content of the register PC after a function call. */ - -static CORE_ADDR -cris_saved_pc_after_call (struct frame_info *frame) -{ - return read_register (SRP_REGNUM); + if (tdep->cris_mode == cris_mode_guru) + return break15_insn; + else + return break8_insn; } /* Returns 1 if spec_reg is applicable to the current gdbarch's CRIS version, 0 otherwise. */ static int -cris_spec_reg_applicable (struct cris_spec_reg spec_reg) +cris_spec_reg_applicable (struct gdbarch *gdbarch, + struct cris_spec_reg spec_reg) { - int version = cris_version (); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int version = tdep->cris_version; switch (spec_reg.applicable_version) { @@ -761,9 +1498,6 @@ cris_spec_reg_applicable (struct cris_spec_reg spec_reg) case cris_ver_warning: /* Indeterminate/obsolete. */ return 0; - case cris_ver_sim: - /* Simulator only. */ - return 0; case cris_ver_v0_3: return (version >= 0 && version <= 3); case cris_ver_v3p: @@ -772,8 +1506,18 @@ cris_spec_reg_applicable (struct cris_spec_reg spec_reg) return (version == 8 || version == 9); case cris_ver_v8p: return (version >= 8); + case cris_ver_v0_10: + return (version >= 0 && version <= 10); + case cris_ver_v3_10: + return (version >= 3 && version <= 10); + case cris_ver_v8_10: + return (version >= 8 && version <= 10); + case cris_ver_v10: + return (version == 10); case cris_ver_v10p: return (version >= 10); + case cris_ver_v32p: + return (version >= 32); default: /* Invalid cris version. */ return 0; @@ -784,8 +1528,9 @@ cris_spec_reg_applicable (struct cris_spec_reg spec_reg) register, -1 for an invalid register. */ static int -cris_register_size (int regno) +cris_register_size (struct gdbarch *gdbarch, int regno) { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int i; int spec_regno; @@ -794,54 +1539,58 @@ cris_register_size (int regno) /* General registers (R0 - R15) are 32 bits. */ return 4; } - else if (regno >= NUM_GENREGS && regno < NUM_REGS) + else if (regno >= NUM_GENREGS && regno < (NUM_GENREGS + NUM_SPECREGS)) { /* Special register (R16 - R31). cris_spec_regs is zero-based. Adjust regno accordingly. */ spec_regno = regno - NUM_GENREGS; - /* The entries in cris_spec_regs are stored in register number order, - which means we can shortcut into the array when searching it. */ - for (i = spec_regno; cris_spec_regs[i].name != NULL; i++) + for (i = 0; cris_spec_regs[i].name != NULL; i++) { if (cris_spec_regs[i].number == spec_regno - && cris_spec_reg_applicable (cris_spec_regs[i])) + && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i])) /* Go with the first applicable register. */ return cris_spec_regs[i].reg_size; } /* Special register not applicable to this CRIS version. */ return 0; } - else + else if (regno >= gdbarch_pc_regnum (gdbarch) + && regno < gdbarch_num_regs (gdbarch)) { - /* Invalid register. */ - return -1; + /* This will apply to CRISv32 only where there are additional registers + after the special registers (pseudo PC and support registers). */ + return 4; } + + + return -1; } /* Nonzero if regno should not be fetched from the target. This is the case for unimplemented (size 0) and non-existant registers. */ static int -cris_cannot_fetch_register (int regno) +cris_cannot_fetch_register (struct gdbarch *gdbarch, int regno) { - return ((regno < 0 || regno >= NUM_REGS) - || (cris_register_size (regno) == 0)); + return ((regno < 0 || regno >= gdbarch_num_regs (gdbarch)) + || (cris_register_size (gdbarch, regno) == 0)); } /* Nonzero if regno should not be written to the target, for various reasons. */ static int -cris_cannot_store_register (int regno) +cris_cannot_store_register (struct gdbarch *gdbarch, int regno) { /* There are three kinds of registers we refuse to write to. 1. Those that not implemented. 2. Those that are read-only (depends on the processor mode). - 3. Those registers to which a write has no effect. - */ + 3. Those registers to which a write has no effect. */ - if (regno < 0 || regno >= NUM_REGS || cris_register_size (regno) == 0) + if (regno < 0 + || regno >= gdbarch_num_regs (gdbarch) + || cris_register_size (gdbarch, regno) == 0) /* Not implemented. */ return 1; @@ -853,117 +1602,164 @@ cris_cannot_store_register (int regno) /* Writing has no effect. */ return 1; - else if (cris_mode () == CRIS_MODE_USER) - { - if (regno == IBR_REGNUM || regno == BAR_REGNUM || regno == BRP_REGNUM - || regno == IRP_REGNUM) - /* Read-only in user mode. */ - return 1; - } + /* IBR, BAR, BRP and IRP are read-only in user mode. Let the debug + agent decide whether they are writable. */ return 0; } -/* Returns the register offset for the first byte of register regno's space - in the saved register state. Returns -1 for an invalid or unimplemented - register. */ +/* Nonzero if regno should not be fetched from the target. This is the case + for unimplemented (size 0) and non-existant registers. */ + +static int +crisv32_cannot_fetch_register (struct gdbarch *gdbarch, int regno) +{ + return ((regno < 0 || regno >= gdbarch_num_regs (gdbarch)) + || (cris_register_size (gdbarch, regno) == 0)); +} + +/* Nonzero if regno should not be written to the target, for various + reasons. */ static int -cris_register_offset (int regno) +crisv32_cannot_store_register (struct gdbarch *gdbarch, int regno) { - int i; - int reg_size; - int offset = 0; + /* There are three kinds of registers we refuse to write to. + 1. Those that not implemented. + 2. Those that are read-only (depends on the processor mode). + 3. Those registers to which a write has no effect. */ + + if (regno < 0 + || regno >= gdbarch_num_regs (gdbarch) + || cris_register_size (gdbarch, regno) == 0) + /* Not implemented. */ + return 1; + + else if (regno == VR_REGNUM) + /* Read-only. */ + return 1; + + else if (regno == BZ_REGNUM || regno == WZ_REGNUM || regno == DZ_REGNUM) + /* Writing has no effect. */ + return 1; + + /* Many special registers are read-only in user mode. Let the debug + agent decide whether they are writable. */ - if (regno >= 0 && regno < NUM_REGS) - { - /* FIXME: The offsets should be cached and calculated only once, - when the architecture being debugged has changed. */ - for (i = 0; i < regno; i++) - offset += cris_register_size (i); - - return offset; - } - else - { - /* Invalid register. */ - return -1; - } + return 0; } /* Return the GDB type (defined in gdbtypes.c) for the "standard" data type of data in register regno. */ static struct type * -cris_register_virtual_type (int regno) +cris_register_type (struct gdbarch *gdbarch, int regno) { - if (regno == SP_REGNUM || regno == PC_REGNUM - || (regno > P8_REGNUM && regno < USP_REGNUM)) - { - /* SP, PC, IBR, IRP, SRP, BAR, DCCR, BRP */ - return lookup_pointer_type (builtin_type_void); - } - else if (regno == P8_REGNUM || regno == USP_REGNUM - || (regno >= 0 && regno < SP_REGNUM)) - { - /* R0 - R13, P8, P15 */ - return builtin_type_unsigned_long; - } - else if (regno > P3_REGNUM && regno < P8_REGNUM) - { - /* P4, CCR, DCR0, DCR1 */ - return builtin_type_unsigned_short; - } - else if (regno > PC_REGNUM && regno < P4_REGNUM) - { - /* P0, P1, P2, P3 */ - return builtin_type_unsigned_char; - } + if (regno == gdbarch_pc_regnum (gdbarch)) + return builtin_type (gdbarch)->builtin_func_ptr; + else if (regno == gdbarch_sp_regnum (gdbarch) + || regno == CRIS_FP_REGNUM) + return builtin_type (gdbarch)->builtin_data_ptr; + else if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch)) + || (regno >= MOF_REGNUM && regno <= USP_REGNUM)) + /* Note: R8 taken care of previous clause. */ + return builtin_type (gdbarch)->builtin_uint32; + else if (regno >= P4_REGNUM && regno <= CCR_REGNUM) + return builtin_type (gdbarch)->builtin_uint16; + else if (regno >= P0_REGNUM && regno <= VR_REGNUM) + return builtin_type (gdbarch)->builtin_uint8; + else + /* Invalid (unimplemented) register. */ + return builtin_type (gdbarch)->builtin_int0; +} + +static struct type * +crisv32_register_type (struct gdbarch *gdbarch, int regno) +{ + if (regno == gdbarch_pc_regnum (gdbarch)) + return builtin_type (gdbarch)->builtin_func_ptr; + else if (regno == gdbarch_sp_regnum (gdbarch) + || regno == CRIS_FP_REGNUM) + return builtin_type (gdbarch)->builtin_data_ptr; + else if ((regno >= 0 && regno <= ACR_REGNUM) + || (regno >= EXS_REGNUM && regno <= SPC_REGNUM) + || (regno == PID_REGNUM) + || (regno >= S0_REGNUM && regno <= S15_REGNUM)) + /* Note: R8 and SP taken care of by previous clause. */ + return builtin_type (gdbarch)->builtin_uint32; + else if (regno == WZ_REGNUM) + return builtin_type (gdbarch)->builtin_uint16; + else if (regno == BZ_REGNUM || regno == VR_REGNUM || regno == SRS_REGNUM) + return builtin_type (gdbarch)->builtin_uint8; else { - /* Invalid register. */ - return builtin_type_void; + /* Invalid (unimplemented) register. Should not happen as there are + no unimplemented CRISv32 registers. */ + warning (_("crisv32_register_type: unknown regno %d"), regno); + return builtin_type (gdbarch)->builtin_int0; } } /* Stores a function return value of type type, where valbuf is the address of the value to be stored. */ -/* In the original CRIS ABI, R10 is used to store return values. */ +/* In the CRIS ABI, R10 and R11 are used to store return values. */ static void -cris_abi_original_store_return_value (struct type *type, char *valbuf) +cris_store_return_value (struct type *type, struct regcache *regcache, + const void *valbuf) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + ULONGEST val; int len = TYPE_LENGTH (type); - if (len <= DEPRECATED_REGISTER_SIZE) - deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (RET_REGNUM), valbuf, len); + if (len <= 4) + { + /* Put the return value in R10. */ + val = extract_unsigned_integer (valbuf, len, byte_order); + regcache_cooked_write_unsigned (regcache, ARG1_REGNUM, val); + } + else if (len <= 8) + { + /* Put the return value in R10 and R11. */ + val = extract_unsigned_integer (valbuf, 4, byte_order); + regcache_cooked_write_unsigned (regcache, ARG1_REGNUM, val); + val = extract_unsigned_integer ((char *)valbuf + 4, len - 4, byte_order); + regcache_cooked_write_unsigned (regcache, ARG2_REGNUM, val); + } else - internal_error (__FILE__, __LINE__, "cris_abi_original_store_return_value: type length too large."); + error (_("cris_store_return_value: type length too large.")); } -/* In the CRIS ABI V2, R10 and R11 are used to store return values. */ +/* Return the name of register regno as a string. Return NULL for an + invalid or unimplemented register. */ -static void -cris_abi_v2_store_return_value (struct type *type, char *valbuf) +static const char * +cris_special_register_name (struct gdbarch *gdbarch, int regno) { - int len = TYPE_LENGTH (type); + int spec_regno; + int i; + + /* Special register (R16 - R31). cris_spec_regs is zero-based. + Adjust regno accordingly. */ + spec_regno = regno - NUM_GENREGS; - if (len <= 2 * DEPRECATED_REGISTER_SIZE) + /* Assume nothing about the layout of the cris_spec_regs struct + when searching. */ + for (i = 0; cris_spec_regs[i].name != NULL; i++) { - /* Note that this works since R10 and R11 are consecutive registers. */ - deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (RET_REGNUM), - valbuf, len); + if (cris_spec_regs[i].number == spec_regno + && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i])) + /* Go with the first applicable register. */ + return cris_spec_regs[i].name; } - else - internal_error (__FILE__, __LINE__, "cris_abi_v2_store_return_value: type length too large."); + /* Special register not applicable to this CRIS version. */ + return NULL; } -/* Return the name of register regno as a string. Return NULL for an invalid or - unimplemented register. */ - static const char * -cris_register_name (int regno) +cris_register_name (struct gdbarch *gdbarch, int regno) { static char *cris_genreg_names[] = { "r0", "r1", "r2", "r3", \ @@ -971,550 +1767,162 @@ cris_register_name (int regno) "r8", "r9", "r10", "r11", \ "r12", "r13", "sp", "pc" }; - int i; - int spec_regno; - if (regno >= 0 && regno < NUM_GENREGS) { /* General register. */ return cris_genreg_names[regno]; } - else if (regno >= NUM_GENREGS && regno < NUM_REGS) + else if (regno >= NUM_GENREGS && regno < gdbarch_num_regs (gdbarch)) { - /* Special register (R16 - R31). cris_spec_regs is zero-based. - Adjust regno accordingly. */ - spec_regno = regno - NUM_GENREGS; - - /* The entries in cris_spec_regs are stored in register number order, - which means we can shortcut into the array when searching it. */ - for (i = spec_regno; cris_spec_regs[i].name != NULL; i++) - { - if (cris_spec_regs[i].number == spec_regno - && cris_spec_reg_applicable (cris_spec_regs[i])) - /* Go with the first applicable register. */ - return cris_spec_regs[i].name; - } - /* Special register not applicable to this CRIS version. */ - return NULL; + return cris_special_register_name (gdbarch, regno); } else { /* Invalid register. */ return NULL; } -} - -static int -cris_register_bytes_ok (long bytes) -{ - return (bytes == DEPRECATED_REGISTER_BYTES); -} - -/* Extract from an array regbuf containing the raw register state a function - return value of type type, and copy that, in virtual format, into - valbuf. */ - -/* In the original CRIS ABI, R10 is used to return values. */ - -static void -cris_abi_original_extract_return_value (struct type *type, char *regbuf, - char *valbuf) -{ - int len = TYPE_LENGTH (type); - - if (len <= DEPRECATED_REGISTER_SIZE) - memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (RET_REGNUM), len); - else - internal_error (__FILE__, __LINE__, "cris_abi_original_extract_return_value: type length too large"); -} - -/* In the CRIS ABI V2, R10 and R11 are used to store return values. */ - -static void -cris_abi_v2_extract_return_value (struct type *type, char *regbuf, - char *valbuf) -{ - int len = TYPE_LENGTH (type); - - if (len <= 2 * DEPRECATED_REGISTER_SIZE) - memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (RET_REGNUM), len); - else - internal_error (__FILE__, __LINE__, "cris_abi_v2_extract_return_value: type length too large"); -} - -/* Store the address of the place in which to copy the structure the - subroutine will return. In the CRIS ABI, R9 is used in order to - pass the address of the allocated area where a structure return - value must be stored. */ - -static void -cris_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - write_register (STR_REGNUM, addr); -} - -/* Returns 1 if the given type will be passed by pointer rather than - directly. */ - -/* In the original CRIS ABI, arguments shorter than or equal to 32 bits are - passed by value. */ - -static int -cris_abi_original_reg_struct_has_addr (int gcc_p, struct type *type) -{ - return (TYPE_LENGTH (type) > 4); -} - -/* In the CRIS ABI V2, arguments shorter than or equal to 64 bits are passed - by value. */ - -static int -cris_abi_v2_reg_struct_has_addr (int gcc_p, struct type *type) -{ - return (TYPE_LENGTH (type) > 8); -} - -/* Returns 1 if the function invocation represented by fi does not have a - stack frame associated with it. Otherwise return 0. */ - -static int -cris_frameless_function_invocation (struct frame_info *fi) -{ - if ((get_frame_type (fi) == SIGTRAMP_FRAME)) - return 0; - else - return frameless_look_for_prologue (fi); -} - -/* See frame.h. Determines the address of all registers in the - current stack frame storing each in frame->saved_regs. Space for - frame->saved_regs shall be allocated by - DEPRECATED_FRAME_INIT_SAVED_REGS using frame_saved_regs_zalloc. */ - -static void -cris_frame_init_saved_regs (struct frame_info *fi) -{ - CORE_ADDR ip; - struct symtab_and_line sal; - int best_limit; - char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi), - get_frame_base (fi)); - - /* Examine the entire prologue. */ - int frameless_p = 0; - - /* Has this frame's registers already been initialized? */ - if (deprecated_get_frame_saved_regs (fi)) - return; - - frame_saved_regs_zalloc (fi); - - if (dummy_regs) - { - /* I don't see this ever happening, considering the context in which - cris_frame_init_saved_regs is called (always when we're not in - a dummy frame). */ - memcpy (deprecated_get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS); - } - else - { - ip = get_frame_func (fi); - sal = find_pc_line (ip, 0); - - /* If there is no symbol information then sal.end == 0, and we end up - examining only the first instruction in the function prologue. - Exaggerating the limit seems to be harmless. */ - if (sal.end > 0) - best_limit = sal.end; - else - best_limit = ip + 100; - - cris_examine (ip, best_limit, fi, frameless_p); - } -} - -/* Initialises the extra frame information at the creation of a new frame. - The inparameter fromleaf is 0 when the call is from create_new_frame. - When the call is from get_prev_frame_info, fromleaf is determined by - cris_frameless_function_invocation. */ - -static void -cris_init_extra_frame_info (int fromleaf, struct frame_info *fi) -{ - if (get_next_frame (fi)) - { - /* Called from get_prev_frame. */ - deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi))); - } - - frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info)); - - get_frame_extra_info (fi)->return_pc = 0; - get_frame_extra_info (fi)->leaf_function = 0; - - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), - get_frame_base (fi), - get_frame_base (fi))) - { - /* We need to setup fi->frame here because call_function_by_hand - gets it wrong by assuming it's always FP. */ - deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM)); - get_frame_extra_info (fi)->return_pc = - deprecated_read_register_dummy (get_frame_pc (fi), - get_frame_base (fi), PC_REGNUM); - - /* FIXME: Is this necessarily true? */ - get_frame_extra_info (fi)->leaf_function = 0; - } - else - { - cris_frame_init_saved_regs (fi); - - /* Check fromleaf/frameless_function_invocation. (FIXME) */ - - if (deprecated_get_frame_saved_regs (fi)[SRP_REGNUM] != 0) - { - /* SRP was saved on the stack; non-leaf function. */ - get_frame_extra_info (fi)->return_pc = - read_memory_integer (deprecated_get_frame_saved_regs (fi)[SRP_REGNUM], - DEPRECATED_REGISTER_RAW_SIZE (SRP_REGNUM)); - } - else - { - /* SRP is still in a register; leaf function. */ - get_frame_extra_info (fi)->return_pc = read_register (SRP_REGNUM); - /* FIXME: Should leaf_function be set to 1 here? */ - get_frame_extra_info (fi)->leaf_function = 1; - } - } -} - -/* Return the content of the frame pointer in the present frame. In other - words, determine the address of the calling function's frame. */ - -static CORE_ADDR -cris_frame_chain (struct frame_info *fi) -{ - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), - get_frame_base (fi), - get_frame_base (fi))) - { - return get_frame_base (fi); - } - else if (!deprecated_inside_entry_file (get_frame_pc (fi))) - { - return read_memory_unsigned_integer (get_frame_base (fi), 4); - } - else - { - return 0; - } -} - -/* Return the saved PC (which equals the return address) of this frame. */ - -static CORE_ADDR -cris_frame_saved_pc (struct frame_info *fi) -{ - return get_frame_extra_info (fi)->return_pc; -} - -/* Setup the function arguments for calling a function in the inferior. */ - -static CORE_ADDR -cris_abi_original_push_arguments (int nargs, struct value **args, - CORE_ADDR sp, int struct_return, - CORE_ADDR struct_addr) -{ - int stack_alloc; - int stack_offset; - int argreg; - int argnum; - struct type *type; - int len; - CORE_ADDR regval; - char *val; - - /* Data and parameters reside in different areas on the stack. - Both frame pointers grow toward higher addresses. */ - CORE_ADDR fp_params; - CORE_ADDR fp_data; - - /* Are we returning a value using a structure return or a normal value - return? struct_addr is the address of the reserved space for the return - structure to be written on the stack. */ - if (struct_return) - { - write_register (STR_REGNUM, struct_addr); - } - - /* Make sure there's space on the stack. Allocate space for data and a - parameter to refer to that data. */ - for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++) - stack_alloc += (TYPE_LENGTH (VALUE_TYPE (args[argnum])) + DEPRECATED_REGISTER_SIZE); - sp -= stack_alloc; - /* We may over-allocate a little here, but that won't hurt anything. */ - - /* Initialize stack frame pointers. */ - fp_params = sp; - fp_data = sp + (nargs * DEPRECATED_REGISTER_SIZE); - - /* Now load as many as possible of the first arguments into - registers, and push the rest onto the stack. */ - argreg = ARG1_REGNUM; - stack_offset = 0; - - for (argnum = 0; argnum < nargs; argnum++) - { - type = VALUE_TYPE (args[argnum]); - len = TYPE_LENGTH (type); - val = (char *) VALUE_CONTENTS (args[argnum]); - - if (len <= DEPRECATED_REGISTER_SIZE && argreg <= ARG4_REGNUM) - { - /* Data fits in a register; put it in the first available - register. */ - write_register (argreg, *(unsigned long *) val); - argreg++; - } - else if (len > DEPRECATED_REGISTER_SIZE && argreg <= ARG4_REGNUM) - { - /* Data does not fit in register; pass it on the stack and - put its address in the first available register. */ - write_memory (fp_data, val, len); - write_register (argreg, fp_data); - fp_data += len; - argreg++; - } - else if (len > DEPRECATED_REGISTER_SIZE) - { - /* Data does not fit in register; put both data and - parameter on the stack. */ - write_memory (fp_data, val, len); - write_memory (fp_params, (char *) (&fp_data), DEPRECATED_REGISTER_SIZE); - fp_data += len; - fp_params += DEPRECATED_REGISTER_SIZE; - } - else - { - /* Data fits in a register, but we are out of registers; - put the parameter on the stack. */ - write_memory (fp_params, val, DEPRECATED_REGISTER_SIZE); - fp_params += DEPRECATED_REGISTER_SIZE; - } - } - - return sp; -} - -static CORE_ADDR -cris_abi_v2_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) -{ - int stack_alloc; - int stack_offset; - int argreg; - int argnum; - - CORE_ADDR regval; - - /* The function's arguments and memory allocated by gdb for the arguments to - point at reside in separate areas on the stack. - Both frame pointers grow toward higher addresses. */ - CORE_ADDR fp_arg; - CORE_ADDR fp_mem; - - /* Are we returning a value using a structure return or a normal value - return? struct_addr is the address of the reserved space for the return - structure to be written on the stack. */ - if (struct_return) - { - write_register (STR_REGNUM, struct_addr); - } - - /* Allocate enough to keep things word-aligned on both parts of the - stack. */ - stack_alloc = 0; - for (argnum = 0; argnum < nargs; argnum++) - { - int len; - int reg_demand; - - len = TYPE_LENGTH (VALUE_TYPE (args[argnum])); - reg_demand = (len / DEPRECATED_REGISTER_SIZE) + (len % DEPRECATED_REGISTER_SIZE != 0 ? 1 : 0); - - /* reg_demand * DEPRECATED_REGISTER_SIZE is the amount of memory - we might need to allocate for this argument. 2 * - DEPRECATED_REGISTER_SIZE is the amount of stack space we - might need to pass the argument itself (either by value or by - reference). */ - stack_alloc += (reg_demand * DEPRECATED_REGISTER_SIZE + 2 * DEPRECATED_REGISTER_SIZE); - } - sp -= stack_alloc; - /* We may over-allocate a little here, but that won't hurt anything. */ - - /* Initialize frame pointers. */ - fp_arg = sp; - fp_mem = sp + (nargs * (2 * DEPRECATED_REGISTER_SIZE)); - - /* Now load as many as possible of the first arguments into registers, - and push the rest onto the stack. */ - argreg = ARG1_REGNUM; - stack_offset = 0; - - for (argnum = 0; argnum < nargs; argnum++) - { - int len; - char *val; - int reg_demand; - int i; - - len = TYPE_LENGTH (VALUE_TYPE (args[argnum])); - val = (char *) VALUE_CONTENTS (args[argnum]); - - /* How may registers worth of storage do we need for this argument? */ - reg_demand = (len / DEPRECATED_REGISTER_SIZE) + (len % DEPRECATED_REGISTER_SIZE != 0 ? 1 : 0); - - if (len <= (2 * DEPRECATED_REGISTER_SIZE) - && (argreg + reg_demand - 1 <= ARG4_REGNUM)) - { - /* Data passed by value. Fits in available register(s). */ - for (i = 0; i < reg_demand; i++) - { - write_register (argreg, *(unsigned long *) val); - argreg++; - val += DEPRECATED_REGISTER_SIZE; - } - } - else if (len <= (2 * DEPRECATED_REGISTER_SIZE) && argreg <= ARG4_REGNUM) - { - /* Data passed by value. Does not fit in available register(s). - Use the register(s) first, then the stack. */ - for (i = 0; i < reg_demand; i++) - { - if (argreg <= ARG4_REGNUM) - { - write_register (argreg, *(unsigned long *) val); - argreg++; - val += DEPRECATED_REGISTER_SIZE; - } - else - { - /* I guess this memory write could write the - remaining data all at once instead of in - DEPRECATED_REGISTER_SIZE chunks. */ - write_memory (fp_arg, val, DEPRECATED_REGISTER_SIZE); - fp_arg += DEPRECATED_REGISTER_SIZE; - val += DEPRECATED_REGISTER_SIZE; - } - } - } - else if (len > (2 * DEPRECATED_REGISTER_SIZE)) - { - /* Data passed by reference. Put it on the stack. */ - write_memory (fp_mem, val, len); - write_memory (fp_arg, (char *) (&fp_mem), DEPRECATED_REGISTER_SIZE); - - /* fp_mem need not be word-aligned since it's just a chunk of - memory being pointed at. That is, += len would do. */ - fp_mem += reg_demand * DEPRECATED_REGISTER_SIZE; - fp_arg += DEPRECATED_REGISTER_SIZE; - } - else - { - /* Data passed by value. No available registers. Put it on - the stack. */ - write_memory (fp_arg, val, len); +} - /* fp_arg must be word-aligned (i.e., don't += len) to match - the function prologue. */ - fp_arg += reg_demand * DEPRECATED_REGISTER_SIZE; - } +static const char * +crisv32_register_name (struct gdbarch *gdbarch, int regno) +{ + static char *crisv32_genreg_names[] = + { "r0", "r1", "r2", "r3", \ + "r4", "r5", "r6", "r7", \ + "r8", "r9", "r10", "r11", \ + "r12", "r13", "sp", "acr" + }; + + static char *crisv32_sreg_names[] = + { "s0", "s1", "s2", "s3", \ + "s4", "s5", "s6", "s7", \ + "s8", "s9", "s10", "s11", \ + "s12", "s13", "s14", "s15" + }; + + if (regno >= 0 && regno < NUM_GENREGS) + { + /* General register. */ + return crisv32_genreg_names[regno]; + } + else if (regno >= NUM_GENREGS && regno < (NUM_GENREGS + NUM_SPECREGS)) + { + return cris_special_register_name (gdbarch, regno); + } + else if (regno == gdbarch_pc_regnum (gdbarch)) + { + return "pc"; + } + else if (regno >= S0_REGNUM && regno <= S15_REGNUM) + { + return crisv32_sreg_names[regno - S0_REGNUM]; + } + else + { + /* Invalid register. */ + return NULL; } +} - return sp; +/* Convert DWARF register number REG to the appropriate register + number used by GDB. */ + +static int +cris_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) +{ + /* We need to re-map a couple of registers (SRP is 16 in Dwarf-2 register + numbering, MOF is 18). + Adapted from gcc/config/cris/cris.h. */ + static int cris_dwarf_regmap[] = { + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 27, -1, -1, -1, + -1, -1, -1, 23, + -1, -1, -1, 27, + -1, -1, -1, -1 + }; + int regnum = -1; + + if (reg >= 0 && reg < ARRAY_SIZE (cris_dwarf_regmap)) + regnum = cris_dwarf_regmap[reg]; + + if (regnum == -1) + warning (_("Unmapped DWARF Register #%d encountered."), reg); + + return regnum; } -/* Never put the return address on the stack. The register SRP is pushed - by the called function unless it is a leaf-function. Due to the BRP - register the PC will change when continue is sent. */ +/* DWARF-2 frame support. */ -static CORE_ADDR -cris_push_return_address (CORE_ADDR pc, CORE_ADDR sp) +static void +cris_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, + struct dwarf2_frame_state_reg *reg, + struct frame_info *this_frame) { - write_register (SRP_REGNUM, entry_point_address ()); - return sp; + /* The return address column. */ + if (regnum == gdbarch_pc_regnum (gdbarch)) + reg->how = DWARF2_FRAME_REG_RA; + + /* The call frame address. */ + else if (regnum == gdbarch_sp_regnum (gdbarch)) + reg->how = DWARF2_FRAME_REG_CFA; } -/* Restore the machine to the state it had before the current frame - was created. Discard the innermost frame from the stack and restore - all saved registers. */ +/* Extract from an array regbuf containing the raw register state a function + return value of type type, and copy that, in virtual format, into + valbuf. */ -static void -cris_pop_frame (void) +/* In the CRIS ABI, R10 and R11 are used to store return values. */ + +static void +cris_extract_return_value (struct type *type, struct regcache *regcache, + void *valbuf) { - struct frame_info *fi = get_current_frame (); - int regno; - int stack_offset = 0; + struct gdbarch *gdbarch = get_regcache_arch (regcache); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + ULONGEST val; + int len = TYPE_LENGTH (type); - if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), - get_frame_base (fi), - get_frame_base (fi))) + if (len <= 4) { - /* This happens when we hit a breakpoint set at the entry point, - when returning from a dummy frame. */ - generic_pop_dummy_frame (); + /* Get the return value from R10. */ + regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &val); + store_unsigned_integer (valbuf, len, byte_order, val); } - else + else if (len <= 8) { - cris_frame_init_saved_regs (fi); - - /* For each register, the address of where it was saved on entry to - the frame now lies in fi->saved_regs[regno], or zero if it was not - saved. This includes special registers such as PC and FP saved in - special ways in the stack frame. The SP_REGNUM is even more - special, the address here is the SP for the next frame, not the - address where the SP was saved. */ - - /* Restore general registers R0 - R7. They were pushed on the stack - after SP was saved. */ - for (regno = 0; regno < DEPRECATED_FP_REGNUM; regno++) - { - if (deprecated_get_frame_saved_regs (fi)[regno]) - { - write_register (regno, - read_memory_integer (deprecated_get_frame_saved_regs (fi)[regno], 4)); - } - } - - if (deprecated_get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM]) - { - /* Pop the frame pointer (R8). It was pushed before SP - was saved. */ - write_register (DEPRECATED_FP_REGNUM, - read_memory_integer (deprecated_get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM], 4)); - stack_offset += 4; - - /* Not a leaf function. */ - if (deprecated_get_frame_saved_regs (fi)[SRP_REGNUM]) - { - /* SRP was pushed before SP was saved. */ - stack_offset += 4; - } - - /* Restore the SP and adjust for R8 and (possibly) SRP. */ - write_register (SP_REGNUM, deprecated_get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM] + stack_offset); - } - else - { - /* Currently, we can't get the correct info into fi->saved_regs - without a frame pointer. */ - } - - /* Restore the PC. */ - write_register (PC_REGNUM, get_frame_extra_info (fi)->return_pc); + /* Get the return value from R10 and R11. */ + regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &val); + store_unsigned_integer (valbuf, 4, byte_order, val); + regcache_cooked_read_unsigned (regcache, ARG2_REGNUM, &val); + store_unsigned_integer ((char *)valbuf + 4, len - 4, byte_order, val); } - flush_cached_frames (); + else + error (_("cris_extract_return_value: type length too large")); +} + +/* Handle the CRIS return value convention. */ + +static enum return_value_convention +cris_return_value (struct gdbarch *gdbarch, struct type *func_type, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) +{ + if (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION + || TYPE_LENGTH (type) > 8) + /* Structs, unions, and anything larger than 8 bytes (2 registers) + goes on the stack. */ + return RETURN_VALUE_STRUCT_CONVENTION; + + if (readbuf) + cris_extract_return_value (type, regcache, readbuf); + if (writebuf) + cris_store_return_value (type, regcache, writebuf); + + return RETURN_VALUE_REGISTER_CONVENTION; } /* Calculates a value that measures how good inst_args constraints an @@ -1621,7 +2029,9 @@ find_cris_op (unsigned short insn, inst_env_type *inst_env) for (i = 0; cris_opcodes[i].name != NULL; i++) { if (((cris_opcodes[i].match & insn) == cris_opcodes[i].match) - && ((cris_opcodes[i].lose & insn) == 0)) + && ((cris_opcodes[i].lose & insn) == 0) + /* Only CRISv10 instructions, please. */ + && (cris_opcodes[i].applicable_version != cris_ver_v32p)) { level_of_match = constraint (insn, cris_opcodes[i].args, inst_env); if (level_of_match >= 0) @@ -1648,21 +2058,25 @@ find_cris_op (unsigned short insn, inst_env_type *inst_env) actually an internal error. */ static int -find_step_target (inst_env_type *inst_env) +find_step_target (struct frame_info *frame, inst_env_type *inst_env) { int i; int offset; unsigned short insn; + struct gdbarch *gdbarch = get_frame_arch (frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Create a local register image and set the initial state. */ for (i = 0; i < NUM_GENREGS; i++) { - inst_env->reg[i] = (unsigned long) read_register (i); + inst_env->reg[i] = + (unsigned long) get_frame_register_unsigned (frame, i); } offset = NUM_GENREGS; for (i = 0; i < NUM_SPECREGS; i++) { - inst_env->preg[i] = (unsigned long) read_register (offset + i); + inst_env->preg[i] = + (unsigned long) get_frame_register_unsigned (frame, offset + i); } inst_env->branch_found = 0; inst_env->slot_needed = 0; @@ -1671,12 +2085,14 @@ find_step_target (inst_env_type *inst_env) inst_env->invalid = 0; inst_env->xflag_found = 0; inst_env->disable_interrupt = 0; + inst_env->byte_order = byte_order; /* Look for a step target. */ do { /* Read an instruction from the client. */ - insn = read_memory_unsigned_integer (inst_env->reg[PC_REGNUM], 2); + insn = read_memory_unsigned_integer + (inst_env->reg[gdbarch_pc_regnum (gdbarch)], 2, byte_order); /* If the instruction is not in a delay slot the new content of the PC is [PC] + 2. If the instruction is in a delay slot it is not @@ -1685,12 +2101,13 @@ find_step_target (inst_env_type *inst_env) Just make sure it is a valid instruction. */ if (!inst_env->delay_slot_pc_active) { - inst_env->reg[PC_REGNUM] += 2; + inst_env->reg[gdbarch_pc_regnum (gdbarch)] += 2; } else { inst_env->delay_slot_pc_active = 0; - inst_env->reg[PC_REGNUM] = inst_env->delay_slot_pc; + inst_env->reg[gdbarch_pc_regnum (gdbarch)] + = inst_env->delay_slot_pc; } /* Analyse the present instruction. */ i = find_cris_op (insn, inst_env); @@ -1700,7 +2117,7 @@ find_step_target (inst_env_type *inst_env) } else { - cris_gdb_func (cris_opcodes[i].op, insn, inst_env); + cris_gdb_func (gdbarch, cris_opcodes[i].op, insn, inst_env); } } while (!inst_env->invalid && (inst_env->prefix_found || inst_env->xflag_found @@ -1709,49 +2126,43 @@ find_step_target (inst_env_type *inst_env) } /* There is no hardware single-step support. The function find_step_target - digs through the opcodes in order to find all possible targets. + digs through the opcodes in order to find all possible targets. Either one ordinary target or two targets for branches may be found. */ -static void -cris_software_single_step (enum target_signal ignore, int insert_breakpoints) +static int +cris_software_single_step (struct frame_info *frame) { + struct gdbarch *gdbarch = get_frame_arch (frame); + struct address_space *aspace = get_frame_address_space (frame); inst_env_type inst_env; - - if (insert_breakpoints) + + /* Analyse the present instruction environment and insert + breakpoints. */ + int status = find_step_target (frame, &inst_env); + if (status == -1) { - /* Analyse the present instruction environment and insert - breakpoints. */ - int status = find_step_target (&inst_env); - if (status == -1) - { - /* Could not find a target. FIXME: Should do something. */ - } - else - { - /* Insert at most two breakpoints. One for the next PC content - and possibly another one for a branch, jump, etc. */ - next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM]; - target_insert_breakpoint (next_pc, break_mem[0]); - if (inst_env.branch_found - && (CORE_ADDR) inst_env.branch_break_address != next_pc) - { - branch_target_address = - (CORE_ADDR) inst_env.branch_break_address; - target_insert_breakpoint (branch_target_address, break_mem[1]); - branch_break_inserted = 1; - } - } + /* Could not find a target. Things are likely to go downhill + from here. */ + warning (_("CRIS software single step could not find a step target.")); } else { - /* Remove breakpoints. */ - target_remove_breakpoint (next_pc, break_mem[0]); - if (branch_break_inserted) - { - target_remove_breakpoint (branch_target_address, break_mem[1]); - branch_break_inserted = 0; - } + /* Insert at most two breakpoints. One for the next PC content + and possibly another one for a branch, jump, etc. */ + CORE_ADDR next_pc + = (CORE_ADDR) inst_env.reg[gdbarch_pc_regnum (gdbarch)]; + insert_single_step_breakpoint (gdbarch, aspace, next_pc); + if (inst_env.branch_found + && (CORE_ADDR) inst_env.branch_break_address != next_pc) + { + CORE_ADDR branch_target_address + = (CORE_ADDR) inst_env.branch_break_address; + insert_single_step_breakpoint (gdbarch, + aspace, branch_target_address); + } } + + return 1; } /* Calculates the prefix value for quick offset addressing mode. */ @@ -1812,7 +2223,8 @@ process_autoincrement (int size, unsigned short inst, inst_env_type *inst_env) /* Just a forward declaration. */ static unsigned long get_data_from_address (unsigned short *inst, - CORE_ADDR address); + CORE_ADDR address, + enum bfd_endian byte_order); /* Calculates the prefix value for the general case of offset addressing mode. */ @@ -1838,7 +2250,8 @@ bdap_prefix (unsigned short inst, inst_env_type *inst_env) /* The offset is an indirection of the contents of the operand1 register. */ inst_env->prefix_value += - get_data_from_address (&inst, inst_env->reg[cris_get_operand1 (inst)]); + get_data_from_address (&inst, inst_env->reg[cris_get_operand1 (inst)], + inst_env->byte_order); if (cris_get_mode (inst) == AUTOINC_MODE) { @@ -1904,7 +2317,8 @@ dip_prefix (unsigned short inst, inst_env_type *inst_env) /* The prefix value is one dereference of the contents of the operand1 register. */ address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)]; - inst_env->prefix_value = read_memory_unsigned_integer (address, 4); + inst_env->prefix_value + = read_memory_unsigned_integer (address, 4, inst_env->byte_order); /* Check if the mode is autoincrement. */ if (cris_get_mode (inst) == AUTOINC_MODE) @@ -1971,7 +2385,8 @@ sixteen_bit_offset_branch_op (unsigned short inst, inst_env_type *inst_env) } /* We have a branch, find out the offset for the branch. */ - offset = read_memory_integer (inst_env->reg[REG_PC], 2); + offset = read_memory_integer (inst_env->reg[REG_PC], 2, + inst_env->byte_order); /* The instruction is one word longer than normal, so add one word to the PC. */ @@ -2074,7 +2489,8 @@ asr_op (unsigned short inst, inst_env_type *inst_env) return; } /* Get the number of bits to shift. */ - shift_steps = cris_get_asr_shift_steps (inst_env->reg[cris_get_operand1 (inst)]); + shift_steps + = cris_get_asr_shift_steps (inst_env->reg[cris_get_operand1 (inst)]); value = inst_env->reg[REG_PC]; /* Find out how many bits the operation should apply to. */ @@ -2153,7 +2569,7 @@ asrq_op (unsigned short inst, inst_env_type *inst_env) return; } /* The shift size is given as a 5 bit quick value, i.e. we don't - want the the sign bit of the quick value. */ + want the sign bit of the quick value. */ shift_steps = cris_get_asr_shift_steps (inst); value = inst_env->reg[REG_PC]; if (value & SIGNED_DWORD_MASK) @@ -2477,16 +2893,17 @@ none_reg_mode_jump_op (unsigned short inst, inst_env_type *inst_env) { check_assign (inst, inst_env); - /* Get the new value for the the PC. */ + /* Get the new value for the PC. */ newpc = read_memory_unsigned_integer ((CORE_ADDR) inst_env->prefix_value, - 4); + 4, inst_env->byte_order); } else { /* Get the new value for the PC. */ address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)]; - newpc = read_memory_unsigned_integer (address, 4); + newpc = read_memory_unsigned_integer (address, + 4, inst_env->byte_order); /* Check if we should increment a register. */ if (cris_get_mode (inst) == AUTOINC_MODE) @@ -2505,7 +2922,8 @@ none_reg_mode_jump_op (unsigned short inst, inst_env_type *inst_env) /* Handles moves to special registers (aka P-register) for all modes. */ static void -move_to_preg_op (unsigned short inst, inst_env_type *inst_env) +move_to_preg_op (struct gdbarch *gdbarch, unsigned short inst, + inst_env_type *inst_env) { if (inst_env->prefix_found) { @@ -2536,11 +2954,11 @@ move_to_preg_op (unsigned short inst, inst_env_type *inst_env) } /* The increment depends on the size of the special register. */ - if (cris_register_size (cris_get_operand2 (inst)) == 1) + if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1) { process_autoincrement (INST_BYTE_SIZE, inst, inst_env); } - else if (cris_register_size (cris_get_operand2 (inst)) == 2) + else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2) { process_autoincrement (INST_WORD_SIZE, inst, inst_env); } @@ -2560,7 +2978,8 @@ move_to_preg_op (unsigned short inst, inst_env_type *inst_env) except register. */ static void -none_reg_mode_move_from_preg_op (unsigned short inst, inst_env_type *inst_env) +none_reg_mode_move_from_preg_op (struct gdbarch *gdbarch, unsigned short inst, + inst_env_type *inst_env) { if (inst_env->prefix_found) { @@ -2591,11 +3010,11 @@ none_reg_mode_move_from_preg_op (unsigned short inst, inst_env_type *inst_env) } /* The increment depends on the size of the special register. */ - if (cris_register_size (cris_get_operand2 (inst)) == 1) + if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 1) { process_autoincrement (INST_BYTE_SIZE, inst, inst_env); } - else if (cris_register_size (cris_get_operand2 (inst)) == 2) + else if (cris_register_size (gdbarch, cris_get_operand2 (inst)) == 2) { process_autoincrement (INST_WORD_SIZE, inst, inst_env); } @@ -2659,7 +3078,8 @@ move_mem_to_reg_movem_op (unsigned short inst, inst_env_type *inst_env) if (cris_get_operand2 (inst) >= REG_PC) { inst_env->reg[REG_PC] = - read_memory_unsigned_integer (inst_env->prefix_value, 4); + read_memory_unsigned_integer (inst_env->prefix_value, + 4, inst_env->byte_order); } /* The assign value is the value after the increment. Normally, the assign value is the value before the increment. */ @@ -2683,11 +3103,12 @@ move_mem_to_reg_movem_op (unsigned short inst, inst_env_type *inst_env) } inst_env->reg[REG_PC] = read_memory_unsigned_integer (inst_env->reg[cris_get_operand1 (inst)], - 4); + 4, inst_env->byte_order); } /* The increment is not depending on the size, instead it's depending on the number of registers loaded from memory. */ - if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE)) + if ((cris_get_operand1 (inst) == REG_PC) + && (cris_get_mode (inst) == AUTOINC_MODE)) { /* It's invalid to change the PC in a delay slot. */ if (inst_env->slot_needed) @@ -2713,8 +3134,8 @@ move_reg_to_mem_movem_op (unsigned short inst, inst_env_type *inst_env) { /* The assign value is the value after the increment. Normally, the assign value is the value before the increment. */ - if ((cris_get_operand1 (inst) == REG_PC) && - (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)) + if ((cris_get_operand1 (inst) == REG_PC) + && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)) { /* The prefix handles the problem if we are in a delay slot. */ inst_env->reg[REG_PC] = inst_env->prefix_value; @@ -2725,7 +3146,8 @@ move_reg_to_mem_movem_op (unsigned short inst, inst_env_type *inst_env) { /* The increment is not depending on the size, instead it's depending on the number of registers loaded to memory. */ - if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE)) + if ((cris_get_operand1 (inst) == REG_PC) + && (cris_get_mode (inst) == AUTOINC_MODE)) { /* It's invalid to change the PC in a delay slot. */ if (inst_env->slot_needed) @@ -2828,7 +3250,7 @@ mulu_op (unsigned short inst, inst_env_type *inst_env) inst_env->disable_interrupt = 0; } -/* Calculate the result of the instruction for ADD, SUB, CMP AND, OR and MOVE. +/* Calculate the result of the instruction for ADD, SUB, CMP AND, OR and MOVE. The MOVE instruction is the move from source to register. */ static void @@ -2997,7 +3419,8 @@ reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst, extend instruction, the size field is changed in instruction. */ static unsigned long -get_data_from_address (unsigned short *inst, CORE_ADDR address) +get_data_from_address (unsigned short *inst, CORE_ADDR address, + enum bfd_endian byte_order) { int size = cris_get_size (*inst); unsigned long value; @@ -3011,7 +3434,7 @@ get_data_from_address (unsigned short *inst, CORE_ADDR address) /* Is there a need for checking the size? Size should contain the number of bytes to read. */ size = 1 << size; - value = read_memory_unsigned_integer (address, size); + value = read_memory_unsigned_integer (address, size, byte_order); /* Check if it's an extend, signed or zero instruction. */ if (cris_get_opcode (*inst) < 4) @@ -3037,7 +3460,8 @@ handle_prefix_assign_mode_for_aritm_op (unsigned short inst, operand2 = inst_env->reg[REG_PC]; /* Get the value of the third operand. */ - operand3 = get_data_from_address (&inst, inst_env->prefix_value); + operand3 = get_data_from_address (&inst, inst_env->prefix_value, + inst_env->byte_order); /* Calculate the PC value after the instruction, i.e. where the breakpoint should be. The order of the udw_operands is vital. */ @@ -3066,7 +3490,8 @@ three_operand_add_sub_cmp_and_or_op (unsigned short inst, operand2 = inst_env->reg[cris_get_operand2 (inst)]; /* Get the value of the third operand. */ - operand3 = get_data_from_address (&inst, inst_env->prefix_value); + operand3 = get_data_from_address (&inst, inst_env->prefix_value, + inst_env->byte_order); /* Calculate the PC value after the instruction, i.e. where the breakpoint should be. */ @@ -3118,7 +3543,7 @@ handle_inc_and_index_mode_for_aritm_op (unsigned short inst, unsigned long operand3; int size; - /* The instruction is either an indirect or autoincrement addressing mode. + /* The instruction is either an indirect or autoincrement addressing mode. Check if the destination register is the PC. */ if (cris_get_operand2 (inst) == REG_PC) { @@ -3129,7 +3554,7 @@ handle_inc_and_index_mode_for_aritm_op (unsigned short inst, /* Get the value of the third operand, i.e. the indirect operand. */ operand1 = inst_env->reg[cris_get_operand1 (inst)]; - operand3 = get_data_from_address (&inst, operand1); + operand3 = get_data_from_address (&inst, operand1, inst_env->byte_order); /* Calculate the PC value after the instruction, i.e. where the breakpoint should be. The order of the udw_operands is vital. */ @@ -3137,7 +3562,8 @@ handle_inc_and_index_mode_for_aritm_op (unsigned short inst, } /* If this is an autoincrement addressing mode, check if the increment changes the PC. */ - if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE)) + if ((cris_get_operand1 (inst) == REG_PC) + && (cris_get_mode (inst) == AUTOINC_MODE)) { /* Get the size field. */ size = cris_get_size (inst); @@ -3275,8 +3701,8 @@ quick_mode_and_cmp_move_or_op (unsigned short inst, inst_env_type *inst_env) /* Translate op_type to a function and call it. */ static void -cris_gdb_func (enum cris_op_type op_type, unsigned short inst, - inst_env_type *inst_env) +cris_gdb_func (struct gdbarch *gdbarch, enum cris_op_type op_type, + unsigned short inst, inst_env_type *inst_env) { switch (op_type) { @@ -3345,7 +3771,7 @@ cris_gdb_func (enum cris_op_type op_type, unsigned short inst, break; case cris_move_to_preg_op: - move_to_preg_op (inst, inst_env); + move_to_preg_op (gdbarch, inst, inst_env); break; case cris_muls_op: @@ -3369,7 +3795,7 @@ cris_gdb_func (enum cris_op_type op_type, unsigned short inst, break; case cris_none_reg_mode_move_from_preg_op: - none_reg_mode_move_from_preg_op (inst, inst_env); + none_reg_mode_move_from_preg_op (gdbarch, inst, inst_env); break; case cris_quick_mode_add_sub_op: @@ -3441,7 +3867,7 @@ cris_delayed_get_disassembler (bfd_vma addr, struct disassemble_info *info) disassembler, even when there is no BFD. Does something like "gdb; target remote; disassmeble *0x123" work? */ gdb_assert (exec_bfd != NULL); - print_insn = cris_get_disassembler (exec_bfd); + print_insn = cris_get_disassembler (exec_bfd); gdb_assert (print_insn != NULL); return print_insn (addr, info); } @@ -3450,13 +3876,19 @@ cris_delayed_get_disassembler (bfd_vma addr, struct disassemble_info *info) typedef unsigned long elf_greg_t; /* Same as user_regs_struct struct in . */ -typedef elf_greg_t elf_gregset_t[35]; +#define CRISV10_ELF_NGREG 35 +typedef elf_greg_t elf_gregset_t[CRISV10_ELF_NGREG]; + +#define CRISV32_ELF_NGREG 32 +typedef elf_greg_t crisv32_elf_gregset_t[CRISV32_ELF_NGREG]; /* Unpack an elf_gregset_t into GDB's register cache. */ static void -supply_gregset (elf_gregset_t *gregsetp) +cris_supply_gregset (struct regcache *regcache, elf_gregset_t *gregsetp) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int i; elf_greg_t *regp = *gregsetp; static char zerobuf[4] = {0}; @@ -3465,7 +3897,19 @@ supply_gregset (elf_gregset_t *gregsetp) knows about the actual size of each register so that's no problem. */ for (i = 0; i < NUM_GENREGS + NUM_SPECREGS; i++) { - supply_register (i, (char *)®p[i]); + regcache_raw_supply (regcache, i, (char *)®p[i]); + } + + if (tdep->cris_version == 32) + { + /* Needed to set pseudo-register PC for CRISv32. */ + /* FIXME: If ERP is in a delay slot at this point then the PC will + be wrong. Issue a warning to alert the user. */ + regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), + (char *)®p[ERP_REGNUM]); + + if (*(char *)®p[ERP_REGNUM] & 0x1) + fprintf_unfiltered (gdb_stderr, "Warning: PC in delay slot\n"); } } @@ -3473,7 +3917,8 @@ supply_gregset (elf_gregset_t *gregsetp) regsets, until multi-arch core support is ready. */ static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, +fetch_core_registers (struct regcache *regcache, + char *core_reg_sect, unsigned core_reg_size, int which, CORE_ADDR reg_addr) { elf_gregset_t gregset; @@ -3481,14 +3926,15 @@ fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, switch (which) { case 0: - if (core_reg_size != sizeof (gregset)) + if (core_reg_size != sizeof (elf_gregset_t) + && core_reg_size != sizeof (crisv32_elf_gregset_t)) { - warning ("wrong size gregset struct in core file"); + warning (_("wrong size gregset struct in core file")); } else { memcpy (&gregset, core_reg_sect, sizeof (gregset)); - supply_gregset (&gregset); + cris_supply_gregset (regcache, &gregset); } default: @@ -3508,280 +3954,53 @@ static struct core_fns cris_elf_core_fns = NULL /* next */ }; -/* Fetch (and possibly build) an appropriate link_map_offsets - structure for native GNU/Linux CRIS targets using the struct - offsets defined in link.h (but without actual reference to that - file). - - This makes it possible to access GNU/Linux CRIS shared libraries - from a GDB that was not built on an GNU/Linux CRIS host (for cross - debugging). - - See gdb/solib-svr4.h for an explanation of these fields. */ - -static struct link_map_offsets * -cris_linux_svr4_fetch_link_map_offsets (void) -{ - static struct link_map_offsets lmo; - static struct link_map_offsets *lmp = NULL; - - if (lmp == NULL) - { - lmp = &lmo; - - lmo.r_debug_size = 8; /* The actual size is 20 bytes, but - this is all we need. */ - lmo.r_map_offset = 4; - lmo.r_map_size = 4; - - lmo.link_map_size = 20; - - lmo.l_addr_offset = 0; - lmo.l_addr_size = 4; - - lmo.l_name_offset = 4; - lmo.l_name_size = 4; - - lmo.l_next_offset = 12; - lmo.l_next_size = 4; - - lmo.l_prev_offset = 16; - lmo.l_prev_size = 4; - } - - return lmp; -} - -static void -cris_fpless_backtrace (char *noargs, int from_tty) -{ - /* Points at the instruction after the jsr (except when in innermost frame - where it points at the original pc). */ - CORE_ADDR pc = 0; - - /* Temporary variable, used for parsing from the start of the function that - the pc is in, up to the pc. */ - CORE_ADDR tmp_pc = 0; - CORE_ADDR sp = 0; - - /* Information about current frame. */ - struct symtab_and_line sal; - char* func_name; - - /* Present instruction. */ - unsigned short insn; - - /* Next instruction, lookahead. */ - unsigned short insn_next; - - /* This is to store the offset between sp at start of function and until we - reach push srp (if any). */ - int sp_add_later = 0; - int push_srp_found = 0; - - int val = 0; - - /* Frame counter. */ - int frame = 0; - - /* For the innermost frame, we want to look at srp in case it's a leaf - function (since there's no push srp in that case). */ - int innermost_frame = 1; - - deprecated_read_register_gen (PC_REGNUM, (char *) &pc); - deprecated_read_register_gen (SP_REGNUM, (char *) &sp); - - /* We make an explicit return when we can't find an outer frame. */ - while (1) - { - /* Get file name and line number. */ - sal = find_pc_line (pc, 0); - - /* Get function name. */ - find_pc_partial_function (pc, &func_name, (CORE_ADDR *) NULL, - (CORE_ADDR *) NULL); - - /* Print information about current frame. */ - printf_unfiltered ("#%i 0x%08lx in %s", frame++, pc, func_name); - if (sal.symtab) - { - printf_unfiltered (" at %s:%i", sal.symtab->filename, sal.line); - } - printf_unfiltered ("\n"); - - /* Get the start address of this function. */ - tmp_pc = get_pc_function_start (pc); - - /* Mini parser, only meant to find push sp and sub ...,sp from the start - of the function, up to the pc. */ - while (tmp_pc < pc) - { - insn = read_memory_unsigned_integer (tmp_pc, sizeof (short)); - tmp_pc += sizeof (short); - if (insn == 0xE1FC) - { - /* push 32 bit instruction */ - insn_next = read_memory_unsigned_integer (tmp_pc, - sizeof (short)); - tmp_pc += sizeof (short); - - /* Recognize srp. */ - if (insn_next == 0xBE7E) - { - /* For subsequent (not this one though) push or sub which - affects sp, adjust sp immediately. */ - push_srp_found = 1; - - /* Note: this will break if we ever encounter a - push vr (1 byte) or push ccr (2 bytes). */ - sp_add_later += 4; - } - else - { - /* Some other register was pushed. */ - if (push_srp_found) - { - sp += 4; - } - else - { - sp_add_later += 4; - } - } - } - else if (cris_get_operand2 (insn) == SP_REGNUM - && cris_get_mode (insn) == 0x0000 - && cris_get_opcode (insn) == 0x000A) - { - /* subq ,sp */ - val = cris_get_quick_value (insn); - - if (push_srp_found) - { - sp += val; - } - else - { - sp_add_later += val; - } - - } - else if (cris_get_operand2 (insn) == SP_REGNUM - /* Autoincrement addressing mode. */ - && cris_get_mode (insn) == 0x0003 - /* Opcode. */ - && ((insn) & 0x03E0) >> 5 == 0x0004) - { - /* subu ,sp */ - val = get_data_from_address (&insn, tmp_pc); - - if (push_srp_found) - { - sp += val; - } - else - { - sp_add_later += val; - } - } - else if (cris_get_operand2 (insn) == SP_REGNUM - && ((insn & 0x0F00) >> 8) == 0x0001 - && (cris_get_signed_offset (insn) < 0)) - { - /* Immediate byte offset addressing prefix word with sp as base - register. Used for CRIS v8 i.e. ETRAX 100 and newer if - is between 64 and 128. - movem r,[sp=sp-] */ - val = -cris_get_signed_offset (insn); - insn_next = read_memory_unsigned_integer (tmp_pc, - sizeof (short)); - tmp_pc += sizeof (short); - - if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE - && cris_get_opcode (insn_next) == 0x000F - && cris_get_size (insn_next) == 0x0003 - && cris_get_operand1 (insn_next) == SP_REGNUM) - { - if (push_srp_found) - { - sp += val; - } - else - { - sp_add_later += val; - } - } - } - } - - if (push_srp_found) - { - /* Reset flag. */ - push_srp_found = 0; - - /* sp should now point at where srp is stored on the stack. Update - the pc to the srp. */ - pc = read_memory_unsigned_integer (sp, 4); - } - else if (innermost_frame) - { - /* We couldn't find a push srp in the prologue, so this must be - a leaf function, and thus we use the srp register directly. - This should happen at most once, for the innermost function. */ - deprecated_read_register_gen (SRP_REGNUM, (char *) &pc); - } - else - { - /* Couldn't find an outer frame. */ - return; - } - - /* Reset flag. (In case the innermost frame wasn't a leaf, we don't - want to look at the srp register later either). */ - innermost_frame = 0; - - /* Now, add the offset for everything up to, and including push srp, - that was held back during the prologue parsing. */ - sp += sp_add_later; - sp_add_later = 0; - } -} - extern initialize_file_ftype _initialize_cris_tdep; /* -Wmissing-prototypes */ void _initialize_cris_tdep (void) { + static struct cmd_list_element *cris_set_cmdlist; + static struct cmd_list_element *cris_show_cmdlist; + struct cmd_list_element *c; gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep); /* CRIS-specific user-commands. */ - c = add_set_cmd ("cris-version", class_support, var_integer, - (char *) &usr_cmd_cris_version, - "Set the current CRIS version.", &setlist); - set_cmd_sfunc (c, cris_version_update); - add_show_from_set (c, &showlist); - - c = add_set_enum_cmd ("cris-mode", class_support, cris_mode_enums, - &usr_cmd_cris_mode, - "Set the current CRIS mode.", &setlist); - set_cmd_sfunc (c, cris_mode_update); - add_show_from_set (c, &showlist); - - c = add_set_enum_cmd ("cris-abi", class_support, cris_abi_enums, - &usr_cmd_cris_abi, - "Set the current CRIS ABI version.", &setlist); - set_cmd_sfunc (c, cris_abi_update); - add_show_from_set (c, &showlist); - - c = add_cmd ("cris-fpless-backtrace", class_support, cris_fpless_backtrace, - "Display call chain using the subroutine return pointer.\n" - "Note that this displays the address after the jump to the " - "subroutine.", &cmdlist); - - add_core_fns (&cris_elf_core_fns); + add_setshow_uinteger_cmd ("cris-version", class_support, + &usr_cmd_cris_version, + _("Set the current CRIS version."), + _("Show the current CRIS version."), + _("\ +Set to 10 for CRISv10 or 32 for CRISv32 if autodetection fails.\n\ +Defaults to 10. "), + set_cris_version, + NULL, /* FIXME: i18n: Current CRIS version + is %s. */ + &setlist, &showlist); + + add_setshow_enum_cmd ("cris-mode", class_support, + cris_modes, &usr_cmd_cris_mode, + _("Set the current CRIS mode."), + _("Show the current CRIS mode."), + _("\ +Set to CRIS_MODE_GURU when debugging in guru mode.\n\ +Makes GDB use the NRP register instead of the ERP register in certain cases."), + set_cris_mode, + NULL, /* FIXME: i18n: Current CRIS version is %s. */ + &setlist, &showlist); + add_setshow_boolean_cmd ("cris-dwarf2-cfi", class_support, + &usr_cmd_cris_dwarf2_cfi, + _("Set the usage of Dwarf-2 CFI for CRIS."), + _("Show the usage of Dwarf-2 CFI for CRIS."), + _("Set this to \"off\" if using gcc-cris < R59."), + set_cris_dwarf2_cfi, + NULL, /* FIXME: i18n: Usage of Dwarf-2 CFI + for CRIS is %d. */ + &setlist, &showlist); + + deprecated_add_core_fns (&cris_elf_core_fns); } /* Prints out all target specific values. */ @@ -3789,134 +4008,57 @@ _initialize_cris_tdep (void) static void cris_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep != NULL) { fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_version = %i\n", tdep->cris_version); fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_mode = %s\n", tdep->cris_mode); - fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_abi = %s\n", - tdep->cris_abi); - + fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_dwarf2_cfi = %i\n", + tdep->cris_dwarf2_cfi); } } static void -cris_version_update (char *ignore_args, int from_tty, - struct cmd_list_element *c) +set_cris_version (char *ignore_args, int from_tty, + struct cmd_list_element *c) { struct gdbarch_info info; - /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones - the set command passed as a parameter. The clone operation will - include (BUG?) any ``set'' command callback, if present. - Commands like ``info set'' call all the ``show'' command - callbacks. Unfortunately, for ``show'' commands cloned from - ``set'', this includes callbacks belonging to ``set'' commands. - Making this worse, this only occures if add_show_from_set() is - called after add_cmd_sfunc() (BUG?). */ - - /* From here on, trust the user's CRIS version setting. */ - if (cmd_type (c) == set_cmd) - { - usr_cmd_cris_version_valid = 1; + usr_cmd_cris_version_valid = 1; - /* Update the current architecture, if needed. */ - gdbarch_info_init (&info); - if (!gdbarch_update_p (info)) - internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture."); - } + /* Update the current architecture, if needed. */ + gdbarch_info_init (&info); + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, + _("cris_gdbarch_update: failed to update architecture.")); } static void -cris_mode_update (char *ignore_args, int from_tty, - struct cmd_list_element *c) +set_cris_mode (char *ignore_args, int from_tty, + struct cmd_list_element *c) { struct gdbarch_info info; - - /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones - the set command passed as a parameter. The clone operation will - include (BUG?) any ``set'' command callback, if present. - Commands like ``info set'' call all the ``show'' command - callbacks. Unfortunately, for ``show'' commands cloned from - ``set'', this includes callbacks belonging to ``set'' commands. - Making this worse, this only occures if add_show_from_set() is - called after add_cmd_sfunc() (BUG?). */ - - /* From here on, trust the user's CRIS mode setting. */ - if (cmd_type (c) == set_cmd) - { - usr_cmd_cris_mode_valid = 1; - - /* Update the current architecture, if needed. */ - gdbarch_info_init (&info); - if (!gdbarch_update_p (info)) - internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture."); - } + + /* Update the current architecture, if needed. */ + gdbarch_info_init (&info); + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, + "cris_gdbarch_update: failed to update architecture."); } static void -cris_abi_update (char *ignore_args, int from_tty, - struct cmd_list_element *c) +set_cris_dwarf2_cfi (char *ignore_args, int from_tty, + struct cmd_list_element *c) { struct gdbarch_info info; - - /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones - the set command passed as a parameter. The clone operation will - include (BUG?) any ``set'' command callback, if present. - Commands like ``info set'' call all the ``show'' command - callbacks. Unfortunately, for ``show'' commands cloned from - ``set'', this includes callbacks belonging to ``set'' commands. - Making this worse, this only occures if add_show_from_set() is - called after add_cmd_sfunc() (BUG?). */ - - /* From here on, trust the user's CRIS ABI setting. */ - if (cmd_type (c) == set_cmd) - { - usr_cmd_cris_abi_valid = 1; - - /* Update the current architecture, if needed. */ - gdbarch_info_init (&info); - if (!gdbarch_update_p (info)) - internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture."); - } -} - -/* Copied from pa64solib.c, with a couple of minor changes. */ - -static CORE_ADDR -bfd_lookup_symbol (bfd *abfd, const char *symname) -{ - unsigned int storage_needed; - asymbol *sym; - asymbol **symbol_table; - unsigned int number_of_symbols; - unsigned int i; - struct cleanup *back_to; - CORE_ADDR symaddr = 0; - storage_needed = bfd_get_symtab_upper_bound (abfd); - - if (storage_needed > 0) - { - symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (free, symbol_table); - number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); - - for (i = 0; i < number_of_symbols; i++) - { - sym = *symbol_table++; - if (!strcmp (sym->name, symname)) - { - /* Bfd symbols are section relative. */ - symaddr = sym->value + sym->section->vma; - break; - } - } - do_cleanups (back_to); - } - return (symaddr); + /* Update the current architecture, if needed. */ + gdbarch_info_init (&info); + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, + _("cris_gdbarch_update: failed to update architecture.")); } static struct gdbarch * @@ -3925,94 +4067,36 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) struct gdbarch *gdbarch; struct gdbarch_tdep *tdep; int cris_version; - const char *cris_mode; - const char *cris_abi; - CORE_ADDR cris_abi_sym = 0; - int register_bytes; if (usr_cmd_cris_version_valid) { /* Trust the user's CRIS version setting. */ cris_version = usr_cmd_cris_version; } - else - { - /* Assume it's CRIS version 10. */ - cris_version = 10; - } - - if (usr_cmd_cris_mode_valid) - { - /* Trust the user's CRIS mode setting. */ - cris_mode = usr_cmd_cris_mode; - } - else if (cris_version == 10) - { - /* Assume CRIS version 10 is in user mode. */ - cris_mode = CRIS_MODE_USER; - } - else - { - /* Strictly speaking, older CRIS version don't have a supervisor mode, - but we regard its only mode as supervisor mode. */ - cris_mode = CRIS_MODE_SUPERVISOR; - } - - if (usr_cmd_cris_abi_valid) - { - /* Trust the user's ABI setting. */ - cris_abi = usr_cmd_cris_abi; - } - else if (info.abfd) - { - if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) - { - /* An elf target uses the new ABI. */ - cris_abi = CRIS_ABI_V2; - } - else if (bfd_get_flavour (info.abfd) == bfd_target_aout_flavour) - { - /* An a.out target may use either ABI. Look for hints in the - symbol table. */ - cris_abi_sym = bfd_lookup_symbol (info.abfd, CRIS_ABI_SYMBOL); - cris_abi = cris_abi_sym ? CRIS_ABI_V2 : CRIS_ABI_ORIGINAL; - } - else - { - /* Unknown bfd flavour. Assume it's the new ABI. */ - cris_abi = CRIS_ABI_V2; - } - } - else if (arches != NULL) + else if (info.abfd && bfd_get_mach (info.abfd) == bfd_mach_cris_v32) { - /* No bfd available. Stick with the ABI from the most recently - selected architecture of this same family (the head of arches - always points to this). (This is to avoid changing the ABI - when the user updates the architecture with the 'set - cris-version' command.) */ - cris_abi = gdbarch_tdep (arches->gdbarch)->cris_abi; + cris_version = 32; } else { - /* No bfd, and no previously selected architecture available. - Assume it's the new ABI. */ - cris_abi = CRIS_ABI_V2; + /* Assume it's CRIS version 10. */ + cris_version = 10; } /* Make the current settings visible to the user. */ usr_cmd_cris_version = cris_version; - usr_cmd_cris_mode = cris_mode; - usr_cmd_cris_abi = cris_abi; - /* Find a candidate among the list of pre-declared architectures. Both - CRIS version and ABI must match. */ + /* Find a candidate among the list of pre-declared architectures. */ for (arches = gdbarch_list_lookup_by_info (arches, &info); arches != NULL; arches = gdbarch_list_lookup_by_info (arches->next, &info)) { - if ((gdbarch_tdep (arches->gdbarch)->cris_version == cris_version) - && (gdbarch_tdep (arches->gdbarch)->cris_mode == cris_mode) - && (gdbarch_tdep (arches->gdbarch)->cris_abi == cris_abi)) + if ((gdbarch_tdep (arches->gdbarch)->cris_version + == usr_cmd_cris_version) + && (gdbarch_tdep (arches->gdbarch)->cris_mode + == usr_cmd_cris_mode) + && (gdbarch_tdep (arches->gdbarch)->cris_dwarf2_cfi + == usr_cmd_cris_dwarf2_cfi)) return arches->gdbarch; } @@ -4020,13 +4104,9 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep)); gdbarch = gdbarch_alloc (&info, tdep); - /* NOTE: cagney/2002-12-06: This can be deleted when this arch is - ready to unwind the PC first (see frame.c:get_prev_frame()). */ - set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default); - - tdep->cris_version = cris_version; - tdep->cris_mode = cris_mode; - tdep->cris_abi = cris_abi; + tdep->cris_version = usr_cmd_cris_version; + tdep->cris_mode = usr_cmd_cris_mode; + tdep->cris_dwarf2_cfi = usr_cmd_cris_dwarf2_cfi; /* INIT shall ensure that the INFO.BYTE_ORDER is non-zero. */ switch (info.byte_order) @@ -4036,67 +4116,31 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) break; case BFD_ENDIAN_BIG: - internal_error (__FILE__, __LINE__, "cris_gdbarch_init: big endian byte order in info"); + internal_error (__FILE__, __LINE__, + _("cris_gdbarch_init: big endian byte order in info")); break; default: - internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unknown byte order in info"); + internal_error (__FILE__, __LINE__, + _("cris_gdbarch_init: unknown byte order in info")); } - /* Initialize the ABI dependent things. */ - if (tdep->cris_abi == CRIS_ABI_ORIGINAL) - { - set_gdbarch_double_bit (gdbarch, 32); - set_gdbarch_deprecated_push_arguments (gdbarch, cris_abi_original_push_arguments); - set_gdbarch_deprecated_store_return_value (gdbarch, - cris_abi_original_store_return_value); - set_gdbarch_deprecated_extract_return_value - (gdbarch, cris_abi_original_extract_return_value); - set_gdbarch_deprecated_reg_struct_has_addr - (gdbarch, cris_abi_original_reg_struct_has_addr); - } - else if (tdep->cris_abi == CRIS_ABI_V2) - { - set_gdbarch_double_bit (gdbarch, 64); - set_gdbarch_deprecated_push_arguments (gdbarch, cris_abi_v2_push_arguments); - set_gdbarch_deprecated_store_return_value (gdbarch, cris_abi_v2_store_return_value); - set_gdbarch_deprecated_extract_return_value - (gdbarch, cris_abi_v2_extract_return_value); - set_gdbarch_deprecated_reg_struct_has_addr - (gdbarch, cris_abi_v2_reg_struct_has_addr); - } - else - internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unknown CRIS ABI"); + set_gdbarch_return_value (gdbarch, cris_return_value); - /* The default definition of a long double is 2 * TARGET_DOUBLE_BIT, - which means we have to set this explicitly. */ - set_gdbarch_long_double_bit (gdbarch, 64); - - /* There are 32 registers (some of which may not be implemented). */ - set_gdbarch_num_regs (gdbarch, 32); set_gdbarch_sp_regnum (gdbarch, 14); - set_gdbarch_deprecated_fp_regnum (gdbarch, 8); - set_gdbarch_pc_regnum (gdbarch, 15); - - set_gdbarch_register_name (gdbarch, cris_register_name); /* Length of ordinary registers used in push_word and a few other - places. DEPRECATED_REGISTER_RAW_SIZE is the real way to know how - big a register is. */ - set_gdbarch_deprecated_register_size (gdbarch, 4); - - /* NEW */ - set_gdbarch_register_bytes_ok (gdbarch, cris_register_bytes_ok); - set_gdbarch_software_single_step (gdbarch, cris_software_single_step); - - - set_gdbarch_cannot_store_register (gdbarch, cris_cannot_store_register); - set_gdbarch_cannot_fetch_register (gdbarch, cris_cannot_fetch_register); + places. register_size() is the real way to know how big a + register is. */ + set_gdbarch_double_bit (gdbarch, 64); + /* The default definition of a long double is 2 * gdbarch_double_bit, + which means we have to set this explicitly. */ + set_gdbarch_long_double_bit (gdbarch, 64); /* The total amount of space needed to store (in an array called registers) GDB's copy of the machine's register state. Note: We can not use - cris_register_size at this point, since it relies on current_gdbarch + cris_register_size at this point, since it relies on gdbarch being set. */ switch (tdep->cris_version) { @@ -4104,69 +4148,60 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case 1: case 2: case 3: - /* Support for these may be added later. */ - internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unsupported CRIS version"); - break; - case 8: case 9: - /* CRIS v8 and v9, a.k.a. ETRAX 100. General registers R0 - R15 - (32 bits), special registers P0 - P1 (8 bits), P4 - P5 (16 bits), - and P8 - P14 (32 bits). */ - register_bytes = (16 * 4) + (2 * 1) + (2 * 2) + (7 * 4); + /* Old versions; not supported. */ + internal_error (__FILE__, __LINE__, + _("cris_gdbarch_init: unsupported CRIS version")); break; case 10: case 11: /* CRIS v10 and v11, a.k.a. ETRAX 100LX. In addition to ETRAX 100, P7 (32 bits), and P15 (32 bits) have been implemented. */ - register_bytes = (16 * 4) + (2 * 1) + (2 * 2) + (9 * 4); + set_gdbarch_pc_regnum (gdbarch, 15); + set_gdbarch_register_type (gdbarch, cris_register_type); + /* There are 32 registers (some of which may not be implemented). */ + set_gdbarch_num_regs (gdbarch, 32); + set_gdbarch_register_name (gdbarch, cris_register_name); + set_gdbarch_cannot_store_register (gdbarch, cris_cannot_store_register); + set_gdbarch_cannot_fetch_register (gdbarch, cris_cannot_fetch_register); + + set_gdbarch_software_single_step (gdbarch, cris_software_single_step); break; - default: - internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unknown CRIS version"); - } + case 32: + /* CRIS v32. General registers R0 - R15 (32 bits), special registers + P0 - P15 (32 bits) except P0, P1, P3 (8 bits) and P4 (16 bits) + and pseudo-register PC (32 bits). */ + set_gdbarch_pc_regnum (gdbarch, 32); + set_gdbarch_register_type (gdbarch, crisv32_register_type); + /* 32 registers + pseudo-register PC + 16 support registers. */ + set_gdbarch_num_regs (gdbarch, 32 + 1 + 16); + set_gdbarch_register_name (gdbarch, crisv32_register_name); - set_gdbarch_deprecated_register_bytes (gdbarch, register_bytes); + set_gdbarch_cannot_store_register + (gdbarch, crisv32_cannot_store_register); + set_gdbarch_cannot_fetch_register + (gdbarch, crisv32_cannot_fetch_register); - /* Returns the register offset for the first byte of register regno's space - in the saved register state. */ - set_gdbarch_deprecated_register_byte (gdbarch, cris_register_offset); - - /* The length of the registers in the actual machine representation. */ - set_gdbarch_deprecated_register_raw_size (gdbarch, cris_register_size); - - /* The largest value DEPRECATED_REGISTER_RAW_SIZE can have. */ - set_gdbarch_deprecated_max_register_raw_size (gdbarch, 32); - - /* The length of the registers in the program's representation. */ - set_gdbarch_deprecated_register_virtual_size (gdbarch, cris_register_size); - - /* The largest value DEPRECATED_REGISTER_VIRTUAL_SIZE can have. */ - set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 32); + set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); - set_gdbarch_deprecated_register_virtual_type (gdbarch, cris_register_virtual_type); - - /* Use generic dummy frames. */ - - /* Read all about dummy frames in blockframe.c. */ - set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_at_entry_point); - - /* Defined to 1 to indicate that the target supports inferior function - calls. */ - set_gdbarch_deprecated_call_dummy_words (gdbarch, 0); - set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0); - - set_gdbarch_deprecated_get_saved_register (gdbarch, deprecated_generic_get_saved_register); - - set_gdbarch_deprecated_push_return_address (gdbarch, cris_push_return_address); - set_gdbarch_deprecated_pop_frame (gdbarch, cris_pop_frame); + set_gdbarch_single_step_through_delay + (gdbarch, crisv32_single_step_through_delay); - set_gdbarch_deprecated_store_struct_return (gdbarch, cris_store_struct_return); - set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention); + break; + + default: + internal_error (__FILE__, __LINE__, + _("cris_gdbarch_init: unknown CRIS version")); + } - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, cris_frame_init_saved_regs); - set_gdbarch_deprecated_init_extra_frame_info (gdbarch, cris_init_extra_frame_info); + /* Dummy frame functions (shared between CRISv10 and CRISv32 since they + have the same ABI). */ + set_gdbarch_push_dummy_code (gdbarch, cris_push_dummy_code); + set_gdbarch_push_dummy_call (gdbarch, cris_push_dummy_call); + set_gdbarch_frame_align (gdbarch, cris_frame_align); set_gdbarch_skip_prologue (gdbarch, cris_skip_prologue); /* The stack grows downward. */ @@ -4174,22 +4209,28 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_breakpoint_from_pc (gdbarch, cris_breakpoint_from_pc); - set_gdbarch_frameless_function_invocation - (gdbarch, cris_frameless_function_invocation); - set_gdbarch_deprecated_frame_chain (gdbarch, cris_frame_chain); + set_gdbarch_unwind_pc (gdbarch, cris_unwind_pc); + set_gdbarch_unwind_sp (gdbarch, cris_unwind_sp); + set_gdbarch_dummy_id (gdbarch, cris_dummy_id); - set_gdbarch_deprecated_frame_saved_pc (gdbarch, cris_frame_saved_pc); - set_gdbarch_deprecated_saved_pc_after_call (gdbarch, cris_saved_pc_after_call); + if (tdep->cris_dwarf2_cfi == 1) + { + /* Hook in the Dwarf-2 frame sniffer. */ + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, cris_dwarf2_reg_to_regnum); + dwarf2_frame_set_init_reg (gdbarch, cris_dwarf2_frame_init_reg); + dwarf2_append_unwinders (gdbarch); + } - /* Helpful for backtracing and returning in a call dummy. */ - set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); + if (tdep->cris_mode != cris_mode_guru) + { + frame_unwind_append_unwinder (gdbarch, &cris_sigtramp_frame_unwind); + } - /* Should be using push_dummy_call. */ - set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp); + frame_unwind_append_unwinder (gdbarch, &cris_frame_unwind); + frame_base_set_default (gdbarch, &cris_frame_base); - /* Use target_specific function to define link map offsets. */ - set_solib_svr4_fetch_link_map_offsets - (gdbarch, cris_linux_svr4_fetch_link_map_offsets); + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_ilp32_fetch_link_map_offsets); /* FIXME: cagney/2003-08-27: It should be possible to select a CRIS disassembler, even when there is no BFD. Does something like