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:
parent
d406f3e430
commit
0cd61f4402
4 changed files with 68 additions and 17 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue