Fixed exported names, removed a bad define
[deliverable/binutils-gdb.git] / bfd / elflink.h
index cdf3afb4b00bc3972ef781a82bceb9fd707a55fa..c656ac12303585efa36ab13fbfdef92b18432abc 100644 (file)
@@ -1,5 +1,5 @@
 /* ELF linker support.
-   Copyright 1995 Free Software Foundation, Inc.
+   Copyright 1995, 1996 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -58,6 +58,7 @@ elf_bfd_link_add_symbols (abfd, info)
       return false;
     }
 }
+\f
 
 /* Add symbols from an ELF archive file to the linker hash table.  We
    don't use _bfd_generic_link_add_archive_symbols because of a
@@ -110,13 +111,10 @@ elf_link_add_archive_symbols (abfd, info)
   c = bfd_ardata (abfd)->symdef_count;
   if (c == 0)
     return true;
-  defined = (boolean *) malloc (c * sizeof (boolean));
-  included = (boolean *) malloc (c * sizeof (boolean));
+  defined = (boolean *) bfd_malloc (c * sizeof (boolean));
+  included = (boolean *) bfd_malloc (c * sizeof (boolean));
   if (defined == (boolean *) NULL || included == (boolean *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto error_return;
-    }
+    goto error_return;
   memset (defined, 0, c * sizeof (boolean));
   memset (included, 0, c * sizeof (boolean));
 
@@ -328,12 +326,10 @@ elf_link_add_object_symbols (abfd, info)
       extsymoff = hdr->sh_info;
     }
 
-  buf = (Elf_External_Sym *) malloc (extsymcount * sizeof (Elf_External_Sym));
+  buf = ((Elf_External_Sym *)
+        bfd_malloc (extsymcount * sizeof (Elf_External_Sym)));
   if (buf == NULL && extsymcount != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto error_return;
-    }
+    goto error_return;
 
   /* We store a pointer to the hash table entry for each external
      symbol.  */
@@ -404,12 +400,9 @@ elf_link_add_object_symbols (abfd, info)
          int elfsec;
          unsigned long link;
 
-         dynbuf = (Elf_External_Dyn *) malloc ((size_t) s->_raw_size);
+         dynbuf = (Elf_External_Dyn *) bfd_malloc ((size_t) s->_raw_size);
          if (dynbuf == NULL)
-           {
-             bfd_set_error (bfd_error_no_memory);
-             goto error_return;
-           }
+           goto error_return;
 
          if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf,
                                          (file_ptr) 0, s->_raw_size))
@@ -472,6 +465,7 @@ elf_link_add_object_symbols (abfd, info)
         still implies that the section takes up space in the output
         file.  */
       abfd->sections = NULL;
+      abfd->section_count = 0;
 
       /* If this is the first dynamic object found in the link, create
         the special sections required for dynamic linking.  */
@@ -636,7 +630,7 @@ elf_link_add_object_symbols (abfd, info)
        definition = true;
 
       size_change_ok = false;
-      type_change_ok = false;
+      type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
       if (info->hash->creator->flavour == bfd_target_elf_flavour)
        {
          /* We need to look up the symbol now in order to get some of
@@ -655,15 +649,16 @@ elf_link_add_object_symbols (abfd, info)
 
          /* It's OK to change the type if it used to be a weak
              definition.  */
-         type_change_ok = (h->root.type == bfd_link_hash_defweak
-                           || h->root.type == bfd_link_hash_undefweak);
+         if (h->root.type == bfd_link_hash_defweak
+             || h->root.type == bfd_link_hash_undefweak)
+           type_change_ok = true;
 
          /* It's OK to change the size if it used to be a weak
             definition, or if it used to be undefined, or if we will
-            be overriding an old definition.
-            */
-         size_change_ok = (type_change_ok
-                           || h->root.type == bfd_link_hash_undefined);
+            be overriding an old definition.  */
+         if (type_change_ok
+             || h->root.type == bfd_link_hash_undefined)
+           size_change_ok = true;
 
          /* If we are looking at a dynamic object, and this is a
             definition, we need to see if it has already been defined
@@ -873,8 +868,7 @@ elf_link_add_object_symbols (abfd, info)
 
          h = *hpp;
          if (h != NULL && h != hlook
-             && (h->root.type == bfd_link_hash_defined
-                 || h->root.type == bfd_link_hash_defweak)
+             && h->root.type == bfd_link_hash_defined
              && h->root.u.def.section == slook
              && h->root.u.def.value == vlook)
            {
@@ -1090,15 +1084,9 @@ elf_add_dynamic_entry (info, tag, val)
   BFD_ASSERT (s != NULL);
 
   newsize = s->_raw_size + sizeof (Elf_External_Dyn);
-  if (s->contents == NULL)
-    newcontents = (bfd_byte *) malloc (newsize);
-  else
-    newcontents = (bfd_byte *) realloc (s->contents, newsize);
+  newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize);
   if (newcontents == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   dyn.d_tag = tag;
   dyn.d_un.d_val = val;
@@ -1110,6 +1098,7 @@ elf_add_dynamic_entry (info, tag, val)
 
   return true;
 }
+\f
 
 /* Read and swap the relocs for a section.  They may have been cached.
    If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are not NULL,
@@ -1146,22 +1135,16 @@ elf_link_read_relocs (abfd, o, external_relocs, internal_relocs, keep_memory)
       if (keep_memory)
        internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size);
       else
-       internal_relocs = alloc2 = (Elf_Internal_Rela *) malloc (size);
+       internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size);
       if (internal_relocs == NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         goto error_return;
-       }
+       goto error_return;
     }
 
   if (external_relocs == NULL)
     {
-      alloc1 = (PTR) malloc ((size_t) rel_hdr->sh_size);
+      alloc1 = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size);
       if (alloc1 == NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         goto error_return;
-       }
+       goto error_return;
       external_relocs = alloc1;
     }
 
@@ -1226,6 +1209,7 @@ elf_link_read_relocs (abfd, o, external_relocs, internal_relocs, keep_memory)
     free (alloc2);
   return NULL;
 }
+\f
 
 /* Record an assignment to a symbol made by a linker script.  We need
    this in case some dynamic object refers to this symbol.  */
@@ -1280,6 +1264,7 @@ NAME(bfd_elf,record_link_assignment) (output_bfd, info, name, provide)
 
   return true;
 }
+\f
 
 /* Array used to determine the number of hash table buckets to use
    based on the number of symbols there are.  If there are fewer than
@@ -1482,6 +1467,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
 
   return true;
 }
+\f
 
 /* This routine is used to export all defined symbols into the dynamic
    symbol table.  It is called via elf_link_hash_traverse.  */
@@ -1506,6 +1492,7 @@ elf_export_symbol (h, data)
 
   return true;
 }
+\f
 
 /* Make the backend pick a good value for a dynamic symbol.  This is
    called via elf_link_hash_traverse, and also calls itself
@@ -1847,13 +1834,10 @@ elf_bfd_final_link (abfd, info)
            goto error_return;
 
          p = ((struct elf_link_hash_entry **)
-              malloc (o->reloc_count
-                      * sizeof (struct elf_link_hash_entry *)));
+              bfd_malloc (o->reloc_count
+                          * sizeof (struct elf_link_hash_entry *)));
          if (p == NULL && o->reloc_count != 0)
-           {
-             bfd_set_error (bfd_error_no_memory);
-             goto error_return;
-           }
+           goto error_return;
          elf_section_data (o)->rel_hashes = p;
          pend = p + o->reloc_count;
          for (; p < pend; p++)
@@ -1898,12 +1882,9 @@ elf_bfd_final_link (abfd, info)
   else
     finfo.symbuf_size = max_sym_count;
   finfo.symbuf = ((Elf_External_Sym *)
-                 malloc (finfo.symbuf_size * sizeof (Elf_External_Sym)));
+                 bfd_malloc (finfo.symbuf_size * sizeof (Elf_External_Sym)));
   if (finfo.symbuf == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto error_return;
-    }
+    goto error_return;
 
   /* Start writing out the symbol table.  The first symbol is always a
      dummy symbol.  */
@@ -1954,17 +1935,20 @@ elf_bfd_final_link (abfd, info)
 
   /* Allocate some memory to hold information read in from the input
      files.  */
-  finfo.contents = (bfd_byte *) malloc (max_contents_size);
-  finfo.external_relocs = (PTR) malloc (max_external_reloc_size);
+  finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+  finfo.external_relocs = (PTR) bfd_malloc (max_external_reloc_size);
   finfo.internal_relocs = ((Elf_Internal_Rela *)
-                          malloc (max_internal_reloc_count
-                                  * sizeof (Elf_Internal_Rela)));
+                          bfd_malloc (max_internal_reloc_count
+                                      * sizeof (Elf_Internal_Rela)));
   finfo.external_syms = ((Elf_External_Sym *)
-                        malloc (max_sym_count * sizeof (Elf_External_Sym)));
+                        bfd_malloc (max_sym_count
+                                    * sizeof (Elf_External_Sym)));
   finfo.internal_syms = ((Elf_Internal_Sym *)
-                        malloc (max_sym_count * sizeof (Elf_Internal_Sym)));
-  finfo.indices = (long *) malloc (max_sym_count * sizeof (long));
-  finfo.sections = (asection **) malloc (max_sym_count * sizeof (asection *));
+                        bfd_malloc (max_sym_count
+                                    * sizeof (Elf_Internal_Sym)));
+  finfo.indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
+  finfo.sections = ((asection **)
+                   bfd_malloc (max_sym_count * sizeof (asection *)));
   if ((finfo.contents == NULL && max_contents_size != 0)
       || (finfo.external_relocs == NULL && max_external_reloc_size != 0)
       || (finfo.internal_relocs == NULL && max_internal_reloc_count != 0)
@@ -1972,10 +1956,7 @@ elf_bfd_final_link (abfd, info)
       || (finfo.internal_syms == NULL && max_sym_count != 0)
       || (finfo.indices == NULL && max_sym_count != 0)
       || (finfo.sections == NULL && max_sym_count != 0))
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto error_return;
-    }
+    goto error_return;
 
   /* Since ELF permits relocations to be against local symbols, we
      must have the local symbols available when we do the relocations.
@@ -2534,6 +2515,12 @@ elf_link_output_extsym (h, data)
 
     case bfd_link_hash_indirect:
     case bfd_link_hash_warning:
+      /* We can't represent these symbols in ELF.  A warning symbol
+         may have come from a .gnu.warning.SYMBOL section anyhow.  We
+         just put the target symbol in the hash table.  If the target
+         symbol does not really exist, don't do anything.  */
+      if (h->root.u.i.link->type == bfd_link_hash_new)
+       return true;
       return (elf_link_output_extsym
              ((struct elf_link_hash_entry *) h->root.u.i.link, data));
     }
@@ -3006,6 +2993,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
   reloc_howto_type *howto;
   long indx;
   bfd_vma offset;
+  bfd_vma addend;
   struct elf_link_hash_entry **rel_hash_ptr;
   Elf_Internal_Shdr *rel_hdr;
 
@@ -3016,10 +3004,61 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
       return false;
     }
 
+  addend = link_order->u.reloc.p->addend;
+
+  /* Figure out the symbol index.  */
+  rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
+                 + output_section->reloc_count);
+  if (link_order->type == bfd_section_reloc_link_order)
+    {
+      indx = link_order->u.reloc.p->u.section->target_index;
+      BFD_ASSERT (indx != 0);
+      *rel_hash_ptr = NULL;
+    }
+  else
+    {
+      struct elf_link_hash_entry *h;
+
+      /* Treat a reloc against a defined symbol as though it were
+         actually against the section.  */
+      h = elf_link_hash_lookup (elf_hash_table (info),
+                               link_order->u.reloc.p->u.name,
+                               false, false, true);
+      if (h != NULL
+         && (h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak))
+       {
+         asection *section;
+
+         section = h->root.u.def.section;
+         indx = section->output_section->target_index;
+         *rel_hash_ptr = NULL;
+         /* It seems that we ought to add the symbol value to the
+             addend here, but in practice it has already been added
+             because it was passed to constructor_callback.  */
+         addend += section->output_section->vma + section->output_offset;
+       }
+      else if (h != NULL)
+       {
+         /* Setting the index to -2 tells elf_link_output_extsym that
+            this symbol is used by a reloc.  */
+         h->indx = -2;
+         *rel_hash_ptr = h;
+         indx = 0;
+       }
+      else
+       {
+         if (! ((*info->callbacks->unattached_reloc)
+                (info, link_order->u.reloc.p->u.name, (bfd *) NULL,
+                 (asection *) NULL, (bfd_vma) 0)))
+           return false;
+         indx = 0;
+       }
+    }
+
   /* If this is an inplace reloc, we must write the addend into the
      object file.  */
-  if (howto->partial_inplace
-      && link_order->u.reloc.p->addend != 0)
+  if (howto->partial_inplace && addend != 0)
     {
       bfd_size_type size;
       bfd_reloc_status_type rstat;
@@ -3030,8 +3069,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
       buf = (bfd_byte *) bfd_zmalloc (size);
       if (buf == (bfd_byte *) NULL)
        return false;
-      rstat = _bfd_relocate_contents (howto, output_bfd,
-                                     link_order->u.reloc.p->addend, buf);
+      rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
       switch (rstat)
        {
        case bfd_reloc_ok:
@@ -3046,8 +3084,8 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
                   ? bfd_section_name (output_bfd,
                                       link_order->u.reloc.p->u.section)
                   : link_order->u.reloc.p->u.name),
-                 howto->name, link_order->u.reloc.p->addend,
-                 (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
+                 howto->name, addend, (bfd *) NULL, (asection *) NULL,
+                 (bfd_vma) 0)))
            {
              free (buf);
              return false;
@@ -3061,40 +3099,6 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
        return false;
     }
 
-  /* Figure out the symbol index.  */
-  rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
-                 + output_section->reloc_count);
-  if (link_order->type == bfd_section_reloc_link_order)
-    {
-      indx = link_order->u.reloc.p->u.section->target_index;
-      BFD_ASSERT (indx != 0);
-      *rel_hash_ptr = NULL;
-    }
-  else
-    {
-      struct elf_link_hash_entry *h;
-
-      h = elf_link_hash_lookup (elf_hash_table (info),
-                               link_order->u.reloc.p->u.name,
-                               false, false, true);
-      if (h != NULL)
-       {
-         /* Setting the index to -2 tells elf_link_output_extsym that
-            this symbol is used by a reloc.  */
-         h->indx = -2;
-         *rel_hash_ptr = h;
-         indx = 0;
-       }
-      else
-       {
-         if (! ((*info->callbacks->unattached_reloc)
-                (info, link_order->u.reloc.p->u.name, (bfd *) NULL,
-                 (asection *) NULL, (bfd_vma) 0)))
-           return false;
-         indx = 0;
-       }
-    }
-
   /* The address of a reloc is relative to the section in a
      relocateable file, and is a virtual address in an executable
      file.  */
@@ -3122,7 +3126,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
 
       irela.r_offset = offset;
       irela.r_info = ELF_R_INFO (indx, howto->type);
-      irela.r_addend = link_order->u.reloc.p->addend;
+      irela.r_addend = addend;
       erela = ((Elf_External_Rela *) rel_hdr->contents
               + output_section->reloc_count);
       elf_swap_reloca_out (output_bfd, &irela, erela);
@@ -3133,3 +3137,228 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
   return true;
 }
 
+\f
+/* Allocate a pointer to live in a linker created section.  */
+
+boolean
+elf_create_pointer_linker_section (abfd, info, lsect, h, rel)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     elf_linker_section_t *lsect;
+     struct elf_link_hash_entry *h;
+     const Elf_Internal_Rela *rel;
+{
+  elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL;
+  elf_linker_section_pointers_t *linker_section_ptr;
+  unsigned long r_symndx = ELF_R_SYM (rel->r_info);;
+
+  BFD_ASSERT (lsect != NULL);
+
+  /* Is this a global symbol? */
+  if (h != NULL)
+    {
+      /* Has this symbol already been allocated, if so, our work is done */
+      if (_bfd_elf_find_pointer_linker_section (h->linker_section_pointer,
+                                               rel->r_addend,
+                                               lsect->which))
+       return true;
+
+      ptr_linker_section_ptr = &h->linker_section_pointer;
+      /* Make sure this symbol is output as a dynamic symbol.  */
+      if (h->dynindx == -1)
+       {
+         if (! elf_link_record_dynamic_symbol (info, h))
+           return false;
+       }
+
+      if (lsect->rel_section)
+       lsect->rel_section->_raw_size += sizeof (Elf_External_Rela);
+    }
+
+  else  /* Allocation of a pointer to a local symbol */
+    {
+      elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd);
+
+      /* Allocate a table to hold the local symbols if first time */
+      if (!ptr)
+       {
+         int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info;
+         register unsigned int i;
+
+         ptr = (elf_linker_section_pointers_t **)
+           bfd_alloc (abfd, num_symbols * sizeof (elf_linker_section_pointers_t *));
+
+         if (!ptr)
+           return false;
+
+         elf_local_ptr_offsets (abfd) = ptr;
+         for (i = 0; i < num_symbols; i++)
+           ptr[i] = (elf_linker_section_pointers_t *)0;
+       }
+
+      /* Has this symbol already been allocated, if so, our work is done */
+      if (_bfd_elf_find_pointer_linker_section (ptr[r_symndx],
+                                               rel->r_addend,
+                                               lsect->which))
+       return true;
+
+      ptr_linker_section_ptr = &ptr[r_symndx];
+
+      if (info->shared)
+       {
+         /* If we are generating a shared object, we need to
+            output a R_<xxx>_RELATIVE reloc so that the
+            dynamic linker can adjust this GOT entry.  */
+         BFD_ASSERT (lsect->rel_section != NULL);
+         lsect->rel_section->_raw_size += sizeof (Elf_External_Rela);
+       }
+    }
+
+  /* Allocate space for a pointer in the linker section, and allocate a new pointer record
+     from internal memory.  */
+  BFD_ASSERT (ptr_linker_section_ptr != NULL);
+  linker_section_ptr = (elf_linker_section_pointers_t *)
+    bfd_alloc (abfd, sizeof (elf_linker_section_pointers_t));
+
+  if (!linker_section_ptr)
+    return false;
+
+  linker_section_ptr->next = *ptr_linker_section_ptr;
+  linker_section_ptr->addend = rel->r_addend;
+  linker_section_ptr->which = lsect->which;
+  linker_section_ptr->written_address_p = false;
+  *ptr_linker_section_ptr = linker_section_ptr;
+
+  if (lsect->hole_size && lsect->hole_offset < lsect->max_hole_offset)
+    {
+      linker_section_ptr->offset = lsect->section->_raw_size - lsect->hole_size;
+      lsect->hole_offset += ARCH_SIZE / 8;
+      lsect->sym_offset  += ARCH_SIZE / 8;
+      if (lsect->sym_hash)     /* Bump up symbol value if needed */
+       lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8;
+    }
+  else
+    linker_section_ptr->offset = lsect->section->_raw_size;
+
+  lsect->section->_raw_size += ARCH_SIZE / 8;
+
+#ifdef DEBUG
+  fprintf (stderr, "Create pointer in linker section %s, offset = %ld, section size = %ld\n",
+          lsect->name, (long)linker_section_ptr->offset, (long)lsect->section->_raw_size);
+#endif
+
+  return true;
+}
+
+\f
+#if ARCH_SIZE==64
+#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_64 (BFD, VAL, ADDR)
+#endif
+#if ARCH_SIZE==32
+#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_32 (BFD, VAL, ADDR)
+#endif
+
+/* Fill in the address for a pointer generated in alinker section.  */
+
+bfd_vma
+elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, relocation, rel, relative_reloc)
+     bfd *output_bfd;
+     bfd *input_bfd;
+     struct bfd_link_info *info;
+     elf_linker_section_t *lsect;
+     struct elf_link_hash_entry *h;
+     bfd_vma relocation;
+     const Elf_Internal_Rela *rel;
+     int relative_reloc;
+{
+  elf_linker_section_pointers_t *linker_section_ptr;
+
+  BFD_ASSERT (lsect != NULL);
+
+  if (h != NULL)               /* global symbol */
+    {
+      linker_section_ptr = _bfd_elf_find_pointer_linker_section (h->linker_section_pointer,
+                                                                rel->r_addend,
+                                                                lsect->which);
+
+      BFD_ASSERT (linker_section_ptr != NULL);
+
+      if (! elf_hash_table (info)->dynamic_sections_created
+         || (info->shared
+             && info->symbolic
+             && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+       {
+         /* This is actually a static link, or it is a
+            -Bsymbolic link and the symbol is defined
+            locally.  We must initialize this entry in the
+            global section.
+
+            When doing a dynamic link, we create a .rela.<xxx>
+            relocation entry to initialize the value.  This
+            is done in the finish_dynamic_symbol routine.  */
+         if (!linker_section_ptr->written_address_p)
+           {
+             linker_section_ptr->written_address_p = true;
+             bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend,
+                         lsect->section->contents + linker_section_ptr->offset);
+           }
+       }
+    }
+  else                         /* local symbol */
+    {
+      unsigned long r_symndx = ELF_R_SYM (rel->r_info);
+      BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL);
+      BFD_ASSERT (elf_local_ptr_offsets (input_bfd)[r_symndx] != NULL);
+      linker_section_ptr = _bfd_elf_find_pointer_linker_section (elf_local_ptr_offsets (input_bfd)[r_symndx],
+                                                                rel->r_addend,
+                                                                lsect->which);
+
+      BFD_ASSERT (linker_section_ptr != NULL);
+
+      /* Write out pointer if it hasn't been rewritten out before */
+      if (!linker_section_ptr->written_address_p)
+       {
+         linker_section_ptr->written_address_p = true;
+         bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend,
+                      lsect->section->contents + linker_section_ptr->offset);
+
+         if (info->shared)
+           {
+             asection *srel = lsect->rel_section;
+             Elf_Internal_Rela outrel;
+
+             /* We need to generate a relative reloc for the dynamic linker.  */
+             if (!srel)
+               lsect->rel_section = srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
+                                                                    lsect->rel_name);
+
+             BFD_ASSERT (srel != NULL);
+
+             outrel.r_offset = (lsect->section->output_section->vma
+                                + lsect->section->output_offset
+                                + linker_section_ptr->offset);
+             outrel.r_info = ELF_R_INFO (0, relative_reloc);
+             outrel.r_addend = 0;
+             elf_swap_reloca_out (output_bfd, &outrel,
+                                  (((Elf_External_Rela *)
+                                    lsect->section->contents)
+                                   + lsect->section->reloc_count));
+             ++lsect->section->reloc_count;
+           }
+       }
+    }
+
+  relocation = (lsect->section->output_offset
+               + linker_section_ptr->offset
+               - lsect->hole_offset
+               - lsect->sym_offset);
+
+#ifdef DEBUG
+  fprintf (stderr, "Finish pointer in linker section %s, offset = %ld (0x%lx)\n",
+          lsect->name, (long)relocation, (long)relocation);
+#endif
+
+  /* Subtract out the addend, because it will get added back in by the normal
+     processing.  */
+  return relocation - linker_section_ptr->addend;
+}
This page took 0.031804 seconds and 4 git commands to generate.