* symfile.c (compare_psymbols, compare_symbols): Declare using
[deliverable/binutils-gdb.git] / gdb / target.c
index 4f4f8b042f2230e61710e8d6bf997fd84d9db4ed..cdccd7f65aed8088170acacee19f3bc04c61d19e 100644 (file)
@@ -1,5 +1,6 @@
 /* Select target systems and architectures at runtime for GDB.
-   Copyright 1990, 1992-1995, 1998-2000 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
    This file is part of GDB.
@@ -21,7 +22,6 @@
 
 #include "defs.h"
 #include <errno.h>
-#include <ctype.h>
 #include "gdb_string.h"
 #include "target.h"
 #include "gdbcmd.h"
@@ -31,7 +31,9 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "gdb_wait.h"
+#include "dcache.h"
 #include <signal.h>
+#include "regcache.h"
 
 extern int errno;
 
@@ -69,7 +71,7 @@ static void update_current_target (void);
 
 static void nosupport_runtime (void);
 
-static void normal_target_post_startup_inferior (int pid);
+static void normal_target_post_startup_inferior (ptid_t ptid);
 
 /* Transfer LEN bytes between target address MEMADDR and GDB address
    MYADDR.  Returns 0 for success, errno code for failure (which
@@ -90,9 +92,9 @@ static void debug_to_attach (char *, int);
 
 static void debug_to_detach (char *, int);
 
-static void debug_to_resume (int, int, enum target_signal);
+static void debug_to_resume (ptid_t, int, enum target_signal);
 
-static int debug_to_wait (int, struct target_waitstatus *);
+static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
 
 static void debug_to_fetch_registers (int);
 
@@ -101,7 +103,8 @@ static void debug_to_store_registers (int);
 static void debug_to_prepare_to_store (void);
 
 static int
-debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
+debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *, 
+                     struct target_ops *);
 
 static void debug_to_files_info (struct target_ops *);
 
@@ -131,9 +134,9 @@ static void debug_to_mourn_inferior (void);
 
 static int debug_to_can_run (void);
 
-static void debug_to_notice_signals (int);
+static void debug_to_notice_signals (ptid_t);
 
-static int debug_to_thread_alive (int);
+static int debug_to_thread_alive (ptid_t);
 
 static void debug_to_stop (void);
 
@@ -177,6 +180,8 @@ static int targetdebug = 0;
 
 static void setup_target_debug (void);
 
+DCACHE *target_dcache;
+
 /* The user just typed 'target' without the name of a target.  */
 
 /* ARGSUSED */
@@ -229,6 +234,7 @@ target_ignore (void)
 void
 target_load (char *arg, int from_tty)
 {
+  dcache_invalidate (target_dcache);
   (*current_target.to_load) (arg, from_tty);
 }
 
@@ -265,7 +271,7 @@ nosymbol (char *name, CORE_ADDR *addrp)
 static void
 nosupport_runtime (void)
 {
-  if (!inferior_pid)
+  if (ptid_equal (inferior_ptid, null_ptid))
     noprocess ();
   else
     error ("No run-time support for this");
@@ -357,13 +363,13 @@ cleanup_target (struct target_ops *t)
            (void (*) (int, char *, int)) 
            target_ignore);
   de_fault (to_resume, 
-           (void (*) (int, int, enum target_signal)) 
+           (void (*) (ptid_t, int, enum target_signal)) 
            noprocess);
   de_fault (to_wait, 
-           (int (*) (int, struct target_waitstatus *)) 
+           (ptid_t (*) (ptid_t, struct target_waitstatus *)) 
            noprocess);
   de_fault (to_post_wait, 
-           (void (*) (int, int)) 
+           (void (*) (ptid_t, int)) 
            target_ignore);
   de_fault (to_fetch_registers, 
            (void (*) (int)) 
@@ -375,7 +381,7 @@ cleanup_target (struct target_ops *t)
            (void (*) (void)) 
            noprocess);
   de_fault (to_xfer_memory, 
-           (int (*) (CORE_ADDR, char *, int, int, struct target_ops *)) 
+           (int (*) (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *)) 
            nomemory);
   de_fault (to_files_info, 
            (void (*) (struct target_ops *)) 
@@ -410,7 +416,7 @@ cleanup_target (struct target_ops *t)
   de_fault (to_create_inferior, 
            maybe_kill_then_create_inferior);
   de_fault (to_post_startup_inferior, 
-           (void (*) (int)) 
+           (void (*) (ptid_t)) 
            target_ignore);
   de_fault (to_acknowledge_created_inferior, 
            (void (*) (int)) 
@@ -468,10 +474,10 @@ cleanup_target (struct target_ops *t)
   de_fault (to_can_run, 
            return_zero);
   de_fault (to_notice_signals, 
-           (void (*) (int)) 
+           (void (*) (ptid_t)) 
            target_ignore);
   de_fault (to_thread_alive, 
-           (int (*) (int)) 
+           (int (*) (ptid_t)) 
            return_zero);
   de_fault (to_find_new_threads, 
            (void (*) (void)) 
@@ -497,9 +503,6 @@ cleanup_target (struct target_ops *t)
   de_fault (to_pid_to_exec_file, 
            (char *(*) (int)) 
            return_zero);
-  de_fault (to_core_file_to_sym_file, 
-           (char *(*) (char *)) 
-           return_zero);
   de_fault (to_can_async_p, 
            (int (*) (void)) 
            return_zero);
@@ -593,7 +596,6 @@ update_current_target (void)
       INHERIT (to_enable_exception_callback, t);
       INHERIT (to_get_current_exception_event, t);
       INHERIT (to_pid_to_exec_file, t);
-      INHERIT (to_core_file_to_sym_file, t);
       INHERIT (to_stratum, t);
       INHERIT (DONT_USE, t);
       INHERIT (to_has_all_memory, t);
@@ -636,7 +638,7 @@ push_target (struct target_ops *t)
       fprintf_unfiltered (gdb_stderr,
                          "Magic number of %s target struct wrong\n",
                          t->to_shortname);
-      abort ();
+      internal_error (__FILE__, __LINE__, "failed internal consistency check");
     }
 
   /* Find the proper stratum to install this target in. */
@@ -660,7 +662,7 @@ push_target (struct target_ops *t)
        else
          target_stack = cur->next;     /* Unchain first on list */
        tmp = cur->next;
-       free (cur);
+       xfree (cur);
        cur = tmp;
       }
 
@@ -714,7 +716,7 @@ unpush_target (struct target_ops *t)
   else
     prev->next = cur->next;
 
-  free (cur);                  /* Release the target_stack_item */
+  xfree (cur);                 /* Release the target_stack_item */
 
   update_current_target ();
   cleanup_target (&current_target);
@@ -732,7 +734,7 @@ pop_target (void)
   fprintf_unfiltered (gdb_stderr,
                      "pop_target couldn't find target %s\n",
                      current_target.to_shortname);
-  abort ();
+  internal_error (__FILE__, __LINE__, "failed internal consistency check");
 }
 
 #undef MIN
@@ -833,21 +835,17 @@ target_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
   return target_xfer_memory (memaddr, myaddr, len, 1);
 }
 
-/* Move memory to or from the targets.  Iterate until all of it has
-   been moved, if necessary.  The top target gets priority; anything
-   it doesn't want, is offered to the next one down, etc.  Note the
-   business with curlen:  if an early target says "no, but I have a
-   boundary overlapping this xfer" then we shorten what we offer to
-   the subsequent targets so the early guy will get a chance at the
-   tail before the subsequent ones do. 
+/* Move memory to or from the targets.  The top target gets priority;
+   if it cannot handle it, it is offered to the next one down, etc.
 
-   Result is 0 or errno value.  */
+   Result is -1 on error, or the number of bytes transfered.  */
 
-static int
-target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
+int
+do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+               struct mem_attrib *attrib)
 {
-  int curlen;
   int res;
+  int done = 0;
   struct target_ops *t;
   struct target_stack_item *item;
 
@@ -859,26 +857,20 @@ target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
      0.  */
   errno = 0;
 
-  /* The quick case is that the top target does it all.  */
+  /* The quick case is that the top target can handle the transfer.  */
   res = current_target.to_xfer_memory
-    (memaddr, myaddr, len, write, &current_target);
-  if (res == len)
-    return 0;
-
-  if (res > 0)
-    goto bump;
-  /* If res <= 0 then we call it again in the loop.  Ah well.  */
+    (memaddr, myaddr, len, write, attrib, &current_target);
 
-  for (; len > 0;)
+  /* If res <= 0 then we call it again in the loop.  Ah well. */
+  if (res <= 0)
     {
-      curlen = len;            /* Want to do it all */
       for (item = target_stack; item; item = item->next)
        {
          t = item->target_ops;
          if (!t->to_has_memory)
            continue;
 
-         res = t->to_xfer_memory (memaddr, myaddr, curlen, write, t);
+         res = t->to_xfer_memory (memaddr, myaddr, len, write, attrib, t);
          if (res > 0)
            break;              /* Handled all or part of xfer */
          if (t->to_has_all_memory)
@@ -886,36 +878,96 @@ target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
        }
 
       if (res <= 0)
+       return -1;
+    }
+
+  return res;
+}
+
+
+/* Perform a memory transfer.  Iterate until the entire region has
+   been transfered.
+
+   Result is 0 or errno value.  */
+
+static int
+target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
+{
+  int res;
+  int reg_len;
+  struct mem_region *region;
+
+  /* Zero length requests are ok and require no work.  */
+  if (len == 0)
+    {
+      return 0;
+    }
+
+  while (len > 0)
+    {
+      region = lookup_mem_region(memaddr);
+      if (memaddr + len < region->hi)
+       reg_len = len;
+      else
+       reg_len = region->hi - memaddr;
+
+      switch (region->attrib.mode)
        {
-         /* If this address is for nonexistent memory,
-            read zeros if reading, or do nothing if writing.  Return error. */
+       case MEM_RO:
+         if (write)
+           return EIO;
+         break;
+         
+       case MEM_WO:
          if (!write)
-           memset (myaddr, 0, len);
-         if (errno == 0)
            return EIO;
+         break;
+       }
+
+      while (reg_len > 0)
+       {
+         if (region->attrib.cache)
+           res = dcache_xfer_memory(target_dcache, memaddr, myaddr,
+                                    reg_len, write);
          else
-           return errno;
+           res = do_xfer_memory(memaddr, myaddr, reg_len, write,
+                                &region->attrib);
+             
+         if (res <= 0)
+           {
+             /* If this address is for nonexistent memory, read zeros
+                if reading, or do nothing if writing.  Return
+                error. */
+             if (!write)
+               memset (myaddr, 0, len);
+             if (errno == 0)
+               return EIO;
+             else
+               return errno;
+           }
+
+         memaddr += res;
+         myaddr  += res;
+         len     -= res;
+         reg_len -= res;
        }
-    bump:
-      memaddr += res;
-      myaddr += res;
-      len -= res;
     }
+  
   return 0;                    /* We managed to cover it all somehow. */
 }
 
 
-/* Perform a partial memory transfer.  */
+/* Perform a partial memory transfer.
+
+   Result is -1 on error, or the number of bytes transfered.  */
 
 static int
-target_xfer_memory_partial (CORE_ADDR memaddr, char *buf, int len,
+target_xfer_memory_partial (CORE_ADDR memaddr, char *myaddr, int len,
                            int write_p, int *err)
 {
   int res;
-  int err_res;
-  int len_res;
-  struct target_ops *t;
-  struct target_stack_item *item;
+  int reg_len;
+  struct mem_region *region;
 
   /* Zero length requests are ok and require no work.  */
   if (len == 0)
@@ -924,42 +976,50 @@ target_xfer_memory_partial (CORE_ADDR memaddr, char *buf, int len,
       return 0;
     }
 
-  /* The quick case is that the top target does it all.  */
-  res = current_target.to_xfer_memory (memaddr, buf, len, write_p, &current_target);
-  if (res > 0)
-    {
-      *err = 0;
-      return res;
-    }
-
-  /* xfer memory doesn't always reliably set errno. */
-  errno = 0;
+  region = lookup_mem_region(memaddr);
+  if (memaddr + len < region->hi)
+    reg_len = len;
+  else
+    reg_len = region->hi - memaddr;
 
-  /* Try all levels of the target stack to see one can handle it. */
-  for (item = target_stack; item; item = item->next)
+  switch (region->attrib.mode)
     {
-      t = item->target_ops;
-      if (!t->to_has_memory)
-       continue;
-      res = t->to_xfer_memory (memaddr, buf, len, write_p, t);
-      if (res > 0)
+    case MEM_RO:
+      if (write_p)
        {
-         /* Handled all or part of xfer */
-         *err = 0;
-         return res;
+         *err = EIO;
+         return -1;
        }
-      if (t->to_has_all_memory)
-       break;
+      break;
+
+    case MEM_WO:
+      if (write_p)
+       {
+         *err = EIO;
+         return -1;
+       }
+      break;
     }
 
-  /* Total failure.  Return error. */
-  if (errno != 0)
+  if (region->attrib.cache)
+    res = dcache_xfer_memory (target_dcache, memaddr, myaddr,
+                             reg_len, write_p);
+  else
+    res = do_xfer_memory (memaddr, myaddr, reg_len, write_p,
+                         &region->attrib);
+      
+  if (res <= 0)
     {
-      *err = errno;
-      return -1;
+      if (errno != 0)
+       *err = errno;
+      else
+       *err = EIO;
+
+        return -1;
     }
-  *err = EIO;
-  return -1;
+
+  *err = 0;
+  return res;
 }
 
 int
@@ -1316,7 +1376,7 @@ generic_mourn_inferior (void)
 {
   extern int show_breakpoint_hit_counts;
 
-  inferior_pid = 0;
+  inferior_ptid = null_ptid;
   attach_flag = 0;
   breakpoint_init_inferior (inf_exited);
   registers_changed ();
@@ -1426,6 +1486,7 @@ static struct {
   {"SIG63", "Real-time event 63"},
   {"SIGCANCEL", "LWP internal signal"},
   {"SIG32", "Real-time event 32"},
+  {"SIG64", "Real-time event 64"},
 
 #if defined(MACH) || defined(__MACH__)
   /* Mach exceptions */
@@ -1740,6 +1801,8 @@ target_signal_from_host (int hostsig)
       if (33 <= hostsig && hostsig <= 63)
        return (enum target_signal)
          (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33);
+      else if (hostsig == 64)
+       return TARGET_SIGNAL_REALTIME_64;
       else
        error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal");
     }
@@ -2011,6 +2074,8 @@ do_target_signal_to_host (enum target_signal oursig,
          if (retsig >= SIGRTMIN && retsig <= SIGRTMAX)
            return retsig;
        }
+      else if (oursig == TARGET_SIGNAL_REALTIME_64)
+       return 64;
 #endif
       *oursig_ok = 0;
       return 0;
@@ -2097,15 +2162,11 @@ int target_activity_fd;
    buffer.  */
 
 char *
-normal_pid_to_str (int pid)
+normal_pid_to_str (ptid_t ptid)
 {
   static char buf[30];
 
-  if (STREQ (current_target.to_shortname, "remote"))
-    sprintf (buf, "thread %d", pid);
-  else
-    sprintf (buf, "process %d", pid);
-
+  sprintf (buf, "process %d", PIDGET (ptid));
   return buf;
 }
 
@@ -2122,7 +2183,7 @@ normal_pid_to_str (int pid)
    target_acknowledge_forked_child.
  */
 static void
-normal_target_post_startup_inferior (int pid)
+normal_target_post_startup_inferior (ptid_t ptid)
 {
   /* This space intentionally left blank. */
 }
@@ -2209,24 +2270,25 @@ debug_to_require_detach (int pid, char *args, int from_tty)
 }
 
 static void
-debug_to_resume (int pid, int step, enum target_signal siggnal)
+debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
-  debug_target.to_resume (pid, step, siggnal);
+  debug_target.to_resume (ptid, step, siggnal);
 
-  fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", pid,
+  fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", PIDGET (ptid),
                      step ? "step" : "continue",
                      target_signal_to_name (siggnal));
 }
 
-static int
-debug_to_wait (int pid, struct target_waitstatus *status)
+static ptid_t
+debug_to_wait (ptid_t ptid, struct target_waitstatus *status)
 {
-  int retval;
+  ptid_t retval;
 
-  retval = debug_target.to_wait (pid, status);
+  retval = debug_target.to_wait (ptid, status);
 
   fprintf_unfiltered (gdb_stdlog,
-                     "target_wait (%d, status) = %d,   ", pid, retval);
+                     "target_wait (%d, status) = %d,   ", PIDGET (ptid),
+                     PIDGET (retval));
   fprintf_unfiltered (gdb_stdlog, "status->kind = ");
   switch (status->kind)
     {
@@ -2266,12 +2328,12 @@ debug_to_wait (int pid, struct target_waitstatus *status)
 }
 
 static void
-debug_to_post_wait (int pid, int status)
+debug_to_post_wait (ptid_t ptid, int status)
 {
-  debug_target.to_post_wait (pid, status);
+  debug_target.to_post_wait (ptid, status);
 
   fprintf_unfiltered (gdb_stdlog, "target_post_wait (%d, %d)\n",
-                     pid, status);
+                     PIDGET (ptid), status);
 }
 
 static void
@@ -2312,11 +2374,13 @@ debug_to_prepare_to_store (void)
 
 static int
 debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+                     struct mem_attrib *attrib,
                      struct target_ops *target)
 {
   int retval;
 
-  retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target);
+  retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write,
+                                       attrib, target);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
@@ -2458,12 +2522,12 @@ debug_to_create_inferior (char *exec_file, char *args, char **env)
 }
 
 static void
-debug_to_post_startup_inferior (int pid)
+debug_to_post_startup_inferior (ptid_t ptid)
 {
-  debug_target.to_post_startup_inferior (pid);
+  debug_target.to_post_startup_inferior (ptid);
 
   fprintf_unfiltered (gdb_stdlog, "target_post_startup_inferior (%d)\n",
-                     pid);
+                     PIDGET (ptid));
 }
 
 static void
@@ -2713,22 +2777,23 @@ debug_to_can_run (void)
 }
 
 static void
-debug_to_notice_signals (int pid)
+debug_to_notice_signals (ptid_t ptid)
 {
-  debug_target.to_notice_signals (pid);
+  debug_target.to_notice_signals (ptid);
 
-  fprintf_unfiltered (gdb_stdlog, "target_notice_signals (%d)\n", pid);
+  fprintf_unfiltered (gdb_stdlog, "target_notice_signals (%d)\n",
+                      PIDGET (ptid));
 }
 
 static int
-debug_to_thread_alive (int pid)
+debug_to_thread_alive (ptid_t ptid)
 {
   int retval;
 
-  retval = debug_target.to_thread_alive (pid);
+  retval = debug_target.to_thread_alive (ptid);
 
   fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
-                     pid, retval);
+                     PIDGET (ptid), retval);
 
   return retval;
 }
@@ -2802,19 +2867,6 @@ debug_to_pid_to_exec_file (int pid)
   return exec_file;
 }
 
-static char *
-debug_to_core_file_to_sym_file (char *core)
-{
-  char *sym_file;
-
-  sym_file = debug_target.to_core_file_to_sym_file (core);
-
-  fprintf_unfiltered (gdb_stdlog, "target_core_file_to_sym_file (%s) = %s\n",
-                     core, sym_file);
-
-  return sym_file;
-}
-
 static void
 setup_target_debug (void)
 {
@@ -2875,7 +2927,6 @@ setup_target_debug (void)
   current_target.to_enable_exception_callback = debug_to_enable_exception_callback;
   current_target.to_get_current_exception_event = debug_to_get_current_exception_event;
   current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
-  current_target.to_core_file_to_sym_file = debug_to_core_file_to_sym_file;
 
 }
 \f
@@ -2920,6 +2971,8 @@ When non-zero, target debugging is enabled.", &setdebuglist),
   add_com ("monitor", class_obscure, do_monitor_command,
           "Send a command to the remote monitor (remote targets only).");
 
+  target_dcache = dcache_init();
+
   if (!STREQ (signals[TARGET_SIGNAL_LAST].string, "TARGET_SIGNAL_MAGIC"))
-    abort ();
+    internal_error (__FILE__, __LINE__, "failed internal consistency check");
 }
This page took 0.049589 seconds and 4 git commands to generate.