* dep-in.sed: Cope with absolute paths.
[deliverable/binutils-gdb.git] / bfd / bfd.c
index 8101814106f2f04f6f9e9b68bb8327ad001c7370..57953837c16c834a2a25274a598fd188e547dac1 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
+   2000, 2001, 2002
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -36,121 +36,118 @@ CODE_FRAGMENT
 .
 .struct _bfd
 .{
-.    {* The filename the application opened the BFD with.  *}
-.    const char *filename;
+.  {* The filename the application opened the BFD with.  *}
+.  const char *filename;
 .
-.    {* A pointer to the target jump table.             *}
-.    const struct bfd_target *xvec;
+.  {* A pointer to the target jump table.  *}
+.  const struct bfd_target *xvec;
 .
-.    {* To avoid dragging too many header files into every file that
-.       includes `<<bfd.h>>', IOSTREAM has been declared as a "char
-.       *", and MTIME as a "long".  Their correct types, to which they
-.       are cast when used, are "FILE *" and "time_t".    The iostream
-.       is the result of an fopen on the filename.  However, if the
-.       BFD_IN_MEMORY flag is set, then iostream is actually a pointer
-.       to a bfd_in_memory struct.  *}
-.    PTR iostream;
+.  {* To avoid dragging too many header files into every file that
+.     includes `<<bfd.h>>', IOSTREAM has been declared as a "char *",
+.     and MTIME as a "long".  Their correct types, to which they
+.     are cast when used, are "FILE *" and "time_t".    The iostream
+.     is the result of an fopen on the filename.  However, if the
+.     BFD_IN_MEMORY flag is set, then iostream is actually a pointer
+.     to a bfd_in_memory struct.  *}
+.  PTR iostream;
+.
+.  {* Is the file descriptor being cached?  That is, can it be closed as
+.     needed, and re-opened when accessed later?  *}
+.  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;
+.
+.  {* The caching routines use these to maintain a
+.     least-recently-used list of BFDs.  *}
+.  struct _bfd *lru_prev, *lru_next;
+.
+.  {* When a file is closed by the caching routines, BFD retains
+.     state information on the file here...  *}
+.  ufile_ptr where;
+.
+.  {* ... and here: (``once'' means at least once).  *}
+.  boolean opened_once;
+.
+.  {* Set if we have a locally maintained mtime value, rather than
+.     getting it from the file each time.  *}
+.  boolean mtime_set;
+.
+.  {* File modified time, if mtime_set is true.  *}
+.  long mtime;
+.
+.  {* Reserved for an unimplemented file locking extension.  *}
+.  int ifd;
+.
+.  {* The format which belongs to the BFD. (object, core, etc.)  *}
+.  bfd_format format;
+.
+.  {* The direction with which the BFD was opened.  *}
+.  enum bfd_direction
+.    {
+.      no_direction = 0,
+.      read_direction = 1,
+.      write_direction = 2,
+.      both_direction = 3
+.    }
+.  direction;
+.
+.  {* Format_specific flags.  *}
+.  flagword flags;
+.
+.  {* Currently my_archive is tested before adding origin to
+.     anything. I believe that this can become always an add of
+.     origin, with origin set to 0 for non archive files.  *}
+.  ufile_ptr origin;
+.
+.  {* Remember when output has begun, to stop strange things
+.     from happening.  *}
+.  boolean output_has_begun;
+.
+.  {* A hash table for section names.  *}
+.  struct bfd_hash_table section_htab;
+.
+.  {* Pointer to linked list of sections.  *}
+.  struct sec *sections;
+.
+.  {* The place where we add to the section list.  *}
+.  struct sec **section_tail;
+.
+.  {* The number of sections.  *}
+.  unsigned int section_count;
+.
+.  {* Stuff only useful for object files:
+.     The start address.  *}
+.  bfd_vma start_address;
+.
+.  {* Used for input and output.  *}
+.  unsigned int symcount;
+.
+.  {* Symbol table for output BFD (with symcount entries).  *}
+.  struct symbol_cache_entry  **outsymbols;
+.
+.  {* Pointer to structure which contains architecture information.  *}
+.  const struct bfd_arch_info *arch_info;
+.
+.  {* Stuff only useful for archives.  *}
+.  PTR arelt_data;
+.  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;
 .
-.    {* Is the file descriptor being cached?  That is, can it be closed as
-.       needed, and re-opened when accessed later?  *}
-.
-.    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;
-.
-.    {* The caching routines use these to maintain a
-.       least-recently-used list of BFDs *}
-.
-.    struct _bfd *lru_prev, *lru_next;
-.
-.    {* When a file is closed by the caching routines, BFD retains
-.       state information on the file here: *}
-.
-.    ufile_ptr where;
-.
-.    {* and here: (``once'' means at least once) *}
-.
-.    boolean opened_once;
-.
-.    {* Set if we have a locally maintained mtime value, rather than
-.       getting it from the file each time: *}
-.
-.    boolean mtime_set;
-.
-.    {* File modified time, if mtime_set is true: *}
-.
-.    long mtime;
-.
-.    {* Reserved for an unimplemented file locking extension.*}
-.
-.    int ifd;
-.
-.    {* The format which belongs to the BFD. (object, core, etc.) *}
-.
-.    bfd_format format;
-.
-.    {* The direction the BFD was opened with*}
-.
-.    enum bfd_direction {no_direction = 0,
-.                        read_direction = 1,
-.                        write_direction = 2,
-.                        both_direction = 3} direction;
-.
-.    {* Format_specific flags*}
-.
-.    flagword flags;
-.
-.    {* Currently my_archive is tested before adding origin to
-.       anything. I believe that this can become always an add of
-.       origin, with origin set to 0 for non archive files.   *}
-.
-.    ufile_ptr origin;
-.
-.    {* Remember when output has begun, to stop strange things
-.       from happening. *}
-.    boolean output_has_begun;
-.
-.    {* Pointer to linked list of sections*}
-.    struct sec  *sections;
-.
-.    {* The number of sections *}
-.    unsigned int section_count;
-.
-.    {* Stuff only useful for object files:
-.       The start address. *}
-.    bfd_vma start_address;
-.
-.    {* Used for input and output*}
-.    unsigned int symcount;
-.
-.    {* Symbol table for output BFD (with symcount entries) *}
-.    struct symbol_cache_entry  **outsymbols;
-.
-.    {* Pointer to structure which contains architecture information*}
-.    const struct bfd_arch_info *arch_info;
-.
-.    {* Stuff only useful for archives:*}
-.    PTR arelt_data;
-.    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;
-.
-.    {* A chain of BFD structures involved in a link.  *}
-.    struct _bfd *link_next;
-.
-.    {* A field used by _bfd_generic_link_add_archive_symbols.  This will
-.       be used only for archive elements.  *}
-.    int archive_pass;
-.
-.    {* Used by the back end to hold private data. *}
-.
-.    union
-.      {
+.  {* A chain of BFD structures involved in a link.  *}
+.  struct _bfd *link_next;
+.
+.  {* A field used by _bfd_generic_link_add_archive_symbols.  This will
+.     be used only for archive elements.  *}
+.  int archive_pass;
+.
+.  {* Used by the back end to hold private data.  *}
+.  union
+.    {
 .      struct aout_data_struct *aout_data;
 .      struct artdata *aout_ar_data;
 .      struct _oasys_data *oasys_obj_data;
@@ -167,6 +164,7 @@ CODE_FRAGMENT
 .      struct elf_obj_tdata *elf_obj_data;
 .      struct nlm_obj_tdata *nlm_obj_data;
 .      struct bout_data_struct *bout_data;
+.      struct mmo_data_struct *mmo_data;
 .      struct sun_core_struct *sun_core_data;
 .      struct sco5_core_struct *sco5_core_data;
 .      struct trad_core_struct *trad_core_data;
@@ -180,15 +178,16 @@ CODE_FRAGMENT
 .      struct versados_data_struct *versados_data;
 .      struct netbsd_core_struct *netbsd_core_data;
 .      PTR any;
-.      } tdata;
+.    }
+.  tdata;
 .
-.    {* Used by the application to hold private data*}
-.    PTR usrdata;
+.  {* Used by the application to hold private data.  *}
+.  PTR usrdata;
 .
 .  {* Where all the allocated stuff under this BFD goes.  This is a
 .     struct objalloc *, but we use PTR to avoid requiring the inclusion of
 .     objalloc.h.  *}
-.    PTR memory;
+.  PTR memory;
 .};
 .
 */
@@ -263,7 +262,8 @@ CODE_FRAGMENT
 .  bfd_error_file_truncated,
 .  bfd_error_file_too_big,
 .  bfd_error_invalid_error_code
-.} bfd_error_type;
+.}
+.bfd_error_type;
 .
 */
 
@@ -410,57 +410,24 @@ static const char *_bfd_error_program_name;
 
 /* This is the default routine to handle BFD error messages.  */
 
-#ifdef ANSI_PROTOTYPES
-
 static void _bfd_default_error_handler PARAMS ((const char *s, ...));
 
 static void
-_bfd_default_error_handler (const char *s, ...)
-{
-  va_list p;
-
-  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);
-
-  fprintf (stderr, "\n");
-}
-
-#else /* ! defined (ANSI_PROTOTYPES) */
-
-static void _bfd_default_error_handler ();
-
-static void
-_bfd_default_error_handler (va_alist)
-     va_dcl
+_bfd_default_error_handler VPARAMS ((const char *s, ...))
 {
-  va_list p;
-  const char *s;
-
   if (_bfd_error_program_name != NULL)
     fprintf (stderr, "%s: ", _bfd_error_program_name);
   else
     fprintf (stderr, "BFD: ");
 
-  va_start (p);
-
-  s = va_arg (p, const char *);
+  VA_OPEN (p, s);
+  VA_FIXEDARG (p, const char *, s);
   vfprintf (stderr, s, p);
-
-  va_end (p);
+  VA_CLOSE (p);
 
   fprintf (stderr, "\n");
 }
 
-#endif /* ! defined (ANSI_PROTOTYPES) */
-
 /* This is a function pointer to the routine which should handle BFD
    error messages.  It is called when a BFD routine encounters an
    error for which it wants to print a message.  Going through a
@@ -529,6 +496,54 @@ bfd_get_error_handler ()
 {
   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 (abfd)
+     bfd *abfd;
+{
+  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 ((bfd_size_type) 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
@@ -610,7 +625,7 @@ FUNCTION
 
 SYNOPSIS
        void bfd_set_reloc
-         (bfd *abfd, asection *sec, arelent **rel, unsigned int count)
+         (bfd *abfd, asection *sec, arelent **rel, unsigned int count);
 
 DESCRIPTION
        Set the relocation pointer and count within
@@ -682,7 +697,8 @@ bfd_assert (file, line)
      const char *file;
      int line;
 {
-  (*_bfd_error_handler) (_("bfd assertion fail %s:%d"), file, line);
+  (*_bfd_error_handler) (_("BFD %s assertion fail %s:%d"),
+                        BFD_VERSION_STRING, file, line);
 }
 
 /* A more or less friendly abort message.  In libbfd.h abort is
@@ -700,12 +716,12 @@ _bfd_abort (file, line, fn)
 {
   if (fn != NULL)
     (*_bfd_error_handler)
-      (_("BFD internal error, aborting at %s line %d in %s\n"),
-       file, line, fn);
+      (_("BFD %s internal error, aborting at %s line %d in %s\n"),
+       BFD_VERSION_STRING, file, line, fn);
   else
     (*_bfd_error_handler)
-      (_("BFD internal error, aborting at %s line %d\n"),
-       file, line);
+      (_("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);
 }
@@ -992,7 +1008,8 @@ DESCRIPTION
        in hex if a leading "0x" or "0X" is found, otherwise
        in octal if a leading zero is found, otherwise in decimal.
 
-       Overflow is not detected.
+       If the value would overflow, the maximum <<bfd_vma>> value is
+       returned.
 */
 
 bfd_vma
@@ -1002,48 +1019,64 @@ bfd_scan_vma (string, end, base)
      int base;
 {
   bfd_vma value;
-  int digit;
+  bfd_vma cutoff;
+  unsigned int cutlim;
+  int overflow;
 
   /* Let the host do it if possible.  */
   if (sizeof (bfd_vma) <= sizeof (unsigned long))
     return (bfd_vma) strtoul (string, (char **) end, base);
 
-  /* A negative base makes no sense, and we only need to go as high as hex.  */
-  if ((base < 0) || (base > 16))
-    return (bfd_vma) 0;
-
   if (base == 0)
     {
       if (string[0] == '0')
        {
          if ((string[1] == 'x') || (string[1] == 'X'))
            base = 16;
-         /* XXX should we also allow "0b" or "0B" to set base to 2?  */
          else
            base = 8;
        }
-      else
-       base = 10;
     }
 
-  if ((base == 16) &&
-      (string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
-    string += 2;
-  /* XXX should we also skip over "0b" or "0B" if base is 2?  */
+  if ((base < 2) || (base > 36))
+    base = 10;
+
+  if (base == 16
+      && string[0] == '0'
+      && (string[1] == 'x' || string[1] == 'X')
+      && ISXDIGIT (string[2]))
+    {
+      string += 2;
+    }
+
+  cutoff = (~ (bfd_vma) 0) / (bfd_vma) base;
+  cutlim = (~ (bfd_vma) 0) % (bfd_vma) base;
+  value = 0;
+  overflow = 0;
+  while (1)
+    {
+      unsigned int digit;
 
-/* Speed could be improved with a table like hex_value[] in gas.  */
-#define HEX_VALUE(c) \
-  (ISXDIGIT (c)                                                        \
-   ? (ISDIGIT (c)                                              \
-      ? (c - '0')                                              \
-      : (10 + c - (ISLOWER (c) ? 'a' : 'A')))                  \
-   : 42)
+      digit = *string;
+      if (ISDIGIT (digit))
+       digit = digit - '0';
+      else if (ISALPHA (digit))
+       digit = TOUPPER (digit) - 'A' + 10;
+      else
+       break;
+      if (digit >= (unsigned int) base)
+       break;
+      if (value > cutoff || (value == cutoff && digit > cutlim))
+       overflow = 1;
+      value = value * base + digit;
+      ++string;
+    }
 
-  for (value = 0; (digit = HEX_VALUE (* string)) < base; string ++)
-    value = value * base + digit;
+  if (overflow)
+    value = ~ (bfd_vma) 0;
 
-  if (end)
-    * end = string;
+  if (end != NULL)
+    *end = string;
 
   return value;
 }
This page took 0.028846 seconds and 4 git commands to generate.