merge from gcc
[deliverable/binutils-gdb.git] / bfd / bfd.c
index bf4516216576e2234f6bac75e45e02dbf5cb49f6..1a332a866b20888e6ce8745353b9cae3f44d62a9 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -4,21 +4,21 @@
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
 SECTION
@@ -36,6 +36,9 @@ CODE_FRAGMENT
 .
 .struct _bfd
 .{
+.  {* A unique identifier of the BFD  *}
+.  unsigned int id;
+.
 .  {* The filename the application opened the BFD with.  *}
 .  const char *filename;
 .
@@ -53,12 +56,12 @@ CODE_FRAGMENT
 .
 .  {* Is the file descriptor being cached?  That is, can it be closed as
 .     needed, and re-opened when accessed later?  *}
-.  boolean cacheable;
+.  bfd_boolean cacheable;
 .
 .  {* Marks whether there was a default target specified when the
 .     BFD was opened. This is used to select which matching algorithm
 .     to use to choose the back end.  *}
-.  boolean target_defaulted;
+.  bfd_boolean target_defaulted;
 .
 .  {* The caching routines use these to maintain a
 .     least-recently-used list of BFDs.  *}
@@ -69,13 +72,13 @@ CODE_FRAGMENT
 .  ufile_ptr where;
 .
 .  {* ... and here: (``once'' means at least once).  *}
-.  boolean opened_once;
+.  bfd_boolean opened_once;
 .
 .  {* Set if we have a locally maintained mtime value, rather than
 .     getting it from the file each time.  *}
-.  boolean mtime_set;
+.  bfd_boolean mtime_set;
 .
-.  {* File modified time, if mtime_set is true.  *}
+.  {* File modified time, if mtime_set is TRUE.  *}
 .  long mtime;
 .
 .  {* Reserved for an unimplemented file locking extension.  *}
@@ -104,7 +107,7 @@ CODE_FRAGMENT
 .
 .  {* Remember when output has begun, to stop strange things
 .     from happening.  *}
-.  boolean output_has_begun;
+.  bfd_boolean output_has_begun;
 .
 .  {* A hash table for section names.  *}
 .  struct bfd_hash_table section_htab;
@@ -139,7 +142,7 @@ CODE_FRAGMENT
 .  struct _bfd *my_archive;     {* The containing archive BFD.  *}
 .  struct _bfd *next;           {* The next BFD in the archive.  *}
 .  struct _bfd *archive_head;   {* The first BFD in the archive.  *}
-.  boolean has_armap;
+.  bfd_boolean has_armap;
 .
 .  {* A chain of BFD structures involved in a link.  *}
 .  struct _bfd *link_next;
@@ -180,6 +183,11 @@ CODE_FRAGMENT
 .      struct cisco_core_struct *cisco_core_data;
 .      struct versados_data_struct *versados_data;
 .      struct netbsd_core_struct *netbsd_core_data;
+.      struct mach_o_data_struct *mach_o_data;
+.      struct mach_o_fat_data_struct *mach_o_fat_data;
+.      struct bfd_pef_data_struct *pef_data;
+.      struct bfd_pef_xlib_data_struct *pef_xlib_data;
+.      struct bfd_sym_data_struct *sym_data;
 .      PTR any;
 .    }
 .  tdata;
@@ -654,7 +662,7 @@ FUNCTION
        bfd_set_file_flags
 
 SYNOPSIS
-       boolean bfd_set_file_flags(bfd *abfd, flagword flags);
+       bfd_boolean bfd_set_file_flags(bfd *abfd, flagword flags);
 
 DESCRIPTION
        Set the flag word in the BFD @var{abfd} to the value @var{flags}.
@@ -669,7 +677,7 @@ DESCRIPTION
 
 */
 
-boolean
+bfd_boolean
 bfd_set_file_flags (abfd, flags)
      bfd *abfd;
      flagword flags;
@@ -677,23 +685,23 @@ bfd_set_file_flags (abfd, flags)
   if (abfd->format != bfd_object)
     {
       bfd_set_error (bfd_error_wrong_format);
-      return false;
+      return FALSE;
     }
 
   if (bfd_read_p (abfd))
     {
       bfd_set_error (bfd_error_invalid_operation);
-      return false;
+      return FALSE;
     }
 
   bfd_get_file_flags (abfd) = flags;
   if ((flags & bfd_applicable_file_flags (abfd)) != flags)
     {
       bfd_set_error (bfd_error_invalid_operation);
-      return false;
+      return FALSE;
     }
 
-  return true;
+  return TRUE;
 }
 
 void
@@ -805,103 +813,22 @@ FUNCTION
        bfd_set_start_address
 
 SYNOPSIS
-       boolean bfd_set_start_address(bfd *abfd, bfd_vma vma);
+       bfd_boolean bfd_set_start_address(bfd *abfd, bfd_vma vma);
 
 DESCRIPTION
        Make @var{vma} the entry point of output BFD @var{abfd}.
 
 RETURNS
-       Returns <<true>> on success, <<false>> otherwise.
+       Returns <<TRUE>> on success, <<FALSE>> otherwise.
 */
 
-boolean
+bfd_boolean
 bfd_set_start_address (abfd, vma)
      bfd *abfd;
      bfd_vma vma;
 {
   abfd->start_address = vma;
-  return true;
-}
-
-/*
-FUNCTION
-       bfd_get_mtime
-
-SYNOPSIS
-       long bfd_get_mtime(bfd *abfd);
-
-DESCRIPTION
-       Return the file modification time (as read from the file system, or
-       from the archive header for archive members).
-
-*/
-
-long
-bfd_get_mtime (abfd)
-     bfd *abfd;
-{
-  FILE *fp;
-  struct stat buf;
-
-  if (abfd->mtime_set)
-    return abfd->mtime;
-
-  fp = bfd_cache_lookup (abfd);
-  if (0 != fstat (fileno (fp), &buf))
-    return 0;
-
-  abfd->mtime = buf.st_mtime;          /* Save value in case anyone wants it */
-  return buf.st_mtime;
-}
-
-/*
-FUNCTION
-       bfd_get_size
-
-SYNOPSIS
-       long bfd_get_size(bfd *abfd);
-
-DESCRIPTION
-       Return the file size (as read from file system) for the file
-       associated with BFD @var{abfd}.
-
-       The initial motivation for, and use of, this routine is not
-       so we can get the exact size of the object the BFD applies to, since
-       that might not be generally possible (archive members for example).
-       It would be ideal if someone could eventually modify
-       it so that such results were guaranteed.
-
-       Instead, we want to ask questions like "is this NNN byte sized
-       object I'm about to try read from file offset YYY reasonable?"
-       As as example of where we might do this, some object formats
-       use string tables for which the first <<sizeof (long)>> bytes of the
-       table contain the size of the table itself, including the size bytes.
-       If an application tries to read what it thinks is one of these
-       string tables, without some way to validate the size, and for
-       some reason the size is wrong (byte swapping error, wrong location
-       for the string table, etc.), the only clue is likely to be a read
-       error when it tries to read the table, or a "virtual memory
-       exhausted" error when it tries to allocate 15 bazillon bytes
-       of space for the 15 bazillon byte table it is about to read.
-       This function at least allows us to answer the quesion, "is the
-       size reasonable?".
-*/
-
-long
-bfd_get_size (abfd)
-     bfd *abfd;
-{
-  FILE *fp;
-  struct stat buf;
-
-  if ((abfd->flags & BFD_IN_MEMORY) != 0)
-    return ((struct bfd_in_memory *) abfd->iostream)->size;
-
-  fp = bfd_cache_lookup (abfd);
-  if (0 != fstat (fileno (fp), & buf))
-    return 0;
-
-  return buf.st_size;
+  return TRUE;
 }
 
 /*
@@ -1089,11 +1016,11 @@ FUNCTION
        bfd_copy_private_bfd_data
 
 SYNOPSIS
-       boolean bfd_copy_private_bfd_data(bfd *ibfd, bfd *obfd);
+       bfd_boolean bfd_copy_private_bfd_data(bfd *ibfd, bfd *obfd);
 
 DESCRIPTION
        Copy private BFD information from the BFD @var{ibfd} to the
-       the BFD @var{obfd}.  Return <<true>> on success, <<false>> on error.
+       the BFD @var{obfd}.  Return <<TRUE>> on success, <<FALSE>> on error.
        Possible error returns are:
 
        o <<bfd_error_no_memory>> -
@@ -1110,12 +1037,12 @@ FUNCTION
        bfd_merge_private_bfd_data
 
 SYNOPSIS
-       boolean bfd_merge_private_bfd_data(bfd *ibfd, bfd *obfd);
+       bfd_boolean bfd_merge_private_bfd_data(bfd *ibfd, bfd *obfd);
 
 DESCRIPTION
        Merge private BFD information from the BFD @var{ibfd} to the
-       the output file BFD @var{obfd} when linking.  Return <<true>>
-       on success, <<false>> on error.  Possible error returns are:
+       the output file BFD @var{obfd} when linking.  Return <<TRUE>>
+       on success, <<FALSE>> on error.  Possible error returns are:
 
        o <<bfd_error_no_memory>> -
        Not enough memory exists to create private data for @var{obfd}.
@@ -1131,11 +1058,11 @@ FUNCTION
        bfd_set_private_flags
 
 SYNOPSIS
-       boolean bfd_set_private_flags(bfd *abfd, flagword flags);
+       bfd_boolean bfd_set_private_flags(bfd *abfd, flagword flags);
 
 DESCRIPTION
        Set private BFD flag information in the BFD @var{abfd}.
-       Return <<true>> on success, <<false>> on error.  Possible error
+       Return <<TRUE>> on success, <<FALSE>> on error.  Possible error
        returns are:
 
        o <<bfd_error_no_memory>> -
@@ -1228,7 +1155,7 @@ DESCRIPTION
 .extern bfd_byte *bfd_get_relocated_section_contents
 .      PARAMS ((bfd *, struct bfd_link_info *,
 .                struct bfd_link_order *, bfd_byte *,
-.                boolean, asymbol **));
+.                bfd_boolean, asymbol **));
 .
 
 */
@@ -1240,12 +1167,12 @@ bfd_get_relocated_section_contents (abfd, link_info, link_order, data,
      struct bfd_link_info *link_info;
      struct bfd_link_order *link_order;
      bfd_byte *data;
-     boolean relocateable;
+     bfd_boolean relocateable;
      asymbol **symbols;
 {
   bfd *abfd2;
   bfd_byte *(*fn) PARAMS ((bfd *, struct bfd_link_info *,
-                          struct bfd_link_order *, bfd_byte *, boolean,
+                          struct bfd_link_order *, bfd_byte *, bfd_boolean,
                           asymbol **));
 
   if (link_order->type == bfd_indirect_link_order)
@@ -1264,17 +1191,17 @@ bfd_get_relocated_section_contents (abfd, link_info, link_order, data,
 
 /* Record information about an ELF program header.  */
 
-boolean
+bfd_boolean
 bfd_record_phdr (abfd, type, flags_valid, flags, at_valid, at,
                 includes_filehdr, includes_phdrs, count, secs)
      bfd *abfd;
      unsigned long type;
-     boolean flags_valid;
+     bfd_boolean flags_valid;
      flagword flags;
-     boolean at_valid;
+     bfd_boolean at_valid;
      bfd_vma at;
-     boolean includes_filehdr;
-     boolean includes_phdrs;
+     bfd_boolean includes_filehdr;
+     bfd_boolean includes_phdrs;
      unsigned int count;
      asection **secs;
 {
@@ -1282,13 +1209,13 @@ bfd_record_phdr (abfd, type, flags_valid, flags, at_valid, at,
   bfd_size_type amt;
 
   if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
-    return true;
+    return TRUE;
 
   amt = sizeof (struct elf_segment_map);
   amt += ((bfd_size_type) count - 1) * sizeof (asection *);
   m = (struct elf_segment_map *) bfd_alloc (abfd, amt);
   if (m == NULL)
-    return false;
+    return FALSE;
 
   m->next = NULL;
   m->p_type = type;
@@ -1306,7 +1233,7 @@ bfd_record_phdr (abfd, type, flags_valid, flags, at_valid, at,
     ;
   *pm = m;
 
-  return true;
+  return TRUE;
 }
 
 void
@@ -1338,7 +1265,7 @@ FUNCTION
        bfd_alt_mach_code
 
 SYNOPSIS
-       boolean bfd_alt_mach_code(bfd *abfd, int alternative);
+       bfd_boolean bfd_alt_mach_code(bfd *abfd, int alternative);
 
 DESCRIPTION
 
@@ -1349,7 +1276,7 @@ DESCRIPTION
        machine codes.
 */
 
-boolean
+bfd_boolean
 bfd_alt_mach_code (abfd, alternative)
      bfd *abfd;
      int alternative;
@@ -1367,23 +1294,150 @@ bfd_alt_mach_code (abfd, alternative)
        case 1:
          code = get_elf_backend_data (abfd)->elf_machine_alt1;
          if (code == 0)
-           return false;
+           return FALSE;
          break;
 
        case 2:
          code = get_elf_backend_data (abfd)->elf_machine_alt2;
          if (code == 0)
-           return false;
+           return FALSE;
          break;
 
        default:
-         return false;
+         return FALSE;
        }
 
       elf_elfheader (abfd)->e_machine = code;
 
-      return true;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/*
+CODE_FRAGMENT
+
+.struct bfd_preserve
+.{
+.  PTR marker;
+.  PTR tdata;
+.  flagword flags;
+.  const struct bfd_arch_info *arch_info;
+.  struct sec *sections;
+.  struct sec **section_tail;
+.  unsigned int section_count;
+.  struct bfd_hash_table section_htab;
+.};
+.
+*/
+
+/*
+FUNCTION
+       bfd_preserve_save
+
+SYNOPSIS
+       bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *);
+
+DESCRIPTION
+       When testing an object for compatibility with a particular
+       target back-end, the back-end object_p function needs to set
+       up certain fields in the bfd on successfully recognizing the
+       object.  This typically happens in a piecemeal fashion, with
+       failures possible at many points.  On failure, the bfd is
+       supposed to be restored to its initial state, which is
+       virtually impossible.  However, restoring a subset of the bfd
+       state works in practice.  This function stores the subset and
+       reinitializes the bfd.
+
+*/
+
+bfd_boolean
+bfd_preserve_save (abfd, preserve)
+     bfd *abfd;
+     struct bfd_preserve *preserve;
+{
+  preserve->tdata = abfd->tdata.any;
+  preserve->arch_info = abfd->arch_info;
+  preserve->flags = abfd->flags;
+  preserve->sections = abfd->sections;
+  preserve->section_tail = abfd->section_tail;
+  preserve->section_count = abfd->section_count;
+  preserve->section_htab = abfd->section_htab;
+
+  if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc))
+    return FALSE;
+
+  abfd->tdata.any = NULL;
+  abfd->arch_info = &bfd_default_arch_struct;
+  abfd->flags &= BFD_IN_MEMORY;
+  abfd->sections = NULL;
+  abfd->section_tail = &abfd->sections;
+  abfd->section_count = 0;
+
+  return TRUE;
+}
+
+/*
+FUNCTION
+       bfd_preserve_restore
+
+SYNOPSIS
+       void bfd_preserve_restore (bfd *, struct bfd_preserve *);
+
+DESCRIPTION
+       This function restores bfd state saved by bfd_preserve_save.
+       If MARKER is non-NULL in struct bfd_preserve then that block
+       and all subsequently bfd_alloc'd memory is freed.
+
+*/
+
+void
+bfd_preserve_restore (abfd, preserve)
+     bfd *abfd;
+     struct bfd_preserve *preserve;
+{
+  bfd_hash_table_free (&abfd->section_htab);
+
+  abfd->tdata.any = preserve->tdata;
+  abfd->arch_info = preserve->arch_info;
+  abfd->flags = preserve->flags;
+  abfd->section_htab = preserve->section_htab;
+  abfd->sections = preserve->sections;
+  abfd->section_tail = preserve->section_tail;
+  abfd->section_count = preserve->section_count;
+
+  /* bfd_release frees all memory more recently bfd_alloc'd than
+     its arg, as well as its arg.  */
+  if (preserve->marker != NULL)
+    {
+      bfd_release (abfd, preserve->marker);
+      preserve->marker = NULL;
     }
+}
 
-  return false;
+/*
+FUNCTION
+       bfd_preserve_finish
+
+SYNOPSIS
+       void bfd_preserve_finish (bfd *, struct bfd_preserve *);
+
+DESCRIPTION
+       This function should be called when the bfd state saved by
+       bfd_preserve_save is no longer needed.  ie. when the back-end
+       object_p function returns with success.
+
+*/
+
+void
+bfd_preserve_finish (abfd, preserve)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     struct bfd_preserve *preserve;
+{
+  /* It would be nice to be able to free more memory here, eg. old
+     tdata, but that's not possible since these blocks are sitting
+     inside bfd_alloc'd memory.  The section hash is on a separate
+     objalloc.  */
+  bfd_hash_table_free (&preserve->section_htab);
 }
This page took 0.029973 seconds and 4 git commands to generate.