* solist.h (struct target_so_ops): New member bfd_open.

(solib_find): Add prototype.
	(solib_bfd_fopen): Add prototype.
	* solib.c (solib_find, solib_bfd_fopen): New functions, extracted
	from solib_bfd_open.
	(solib_bfd_open): Use ops->bfd_open override if present.  Call
	solib_find and solib_bfd_open otherwise.

	* objfiles.h (OBJF_KEEPBFD): New define.
	* objfiles.c (free_objfile): Do not close BFD if OBJF_KEEPBFD
	objfile flag is set.
	* solib.c (symbol_add_stub): Do not allocate second BFD for
	shared library; use OBJF_KEEPBFD flag on solib objfile.
This commit is contained in:
Ulrich Weigand 2009-01-15 16:35:22 +00:00
parent 0701b27131
commit 572d275cf7
5 changed files with 108 additions and 42 deletions

View File

@ -1,3 +1,20 @@
2009-01-15 Ulrich Weigand <uweigand@de.ibm.com>
Tristan Gingold <gingold@adacore.com>
* solist.h (struct target_so_ops): New member bfd_open.
(solib_find): Add prototype.
(solib_bfd_fopen): Add prototype.
* solib.c (solib_find, solib_bfd_fopen): New functions, extracted
from solib_bfd_open.
(solib_bfd_open): Use ops->bfd_open override if present. Call
solib_find and solib_bfd_open otherwise.
* objfiles.h (OBJF_KEEPBFD): New define.
* objfiles.c (free_objfile): Do not close BFD if OBJF_KEEPBFD
objfile flag is set.
* solib.c (symbol_add_stub): Do not allocate second BFD for
shared library; use OBJF_KEEPBFD flag on solib objfile.
2009-01-15 Ulrich Weigand <uweigand@de.ibm.com>
* frame.c (get_frame_arch): Abort if called with NULL this_frame.

View File

@ -422,9 +422,9 @@ free_objfile (struct objfile *objfile)
(*objfile->sf->sym_finish) (objfile);
}
/* We always close the bfd. */
/* We always close the bfd, unless the OBJF_KEEPBFD flag is set. */
if (objfile->obfd != NULL)
if (objfile->obfd != NULL && !(objfile->flags & OBJF_KEEPBFD))
{
char *name = bfd_get_filename (objfile->obfd);
if (!bfd_close (objfile->obfd))

View File

@ -414,6 +414,12 @@ struct objfile
#define OBJF_USERLOADED (1 << 3) /* User loaded */
/* The bfd of this objfile is used outside of the objfile (e.g. by solib).
Do not try to free it. */
#define OBJF_KEEPBFD (1 << 4) /* Do not delete bfd */
/* The object file that the main symbol table was loaded from (e.g. the
argument to the "symbol-file" or "file" command). */

View File

@ -107,11 +107,11 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
GLOBAL FUNCTION
solib_bfd_open -- Find a shared library file and open BFD for it.
solib_find -- Find a shared library file.
SYNOPSIS
struct bfd *solib_open (char *in_pathname);
char *solib_find (char *in_pathname, int *fd);
DESCRIPTION
@ -138,17 +138,17 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
RETURNS
BFD file handle for opened solib; throws error on failure. */
Full pathname of the shared library file, or NULL if not found.
(The pathname is malloc'ed; it needs to be freed by the caller.)
*FD is set to either -1 or an open file handle for the library. */
bfd *
solib_bfd_open (char *in_pathname)
char *
solib_find (char *in_pathname, int *fd)
{
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);
@ -173,24 +173,8 @@ solib_bfd_open (char *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;
*fd = -1;
return xstrdup (temp_pathname);
}
/* Now see if we can open it. */
@ -253,29 +237,79 @@ solib_bfd_open (char *in_pathname)
OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
&temp_pathname);
/* Done. If still not found, error. */
if (found_file < 0)
perror_with_name (in_pathname);
*fd = found_file;
return temp_pathname;
}
/* Leave temp_pathname allocated. abfd->name will point to it. */
abfd = bfd_fopen (temp_pathname, gnutarget, FOPEN_RB, found_file);
if (!abfd)
/* Open and return a BFD for the shared library PATHNAME. If FD is not -1,
it is used as file handle to open the file. Throws an error if the file
could not be opened. Handles both local and remote file access.
PATHNAME must be malloc'ed by the caller. If successful, the new BFD's
name will point to it. If unsuccessful, PATHNAME will be freed and the
FD will be closed (unless FD was -1). */
bfd *
solib_bfd_fopen (char *pathname, int fd)
{
bfd *abfd;
if (remote_filename_p (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 ()));
gdb_assert (fd == -1);
abfd = remote_bfd_open (pathname, gnutarget);
}
else
{
abfd = bfd_fopen (pathname, gnutarget, FOPEN_RB, fd);
if (abfd)
bfd_set_cacheable (abfd, 1);
else if (fd != -1)
close (fd);
}
if (!abfd)
{
make_cleanup (xfree, pathname);
error (_("Could not open `%s' as an executable file: %s"),
pathname, bfd_errmsg (bfd_get_error ()));
}
return abfd;
}
/* Find shared library PATHNAME and open a BFD for it. */
bfd *
solib_bfd_open (char *pathname)
{
struct target_so_ops *ops = solib_ops (target_gdbarch);
char *found_pathname;
int found_file;
bfd *abfd;
/* Use target-specific override if present. */
if (ops->bfd_open)
return ops->bfd_open (pathname);
/* Search for shared library file. */
found_pathname = solib_find (pathname, &found_file);
if (found_pathname == NULL)
perror_with_name (pathname);
/* Open bfd for shared library. */
abfd = solib_bfd_fopen (found_pathname, found_file);
/* Check bfd format. */
if (!bfd_check_format (abfd, bfd_object))
{
bfd_close (abfd);
make_cleanup (xfree, temp_pathname);
make_cleanup (xfree, found_pathname);
error (_("`%s': not in executable format: %s"),
temp_pathname, bfd_errmsg (bfd_get_error ()));
found_pathname, bfd_errmsg (bfd_get_error ()));
}
bfd_set_cacheable (abfd, 1);
return abfd;
}
@ -432,8 +466,8 @@ symbol_add_stub (void *arg)
sap = build_section_addr_info_from_section_table (so->sections,
so->sections_end);
so->objfile = symbol_file_add (so->so_name, so->from_tty,
sap, 0, OBJF_SHARED);
so->objfile = symbol_file_add_from_bfd (so->abfd, so->from_tty,
sap, 0, OBJF_SHARED | OBJF_KEEPBFD);
free_section_addr_info (sap);
return (1);

View File

@ -103,6 +103,9 @@ struct target_so_ops
the run time loader */
int (*in_dynsym_resolve_code) (CORE_ADDR pc);
/* Find and open shared library binary file. */
bfd *(*bfd_open) (char *pathname);
/* Extra hook for finding and opening a solib.
Convenience function for remote debuggers finding host libs. */
int (*find_and_open_solib) (char *soname,
@ -126,6 +129,12 @@ void free_so (struct so_list *so);
/* Return address of first so_list entry in master shared object list. */
struct so_list *master_so_list (void);
/* Find shared library binary file. */
extern char *solib_find (char *in_pathname, int *fd);
/* Open BFD for shared library file. */
extern bfd *solib_bfd_fopen (char *pathname, int fd);
/* Find solib binary file and open it. */
extern bfd *solib_bfd_open (char *in_pathname);