PR symtab/16426
[deliverable/binutils-gdb.git] / gdb / gdb_bfd.c
index e7cd5237943c6899e299f7030394bc197de92631..4d4b0a53593a3560b742a27f7ad51d1dff5e109f 100644 (file)
@@ -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.
 
 #include "defs.h"
 #include "gdb_bfd.h"
 #include "gdb_assert.h"
-#include "gdb_string.h"
+#include <string.h>
 #include "ui-out.h"
 #include "gdbcmd.h"
 #include "hashtab.h"
+#include "filestuff.h"
+#include "vec.h"
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #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;
+}
+
 \f
 
 /* A callback for htab_traverse that prints a single BFD.  */
This page took 0.03157 seconds and 4 git commands to generate.