This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: remote protocol support for TARGET_OBJECT_AUXV


I am proposing a new query packet `qAuxVector' to support reading
TARGET_OBJECT_AUXV data.  Here's the proposed docs addition describing it.
After that, I've appended (short) patches implementing it in gdb and
gdbserver so you can see concretely what I mean.

(roland, in case you're confused - this gets discussed as a protocol change and also approved as a doco change)


Index: gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.192
diff -u -b -p -r1.192 gdb.texinfo
--- gdb.texinfo 4 Feb 2004 23:24:43 -0000 1.192
+++ gdb.texinfo 4 Feb 2004 23:56:55 -0000
@@ -20420,6 +20420,23 @@ The target does not need to look up any The target requests the value of a new symbol @var{sym_name} (hex
encoded). @value{GDBN} will continue to supply the values of symbols
(if available), until the target ceases to request them.
+@end table
+
+@item @code{qAuxVector}:@var{offset},@var{length} --- auxiliary vector data

The underlying target methods that this is adding support for are:


/* 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: With a TARGET_OBJECT_KOD object, for
   backward compatibility with the "target_query" method that this
   replaced, when OFFSET and LEN are both 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_MEMORY,
  /* Kernel Unwind Table.  See "ia64-tdep.c".  */
  TARGET_OBJECT_UNWIND_TABLE,
  /* Transfer auxilliary vector.  */
  TARGET_OBJECT_AUXV,
  /* StackGhost cookie.  See "sparc-tdep.c".  */
  TARGET_OBJECT_WCOOKIE

/* 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, 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);

I think it would be better to specify something that accomodates this (to my suprise) rapidly expanding interface.
Otherwize, in a month or so, we'll find ourselves discussing the exact saome problem for "unwind-table", "wcookie", "avr", and "kod".


I also think that the protocol semantics should reflect this interfaces semantics (or a superset of it).

+Read from the target's @dfn{auxiliary vector}, treated as an
+uninterpreted block of bytes.  (@xref{Auxiliary Vector}.)
+Request @var{length} bytes starting at @var{offset} bytes into the data.
+
+Reply:
+@table @samp
+@item @code{=}@var{data}
+@var{data} (hex encoded) contains the data bytes read.
+There is no more auxiliary data after what was requested.
+
+@item @code{+}@var{data}
+@var{data} (hex encoded) contains the data bytes read.
+There may be additional data that can be read with another request.
 @end table

(technical nit "+" can't be used. For want of a better term, it acts as a [re]sync character and hence can't appear in the middle of a packet. Also see note at end.)


Lets start with this:

-> qPartial:<obj>:read:<x-annex>:<x-offset>,<x-length>
	<- OK -- implicit zero length returned EOF
	<- <x-data> -- must contain the byte @<x-offset>
	<- "" -- packet not recognized
	<- Enn - something wrong with the request

-> qPartial:<obj>:write:<x-annex>:<x-offset>:<x-data>
	<- <x-be-length> -- number of bytes actially written
	<- "" -- packet not recognized
	<- Enn -- something wrong with the request

-> qPartial:<obj>?
	<- OK -- queries of type <obj> are supported
	<- "" -- queries of type <obj> are not supported

a variation being something like:
qPartial:obj=<obj>:op=write[:annex=<x-annex>]:offset=<x-offset>:data=<x-data>
which makes it more extensible.

Anyway, this would give us:
-> qPartial:auxv?
OK
-> qPartial:auxv:read::0,ff
123456....

And closely parallels the read/write partial methods.

Once that's been used for a bit, and its performance evaluated, we can look to refine it. Perhaphs by adding additional replies to the read side (and even the write side).

--

Looking more closely at this fragment of the committed code:

LONGEST
target_auxv_read (struct target_ops *ops, char **data)
{
  size_t auxv_alloc = 512, auxv_pos = 0;
  char *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;

the it must assume that the transfer was fragmented, and attempt a re-fetch.


Andrew



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]