X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Falpha-tdep.c;h=107b46f22b1064ebd829813c7775564800865b58;hb=c055b1010f3ff41e33e30b195f809e05d68af989;hp=da803fb0a52f888d3a1c3e3119d0215142986db4;hpb=359a926234e5b72f99e7e60d46b4886b5c9af0b2;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index da803fb0a5..107b46f22b 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -1,13 +1,13 @@ /* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger. - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. 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 + 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, @@ -16,9 +16,7 @@ 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "doublest.h" @@ -42,6 +40,7 @@ #include "osabi.h" #include "block.h" #include "infcall.h" +#include "trad-frame.h" #include "elf-bfd.h" @@ -56,7 +55,7 @@ compatibility with existing remote alpha targets. */ static const char * -alpha_register_name (int regno) +alpha_register_name (struct gdbarch *gdbarch, int regno) { static const char * const register_names[] = { @@ -73,23 +72,23 @@ alpha_register_name (int regno) if (regno < 0) return NULL; - if (regno >= (sizeof(register_names) / sizeof(*register_names))) + if (regno >= ARRAY_SIZE(register_names)) return NULL; return register_names[regno]; } static int -alpha_cannot_fetch_register (int regno) +alpha_cannot_fetch_register (struct gdbarch *gdbarch, int regno) { return (regno == ALPHA_ZERO_REGNUM - || strlen (alpha_register_name (regno)) == 0); + || strlen (alpha_register_name (gdbarch, regno)) == 0); } static int -alpha_cannot_store_register (int regno) +alpha_cannot_store_register (struct gdbarch *gdbarch, int regno) { return (regno == ALPHA_ZERO_REGNUM - || strlen (alpha_register_name (regno)) == 0); + || strlen (alpha_register_name (gdbarch, regno)) == 0); } static struct type * @@ -103,7 +102,7 @@ alpha_register_type (struct gdbarch *gdbarch, int regno) /* Don't need to worry about little vs big endian until some jerk tries to port to alpha-unicosmk. */ if (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31) - return builtin_type_ieee_double_little; + return builtin_type_ieee_double; return builtin_type_int64; } @@ -116,7 +115,8 @@ alpha_register_reggroup_p (struct gdbarch *gdbarch, int regnum, { /* Filter out any registers eliminated, but whose regnum is reserved for backward compatibility, e.g. the vfp. */ - if (REGISTER_NAME (regnum) == NULL || *REGISTER_NAME (regnum) == '\0') + if (gdbarch_register_name (gdbarch, regnum) == NULL + || *gdbarch_register_name (gdbarch, regnum) == '\0') return 0; if (group == all_reggroup) @@ -199,25 +199,24 @@ alpha_sts (void *out, const void *in) registers is different. */ static int -alpha_convert_register_p (int regno, struct type *type) +alpha_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type) { - return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31); + return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31 + && TYPE_LENGTH (type) != 8); } static void alpha_register_to_value (struct frame_info *frame, int regnum, struct type *valtype, gdb_byte *out) { - char in[MAX_REGISTER_SIZE]; + gdb_byte in[MAX_REGISTER_SIZE]; + frame_register_read (frame, regnum, in); switch (TYPE_LENGTH (valtype)) { case 4: alpha_sts (out, in); break; - case 8: - memcpy (out, in, 8); - break; default: error (_("Cannot retrieve value from floating point register")); } @@ -227,15 +226,13 @@ static void alpha_value_to_register (struct frame_info *frame, int regnum, struct type *valtype, const gdb_byte *in) { - char out[MAX_REGISTER_SIZE]; + gdb_byte out[MAX_REGISTER_SIZE]; + switch (TYPE_LENGTH (valtype)) { case 4: alpha_lds (out, in); break; - case 8: - memcpy (out, in, 8); - break; default: error (_("Cannot store value in floating point register")); } @@ -265,14 +262,14 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int accumulate_size = struct_return ? 8 : 0; struct alpha_arg { - char *contents; + gdb_byte *contents; int len; int offset; }; struct alpha_arg *alpha_args = (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg)); struct alpha_arg *m_arg; - char arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS]; + gdb_byte arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS]; int required_arg_regs; CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -317,7 +314,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function, if (accumulate_size < sizeof (arg_reg_buffer) && TYPE_LENGTH (arg_type) == 4) { - arg_type = builtin_type_ieee_double_little; + arg_type = builtin_type_ieee_double; arg = value_cast (arg_type, arg); } /* Tru64 5.1 has a 128-bit long double, and passes this by @@ -385,7 +382,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* `Push' arguments on the stack. */ for (i = nargs; m_arg--, --i >= 0;) { - char *contents = m_arg->contents; + gdb_byte *contents = m_arg->contents; int offset = m_arg->offset; int len = m_arg->len; @@ -436,7 +433,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache, gdb_byte *valbuf) { int length = TYPE_LENGTH (valtype); - char raw_buffer[ALPHA_REGISTER_SIZE]; + gdb_byte raw_buffer[ALPHA_REGISTER_SIZE]; ULONGEST l; switch (TYPE_CODE (valtype)) @@ -473,8 +470,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache, case 16: regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf); - regcache_cooked_read (regcache, ALPHA_FP0_REGNUM+1, - (char *)valbuf + 8); + regcache_cooked_read (regcache, ALPHA_FP0_REGNUM + 1, valbuf + 8); break; case 32: @@ -503,7 +499,7 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache, const gdb_byte *valbuf) { int length = TYPE_LENGTH (valtype); - char raw_buffer[ALPHA_REGISTER_SIZE]; + gdb_byte raw_buffer[ALPHA_REGISTER_SIZE]; ULONGEST l; switch (TYPE_CODE (valtype)) @@ -541,8 +537,7 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache, case 16: regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf); - regcache_cooked_write (regcache, ALPHA_FP0_REGNUM+1, - (const char *)valbuf + 8); + regcache_cooked_write (regcache, ALPHA_FP0_REGNUM + 1, valbuf + 8); break; case 32: @@ -569,9 +564,9 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache, } static enum return_value_convention -alpha_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, gdb_byte *readbuf, - const gdb_byte *writebuf) +alpha_return_value (struct gdbarch *gdbarch, struct type *func_type, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) { enum type_code code = TYPE_CODE (type); @@ -604,14 +599,13 @@ alpha_return_in_memory_always (struct type *type) return 1; } -static const unsigned char * -alpha_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +static const gdb_byte * +alpha_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) { - static const unsigned char alpha_breakpoint[] = - { 0x80, 0, 0, 0 }; /* call_pal bpt */ + static const gdb_byte break_insn[] = { 0x80, 0, 0, 0 }; /* call_pal bpt */ - *lenptr = sizeof(alpha_breakpoint); - return (alpha_breakpoint); + *len = sizeof(break_insn); + return break_insn; } @@ -641,13 +635,13 @@ alpha_after_prologue (CORE_ADDR pc) unsigned int alpha_read_insn (CORE_ADDR pc) { - char buf[4]; + gdb_byte buf[ALPHA_INSN_SIZE]; int status; - status = read_memory_nobpt (pc, buf, 4); + status = target_read_memory (pc, buf, sizeof (buf)); if (status) memory_error (status, pc); - return extract_unsigned_integer (buf, 4); + return extract_unsigned_integer (buf, sizeof (buf)); } /* To skip prologues, I use this predicate. Returns either PC itself @@ -658,12 +652,12 @@ alpha_read_insn (CORE_ADDR pc) anything which might clobber the registers which are being saved. */ static CORE_ADDR -alpha_skip_prologue (CORE_ADDR pc) +alpha_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { unsigned long inst; int offset; CORE_ADDR post_prologue_pc; - char buf[4]; + gdb_byte buf[ALPHA_INSN_SIZE]; /* Silently return the unaltered pc upon memory errors. This could happen on OSF/1 if decode_line_1 tries to skip the @@ -672,7 +666,7 @@ alpha_skip_prologue (CORE_ADDR pc) Reading target memory is slow over serial lines, so we perform this check only if the target has shared libraries (which all Alpha targets do). */ - if (target_read_memory (pc, buf, 4)) + if (target_read_memory (pc, buf, sizeof (buf))) return pc; /* See if we can determine the end of the prologue via the symbol table. @@ -689,7 +683,7 @@ alpha_skip_prologue (CORE_ADDR pc) /* Skip the typical prologue instructions. These are the stack adjustment instruction and the instructions that save registers on the stack or in the gcc frame. */ - for (offset = 0; offset < 100; offset += 4) + for (offset = 0; offset < 100; offset += ALPHA_INSN_SIZE) { inst = alpha_read_insn (pc + offset); @@ -724,13 +718,13 @@ alpha_skip_prologue (CORE_ADDR pc) into the "pc". This routine returns true on success. */ static int -alpha_get_longjmp_target (CORE_ADDR *pc) +alpha_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); CORE_ADDR jb_addr; - char raw_buffer[ALPHA_REGISTER_SIZE]; + gdb_byte raw_buffer[ALPHA_REGISTER_SIZE]; - jb_addr = read_register (ALPHA_A0_REGNUM); + jb_addr = get_frame_register_unsigned (frame, ALPHA_A0_REGNUM); if (target_read_memory (jb_addr + (tdep->jb_pc * tdep->jb_elt_size), raw_buffer, tdep->jb_elt_size)) @@ -765,7 +759,7 @@ alpha_sigtramp_frame_unwind_cache (struct frame_info *next_frame, info = FRAME_OBSTACK_ZALLOC (struct alpha_sigtramp_unwind_cache); *this_prologue_cache = info; - tdep = gdbarch_tdep (current_gdbarch); + tdep = gdbarch_tdep (get_frame_arch (next_frame)); info->sigcontext_addr = tdep->sigcontext_addr (next_frame); return info; @@ -775,9 +769,10 @@ alpha_sigtramp_frame_unwind_cache (struct frame_info *next_frame, all arithmetic, it doesn't seem worthwhile to cache it. */ static CORE_ADDR -alpha_sigtramp_register_address (CORE_ADDR sigcontext_addr, int regnum) +alpha_sigtramp_register_address (struct gdbarch *gdbarch, + CORE_ADDR sigcontext_addr, int regnum) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (regnum >= 0 && regnum < 32) return sigcontext_addr + tdep->sc_regs_offset + regnum * 8; @@ -797,9 +792,10 @@ alpha_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_prologue_cache, struct frame_id *this_id) { + struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct alpha_sigtramp_unwind_cache *info = alpha_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache); - struct gdbarch_tdep *tdep; CORE_ADDR stack_addr, code_addr; /* If the OSABI couldn't locate the sigcontext, give up. */ @@ -809,7 +805,6 @@ alpha_sigtramp_frame_this_id (struct frame_info *next_frame, /* If we have dynamic signal trampolines, find their start. If we do not, then we must assume there is a symbol record that can provide the start address. */ - tdep = gdbarch_tdep (current_gdbarch); if (tdep->dynamic_sigtramp_offset) { int offset; @@ -821,10 +816,10 @@ alpha_sigtramp_frame_this_id (struct frame_info *next_frame, code_addr = 0; } else - code_addr = frame_func_unwind (next_frame); + code_addr = frame_func_unwind (next_frame, SIGTRAMP_FRAME); /* The stack address is trivially read from the sigcontext. */ - stack_addr = alpha_sigtramp_register_address (info->sigcontext_addr, + stack_addr = alpha_sigtramp_register_address (gdbarch, info->sigcontext_addr, ALPHA_SP_REGNUM); stack_addr = get_frame_memory_unsigned (next_frame, stack_addr, ALPHA_REGISTER_SIZE); @@ -848,7 +843,8 @@ alpha_sigtramp_frame_prev_register (struct frame_info *next_frame, if (info->sigcontext_addr != 0) { /* All integer and fp registers are stored in memory. */ - addr = alpha_sigtramp_register_address (info->sigcontext_addr, regnum); + addr = alpha_sigtramp_register_address (get_frame_arch (next_frame), + info->sigcontext_addr, regnum); if (addr != 0) { *optimizedp = 0; @@ -865,8 +861,12 @@ alpha_sigtramp_frame_prev_register (struct frame_info *next_frame, current description of it in alpha_sigtramp_frame_unwind_cache doesn't include it. Too bad. Fall back on whatever's in the outer frame. */ - frame_register (next_frame, regnum, optimizedp, lvalp, addrp, - realnump, bufferp); + *optimizedp = 0; + *lvalp = lval_register; + *addrp = 0; + *realnump = regnum; + if (bufferp) + frame_unwind_register (next_frame, *realnump, bufferp); } static const struct frame_unwind alpha_sigtramp_frame_unwind = { @@ -878,6 +878,7 @@ static const struct frame_unwind alpha_sigtramp_frame_unwind = { static const struct frame_unwind * alpha_sigtramp_frame_sniffer (struct frame_info *next_frame) { + struct gdbarch *gdbarch = get_frame_arch (next_frame); CORE_ADDR pc = frame_pc_unwind (next_frame); char *name; @@ -887,29 +888,19 @@ alpha_sigtramp_frame_sniffer (struct frame_info *next_frame) /* We shouldn't even bother to try if the OSABI didn't register a sigcontext_addr handler or pc_in_sigtramp hander. */ - if (gdbarch_tdep (current_gdbarch)->sigcontext_addr == NULL) + if (gdbarch_tdep (gdbarch)->sigcontext_addr == NULL) return NULL; - if (gdbarch_tdep (current_gdbarch)->pc_in_sigtramp == NULL) + if (gdbarch_tdep (gdbarch)->pc_in_sigtramp == NULL) return NULL; /* Otherwise we should be in a signal frame. */ find_pc_partial_function (pc, &name, NULL, NULL); - if (gdbarch_tdep (current_gdbarch)->pc_in_sigtramp (pc, name)) + if (gdbarch_tdep (gdbarch)->pc_in_sigtramp (pc, name)) return &alpha_sigtramp_frame_unwind; return NULL; } -/* Fallback alpha frame unwinder. Uses instruction scanning and knows - something about the traditional layout of alpha stack frames. */ - -struct alpha_heuristic_unwind_cache -{ - CORE_ADDR *saved_regs; - CORE_ADDR vfp; - CORE_ADDR start_pc; - int return_reg; -}; /* Heuristic_proc_start may hunt through the text section for a long time across a 2400 baud serial line. Allows the user to limit this @@ -922,9 +913,9 @@ static unsigned int heuristic_fence_post = 0; function. But we're guessing anyway... */ static CORE_ADDR -alpha_heuristic_proc_start (CORE_ADDR pc) +alpha_heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); CORE_ADDR last_non_nop = pc; CORE_ADDR fence = pc - heuristic_fence_post; CORE_ADDR orig_pc = pc; @@ -947,7 +938,7 @@ alpha_heuristic_proc_start (CORE_ADDR pc) /* Search back for previous return; also stop at a 0, which might be seen for instance before the start of a code section. Don't include nops, since this usually indicates padding between functions. */ - for (pc -= 4; pc >= fence; pc -= 4) + for (pc -= ALPHA_INSN_SIZE; pc >= fence; pc -= ALPHA_INSN_SIZE) { unsigned int insn = alpha_read_insn (pc); switch (insn) @@ -996,11 +987,23 @@ Otherwise, you told GDB there was a function where there isn't one, or\n\ return 0; } +/* Fallback alpha frame unwinder. Uses instruction scanning and knows + something about the traditional layout of alpha stack frames. */ + +struct alpha_heuristic_unwind_cache +{ + CORE_ADDR vfp; + CORE_ADDR start_pc; + struct trad_frame_saved_reg *saved_regs; + int return_reg; +}; + static struct alpha_heuristic_unwind_cache * alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, void **this_prologue_cache, CORE_ADDR start_pc) { + struct gdbarch *gdbarch = get_frame_arch (next_frame); struct alpha_heuristic_unwind_cache *info; ULONGEST val; CORE_ADDR limit_pc, cur_pc; @@ -1011,11 +1014,11 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, info = FRAME_OBSTACK_ZALLOC (struct alpha_heuristic_unwind_cache); *this_prologue_cache = info; - info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS); + info->saved_regs = trad_frame_alloc_saved_regs (next_frame); limit_pc = frame_pc_unwind (next_frame); if (start_pc == 0) - start_pc = alpha_heuristic_proc_start (limit_pc); + start_pc = alpha_heuristic_proc_start (gdbarch, limit_pc); info->start_pc = start_pc; frame_reg = ALPHA_SP_REGNUM; @@ -1029,7 +1032,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, if (start_pc + 200 < limit_pc) limit_pc = start_pc + 200; - for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) + for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += ALPHA_INSN_SIZE) { unsigned int word = alpha_read_insn (cur_pc); @@ -1061,7 +1064,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, All it says is that the function we are scanning reused that register for some computation of its own, and is now saving its result. */ - if (info->saved_regs[reg]) + if (trad_frame_addr_p(info->saved_regs, reg)) continue; if (reg == 31) @@ -1077,7 +1080,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, pointer or not. */ /* Hack: temporarily add one, so that the offset is non-zero and we can tell which registers have save offsets below. */ - info->saved_regs[reg] = (word & 0xffff) + 1; + info->saved_regs[reg].addr = (word & 0xffff) + 1; /* Starting with OSF/1-3.2C, the system libraries are shipped without local symbols, but they still contain procedure @@ -1138,7 +1141,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, break; } - cur_pc += 4; + cur_pc += ALPHA_INSN_SIZE; } } } @@ -1148,14 +1151,14 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, return_reg = ALPHA_RA_REGNUM; info->return_reg = return_reg; - frame_unwind_unsigned_register (next_frame, frame_reg, &val); + val = frame_unwind_register_unsigned (next_frame, frame_reg); info->vfp = val + frame_size; /* Convert offsets to absolute addresses. See above about adding one to the offsets to make all detected offsets non-zero. */ for (reg = 0; reg < ALPHA_NUM_REGS; ++reg) - if (info->saved_regs[reg]) - info->saved_regs[reg] += val - 1; + if (trad_frame_addr_p(info->saved_regs, reg)) + info->saved_regs[reg].addr += val - 1; return info; } @@ -1192,35 +1195,8 @@ alpha_heuristic_frame_prev_register (struct frame_info *next_frame, if (regnum == ALPHA_PC_REGNUM) regnum = info->return_reg; - /* For all registers known to be saved in the current frame, - do the obvious and pull the value out. */ - if (info->saved_regs[regnum]) - { - *optimizedp = 0; - *lvalp = lval_memory; - *addrp = info->saved_regs[regnum]; - *realnump = -1; - if (bufferp != NULL) - get_frame_memory (next_frame, *addrp, bufferp, ALPHA_REGISTER_SIZE); - return; - } - - /* The stack pointer of the previous frame is computed by popping - the current stack frame. */ - if (regnum == ALPHA_SP_REGNUM) - { - *optimizedp = 0; - *lvalp = not_lval; - *addrp = 0; - *realnump = -1; - if (bufferp != NULL) - store_unsigned_integer (bufferp, ALPHA_REGISTER_SIZE, info->vfp); - return; - } - - /* Otherwise assume the next frame has the same register value. */ - frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp, - realnump, bufferp); + trad_frame_get_prev_register (next_frame, info->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, bufferp); } static const struct frame_unwind alpha_heuristic_frame_unwind = { @@ -1271,7 +1247,7 @@ static struct frame_id alpha_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) { ULONGEST base; - frame_unwind_unsigned_register (next_frame, ALPHA_SP_REGNUM, &base); + base = frame_unwind_register_unsigned (next_frame, ALPHA_SP_REGNUM); return frame_id_build (base, frame_pc_unwind (next_frame)); } @@ -1279,7 +1255,7 @@ static CORE_ADDR alpha_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { ULONGEST pc; - frame_unwind_unsigned_register (next_frame, ALPHA_PC_REGNUM, &pc); + pc = frame_unwind_register_unsigned (next_frame, ALPHA_PC_REGNUM); return pc; } @@ -1289,67 +1265,74 @@ alpha_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) targets don't supply this value in their core files. */ void -alpha_supply_int_regs (int regno, const void *r0_r30, - const void *pc, const void *unique) +alpha_supply_int_regs (struct regcache *regcache, int regno, + const void *r0_r30, const void *pc, const void *unique) { + const gdb_byte *regs = r0_r30; int i; for (i = 0; i < 31; ++i) if (regno == i || regno == -1) - regcache_raw_supply (current_regcache, i, (const char *)r0_r30 + i*8); + regcache_raw_supply (regcache, i, regs + i * 8); if (regno == ALPHA_ZERO_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, ALPHA_ZERO_REGNUM, NULL); + regcache_raw_supply (regcache, ALPHA_ZERO_REGNUM, NULL); if (regno == ALPHA_PC_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, ALPHA_PC_REGNUM, pc); + regcache_raw_supply (regcache, ALPHA_PC_REGNUM, pc); if (regno == ALPHA_UNIQUE_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, ALPHA_UNIQUE_REGNUM, unique); + regcache_raw_supply (regcache, ALPHA_UNIQUE_REGNUM, unique); } void -alpha_fill_int_regs (int regno, void *r0_r30, void *pc, void *unique) +alpha_fill_int_regs (const struct regcache *regcache, + int regno, void *r0_r30, void *pc, void *unique) { + gdb_byte *regs = r0_r30; int i; for (i = 0; i < 31; ++i) if (regno == i || regno == -1) - regcache_raw_collect (current_regcache, i, (char *)r0_r30 + i*8); + regcache_raw_collect (regcache, i, regs + i * 8); if (regno == ALPHA_PC_REGNUM || regno == -1) - regcache_raw_collect (current_regcache, ALPHA_PC_REGNUM, pc); + regcache_raw_collect (regcache, ALPHA_PC_REGNUM, pc); if (unique && (regno == ALPHA_UNIQUE_REGNUM || regno == -1)) - regcache_raw_collect (current_regcache, ALPHA_UNIQUE_REGNUM, unique); + regcache_raw_collect (regcache, ALPHA_UNIQUE_REGNUM, unique); } void -alpha_supply_fp_regs (int regno, const void *f0_f30, const void *fpcr) +alpha_supply_fp_regs (struct regcache *regcache, int regno, + const void *f0_f30, const void *fpcr) { + const gdb_byte *regs = f0_f30; int i; for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i) if (regno == i || regno == -1) - regcache_raw_supply (current_regcache, i, - (const char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); + regcache_raw_supply (regcache, i, + regs + (i - ALPHA_FP0_REGNUM) * 8); if (regno == ALPHA_FPCR_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, ALPHA_FPCR_REGNUM, fpcr); + regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, fpcr); } void -alpha_fill_fp_regs (int regno, void *f0_f30, void *fpcr) +alpha_fill_fp_regs (const struct regcache *regcache, + int regno, void *f0_f30, void *fpcr) { + gdb_byte *regs = f0_f30; int i; for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i) if (regno == i || regno == -1) - regcache_raw_collect (current_regcache, i, - (char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); + regcache_raw_collect (regcache, i, + regs + (i - ALPHA_FP0_REGNUM) * 8); if (regno == ALPHA_FPCR_REGNUM || regno == -1) - regcache_raw_collect (current_regcache, ALPHA_FPCR_REGNUM, fpcr); + regcache_raw_collect (regcache, ALPHA_FPCR_REGNUM, fpcr); } @@ -1380,20 +1363,16 @@ fp_register_sign_bit (LONGEST reg) /* alpha_software_single_step() is called just before we want to resume the inferior, if we want to single-step it but there is no hardware or kernel single-step support (NetBSD on Alpha, for example). We find - the target of the coming instruction and breakpoint it. - - single_step is also called just after the inferior stops. If we had - set up a simulated single-step, we undo our damage. */ + the target of the coming instruction and breakpoint it. */ static CORE_ADDR -alpha_next_pc (CORE_ADDR pc) +alpha_next_pc (struct frame_info *frame, CORE_ADDR pc) { unsigned int insn; unsigned int op; int regno; int offset; LONGEST rav; - char reg[8]; insn = alpha_read_insn (pc); @@ -1404,7 +1383,7 @@ alpha_next_pc (CORE_ADDR pc) { /* Jump format: target PC is: RB & ~3 */ - return (read_register ((insn >> 16) & 0x1f) & ~3); + return (get_frame_register_unsigned (frame, (insn >> 16) & 0x1f) & ~3); } if ((op & 0x30) == 0x30) @@ -1418,8 +1397,8 @@ alpha_next_pc (CORE_ADDR pc) offset = (insn & 0x001fffff); if (offset & 0x00100000) offset |= 0xffe00000; - offset *= 4; - return (pc + 4 + offset); + offset *= ALPHA_INSN_SIZE; + return (pc + ALPHA_INSN_SIZE + offset); } /* Need to determine if branch is taken; read RA. */ @@ -1432,11 +1411,10 @@ alpha_next_pc (CORE_ADDR pc) case 0x33: /* FBLE */ case 0x32: /* FBLT */ case 0x35: /* FBNE */ - regno += FP0_REGNUM; + regno += gdbarch_fp0_regnum (get_frame_arch (frame)); } - regcache_cooked_read (current_regcache, regno, reg); - rav = extract_signed_integer (reg, 8); + rav = get_frame_register_signed (frame, regno); switch (op) { @@ -1504,27 +1482,19 @@ alpha_next_pc (CORE_ADDR pc) /* Not a branch or branch not taken; target PC is: pc + 4 */ - return (pc + 4); + return (pc + ALPHA_INSN_SIZE); } -void -alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) +int +alpha_software_single_step (struct frame_info *frame) { - static CORE_ADDR next_pc; - CORE_ADDR pc; + CORE_ADDR pc, next_pc; - if (insert_breakpoints_p) - { - pc = read_pc (); - next_pc = alpha_next_pc (pc); + pc = get_frame_pc (frame); + next_pc = alpha_next_pc (frame, pc); - insert_single_step_breakpoint (next_pc); - } - else - { - remove_single_step_breakpoints (); - write_pc (next_pc); - } + insert_single_step_breakpoint (next_pc); + return 1; } @@ -1622,7 +1592,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc); - set_gdbarch_decr_pc_after_break (gdbarch, 4); + set_gdbarch_decr_pc_after_break (gdbarch, ALPHA_INSN_SIZE); set_gdbarch_cannot_step_breakpoint (gdbarch, 1); /* Hook in ABI-specific overrides, if they have been registered. */