* 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:
Daniel Jacobowitz 2006-07-12 18:13:45 +00:00
parent edfb1a2648
commit 13547ab600
11 changed files with 206 additions and 165 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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 (&current_target, TARGET_OBJECT_AVR,
NULL, NULL, 0, 0);
if (bufsiz < 0)
/* Find out how many io registers the target has. */
bufsiz = target_read_alloc (&current_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 (&current_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 (&current_target, TARGET_OBJECT_AVR, query, buf,
0, bufsiz);
bufsiz = target_read_alloc (&current_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);
}
}

View File

@ -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 (&current_target, TARGET_OBJECT_UNWIND_TABLE, NULL,
buf, 0, len);
return (int)x;
x = target_read_alloc (&current_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;
}

View File

@ -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 (&current_target, &auxv);
auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
NULL, &auxv);
if (auxv_len > 0)
{
note_data = elfcore_write_note (obfd, note_data, note_size,

View File

@ -6130,7 +6130,8 @@ procfs_make_note_section (bfd *obfd, int *note_size)
note_data = thread_args.note_data;
}
auxv_len = target_auxv_read (&current_target, &auxv);
auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
NULL, &auxv);
if (auxv_len > 0)
{
note_data = elfcore_write_note (obfd, note_data, note_size,

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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,