#include "symfile.h"
#include "objfiles.h"
#include "gdb_wait.h"
+#include "dcache.h"
#include <signal.h>
extern int errno;
static void setup_target_debug (void);
+DCACHE *target_dcache;
+
/* The user just typed 'target' without the name of a target. */
/* ARGSUSED */
void
target_load (char *arg, int from_tty)
{
+ dcache_invalidate (target_dcache);
(*current_target.to_load) (arg, from_tty);
}
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)
{
- int curlen;
int res;
+ int done = 0;
struct target_ops *t;
struct target_stack_item *item;
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, ¤t_target);
- if (res == len)
- return 0;
-
- if (res > 0)
- goto bump;
- /* If res <= 0 then we call it again in the loop. Ah well. */
- 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, t);
if (res > 0)
break; /* Handled all or part of xfer */
if (t->to_has_all_memory)
break;
}
+ 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;
+
+ /* Zero length requests are ok and require no work. */
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ while (len > 0)
+ {
+ res = dcache_xfer_memory(target_dcache, memaddr, myaddr, len, write);
if (res <= 0)
{
/* If this address is for nonexistent memory,
else
return errno;
}
- bump:
+
memaddr += res;
- myaddr += res;
- len -= 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;
/* Zero length requests are ok and require no work. */
if (len == 0)
return 0;
}
- /* The quick case is that the top target does it all. */
- res = current_target.to_xfer_memory (memaddr, buf, len, write_p, ¤t_target);
- if (res > 0)
+ res = dcache_xfer_memory (target_dcache, memaddr, myaddr, len, write_p);
+ if (res <= 0)
{
- *err = 0;
- return res;
- }
-
- /* xfer memory doesn't always reliably set errno. */
- errno = 0;
+ if (errno != 0)
+ *err = errno;
+ else
+ *err = EIO;
- /* Try all levels of the target stack to see one can handle it. */
- for (item = target_stack; item; item = item->next)
- {
- t = item->target_ops;
- if (!t->to_has_memory)
- continue;
- res = t->to_xfer_memory (memaddr, buf, len, write_p, t);
- if (res > 0)
- {
- /* Handled all or part of xfer */
- *err = 0;
- return res;
- }
- if (t->to_has_all_memory)
- break;
+ return -1;
}
- /* Total failure. Return error. */
- if (errno != 0)
- {
- *err = errno;
- return -1;
- }
- *err = EIO;
- return -1;
+ *err = 0;
+ return res;
}
int
using hit counts. So don't clear them if we're counting hits. */
if (!show_breakpoint_hit_counts)
breakpoint_clear_ignore_counts ();
+
+ if (detach_hook)
+ detach_hook ();
}
\f
/* This table must match in order and size the signals in enum target_signal
{"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 */
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");
}
if (retsig >= SIGRTMIN && retsig <= SIGRTMAX)
return retsig;
}
+ else if (oursig == TARGET_SIGNAL_REALTIME_64)
+ return 64;
#endif
*oursig_ok = 0;
return 0;
signal. The idea is to keep these circumstances limited so that
users (and scripts) develop portable habits. For comparison,
POSIX.2 `kill' requires that 1,2,3,6,9,14, and 15 work (and using a
- numeric signal at all is obscelescent. We are slightly more
+ numeric signal at all is obsolescent. We are slightly more
lenient and allow 1-15 which should match host signal numbers on
most systems. Use of symbolic signal names is strongly encouraged. */
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 ();
}