Support for more than 64k ELF sections.
[deliverable/binutils-gdb.git] / bfd / bfd.c
index c663d0ecd7232f51063b7e08e86cf7b351ab34dd..f0c4037486987b5c25f5a96c98632247d3d9d462 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -70,7 +70,7 @@ CODE_FRAGMENT
 .    {* When a file is closed by the caching routines, BFD retains
 .       state information on the file here: *}
 .
-.    file_ptr where;
+.    ufile_ptr where;
 .
 .    {* and here: (``once'' means at least once) *}
 .
@@ -108,14 +108,20 @@ CODE_FRAGMENT
 .       anything. I believe that this can become always an add of
 .       origin, with origin set to 0 for non archive files.   *}
 .
-.    file_ptr origin;
+.    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;
+.    {* 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;
@@ -167,6 +173,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;
@@ -203,6 +210,7 @@ CODE_FRAGMENT
 #endif
 
 #include "libiberty.h"
+#include "safe-ctype.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "coff/internal.h"
@@ -211,8 +219,6 @@ CODE_FRAGMENT
 #include "libecoff.h"
 #undef obj_symbols
 #include "elf-bfd.h"
-
-#include <ctype.h>
 \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
@@ -248,6 +254,7 @@ CODE_FRAGMENT
 .  bfd_error_system_call,
 .  bfd_error_invalid_target,
 .  bfd_error_wrong_format,
+.  bfd_error_wrong_object_format,
 .  bfd_error_invalid_operation,
 .  bfd_error_no_memory,
 .  bfd_error_no_symbols,
@@ -275,6 +282,7 @@ const char *const bfd_errmsgs[] =
   N_("System call error"),
   N_("Invalid bfd target"),
   N_("File in wrong format"),
+  N_("Archive object file in wrong format"),
   N_("Invalid operation"),
   N_("Memory exhausted"),
   N_("No symbols"),
@@ -409,57 +417,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
@@ -528,6 +503,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
@@ -681,7 +704,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
@@ -699,12 +723,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 %sinternal error, aborting at %s line %d\n"),
+       BFD_VERSION_STRING, file, line);
   (*_bfd_error_handler) (_("Please report this bug.\n"));
   xexit (EXIT_FAILURE);
 }
@@ -889,7 +913,7 @@ FUNCTION
        bfd_get_gp_size
 
 SYNOPSIS
-       int bfd_get_gp_size(bfd *abfd);
+       unsigned int bfd_get_gp_size(bfd *abfd);
 
 DESCRIPTION
        Return the maximum size of objects to be optimized using the GP
@@ -897,7 +921,7 @@ DESCRIPTION
        argument to the compiler, assembler or linker.
 */
 
-int
+unsigned int
 bfd_get_gp_size (abfd)
      bfd *abfd;
 {
@@ -916,7 +940,7 @@ FUNCTION
        bfd_set_gp_size
 
 SYNOPSIS
-       void bfd_set_gp_size(bfd *abfd, int i);
+       void bfd_set_gp_size(bfd *abfd, unsigned int i);
 
 DESCRIPTION
        Set the maximum size of objects to be optimized using the GP
@@ -927,7 +951,7 @@ DESCRIPTION
 void
 bfd_set_gp_size (abfd, i)
      bfd *abfd;
-     int i;
+     unsigned int i;
 {
   /* Don't try to set GP size on an archive or core file!  */
   if (abfd->format != bfd_object)
@@ -1032,10 +1056,10 @@ bfd_scan_vma (string, end, base)
 
 /* Speed could be improved with a table like hex_value[] in gas.  */
 #define HEX_VALUE(c) \
-  (isxdigit ((unsigned char) c)                                        \
-   ? (isdigit ((unsigned char) c)                              \
+  (ISXDIGIT (c)                                                        \
+   ? (ISDIGIT (c)                                              \
       ? (c - '0')                                              \
-      : (10 + c - (islower ((unsigned char) c) ? 'a' : 'A')))  \
+      : (10 + c - (ISLOWER (c) ? 'a' : 'A')))                  \
    : 42)
 
   for (value = 0; (digit = HEX_VALUE (* string)) < base; string ++)
@@ -1233,14 +1257,14 @@ bfd_record_phdr (abfd, type, flags_valid, flags, at_valid, at,
      asection **secs;
 {
   struct elf_segment_map *m, **pm;
+  bfd_size_type amt;
 
   if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
     return true;
 
-  m = ((struct elf_segment_map *)
-       bfd_alloc (abfd,
-                 (sizeof (struct elf_segment_map)
-                  + ((size_t) count - 1) * sizeof (asection *))));
+  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;
 
@@ -1270,8 +1294,9 @@ bfd_sprintf_vma (abfd, buf, value)
      bfd_vma value;
 {
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-    return bfd_elf_sprintf_vma (abfd, buf, value);
-  sprintf_vma (buf, value);
+    get_elf_backend_data (abfd)->elf_backend_sprintf_vma (abfd, buf, value);
+  else
+    sprintf_vma (buf, value);
 }
 
 void
@@ -1281,6 +1306,62 @@ bfd_fprintf_vma (abfd, stream, value)
      bfd_vma value;
 {
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-    return bfd_elf_fprintf_vma (abfd, stream, value);
-  fprintf_vma ((FILE *) stream, value);
+    get_elf_backend_data (abfd)->elf_backend_fprintf_vma (abfd, stream, value);
+  else
+    fprintf_vma ((FILE *) stream, value);
+}
+
+/*
+FUNCTION
+       bfd_alt_mach_code
+
+SYNOPSIS
+       boolean bfd_alt_mach_code(bfd *abfd, int index);
+
+DESCRIPTION
+
+       When more than one machine code number is available for the
+       same machine type, this function can be used to switch between
+       the preferred one (index == 0) and any others.  Currently,
+       only ELF supports this feature, with up to two alternate
+       machine codes.
+*/
+
+boolean
+bfd_alt_mach_code (abfd, index)
+     bfd *abfd;
+     int index;
+{
+  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+    {
+      int code;
+
+      switch (index)
+       {
+       case 0:
+         code = get_elf_backend_data (abfd)->elf_machine_code;
+         break;
+
+       case 1:
+         code = get_elf_backend_data (abfd)->elf_machine_alt1;
+         if (code == 0)
+           return false;
+         break;
+
+       case 2:
+         code = get_elf_backend_data (abfd)->elf_machine_alt2;
+         if (code == 0)
+           return false;
+         break;
+
+       default:
+         return false;
+       }
+
+      elf_elfheader (abfd)->e_machine = code;
+
+      return true;
+    }
+
+  return false;
 }
This page took 0.027964 seconds and 4 git commands to generate.