* som.c (setup_sections): Don't lose for a space which has
[deliverable/binutils-gdb.git] / bfd / i386linux.c
index 5390b425af7f221f9846088a4c30c3a275579591..094c2c843b7c1bd54277fc1bbd02ece757917dbd 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for linux flavored i386 a.out binaries.
 /* BFD back-end for linux flavored i386 a.out binaries.
-   Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -15,14 +15,13 @@ 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
 
 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
-#define        PAGE_SIZE       4096
+#define        TARGET_PAGE_SIZE        4096
 #define ZMAGIC_DISK_BLOCK_SIZE 1024
 #define        SEGMENT_SIZE    4096
 #define TEXT_START_ADDR        0x0
 #define N_SHARED_LIB(x) 0
 #define ZMAGIC_DISK_BLOCK_SIZE 1024
 #define        SEGMENT_SIZE    4096
 #define TEXT_START_ADDR        0x0
 #define N_SHARED_LIB(x) 0
-#define ARCH 32
 #define BYTES_IN_WORD 4
 
 #include "bfd.h"
 #define BYTES_IN_WORD 4
 
 #include "bfd.h"
@@ -35,9 +34,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #define DEFAULT_ARCH bfd_arch_i386
 #define MY(OP) CAT(i386linux_,OP)
 
 #define DEFAULT_ARCH bfd_arch_i386
 #define MY(OP) CAT(i386linux_,OP)
-#define MY_text_includes_header 1
 #define TARGETNAME "a.out-i386-linux"
 
 #define TARGETNAME "a.out-i386-linux"
 
+extern const bfd_target MY(vec);
+
 /* We always generate QMAGIC files in preference to ZMAGIC files.  It
    would be possible to make this a linker option, if that ever
    becomes important.  */
 /* We always generate QMAGIC files in preference to ZMAGIC files.  It
    would be possible to make this a linker option, if that ever
    becomes important.  */
@@ -96,6 +96,12 @@ i386linux_write_object_contents (abfd)
 #define IS_PLT_SYM(name) \
   (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
 
 #define IS_PLT_SYM(name) \
   (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
 
+/* This string is used to generate specialized error messages.  */
+
+#ifndef NEEDS_SHRLIB
+#define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
+#endif
+
 /* This special symbol is a set vector that contains a list of
    pointers to fixup tables.  It will be present in any dynamicly
    linked file.  The linker generated fixup table should also be added
 /* This special symbol is a set vector that contains a list of
    pointers to fixup tables.  It will be present in any dynamicly
    linked file.  The linker generated fixup table should also be added
@@ -213,12 +219,9 @@ linux_link_hash_table_create (abfd)
   struct linux_link_hash_table *ret;
 
   ret = ((struct linux_link_hash_table *)
   struct linux_link_hash_table *ret;
 
   ret = ((struct linux_link_hash_table *)
-        malloc (sizeof (struct linux_link_hash_table)));
+        bfd_alloc (abfd, sizeof (struct linux_link_hash_table)));
   if (ret == (struct linux_link_hash_table *) NULL)
   if (ret == (struct linux_link_hash_table *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return (struct bfd_link_hash_table *) NULL;
-    }
+    return (struct bfd_link_hash_table *) NULL;
   if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
                                         linux_link_hash_newfunc))
     {
   if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
                                         linux_link_hash_newfunc))
     {
@@ -297,9 +300,9 @@ linux_link_create_dynamic_sections (abfd, info)
   /* Note that we set the SEC_IN_MEMORY flag.  */
   flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
 
   /* Note that we set the SEC_IN_MEMORY flag.  */
   flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
 
-  /* We choose to use the name ".dynamic" for the fixup table.  Why
-     not? */
-  s = bfd_make_section (abfd, ".dynamic");
+  /* We choose to use the name ".linux-dynamic" for the fixup table.
+     Why not? */
+  s = bfd_make_section (abfd, ".linux-dynamic");
   if (s == NULL
       || ! bfd_set_section_flags (abfd, s, flags)
       || ! bfd_set_section_alignment (abfd, s, 2))
   if (s == NULL
       || ! bfd_set_section_flags (abfd, s, flags)
       || ! bfd_set_section_alignment (abfd, s, 2))
@@ -343,7 +346,9 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string,
 
   if (! info->relocateable
       && linux_hash_table (info)->dynobj == NULL
 
   if (! info->relocateable
       && linux_hash_table (info)->dynobj == NULL
-      && strcmp (name, SHARABLE_CONFLICTS) == 0)
+      && strcmp (name, SHARABLE_CONFLICTS) == 0
+      && (flags & BSF_CONSTRUCTOR) != 0
+      && abfd->xvec == info->hash->creator)
     {
       if (! linux_link_create_dynamic_sections (abfd, info))
        return false;
     {
       if (! linux_link_create_dynamic_sections (abfd, info))
        return false;
@@ -351,20 +356,27 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string,
       insert = true;
     }
 
       insert = true;
     }
 
-  if (section == &bfd_abs_section
-      && (IS_GOT_SYM (name) || IS_PLT_SYM (name)))
+  if (bfd_is_abs_section (section)
+      && abfd->xvec == info->hash->creator)
     {
       h = linux_link_hash_lookup (linux_hash_table (info), name, false,
                                  false, false);
       if (h != NULL
     {
       h = linux_link_hash_lookup (linux_hash_table (info), name, false,
                                  false, false);
       if (h != NULL
-         && h->root.root.type == bfd_link_hash_defined)
+         && (h->root.root.type == bfd_link_hash_defined
+             || h->root.root.type == bfd_link_hash_defweak))
        {
        {
-         if (new_fixup (info, h, value, ! IS_PLT_SYM(name)) == NULL)
+         struct fixup *f;
+
+         if (hashp != NULL)
+           *hashp = (struct bfd_link_hash_entry *) h;
+
+         f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
+         if (f == NULL)
            return false;
            return false;
+         f->jump = IS_PLT_SYM (name);
+
          return true;
        }
          return true;
        }
-      if (hashp != NULL)
-       *hashp = (struct bfd_link_hash_entry *) h;
     }
 
   /* Do the usual procedure for adding a symbol.  */
     }
 
   /* Do the usual procedure for adding a symbol.  */
@@ -382,7 +394,7 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string,
       /* Here we do our special thing to add the pointer to the
         dynamic section in the SHARABLE_CONFLICTS set vector.  */
       s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
       /* Here we do our special thing to add the pointer to the
         dynamic section in the SHARABLE_CONFLICTS set vector.  */
       s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
-                                  ".dynamic");
+                                  ".linux-dynamic");
       BFD_ASSERT (s != NULL);
 
       if (! (_bfd_generic_link_add_one_symbol
       BFD_ASSERT (s != NULL);
 
       if (! (_bfd_generic_link_add_one_symbol
@@ -413,6 +425,37 @@ linux_tally_symbols (h, data)
   struct fixup *f, *f1;
   int is_plt;
   struct linux_link_hash_entry *h1, *h2;
   struct fixup *f, *f1;
   int is_plt;
   struct linux_link_hash_entry *h1, *h2;
+  boolean exists;
+
+  if (h->root.root.type == bfd_link_hash_undefined
+      && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
+                 sizeof NEEDS_SHRLIB - 1) == 0)
+    {
+      const char *name;
+      char *p;
+      char *alloc = NULL;
+
+      name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
+      p = strrchr (name, '_');
+      if (p != NULL)
+       alloc = (char *) malloc (strlen (name) + 1);
+
+      if (p == NULL || alloc == NULL)
+       (*_bfd_error_handler) ("Output file requires shared library `%s'\n",
+                              name);
+      else
+       {
+         strcpy (alloc, name);
+         p = strrchr (alloc, '_');
+         *p++ = '\0';
+         (*_bfd_error_handler)
+           ("Output file requires shared library `%s.so.%s'\n",
+            alloc, p);
+         free (alloc);
+       }
+
+      abort ();
+    }
 
   /* If this symbol is not a PLT/GOT, we do not even need to look at it */
   is_plt = IS_PLT_SYM (h->root.root.root.string);
 
   /* If this symbol is not a PLT/GOT, we do not even need to look at it */
   is_plt = IS_PLT_SYM (h->root.root.root.string);
@@ -439,49 +482,63 @@ linux_tally_symbols (h, data)
         fixup anyway, since there are cases where these symbols come
         from different shared libraries */
       if (h1 != NULL
         fixup anyway, since there are cases where these symbols come
         from different shared libraries */
       if (h1 != NULL
-         && ((h1->root.root.type == bfd_link_hash_defined
-              && h1->root.root.u.def.section != &bfd_abs_section)
+         && (((h1->root.root.type == bfd_link_hash_defined
+               || h1->root.root.type == bfd_link_hash_defweak)
+              && ! bfd_is_abs_section (h1->root.root.u.def.section))
              || h2->root.root.type == bfd_link_hash_indirect))
        {
              || h2->root.root.type == bfd_link_hash_indirect))
        {
-         f = new_fixup (info, h1, h->root.root.u.def.value, 0);
-         if (f == NULL)
-           {
-             /* FIXME: No way to return error.  */
-             abort ();
-           }
-         f->jump = is_plt;
-
          /* See if there is a "builtin" fixup already present
             involving this symbol.  If so, convert it to a regular
             fixup.  In the end, this relaxes some of the requirements
             about the order of performing fixups.  */
          /* See if there is a "builtin" fixup already present
             involving this symbol.  If so, convert it to a regular
             fixup.  In the end, this relaxes some of the requirements
             about the order of performing fixups.  */
+         exists = false;
          for (f1 = linux_hash_table (info)->fixup_list;
               f1 != NULL;
               f1 = f1->next)
            {
          for (f1 = linux_hash_table (info)->fixup_list;
               f1 != NULL;
               f1 = f1->next)
            {
-             if (f1 == f)
-               continue;
-             if (f1->h != h)
+             if ((f1->h != h && f1->h != h1)
+                 || (! f1->builtin && ! f1->jump))
                continue;
                continue;
+             if (f1->h == h1)
+               exists = true;
+             if (! exists
+                 && bfd_is_abs_section (h->root.root.u.def.section))
+               {
+                 f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
+                 f->jump = is_plt;
+               }
              f1->h = h1;
              f1->jump = is_plt;
              f1->builtin = 0;
              f1->h = h1;
              f1->jump = is_plt;
              f1->builtin = 0;
+             exists = true;
+           }
+         if (! exists
+             && bfd_is_abs_section (h->root.root.u.def.section))
+           {
+             f = new_fixup (info, h1, h->root.root.u.def.value, 0);
+             if (f == NULL)
+               {
+                 /* FIXME: No way to return error.  */
+                 abort ();
+               }
+             f->jump = is_plt;
            }
        }
 
       /* Quick and dirty way of stripping these symbols from the
         symtab. */
            }
        }
 
       /* Quick and dirty way of stripping these symbols from the
         symtab. */
-      h->root.written = true;
+      if (bfd_is_abs_section (h->root.root.u.def.section))
+       h->root.written = true;
     }
 
   return true;
 }
 
     }
 
   return true;
 }
 
-/* This is called to set the size of the .dynamic section is.  It is
-   called by the Linux linker emulation before_allocation routine.  We
-   have finished reading all of the input files, and now we just scan
-   the hash tables to find out how many additional fixups are
-   required.  */
+/* This is called to set the size of the .linux-dynamic section is.
+   It is called by the Linux linker emulation before_allocation
+   routine.  We have finished reading all of the input files, and now
+   we just scan the hash tables to find out how many additional fixups
+   are required.  */
 
 boolean
 bfd_linux_size_dynamic_sections (output_bfd, info)
 
 boolean
 bfd_linux_size_dynamic_sections (output_bfd, info)
@@ -491,6 +548,9 @@ bfd_linux_size_dynamic_sections (output_bfd, info)
   struct fixup *f;
   asection *s;
 
   struct fixup *f;
   asection *s;
 
+  if (output_bfd->xvec != &MY(vec))
+    return true;
+
   /* First find the fixups... */
   linux_link_hash_traverse (linux_hash_table (info),
                            linux_tally_symbols,
   /* First find the fixups... */
   linux_link_hash_traverse (linux_hash_table (info),
                            linux_tally_symbols,
@@ -517,17 +577,15 @@ bfd_linux_size_dynamic_sections (output_bfd, info)
     }
 
   /* Allocate memory for our fixup table.  We will fill it in later.  */
     }
 
   /* Allocate memory for our fixup table.  We will fill it in later.  */
-  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, ".dynamic");
+  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+                              ".linux-dynamic");
   if (s != NULL)
     {
       s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8;
       s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
       if (s->contents == NULL)
   if (s != NULL)
     {
       s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8;
       s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
       if (s->contents == NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
-      memset (s->contents, 0, s->_raw_size);
+       return false;
+      memset (s->contents, 0, (size_t) s->_raw_size);
     }
 
   return true;
     }
 
   return true;
@@ -548,12 +606,13 @@ linux_finish_dynamic_link (output_bfd, info)
   struct fixup *f;
   unsigned int new_addr;
   int section_offset;
   struct fixup *f;
   unsigned int new_addr;
   int section_offset;
-  int fixups_written;
+  unsigned int fixups_written;
 
   if (linux_hash_table (info)->dynobj == NULL)
     return true;
 
 
   if (linux_hash_table (info)->dynobj == NULL)
     return true;
 
-  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, ".dynamic");
+  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+                              ".linux-dynamic");
   BFD_ASSERT (s != NULL);
   os = s->output_section;
   fixups_written = 0;
   BFD_ASSERT (s != NULL);
   os = s->output_section;
   fixups_written = 0;
@@ -574,12 +633,12 @@ linux_finish_dynamic_link (output_bfd, info)
       if (f->builtin)
        continue;
 
       if (f->builtin)
        continue;
 
-      if (f->h->root.root.type != bfd_link_hash_defined)
+      if (f->h->root.root.type != bfd_link_hash_defined
+         && f->h->root.root.type != bfd_link_hash_defweak)
        {
        {
-         /* FIXME!  */
-         fprintf (stderr,
-                  "Symbol %s not defined for fixups\n",
-                  f->h->root.root.root.string);
+         (*_bfd_error_handler)
+           ("Symbol %s not defined for fixups\n",
+            f->h->root.root.root.string);
          continue;
        }
 
          continue;
        }
 
@@ -624,12 +683,12 @@ linux_finish_dynamic_link (output_bfd, info)
          if (! f->builtin)
            continue;
 
          if (! f->builtin)
            continue;
 
-         if (f->h->root.root.type != bfd_link_hash_defined)
+         if (f->h->root.root.type != bfd_link_hash_defined
+             && f->h->root.root.type != bfd_link_hash_defweak)
            {
            {
-             /* FIXME!  */
-             fprintf (stderr,
-                      "Symbol %s not defined for fixups\n",
-                      f->h->root.root.root.string);
+             (*_bfd_error_handler)
+               ("Symbol %s not defined for fixups\n",
+                f->h->root.root.root.string);
              continue;
            }
 
              continue;
            }
 
@@ -652,8 +711,7 @@ linux_finish_dynamic_link (output_bfd, info)
 
   if (linux_hash_table (info)->fixup_count != fixups_written)
     {
 
   if (linux_hash_table (info)->fixup_count != fixups_written)
     {
-      /* FIXME!  */
-      fprintf (stderr, "Warning: fixup count mismatch\n");
+      (*_bfd_error_handler) ("Warning: fixup count mismatch\n");
       while (linux_hash_table (info)->fixup_count > fixups_written)
        {
          bfd_put_32 (output_bfd, 0, fixup_table);
       while (linux_hash_table (info)->fixup_count > fixups_written)
        {
          bfd_put_32 (output_bfd, 0, fixup_table);
@@ -668,7 +726,9 @@ linux_finish_dynamic_link (output_bfd, info)
                              "__BUILTIN_FIXUPS__",
                              false, false, false);
 
                              "__BUILTIN_FIXUPS__",
                              false, false, false);
 
-  if (h != NULL && h->root.root.type == bfd_link_hash_defined)
+  if (h != NULL
+      && (h->root.root.type == bfd_link_hash_defined
+         || h->root.root.type == bfd_link_hash_defweak))
     {
       is = h->root.root.u.def.section;
       section_offset = is->output_section->vma + is->output_offset;
     {
       is = h->root.root.u.def.section;
       section_offset = is->output_section->vma + is->output_offset;
@@ -697,4 +757,6 @@ linux_finish_dynamic_link (output_bfd, info)
 #define MY_add_one_symbol linux_add_one_symbol
 #define MY_finish_dynamic_link linux_finish_dynamic_link
 
 #define MY_add_one_symbol linux_add_one_symbol
 #define MY_finish_dynamic_link linux_finish_dynamic_link
 
+#define MY_zmagic_contiguous 1
+
 #include "aout-target.h"
 #include "aout-target.h"
This page took 0.029773 seconds and 4 git commands to generate.