2003-10-22 Andrew Cagney <cagney@redhat.com>
* target.c: Include "gdb_assert.h" (target_read): Call "target_read_partial", not "target_write_partial". (default_read_partial, default_write_partial): New function. (target_read_partial, target_write_partial): Simplify, assume that there is always a read/write method. (update_current_target, add_target): Always set "to_read_partial" and "to_write_partial". (target_write, target_read): Fail on a zero byte transfer. * Makefile.in (target.o): Update dependencies. * target.h: Update copyright date. (target_object): Fix typo.
This commit is contained in:
parent
f24c5e49d7
commit
0088c768bb
4 changed files with 123 additions and 36 deletions
|
@ -1,3 +1,17 @@
|
|||
2003-10-22 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* target.c: Include "gdb_assert.h" (target_read): Call
|
||||
"target_read_partial", not "target_write_partial".
|
||||
(default_read_partial, default_write_partial): New function.
|
||||
(target_read_partial, target_write_partial): Simplify, assume that
|
||||
there is always a read/write method.
|
||||
(update_current_target, add_target): Always set "to_read_partial"
|
||||
and "to_write_partial".
|
||||
(target_write, target_read): Fail on a zero byte transfer.
|
||||
* Makefile.in (target.o): Update dependencies.
|
||||
* target.h: Update copyright date.
|
||||
(target_object): Fix typo.
|
||||
|
||||
2003-10-22 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* gdbarch.sh (convert_from_func_ptr_addr): Convert to a pure
|
||||
|
|
|
@ -2365,7 +2365,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
|
|||
$(block_h) $(dictionary_h) $(gdb_string_h) $(gdb_stat_h) $(cp_abi_h)
|
||||
target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
|
||||
$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
|
||||
$(gdb_wait_h) $(dcache_h) $(regcache_h)
|
||||
$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h)
|
||||
thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \
|
||||
$(environ_h) $(value_h) $(target_h) $(gdbthread_h) $(command_h) \
|
||||
$(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) $(ui_out_h)
|
||||
|
|
135
gdb/target.c
135
gdb/target.c
|
@ -36,6 +36,7 @@
|
|||
#include "dcache.h"
|
||||
#include <signal.h>
|
||||
#include "regcache.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
static void target_info (char *, int);
|
||||
|
||||
|
@ -71,6 +72,15 @@ static void nosupport_runtime (void);
|
|||
|
||||
static void normal_target_post_startup_inferior (ptid_t ptid);
|
||||
|
||||
static LONGEST default_read_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, void *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
static LONGEST default_write_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, const void *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
|
||||
/* Transfer LEN bytes between target address MEMADDR and GDB address
|
||||
MYADDR. Returns 0 for success, errno code for failure (which
|
||||
includes partial transfers -- if you want a more useful response to
|
||||
|
@ -211,6 +221,10 @@ target_command (char *arg, int from_tty)
|
|||
void
|
||||
add_target (struct target_ops *t)
|
||||
{
|
||||
/* Provide default values for all "must have" methods. */
|
||||
t->to_read_partial = default_read_partial;
|
||||
t->to_write_partial = default_write_partial;
|
||||
|
||||
if (!target_structs)
|
||||
{
|
||||
target_struct_allocsize = DEFAULT_ALLOCSIZE;
|
||||
|
@ -445,8 +459,8 @@ update_current_target (void)
|
|||
#undef INHERIT
|
||||
|
||||
/* Clean up a target struct so it no longer has any zero pointers in
|
||||
it. We default entries, at least to stubs that print error
|
||||
messages. */
|
||||
it. Some entries are defaulted to a method that print an error,
|
||||
others are hard-wired to a standard recursive default. */
|
||||
|
||||
#define de_fault(field, value) \
|
||||
if (!current_target.field) \
|
||||
|
@ -601,6 +615,8 @@ update_current_target (void)
|
|||
de_fault (to_stop,
|
||||
(void (*) (void))
|
||||
target_ignore);
|
||||
current_target.to_read_partial = default_read_partial;
|
||||
current_target.to_write_partial = default_write_partial;
|
||||
de_fault (to_rcmd,
|
||||
(void (*) (char *, struct ui_file *))
|
||||
tcomplain);
|
||||
|
@ -1061,24 +1077,86 @@ target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
|
|||
|
||||
/* More generic transfers. */
|
||||
|
||||
static LONGEST
|
||||
default_read_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, void *buf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
if (object == TARGET_OBJECT_MEMORY
|
||||
&& ops->to_xfer_memory != NULL)
|
||||
/* If available, fall back to the target's "to_xfer_memory"
|
||||
method. */
|
||||
{
|
||||
int xfered;
|
||||
errno = 0;
|
||||
xfered = ops->to_xfer_memory (offset, buf, len, 0/*read*/, NULL, ops);
|
||||
if (xfered > 0)
|
||||
return xfered;
|
||||
else if (xfered == 0 && errno == 0)
|
||||
/* "to_xfer_memory" uses 0, cross checked against ERRNO as one
|
||||
indication of an error. */
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else if (ops->beneath != NULL)
|
||||
return target_read_partial (ops->beneath, object, annex, buf, offset, len);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static LONGEST
|
||||
default_write_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, const void *buf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
if (object == TARGET_OBJECT_MEMORY
|
||||
&& ops->to_xfer_memory != NULL)
|
||||
/* If available, fall back to the target's "to_xfer_memory"
|
||||
method. */
|
||||
{
|
||||
int xfered;
|
||||
errno = 0;
|
||||
{
|
||||
void *buffer = xmalloc (len);
|
||||
struct cleanup *cleanup = make_cleanup (xfree, buffer);
|
||||
memcpy (buffer, buf, len);
|
||||
xfered = ops->to_xfer_memory (offset, buffer, len, 1/*write*/, NULL,
|
||||
ops);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
if (xfered > 0)
|
||||
return xfered;
|
||||
else if (xfered == 0 && errno == 0)
|
||||
/* "to_xfer_memory" uses 0, cross checked against ERRNO as one
|
||||
indication of an error. */
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else if (ops->beneath != NULL)
|
||||
return target_write_partial (ops->beneath, object, annex, buf, offset,
|
||||
len);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Target vector read/write partial wrapper functions.
|
||||
|
||||
NOTE: cagney/2003-10-21: I wonder if having "to_xfer_partial
|
||||
(inbuf, outbuf)", instead of separate read/write methods, make life
|
||||
easier. */
|
||||
|
||||
LONGEST
|
||||
target_read_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, void *buf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
struct target_ops *op;
|
||||
|
||||
/* Find the first target stratum that can handle the request. */
|
||||
for (op = ops;
|
||||
op != NULL && op->to_read_partial == NULL;
|
||||
op = op->beneath)
|
||||
;
|
||||
if (op == NULL)
|
||||
return -1;
|
||||
|
||||
/* Now apply the operation at that level. */
|
||||
return op->to_read_partial (op, object, annex, buf, offset, len);
|
||||
gdb_assert (ops->to_read_partial != NULL);
|
||||
return ops->to_read_partial (ops, object, annex, buf, offset, len);
|
||||
}
|
||||
|
||||
LONGEST
|
||||
|
@ -1087,17 +1165,8 @@ target_write_partial (struct target_ops *ops,
|
|||
const char *annex, const void *buf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
struct target_ops *op;
|
||||
|
||||
/* Find the first target stratum that can handle the request. */
|
||||
for (op = ops;
|
||||
op != NULL && op->to_write_partial == NULL;
|
||||
op = op->beneath)
|
||||
;
|
||||
if (op == NULL)
|
||||
return -1;
|
||||
|
||||
return op->to_write_partial (op, object, annex, buf, offset, len);
|
||||
gdb_assert (ops->to_write_partial != NULL);
|
||||
return ops->to_write_partial (ops, object, annex, buf, offset, len);
|
||||
}
|
||||
|
||||
/* Wrappers to perform the full transfer. */
|
||||
|
@ -1110,12 +1179,13 @@ target_read (struct target_ops *ops,
|
|||
LONGEST xfered = 0;
|
||||
while (xfered < len)
|
||||
{
|
||||
LONGEST xfer = target_write_partial (ops, object, annex,
|
||||
(bfd_byte *) buf + xfered,
|
||||
offset + xfered, len - xfered);
|
||||
LONGEST xfer = target_read_partial (ops, object, annex,
|
||||
(bfd_byte *) buf + xfered,
|
||||
offset + xfered, len - xfered);
|
||||
/* Call an observer, notifying them of the xfer progress? */
|
||||
if (xfer < 0)
|
||||
return xfer;
|
||||
if (xfer <= 0)
|
||||
/* Call memory_error? */
|
||||
return -1;
|
||||
xfered += xfer;
|
||||
QUIT;
|
||||
}
|
||||
|
@ -1135,8 +1205,9 @@ target_write (struct target_ops *ops,
|
|||
(bfd_byte *) buf + xfered,
|
||||
offset + xfered, len - xfered);
|
||||
/* Call an observer, notifying them of the xfer progress? */
|
||||
if (xfer < 0)
|
||||
return xfer;
|
||||
if (xfer <= 0)
|
||||
/* Call memory_error? */
|
||||
return -1;
|
||||
xfered += xfer;
|
||||
QUIT;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* Interface between GDB and target environments, including files and processes
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Cygnus Support. Written by John Gilmore.
|
||||
|
||||
This file is part of GDB.
|
||||
|
@ -221,7 +223,7 @@ enum target_object
|
|||
/* AVR target specific transfer. See "avr-tdep.c" and "remote.c". */
|
||||
TARGET_OBJECT_AVR,
|
||||
/* Transfer up-to LEN bytes of memory starting at OFFSET. */
|
||||
TARGET_OBJECT_MEORY
|
||||
TARGET_OBJECT_MEMORY
|
||||
/* Possible future ojbects: TARGET_OJBECT_FILE, TARGET_OBJECT_PROC,
|
||||
TARGET_OBJECT_AUXV, ... */
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue