2003-10-17 Andrew Cagney <cagney@redhat.com>

* target.h (struct target_ops): Add "to_read_partial" and
	"to_write_partial", delete "to_query".
	(target_read_partial, target_write_partial): Declare.
	(target_read, target_write): Declare.
	(target_query): Delete macro.
	* target.c (target_read_partial): New function.
	(target_write_partial, target_read, target_write): New function.
	(update_current_target): Delete inheritance of "to_query".  Add
	comments about "to_read_partial" and "to_write_partial".
	(debug_to_partial_read, debug_to_partial_write): New functions.
	(debug_to_query): Delete function.
	(setup_target_debug): Set "to_read_partial" and "to_write_partial"
	instead of "to_query".
	* remote.c (remote_read_partial): Replace "remote_query".
	(init_remote_ops): Set "to_read_partial" instead of "to_query".
	(init_remote_async_ops): Ditto.
	* kod.c (gdb_kod_query): Make "bufsize" a LONGEST.  Use
	"target_read_partial" instead of "target_query".
	* avr-tdep.c (avr_io_reg_read_command): Make "bufsize" a LONGEST.
	Use "target_read_partial" instead of "target_query".
This commit is contained in:
Andrew Cagney 2003-10-17 18:24:49 +00:00
parent 4b71bec021
commit 1e3ff5ad7f
6 changed files with 280 additions and 70 deletions

View File

@ -1,3 +1,26 @@
2003-10-17 Andrew Cagney <cagney@redhat.com>
* target.h (struct target_ops): Add "to_read_partial" and
"to_write_partial", delete "to_query".
(target_read_partial, target_write_partial): Declare.
(target_read, target_write): Declare.
(target_query): Delete macro.
* target.c (target_read_partial): New function.
(target_write_partial, target_read, target_write): New function.
(update_current_target): Delete inheritance of "to_query". Add
comments about "to_read_partial" and "to_write_partial".
(debug_to_partial_read, debug_to_partial_write): New functions.
(debug_to_query): Delete function.
(setup_target_debug): Set "to_read_partial" and "to_write_partial"
instead of "to_query".
* remote.c (remote_read_partial): Replace "remote_query".
(init_remote_ops): Set "to_read_partial" instead of "to_query".
(init_remote_async_ops): Ditto.
* kod.c (gdb_kod_query): Make "bufsize" a LONGEST. Use
"target_read_partial" instead of "target_query".
* avr-tdep.c (avr_io_reg_read_command): Make "bufsize" a LONGEST.
Use "target_read_partial" instead of "target_query".
2003-10-17 Jeff Johnston <jjohnstn@redhat.com>
* frame.h (struct frame_id): Add new field: special_addr.

View File

@ -1359,7 +1359,7 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
static void
avr_io_reg_read_command (char *args, int from_tty)
{
int bufsiz = 0;
LONGEST bufsiz = 0;
char buf[400];
char query[400];
char *p;
@ -1367,22 +1367,23 @@ avr_io_reg_read_command (char *args, int from_tty)
unsigned int val;
int i, j, k, step;
if (!current_target.to_query)
/* Just get the maximum buffer size. */
bufsiz = target_read_partial (&current_target, TARGET_OBJECT_AVR,
NULL, NULL, 0, 0);
if (bufsiz < 0)
{
fprintf_unfiltered (gdb_stderr,
"ERR: info io_registers NOT supported by current "
"target\n");
return;
}
/* Just get the maximum buffer size. */
target_query ((int) 'R', 0, 0, &bufsiz);
if (bufsiz > sizeof (buf))
bufsiz = sizeof (buf);
/* Find out how many io registers the target has. */
strcpy (query, "avr.io_reg");
target_query ((int) 'R', query, buf, &bufsiz);
target_read_partial (&current_target, TARGET_OBJECT_AVR, query, buf, 0,
bufsiz);
if (strncmp (buf, "", bufsiz) == 0)
{
@ -1413,7 +1414,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_query ((int) 'R', query, buf, &bufsiz);
target_read_partial (&current_target, TARGET_OBJECT_AVR, query, buf,
0, bufsiz);
p = buf;
for (k = i; k < (i + j); k++)

View File

@ -87,11 +87,13 @@ gdb_kod_display (char *arg)
static void
gdb_kod_query (char *arg, char *result, int *maxsiz)
{
int bufsiz = 0;
LONGEST bufsiz = 0;
/* Check if current target has remote_query capabilities.
If not, it does not have kod either. */
if (! current_target.to_query)
/* Check if current target has remote_query capabilities. If not,
it does not have kod either. */
bufsiz = target_read_partial (&current_target, TARGET_OBJECT_KOD,
NULL, NULL, 0, 0);
if (bufsiz < 0)
{
strcpy (result,
"ERR: Kernel Object Display not supported by current target\n");
@ -99,7 +101,6 @@ gdb_kod_query (char *arg, char *result, int *maxsiz)
}
/* Just get the maximum buffer size. */
target_query ((int) 'K', 0, 0, &bufsiz);
/* Check if *we* were called just for getting the buffer size. */
if (*maxsiz == 0)
@ -119,7 +120,8 @@ gdb_kod_query (char *arg, char *result, int *maxsiz)
error ("kod: query argument too long");
/* Send actual request. */
if (target_query ((int) 'K', arg, result, &bufsiz))
if (target_read_partial (&current_target, TARGET_OBJECT_KOD,
arg, result, 0, bufsiz) < 0)
strcpy (result, "ERR: remote query failed");
}

View File

@ -161,8 +161,6 @@ static int ishex (int ch, int *val);
static int stubhex (int ch);
static int remote_query (int /*char */ , char *, char *, int *);
static int hexnumstr (char *, ULONGEST);
static int hexnumnstr (char *, ULONGEST, int);
@ -5103,41 +5101,47 @@ the loaded file\n");
printf_filtered ("No loaded section named '%s'.\n", args);
}
static int
remote_query (int query_type, char *buf, char *outbuf, int *bufsiz)
static LONGEST
remote_read_partial (struct target_ops *ops, enum target_object object,
const char *annex, void *buf,
ULONGEST offset, LONGEST len)
{
struct remote_state *rs = get_remote_state ();
int i;
char *buf2 = alloca (rs->remote_packet_size);
char *p2 = &buf2[0];
char query_type;
if (!bufsiz)
error ("null pointer to remote bufer size specified");
/* minimum outbuf size is (rs->remote_packet_size) - if bufsiz is not large enough let
the caller know and return what the minimum size is */
/* Note: a zero bufsiz can be used to query the minimum buffer size */
if (*bufsiz < (rs->remote_packet_size))
/* Map pre-existing objects onto letters. DO NOT do this for new
objects!!! Instead specify new query packets. */
switch (object)
{
*bufsiz = (rs->remote_packet_size);
case TARGET_OBJECT_KOD:
query_type = 'K';
break;
case TARGET_OBJECT_AVR:
query_type = 'R';
break;
default:
return -1;
}
/* Note: a zero BUF, OFFSET and LEN can be used to query the minimum
buffer size. */
if (buf == NULL && offset == 0 && len == 0)
return (rs->remote_packet_size);
/* Minimum outbuf size is (rs->remote_packet_size) - if bufsiz is
not large enough let the caller. */
if (len < (rs->remote_packet_size))
return -1;
len = rs->remote_packet_size;
/* except for querying the minimum buffer size, target must be open */
if (!remote_desc)
error ("remote query is only available after target open");
/* we only take uppercase letters as query types, at least for now */
if ((query_type < 'A') || (query_type > 'Z'))
error ("invalid remote query type");
if (!buf)
error ("null remote query specified");
if (!outbuf)
error ("remote query requires a buffer to receive data");
outbuf[0] = '\0';
gdb_assert (annex != NULL);
gdb_assert (buf != NULL);
*p2++ = 'q';
*p2++ = query_type;
@ -5147,27 +5151,23 @@ remote_query (int query_type, char *buf, char *outbuf, int *bufsiz)
plus one extra in case we are debugging (remote_debug),
we have PBUFZIZ - 7 left to pack the query string */
i = 0;
while (buf[i] && (i < ((rs->remote_packet_size) - 8)))
while (annex[i] && (i < ((rs->remote_packet_size) - 8)))
{
/* bad caller may have sent forbidden characters */
if ((!isprint (buf[i])) || (buf[i] == '$') || (buf[i] == '#'))
error ("illegal characters in query string");
*p2++ = buf[i];
/* Bad caller may have sent forbidden characters. */
gdb_assert (isprint (annex[i]) && annex[i] != '$' && annex[i] != '#');
*p2++ = annex[i];
i++;
}
*p2 = buf[i];
if (buf[i])
error ("query larger than available buffer");
*p2 = '\0';
gdb_assert (annex[i] == '\0');
i = putpkt (buf2);
if (i < 0)
return i;
getpkt (outbuf, *bufsiz, 0);
getpkt (buf, len, 0);
return 0;
return strlen (buf);
}
static void
@ -5445,7 +5445,7 @@ Specify the serial device it is connected to\n\
remote_ops.to_pid_to_str = remote_pid_to_str;
remote_ops.to_extra_thread_info = remote_threads_extra_info;
remote_ops.to_stop = remote_stop;
remote_ops.to_query = remote_query;
remote_ops.to_read_partial = remote_read_partial;
remote_ops.to_rcmd = remote_rcmd;
remote_ops.to_stratum = process_stratum;
remote_ops.to_has_all_memory = 1;
@ -5965,7 +5965,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
remote_async_ops.to_pid_to_str = remote_pid_to_str;
remote_async_ops.to_extra_thread_info = remote_threads_extra_info;
remote_async_ops.to_stop = remote_stop;
remote_async_ops.to_query = remote_query;
remote_async_ops.to_read_partial = remote_read_partial;
remote_async_ops.to_rcmd = remote_rcmd;
remote_async_ops.to_stratum = process_stratum;
remote_async_ops.to_has_all_memory = 1;

View File

@ -159,8 +159,6 @@ static int debug_to_thread_alive (ptid_t);
static void debug_to_stop (void);
static int debug_to_query (int /*char */ , char *, char *, int *);
/* Pointer to array of target architecture structures; the size of the
array; the current index into the array; the allocated size of the
array. */
@ -422,7 +420,8 @@ update_current_target (void)
INHERIT (to_pid_to_str, t);
INHERIT (to_extra_thread_info, t);
INHERIT (to_stop, t);
INHERIT (to_query, t);
/* Do not inherit to_read_partial. */
/* Do not inherit to_write_partial. */
INHERIT (to_rcmd, t);
INHERIT (to_enable_exception_callback, t);
INHERIT (to_get_current_exception_event, t);
@ -1056,6 +1055,90 @@ target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
return target_xfer_memory_partial (memaddr, buf, len, 1, err);
}
/* More generic transfers. */
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);
}
LONGEST
target_write_partial (struct target_ops *ops,
enum target_object object,
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);
}
/* Wrappers to perform the full transfer. */
LONGEST
target_read (struct target_ops *ops,
enum target_object object,
const char *annex, void *buf,
ULONGEST offset, LONGEST len)
{
LONGEST xfered = 0;
while (xfered < len)
{
LONGEST xfer = target_write_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;
xfered += xfer;
QUIT;
}
return len;
}
LONGEST
target_write (struct target_ops *ops,
enum target_object object,
const char *annex, const void *buf,
ULONGEST offset, LONGEST len)
{
LONGEST xfered = 0;
while (xfered < len)
{
LONGEST xfer = target_write_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;
xfered += xfer;
QUIT;
}
return len;
}
static void
target_info (char *args, int from_tty)
{
@ -2128,14 +2211,42 @@ debug_to_stop (void)
fprintf_unfiltered (gdb_stdlog, "target_stop ()\n");
}
static int
debug_to_query (int type, char *req, char *resp, int *siz)
static LONGEST
debug_to_read_partial (struct target_ops *ops,
enum target_object object,
const char *annex, void *buf,
ULONGEST offset, LONGEST len)
{
int retval;
LONGEST retval;
retval = debug_target.to_query (type, req, resp, siz);
retval = target_read_partial (&debug_target, object, annex, buf, offset,
len);
fprintf_unfiltered (gdb_stdlog, "target_query (%c, %s, %s, %d) = %d\n", type, req, resp, *siz, retval);
fprintf_unfiltered (gdb_stdlog,
"target_read_partial (%d, %s, 0x%lx, 0x%s, %s) = %s\n",
(int) object, (annex ? annex : "(null)"),
(long) buf, paddr_nz (offset),
paddr_d (len), paddr_d (retval));
return retval;
}
static LONGEST
debug_to_write_partial (struct target_ops *ops,
enum target_object object,
const char *annex, const void *buf,
ULONGEST offset, LONGEST len)
{
LONGEST retval;
retval = target_write_partial (&debug_target, object, annex, buf, offset,
len);
fprintf_unfiltered (gdb_stdlog,
"target_write_partial (%d, %s, 0x%lx, 0x%s, %s) = %s\n",
(int) object, (annex ? annex : "(null)"),
(long) buf, paddr_nz (offset),
paddr_d (len), paddr_d (retval));
return retval;
}
@ -2237,7 +2348,8 @@ setup_target_debug (void)
current_target.to_thread_alive = debug_to_thread_alive;
current_target.to_find_new_threads = debug_to_find_new_threads;
current_target.to_stop = debug_to_stop;
current_target.to_query = debug_to_query;
current_target.to_read_partial = debug_to_read_partial;
current_target.to_write_partial = debug_to_write_partial;
current_target.to_rcmd = debug_to_rcmd;
current_target.to_enable_exception_callback = debug_to_enable_exception_callback;
current_target.to_get_current_exception_event = debug_to_get_current_exception_event;

View File

@ -26,6 +26,7 @@
struct objfile;
struct ui_file;
struct mem_attrib;
struct target_ops;
/* This include file defines the interface between the main part
of the debugger, and the part which is target-specific, or
@ -175,6 +176,77 @@ 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.
NOTE: cagney/2003-10-17: For backward compatibility with the
"target_query" method that this replaced, when BUF, OFFSET and LEN
are NULL/zero, return the "minimum" buffer size. See "remote.c"
for further information. */
enum target_object
{
/* Kernel Object Display transfer. See "kod.c" and "remote.c". */
TARGET_OBJECT_KOD,
/* 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
/* Possible future ojbects: TARGET_OJBECT_FILE, TARGET_OBJECT_PROC,
TARGET_OBJECT_AUXV, ... */
};
extern LONGEST target_read_partial (struct target_ops *ops,
enum target_object object,
const char *annex, void *buf,
ULONGEST offset, LONGEST len);
extern LONGEST target_write_partial (struct target_ops *ops,
enum target_object object,
const char *annex, const void *buf,
ULONGEST offset, LONGEST len);
/* Wrappers to perform the full transfer. */
extern LONGEST target_read (struct target_ops *ops,
enum target_object object,
const char *annex, void *buf,
ULONGEST offset, LONGEST len);
extern LONGEST target_write (struct target_ops *ops,
enum target_object object,
const char *annex, const void *buf,
ULONGEST offset, LONGEST len);
/* If certain kinds of activity happen, target_wait should perform
callbacks. */
@ -271,7 +343,6 @@ struct target_ops
char *(*to_pid_to_str) (ptid_t);
char *(*to_extra_thread_info) (struct thread_info *);
void (*to_stop) (void);
int (*to_query) (int /*char */ , char *, char *, int *);
void (*to_rcmd) (char *command, struct ui_file *output);
struct symtab_and_line *(*to_enable_exception_callback) (enum
exception_event_kind,
@ -311,6 +382,16 @@ struct target_ops
struct objfile *objfile,
CORE_ADDR offset);
/* See above. */
LONGEST (*to_read_partial) (struct target_ops *ops,
enum target_object object,
const char *annex, void *buf,
ULONGEST offset, LONGEST len);
LONGEST (*to_write_partial) (struct target_ops *ops,
enum target_object object,
const char *annex, const void *buf,
ULONGEST offset, LONGEST len);
int to_magic;
/* Need sub-structure for target machine related rather than comm related?
*/
@ -722,16 +803,6 @@ extern void target_load (char *arg, int from_tty);
#define target_stop current_target.to_stop
/* Queries the target side for some information. The first argument is a
letter specifying the type of the query, which is used to determine who
should process it. The second argument is a string that specifies which
information is desired and the third is a buffer that carries back the
response from the target side. The fourth parameter is the size of the
output buffer supplied. */
#define target_query(query_type, query, resp_buffer, bufffer_size) \
(*current_target.to_query) (query_type, query, resp_buffer, bufffer_size)
/* Send the specified COMMAND to the target's monitor
(shell,interpreter) for execution. The result of the query is
placed in OUTBUF. */