* cgen-asm.in (insert_normal): Handle empty fields and 64 bit hosts.
[deliverable/binutils-gdb.git] / bfd / elflink.c
index 123bccd71480dfe40134340071499a5b7a92c584..4f7facf93dbe150ceb5cfbe0fc5bc82eaf9d450e 100644 (file)
@@ -1,5 +1,5 @@
 /* ELF linking support for BFD.
-   Copyright 1993, 1995 Free Software Foundation, Inc.
+   Copyright 1995 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -15,14 +15,14 @@ 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
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #define ARCH_SIZE 0
-#include "libelf.h"
+#include "elf-bfd.h"
 
 boolean
 _bfd_elf_create_got_section (abfd, info)
@@ -38,7 +38,8 @@ _bfd_elf_create_got_section (abfd, info)
   if (bfd_get_section_by_name (abfd, ".got") != NULL)
     return true;
 
-  flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+          | SEC_LINKER_CREATED);
 
   s = bfd_make_section (abfd, ".got");
   if (s == NULL
@@ -72,11 +73,14 @@ _bfd_elf_create_got_section (abfd, info)
       && ! _bfd_elf_link_record_dynamic_symbol (info, h))
     return false;
 
+  elf_hash_table (info)->hgot = h;
+
   /* The first three global offset table entries are reserved.  */
   s->_raw_size += 3 * 4;
 
   return true;
 }
+\f
 
 /* Create dynamic sections when linking against a dynamic object.  */
 
@@ -92,7 +96,8 @@ _bfd_elf_create_dynamic_sections (abfd, info)
   /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
      .rel[a].bss sections.  */
 
-  flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+          | SEC_LINKER_CREATED);
 
   s = bfd_make_section (abfd, ".plt");
   if (s == NULL
@@ -163,6 +168,7 @@ _bfd_elf_create_dynamic_sections (abfd, info)
 
   return true;
 }
+\f
 
 /* Record a new dynamic symbol.  We record the dynamic symbols as we
    read the input files, since we need to have a list of all of them
@@ -202,3 +208,172 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
 
   return true;
 }
+\f
+/* Create a special linker section, or return a pointer to a linker section already created  */
+
+elf_linker_section_t *
+_bfd_elf_create_linker_section (abfd, info, which, defaults)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     enum elf_linker_section_enum which;
+     elf_linker_section_t *defaults;
+{
+  bfd *dynobj = elf_hash_table (info)->dynobj;
+  elf_linker_section_t *lsect;
+
+  /* Record the first bfd section that needs the special section */
+  if (!dynobj)
+    dynobj = elf_hash_table (info)->dynobj = abfd;
+
+  /* If this is the first time, create the section */
+  lsect = elf_linker_section (dynobj, which);
+  if (!lsect)
+    {
+      asection *s;
+
+      lsect = (elf_linker_section_t *)
+       bfd_alloc (dynobj, sizeof (elf_linker_section_t));
+
+      *lsect = *defaults;
+      elf_linker_section (dynobj, which) = lsect;
+      lsect->which = which;
+      lsect->hole_written_p = false;
+
+      /* See if the sections already exist */
+      lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);
+      if (!s || (s->flags & defaults->flags) != defaults->flags)
+       {
+         lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);
+
+         if (s == NULL)
+           return (elf_linker_section_t *)0;
+
+         bfd_set_section_flags (dynobj, s, defaults->flags);
+         bfd_set_section_alignment (dynobj, s, lsect->alignment);
+       }
+      else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment)
+       bfd_set_section_alignment (dynobj, s, lsect->alignment);
+
+      s->_raw_size = align_power (s->_raw_size, lsect->alignment);
+
+      /* Is there a hole we have to provide?  If so check whether the segment is
+        too big already */
+      if (lsect->hole_size)
+       {
+         lsect->hole_offset = s->_raw_size;
+         s->_raw_size += lsect->hole_size;
+         if (lsect->hole_offset > lsect->max_hole_offset)
+           {
+             (*_bfd_error_handler) ("%s: Section %s is already to large to put hole of %ld bytes in",
+                                    bfd_get_filename (abfd),
+                                    lsect->name,
+                                    (long)lsect->hole_size);
+
+             bfd_set_error (bfd_error_bad_value);
+             return (elf_linker_section_t *)0;
+           }
+       }
+
+#ifdef DEBUG
+      fprintf (stderr, "Creating section %s, current size = %ld\n",
+              lsect->name, (long)s->_raw_size);
+#endif
+
+      if (lsect->sym_name)
+       {
+         struct elf_link_hash_entry *h = NULL;
+#ifdef DEBUG
+         fprintf (stderr, "Adding %s to section %s\n",
+                  lsect->sym_name,
+                  lsect->name);
+#endif
+         h = (struct elf_link_hash_entry *)
+           bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false);
+
+         if ((h == NULL || h->root.type == bfd_link_hash_undefined)
+             && !(_bfd_generic_link_add_one_symbol (info,
+                                                    abfd,
+                                                    lsect->sym_name,
+                                                    BSF_GLOBAL,
+                                                    s,
+                                                    ((lsect->hole_size)
+                                                     ? s->_raw_size - lsect->hole_size + lsect->sym_offset
+                                                     : lsect->sym_offset),
+                                                    (const char *) NULL,
+                                                    false,
+                                                    get_elf_backend_data (abfd)->collect,
+                                                    (struct bfd_link_hash_entry **) &h)))
+           return (elf_linker_section_t *)0;
+
+         if ((defaults->which != LINKER_SECTION_SDATA)
+             && (defaults->which != LINKER_SECTION_SDATA2))
+           h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;
+
+         h->type = STT_OBJECT;
+         lsect->sym_hash = h;
+
+         if (info->shared
+             && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+           return (elf_linker_section_t *)0;
+       }
+    }
+
+  /* Find the related sections if they have been created */
+  if (lsect->bss_name && !lsect->bss_section)
+    lsect->bss_section = bfd_get_section_by_name (dynobj, lsect->bss_name);
+
+  if (lsect->rel_name && !lsect->rel_section)
+    lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
+
+  return lsect;
+}
+
+\f
+/* Find a linker generated pointer with a given addend and type.  */
+
+elf_linker_section_pointers_t *
+_bfd_elf_find_pointer_linker_section (linker_pointers, addend, which)
+     elf_linker_section_pointers_t *linker_pointers;
+     bfd_signed_vma addend;
+     elf_linker_section_enum_t which;
+{
+  for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
+    {
+      if (which == linker_pointers->which && addend == linker_pointers->addend)
+       return linker_pointers;
+    }
+
+  return (elf_linker_section_pointers_t *)0;
+}
+
+\f
+/* Make the .rela section corresponding to the generated linker section.  */
+
+boolean
+_bfd_elf_make_linker_section_rela (dynobj, lsect, alignment)
+     bfd *dynobj;
+     elf_linker_section_t *lsect;
+     int alignment;
+{
+  if (lsect->rel_section)
+    return true;
+
+  lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
+  if (lsect->rel_section == NULL)
+    {
+      lsect->rel_section = bfd_make_section (dynobj, lsect->rel_name);
+      if (lsect->rel_section == NULL
+         || ! bfd_set_section_flags (dynobj,
+                                     lsect->rel_section,
+                                     (SEC_ALLOC
+                                      | SEC_LOAD
+                                      | SEC_HAS_CONTENTS
+                                      | SEC_IN_MEMORY
+                                      | SEC_LINKER_CREATED
+                                      | SEC_READONLY))
+         || ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment))
+       return false;
+    }
+
+  return true;
+}
This page took 0.03119 seconds and 4 git commands to generate.