* target.c (target_read): Stop if target_read_partial returns 0
when some bytes have already been read. (target_write): Likewise for target_write_partial. (target_read_partial, target_write_partial): Make static. (target_read_alloc): New. * target.h: Doc fixes. (target_read_partial, target_write_partial): Delete prototypes. (target_read_alloc): New prototype. * auxv.c (target_auxv_read): Delete. (target_auxv_search, fprint_target_auxv): Use target_read_alloc. * auxv.h (target_auxv_read): Delete prototype. * avr-tdep.c (avr_io_reg_read_command): Use target_read_alloc. * ia64-tdep.c (getunwind_table, get_kernel_table): Likewise. * linux-nat.c (linux_nat_make_corefile_notes): Likewise. * procfs.c (procfs_make_note_section): Likewise. * remote.c (remote_xfer_partial): Don't loop here. * sparc-tdep.c (sparc_fetch_wcookie): Use target_read.
This commit is contained in:
parent
edfb1a2648
commit
13547ab600
11 changed files with 206 additions and 165 deletions
|
@ -1,3 +1,24 @@
|
|||
2006-07-12 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* target.c (target_read): Stop if target_read_partial returns 0
|
||||
when some bytes have already been read.
|
||||
(target_write): Likewise for target_write_partial.
|
||||
(target_read_partial, target_write_partial): Make static.
|
||||
(target_read_alloc): New.
|
||||
* target.h: Doc fixes.
|
||||
(target_read_partial, target_write_partial): Delete prototypes.
|
||||
(target_read_alloc): New prototype.
|
||||
|
||||
* auxv.c (target_auxv_read): Delete.
|
||||
(target_auxv_search, fprint_target_auxv): Use target_read_alloc.
|
||||
* auxv.h (target_auxv_read): Delete prototype.
|
||||
* avr-tdep.c (avr_io_reg_read_command): Use target_read_alloc.
|
||||
* ia64-tdep.c (getunwind_table, get_kernel_table): Likewise.
|
||||
* linux-nat.c (linux_nat_make_corefile_notes): Likewise.
|
||||
* procfs.c (procfs_make_note_section): Likewise.
|
||||
* remote.c (remote_xfer_partial): Don't loop here.
|
||||
* sparc-tdep.c (sparc_fetch_wcookie): Use target_read.
|
||||
|
||||
2006-07-12 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* arm-linux-tdep.c: Doc fixes.
|
||||
|
|
44
gdb/auxv.c
44
gdb/auxv.c
|
@ -1,6 +1,6 @@
|
|||
/* Auxiliary vector support for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
@ -76,43 +76,6 @@ procfs_xfer_auxv (struct target_ops *ops,
|
|||
return n;
|
||||
}
|
||||
|
||||
/* Read all the auxv data into a contiguous xmalloc'd buffer,
|
||||
stored in *DATA. Return the size in bytes of this data.
|
||||
If zero, there is no data and *DATA is null.
|
||||
if < 0, there was an error and *DATA is null. */
|
||||
LONGEST
|
||||
target_auxv_read (struct target_ops *ops, gdb_byte **data)
|
||||
{
|
||||
size_t auxv_alloc = 512, auxv_pos = 0;
|
||||
gdb_byte *auxv = xmalloc (auxv_alloc);
|
||||
int n;
|
||||
|
||||
while (1)
|
||||
{
|
||||
n = target_read_partial (ops, TARGET_OBJECT_AUXV,
|
||||
NULL, &auxv[auxv_pos], 0,
|
||||
auxv_alloc - auxv_pos);
|
||||
if (n <= 0)
|
||||
break;
|
||||
auxv_pos += n;
|
||||
if (auxv_pos < auxv_alloc) /* Read all there was. */
|
||||
break;
|
||||
gdb_assert (auxv_pos == auxv_alloc);
|
||||
auxv_alloc *= 2;
|
||||
auxv = xrealloc (auxv, auxv_alloc);
|
||||
}
|
||||
|
||||
if (auxv_pos == 0)
|
||||
{
|
||||
xfree (auxv);
|
||||
*data = NULL;
|
||||
return n;
|
||||
}
|
||||
|
||||
*data = auxv;
|
||||
return auxv_pos;
|
||||
}
|
||||
|
||||
/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
|
||||
Return 0 if *READPTR is already at the end of the buffer.
|
||||
Return -1 if there is insufficient buffer for a whole entry.
|
||||
|
@ -148,7 +111,7 @@ target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
|
|||
{
|
||||
CORE_ADDR type, val;
|
||||
gdb_byte *data;
|
||||
int n = target_auxv_read (ops, &data);
|
||||
LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data);
|
||||
gdb_byte *ptr = data;
|
||||
int ents = 0;
|
||||
|
||||
|
@ -184,7 +147,8 @@ fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
|
|||
{
|
||||
CORE_ADDR type, val;
|
||||
gdb_byte *data;
|
||||
int len = target_auxv_read (ops, &data);
|
||||
LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL,
|
||||
&data);
|
||||
gdb_byte *ptr = data;
|
||||
int ents = 0;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Auxiliary vector support for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
@ -31,12 +31,6 @@
|
|||
struct target_ops; /* Forward declaration. */
|
||||
|
||||
|
||||
/* Read all the auxv data into a contiguous xmalloc'd buffer,
|
||||
stored in *DATA. Return the size in bytes of this data.
|
||||
If zero, there is no data and *DATA is null.
|
||||
if < 0, there was an error and *DATA is null. */
|
||||
extern LONGEST target_auxv_read (struct target_ops *ops, gdb_byte **data);
|
||||
|
||||
/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
|
||||
Return 0 if *READPTR is already at the end of the buffer.
|
||||
Return -1 if there is insufficient buffer for a whole entry.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Target-dependent code for Atmel AVR, for GDB.
|
||||
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
2005 Free Software Foundation, Inc.
|
||||
2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
@ -1323,45 +1323,35 @@ static void
|
|||
avr_io_reg_read_command (char *args, int from_tty)
|
||||
{
|
||||
LONGEST bufsiz = 0;
|
||||
char buf[400];
|
||||
gdb_byte *buf;
|
||||
char query[400];
|
||||
char *p;
|
||||
unsigned int nreg = 0;
|
||||
unsigned int val;
|
||||
int i, j, k, step;
|
||||
|
||||
/* Just get the maximum buffer size. */
|
||||
bufsiz = target_read_partial (¤t_target, TARGET_OBJECT_AVR,
|
||||
NULL, NULL, 0, 0);
|
||||
if (bufsiz < 0)
|
||||
/* Find out how many io registers the target has. */
|
||||
bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR,
|
||||
"avr.io_reg", &buf);
|
||||
|
||||
if (bufsiz <= 0)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
_("ERR: info io_registers NOT supported "
|
||||
"by current target\n"));
|
||||
return;
|
||||
}
|
||||
if (bufsiz > sizeof (buf))
|
||||
bufsiz = sizeof (buf);
|
||||
|
||||
/* Find out how many io registers the target has. */
|
||||
strcpy (query, "avr.io_reg");
|
||||
target_read_partial (¤t_target, TARGET_OBJECT_AVR, query, buf, 0,
|
||||
bufsiz);
|
||||
|
||||
if (strncmp (buf, "", bufsiz) == 0)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
_("info io_registers NOT supported by target\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf (buf, "%x", &nreg) != 1)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
_("Error fetching number of io registers\n"));
|
||||
xfree (buf);
|
||||
return;
|
||||
}
|
||||
|
||||
xfree (buf);
|
||||
|
||||
reinitialize_more_filter ();
|
||||
|
||||
printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);
|
||||
|
@ -1377,8 +1367,8 @@ avr_io_reg_read_command (char *args, int from_tty)
|
|||
j = nreg - i; /* last block is less than 8 registers */
|
||||
|
||||
snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
|
||||
target_read_partial (¤t_target, TARGET_OBJECT_AVR, query, buf,
|
||||
0, bufsiz);
|
||||
bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR,
|
||||
query, &buf);
|
||||
|
||||
p = buf;
|
||||
for (k = i; k < (i + j); k++)
|
||||
|
@ -1393,6 +1383,8 @@ avr_io_reg_read_command (char *args, int from_tty)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xfree (buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
|
||||
Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
@ -2458,8 +2458,8 @@ ia64_access_mem (unw_addr_space_t as,
|
|||
}
|
||||
|
||||
/* Call low-level function to access the kernel unwind table. */
|
||||
static int
|
||||
getunwind_table (void *buf, size_t len)
|
||||
static LONGEST
|
||||
getunwind_table (gdb_byte **buf_p)
|
||||
{
|
||||
LONGEST x;
|
||||
|
||||
|
@ -2470,10 +2470,11 @@ getunwind_table (void *buf, size_t len)
|
|||
we want to preserve fall back to the running kernel's table, then
|
||||
we should find a way to override the corefile layer's
|
||||
xfer_partial method. */
|
||||
x = target_read_partial (¤t_target, TARGET_OBJECT_UNWIND_TABLE, NULL,
|
||||
buf, 0, len);
|
||||
|
||||
return (int)x;
|
||||
x = target_read_alloc (¤t_target, TARGET_OBJECT_UNWIND_TABLE,
|
||||
NULL, buf_p);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Get the kernel unwind table. */
|
||||
|
@ -2484,14 +2485,15 @@ get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
|
|||
|
||||
if (!ktab)
|
||||
{
|
||||
gdb_byte *ktab_buf;
|
||||
size_t size;
|
||||
size = getunwind_table (NULL, 0);
|
||||
if ((int)size < 0)
|
||||
return -UNW_ENOINFO;
|
||||
ktab_size = size;
|
||||
ktab = xmalloc (ktab_size);
|
||||
getunwind_table (ktab, ktab_size);
|
||||
|
||||
|
||||
ktab_size = getunwind_table (&ktab_buf);
|
||||
if (ktab_size <= 0)
|
||||
return -UNW_ENOINFO;
|
||||
else
|
||||
ktab = (struct ia64_table_entry *) ktab_buf;
|
||||
|
||||
for (etab = ktab; etab->start_offset; ++etab)
|
||||
etab->info_offset += KERNEL_START;
|
||||
}
|
||||
|
|
|
@ -2697,7 +2697,8 @@ linux_nat_make_corefile_notes (bfd *obfd, int *note_size)
|
|||
note_data = thread_args.note_data;
|
||||
}
|
||||
|
||||
auxv_len = target_auxv_read (¤t_target, &auxv);
|
||||
auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
|
||||
NULL, &auxv);
|
||||
if (auxv_len > 0)
|
||||
{
|
||||
note_data = elfcore_write_note (obfd, note_data, note_size,
|
||||
|
|
|
@ -6130,7 +6130,8 @@ procfs_make_note_section (bfd *obfd, int *note_size)
|
|||
note_data = thread_args.note_data;
|
||||
}
|
||||
|
||||
auxv_len = target_auxv_read (¤t_target, &auxv);
|
||||
auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
|
||||
NULL, &auxv);
|
||||
if (auxv_len > 0)
|
||||
{
|
||||
note_data = elfcore_write_note (obfd, note_data, note_size,
|
||||
|
|
46
gdb/remote.c
46
gdb/remote.c
|
@ -5147,35 +5147,23 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
|
|||
case TARGET_OBJECT_AUXV:
|
||||
if (remote_protocol_packets[PACKET_qPart_auxv].support != PACKET_DISABLE)
|
||||
{
|
||||
unsigned int total = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
LONGEST n = min ((get_remote_packet_size () - 2) / 2, len);
|
||||
snprintf (rs->buf, get_remote_packet_size (),
|
||||
"qPart:auxv:read::%s,%s",
|
||||
phex_nz (offset, sizeof offset),
|
||||
phex_nz (n, sizeof n));
|
||||
i = putpkt (rs->buf);
|
||||
if (i < 0)
|
||||
return total > 0 ? total : i;
|
||||
rs->buf[0] = '\0';
|
||||
getpkt (&rs->buf, &rs->buf_size, 0);
|
||||
if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_qPart_auxv])
|
||||
!= PACKET_OK)
|
||||
return total > 0 ? total : -1;
|
||||
if (strcmp (rs->buf, "OK") == 0)
|
||||
break; /* Got EOF indicator. */
|
||||
/* Got some data. */
|
||||
i = hex2bin (rs->buf, readbuf, len);
|
||||
if (i > 0)
|
||||
{
|
||||
readbuf = (void *) ((char *) readbuf + i);
|
||||
offset += i;
|
||||
len -= i;
|
||||
total += i;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
LONGEST n = min ((get_remote_packet_size () - 2) / 2, len);
|
||||
snprintf (rs->buf, get_remote_packet_size (),
|
||||
"qPart:auxv:read::%s,%s",
|
||||
phex_nz (offset, sizeof offset),
|
||||
phex_nz (n, sizeof n));
|
||||
i = putpkt (rs->buf);
|
||||
if (i < 0)
|
||||
return i;
|
||||
rs->buf[0] = '\0';
|
||||
getpkt (&rs->buf, &rs->buf_size, 0);
|
||||
if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_qPart_auxv])
|
||||
!= PACKET_OK)
|
||||
return -1;
|
||||
if (strcmp (rs->buf, "OK") == 0)
|
||||
return 0; /* Got EOF indicator. */
|
||||
/* Got some data. */
|
||||
return hex2bin (rs->buf, readbuf, len);
|
||||
}
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ sparc_fetch_wcookie (void)
|
|||
gdb_byte buf[8];
|
||||
int len;
|
||||
|
||||
len = target_read_partial (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
|
||||
len = target_read (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
|
||||
if (len == -1)
|
||||
return 0;
|
||||
|
||||
|
|
80
gdb/target.c
80
gdb/target.c
|
@ -1341,7 +1341,7 @@ default_xfer_partial (struct target_ops *ops, enum target_object object,
|
|||
(inbuf, outbuf)", instead of separate read/write methods, make life
|
||||
easier. */
|
||||
|
||||
LONGEST
|
||||
static LONGEST
|
||||
target_read_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, gdb_byte *buf,
|
||||
|
@ -1350,7 +1350,7 @@ target_read_partial (struct target_ops *ops,
|
|||
return target_xfer_partial (ops, object, annex, buf, NULL, offset, len);
|
||||
}
|
||||
|
||||
LONGEST
|
||||
static LONGEST
|
||||
target_write_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, const gdb_byte *buf,
|
||||
|
@ -1373,8 +1373,9 @@ target_read (struct target_ops *ops,
|
|||
(gdb_byte *) buf + xfered,
|
||||
offset + xfered, len - xfered);
|
||||
/* Call an observer, notifying them of the xfer progress? */
|
||||
if (xfer <= 0)
|
||||
/* Call memory_error? */
|
||||
if (xfer == 0)
|
||||
return xfered;
|
||||
if (xfer < 0)
|
||||
return -1;
|
||||
xfered += xfer;
|
||||
QUIT;
|
||||
|
@ -1395,8 +1396,9 @@ target_write (struct target_ops *ops,
|
|||
(gdb_byte *) buf + xfered,
|
||||
offset + xfered, len - xfered);
|
||||
/* Call an observer, notifying them of the xfer progress? */
|
||||
if (xfer <= 0)
|
||||
/* Call memory_error? */
|
||||
if (xfer == 0)
|
||||
return xfered;
|
||||
if (xfer < 0)
|
||||
return -1;
|
||||
xfered += xfer;
|
||||
QUIT;
|
||||
|
@ -1404,6 +1406,72 @@ target_write (struct target_ops *ops,
|
|||
return len;
|
||||
}
|
||||
|
||||
/* Wrapper to perform a full read of unknown size. OBJECT/ANNEX will
|
||||
be read using OPS. The return value will be -1 if the transfer
|
||||
fails or is not supported; 0 if the object is empty; or the length
|
||||
of the object otherwise. If a positive value is returned, a
|
||||
sufficiently large buffer will be allocated using xmalloc and
|
||||
returned in *BUF_P containing the contents of the object.
|
||||
|
||||
This method should be used for objects sufficiently small to store
|
||||
in a single xmalloc'd buffer, when no fixed bound on the object's
|
||||
size is known in advance. Don't try to read TARGET_OBJECT_MEMORY
|
||||
through this function. */
|
||||
|
||||
LONGEST
|
||||
target_read_alloc (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, gdb_byte **buf_p)
|
||||
{
|
||||
size_t buf_alloc, buf_pos;
|
||||
gdb_byte *buf;
|
||||
LONGEST n;
|
||||
|
||||
/* This function does not have a length parameter; it reads the
|
||||
entire OBJECT). Also, it doesn't support objects fetched partly
|
||||
from one target and partly from another (in a different stratum,
|
||||
e.g. a core file and an executable). Both reasons make it
|
||||
unsuitable for reading memory. */
|
||||
gdb_assert (object != TARGET_OBJECT_MEMORY);
|
||||
|
||||
/* Start by reading up to 4K at a time. The target will throttle
|
||||
this number down if necessary. */
|
||||
buf_alloc = 4096;
|
||||
buf = xmalloc (buf_alloc);
|
||||
buf_pos = 0;
|
||||
while (1)
|
||||
{
|
||||
n = target_read_partial (ops, object, annex, &buf[buf_pos],
|
||||
buf_pos, buf_alloc - buf_pos);
|
||||
if (n < 0)
|
||||
{
|
||||
/* An error occurred. */
|
||||
xfree (buf);
|
||||
return -1;
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
/* Read all there was. */
|
||||
if (buf_pos == 0)
|
||||
xfree (buf);
|
||||
else
|
||||
*buf_p = buf;
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
buf_pos += n;
|
||||
|
||||
/* If the buffer is filling up, expand it. */
|
||||
if (buf_alloc < buf_pos * 2)
|
||||
{
|
||||
buf_alloc *= 2;
|
||||
buf = xrealloc (buf, buf_alloc);
|
||||
}
|
||||
|
||||
QUIT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Memory transfer methods. */
|
||||
|
||||
void
|
||||
|
|
98
gdb/target.h
98
gdb/target.h
|
@ -180,38 +180,8 @@ extern char *target_signal_to_name (enum target_signal);
|
|||
/* Given a name (SIGHUP, etc.), return its signal. */
|
||||
enum target_signal target_signal_from_name (char *);
|
||||
|
||||
/* Request the transfer of up to LEN 8-bit bytes of the target's
|
||||
OBJECT. The OFFSET, for a seekable object, specifies the starting
|
||||
point. The ANNEX can be used to provide additional data-specific
|
||||
information to the target.
|
||||
|
||||
Return the number of bytes actually transfered, zero when no
|
||||
further transfer is possible, and -1 when the transfer is not
|
||||
supported.
|
||||
|
||||
NOTE: cagney/2003-10-17: The current interface does not support a
|
||||
"retry" mechanism. Instead it assumes that at least one byte will
|
||||
be transfered on each call.
|
||||
|
||||
NOTE: cagney/2003-10-17: The current interface can lead to
|
||||
fragmented transfers. Lower target levels should not implement
|
||||
hacks, such as enlarging the transfer, in an attempt to compensate
|
||||
for this. Instead, the target stack should be extended so that it
|
||||
implements supply/collect methods and a look-aside object cache.
|
||||
With that available, the lowest target can safely and freely "push"
|
||||
data up the stack.
|
||||
|
||||
NOTE: cagney/2003-10-17: Unlike the old query and the memory
|
||||
transfer mechanisms, these methods are explicitly parameterized by
|
||||
the target that it should be applied to.
|
||||
|
||||
NOTE: cagney/2003-10-17: Just like the old query and memory xfer
|
||||
methods, these new methods perform partial transfers. The only
|
||||
difference is that these new methods thought to include "partial"
|
||||
in the name. The old code's failure to do this lead to much
|
||||
confusion and duplication of effort as each target object attempted
|
||||
to locally take responsibility for something it didn't have to
|
||||
worry about. */
|
||||
/* Target objects which can be transfered using target_read,
|
||||
target_write, et cetera. */
|
||||
|
||||
enum target_object
|
||||
{
|
||||
|
@ -229,17 +199,17 @@ enum target_object
|
|||
/* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC, ... */
|
||||
};
|
||||
|
||||
extern LONGEST target_read_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, gdb_byte *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
/* Request that OPS transfer up to LEN 8-bit bytes of the target's
|
||||
OBJECT. The OFFSET, for a seekable object, specifies the
|
||||
starting point. The ANNEX can be used to provide additional
|
||||
data-specific information to the target.
|
||||
|
||||
extern LONGEST target_write_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, const gdb_byte *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
Return the number of bytes actually transfered, or -1 if the
|
||||
transfer is not supported or otherwise fails. Return of a positive
|
||||
value less than LEN indicates that no further transfer is possible.
|
||||
Unlike the raw to_xfer_partial interface, callers of these
|
||||
functions do not need to retry partial transfers. */
|
||||
|
||||
/* Wrappers to perform the full transfer. */
|
||||
extern LONGEST target_read (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, gdb_byte *buf,
|
||||
|
@ -250,6 +220,22 @@ extern LONGEST target_write (struct target_ops *ops,
|
|||
const char *annex, const gdb_byte *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
|
||||
/* Wrapper to perform a full read of unknown size. OBJECT/ANNEX will
|
||||
be read using OPS. The return value will be -1 if the transfer
|
||||
fails or is not supported; 0 if the object is empty; or the length
|
||||
of the object otherwise. If a positive value is returned, a
|
||||
sufficiently large buffer will be allocated using xmalloc and
|
||||
returned in *BUF_P containing the contents of the object.
|
||||
|
||||
This method should be used for objects sufficiently small to store
|
||||
in a single xmalloc'd buffer, when no fixed bound on the object's
|
||||
size is known in advance. Don't try to read TARGET_OBJECT_MEMORY
|
||||
through this function. */
|
||||
|
||||
extern LONGEST target_read_alloc (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, gdb_byte **buf_p);
|
||||
|
||||
/* Wrappers to target read/write that perform memory transfers. They
|
||||
throw an error if the memory transfer fails.
|
||||
|
||||
|
@ -409,9 +395,33 @@ struct target_ops
|
|||
CORE_ADDR load_module_addr,
|
||||
CORE_ADDR offset);
|
||||
|
||||
/* Perform partial transfers on OBJECT. See target_read_partial
|
||||
and target_write_partial for details of each variant. One, and
|
||||
only one, of readbuf or writebuf must be non-NULL. */
|
||||
/* Request that OPS transfer up to LEN 8-bit bytes of the target's
|
||||
OBJECT. The OFFSET, for a seekable object, specifies the
|
||||
starting point. The ANNEX can be used to provide additional
|
||||
data-specific information to the target.
|
||||
|
||||
Return the number of bytes actually transfered, zero when no
|
||||
further transfer is possible, and -1 when the transfer is not
|
||||
supported. Return of a positive value smaller than LEN does
|
||||
not indicate the end of the object, only the end of the
|
||||
transfer; higher level code should continue transferring if
|
||||
desired. This is handled in target.c.
|
||||
|
||||
The interface does not support a "retry" mechanism. Instead it
|
||||
assumes that at least one byte will be transfered on each
|
||||
successful call.
|
||||
|
||||
NOTE: cagney/2003-10-17: The current interface can lead to
|
||||
fragmented transfers. Lower target levels should not implement
|
||||
hacks, such as enlarging the transfer, in an attempt to
|
||||
compensate for this. Instead, the target stack should be
|
||||
extended so that it implements supply/collect methods and a
|
||||
look-aside object cache. With that available, the lowest
|
||||
target can safely and freely "push" data up the stack.
|
||||
|
||||
See target_read and target_write for more information. One,
|
||||
and only one, of readbuf or writebuf must be non-NULL. */
|
||||
|
||||
LONGEST (*to_xfer_partial) (struct target_ops *ops,
|
||||
enum target_object object, const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
|
|
Loading…
Reference in a new issue