X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdb_bfd.c;h=4d4b0a53593a3560b742a27f7ad51d1dff5e109f;hb=cf2a3e990524cb794c75e0493169736dee6a660c;hp=e7cd5237943c6899e299f7030394bc197de92631;hpb=65cf3563597713173bb688287a21666ec66e722d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index e7cd523794..4d4b0a5359 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -1,6 +1,6 @@ /* Definitions for BFD wrappers used by GDB. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -20,10 +20,12 @@ #include "defs.h" #include "gdb_bfd.h" #include "gdb_assert.h" -#include "gdb_string.h" +#include #include "ui-out.h" #include "gdbcmd.h" #include "hashtab.h" +#include "filestuff.h" +#include "vec.h" #ifdef HAVE_ZLIB_H #include #endif @@ -34,6 +36,9 @@ #endif #endif +typedef bfd *bfdp; +DEF_VEC_P (bfdp); + /* An object of this type is stored in the section's user data when mapping a section. */ @@ -56,21 +61,6 @@ struct gdb_bfd_section_data static htab_t all_bfds; -/* See gdb_bfd.h. */ - -void -gdb_bfd_stash_filename (struct bfd *abfd) -{ - char *name = bfd_get_filename (abfd); - char *data; - - data = bfd_alloc (abfd, strlen (name) + 1); - strcpy (data, name); - - /* Unwarranted chumminess with BFD. */ - abfd->filename = data; -} - /* An object of this type is stored in each BFD's user data. */ struct gdb_bfd_data @@ -81,6 +71,13 @@ struct gdb_bfd_data /* The mtime of the BFD at the point the cache entry was made. */ time_t mtime; + /* This is true if we have determined whether this BFD has any + sections requiring relocation. */ + unsigned int relocation_computed : 1; + + /* This is true if any section needs relocation. */ + unsigned int needs_relocations : 1; + /* This is true if we have successfully computed the file's CRC. */ unsigned int crc_computed : 1; @@ -91,6 +88,9 @@ struct gdb_bfd_data BFD. Otherwise, this is NULL. */ bfd *archive_bfd; + /* Table of all the bfds this bfd has included. */ + VEC (bfdp) *included_bfds; + /* The registry. */ REGISTRY_FIELDS; }; @@ -158,7 +158,7 @@ gdb_bfd_open (const char *name, const char *target, int fd) if (fd == -1) { - fd = open (name, O_RDONLY | O_BINARY); + fd = gdb_open_cloexec (name, O_RDONLY | O_BINARY, 0); if (fd == -1) { bfd_set_error (bfd_error_system_call); @@ -196,7 +196,6 @@ gdb_bfd_open (const char *name, const char *target, int fd) gdb_assert (!*slot); *slot = abfd; - gdb_bfd_stash_filename (abfd); gdb_bfd_ref (abfd); return abfd; } @@ -285,9 +284,10 @@ gdb_bfd_ref (struct bfd *abfd) void gdb_bfd_unref (struct bfd *abfd) { + int ix; struct gdb_bfd_data *gdata; struct gdb_bfd_cache_search search; - bfd *archive_bfd; + bfd *archive_bfd, *included_bfd; if (abfd == NULL) return; @@ -315,6 +315,12 @@ gdb_bfd_unref (struct bfd *abfd) htab_clear_slot (gdb_bfd_cache, slot); } + for (ix = 0; + VEC_iterate (bfdp, gdata->included_bfds, ix, included_bfd); + ++ix) + gdb_bfd_unref (included_bfd); + VEC_free (bfdp, gdata->included_bfds); + bfd_free_data (abfd); bfd_usrdata (abfd) = NULL; /* Paranoia. */ @@ -482,10 +488,7 @@ gdb_bfd_fopen (const char *filename, const char *target, const char *mode, bfd *result = bfd_fopen (filename, target, mode, fd); if (result) - { - gdb_bfd_stash_filename (result); - gdb_bfd_ref (result); - } + gdb_bfd_ref (result); return result; } @@ -498,10 +501,7 @@ gdb_bfd_openr (const char *filename, const char *target) bfd *result = bfd_openr (filename, target); if (result) - { - gdb_bfd_stash_filename (result); - gdb_bfd_ref (result); - } + gdb_bfd_ref (result); return result; } @@ -514,10 +514,7 @@ gdb_bfd_openw (const char *filename, const char *target) bfd *result = bfd_openw (filename, target); if (result) - { - gdb_bfd_stash_filename (result); - gdb_bfd_ref (result); - } + gdb_bfd_ref (result); return result; } @@ -545,10 +542,7 @@ gdb_bfd_openr_iovec (const char *filename, const char *target, pread_func, close_func, stat_func); if (result) - { - gdb_bfd_ref (result); - gdb_bfd_stash_filename (result); - } + gdb_bfd_ref (result); return result; } @@ -589,16 +583,25 @@ gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous) /* See gdb_bfd.h. */ +void +gdb_bfd_record_inclusion (bfd *includer, bfd *includee) +{ + struct gdb_bfd_data *gdata; + + gdb_bfd_ref (includee); + gdata = bfd_usrdata (includer); + VEC_safe_push (bfdp, gdata->included_bfds, includee); +} + +/* See gdb_bfd.h. */ + bfd * gdb_bfd_fdopenr (const char *filename, const char *target, int fd) { bfd *result = bfd_fdopenr (filename, target, fd); if (result) - { - gdb_bfd_ref (result); - gdb_bfd_stash_filename (result); - } + gdb_bfd_ref (result); return result; } @@ -633,6 +636,30 @@ gdb_bfd_count_sections (bfd *abfd) return bfd_count_sections (abfd) + 4; } +/* See gdb_bfd.h. */ + +int +gdb_bfd_requires_relocations (bfd *abfd) +{ + struct gdb_bfd_data *gdata = bfd_usrdata (abfd); + + if (gdata->relocation_computed == 0) + { + asection *sect; + + for (sect = abfd->sections; sect != NULL; sect = sect->next) + if ((sect->flags & SEC_RELOC) != 0) + { + gdata->needs_relocations = 1; + break; + } + + gdata->relocation_computed = 1; + } + + return gdata->needs_relocations; +} + /* A callback for htab_traverse that prints a single BFD. */