X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fm68k-tdep.c;h=90cb169234f4ad1144056ec3ba5ade395e1d55c6;hb=df1f7f58bb9018211615ce880b558408e52fef2e;hp=5973f0ba81a76989966a9b8c6583c9071af66009;hpb=51da707ac6f9602d6a34e46e8602c93f80bf6ef6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index 5973f0ba81..90cb169234 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -1,7 +1,7 @@ /* Target-dependent code for the Motorola 68000 series. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, - 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GDB. @@ -17,15 +17,15 @@ 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. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" #include "dwarf2-frame.h" #include "frame.h" #include "frame-base.h" #include "frame-unwind.h" -#include "floatformat.h" +#include "gdbtypes.h" #include "symtab.h" #include "gdbcore.h" #include "value.h" @@ -65,10 +65,10 @@ #define BPT_VECTOR 0xf #endif -static const unsigned char * +static const gdb_byte * m68k_local_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) { - static unsigned char break_insn[] = {0x4e, (0x40 | BPT_VECTOR)}; + static gdb_byte break_insn[] = {0x4e, (0x40 | BPT_VECTOR)}; *lenptr = sizeof (break_insn); return break_insn; } @@ -122,10 +122,9 @@ m68k_register_name (int regnum) "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags" }; - if (regnum < 0 || - regnum >= sizeof (register_names) / sizeof (register_names[0])) + if (regnum < 0 || regnum >= ARRAY_SIZE (register_names)) internal_error (__FILE__, __LINE__, - "m68k_register_name: illegal register number %d", regnum); + _("m68k_register_name: illegal register number %d"), regnum); else return register_names[regnum]; } @@ -144,15 +143,15 @@ m68k_convert_register_p (int regnum, struct type *type) static void m68k_register_to_value (struct frame_info *frame, int regnum, - struct type *type, void *to) + struct type *type, gdb_byte *to) { - char from[M68K_MAX_REGISTER_SIZE]; + gdb_byte from[M68K_MAX_REGISTER_SIZE]; /* We only support floating-point values. */ if (TYPE_CODE (type) != TYPE_CODE_FLT) { - warning ("Cannot convert floating-point register value " - "to non-floating-point type."); + warning (_("Cannot convert floating-point register value " + "to non-floating-point type.")); return; } @@ -167,15 +166,15 @@ m68k_register_to_value (struct frame_info *frame, int regnum, static void m68k_value_to_register (struct frame_info *frame, int regnum, - struct type *type, const void *from) + struct type *type, const gdb_byte *from) { - char to[M68K_MAX_REGISTER_SIZE]; + gdb_byte to[M68K_MAX_REGISTER_SIZE]; /* We only support floating-point values. */ if (TYPE_CODE (type) != TYPE_CODE_FLT) { - warning ("Cannot convert non-floating-point type " - "to floating-point register value."); + warning (_("Cannot convert non-floating-point type " + "to floating-point register value.")); return; } @@ -220,10 +219,10 @@ m68k_value_to_register (struct frame_info *frame, int regnum, static void m68k_extract_return_value (struct type *type, struct regcache *regcache, - void *valbuf) + gdb_byte *valbuf) { int len = TYPE_LENGTH (type); - char buf[M68K_MAX_REGISTER_SIZE]; + gdb_byte buf[M68K_MAX_REGISTER_SIZE]; if (len <= 4) { @@ -234,20 +233,19 @@ m68k_extract_return_value (struct type *type, struct regcache *regcache, { regcache_raw_read (regcache, M68K_D0_REGNUM, buf); memcpy (valbuf, buf + (8 - len), len - 4); - regcache_raw_read (regcache, M68K_D1_REGNUM, - (char *) valbuf + (len - 4)); + regcache_raw_read (regcache, M68K_D1_REGNUM, valbuf + (len - 4)); } else internal_error (__FILE__, __LINE__, - "Cannot extract return value of %d bytes long.", len); + _("Cannot extract return value of %d bytes long."), len); } static void m68k_svr4_extract_return_value (struct type *type, struct regcache *regcache, - void *valbuf) + gdb_byte *valbuf) { int len = TYPE_LENGTH (type); - char buf[M68K_MAX_REGISTER_SIZE]; + gdb_byte buf[M68K_MAX_REGISTER_SIZE]; if (TYPE_CODE (type) == TYPE_CODE_FLT) { @@ -264,7 +262,7 @@ m68k_svr4_extract_return_value (struct type *type, struct regcache *regcache, static void m68k_store_return_value (struct type *type, struct regcache *regcache, - const void *valbuf) + const gdb_byte *valbuf) { int len = TYPE_LENGTH (type); @@ -274,23 +272,22 @@ m68k_store_return_value (struct type *type, struct regcache *regcache, { regcache_raw_write_part (regcache, M68K_D0_REGNUM, 8 - len, len - 4, valbuf); - regcache_raw_write (regcache, M68K_D1_REGNUM, - (char *) valbuf + (len - 4)); + regcache_raw_write (regcache, M68K_D1_REGNUM, valbuf + (len - 4)); } else internal_error (__FILE__, __LINE__, - "Cannot store return value of %d bytes long.", len); + _("Cannot store return value of %d bytes long."), len); } static void m68k_svr4_store_return_value (struct type *type, struct regcache *regcache, - const void *valbuf) + const gdb_byte *valbuf) { int len = TYPE_LENGTH (type); if (TYPE_CODE (type) == TYPE_CODE_FLT) { - char buf[M68K_MAX_REGISTER_SIZE]; + gdb_byte buf[M68K_MAX_REGISTER_SIZE]; convert_typed_floating (valbuf, type, buf, builtin_type_m68881_ext); regcache_raw_write (regcache, M68K_FP0_REGNUM, buf); } @@ -330,18 +327,30 @@ m68k_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type) static enum return_value_convention m68k_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, void *readbuf, - const void *writebuf) + struct regcache *regcache, gdb_byte *readbuf, + const gdb_byte *writebuf) { enum type_code code = TYPE_CODE (type); - if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) - && !m68k_reg_struct_return_p (gdbarch, type)) - return RETURN_VALUE_STRUCT_CONVENTION; + /* GCC returns a `long double' in memory too. */ + if (((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) + && !m68k_reg_struct_return_p (gdbarch, type)) + || (code == TYPE_CODE_FLT && TYPE_LENGTH (type) == 12)) + { + /* The default on m68k is to return structures in static memory. + Consequently a function must return the address where we can + find the return value. */ - /* GCC returns a `long double' in memory. */ - if (code == TYPE_CODE_FLT && TYPE_LENGTH (type) == 12) - return RETURN_VALUE_STRUCT_CONVENTION; + if (readbuf) + { + ULONGEST addr; + + regcache_raw_read_unsigned (regcache, M68K_D0_REGNUM, &addr); + read_memory (addr, readbuf, TYPE_LENGTH (type)); + } + + return RETURN_VALUE_ABI_RETURNS_ADDRESS; + } if (readbuf) m68k_extract_return_value (type, regcache, readbuf); @@ -353,8 +362,8 @@ m68k_return_value (struct gdbarch *gdbarch, struct type *type, static enum return_value_convention m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, void *readbuf, - const void *writebuf) + struct regcache *regcache, gdb_byte *readbuf, + const gdb_byte *writebuf) { enum type_code code = TYPE_CODE (type); @@ -404,20 +413,30 @@ m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *type, } +/* Always align the frame to a 4-byte boundary. This is required on + coldfire and harmless on the rest. */ + static CORE_ADDR -m68k_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, +m68k_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) +{ + /* Align the stack to four bytes. */ + return sp & ~3; +} + +static CORE_ADDR +m68k_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) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - char buf[4]; + gdb_byte buf[4]; int i; /* Push arguments in reverse order. */ for (i = nargs - 1; i >= 0; i--) { - struct type *value_type = VALUE_ENCLOSING_TYPE (args[i]); + struct type *value_type = value_enclosing_type (args[i]); int len = TYPE_LENGTH (value_type); int container_len = (len + 3) & ~3; int offset; @@ -432,7 +451,7 @@ m68k_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, else offset = container_len - len; sp -= container_len; - write_memory (sp + offset, VALUE_CONTENTS_ALL (args[i]), len); + write_memory (sp + offset, value_contents_all (args[i]), len); } /* Store struct value address. */ @@ -458,6 +477,28 @@ m68k_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, frame's CFA. */ return sp + 8; } + +/* Convert a dwarf or dwarf2 regnumber to a GDB regnum. */ + +static int +m68k_dwarf_reg_to_regnum (int num) +{ + if (num < 8) + /* d0..7 */ + return (num - 0) + M68K_D0_REGNUM; + else if (num < 16) + /* a0..7 */ + return (num - 8) + M68K_A0_REGNUM; + else if (num < 24) + /* fp0..7 */ + return (num - 16) + M68K_FP0_REGNUM; + else if (num == 25) + /* pc */ + return M68K_PC_REGNUM; + else + return NUM_REGS + NUM_PSEUDO_REGS; +} + struct m68k_frame_cache { @@ -636,10 +677,10 @@ m68k_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc, else break; } - else if ((op & 0170677) == P_MOVEL_SP) + else if ((op & 0177760) == P_MOVEL_SP) { /* move.l %R,-(%sp) */ - regno = ((op & 07000) >> 9) | ((op & 0100) >> 3); + regno = op & 017; cache->saved_regs[regno] = offset; offset -= 4; pc += 2; @@ -740,7 +781,7 @@ m68k_skip_prologue (CORE_ADDR start_pc) static CORE_ADDR m68k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - char buf[8]; + gdb_byte buf[8]; frame_unwind_register (next_frame, PC_REGNUM, buf); return extract_typed_address (buf, builtin_type_void_func_ptr); @@ -752,7 +793,7 @@ static struct m68k_frame_cache * m68k_frame_cache (struct frame_info *next_frame, void **this_cache) { struct m68k_frame_cache *cache; - char buf[4]; + gdb_byte buf[4]; int i; if (*this_cache) @@ -778,7 +819,7 @@ m68k_frame_cache (struct frame_info *next_frame, void **this_cache) /* For normal frames, %pc is stored at 4(%fp). */ cache->saved_regs[M68K_PC_REGNUM] = 4; - cache->pc = frame_func_unwind (next_frame); + cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME); if (cache->pc != 0) m68k_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache); @@ -827,7 +868,7 @@ static void m68k_frame_prev_register (struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *valuep) + int *realnump, gdb_byte *valuep) { struct m68k_frame_cache *cache = m68k_frame_cache (next_frame, this_cache); @@ -862,8 +903,12 @@ m68k_frame_prev_register (struct frame_info *next_frame, void **this_cache, return; } - frame_register_unwind (next_frame, regnum, - optimizedp, lvalp, addrp, realnump, valuep); + *optimizedp = 0; + *lvalp = lval_register; + *addrp = 0; + *realnump = regnum; + if (valuep) + frame_unwind_register (next_frame, (*realnump), valuep); } static const struct frame_unwind m68k_frame_unwind = @@ -898,7 +943,7 @@ static const struct frame_base m68k_frame_base = static struct frame_id m68k_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) { - char buf[4]; + gdb_byte buf[4]; CORE_ADDR fp; frame_unwind_register (next_frame, M68K_FP_REGNUM, buf); @@ -963,10 +1008,10 @@ supply_gregset (gregset_t *gregsetp) for (regi = 0; regi < R_PC; regi++) { - supply_register (regi, (char *) (regp + regi)); + regcache_raw_supply (current_regcache, regi, (char *) (regp + regi)); } - supply_register (PS_REGNUM, (char *) (regp + R_PS)); - supply_register (PC_REGNUM, (char *) (regp + R_PC)); + regcache_raw_supply (current_regcache, PS_REGNUM, (char *) (regp + R_PS)); + regcache_raw_supply (current_regcache, PC_REGNUM, (char *) (regp + R_PC)); } void @@ -978,12 +1023,12 @@ fill_gregset (gregset_t *gregsetp, int regno) for (regi = 0; regi < R_PC; regi++) { if (regno == -1 || regno == regi) - regcache_collect (regi, regp + regi); + regcache_raw_collect (current_regcache, regi, regp + regi); } if (regno == -1 || regno == PS_REGNUM) - regcache_collect (PS_REGNUM, regp + R_PS); + regcache_raw_collect (current_regcache, PS_REGNUM, regp + R_PS); if (regno == -1 || regno == PC_REGNUM) - regcache_collect (PC_REGNUM, regp + R_PC); + regcache_raw_collect (current_regcache, PC_REGNUM, regp + R_PC); } #if defined (FP0_REGNUM) @@ -1001,11 +1046,14 @@ supply_fpregset (fpregset_t *fpregsetp) for (regi = FP0_REGNUM; regi < M68K_FPC_REGNUM; regi++) { from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]); - supply_register (regi, from); + regcache_raw_supply (current_regcache, regi, from); } - supply_register (M68K_FPC_REGNUM, (char *) &(fpregsetp->f_pcr)); - supply_register (M68K_FPS_REGNUM, (char *) &(fpregsetp->f_psr)); - supply_register (M68K_FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr)); + regcache_raw_supply (current_regcache, M68K_FPC_REGNUM, + (char *) &(fpregsetp->f_pcr)); + regcache_raw_supply (current_regcache, M68K_FPS_REGNUM, + (char *) &(fpregsetp->f_psr)); + regcache_raw_supply (current_regcache, M68K_FPI_REGNUM, + (char *) &(fpregsetp->f_fpiaddr)); } /* Given a pointer to a floating point register set in /proc format @@ -1021,14 +1069,18 @@ fill_fpregset (fpregset_t *fpregsetp, int regno) for (regi = FP0_REGNUM; regi < M68K_FPC_REGNUM; regi++) { if (regno == -1 || regno == regi) - regcache_collect (regi, &fpregsetp->f_fpregs[regi - FP0_REGNUM][0]); + regcache_raw_collect (current_regcache, regi, + &fpregsetp->f_fpregs[regi - FP0_REGNUM][0]); } if (regno == -1 || regno == M68K_FPC_REGNUM) - regcache_collect (M68K_FPC_REGNUM, &fpregsetp->f_pcr); + regcache_raw_collect (current_regcache, M68K_FPC_REGNUM, + &fpregsetp->f_pcr); if (regno == -1 || regno == M68K_FPS_REGNUM) - regcache_collect (M68K_FPS_REGNUM, &fpregsetp->f_psr); + regcache_raw_collect (current_regcache, M68K_FPS_REGNUM, + &fpregsetp->f_psr); if (regno == -1 || regno == M68K_FPI_REGNUM) - regcache_collect (M68K_FPI_REGNUM, &fpregsetp->f_fpiaddr); + regcache_raw_collect (current_regcache, M68K_FPI_REGNUM, + &fpregsetp->f_fpiaddr); } #endif /* defined (FP0_REGNUM) */ @@ -1040,17 +1092,17 @@ fill_fpregset (fpregset_t *fpregsetp, int regno) we extract the pc (JB_PC) that we will land at. The pc is copied into PC. This routine returns true on success. */ -int +static int m68k_get_longjmp_target (CORE_ADDR *pc) { - char *buf; + gdb_byte *buf; CORE_ADDR sp, jb_addr; struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); if (tdep->jb_pc < 0) { internal_error (__FILE__, __LINE__, - "m68k_get_longjmp_target: not implemented"); + _("m68k_get_longjmp_target: not implemented")); return 0; } @@ -1105,7 +1157,7 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep = xmalloc (sizeof (struct gdbarch_tdep)); gdbarch = gdbarch_alloc (&info, tdep); - set_gdbarch_long_double_format (gdbarch, &floatformat_m68881_ext); + set_gdbarch_long_double_format (gdbarch, floatformats_m68881_ext); set_gdbarch_long_double_bit (gdbarch, 96); set_gdbarch_skip_prologue (gdbarch, m68k_skip_prologue); @@ -1113,15 +1165,18 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Stack grows down. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + set_gdbarch_frame_align (gdbarch, m68k_frame_align); set_gdbarch_believe_pcc_promotion (gdbarch, 1); set_gdbarch_decr_pc_after_break (gdbarch, 2); set_gdbarch_frame_args_skip (gdbarch, 8); + set_gdbarch_dwarf_reg_to_regnum (gdbarch, m68k_dwarf_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, m68k_dwarf_reg_to_regnum); set_gdbarch_register_type (gdbarch, m68k_register_type); set_gdbarch_register_name (gdbarch, m68k_register_name); - set_gdbarch_num_regs (gdbarch, 29); + set_gdbarch_num_regs (gdbarch, M68K_NUM_REGS); set_gdbarch_register_bytes_ok (gdbarch, m68k_register_bytes_ok); set_gdbarch_sp_regnum (gdbarch, M68K_SP_REGNUM); set_gdbarch_pc_regnum (gdbarch, M68K_PC_REGNUM);