-How to implement a stub or server using RDA (Red Hat Debug Agent and library).
-==================================================
-Andrew Cagney <cagney@cygnus.com>
-Fernando Nasser <fnasser@cygnus.com>
-Frank Eigler <fche@cygnus.com>
+How to implement a stub or server using RDA
+===========================================
+
+Andrew Cagney <cagney@redhat.com>
+Fernando Nasser <fnasser@redhat.com>
+Frank Eigler <fche@redhat.com>
+Kevin Buettner <kevinb@redhat.com>
Introduction
------------
-This is the implementation of a server for the gdb remote protocol.
-It is available as a host library that provides most of the common code
-required. By adding a relatively small amount of target dependent code,
-one can build a server that allows gdb to connect to that target using
-the gdb "target remote" command.
-
-Gdb connects to this server through a TCP/IP connection. The server
-waits for a connection from GDB by listening to a non-restricted TCP port.
-Anyone with GDB (or even telnet) network connectivity to the machine
-running the server can initiate a connection to it.
-
-Note: The user of this software is advised to ensure
-that access to the TCP port being used is restricted to
-secure siblings. For instance, the user may need to take
-action that ensures that `The Internet' is not able to access
-the TCP port being used.
+RDA is a "Remote Debugger Agent" for GDB. It provides a library of
+commonly used routines which may be used to construct a "debugger
+stub" or "debug agent". The RDA package also includes several
+applications which use the RDA library. It is useful to examine these
+examples when creating a new RDA application. (One of the
+applications provides functionality similar to that of "gdbserver"
+found in the GDB sources.)
+
+The RDA library provides an implementation of the "server" end of
+the GDB remote protocol. An application which uses the RDA library
+will typically start up and then wait for GDB to connect to the
+the application via GDB's "target remote" command. Once communication
+between the RDA application and GDB has been established, the
+RDA application translates GDB's remote protocol requests into queries
+against the target environment. When results from these queries are
+known, the results are communicated back to GDB in a response packet.
+
+The RDA library has been designed so that a relatively small amount of
+target dependent code is required in order to create a new RDA
+application.
+
+GDB connects to the RDA application via either a TCP/IP connection
+or a connection on a serial port. When TCP/IP is used, the RDA
+application waits for a connection from GDB by listening on a
+non-restricted TCP port. A serial connection behaves in a similar
+fashion except that (obviously) no initial listen is needed.
+
+Note: Users of this software should take the usual precautions with
+regard to security of TCP/IP ports.
Architecture
------------
-The following diagram shows the components of RDA.
+The following diagram shows the components of an RDA application
+communicating with GDB:
(GDB) <---"remote"---> CLIENT <--> SERVER <--> TARGET
------- ------------------------------
- The client. The server.
+ The client. The RDA application (server).
Where:
target state changes.
-Looking at SERVER in more detail, that component consists of three sub
-components INPUT, OUTPUT and STATE. Visually:
+Adding Target Dependent Code
+----------------------------
- .------------ fromtarget_*
- \|/
- fromclient_* -> INPUT -> STATE (M/C) -> target->*
- /|\ |
- |
- \|/ |
- client->write <- OUTPUT <----'
+An RDA application communicates with a debugger, such as GDB, using
+the GDB Remote Serial Protocol. The RDA library performs the high
+level I/O management for the debugger connections, watches for new
+connections, and looks for protocol requests from existing
+connections. The RDA library packages up suitable responses to
+protocol requests after invoking target specific callbacks which
+collect the necessary information. In short, the RDA library manages
+communication with the debugger. You are responsible for implementing
+target specific support.
-Where:
+The "target" is a simulator, hardware device, board, program, or
+whatever you are interfacing to your stub/server.
- INPUT Filters the raw input stream from the client
- breaking it up into complete packets and
- passing them onto STATE.
+Starting up:
- This component co-operates with OUTPUT for
- the ACK/NAK of input packets.
+The function gdbsocket_startup() is used to register a TCP/IP port
+number upon which to listen. It is called with the port number upon
+which to listen, a callback function to be invoked when a connection
+is made, and a pointer to target specific data which will be passed to
+the callback function. The callback will be referred to as the
+"attach callback", perhaps due to the fact that GDB is attaching to
+RDA.
- OUTPUT Wraps up and then passes onto the client
- raw output packets ready for transmission
- on the output stream.
+The function gdbsocket_startup() might be invoked as
+follows:
- This component co-operates with INPUT for
- the ACK/NAK of output packets.
+ gdbsocket_startup (portnum, my_attach_func, my_attach_data)
- STATE The state machine proper.
+The RDA library is capable of handling several connections (sessions)
+simultaneously. If listening on several ports is desired, it is
+permitted to make several calls to gdbsocket_startup() in order to
+register the various sockets upon which the RDA application should
+listen. (Note that it is still possible to have several connections
+at a time even without monitoring more than one port number.)
+Callback Registration:
-The Appendix provides various scenarios showing in some detail how typical
-operations are handled by these components. It may be convenient to read the
-next section first before turning to the Appendix.
-
-
-Adding the target dependent code
---------------------------------
+The library requires that you implement a set of callback routines for
+reading and writing memory, reading and writing registers, controlling
+the target, etc. These callbacks are made available by filling in
+members of a gdbserv_target struct. Registration of these callbacks
+is performed via the attach function passed as the second argument
+to gdbsocket_startup(). This function will be invoked when a new
+connection is detected upon the input port.
-In the following discussion, assume your debugger (gdb) is using
-the remote protocol to communicate with the code you are building here.
-The "target" is a simulator, hardware device, board, program or whatever you
-are interfacing to with your stub/server.
+When a new connection is received on one of the sockets registered by
+gdbsocket_startup(), the corresponding attach routine is invoked. The
+attach routine can reject the connection attempt by returning NULL.
+Otherwise, it is the responsibility of the attach function to allocate
+a gdbserv_target struct, fill in the various callback members, and
+perhaps perform some other initializations. If all of this
+successfully completes, the attach function should return a pointer to
+the gdbserv_target struct that's been initialized.
-The library provides gdbsocket_*() and gdbserv_fromtarget_*() routines that
-must be called and requires you to set a series of callback routines.
-You make these callbacks known/available to the library by filling the entries
-of a "gdbserv_target" object. You must also provide an extra function that
-will be invoked when a new connection is detected on the input port (a socket).
+A skeleton of my_attach_func() might look something like this:
+ struct gdbserv_target *
+ my_attach_func (struct gdbserv *serv, void *context)
+ {
+ struct gdbserv_target *my_target;
-Handling the connection:
+ if (!new_connection_okay ())
+ return NULL;
-The server is capable of handling several connections (named, sessions)
-simultaneously. This is possible because each session data is kept on
-an instance of a GDBSERV object. A routine called gdbserv_fromclient_attach()
-is called when a connection request is received by the socket.
-If the connection is accepted, a new instance of a GDBSERV object is returned,
-otherwise NULL is returned indicating that it has been rejected (a EOF will be
-sensed on the other end).
+ my_target = malloc (sizeof (struct gdbserv_target));
+ if (!my_target)
+ return NULL;
+ memset (my_target, 0, sizeof (struct gdbserv_target));
-The server will, in turn, pass the request onto the target. The target can
-either reject the connection (returning NULL) or accept the connection
-(returning a target object). That is where you come in.
+ my_target->get_reg = my_get_reg;
+ my_target->set_reg = my_set_reg;
+ ...
-You must provide a routine like (please see the precise API in the header file
-include/gdbserv-client.h):
-
-typedef struct gdbserv_target *(gdbserv_target_attach) (struct gdbserv *gdbserv, void *attatch_data);
-
-This will be called by the server to notify that the client has initiated a
-connection. You must return a GDBSERV_TARGET struct for the session or null
-if your target has rejected the connection.
-
-The recommended way to create your gdbserv_target object is:
-
-struct gdbserv_target *gdbtarget = malloc (sizeof (struct gdbserv_target));
-memset (gdbtarget, 0, sizeof (*gdbtarget));
-gdbtarget->process_get_gen = process_get_gen;
-(...)
-
-If you initialize it like this, you will not have to change your code even if
-new entries are added to this struct.
+ perform_other_initializations ();
+ return my_target;
+ }
Handling target events:
-The fromtarget_* routines may be called by your target. Before you
-despair, let me tell you that they are only three: reset, break and
-exit. They indicate that some interesting condition happened in your
-target that requires debugger attention. Reset and exit are quite
-obvious and break is for everything else. These routines must *not*
-be called from within a gdbserv_target callback function, so it may be
-necessary for your target to set some flags to signal state change
-calls later.
-
-If your target is a simulator, call those when the corresponding
-condition arises in your simulated target. If it is a board, it will
-probably be called from your ISRs. A special case occurs if your
-target is a device that has to be polled in order to detect state
-changes. If this is the case, you will call these routines from the
-polling code.
-
-
-The main loop:
-
-At some point you must get things going by:
-
-1) looking for connection requests from gdb and
-2) causing remote protocol commands to be read from the input port (socket).
-
-You must (repeatedly) call a function called gdbloop_poll(). This
-will be in your main loop. If it is a server it will be in your
-main() function. If it is a simulator that also accepts input from
-other sources, it will have to be added to the existing main loop. If
-it is a board, it will probably be called from the timer ISR.
-
-Before doing that you must initialize your socket interface. Look in
-the main() routine of the sample program to see what to call. When
-calling gdbsocket_startup() you must give the address of the callback
-that handles connection requests for your target.
-
-If your target has to be polled for state changes, you will have to alternate
-calls to poll() and to check your target status. As I mentioned before,
-your status checking routine must call the appropriate fromtarget_* function.
-
-
-The callbacks:
-
-All that is left now is to implement your callbacks, which are, directly or
-indirectly, called as a result of a remote protocol packet being received and
-processed by some fromclient_* routine. I will assume that the remote
-protocol packets are known. If not, please refer to the "Remote Protocol"
-section of the gdb manual. There you will find how your target should be
-affected by each packet and what the response should be. It is always
-useful to look at what some other remote targets do as well.
-
-The list of all callbacks with the situation in which they are invoked can be
-found in the header file lib/gdbserv-target.h.
-
-Have fun!
-
-
-
-Appendix
---------
-
-SCENARIOS
-
-
-ATTACH: Creating a connection into the server/target.
-
-Client receives a connect request from the remote GDB. A socket
-interface would see this as an attach. For Cygmon this is the
-``transfer'' command.
-
-The client creates an output object (struct gdbserv_client) and passes
-that and the target side attach function onto GDBSERV. SERVER will
-then initialize itself and call ``to_target_attach'' for final
-approval of the request.
-
- struct gdbserv_client *client;
- ...
- client->write = client_write_to_output_port;
- client->data = ... local state ...
- server = gdbserv_fromclient_attach (client, to_target_attach,
- target_data);
-
-The target_attach() function is expected to either create and return a
-gdbserv_target object or return NULL. The latter indicates that the
-connection request is rejected.
-
-Finally gdbserv_fromclient_attach() returns a SERVER state object that
-should be passed to all client->server calls.
-
-
-DATA-IN: Data being sent to the client from the remote GDB
-
-The client passes the data vis:
-
- len = read (fd, buf, sizeof (buf));
- gdbserv_fromclient_data (server, buf, len);
-
-
-BREAK-IN: Request to stop sent to the client from the remote GDB
-
-The client passes the request to SERVER:
-
- server.c:
-
- volatile
- break_handler ()
- {
- gdbserv_fromclient_break (server);
- }
-
-If the target is currently running, the server will in turn pass the
-request onto the TARGET:
-
- ->target->break_program (server);
+The "gdbserv_fromtarget" prefixed routines are called by your
+target-specific code, however they must not be called from any of the
+gdbserv_target callback functions. (Use of a flag or flags for
+indicating a state change that is checked at some later time is
+recommended.) There are essentially only three of these routines that
+you need to be concerned with. They are:
+
+ void gdbserv_fromtarget_reset (struct gdbserv *gdbserv, int sigval);
+ void gdbserv_fromtarget_exit (struct gdbserv *gdbserv, int sigval);
+ void gdbserv_fromtarget_break (struct gdbserv *gdbserv, int sigval);
+
+The first two (gdbserv_fromtarget_reset and gdbserv_fromtarget_exit)
+are used to indicate target reset and program exit. The latter,
+gdbserv_fromtarget_break, is used in all other situations to indicate
+that the target has stopped for some reason (indicated by sigval).
+
+If your target is a simulator, these "gdbserv_fromtarget" prefixed
+routines should be called when the corresponding condition arises in
+your simulated target. If your target is a board, these functions
+might be invoked from your interrupt service routines. If you target
+is a device that has to be polled to detect state changes, you'll call
+these routines from the polling code.
+
+The Event Loop:
+
+The RDA library uses an event driven model. The function gdbloop_poll()
+causes the library to:
+
+ 1) Look for and handle new connection requests from a debugger.
+ 2) Read remote protocol commands from a stream associated with an
+ already connected debugger and invoke one or more of the
+ callbacks that you have registered.
+
+A single argument is passed to gdbloop_poll() indicating the length of
+time to wait for an event to occur. A negative value will cause
+gdbloop_poll() to block as long as needed for something to happen.
+Otherwise, the integer passed to gdbloop_poll is the time in
+milliseconds to wait for an event to occur.
+
+If your RDA application is structured as a server, then gdbloop_poll()
+will be called repeatedly in the main loop. If the RDA application is
+part of a simulator, then a call to gdbloop_poll() should be added to
+the existing main loop. If a debugging stub for a board is being
+implemented, then gdbloop_poll() should be invoked periodically,
+perhaps in response to a timer interrupt.
+
+If your target has to be polled for state changes, you will have to
+alternate calls to gdbloop_poll() with polls of the target status.
+As noted earlier, one of the "gdbserv_fromtarget" prefixed functions
+is called to indicate a change of state (stop, exit, or reset).
+
+Callbacks:
+
+Recall that gdbsocket_startup() is given, as one of its arguments,
+the address of a function which is called to register a set of
+callbacks via a gdbserv_target struct. You will, of course, have
+to implement each these callbacks.
+
+Some knowledge of the GDB remote protocol will be required. Refer to
+the appendix of the GDB manual entitled "GDB Remote Serial Protocol"
+for these details. Here is a link (which may or may not work):
+
+ http://sourceware.org/gdb/current/onlinedocs/gdb_33.html#SEC691
+
+The layout of the gdbserv_target struct is defined in the RDA
+source tree in the header file include/gdbserv-target.h. (Most
+of the callbacks are discussed below.)
+
+Finally, it should prove useful to examine samples/demo-target.c,
+unix/thread-db.c, and unix/linux-target.c to see how these RDA
+applications implement the various callbacks.
+
+Register Related Callbacks
+--------------------------
+
+The register related callbacks are probably the most confusing because
+there are many of them. Moreover, not all of them should be
+implemented.
+
+If your target has a concept of threads and you want GDB to be able to
+debug these threads, you should implement the threaded register
+processing callbacks. These are next_gg_reg, next_expedited_reg,
+reg_format, set_thread_reg and get_thread_reg. Even if your
+target is single-threaded, you should consider using these
+methods anyway.
+
+If you target does not use threads you may instead implement the
+following methods: input_reg, output_reg, gg_reg_nr,
+expedited_reg_nr, sizeof_reg, set_reg, and get_reg.
+
+Finally, there are an older set of register related callbacks that
+should be avoided. These are: process_set_reg, process_get_reg,
+process_set_regs, and process_get_regs. These older callbacks will
+not be discussed further.
+
+The thread aware register related callbacks are as follows:
+
+ int (*next_gg_reg) (struct gdbserv *, struct gdbserv_thread *,
+ int reg_nr);
+ int (*next_expedited_reg) (struct gdbserv *, struct gdbserv_thread *,
+ int reg_nr);
+ int (*reg_format) (struct gdbserv *, struct gdbserv_thread *,
+ int reg_nr, int *size, int *padding);
+ int (*set_thread_reg) (struct gdbserv *, struct gdbserv_thread *,
+ int regnr, const struct gdbserv_reg *reg);
+ int (*get_thread_reg) (struct gdbserv *, struct gdbserv_thread *,
+ int regnr, struct gdbserv_reg *reg);
+
+ All of these thread aware register related callbacks are passed a
+ pointer to a gdbserv object, as well as a pointer to a target
+ defined thread object (struct gdbserv_thread *). (You will need
+ to define the layout of struct gdbserv_thread.)
+
+ The ``next_gg_reg'' callback is used by the RDA library to iterate
+ over the registers in a 'G' or 'g' packet. (A 'g' packet is used
+ to read general purpose registers. A 'G' packet is used to write
+ them.) Thus, the ``next_gg_reg'' callback effectively defines
+ the registers that are in a 'G' or 'g' packet and their order.
+ This function is initially called with the reg_nr parameter set to
+ -1. This callback should be implemented to return the register
+ number of the first register when reg_nr is -1. After that, it is
+ called successively with its previous return value in order to
+ obtain successive register numbers. next_gg_reg() should return a
+ negative value (such as -1) when the end of the list is reached.
+ (Technically, the end of list is reached on the call prior to the
+ one that returns -1.)
+
+ The ``next_expedited_reg'' callback is optional. It is used to
+ construct the list of values to include in a 'T' (stop reply)
+ packet. The RDA library will initially call next_expedited_reg()
+ with reg_nr set to -1 in order to obtain the first register (as
+ the return value of the callback), and will, on successive calls,
+ be called with the previous return value. A negative value should
+ be returned when there are no more values to return.
+
+ Although the ``next_expedited_reg'' callback is optional, it is
+ strongly recommended that you implement it. Defining this method
+ will permit the RDA library to send register values to GDB that it
+ will almost certainly need. Examples of registers that should be
+ included in the 'T' packet include the stack pointer and program
+ counter. If this callback is not defined, RDA will not send any
+ registers to GDB in the stop reply packet. GDB will then need to
+ use a 'g' packet to retrieve all values (even if all values aren't
+ required).
+
+ The ``reg_format'' method describes format of the register given
+ by reg_nr in the 'g' and 'G' packets. This method should set
+ ``size'' to the width (in bytes) of the register given by
+ ``reg_nr''. (Due to the representation of bytes in the remote
+ protocol, 2*size bytes will actually be input or output.) If
+ padding is required in the 'g' or 'G' packet, then ``padding''
+ should be set to the number of bytes of padding required. Again,
+ 2*size bytes will be actually be output. A negative value of
+ padding indicates that the padding should preceded the register
+ value. A positive value places the padding after the register
+ value. Note that the ``size'' and ``padding'' parameters are
+ actually pointers, and that suitable pointer dereferencing is
+ required when setting these as return values.
+
+ The ``set_thread_reg'' method is used to change the value of the
+ register specified by ``regnr'' to that of the value specified in
+ ``reg'' parameter. (The new register value does not actually need
+ to be set until the target is made to run again (in some fashion).
+ Thus, it is permissible for your target specific code to
+ accumulate the changes to be made to the registers and update them
+ all at once if that is more efficient or convenient.) Return
+ 0 if successful, or -1 if not.
+
+ The ``get_thread_reg'' method is used to retrieve the value of
+ the register specified by ``regnr''. The value should be placed
+ in ``reg''. Return 0 if successful, or -1 if not.
+
+The non-threaded register related callbacks are as follows:
+
+ int (*input_reg) (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int len);
+ void (*output_reg) (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int len);
+ int (*gg_reg_nr) (struct gdbserv *, int index);
+ int (*expedited_reg_nr) (struct gdbserv *, int index);
+ long (*sizeof_reg) (struct gdbserv *, int regnr);
+ int (*set_reg) (struct gdbserv *, int regnr, struct gdbserv_reg *reg);
+ int (*get_reg) (struct gdbserv *, int regnr, struct gdbserv_reg *reg);
+
+ Each of these methods is passed passed a pointer to a gdbserv
+ object.
+
+ The ``input_reg'' method should be set to one of two predefined
+ methods, either gdbserv_input_reg_beb(), for reading big endian
+ data, or gdbserv_input_reg_leb(), for reading little endian data.
+ It is unlikely that you'll need to define some custom method for
+ reading or writing data.
+
+ Likewise, the ``output_reg'' method should be set to one of two
+ predefined methods, either gdbserv_output_reg_beb() or
+ gdbserv_output_leb(). Again, it is unlikely that you'll need to
+ define some custom method for reading or writing data.
+
+ The ``gg_reg_nr'' method is used by the RDA library to obtain
+ register numbers for 'G' or 'g' packets. (A 'g' packet is used to
+ read general purpose registers. A 'G' packet is used to write
+ them.) The library will initially invoke this method with index
+ set to 0 and will successively increase the value passed as
+ index by 1 until gg_reg_nr returns a negative value. This method
+ should return the register number associated with the given index
+ (in the 'g' or 'G' packet). It should do so even if there is a
+ hole or undefined register in the packet, and only return -1 when
+ there truly are no more registers.
+
+ The ``expedited_reg_nr'' method works the same as ``gg_reg_nr''
+ except that it specifies the registers in a 'T' (stop reply)
+ packet. See the discussion above for ``next_expedited_reg''.
+
+ The ``sizeof_reg'' method is used to return the size in bytes
+ of the register specified by ``regnr''. (The ``regnr'' value
+ passed to sizeof_reg() is obtained from either gg_reg_nr() or
+ expedited_reg_nr(). See above.) Due to the way that register
+ values are transmitted using the GDB remote protocol, 2*size bytes
+ are actually output. Finally, a negative size (return) value
+ indicates a hole in the 'G' or 'g' packet, i.e. space is allocated
+ in the packet, but there's no corresponding register in your
+ target.
+
+ The ``set_reg'' method is used to update the value specified
+ by ``regnr'' in your target to that of the value specified
+ by the ``reg'' parameter. Return 0 if successful, -1 if not.
+
+ The ``get_reg'' method is used to fetch the value specified by
+ ``regrn'' from your target. It should be placed in the
+ gdbserv_reg struct specified by ``reg''. Return 0 if successful,
+ -1 if not.
+
+Dealing with gdbserv_reg * values
+---------------------------------
+
+Some of the callbacks have parameters of type `struct gdbserv_reg *'.
+This type is used to specify the value of registers, and is quite
+often used to specify addresses and other integral values as well.
+The RDA library provides several functions for converting to/from
+this type and an array of bytes.
+
+These functions which put an array of bytes into a gdbserv_reg
+struct are as follows:
+
+ void gdbserv_be_bytes_to_reg (struct gdbserv *gdbserv,
+ const void *buf,
+ int buflen,
+ struct gdbserv_reg *reg,
+ int reglen,
+ int sign_extend);
+ void gdbserv_le_bytes_to_reg (struct gdbserv *gdbserv,
+ const void *buf,
+ int buflen,
+ struct gdbserv_reg *reg,
+ int reglen,
+ int sign_extend);
+ void gdbserv_host_bytes_to_reg (struct gdbserv *gdbserv,
+ const void *buf,
+ int buflen,
+ struct gdbserv_reg *reg,
+ int reglen,
+ int sign_extend);
+
+ In each case, `gdbserv' represents the gdbserv object, `buf' is
+ the array of bytes to to convert, `buflen' is the number of bytes
+ in the buffer `buf', `reg' is the gdbserv_reg struct into which
+ the value should be placed, `reglen' is the size of the register,
+ and `sign_extend' is non-zero iff the value should be
+ sign-extended. (To the best of my knowledge, the only
+ architecture which requires sign extension is MIPS.)
+
+ Each of these methods handles a different byte order. The
+ ``gdbserv_be_bytes_to_reg'' method converts a buffer of big-endian
+ bytes to the gdbserv_reg format. Likewise,
+ ``gdbserv_le_bytes_to_reg'' and ``gdbserv_host_bytes_to_reg''
+ convert little endian and host format bytes. The latter method is
+ really a convenience function which just picks either the big
+ endian or little endian formatter based on the endianess of the
+ host that the RDA application is being built upon.
+
+ For example, suppose you are interfacing the RDA library to a
+ simulator which resides in the same process. If the variable
+ ``regval'' has a register's value, this value may be put into
+ the gdbserv_reg format as follows:
+
+ unsigned long regval;
+ struct gdbserv_reg regval_as_reg;
+
+ regval = ...
+
+ gdbserv_host_bytes_to_reg (serv, ®val, sizeof(regval),
+ &addr_as_reg), sizeof(regval), 0);
+
+Conversely, these functions (below) convert the value found in a
+gdbserv_reg struct into an array of bytes:
+
+ void gdbserv_be_bytes_from_reg (struct gdbserv *gdbserv,
+ void *buf,
+ int buflen,
+ const struct gdbserv_reg *reg,
+ int sign_extend);
+
+ void gdbserv_le_bytes_from_reg (struct gdbserv *gdbserv,
+ void *buf,
+ int buflen,
+ const struct gdbserv_reg *reg,
+ int sign_extend);
+
+ void gdbserv_host_bytes_from_reg (struct gdbserv *gdbserv,
+ void *buf,
+ int buflen,
+ const struct gdbserv_reg *reg,
+ int sign_extend);
+
+ In each of these functions, ``gdbserv'' is a pointer o the gdbserv
+ object, ``buf'' is a pointer to the array of bytes into which to place
+ a value, ``buflen'' is the length of the buffer ``buf'', ``reg'' is
+ a pointer to the gdbserv_reg struct to convert from, and ``sign_extend''
+ is non-zero iff sign-extension should be performed in the event that
+ ``buf'' is bigger than the size of the register.
+
+Memory Related Callbacks
+------------------------
+
+Like the register related callbacks, the memory related callbacks come in
+two varieties, threaded and non-threaded. You only need to implement one
+set of these callbacks. The only difference between these callbacks is
+the fact that a thread object is passed to the threaded-version.
+
+Here are the thread aware versions of the memory callbacks:
+
+ long (*get_thread_mem) (struct gdbserv *, struct gdbserv_thread *,
+ struct gdbserv_reg *addr, void *data, long len);
+ long (*set_thread_mem) (struct gdbserv *, struct gdbserv_thread *,
+ struct gdbserv_reg *addr, void *data, long len);
+
+ Both of these functions are passed both the gdbserv object and
+ a thread object. The ``addr'' parameter represents the target
+ memory address to either read or write. The ``data'' parameter is
+ a pointer to the buffer to either deposit data into or from which
+ data is written. The ``len'' parameter is the number of bytes
+ that should be read or written.
+
+ The ``get_thread_mem'' callback attempts to read the specified
+ number of bytes from the target and place them into the buffer.
+ It returns the number of bytes successfully read, or -1 if the
+ memory read completely fails.
+
+ The ``set_thread_mem'' callback attempts to write the specified
+ number of bytes from the buffer provided to the target's memory.
+ It returns the number of bytes successfully written, or -1 if
+ the memory write completely fails.
+
+Here are the non-thread-aware memory callbacks:
+
+ long (*get_mem) (struct gdbserv *, struct gdbserv_reg *addr, void *data,
+ long len);
+ long (*set_mem) (struct gdbserv *, struct gdbserv_reg *addr, void *data,
+ long len);
+
+ The gdbserv object is passed to these functions. The ``addr''
+ parameter represents the target memory address to either read or
+ write. The ``data'' parameter is a pointer to the buffer to
+ either deposit data into or from which data is written. The
+ ``len'' parameter is the number of bytes that should be read or
+ written.
+
+ The ``get_mem'' callback attempts to read the specified number of
+ bytes from the target and place them into the buffer. It returns
+ the number of bytes successfully read, or -1 if the memory read
+ completely fails.
+
+ The ``set_mem'' callback attempts to write the specified number of
+ bytes from the buffer provided to the target's memory. It returns
+ the number of bytes successfully written, or -1 if the memory
+ write completely fails.
+
+General Query Packets / General Set Packets
+-------------------------------------------
+
+General query packets start with a 'q' prefix and general set packets
+begin with a 'Q' prefix. In recent years, nearly all new extensions
+to the remote protocol have added either a new 'q' or 'Q' packet, or
+both.
+
+There are a number of general query packets defined by the remote
+protocol. The RDA library currently recognizes the 'qRcmd', 'qCRC:',
+'qC', 'qfThreadInfo', 'qsThreadInfo', and 'qThreadExtraInfo' packets.
+For all other 'q' and 'Q' packets, you will need to implement a
+callback which parses everything after the 'q' or 'Q', including the
+packet's parameters (if any), queries the target in an appropriate
+manner, and then formats and outputs the response.
+
+When a unrecognized 'q' packet is received from the client, the
+``process_get_gen'' method is called. Here's the prototype:
+
+ void (*process_get_gen) (struct gdbserv *);
+
+When any 'Q' packet is received from the client, the ``process_set_gen''
+method is called. Here's the prototype:
+
+ void (*process_set_gen) (struct gdbserv *);
+
+The 'qRcmd' packet is used to invoke arbitrary target specific
+commands. Results from these commands are usually directly printed
+out to GDB's console. Reciept of the qRcmd packet causes
+``process_rcmd'' callback to be invoked. Here's the prototype:
+
+ void (*process_rcmd) (struct gdbserv *, const char *cmd,
+ int sizeof_cmd);
+
+Each of these callbacks is passed a pointer to a gdbserv object. The
+``process_rcmd'' callback is passed two additional parameters, ``cmd'',
+a string representing the target specific command, and ``sizeof_cmd'' which
+represents the length of ``cmd''. (Do not assume that ``cmd'' will be
+null-terminated.)
-and the target will record the break request and then return control
-back to the SERVER. The server returning control to the client.
+When implementing either the ``process_get_gen'' or ``process_set_gen''
+callbacks, the following function is useful for parsing reset of the
+packet name (and delimiters associated with any arguments):
-Later, once the target has halted, the SERVER is notified of the state
-change vis:
+ int gdbserv_input_string_match (struct gdbserv *gdbserv,
+ const char *string);
- target.c:
+gdbserv_input_string_match() will attempt to compare the next portion
+of the input packet against the characters in ``string''. If an
+exact match is found, the number of characters matched is returned
+and that number of characters is advanced in the input packet. If
+the characters in ``string'' are not matched exactly, and in their
+entirety, -1 is returned.
- gdbserv_fromtarget_break (server);
+Hex encoded numeric arguments may be parsed from the 'q' or 'Q' packet
+by invoking gdbserv_input_hex_long() or gdbserv_input_hex_ulong():
+ int gdbserv_input_hex_long (struct gdbserv *gdbserv, long *val);
-NB: Often ``break'' is sent across the stream interface as a special
-character sequence.
+ int gdbserv_input_hex_ulong (struct gdbserv *gdbserv,
+ unsigned long *val);
-FIXME: gdbserv-input.c should be able to parse such character
-sequences.
+In both of these functions, the ``val'' parameter is a pointer to either
+a long or unsigned long into which to put the decoded integer. If no
+number could be matched, a -1 is returned.
+There are a number of functions which may be used to compose and
+output a reply. Here are several of the more useful ones:
-DATA-OUT: Data for the remote GDB from SERVER
+ void gdbserv_output_string (struct gdbserv *gdbserv, const char *buf);
-The ``write'' function specified in the ``struct gdbserv_client''
-object is called.
+ void gdbserv_output_string_as_bytes (struct gdbserv *gdbserv,
+ const char *buf);
+ void gdbserv_output_bytes (struct gdbserv *gdbserv, const char *buf,
+ unsigned sizeof_buf);
-DETACH: Remote GDB disconnects from the SERVER
+gdbserv_output_string() outputs the string specified by ``buf''
+verbatim. gdbserv_output_string_as_bytes() outputs a string, ``buf'',
+as a hex encoded value. Finally, gdbserv_output_bytes(), outputs an
+abitrary sequence of bytes given by ``buf'' with length ``sizeof_buf''
+as a hex encoded value.
-The CLIENT notifies SERVER via the gdbserv_fromclient_detach() call.
+There exist several other "gdbserv_input_" and "gdb_serv_output_"
+prefixed functions. Declarations for these may be found in
+include/gdbserv.h.
+Callback for Setting Program Arguments
+--------------------------------------
-HARD-RESET: A hard reset is performed on a serial board.
+The 'A' packet is used to set program arguments. When the 'A' packet is
+recognized, the process_set_args() callback is invoked. It has the following
+prototype:
-Assuming a standalone system, the client/target side sequences would
-be performed:
+ void (*process_set_args) (struct gdbserv *);
- /* create the server */
- server = gdbserv_fromclient_attach (...);
- /* notify the server that the target was just reset */
- gdbserv_fromtarget_reset (server);
+Notice that the library does not decode the arguments. Suitable calls
+to the various "gdbserv_input_" functions must be called to parse
+these arguments.
+Callback for setting the PC
+---------------------------
-WRITE-MEMORY: GDB sends the server a write-memory packet.
+When a 'c' or 's' (continue or singlestep) packet is received with the
+address to continue from the ``process_set_pc'' callback is invoked.
+Its prototype is as follows:
-Eventually SERVER passes the request onto the TARGET with the call:
+ void (*process_set_pc) (struct gdbserv *, const struct gdbserv_reg *val);
- ->target->process_set_mem (server, addr, len);
+The ``val'' parameter species the PC value to set.
-where ADDR and LEN contain the uninterpreted address/length of the
-data to follow. target_process_set_mem() might be implemented as:
+Callback for Flushing the Instruction Cache
+-------------------------------------------
- long long addr;
- long int;
- gdbserv_reg_to_ulonglong (server, reg_addr, &addr);
- gdbserv_reg_to_ulong (server, reg_len, &len);
- /* just blat local memory */
- len = gdbserv_input_bytes (server, addr, len);
-
+The ``flush_i_cache'' callback is invoked prior to continuing or
+singlestepping the program. This callback should do whatever
+operations are required in order to invalidate the instruction cache.
+Its prototype is:
+
+ void (*flush_i_cache) (struct gdbserv *);
-READ-MEMORY: GDB requests memory from the target.
+Signal Related Callbacks
+------------------------
-Eventually target_process_get_mem() function is called. An
-implementation may look like:
+Non-threaded targets should define the ``process_signal'' callback. This
+callback specifies the signal to deliver to the target when either a
+'C' or 'S' packet is used. (The 'C' packet continues the program with a
+given signal; the 'S' packet singlesteps the program with the given signal.)
+The prototype for ``process_signal'' is:
- gdbserv_reg_to_ulonglong (gdbserv, reg_addr, &addr);
- gdbserv_reg_to_ulong (gdbserv, reg_len, &len);
- /* assume we're reading raw memory from the local mc */
- gdbserv_output_bytes (gdbserv, addr, len);
+ int (*process_signal) (struct gdbserv *, int sigval);
+The ``sigkill_program'' method is invoked if ``process_signal'' fails
+to deliver a signal. This method will not deliver the desired signal,
+but should instead kill the program. This method should not really be
+needed so long as the ``process_signal'' exists and works properly.
+Here's the prototype:
-TARGET-RESUME: GDB requests that the target resume execution.
+ void (*sigkill_program) (struct gdbserv *);
-Eventually ->target->continue_program() is called. That function
-should record the request and then wait for SERVER to exit before
-actually continuing the target.
+There are two other signal related callbacks, ``compute_signal'' and
+``get_trap_number''. Neither of these are called by the RDA library
+though. New RDA applications do not need to define these callbacks.
---
+Target State/Control Callbacks
+--------------------------------
+The ``exit_program'' callback is invoked when a 'k' (kill) packet is
+received from the client. It's prototype is as follows:
+
+ void (*exit_program) (struct gdbserv *);
+
+The ``break_program'' callback is invoked when a request to halt,
+suspend, or break the target is received from the client. This
+callback should do whatever is necessary to direct the target to stop.
+Later, when the target has actually stopped, the function
+gdbserv_fromtarget_break() should be called to indicate that it has
+indeed stopped. The ``break_program'' callback must NOT call
+gdbserv_fromtarget_break(). Here's the prototype:
+
+ void (*break_program) (struct gdbserv *);
+
+The ``reset_program'' callback is invoked when an 'r' (reset system)
+packet is recieved from the client. The ``reset_program'' callback
+is invoked when an 'R' (reset program) packet is received. The
+prototypes for these methods are as follows:
+
+ int (*reset_program) (struct gdbserv *);
+ void (*restart_program) (struct gdbserv *);
+
+The ``singlestep_thread'' or ``singlestep_program'' callbacks are
+invoked for 's' (singlestep) or 'S' (singlestep with signal) packets.
+Only one of these methods needs to be implemented. If the
+``singlestep_thread'' method is defined, it will be tried before the
+``singlestep_program'' is invoked. The ``singlestep_thread'' method
+is passed a pointer to a gdbserv object, a pointer to a thread object,
+as well as the signal, ``siggnal'' to continue with. The
+``singlestep_program'' method is only passed the gdbserv object. Care
+must be taken to also define ``process_signal'' when only
+``singlestep_program'' is defined. Here are the prototypes:
+
+ void (*singlestep_thread) (struct gdbserv *, struct gdbserv_thread *,
+ const struct gdbserv_reg *signnal);
+ void (*singlestep_program) (struct gdbserv *);
+
+The ``cyclestep_thread'' and ``cyclestep_program'' callbacks are invoked
+in response to an 'i' (cycle step) packet. Only one of these methods
+need to be define, and as before, the thread-specific method is tried
+first. The prototypes are as follows:
+
+ void (*cyclestep_thread) (struct gdbserv *, struct gdbserv_thread *,
+ const struct gdbserv_reg *signnal);
+ void (*cyclestep_program) (struct gdbserv *);
+
+The ``continue_thread'' or ``continue_program'' callbacks are invoked
+in response to either a 'c' (continue) or 'C' (continue with signal)
+packet. As before, only one of these methods needs to be defined.
+The thread-specific method is tried first. The ``continue_thread''
+method is passed the signal, ``signnal'', to continue with (in
+addition to the gdbserv object and the gdbserv_thread object). The
+``continue_program'' method is not passed a signal, thus the
+``process_signal'' must be defined in order for the signal to be
+delivered to the target. Here are the prototypes:
+
+ void (*continue_thread) (struct gdbserv *, struct gdbserv_thread *,
+ const struct gdbserv_reg *signnal);
+ void (*continue_program) (struct gdbserv *);
+
+Breakpoint Callbacks
+--------------------
+
+The ``set_breakpoint'' and ``remove_breakpoint'' callbacks are invoked
+in response to the 'z' (set breakpoint) and 'Z' (remove breakpoint)
+packets respectively. If these operations do are not defined here,
+that fact will be reported to GDB and GDB will attempt to set software
+breakpoints via reads and writes to memory. The prototypes for these
+callbacks are as follows:
+
+ enum gdbserv_target_rc (*set_breakpoint) (struct gdbserv *,
+ enum gdbserv_target_bp type,
+ struct gdbserv_reg *addr,
+ struct gdbserv_reg *len);
+ enum gdbserv_target_rc (*remove_breakpoint) (struct gdbserv *,
+ enum gdbserv_target_bp type,
+ struct gdbserv_reg *addr,
+ struct gdbserv_reg *len);
+
+The return status codes (of type enum gdbserv_target_rc) for these methods
+may be one of the following:
+
+ GDBSERV_TARGET_RC_ERROR - Operation failed; reply with an 'Enn' error.
+ (The breakpoint methods reply with 'E03'.)
+ GDBSERV_TARGET_RC_OK - Operation succeeded; reply with 'OK'.
+ GDBSERV_TARGET_RC_UNKNOWN - Operation not supported; send no reply.
+ This null reply signals to GDB that the
+ operation is not supported. For many
+ operations, GDB will attempt to find
+ an alternate mechanism to use, or will
+ continue on as best as it can.
+
+The ``type'' parameter for these methods (of type enum gdbserv_target_bp)
+may be one of the following:
+
+ GDBSERV_TARGET_BP_SOFTWARE - Software breakpoint.
+ GDBSERV_TARGET_BP_HARDWARE - Hardware breakpoint.
+ GDBSERV_TARGET_BP_WRITE - Write watchpoint.
+ GDBSERV_TARGET_BP_READ - Read watchpoint.
+ GDBSERV_TARGET_BP_ACCESS - Access (read or write) watchpoint.
+
+Note too that the address, ``addr'', at which to set the breakpoint or
+watchpoint is specified using a gdbserv_reg struct. The length,
+``len'', is also specified using this type. See the section entitled
+"Dealing with gdbserv_reg * values" for a list of functions which
+may be used for accessing the values stored in these containers.
+
+Thread Related Callbacks
+------------------------
+
+The ``thread_info'' callback is called in response to the
+'qThreadExtraInfo' packet. It allocates and returns a string
+containing printable information about the thread specified by the
+parameter ``thread''. This information is returned to GDB for use in
+its "info threads" command. Its prototype is as follows:
+
+ char *(*thread_info) (struct gdbserv *, struct gdbserv_thread *thread);
+
+The ``thread_id'' callback is used to map the thread specified by
+``thread'' to a unique identifier (an integer) shared between GDB and
+the RDA application. The integer needs to be placed into a gdbserv_reg
+container. Its prototype is as follows:
+
+ char *(*thread_info) (struct gdbserv *, struct gdbserv_thread *thread);
+
+The ``thread_lookup_by_id'' callback is used to map a thread id, ``id'',
+to a thread, ``thread'', of type ``struct gdbserv_thread *''. It
+should return a positive integer if ``id'' uniquely identifies a
+thread. It should return 0 and select an arbitrary thread if the
+thread ID is zero. Otherwise, it should return -1 and select an
+arbitrary thread if the ID does not uniquely identify a thread or if
+the thread id is invalid. Here's the prototype:
+
+ int (*thread_lookup_by_id) (struct gdbserv *,
+ const struct gdbserv_reg *id,
+ struct gdbserv_thread **thread);
+
+The ``thread_next'' callback is used to iterate over all threads known
+to the RDA application. The GDB library will start off by calling the
+``thread_next'' callback with the ``thread_last'' parameter set to
+NULL and expect the first thread to be returned. (It doesn't really
+matter which thread is first, so long as all threads are eventually
+enumerated.) On successive calls, ``thread_next'' will be called with
+the previous thread returned as the value of ``thread_last'', with the
+expectation that the next (for some suitable meaning of "next") thread
+be returned. When there are no more threads, NULL is returned.
+Here's the prototype:
+
+ struct gdbserv_thread *(*thread_next) (struct gdbserv *,
+ struct gdbserv_thread *thread_last);
+
+Unknown Packet Callback
+-----------------------
+
+The ``process_target_packet'' callback is invoked when a packet is
+seen that does not start with one of the letters used by the remote
+protocol. Here's the prototype:
+
+ void (*process_target_packet) (struct gdbserv *);
+
+Note: This method is probably not all that useful given that the
+leading packet character is consumed by the the caller of the
+``process_target_packet'' callback.
+
+Shutdown Callback
+-----------------
+
+The ``detach'' callback is invoked when an end-of-file condition is
+sensed on the input stream. Note that the second parameter,
+``target'' is a pointer to the data structure containing the list of
+callbacks originally allocated by the ``attach'' method. It is passed
+to the ``detach'' callback so that the callback struct can be
+deallocated. Here's the prototype:
+
+ void (*detach) (struct gdbserv *, struct gdbserv_target *target);
--- /dev/null
+How to implement a stub or server using RDA (Red Hat Debug Agent and library).
+==================================================
+Andrew Cagney <cagney@cygnus.com>
+Fernando Nasser <fnasser@cygnus.com>
+Frank Eigler <fche@cygnus.com>
+
+Introduction
+------------
+
+This is the implementation of a server for the gdb remote protocol.
+It is available as a host library that provides most of the common code
+required. By adding a relatively small amount of target dependent code,
+one can build a server that allows gdb to connect to that target using
+the gdb "target remote" command.
+
+Gdb connects to this server through a TCP/IP connection. The server
+waits for a connection from GDB by listening to a non-restricted TCP port.
+Anyone with GDB (or even telnet) network connectivity to the machine
+running the server can initiate a connection to it.
+
+Note: The user of this software is advised to ensure
+that access to the TCP port being used is restricted to
+secure siblings. For instance, the user may need to take
+action that ensures that `The Internet' is not able to access
+the TCP port being used.
+
+Architecture
+------------
+
+The following diagram shows the components of RDA.
+
+ (GDB) <---"remote"---> CLIENT <--> SERVER <--> TARGET
+ ------- ------------------------------
+ The client. The server.
+
+Where:
+
+ CLIENT Provides the raw interface between
+ GDB and the internal SERVER
+ mechanism.
+
+ The client passes on any data relevant
+ to the server. The SERVER presents
+ CLIENT with raw output to be returned
+ to GDB.
+
+ SERVER Implements the state-machine that
+ is capable of decoding / processing
+ various GDB remote protocol requests.
+
+ TARGET The embedded system proper. SERVER
+ passes decoded requests onto the TARGET
+ while TARGET notifies the SERVER of any
+ target state changes.
+
+
+Looking at SERVER in more detail, that component consists of three sub
+components INPUT, OUTPUT and STATE. Visually:
+
+ .------------ fromtarget_*
+ \|/
+ fromclient_* -> INPUT -> STATE (M/C) -> target->*
+ /|\ |
+ |
+ \|/ |
+ client->write <- OUTPUT <----'
+
+Where:
+
+ INPUT Filters the raw input stream from the client
+ breaking it up into complete packets and
+ passing them onto STATE.
+
+ This component co-operates with OUTPUT for
+ the ACK/NAK of input packets.
+
+ OUTPUT Wraps up and then passes onto the client
+ raw output packets ready for transmission
+ on the output stream.
+
+ This component co-operates with INPUT for
+ the ACK/NAK of output packets.
+
+ STATE The state machine proper.
+
+
+The Appendix provides various scenarios showing in some detail how typical
+operations are handled by these components. It may be convenient to read the
+next section first before turning to the Appendix.
+
+
+Adding the target dependent code
+--------------------------------
+
+In the following discussion, assume your debugger (gdb) is using
+the remote protocol to communicate with the code you are building here.
+The "target" is a simulator, hardware device, board, program or whatever you
+are interfacing to with your stub/server.
+
+The library provides gdbsocket_*() and gdbserv_fromtarget_*() routines that
+must be called and requires you to set a series of callback routines.
+You make these callbacks known/available to the library by filling the entries
+of a "gdbserv_target" object. You must also provide an extra function that
+will be invoked when a new connection is detected on the input port (a socket).
+
+
+Handling the connection:
+
+The server is capable of handling several connections (named, sessions)
+simultaneously. This is possible because each session data is kept on
+an instance of a GDBSERV object. A routine called gdbserv_fromclient_attach()
+is called when a connection request is received by the socket.
+If the connection is accepted, a new instance of a GDBSERV object is returned,
+otherwise NULL is returned indicating that it has been rejected (a EOF will be
+sensed on the other end).
+
+The server will, in turn, pass the request onto the target. The target can
+either reject the connection (returning NULL) or accept the connection
+(returning a target object). That is where you come in.
+
+You must provide a routine like (please see the precise API in the header file
+include/gdbserv-client.h):
+
+typedef struct gdbserv_target *(gdbserv_target_attach) (struct gdbserv *gdbserv, void *attatch_data);
+
+This will be called by the server to notify that the client has initiated a
+connection. You must return a GDBSERV_TARGET struct for the session or null
+if your target has rejected the connection.
+
+The recommended way to create your gdbserv_target object is:
+
+struct gdbserv_target *gdbtarget = malloc (sizeof (struct gdbserv_target));
+memset (gdbtarget, 0, sizeof (*gdbtarget));
+gdbtarget->process_get_gen = process_get_gen;
+(...)
+
+If you initialize it like this, you will not have to change your code even if
+new entries are added to this struct.
+
+
+Handling target events:
+
+The fromtarget_* routines may be called by your target. Before you
+despair, let me tell you that they are only three: reset, break and
+exit. They indicate that some interesting condition happened in your
+target that requires debugger attention. Reset and exit are quite
+obvious and break is for everything else. These routines must *not*
+be called from within a gdbserv_target callback function, so it may be
+necessary for your target to set some flags to signal state change
+calls later.
+
+If your target is a simulator, call those when the corresponding
+condition arises in your simulated target. If it is a board, it will
+probably be called from your ISRs. A special case occurs if your
+target is a device that has to be polled in order to detect state
+changes. If this is the case, you will call these routines from the
+polling code.
+
+
+The main loop:
+
+At some point you must get things going by:
+
+1) looking for connection requests from gdb and
+2) causing remote protocol commands to be read from the input port (socket).
+
+You must (repeatedly) call a function called gdbloop_poll(). This
+will be in your main loop. If it is a server it will be in your
+main() function. If it is a simulator that also accepts input from
+other sources, it will have to be added to the existing main loop. If
+it is a board, it will probably be called from the timer ISR.
+
+Before doing that you must initialize your socket interface. Look in
+the main() routine of the sample program to see what to call. When
+calling gdbsocket_startup() you must give the address of the callback
+that handles connection requests for your target.
+
+If your target has to be polled for state changes, you will have to alternate
+calls to poll() and to check your target status. As I mentioned before,
+your status checking routine must call the appropriate fromtarget_* function.
+
+
+The callbacks:
+
+All that is left now is to implement your callbacks, which are, directly or
+indirectly, called as a result of a remote protocol packet being received and
+processed by some fromclient_* routine. I will assume that the remote
+protocol packets are known. If not, please refer to the "Remote Protocol"
+section of the gdb manual. There you will find how your target should be
+affected by each packet and what the response should be. It is always
+useful to look at what some other remote targets do as well.
+
+The list of all callbacks with the situation in which they are invoked can be
+found in the header file lib/gdbserv-target.h.
+
+Have fun!
+
+
+
+Appendix
+--------
+
+SCENARIOS
+
+
+ATTACH: Creating a connection into the server/target.
+
+Client receives a connect request from the remote GDB. A socket
+interface would see this as an attach. For Cygmon this is the
+``transfer'' command.
+
+The client creates an output object (struct gdbserv_client) and passes
+that and the target side attach function onto GDBSERV. SERVER will
+then initialize itself and call ``to_target_attach'' for final
+approval of the request.
+
+ struct gdbserv_client *client;
+ ...
+ client->write = client_write_to_output_port;
+ client->data = ... local state ...
+ server = gdbserv_fromclient_attach (client, to_target_attach,
+ target_data);
+
+The target_attach() function is expected to either create and return a
+gdbserv_target object or return NULL. The latter indicates that the
+connection request is rejected.
+
+Finally gdbserv_fromclient_attach() returns a SERVER state object that
+should be passed to all client->server calls.
+
+
+DATA-IN: Data being sent to the client from the remote GDB
+
+The client passes the data vis:
+
+ len = read (fd, buf, sizeof (buf));
+ gdbserv_fromclient_data (server, buf, len);
+
+
+BREAK-IN: Request to stop sent to the client from the remote GDB
+
+The client passes the request to SERVER:
+
+ server.c:
+
+ volatile
+ break_handler ()
+ {
+ gdbserv_fromclient_break (server);
+ }
+
+If the target is currently running, the server will in turn pass the
+request onto the TARGET:
+
+ ->target->break_program (server);
+
+and the target will record the break request and then return control
+back to the SERVER. The server returning control to the client.
+
+Later, once the target has halted, the SERVER is notified of the state
+change vis:
+
+ target.c:
+
+ gdbserv_fromtarget_break (server);
+
+
+NB: Often ``break'' is sent across the stream interface as a special
+character sequence.
+
+FIXME: gdbserv-input.c should be able to parse such character
+sequences.
+
+
+DATA-OUT: Data for the remote GDB from SERVER
+
+The ``write'' function specified in the ``struct gdbserv_client''
+object is called.
+
+
+DETACH: Remote GDB disconnects from the SERVER
+
+The CLIENT notifies SERVER via the gdbserv_fromclient_detach() call.
+
+
+HARD-RESET: A hard reset is performed on a serial board.
+
+Assuming a standalone system, the client/target side sequences would
+be performed:
+
+ /* create the server */
+ server = gdbserv_fromclient_attach (...);
+ /* notify the server that the target was just reset */
+ gdbserv_fromtarget_reset (server);
+
+
+WRITE-MEMORY: GDB sends the server a write-memory packet.
+
+Eventually SERVER passes the request onto the TARGET with the call:
+
+ ->target->process_set_mem (server, addr, len);
+
+where ADDR and LEN contain the uninterpreted address/length of the
+data to follow. target_process_set_mem() might be implemented as:
+
+ long long addr;
+ long int;
+ gdbserv_reg_to_ulonglong (server, reg_addr, &addr);
+ gdbserv_reg_to_ulong (server, reg_len, &len);
+ /* just blat local memory */
+ len = gdbserv_input_bytes (server, addr, len);
+
+
+READ-MEMORY: GDB requests memory from the target.
+
+Eventually target_process_get_mem() function is called. An
+implementation may look like:
+
+ gdbserv_reg_to_ulonglong (gdbserv, reg_addr, &addr);
+ gdbserv_reg_to_ulong (gdbserv, reg_len, &len);
+ /* assume we're reading raw memory from the local mc */
+ gdbserv_output_bytes (gdbserv, addr, len);
+
+
+TARGET-RESUME: GDB requests that the target resume execution.
+
+Eventually ->target->continue_program() is called. That function
+should record the request and then wait for SERVER to exit before
+actually continuing the target.
+
+--
+