* target.c (memory_xfer_partial): Accesses to unmapped overlay
[deliverable/binutils-gdb.git] / gdb / target.c
index 349f1b6cb328a44ba47275172fa384f630dbdb91..92a4d6ac2c98c51f335ca4d8e49e861c08470f04 100644 (file)
@@ -1,7 +1,7 @@
 /* Select target systems and architectures at runtime for GDB.
 
-   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
@@ -106,11 +106,11 @@ static void debug_to_resume (ptid_t, int, enum target_signal);
 
 static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
 
-static void debug_to_fetch_registers (int);
+static void debug_to_fetch_registers (struct regcache *, int);
 
-static void debug_to_store_registers (int);
+static void debug_to_store_registers (struct regcache *, int);
 
-static void debug_to_prepare_to_store (void);
+static void debug_to_prepare_to_store (struct regcache *);
 
 static void debug_to_files_info (struct target_ops *);
 
@@ -379,7 +379,7 @@ update_current_target (void)
 {
   struct target_ops *t;
 
-  /* First, reset curren'ts contents.  */
+  /* First, reset current's contents.  */
   memset (&current_target, 0, sizeof (current_target));
 
 #define INHERIT(FIELD, TARGET) \
@@ -413,6 +413,7 @@ update_current_target (void)
       INHERIT (to_remove_watchpoint, t);
       INHERIT (to_stopped_data_address, t);
       INHERIT (to_stopped_by_watchpoint, t);
+      INHERIT (to_have_steppable_watchpoint, t);
       INHERIT (to_have_continuable_watchpoint, t);
       INHERIT (to_region_ok_for_hw_watchpoint, t);
       INHERIT (to_terminal_init, t);
@@ -502,13 +503,13 @@ update_current_target (void)
            (ptid_t (*) (ptid_t, struct target_waitstatus *))
            noprocess);
   de_fault (to_fetch_registers,
-           (void (*) (int))
+           (void (*) (struct regcache *, int))
            target_ignore);
   de_fault (to_store_registers,
-           (void (*) (int))
+           (void (*) (struct regcache *, int))
            noprocess);
   de_fault (to_prepare_to_store,
-           (void (*) (void))
+           (void (*) (struct regcache *))
            noprocess);
   de_fault (deprecated_xfer_memory,
            (int (*) (CORE_ADDR, gdb_byte *, int, int, struct mem_attrib *, struct target_ops *))
@@ -1016,6 +1017,14 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
        return xfer_memory (memaddr, readbuf, len, 0, NULL, ops);
     }
 
+  /* Likewise for accesses to unmapped overlay sections.  */
+  if (readbuf != NULL && overlay_debugging)
+    {
+      asection *section = find_pc_overlay (memaddr);
+      if (pc_in_unmapped_range (memaddr, section))
+       return xfer_memory (memaddr, readbuf, len, 0, NULL, ops);
+    }
+
   /* Try GDB's internal data cache.  */
   region = lookup_mem_region (memaddr);
   /* region->hi == 0 means there's no upper bound.  */
@@ -1083,6 +1092,11 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
       if (res > 0)
        return res;
 
+      /* We want to continue past core files to executables, but not
+        past a running target's memory.  */
+      if (ops->to_has_all_memory)
+       return res;
+
       ops = ops->beneath;
     }
   while (ops != NULL);
@@ -1252,7 +1266,8 @@ target_flash_erase (ULONGEST address, LONGEST length)
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
                                 paddr (address), phex (length, 0));
-         return t->to_flash_erase (t, address, length);
+         t->to_flash_erase (t, address, length);
+         return;
        }
 
   tcomplain ();
@@ -1268,7 +1283,8 @@ target_flash_done (void)
        {
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
-         return t->to_flash_done (t);
+         t->to_flash_done (t);
+         return;
        }
 
   tcomplain ();
@@ -1967,19 +1983,12 @@ generic_mourn_inferior (void)
     deprecated_detach_hook ();
 }
 \f
-/* Helper function for child_wait and the Lynx derivatives of child_wait.
+/* Helper function for child_wait and the derivatives of child_wait.
    HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
    translation of that in OURSTATUS.  */
 void
 store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
 {
-#ifdef CHILD_SPECIAL_WAITSTATUS
-  /* CHILD_SPECIAL_WAITSTATUS should return nonzero and set *OURSTATUS
-     if it wants to deal with hoststatus.  */
-  if (CHILD_SPECIAL_WAITSTATUS (ourstatus, hoststatus))
-    return;
-#endif
-
   if (WIFEXITED (hoststatus))
     {
       ourstatus->kind = TARGET_WAITKIND_EXITED;
@@ -2154,53 +2163,57 @@ debug_to_wait (ptid_t ptid, struct target_waitstatus *status)
 }
 
 static void
-debug_print_register (const char * func, int regno)
+debug_print_register (const char * func,
+                     struct regcache *regcache, int regno)
 {
   fprintf_unfiltered (gdb_stdlog, "%s ", func);
-  if (regno >= 0 && regno < NUM_REGS + NUM_PSEUDO_REGS
-      && REGISTER_NAME (regno) != NULL && REGISTER_NAME (regno)[0] != '\0')
-    fprintf_unfiltered (gdb_stdlog, "(%s)", REGISTER_NAME (regno));
+  if (regno >= 0 && regno < gdbarch_num_regs (current_gdbarch)
+                           + gdbarch_num_pseudo_regs (current_gdbarch)
+      && gdbarch_register_name (current_gdbarch, regno) != NULL
+      && gdbarch_register_name (current_gdbarch, regno)[0] != '\0')
+    fprintf_unfiltered (gdb_stdlog, "(%s)", gdbarch_register_name
+                                             (current_gdbarch, regno));
   else
     fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
   if (regno >= 0)
     {
-      int i;
+      int i, size = register_size (current_gdbarch, regno);
       unsigned char buf[MAX_REGISTER_SIZE];
-      deprecated_read_register_gen (regno, buf);
+      regcache_cooked_read (regcache, regno, buf);
       fprintf_unfiltered (gdb_stdlog, " = ");
-      for (i = 0; i < register_size (current_gdbarch, regno); i++)
+      for (i = 0; i < size; i++)
        {
          fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
        }
-      if (register_size (current_gdbarch, regno) <= sizeof (LONGEST))
+      if (size <= sizeof (LONGEST))
        {
+         ULONGEST val = extract_unsigned_integer (buf, size);
          fprintf_unfiltered (gdb_stdlog, " 0x%s %s",
-                             paddr_nz (read_register (regno)),
-                             paddr_d (read_register (regno)));
+                             paddr_nz (val), paddr_d (val));
        }
     }
   fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
 static void
-debug_to_fetch_registers (int regno)
+debug_to_fetch_registers (struct regcache *regcache, int regno)
 {
-  debug_target.to_fetch_registers (regno);
-  debug_print_register ("target_fetch_registers", regno);
+  debug_target.to_fetch_registers (regcache, regno);
+  debug_print_register ("target_fetch_registers", regcache, regno);
 }
 
 static void
-debug_to_store_registers (int regno)
+debug_to_store_registers (struct regcache *regcache, int regno)
 {
-  debug_target.to_store_registers (regno);
-  debug_print_register ("target_store_registers", regno);
+  debug_target.to_store_registers (regcache, regno);
+  debug_print_register ("target_store_registers", regcache, regno);
   fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
 static void
-debug_to_prepare_to_store (void)
+debug_to_prepare_to_store (struct regcache *regcache)
 {
-  debug_target.to_prepare_to_store ();
+  debug_target.to_prepare_to_store (regcache);
 
   fprintf_unfiltered (gdb_stdlog, "target_prepare_to_store ()\n");
 }
@@ -2386,10 +2399,10 @@ debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type)
 {
   int retval;
 
-  retval = debug_target.to_insert_watchpoint (addr, len, type);
+  retval = debug_target.to_remove_watchpoint (addr, len, type);
 
   fprintf_unfiltered (gdb_stdlog,
-                     "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n",
+                     "target_remove_watchpoint (0x%lx, %d, %d) = %ld\n",
                      (unsigned long) addr, len, type, (unsigned long) retval);
   return retval;
 }
@@ -2769,6 +2782,21 @@ do_monitor_command (char *cmd,
   target_rcmd (cmd, gdb_stdtarg);
 }
 
+/* Print the name of each layers of our target stack.  */
+
+static void
+maintenance_print_target_stack (char *cmd, int from_tty)
+{
+  struct target_ops *t;
+
+  printf_filtered (_("The current target stack is:\n"));
+
+  for (t = target_stack; t != NULL; t = t->beneath)
+    {
+      printf_filtered ("  - %s (%s)\n", t->to_shortname, t->to_longname);
+    }
+}
+
 void
 initialize_targets (void)
 {
@@ -2802,5 +2830,9 @@ result in significant performance improvement for remote targets."),
   add_com ("monitor", class_obscure, do_monitor_command,
           _("Send a command to the remote monitor (remote targets only)."));
 
+  add_cmd ("target-stack", class_maintenance, maintenance_print_target_stack,
+           _("Print the name of each layer of the internal target stack."),
+           &maintenanceprintlist);
+
   target_dcache = dcache_init ();
 }
This page took 0.027807 seconds and 4 git commands to generate.