The RSP server has one data structure, rsp
,
shared amongst its implementing functions (and is thus declared
static
in rsp-server.c
).
static struct { int client_waiting; int proto_num; int server_fd; int client_fd; int sigval; unsigned long int start_addr; struct mp_entry *mp_hash[MP_HASH_SIZE]; } rsp;
The fields are:
client_waiting
. A flag to indicate if the
target has previously been set running (by a GDB
continue or step)
instruction, in which case the client will be waiting for a
response indicating when and why the server has stopped.
proto_num
. The number of the communication
protocol used (in this case TCP/IP).
server_fd
. File handle of the server
connection to the RSP port, listening for connections. Set to
-1 if it is not open.
client_fd
. File handle of the current client
connection to the RSP port, on which all packet transfers take
place. Set to -1 if it is not open.
sigval
. The last exception raised by the
target as a GDB target signal number. Set by the simulator
calling rsp_exception ()
.
start_addr
. The start address of the last
run. Needed to support the restart function of extended remote
debugging.
mp_hash
. Pointer to the hash table of
matchpoints set (see Section 4.3.2.1).
The RSP server also draws on several Or1ksim data
structures. Most notably config
for configuration
data and cpu_state
for all the CPU state data.
The matchpoint hash table is implemented as an open hash table,
where the hash table entry is calculated as the address of the
matchpoint modulo the size of the hash table
(MP_HASH_SIZE
) and the key is formed from the
address and the matchpoint type. Matchpoint types are defined for
memory and hardware breakpoints and hardware write, read and
access watchpoints:
enum mp_type { BP_MEMORY = 0, BP_HARDWARE = 1, WP_WRITE = 2, WP_READ = 3, WP_ACCESS = 4 };
Each entry in the table holds the instruction at the location of
the matchpoint, which in the case of memory breakpoints will have
been replaced by l.trap
struct mp_entry { enum mp_type type; unsigned long int addr; unsigned long int instr; struct mp_entry *next; };
Linking through the next
field allows multiple
entries with the same hash value to be stored.
Interface to the hash table is through four functions:
mp_hash_init ()
. void
function which sets all the hash table slots to NULL
mp_hash_add ()
. void
function which adds an entry to the hash table (if it is not
already there). It takes three arguments, the matchpoint type
and address and the instruction stored at that
address. Repeated adding of the same entry has no effect,
which provides convenient behavior for debugging over noisy
connections where packets may be duplicated.
mp_hash_lookup ()
. Function to look
up a key in the hash table. It takes a matchpoint type and
address and returns a pointer to the entry (as a pointer to
struct mp_entry) or NULL
if
the key is not found.
mp_hash_delete ()
. Function with the
same behavior as mp_hash_lookup ()
,
but also deletes the entry from the hash table if it is found
there. If the entry is not found, it silently does nothing
(and returns NULL
).