2006-03-17 Daniel Jacobowitz <dan@codesourcery.com>
[deliverable/binutils-gdb.git] / bfd / bfd.c
index 3ead0ee5b5ac7bbd758610fe4756bdf1b27f883c..733f6ee0272db1beb8b385505719f27f45929391 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,6 +1,6 @@
 /* Generic BFD library interface and support routines.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004
+   2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -18,7 +18,7 @@
 
    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.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 /*
 SECTION
@@ -111,8 +111,8 @@ CODE_FRAGMENT
 .  {* Pointer to linked list of sections.  *}
 .  struct bfd_section *sections;
 .
-.  {* The place where we add to the section list.  *}
-.  struct bfd_section **section_tail;
+.  {* The last section on the section list.  *}
+.  struct bfd_section *section_last;
 .
 .  {* The number of sections.  *}
 .  unsigned int section_count;
@@ -133,6 +133,9 @@ CODE_FRAGMENT
 .  {* Pointer to structure which contains architecture information.  *}
 .  const struct bfd_arch_info *arch_info;
 .
+.  {* Flag set if symbols from this BFD should not be exported.  *}
+.  bfd_boolean no_export;
+.
 .  {* Stuff only useful for archives.  *}
 .  void *arelt_data;
 .  struct bfd *my_archive;      {* The containing archive BFD.  *}
@@ -213,6 +216,11 @@ CODE_FRAGMENT
 #include "libecoff.h"
 #undef obj_symbols
 #include "elf-bfd.h"
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
 \f
 /* provide storage for subsystem, stack and heap data which may have been
    passed in on the command line.  Ld puts this data into a bfd_link_info
@@ -406,23 +414,152 @@ CODE_FRAGMENT
 
 static const char *_bfd_error_program_name;
 
-/* This is the default routine to handle BFD error messages.  */
+/* This is the default routine to handle BFD error messages.
+   Like fprintf (stderr, ...), but also handles some extra format specifiers.
+
+   %A section name from section.  For group components, print group name too.
+   %B file name from bfd.  For archive components, prints archive too.
+ */
 
-static void
-_bfd_default_error_handler (const char *s, ...)
+void
+_bfd_default_error_handler (const char *fmt, ...)
 {
-  va_list p;
+  va_list ap;
+  char *bufp;
+  const char *new_fmt, *p;
+  size_t avail = 1000;
+  char buf[1000];
 
   if (_bfd_error_program_name != NULL)
     fprintf (stderr, "%s: ", _bfd_error_program_name);
   else
     fprintf (stderr, "BFD: ");
 
-  va_start (p, s);
-  vfprintf (stderr, s, p);
-  va_end (p);
+  va_start (ap, fmt);
+  new_fmt = fmt;
+  bufp = buf;
+
+  /* Reserve enough space for the existing format string.  */
+  avail -= strlen (fmt) + 1;
+  if (avail > 1000)
+    _exit (EXIT_FAILURE);
+
+  p = fmt;
+  while (1)
+    {
+      char *q;
+      size_t len, extra, trim;
+
+      p = strchr (p, '%');
+      if (p == NULL || p[1] == '\0')
+       {
+         if (new_fmt == buf)
+           {
+             len = strlen (fmt);
+             memcpy (bufp, fmt, len + 1);
+           }
+         break;
+       }
+
+      if (p[1] == 'A' || p[1] == 'B')
+       {
+         len = p - fmt;
+         memcpy (bufp, fmt, len);
+         bufp += len;
+         fmt = p + 2;
+         new_fmt = buf;
+
+         /* If we run out of space, tough, you lose your ridiculously
+            long file or section name.  It's not safe to try to alloc
+            memory here;  We might be printing an out of memory message.  */
+         if (avail == 0)
+           {
+             *bufp++ = '*';
+             *bufp++ = '*';
+             *bufp = '\0';
+           }
+         else
+           {
+             if (p[1] == 'B')
+               {
+                 bfd *abfd = va_arg (ap, bfd *);
+                 if (abfd->my_archive)
+                   snprintf (bufp, avail, "%s(%s)",
+                             abfd->my_archive->filename, abfd->filename);
+                 else
+                   snprintf (bufp, avail, "%s", abfd->filename);
+               }
+             else
+               {
+                 asection *sec = va_arg (ap, asection *);
+                 bfd *abfd = sec->owner;
+                 const char *group = NULL;
+                 struct coff_comdat_info *ci;
+
+                 if (abfd != NULL
+                     && bfd_get_flavour (abfd) == bfd_target_elf_flavour
+                     && elf_next_in_group (sec) != NULL
+                     && (sec->flags & SEC_GROUP) == 0)
+                   group = elf_group_name (sec);
+                 else if (abfd != NULL
+                          && bfd_get_flavour (abfd) == bfd_target_coff_flavour
+                          && (ci = bfd_coff_get_comdat_section (sec->owner,
+                                                                sec)) != NULL)
+                   group = ci->name;
+                 if (group != NULL)
+                   snprintf (bufp, avail, "%s[%s]", sec->name, group);
+                 else
+                   snprintf (bufp, avail, "%s", sec->name);
+               }
+             len = strlen (bufp);
+             avail = avail - len + 2;
+
+             /* We need to replace any '%' we printed by "%%".
+                First count how many.  */
+             q = bufp;
+             bufp += len;
+             extra = 0;
+             while ((q = strchr (q, '%')) != NULL)
+               {
+                 ++q;
+                 ++extra;
+               }
+
+             /* If there isn't room, trim off the end of the string.  */
+             q = bufp;
+             bufp += extra;
+             if (extra > avail)
+               {
+                 trim = extra - avail;
+                 bufp -= trim;
+                 do
+                   {
+                     if (*--q == '%')
+                       --extra;
+                   }
+                 while (--trim != 0);
+                 *q = '\0';
+                 avail = extra;
+               }
+             avail -= extra;
+
+             /* Now double all '%' chars, shuffling the string as we go.  */
+             while (extra != 0)
+               {
+                 while ((q[extra] = *q) != '%')
+                   --q;
+                 q[--extra] = '%';
+                 --q;
+               }
+           }
+       }
+      p = p + 2;
+    }
+
+  vfprintf (stderr, new_fmt, ap);
+  va_end (ap);
 
-  fprintf (stderr, "\n");
+  putc ('\n', stderr);
 }
 
 /* This is a function pointer to the routine which should handle BFD
@@ -491,60 +628,13 @@ bfd_get_error_handler (void)
 {
   return _bfd_error_handler;
 }
-
-/*
-FUNCTION
-       bfd_archive_filename
-
-SYNOPSIS
-       const char *bfd_archive_filename (bfd *);
-
-DESCRIPTION
-       For a BFD that is a component of an archive, returns a string
-       with both the archive name and file name.  For other BFDs, just
-       returns the file name.
-*/
-
-const char *
-bfd_archive_filename (bfd *abfd)
-{
-  if (abfd == NULL)
-    return NULL;
-  
-  if (abfd->my_archive)
-    {
-      static size_t curr = 0;
-      static char *buf;
-      size_t needed;
-
-      needed = (strlen (bfd_get_filename (abfd->my_archive))
-               + strlen (bfd_get_filename (abfd)) + 3);
-      if (needed > curr)
-       {
-         if (curr)
-           free (buf);
-         curr = needed + (needed >> 1);
-         buf = bfd_malloc (curr);
-         /* If we can't malloc, fail safe by returning just the file
-            name. This function is only used when building error
-            messages.  */
-         if (!buf)
-           {
-             curr = 0;
-             return bfd_get_filename (abfd);
-           }
-       }
-      sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
-              bfd_get_filename (abfd));
-      return buf;
-    }
-  else
-    return bfd_get_filename (abfd);
-}
 \f
 /*
 SECTION
-       Symbols
+       Miscellaneous
+
+SUBSECTION
+       Miscellaneous functions
 */
 
 /*
@@ -690,10 +780,6 @@ bfd_assert (const char *file, int line)
 /* A more or less friendly abort message.  In libbfd.h abort is
    defined to call this function.  */
 
-#ifndef EXIT_FAILURE
-#define EXIT_FAILURE 1
-#endif
-
 void
 _bfd_abort (const char *file, int line, const char *fn)
 {
@@ -706,7 +792,7 @@ _bfd_abort (const char *file, int line, const char *fn)
       (_("BFD %s internal error, aborting at %s line %d\n"),
        BFD_VERSION_STRING, file, line);
   (*_bfd_error_handler) (_("Please report this bug.\n"));
-  xexit (EXIT_FAILURE);
+  _exit (EXIT_FAILURE);
 }
 
 /*
@@ -1079,6 +1165,14 @@ DESCRIPTION
 .       BFD_SEND (abfd, _bfd_find_nearest_line, \
 .                 (abfd, sec, syms, off, file, func, line))
 .
+.#define bfd_find_line(abfd, syms, sym, file, line) \
+.       BFD_SEND (abfd, _bfd_find_line, \
+.                 (abfd, syms, sym, file, line))
+.
+.#define bfd_find_inliner_info(abfd, file, func, line) \
+.       BFD_SEND (abfd, _bfd_find_inliner_info, \
+.                 (abfd, file, func, line))
+.
 .#define bfd_debug_info_start(abfd) \
 .       BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
 .
@@ -1121,7 +1215,7 @@ DESCRIPTION
 .#define bfd_link_add_symbols(abfd, info) \
 .      BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
 .
-.#define bfd_link_just_syms(sec, info) \
+.#define bfd_link_just_syms(abfd, sec, info) \
 .      BFD_SEND (abfd, _bfd_link_just_syms, (sec, info))
 .
 .#define bfd_final_link(abfd, info) \
@@ -1139,8 +1233,9 @@ DESCRIPTION
 .#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
 .      BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
 .
-.#define bfd_get_synthetic_symtab(abfd, dynsyms, ret) \
-.      BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, dynsyms, ret))
+.#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
+.      BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
+.                                                  dyncount, dynsyms, ret))
 .
 .#define bfd_get_dynamic_reloc_upper_bound(abfd) \
 .      BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
@@ -1307,7 +1402,7 @@ CODE_FRAGMENT
 .  flagword flags;
 .  const struct bfd_arch_info *arch_info;
 .  struct bfd_section *sections;
-.  struct bfd_section **section_tail;
+.  struct bfd_section *section_last;
 .  unsigned int section_count;
 .  struct bfd_hash_table section_htab;
 .};
@@ -1341,18 +1436,19 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
   preserve->arch_info = abfd->arch_info;
   preserve->flags = abfd->flags;
   preserve->sections = abfd->sections;
-  preserve->section_tail = abfd->section_tail;
+  preserve->section_last = abfd->section_last;
   preserve->section_count = abfd->section_count;
   preserve->section_htab = abfd->section_htab;
 
-  if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc))
+  if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc,
+                            sizeof (struct section_hash_entry)))
     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_last = NULL;
   abfd->section_count = 0;
 
   return TRUE;
@@ -1382,7 +1478,7 @@ bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
   abfd->flags = preserve->flags;
   abfd->section_htab = preserve->section_htab;
   abfd->sections = preserve->sections;
-  abfd->section_tail = preserve->section_tail;
+  abfd->section_last = preserve->section_last;
   abfd->section_count = preserve->section_count;
 
   /* bfd_release frees all memory more recently bfd_alloc'd than
This page took 0.028181 seconds and 4 git commands to generate.