[RFA] Remote symbol look-up (resubmission)

Michael Snyder
2001-05-11T10:26:00Z

This is a re-submission, with documentation and changes to answer Andrew's concerns.

2001-05-10 Michael Snyder <msnyder@redhat.com>

* solib.h (no_shared_libraries): Export definition.
* remote.c (remote_new_objfile): New function. Called whenever
a new objfile is created (which is generally a new shared library).
(remote_check_symbols): Send notification to the target that it is
now a good time to ask for symbol look-up service, and handle any
symbol look-up requests. Called whenever a new symbol file becomes
available, and from remote open.
(hex2bin): Require explicit count, don't accept null-terminated str.
(set_remote_protocol_qSymbol_packet_cmd): New function.
(show_remote_protocol_qSymbol_packet_cmd): New function.
(remote_open_1, remote_async_open_1): Call remote_check_symbols.
(_initialize_remote): Hook remote_new_objfile into the new
objfile notification chain. Add set/show remote symbol-lookup
commands.
* doc/gdb.texinfo: Document the new 'qSymbol' and 'QSymbol' packets.

Index: solib.h
===================================================================
RCS file: /cvs/src/src/gdb/solib.h,v
retrieving revision 1.4
diff -c -3 -p -r1.4 solib.h
*** solib.h 2001/03/06 08:21:17 1.4
--- solib.h 2001/05/11 01:50:49
*************** extern char *solib_address (CORE_ADDR);
*** 193,195 ****
--- 193,197 ----
#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) in_solib_dynsym_resolve_code (pc)

extern int in_solib_dynsym_resolve_code (CORE_ADDR); /* solib.c */
+
+ extern void no_shared_libraries (char *, int); /* solib.c */
Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.49
diff -c -3 -p -r1.49 remote.c
*** remote.c 2001/05/10 19:06:19 1.49
--- remote.c 2001/05/11 01:50:50
*************** static void record_currthread (int currt
*** 188,195 ****

static int fromhex (int a);

! static int hex2bin (const char *hex, char *bin, int);

static int putpkt_binary (char *buf, int cnt);

static void check_binary_download (CORE_ADDR addr);
--- 188,197 ----

static int fromhex (int a);

! static int hex2bin (const char *hex, char *bin, int count);

+ static int bin2hex (const char *bin, char *hex, int count);
+
static int putpkt_binary (char *buf, int cnt);

static void check_binary_download (CORE_ADDR addr);
*************** packet_ok (const char *buf, struct packe
*** 668,673 ****
--- 670,691 ----
}
}

+ /* Should we try the 'qSymbol' (target symbol lookup service) request? */
+ static struct packet_config remote_protocol_qSymbol;
+
+ static void
+ set_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+ {
+ update_packet_config (&remote_protocol_qSymbol);
+ }
+
+ static void
+ show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty)
+ {
+ show_packet_config_cmd (&remote_protocol_qSymbol);
+ }
+
/* Should we try the 'e' (step over range) request? */
static struct packet_config remote_protocol_e;

*************** init_all_packet_configs (void)
*** 2068,2073 ****
--- 2086,2092 ----
update_packet_config (&remote_protocol_e);
update_packet_config (&remote_protocol_E);
update_packet_config (&remote_protocol_P);
+ update_packet_config (&remote_protocol_qSymbol);
for (i = 0; i < NR_Z_PACKET_TYPES; i++)
update_packet_config (&remote_protocol_Z[i]);
/* Force remote_write_bytes to check whether target supports binary
*************** init_all_packet_configs (void)
*** 2076,2081 ****
--- 2095,2152 ----
}

static void
+ remote_check_symbols (struct objfile *objfile)
+ {
+ char *msg, *reply, *prev, *tmp;
+ struct minimal_symbol *sym;
+ int end;
+
+ if (remote_protocol_qSymbol.support == PACKET_DISABLE)
+ return;
+
+ msg = alloca (PBUFSIZ);
+ reply = alloca (PBUFSIZ);
+
+ /* Inform target of new objfile. */
+
+ /* NOTE: you might say that I should use SLASH_CHAR here, but
+ not so! SLASH_CHAR is defined for the host, while the shared
+ libraries are relevant to the target. */
+ if (objfile)
+ {
+ tmp = strrchr (objfile->name, '/');
+ if (tmp == NULL)
+ tmp = strrchr (objfile->name, '\\');
+ if (tmp == NULL)
+ tmp = objfile->name;
+ bin2hex (tmp + 1, reply, 0);
+ sprintf (msg, "qSymbol:%s", reply);
+ }
+ else
+ strcpy (msg, "qSymbol:");
+
+ putpkt (msg);
+ getpkt (reply, PBUFSIZ, 0);
+ packet_ok (reply, &remote_protocol_qSymbol);
+
+ while (strncmp (reply, "qSymbol:", 8) == 0)
+ {
+ tmp = &reply[8];
+ end = hex2bin (tmp, msg, strlen (tmp) / 2);
+ msg[end] = '\0';
+ sym = lookup_minimal_symbol (msg, NULL, NULL);
+ if (sym == NULL)
+ sprintf (msg, "QSymbol::%s", &reply[8]);
+ else
+ sprintf (msg, "QSymbol:%s:%s",
+ paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
+ &reply[8]);
+ putpkt (msg);
+ getpkt (reply, PBUFSIZ, 0);
+ }
+ }
+
+ static void
remote_open_1 (char *name, int from_tty, struct target_ops *target,
int extended_p)
{
*************** serial device is attached to the remote
*** 2167,2173 ****

/* Set up to detect and load shared libraries. */
if (exec_bfd) /* No use without an exec file. */
! SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
#endif
}

--- 2238,2247 ----

/* Set up to detect and load shared libraries. */
if (exec_bfd) /* No use without an exec file. */
! {
! SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
! remote_check_symbols (symfile_objfile);
! }
#endif
}

*************** serial device is attached to the remote
*** 2277,2283 ****

/* Set up to detect and load shared libraries. */
if (exec_bfd) /* No use without an exec file. */
! SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
#endif
}

--- 2351,2360 ----

/* Set up to detect and load shared libraries. */
if (exec_bfd) /* No use without an exec file. */
! {
! SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
! remote_check_symbols (symfile_objfile);
! }
#endif
}

*************** hex2bin (const char *hex, char *bin, int
*** 2346,2355 ****
{
int i;

- /* May use a length, or a nul-terminated string as input. */
- if (count == 0)
- count = strlen (hex) / 2;
-
for (i = 0; i < count; i++)
{
if (hex[0] == 0 || hex[1] == 0)
--- 2423,2428 ----
*************** tohex (int nib)
*** 2376,2382 ****
}

static int
! bin2hex (char *bin, char *hex, int count)
{
int i;
/* May use a length, or a nul-terminated string as input. */
--- 2449,2455 ----
}

static int
! bin2hex (const char *bin, char *hex, int count)
{
int i;
/* May use a length, or a nul-terminated string as input. */
*************** remote_resume (ptid_t ptid, int step, en
*** 2449,2455 ****
putpkt (buf);
getpkt (buf, PBUFSIZ, 0);

! if (packet_ok(buf, &remote_protocol_E) == PACKET_OK)
return;
}
}
--- 2522,2528 ----
putpkt (buf);
getpkt (buf, PBUFSIZ, 0);

! if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
return;
}
}
*************** remote_resume (ptid_t ptid, int step, en
*** 2467,2473 ****
putpkt (buf);
getpkt (buf, PBUFSIZ, 0);

! if (packet_ok(buf, &remote_protocol_e) == PACKET_OK)
return;
}
}
--- 2540,2546 ----
putpkt (buf);
getpkt (buf, PBUFSIZ, 0);

! if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
return;
}
}
*************** remote_async_resume (ptid_t ptid, int st
*** 2537,2543 ****
putpkt (buf);
getpkt (buf, PBUFSIZ, 0);

! if (packet_ok(buf, &remote_protocol_E) == PACKET_OK)
goto register_event_loop;
}
}
--- 2610,2616 ----
putpkt (buf);
getpkt (buf, PBUFSIZ, 0);

! if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
goto register_event_loop;
}
}
*************** remote_async_resume (ptid_t ptid, int st
*** 2555,2561 ****
putpkt (buf);
getpkt (buf, PBUFSIZ, 0);

! if (packet_ok(buf, &remote_protocol_e) == PACKET_OK)
goto register_event_loop;
}
}
--- 2628,2634 ----
putpkt (buf);
getpkt (buf, PBUFSIZ, 0);

! if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
goto register_event_loop;
}
}
*************** Specify the serial device it is connecte
*** 5702,5708 ****
static void
set_remote_cmd (char *args, int from_tty)
{
!
}

static void
--- 5775,5781 ----
static void
set_remote_cmd (char *args, int from_tty)
{
!
}

static void
*************** show_remote_cmd (char *args, int from_tt
*** 5713,5718 ****
--- 5786,5792 ----
show_remote_protocol_e_packet_cmd (args, from_tty);
show_remote_protocol_E_packet_cmd (args, from_tty);
show_remote_protocol_P_packet_cmd (args, from_tty);
+ show_remote_protocol_qSymbol_packet_cmd (args, from_tty);
show_remote_protocol_binary_download_cmd (args, from_tty);
}

*************** build_remote_gdbarch_data (void)
*** 5726,5731 ****
--- 5800,5822 ----
remote_address_size = TARGET_ADDR_BIT;
}

+ /* Saved pointer to previous owner of the new_objfile event. */
+ static void (*remote_new_objfile_chain) (struct objfile *);
+
+ /* Function to be called whenever a new objfile (shlib) is detected. */
+ static void
+ remote_new_objfile (struct objfile *objfile)
+ {
+ if (remote_desc != 0) /* Have a remote connection */
+ {
+ remote_check_symbols (objfile);
+ }
+ /* Call predecessor on chain, if any. */
+ if (remote_new_objfile_chain != 0 &&
+ remote_desc == 0)
+ remote_new_objfile_chain (objfile);
+ }
+
void
_initialize_remote (void)
{
*************** _initialize_remote (void)
*** 5756,5761 ****
--- 5847,5856 ----
init_remote_cisco_ops ();
add_target (&remote_cisco_ops);

+ /* Hook into new objfile notification. */
+ remote_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = remote_new_objfile;
+
#if 0
init_remote_threadtests ();
#endif
*************** in a memory packet.\n",
*** 5860,5865 ****
--- 5955,5967 ----
"e", "step-over-range",
set_remote_protocol_e_packet_cmd,
show_remote_protocol_e_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
+ add_packet_config_cmd (&remote_protocol_qSymbol,
+ "qSymbol", "symbol-lookup",
+ set_remote_protocol_qSymbol_packet_cmd,
+ show_remote_protocol_qSymbol_packet_cmd,
&remote_set_cmdlist, &remote_show_cmdlist,
0);

Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.38
diff -c -3 -p -r1.38 gdb.texinfo
*** gdb.texinfo 2001/04/02 08:58:19 1.38
--- gdb.texinfo 2001/05/11 01:50:51
*************** A command response with the hex encoded
*** 10396,10401 ****
--- 10396,10449 ----
@tab
Indicate a badly formed request.

+ @item symbol lookup
+ @tab @code{q}@code{Symbol:}@var{SYMBOL_FILE_NAME}
+ @tab
+ Notify the target that a new symbol file is available for symbol look-up.
+ Accept requests from the target for the values of symbols.
+ @item
+ @tab
+ @tab
+ @var{SYMBOL_FILE_NAME} (hex encoded) is the name of a debugger symbol file
+ (executable, shared library) which is available for symbol look-up.
+ @item
+ @tab reply @code{OK}
+ @tab
+ The target does not need to look up any (more) symbols.
+ @item
+ @tab reply @code{q}@code{Symbol:}@var{SYM_NAME}
+ @tab
+ The target requests the value of symbol @var{SYM_NAME} (hex encoded).
+ @value{GDBN} may provide the value by using the @code{Q}@code{Symbol}
+ message, described below.
+
+ @item symbol value
+ @tab @code{Q}@code{Symbol:}@var{SYM_VALUE}:@var{SYM_NAME}
+ @tab
+ Set the value of SYM_NAME to SYM_VALUE.
+ @item
+ @tab
+ @tab
+ @var{SYM_NAME} (hex encoded) is the name of a symbol whose value
+ the target has previously requested.
+ @item
+ @tab
+ @tab
+ @var{SYM_VALUE} (hex) is the value for symbol @var{SYM_NAME}.
+ If @value{GDBN} cannot supply a value for @var{SYM_NAME}, then this
+ field may be empty.
+ @item
+ @tab reply @code{OK}
+ @tab
+ The target does not need to look up any (more) symbols.
+ @item
+ @tab reply @code{q}@code{Symbol:}@var{SYM_NAME}
+ @tab
+ 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.
+
+
@item
@tab reply @samp{}
@tab