* alphafbsd-tdep.c: Update for unwinder changes.
[deliverable/binutils-gdb.git] / gdb / mn10300-tdep.c
index 6c9774fa3b33106ad56fff35323aba568014d428..37d0b84b645c2ae134a5ae7614bd0d13ca9a1f74 100644 (file)
@@ -1,13 +1,13 @@
 /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
 
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+   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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "arch-utils.h"
@@ -37,6 +35,8 @@
 #include "symtab.h"
 #include "dwarf2-frame.h"
 #include "osabi.h"
+#include "infcall.h"
+#include "target.h"
 
 #include "mn10300-tdep.h"
 
@@ -196,9 +196,9 @@ mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type,
    from WRITEBUF into REGCACHE.  */
 
 static enum return_value_convention
-mn10300_return_value (struct gdbarch *gdbarch, struct type *type,
-                     struct regcache *regcache, gdb_byte *readbuf,
-                     const gdb_byte *writebuf)
+mn10300_return_value (struct gdbarch *gdbarch, struct type *func_type,
+                     struct type *type, struct regcache *regcache,
+                     gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   if (mn10300_use_struct_convention (type))
     return RETURN_VALUE_STRUCT_CONVENTION;
@@ -221,7 +221,7 @@ register_name (int reg, char **regs, long sizeof_regs)
 }
 
 static const char *
-mn10300_generic_register_name (int reg)
+mn10300_generic_register_name (struct gdbarch *gdbarch, int reg)
 {
   static char *regs[] =
   { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3",
@@ -234,7 +234,7 @@ mn10300_generic_register_name (int reg)
 
 
 static const char *
-am33_register_name (int reg)
+am33_register_name (struct gdbarch *gdbarch, int reg)
 {
   static char *regs[] =
   { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3",
@@ -246,7 +246,7 @@ am33_register_name (int reg)
 }
 
 static const char *
-am33_2_register_name (int reg)
+am33_2_register_name (struct gdbarch *gdbarch, int reg)
 {
   static char *regs[] =
   {
@@ -269,15 +269,17 @@ mn10300_register_type (struct gdbarch *gdbarch, int reg)
 }
 
 static CORE_ADDR
-mn10300_read_pc (ptid_t ptid)
+mn10300_read_pc (struct regcache *regcache)
 {
-  return read_register_pid (E_PC_REGNUM, ptid);
+  ULONGEST val;
+  regcache_cooked_read_unsigned (regcache, E_PC_REGNUM, &val);
+  return val;
 }
 
 static void
-mn10300_write_pc (CORE_ADDR val, ptid_t ptid)
+mn10300_write_pc (struct regcache *regcache, CORE_ADDR val)
 {
-  return write_register_pid (E_PC_REGNUM, val, ptid);
+  regcache_cooked_write_unsigned (regcache, E_PC_REGNUM, val);
 }
 
 /* The breakpoint instruction must be the same size as the smallest
@@ -288,7 +290,8 @@ mn10300_write_pc (CORE_ADDR val, ptid_t ptid)
    one, so we defined it ourselves.  */
 
 const static unsigned char *
-mn10300_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
+mn10300_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
+                           int *bp_size)
 {
   static char breakpoint[] = {0xff};
   *bp_size = 1;
@@ -306,6 +309,7 @@ set_reg_offsets (struct frame_info *fi,
                  int stack_extra_size,
                  int frame_in_fp)
 {
+  struct gdbarch *gdbarch;
   struct trad_frame_cache *cache;
   int offset = 0;
   CORE_ADDR base;
@@ -316,6 +320,7 @@ set_reg_offsets (struct frame_info *fi,
   cache = mn10300_frame_unwind_cache (fi, this_cache);
   if (cache == NULL)
     return;
+  gdbarch = get_frame_arch (fi);
 
   if (frame_in_fp)
     {
@@ -323,12 +328,13 @@ set_reg_offsets (struct frame_info *fi,
     }
   else
     {
-      base = frame_unwind_register_unsigned (fi, E_SP_REGNUM) + stack_extra_size;
+      base = frame_unwind_register_unsigned (fi, E_SP_REGNUM)
+              + stack_extra_size;
     }
 
   trad_frame_set_this_base (cache, base);
 
-  if (AM33_MODE == 2)
+  if (AM33_MODE (gdbarch) == 2)
     {
       /* If bit N is set in fpregmask, fsN is saved on the stack.
         The floating point registers are saved in ascending order.
@@ -341,7 +347,8 @@ set_reg_offsets (struct frame_info *fi,
            {
              if (fpregmask & (1 << i))
                {
-                 trad_frame_set_reg_addr (cache, E_FS0_REGNUM + i, base + offset);
+                 trad_frame_set_reg_addr (cache, E_FS0_REGNUM + i,
+                                          base + offset);
                  offset += 4;
                }
            }
@@ -384,7 +391,7 @@ set_reg_offsets (struct frame_info *fi,
       trad_frame_set_reg_addr (cache, E_D2_REGNUM, base + offset);
       offset += 4;
     }
-  if (AM33_MODE)
+  if (AM33_MODE (gdbarch))
     {
       if (movm_args & movm_exother_bit)
         {
@@ -514,7 +521,7 @@ set_reg_offsets (struct frame_info *fi,
    frame chain to not bother trying to unwind past this frame.  */
 
 static CORE_ADDR
-mn10300_analyze_prologue (struct frame_info *fi, 
+mn10300_analyze_prologue (struct gdbarch *gdbarch, struct frame_info *fi, 
                          void **this_cache, 
                          CORE_ADDR pc)
 {
@@ -603,7 +610,23 @@ mn10300_analyze_prologue (struct frame_info *fi,
        goto finish_prologue;
     }
 
-  if (AM33_MODE == 2)
+  /* Check for "mov pc, a2", an instruction found in optimized, position
+     independent code.  Skip it if found.  */
+  if (buf[0] == 0xf0 && buf[1] == 0x2e)
+    {
+      addr += 2;
+
+      /* Quit now if we're beyond the stop point.  */
+      if (addr >= stop)
+       goto finish_prologue;
+
+      /* Get the next two bytes so the prologue scan can continue.  */
+      status = target_read_memory (addr, buf, 2);
+      if (status != 0)
+       goto finish_prologue;
+    }
+
+  if (AM33_MODE (gdbarch) == 2)
     {
       /* Determine if any floating point registers are to be saved.
         Look for one of the following three prologue formats:
@@ -620,6 +643,18 @@ mn10300_analyze_prologue (struct frame_info *fi,
        [mov sp,a3]        [mov sp,a3]
        [add -SIZE2,sp]    [add -SIZE2,sp]                                 */
 
+      /* Remember the address at which we started in the event that we
+        don't ultimately find an fmov instruction.  Once we're certain
+        that we matched one of the above patterns, we'll set
+        ``restore_addr'' to the appropriate value.  Note: At one time
+        in the past, this code attempted to not adjust ``addr'' until
+        there was a fair degree of certainty that the pattern would be
+        matched.  However, that code did not wait until an fmov instruction
+        was actually encountered.  As a consequence, ``addr'' would
+        sometimes be advanced even when no fmov instructions were found.  */
+      CORE_ADDR restore_addr = addr;
+      int fmov_found = 0;
+
       /* First, look for add -SIZE,sp (i.e. add imm8,sp  (0xf8feXX)
                                          or add imm16,sp (0xfafeXXXX)
                                          or add imm32,sp (0xfcfeXXXXXXXX)) */
@@ -651,10 +686,10 @@ mn10300_analyze_prologue (struct frame_info *fi,
                     This is a one byte instruction:  mov sp,aN = 0011 11XX
                     where XX is the register number.
 
-                    Skip this instruction by incrementing addr. (We're
-                    committed now.) The "fmov" instructions will have the
-                    form "fmov fs#,(aN+)" in this case, but that will not
-                    necessitate a change in the "fmov" parsing logic below. */
+                    Skip this instruction by incrementing addr.  The "fmov"
+                    instructions will have the form "fmov fs#,(aN+)" in this
+                    case, but that will not necessitate a change in the
+                    "fmov" parsing logic below. */
 
                  addr++;
 
@@ -698,6 +733,11 @@ mn10300_analyze_prologue (struct frame_info *fi,
                      if (buf[0] != 0xf9 && buf[0] != 0xfb)
                        break;
 
+                     /* An fmov instruction has just been seen.  We can
+                        now really commit to the pattern match.  */
+
+                     fmov_found = 1;
+
                      /* Get the floating point register number from the 
                         2nd and 3rd bytes of the "fmov" instruction:
                         Machine Code: 0000 00X0 YYYY 0000 =>
@@ -715,20 +755,18 @@ mn10300_analyze_prologue (struct frame_info *fi,
                      imm_size = (buf[0] == 0xf9) ? 3 : 4;
                    }
                }
-             else
-               {
-                 /* No "fmov" was found. Reread the two bytes at the original
-                    "addr" to reset the state. */
-                 if (!safe_frame_unwind_memory (fi, addr, buf, 2))
-                   goto finish_prologue;
-               }
            }
-         /* else the prologue consists entirely of an "add -SIZE,sp"
-            instruction. Handle this below. */
        }
-      /* else no "add -SIZE,sp" was found indicating no floating point
-        registers are saved in this prologue. Do not increment addr. Pretend
-        this bit of code never happened. */
+      /* If no fmov instructions were found by the above sequence, reset
+         the state and pretend that the above bit of code never happened.  */
+      if (!fmov_found)
+       {
+         addr = restore_addr;
+         status = target_read_memory (addr, buf, 2);
+         if (status != 0)
+           goto finish_prologue;
+         stack_extra_size = 0;
+       }
     }
 
   /* Now see if we set up a frame pointer via "mov sp,a3" */
@@ -777,7 +815,7 @@ mn10300_analyze_prologue (struct frame_info *fi,
        goto finish_prologue;
 
       /* Note the size of the stack.  */
-      stack_extra_size += extract_signed_integer (buf, imm_size);
+      stack_extra_size -= extract_signed_integer (buf, imm_size);
 
       /* We just consumed 2 + imm_size bytes.  */
       addr += 2 + imm_size;
@@ -789,7 +827,8 @@ mn10300_analyze_prologue (struct frame_info *fi,
  finish_prologue:
   /* Note if/where callee saved registers were saved.  */
   if (fi)
-    set_reg_offsets (fi, this_cache, movm_args, fpregmask, stack_extra_size, frame_in_fp);
+    set_reg_offsets (fi, this_cache, movm_args, fpregmask, stack_extra_size,
+                    frame_in_fp);
   return addr;
 }
 
@@ -797,34 +836,42 @@ mn10300_analyze_prologue (struct frame_info *fi,
    Return the address of the first inst past the prologue of the function.  */
 
 static CORE_ADDR
-mn10300_skip_prologue (CORE_ADDR pc)
+mn10300_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
-  return mn10300_analyze_prologue (NULL, NULL, pc);
+  return mn10300_analyze_prologue (gdbarch, NULL, NULL, pc);
 }
 
 /* Simple frame_unwind_cache.  
    This finds the "extra info" for the frame.  */
 struct trad_frame_cache *
-mn10300_frame_unwind_cache (struct frame_info *next_frame,
+mn10300_frame_unwind_cache (struct frame_info *this_frame,
                            void **this_prologue_cache)
 {
+  struct gdbarch *gdbarch;
   struct trad_frame_cache *cache;
   CORE_ADDR pc, start, end;
+  void *cache_p;
 
   if (*this_prologue_cache)
     return (*this_prologue_cache);
 
-  cache = trad_frame_cache_zalloc (next_frame);
-  pc = gdbarch_unwind_pc (current_gdbarch, next_frame);
-  mn10300_analyze_prologue (next_frame, (void **) &cache, pc);
+  gdbarch = get_frame_arch (this_frame);
+  cache_p = trad_frame_cache_zalloc (this_frame);
+  pc = get_frame_register_unsigned (this_frame, E_PC_REGNUM);
+  mn10300_analyze_prologue (gdbarch, this_frame, &cache_p, pc);
+  cache = cache_p;
+
   if (find_pc_partial_function (pc, NULL, &start, &end))
     trad_frame_set_id (cache, 
                       frame_id_build (trad_frame_get_this_base (cache), 
                                       start));
   else
-    trad_frame_set_id (cache, 
-                      frame_id_build (trad_frame_get_this_base (cache), 
-                                      frame_func_unwind (next_frame)));
+    {
+      start = get_frame_func (this_frame);
+      trad_frame_set_id (cache,
+                        frame_id_build (trad_frame_get_this_base (cache),
+                                        start));
+    }
 
   (*this_prologue_cache) = cache;
   return cache;
@@ -832,65 +879,53 @@ mn10300_frame_unwind_cache (struct frame_info *next_frame,
 
 /* Here is a dummy implementation.  */
 static struct frame_id
-mn10300_unwind_dummy_id (struct gdbarch *gdbarch,
-                        struct frame_info *next_frame)
+mn10300_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
-  return frame_id_build (frame_sp_unwind (next_frame), 
-                        frame_pc_unwind (next_frame));
+  CORE_ADDR sp = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
+  CORE_ADDR pc = get_frame_register_unsigned (this_frame, E_PC_REGNUM);
+  return frame_id_build (sp, pc);
 }
 
 /* Trad frame implementation.  */
 static void
-mn10300_frame_this_id (struct frame_info *next_frame,
+mn10300_frame_this_id (struct frame_info *this_frame,
                       void **this_prologue_cache,
                       struct frame_id *this_id)
 {
   struct trad_frame_cache *cache = 
-    mn10300_frame_unwind_cache (next_frame, this_prologue_cache);
+    mn10300_frame_unwind_cache (this_frame, this_prologue_cache);
 
   trad_frame_get_id (cache, this_id);
 }
 
-static void
-mn10300_frame_prev_register (struct frame_info *next_frame,
-                            void **this_prologue_cache,
-                            int regnum, int *optimizedp,
-                            enum lval_type *lvalp, CORE_ADDR *addrp,
-                            int *realnump, gdb_byte *bufferp)
+static struct value *
+mn10300_frame_prev_register (struct frame_info *this_frame,
+                            void **this_prologue_cache, int regnum)
 {
   struct trad_frame_cache *cache =
-    mn10300_frame_unwind_cache (next_frame, this_prologue_cache);
+    mn10300_frame_unwind_cache (this_frame, this_prologue_cache);
 
-  trad_frame_get_register (cache, next_frame, regnum, optimizedp, 
-                          lvalp, addrp, realnump, bufferp);
-  /* Or...
-  trad_frame_get_prev_register (next_frame, cache->prev_regs, regnum, 
-                          optimizedp, lvalp, addrp, realnump, bufferp);
-  */
+  return trad_frame_get_register (cache, this_frame, regnum);
 }
 
 static const struct frame_unwind mn10300_frame_unwind = {
   NORMAL_FRAME,
   mn10300_frame_this_id, 
-  mn10300_frame_prev_register
+  mn10300_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
 
 static CORE_ADDR
-mn10300_frame_base_address (struct frame_info *next_frame,
+mn10300_frame_base_address (struct frame_info *this_frame,
                            void **this_prologue_cache)
 {
   struct trad_frame_cache *cache = 
-    mn10300_frame_unwind_cache (next_frame, this_prologue_cache);
+    mn10300_frame_unwind_cache (this_frame, this_prologue_cache);
 
   return trad_frame_get_this_base (cache);
 }
 
-static const struct frame_unwind *
-mn10300_frame_sniffer (struct frame_info *next_frame)
-{
-  return &mn10300_frame_unwind;
-}
-
 static const struct frame_base mn10300_frame_base = {
   &mn10300_frame_unwind, 
   mn10300_frame_base_address, 
@@ -903,7 +938,7 @@ mn10300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   ULONGEST pc;
 
-  frame_unwind_unsigned_register (next_frame, E_PC_REGNUM, &pc);
+  pc = frame_unwind_register_unsigned (next_frame, E_PC_REGNUM);
   return pc;
 }
 
@@ -912,17 +947,17 @@ mn10300_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   ULONGEST sp;
 
-  frame_unwind_unsigned_register (next_frame, E_SP_REGNUM, &sp);
+  sp = frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
   return sp;
 }
 
 static void
 mn10300_frame_unwind_init (struct gdbarch *gdbarch)
 {
-  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
-  frame_unwind_append_sniffer (gdbarch, mn10300_frame_sniffer);
+  dwarf2_append_unwinders (gdbarch);
+  frame_unwind_append_unwinder (gdbarch, &mn10300_frame_unwind);
   frame_base_set_default (gdbarch, &mn10300_frame_base);
-  set_gdbarch_unwind_dummy_id (gdbarch, mn10300_unwind_dummy_id);
+  set_gdbarch_dummy_id (gdbarch, mn10300_dummy_id);
   set_gdbarch_unwind_pc (gdbarch, mn10300_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, mn10300_unwind_sp);
 }
@@ -977,7 +1012,7 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
   if (struct_return)
     {
       regs_used = 1;
-      write_register (E_D0_REGNUM, struct_addr);
+      regcache_cooked_write_unsigned (regcache, E_D0_REGNUM, struct_addr);
     }
   else
     regs_used = 0;
@@ -1003,8 +1038,8 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
 
       while (regs_used < 2 && arg_len > 0)
        {
-         write_register (regs_used, 
-                         extract_unsigned_integer (val, push_size));
+         regcache_cooked_write_unsigned (regcache, regs_used, 
+                                 extract_unsigned_integer (val, push_size));
          val += push_size;
          arg_len -= push_size;
          regs_used++;
@@ -1027,8 +1062,40 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
   /* Push the return address that contains the magic breakpoint.  */
   sp -= 4;
   write_memory_unsigned_integer (sp, push_size, bp_addr);
+
+  /* The CPU also writes the return address always into the
+     MDR register on "call".  */
+  regcache_cooked_write_unsigned (regcache, E_MDR_REGNUM, bp_addr);
+
   /* Update $sp.  */
   regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp);
+
+  /* On the mn10300, it's possible to move some of the stack adjustment
+     and saving of the caller-save registers out of the prologue and
+     into the call sites.  (When using gcc, this optimization can
+     occur when using the -mrelax switch.) If this occurs, the dwarf2
+     info will reflect this fact.  We can test to see if this is the
+     case by creating a new frame using the current stack pointer and
+     the address of the function that we're about to call.  We then
+     unwind SP and see if it's different than the SP of our newly
+     created frame.  If the SP values are the same, the caller is not
+     expected to allocate any additional stack.  On the other hand, if
+     the SP values are different, the difference determines the
+     additional stack that must be allocated.
+     
+     Note that we don't update the return value though because that's
+     the value of the stack just after pushing the arguments, but prior
+     to performing the call.  This value is needed in order to
+     construct the frame ID of the dummy call.   */
+  {
+    CORE_ADDR func_addr = find_function_addr (target_func, NULL);
+    CORE_ADDR unwound_sp 
+      = mn10300_unwind_sp (gdbarch, create_new_frame (sp, func_addr));
+    if (sp != unwound_sp)
+      regcache_cooked_write_unsigned (regcache, E_SP_REGNUM,
+                                      sp - (unwound_sp - sp));
+  }
+
   return sp;
 }
 
@@ -1040,9 +1107,9 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
    to work with the existing GDB, neither of them can change.  So we
    just have to cope.  */
 static int
-mn10300_dwarf2_reg_to_regnum (int dwarf2)
+mn10300_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2)
 {
-  /* This table is supposed to be shaped like the REGISTER_NAMES
+  /* This table is supposed to be shaped like the gdbarch_register_name
      initializer in gcc/config/mn10300/mn10300.h.  Registers which
      appear in GCC's numbering, but have no counterpart in GDB's
      world, are marked with a -1.  */
@@ -1052,15 +1119,15 @@ mn10300_dwarf2_reg_to_regnum (int dwarf2)
     32, 33, 34, 35, 36, 37, 38, 39,
     40, 41, 42, 43, 44, 45, 46, 47,
     48, 49, 50, 51, 52, 53, 54, 55,
-    56, 57, 58, 59, 60, 61, 62, 63
+    56, 57, 58, 59, 60, 61, 62, 63,
+    9
   };
 
   if (dwarf2 < 0
-      || dwarf2 >= ARRAY_SIZE (dwarf2_to_gdb)
-      || dwarf2_to_gdb[dwarf2] == -1)
+      || dwarf2 >= ARRAY_SIZE (dwarf2_to_gdb))
     {
       warning (_("Bogus register number in debug info: %d"), dwarf2);
-      return 0;
+      return -1;
     }
 
   return dwarf2_to_gdb[dwarf2];
@@ -1143,9 +1210,9 @@ mn10300_gdbarch_init (struct gdbarch_info info,
 /* Dump out the mn10300 specific architecture information. */
 
 static void
-mn10300_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+mn10300_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   fprintf_unfiltered (file, "mn10300_dump_tdep: am33_mode = %d\n",
                      tdep->am33_mode);
 }
This page took 0.045356 seconds and 4 git commands to generate.