daily update
[deliverable/binutils-gdb.git] / bfd / bfd.c
index f67e85c44b773afd763c19ff8e66aa293668fd0a..3783ccfc39dcee73db971667dea529fa1d7782e8 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
    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.  *}
@@ -406,23 +409,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.
+ */
 
 void
-_bfd_default_error_handler (const char *s, ...)
+_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)
+    abort ();
+
+  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 +623,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
 */
 
 /*
@@ -1079,6 +1164,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 +1214,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 +1232,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 +1401,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,7 +1435,7 @@ 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;
 
@@ -1352,7 +1446,7 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
   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 +1476,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
@@ -1420,43 +1514,26 @@ bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve)
 
 /*
 FUNCTION
-       bfd_get_section_ident
+       bfd_hide_symbol
 
 SYNOPSIS
-       char *bfd_get_section_ident (asection *sec);
+       void bfd_hide_symbol (bfd *,
+                             struct bfd_link_info *,
+                             struct bfd_link_hash_entry *,
+                             bfd_boolean);
 
 DESCRIPTION
-       This function returns "section name[group name]" in a malloced
-       buffer if @var{sec} is a member of an ELF section group and
-       returns NULL otherwise. The caller should free the non-NULL
-       return after use.
+       This function hides a symbol so that it won't be exported. 
 
 */
 
-char *
-bfd_get_section_ident (asection *sec)
+void
+bfd_hide_symbol (bfd *abfd,
+                struct bfd_link_info *link_info,
+                struct bfd_link_hash_entry *h,
+                bfd_boolean force_local)
 {
-  char *buf;
-  bfd_size_type nlen;
-  bfd_size_type glen;
-
-  if (sec->owner == NULL
-      || bfd_get_flavour (sec->owner) != bfd_target_elf_flavour
-      || elf_next_in_group (sec) == NULL
-      || (sec->flags & SEC_GROUP) != 0)
-    return NULL;
-
-  nlen = strlen (sec->name);
-  glen = strlen (elf_group_name (sec));
-  buf = bfd_malloc (nlen + glen + 2 + 1);
-  if (buf != NULL)
-    {
-      strcpy (buf, sec->name);
-      buf [nlen] = '[';
-      strcpy (&buf [nlen + 1], elf_group_name (sec));
-      buf [nlen + 1 + glen] = ']';
-      buf [nlen + 1 + glen + 1] = '\0';
-    }
-
-  return buf;
+  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+    (get_elf_backend_data (abfd)->elf_backend_hide_symbol)
+      (link_info, (struct elf_link_hash_entry *) h, force_local);
 }
This page took 0.02845 seconds and 4 git commands to generate.