PR gdb/14290:

* solib-darwin.c (gdb_bfd_mach_o_fat_extract): New function.
	(darwin_solib_get_all_image_info_addr_at_init, darwin_bfd_open):
	Use it.
	* gdb_bfd.h (gdb_bfd_mark_parent): Declare.
	* gdb_bfd.c (gdb_bfd_mark_parent): New function.
	(gdb_bfd_openr_next_archived_file): Use it.
This commit is contained in:
Tom Tromey 2012-11-28 18:48:38 +00:00
parent d406f3e430
commit 0cd61f4402
4 changed files with 68 additions and 17 deletions

View file

@ -1,3 +1,13 @@
2012-11-28 Tom Tromey <tromey@redhat.com>
PR gdb/14290:
* solib-darwin.c (gdb_bfd_mach_o_fat_extract): New function.
(darwin_solib_get_all_image_info_addr_at_init, darwin_bfd_open):
Use it.
* gdb_bfd.h (gdb_bfd_mark_parent): Declare.
* gdb_bfd.c (gdb_bfd_mark_parent): New function.
(gdb_bfd_openr_next_archived_file): Use it.
2012-11-28 Markus Metzger <markus.t.metzger@intel.com>
* configure.ac: Check for linux/perf_event.h.

View file

@ -499,24 +499,34 @@ gdb_bfd_openr_iovec (const char *filename, const char *target,
/* See gdb_bfd.h. */
void
gdb_bfd_mark_parent (bfd *child, bfd *parent)
{
struct gdb_bfd_data *gdata;
gdb_bfd_ref (child);
/* No need to stash the filename here, because we also keep a
reference on the parent archive. */
gdata = bfd_usrdata (child);
if (gdata->archive_bfd == NULL)
{
gdata->archive_bfd = parent;
gdb_bfd_ref (parent);
}
else
gdb_assert (gdata->archive_bfd == parent);
}
/* See gdb_bfd.h. */
bfd *
gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous)
{
bfd *result = bfd_openr_next_archived_file (archive, previous);
if (result)
{
struct gdb_bfd_data *gdata;
gdb_bfd_ref (result);
/* No need to stash the filename here, because we also keep a
reference on the parent archive. */
gdata = bfd_usrdata (result);
gdb_assert (gdata->archive_bfd == NULL || gdata->archive_bfd == archive);
gdata->archive_bfd = archive;
gdb_bfd_ref (archive);
}
gdb_bfd_mark_parent (result, archive);
return result;
}

View file

@ -50,6 +50,15 @@ void gdb_bfd_ref (struct bfd *abfd);
void gdb_bfd_unref (struct bfd *abfd);
/* Mark the CHILD BFD as being a member of PARENT. Also, increment
the reference count of CHILD. Calling this function ensures that
as along as CHILD remains alive, PARENT will as well. Both CHILD
and PARENT must be non-NULL. This can be called more than once
with the same arguments; but it is not allowed to call it for a
single CHILD with different values for PARENT. */
void gdb_bfd_mark_parent (bfd *child, bfd *parent);
/* Try to read or map the contents of the section SECT. If
successful, the section data is returned and *SIZE is set to the
size of the section data; this may not be the same as the size

View file

@ -348,6 +348,27 @@ darwin_special_symbol_handling (void)
{
}
/* A wrapper for bfd_mach_o_fat_extract that handles reference
counting properly. This will either return NULL, or return a new
reference to a BFD. */
static bfd *
gdb_bfd_mach_o_fat_extract (bfd *abfd, bfd_format format,
const bfd_arch_info_type *arch)
{
bfd *result = bfd_mach_o_fat_extract (abfd, format, arch);
if (result == NULL)
return NULL;
if (result == abfd)
gdb_bfd_ref (result);
else
gdb_bfd_mark_parent (result, abfd);
return result;
}
/* Extract dyld_all_image_addr when the process was just created, assuming the
current PC is at the entry of the dynamic linker. */
@ -377,12 +398,11 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info)
bfd *sub;
make_cleanup_bfd_unref (dyld_bfd);
sub = bfd_mach_o_fat_extract (dyld_bfd, bfd_object,
gdbarch_bfd_arch_info (target_gdbarch ()));
sub = gdb_bfd_mach_o_fat_extract (dyld_bfd, bfd_object,
gdbarch_bfd_arch_info (target_gdbarch ()));
if (sub)
{
dyld_bfd = sub;
gdb_bfd_ref (sub);
make_cleanup_bfd_unref (sub);
}
else
@ -514,14 +534,16 @@ darwin_bfd_open (char *pathname)
/* Open bfd for shared library. */
abfd = solib_bfd_fopen (found_pathname, found_file);
res = bfd_mach_o_fat_extract (abfd, bfd_object,
gdbarch_bfd_arch_info (target_gdbarch ()));
res = gdb_bfd_mach_o_fat_extract (abfd, bfd_object,
gdbarch_bfd_arch_info (target_gdbarch ()));
if (!res)
{
make_cleanup_bfd_unref (abfd);
error (_("`%s': not a shared-library: %s"),
bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
}
gdb_bfd_unref (abfd);
return res;
}