ChangeLog:

* remote.h (remote_filename_p, remote_bfd_open): Add prototypes.
	* remote.c (remote_bfd_iovec_open, remote_bfd_iovec_close,
	remote_bfd_iovec_pread, remote_bfd_iovec_stat, remote_filename_p,
	remote_bfd_open): New functions.
	(remote_hostio_send_command): Fail safely if remote connection
	is not set up.

	* solist.h (solib_open): Remove prototype.
	(solib_bfd_open): Add prototype.
	* solib.c: Include "remote.h".
	(solib_open): Remove, replace by ...
	(solib_bfd_open): ... this new function.  Handle remote BFDs.
	(solib_map_sections): Replace solib_open by solib_bfd_open.
	* solib-frv.c: Include "exceptions.h".
	(enable_break2): Replace solib_open by solib_bfd_open.
	* solib-svr4.c: Include "exceptions.h".
	(enable_break): Replace solib_open by solib_bfd_open.

	* symfile.c: Include "remote.h".
	(build_id_verify): Handle remote BFDs.
	(separate_debug_file_exists): Use BFD to access file.  Handle
	remote BFDs.
	(symfile_bfd_open): Handle remote BFDs.
	(reread_symbols): Handle remote BFDs.

	* NEWS: Mention "remote:" argument prefix to "set sysroot".

doc/ChangeLog:

	* gdb.texinfo (Commands to Specify Files): Document "remote:"
	argument prefix to "set sysroot".
This commit is contained in:
Ulrich Weigand 2008-08-26 17:30:35 +00:00
parent 1cf3db46a6
commit f1838a9841
11 changed files with 263 additions and 86 deletions

View File

@ -1,3 +1,32 @@
2008-08-26 Ulrich Weigand <uweigand@de.ibm.com>
* remote.h (remote_filename_p, remote_bfd_open): Add prototypes.
* remote.c (remote_bfd_iovec_open, remote_bfd_iovec_close,
remote_bfd_iovec_pread, remote_bfd_iovec_stat, remote_filename_p,
remote_bfd_open): New functions.
(remote_hostio_send_command): Fail safely if remote connection
is not set up.
* solist.h (solib_open): Remove prototype.
(solib_bfd_open): Add prototype.
* solib.c: Include "remote.h".
(solib_open): Remove, replace by ...
(solib_bfd_open): ... this new function. Handle remote BFDs.
(solib_map_sections): Replace solib_open by solib_bfd_open.
* solib-frv.c: Include "exceptions.h".
(enable_break2): Replace solib_open by solib_bfd_open.
* solib-svr4.c: Include "exceptions.h".
(enable_break): Replace solib_open by solib_bfd_open.
* symfile.c: Include "remote.h".
(build_id_verify): Handle remote BFDs.
(separate_debug_file_exists): Use BFD to access file. Handle
remote BFDs.
(symfile_bfd_open): Handle remote BFDs.
(reread_symbols): Handle remote BFDs.
* NEWS: Mention "remote:" argument prefix to "set sysroot".
2008-08-26 Ulrich Weigand <uweigand@de.ibm.com>
* gdbarch.sh (target_gdbarch): New global variable.

View File

@ -3,6 +3,11 @@
*** Changes since GDB 6.8
* GDB now supports automatic retrieval of shared library files from
remote targets. To use this feature, specify a system root that begins
with the `remote:' prefix, either via the `set sysroot' command or via
the `--with-sysroot' configure-time option.
* Commands `set debug-file-directory', `set solib-search-path' and `set args'
now complete on file names.

View File

@ -1,3 +1,8 @@
2008-08-26 Ulrich Weigand <uweigand@de.ibm.com>
* gdb.texinfo (Commands to Specify Files): Document "remote:"
argument prefix to "set sysroot".
2008-08-21 Paul N. Hilfinger <hilfinger@adacore.com>
* gdb.texinfo (Omissions from Ada): Describe new treatment of True

View File

@ -12605,8 +12605,11 @@ library events happen.
@end table
Shared libraries are also supported in many cross or remote debugging
configurations. A copy of the target's libraries need to be present on the
host system; they need to be the same as the target libraries, although the
configurations. @value{GDBN} needs to have access to the target's libraries;
this can be accomplished either by providing copies of the libraries
on the host system, or by asking @value{GDBN} to automatically retrieve the
libraries from the target. If copies of the target libraries are
provided, they need to be the same as the target libraries, although the
copies on the target can be stripped as long as the copies on the host are
not.
@ -12630,6 +12633,16 @@ libraries, they need to be laid out in the same way that they are on
the target, with e.g.@: a @file{/lib} and @file{/usr/lib} hierarchy
under @var{path}.
If @var{path} starts with the sequence @file{remote:}, @value{GDBN} will
retrieve the target libraries from the remote system. This is only
supported when using a remote target that supports the @code{remote get}
command (@pxref{File Transfer,,Sending files to a remote system}).
The part of @var{path} following the initial @file{remote:}
(if present) is used as system root prefix on the remote file system.
@footnote{If you want to specify a local system root using a directory
that happens to be named @file{remote:}, you need to use some equivalent
variant of the name like @file{./remote:}.}
The @code{set solib-absolute-prefix} command is an alias for @code{set
sysroot}.

View File

@ -6668,7 +6668,8 @@ remote_hostio_send_command (int command_bytes, int which_packet,
int ret, bytes_read;
char *attachment_tmp;
if (remote_protocol_packets[which_packet].support == PACKET_DISABLE)
if (!remote_desc
|| remote_protocol_packets[which_packet].support == PACKET_DISABLE)
{
*remote_errno = FILEIO_ENOSYS;
return -1;
@ -6932,6 +6933,97 @@ remote_hostio_close_cleanup (void *opaque)
remote_hostio_close (fd, &remote_errno);
}
static void *
remote_bfd_iovec_open (struct bfd *abfd, void *open_closure)
{
const char *filename = bfd_get_filename (abfd);
int fd, remote_errno;
int *stream;
gdb_assert (remote_filename_p (filename));
fd = remote_hostio_open (filename + 7, FILEIO_O_RDONLY, 0, &remote_errno);
if (fd == -1)
{
errno = remote_fileio_errno_to_host (remote_errno);
bfd_set_error (bfd_error_system_call);
return NULL;
}
stream = xmalloc (sizeof (int));
*stream = fd;
return stream;
}
static int
remote_bfd_iovec_close (struct bfd *abfd, void *stream)
{
int fd = *(int *)stream;
int remote_errno;
xfree (stream);
/* Ignore errors on close; these may happen if the remote
connection was already torn down. */
remote_hostio_close (fd, &remote_errno);
return 1;
}
static file_ptr
remote_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
file_ptr nbytes, file_ptr offset)
{
int fd = *(int *)stream;
int remote_errno;
file_ptr pos, bytes;
pos = 0;
while (nbytes > pos)
{
bytes = remote_hostio_pread (fd, (char *)buf + pos, nbytes - pos,
offset + pos, &remote_errno);
if (bytes == 0)
/* Success, but no bytes, means end-of-file. */
break;
if (bytes == -1)
{
errno = remote_fileio_errno_to_host (remote_errno);
bfd_set_error (bfd_error_system_call);
return -1;
}
pos += bytes;
}
return pos;
}
static int
remote_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
{
/* FIXME: We should probably implement remote_hostio_stat. */
sb->st_size = INT_MAX;
return 0;
}
int
remote_filename_p (const char *filename)
{
return strncmp (filename, "remote:", 7) == 0;
}
bfd *
remote_bfd_open (const char *remote_file, const char *target)
{
return bfd_openr_iovec (remote_file, target,
remote_bfd_iovec_open, NULL,
remote_bfd_iovec_pread,
remote_bfd_iovec_close,
remote_bfd_iovec_stat);
}
void
remote_file_put (const char *local_file, const char *remote_file, int from_tty)
{

View File

@ -73,4 +73,8 @@ void remote_file_get (const char *remote_file, const char *local_file,
int from_tty);
void remote_file_delete (const char *remote_file, int from_tty);
bfd *remote_bfd_open (const char *remote_file, const char *target);
int remote_filename_p (const char *filename);
#endif

View File

@ -30,6 +30,7 @@
#include "command.h"
#include "gdbcmd.h"
#include "elf/frv.h"
#include "exceptions.h"
/* Flag which indicates whether internal debug messages should be printed. */
static int solib_frv_debug;
@ -645,12 +646,11 @@ enable_break2 (void)
unsigned int interp_sect_size;
gdb_byte *buf;
bfd *tmp_bfd = NULL;
int tmp_fd = -1;
char *tmp_pathname = NULL;
int status;
CORE_ADDR addr, interp_loadmap_addr;
gdb_byte addr_buf[FRV_PTR_SIZE];
struct int_elf32_fdpic_loadmap *ldm;
volatile struct gdb_exception ex;
/* Read the contents of the .interp section into a local buffer;
the contents specify the dynamic linker this program uses. */
@ -668,25 +668,16 @@ enable_break2 (void)
be trivial on GNU/Linux). Therefore, we have to try an alternate
mechanism to find the dynamic linker's base address. */
tmp_fd = solib_open (buf, &tmp_pathname);
if (tmp_fd >= 0)
tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd);
TRY_CATCH (ex, RETURN_MASK_ALL)
{
tmp_bfd = solib_bfd_open (buf);
}
if (tmp_bfd == NULL)
{
enable_break_failure_warning ();
return 0;
}
/* Make sure the dynamic linker is really a useful object. */
if (!bfd_check_format (tmp_bfd, bfd_object))
{
warning (_("Unable to grok dynamic linker %s as an object file"), buf);
enable_break_failure_warning ();
bfd_close (tmp_bfd);
return 0;
}
status = frv_fdpic_loadmap_addresses (target_gdbarch,
&interp_loadmap_addr, 0);
if (status < 0)

View File

@ -42,6 +42,7 @@
#include "elf-bfd.h"
#include "exec.h"
#include "auxv.h"
#include "exceptions.h"
static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
static int svr4_have_link_map_offsets (void);
@ -1038,8 +1039,7 @@ enable_break (void)
struct so_list *so;
bfd *tmp_bfd = NULL;
struct target_ops *tmp_bfd_target;
int tmp_fd = -1;
char *tmp_pathname = NULL;
volatile struct gdb_exception ex;
/* Read the contents of the .interp section into a local buffer;
the contents specify the dynamic linker this program uses. */
@ -1058,21 +1058,13 @@ enable_break (void)
be trivial on GNU/Linux). Therefore, we have to try an alternate
mechanism to find the dynamic linker's base address. */
tmp_fd = solib_open (buf, &tmp_pathname);
if (tmp_fd >= 0)
tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd);
TRY_CATCH (ex, RETURN_MASK_ALL)
{
tmp_bfd = solib_bfd_open (buf);
}
if (tmp_bfd == NULL)
goto bkpt_at_symbol;
/* Make sure the dynamic linker's really a useful object. */
if (!bfd_check_format (tmp_bfd, bfd_object))
{
warning (_("Unable to grok dynamic linker %s as an object file"), buf);
bfd_close (tmp_bfd);
goto bkpt_at_symbol;
}
/* Now convert the TMP_BFD into a target. That way target, as
well as BFD operations can be used. Note that closing the
target will also close the underlying bfd. */
@ -1166,7 +1158,6 @@ enable_break (void)
/* For whatever reason we couldn't set a breakpoint in the dynamic
linker. Warn and drop into the old code. */
bkpt_at_symbol:
xfree (tmp_pathname);
warning (_("Unable to find dynamic linker breakpoint function.\n"
"GDB will be unable to debug shared library initializers\n"
"and track explicitly loaded dynamic code."));

View File

@ -44,6 +44,7 @@
#include "solist.h"
#include "observer.h"
#include "readline/readline.h"
#include "remote.h"
/* Architecture-specific operations. */
@ -106,11 +107,11 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
GLOBAL FUNCTION
solib_open -- Find a shared library file and open it.
solib_bfd_open -- Find a shared library file and open BFD for it.
SYNOPSIS
int solib_open (char *in_patname, char **found_pathname);
struct bfd *solib_open (char *in_pathname);
DESCRIPTION
@ -137,16 +138,17 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
RETURNS
file handle for opened solib, or -1 for failure. */
BFD file handle for opened solib; throws error on failure. */
int
solib_open (char *in_pathname, char **found_pathname)
bfd *
solib_bfd_open (char *in_pathname)
{
struct target_so_ops *ops = solib_ops (target_gdbarch);
int found_file = -1;
char *temp_pathname = NULL;
char *p = in_pathname;
int gdb_sysroot_is_empty;
bfd *abfd;
gdb_sysroot_is_empty = (gdb_sysroot == NULL || *gdb_sysroot == 0);
@ -168,6 +170,29 @@ solib_open (char *in_pathname, char **found_pathname)
strcat (temp_pathname, in_pathname);
}
/* Handle remote files. */
if (remote_filename_p (temp_pathname))
{
temp_pathname = xstrdup (temp_pathname);
abfd = remote_bfd_open (temp_pathname, gnutarget);
if (!abfd)
{
make_cleanup (xfree, temp_pathname);
error (_("Could not open `%s' as an executable file: %s"),
temp_pathname, bfd_errmsg (bfd_get_error ()));
}
if (!bfd_check_format (abfd, bfd_object))
{
bfd_close (abfd);
make_cleanup (xfree, temp_pathname);
error (_("`%s': not in executable format: %s"),
temp_pathname, bfd_errmsg (bfd_get_error ()));
}
return abfd;
}
/* Now see if we can open it. */
found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
@ -228,16 +253,30 @@ solib_open (char *in_pathname, char **found_pathname)
OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
&temp_pathname);
/* Done. If not found, tough luck. Return found_file and
(optionally) found_pathname. */
if (temp_pathname)
/* Done. If still not found, error. */
if (found_file < 0)
perror_with_name (in_pathname);
/* Leave temp_pathname allocated. abfd->name will point to it. */
abfd = bfd_fopen (temp_pathname, gnutarget, FOPEN_RB, found_file);
if (!abfd)
{
if (found_pathname != NULL)
*found_pathname = temp_pathname;
else
xfree (temp_pathname);
close (found_file);
make_cleanup (xfree, temp_pathname);
error (_("Could not open `%s' as an executable file: %s"),
temp_pathname, bfd_errmsg (bfd_get_error ()));
}
return found_file;
if (!bfd_check_format (abfd, bfd_object))
{
bfd_close (abfd);
make_cleanup (xfree, temp_pathname);
error (_("`%s': not in executable format: %s"),
temp_pathname, bfd_errmsg (bfd_get_error ()));
}
bfd_set_cacheable (abfd, 1);
return abfd;
}
@ -273,46 +312,24 @@ solib_map_sections (void *arg)
{
struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
char *filename;
char *scratch_pathname;
int scratch_chan;
struct section_table *p;
struct cleanup *old_chain;
bfd *abfd;
filename = tilde_expand (so->so_name);
old_chain = make_cleanup (xfree, filename);
scratch_chan = solib_open (filename, &scratch_pathname);
if (scratch_chan < 0)
{
perror_with_name (filename);
}
/* Leave scratch_pathname allocated. abfd->name will point to it. */
abfd = bfd_fopen (scratch_pathname, gnutarget, FOPEN_RB, scratch_chan);
if (!abfd)
{
close (scratch_chan);
error (_("Could not open `%s' as an executable file: %s"),
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
abfd = solib_bfd_open (filename);
do_cleanups (old_chain);
/* Leave bfd open, core_xfer_memory and "info files" need it. */
so->abfd = abfd;
bfd_set_cacheable (abfd, 1);
/* copy full path name into so_name, so that later symbol_file_add
can find it */
if (strlen (scratch_pathname) >= SO_NAME_MAX_PATH_SIZE)
error (_("Full path name length of shared library exceeds SO_NAME_MAX_PATH_SIZE in so_list structure."));
strcpy (so->so_name, scratch_pathname);
if (strlen (bfd_get_filename (abfd)) >= SO_NAME_MAX_PATH_SIZE)
error (_("Shared library file name is too long."));
strcpy (so->so_name, bfd_get_filename (abfd));
if (!bfd_check_format (abfd, bfd_object))
{
error (_("\"%s\": not in executable format: %s."),
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
if (build_section_table (abfd, &so->sections, &so->sections_end))
{
error (_("Can't find the file sections in `%s': %s"),
@ -339,9 +356,6 @@ solib_map_sections (void *arg)
}
}
/* Free the file names, close the file now. */
do_cleanups (old_chain);
return (1);
}

View File

@ -127,7 +127,7 @@ void free_so (struct so_list *so);
struct so_list *master_so_list (void);
/* Find solib binary file and open it. */
extern int solib_open (char *in_pathname, char **found_pathname);
extern bfd *solib_bfd_open (char *in_pathname);
/* FIXME: gdbarch needs to control this variable */
extern struct target_so_ops *current_target_so_ops;

View File

@ -53,6 +53,7 @@
#include "varobj.h"
#include "elf-bfd.h"
#include "solib.h"
#include "remote.h"
#include <sys/types.h>
#include <fcntl.h>
@ -1216,7 +1217,10 @@ build_id_verify (const char *filename, struct build_id *check)
int retval = 0;
/* We expect to be silent on the non-existing files. */
abfd = bfd_openr (filename, gnutarget);
if (remote_filename_p (filename))
abfd = remote_bfd_open (filename, gnutarget);
else
abfd = bfd_openr (filename, gnutarget);
if (abfd == NULL)
return 0;
@ -1307,18 +1311,22 @@ static int
separate_debug_file_exists (const char *name, unsigned long crc)
{
unsigned long file_crc = 0;
int fd;
bfd *abfd;
gdb_byte buffer[8*1024];
int count;
fd = open (name, O_RDONLY | O_BINARY);
if (fd < 0)
if (remote_filename_p (name))
abfd = remote_bfd_open (name, gnutarget);
else
abfd = bfd_openr (name, gnutarget);
if (!abfd)
return 0;
while ((count = read (fd, buffer, sizeof (buffer))) > 0)
while ((count = bfd_bread (buffer, sizeof (buffer), abfd)) > 0)
file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
close (fd);
bfd_close (abfd);
return crc == file_crc;
}
@ -1564,6 +1572,28 @@ symfile_bfd_open (char *name)
int desc;
char *absolute_name;
if (remote_filename_p (name))
{
name = xstrdup (name);
sym_bfd = remote_bfd_open (name, gnutarget);
if (!sym_bfd)
{
make_cleanup (xfree, name);
error (_("`%s': can't open to read symbols: %s."), name,
bfd_errmsg (bfd_get_error ()));
}
if (!bfd_check_format (sym_bfd, bfd_object))
{
bfd_close (sym_bfd);
make_cleanup (xfree, name);
error (_("`%s': can't read symbols: %s."), name,
bfd_errmsg (bfd_get_error ()));
}
return sym_bfd;
}
name = tilde_expand (name); /* Returns 1st new malloc'd copy. */
/* Look down path for it, allocate 2nd new malloc'd copy. */
@ -1594,7 +1624,7 @@ symfile_bfd_open (char *name)
{
close (desc);
make_cleanup (xfree, name);
error (_("\"%s\": can't open to read symbols: %s."), name,
error (_("`%s': can't open to read symbols: %s."), name,
bfd_errmsg (bfd_get_error ()));
}
bfd_set_cacheable (sym_bfd, 1);
@ -1606,7 +1636,7 @@ symfile_bfd_open (char *name)
with the bfd). */
bfd_close (sym_bfd); /* This also closes desc. */
make_cleanup (xfree, name);
error (_("\"%s\": can't read symbols: %s."), name,
error (_("`%s': can't read symbols: %s."), name,
bfd_errmsg (bfd_get_error ()));
}
@ -2307,7 +2337,10 @@ reread_symbols (void)
if (!bfd_close (objfile->obfd))
error (_("Can't close BFD for %s: %s"), objfile->name,
bfd_errmsg (bfd_get_error ()));
objfile->obfd = bfd_openr (obfd_filename, gnutarget);
if (remote_filename_p (obfd_filename))
objfile->obfd = remote_bfd_open (obfd_filename, gnutarget);
else
objfile->obfd = bfd_openr (obfd_filename, gnutarget);
if (objfile->obfd == NULL)
error (_("Can't open %s to read symbols."), objfile->name);
/* bfd_openr sets cacheable to true, which is what we want. */