mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-30 17:31:13 +08:00
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:
@ -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>
|
2003-10-22 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
* gdbarch.sh (convert_from_func_ptr_addr): Convert to a pure
|
* 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)
|
$(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) \
|
target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
|
||||||
$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_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) \
|
thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \
|
||||||
$(environ_h) $(value_h) $(target_h) $(gdbthread_h) $(command_h) \
|
$(environ_h) $(value_h) $(target_h) $(gdbthread_h) $(command_h) \
|
||||||
$(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) $(ui_out_h)
|
$(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) $(ui_out_h)
|
||||||
|
131
gdb/target.c
131
gdb/target.c
@ -36,6 +36,7 @@
|
|||||||
#include "dcache.h"
|
#include "dcache.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
|
#include "gdb_assert.h"
|
||||||
|
|
||||||
static void target_info (char *, int);
|
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 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
|
/* Transfer LEN bytes between target address MEMADDR and GDB address
|
||||||
MYADDR. Returns 0 for success, errno code for failure (which
|
MYADDR. Returns 0 for success, errno code for failure (which
|
||||||
includes partial transfers -- if you want a more useful response to
|
includes partial transfers -- if you want a more useful response to
|
||||||
@ -211,6 +221,10 @@ target_command (char *arg, int from_tty)
|
|||||||
void
|
void
|
||||||
add_target (struct target_ops *t)
|
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)
|
if (!target_structs)
|
||||||
{
|
{
|
||||||
target_struct_allocsize = DEFAULT_ALLOCSIZE;
|
target_struct_allocsize = DEFAULT_ALLOCSIZE;
|
||||||
@ -445,8 +459,8 @@ update_current_target (void)
|
|||||||
#undef INHERIT
|
#undef INHERIT
|
||||||
|
|
||||||
/* Clean up a target struct so it no longer has any zero pointers in
|
/* 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
|
it. Some entries are defaulted to a method that print an error,
|
||||||
messages. */
|
others are hard-wired to a standard recursive default. */
|
||||||
|
|
||||||
#define de_fault(field, value) \
|
#define de_fault(field, value) \
|
||||||
if (!current_target.field) \
|
if (!current_target.field) \
|
||||||
@ -601,6 +615,8 @@ update_current_target (void)
|
|||||||
de_fault (to_stop,
|
de_fault (to_stop,
|
||||||
(void (*) (void))
|
(void (*) (void))
|
||||||
target_ignore);
|
target_ignore);
|
||||||
|
current_target.to_read_partial = default_read_partial;
|
||||||
|
current_target.to_write_partial = default_write_partial;
|
||||||
de_fault (to_rcmd,
|
de_fault (to_rcmd,
|
||||||
(void (*) (char *, struct ui_file *))
|
(void (*) (char *, struct ui_file *))
|
||||||
tcomplain);
|
tcomplain);
|
||||||
@ -1061,24 +1077,86 @@ target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
|
|||||||
|
|
||||||
/* More generic transfers. */
|
/* 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
|
LONGEST
|
||||||
target_read_partial (struct target_ops *ops,
|
target_read_partial (struct target_ops *ops,
|
||||||
enum target_object object,
|
enum target_object object,
|
||||||
const char *annex, void *buf,
|
const char *annex, void *buf,
|
||||||
ULONGEST offset, LONGEST len)
|
ULONGEST offset, LONGEST len)
|
||||||
{
|
{
|
||||||
struct target_ops *op;
|
gdb_assert (ops->to_read_partial != NULL);
|
||||||
|
return ops->to_read_partial (ops, object, annex, buf, offset, len);
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LONGEST
|
LONGEST
|
||||||
@ -1087,17 +1165,8 @@ target_write_partial (struct target_ops *ops,
|
|||||||
const char *annex, const void *buf,
|
const char *annex, const void *buf,
|
||||||
ULONGEST offset, LONGEST len)
|
ULONGEST offset, LONGEST len)
|
||||||
{
|
{
|
||||||
struct target_ops *op;
|
gdb_assert (ops->to_write_partial != NULL);
|
||||||
|
return ops->to_write_partial (ops, object, annex, buf, offset, len);
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrappers to perform the full transfer. */
|
/* Wrappers to perform the full transfer. */
|
||||||
@ -1110,12 +1179,13 @@ target_read (struct target_ops *ops,
|
|||||||
LONGEST xfered = 0;
|
LONGEST xfered = 0;
|
||||||
while (xfered < len)
|
while (xfered < len)
|
||||||
{
|
{
|
||||||
LONGEST xfer = target_write_partial (ops, object, annex,
|
LONGEST xfer = target_read_partial (ops, object, annex,
|
||||||
(bfd_byte *) buf + xfered,
|
(bfd_byte *) buf + xfered,
|
||||||
offset + xfered, len - xfered);
|
offset + xfered, len - xfered);
|
||||||
/* Call an observer, notifying them of the xfer progress? */
|
/* Call an observer, notifying them of the xfer progress? */
|
||||||
if (xfer < 0)
|
if (xfer <= 0)
|
||||||
return xfer;
|
/* Call memory_error? */
|
||||||
|
return -1;
|
||||||
xfered += xfer;
|
xfered += xfer;
|
||||||
QUIT;
|
QUIT;
|
||||||
}
|
}
|
||||||
@ -1135,8 +1205,9 @@ target_write (struct target_ops *ops,
|
|||||||
(bfd_byte *) buf + xfered,
|
(bfd_byte *) buf + xfered,
|
||||||
offset + xfered, len - xfered);
|
offset + xfered, len - xfered);
|
||||||
/* Call an observer, notifying them of the xfer progress? */
|
/* Call an observer, notifying them of the xfer progress? */
|
||||||
if (xfer < 0)
|
if (xfer <= 0)
|
||||||
return xfer;
|
/* Call memory_error? */
|
||||||
|
return -1;
|
||||||
xfered += xfer;
|
xfered += xfer;
|
||||||
QUIT;
|
QUIT;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/* Interface between GDB and target environments, including files and processes
|
/* 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.
|
Contributed by Cygnus Support. Written by John Gilmore.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
@ -221,7 +223,7 @@ enum target_object
|
|||||||
/* AVR target specific transfer. See "avr-tdep.c" and "remote.c". */
|
/* AVR target specific transfer. See "avr-tdep.c" and "remote.c". */
|
||||||
TARGET_OBJECT_AVR,
|
TARGET_OBJECT_AVR,
|
||||||
/* Transfer up-to LEN bytes of memory starting at OFFSET. */
|
/* 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,
|
/* Possible future ojbects: TARGET_OJBECT_FILE, TARGET_OBJECT_PROC,
|
||||||
TARGET_OBJECT_AUXV, ... */
|
TARGET_OBJECT_AUXV, ... */
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user