This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Move bfd *_pointer_linker_section into elf32-ppc.c


This moves all the bfd *_linker_section functions into elf32-ppc.c, the
only place they are used.  I suppose these functions were considered
generally useful at the time they were created in Jan 1996, but no other
uses have emerged since then (except for a time by m32r), so they're
really just bloat for most targets.  The other benefit of this move is
that we can get rid of a pointer in struct elf_link_hash_entry, reducing
symbol table memory usage.

If no one objects to this patch, I'll apply it in a day or so, and
also make the elf_link_hash_entry change.

	* elf-bfd.h (_bfd_elf_create_linker_section) Don't declare.
	(_bfd_elf_find_pointer_linker_section): Likewise.
	(bfd_elf32_create_pointer_linker_section): Likewise.
	(bfd_elf32_finish_pointer_linker_section): Likewise.
	(bfd_elf64_create_pointer_linker_section): Likewise.
	(bfd_elf64_finish_pointer_linker_section): Likewise.
	(_bfd_elf_make_linker_section_rela): Likewise.
	* elfcode.h (elf_create_pointer_linker_section): Don't define.
	(elf_finish_pointer_linker_section): Likewise.
	* elflink.c (_bfd_elf_make_linker_section_rela): Delete.
	(_bfd_elf_create_linker_section): Move this function..
	(_bfd_elf_find_pointer_linker_section): ..and this..
	* elflink.h (elf_create_pointer_linker_section): ..and this..
	(elf_finish_pointer_linker_section): ..and this..
	* elf32-ppc.c: ..to here, renaming to the following, and adjusting
	calls.
	(elf_create_linker_section): Convert to C90, tidy.
	(elf_find_pointer_linker_section): Likewise.
	(elf_create_pointer_linker_section): Likewise.
	(elf_finish_pointer_linker_section): Likewise.
	* elf32-i370.c: Delete #if 0 code.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.99
diff -u -p -r1.99 elf-bfd.h
--- bfd/elf-bfd.h	25 Jun 2003 06:40:24 -0000	1.99
+++ bfd/elf-bfd.h	3 Jul 2003 04:56:57 -0000
@@ -1554,35 +1554,6 @@ extern bfd_boolean _bfd_elfcore_make_pse
 extern char *_bfd_elfcore_strndup
   PARAMS ((bfd *, char *, size_t));
 
-extern elf_linker_section_t *_bfd_elf_create_linker_section
-  PARAMS ((bfd *, struct bfd_link_info *, enum elf_linker_section_enum,
-	   elf_linker_section_t *));
-
-extern elf_linker_section_pointers_t *_bfd_elf_find_pointer_linker_section
-  PARAMS ((elf_linker_section_pointers_t *, bfd_vma,
-	   elf_linker_section_enum_t));
-
-extern bfd_boolean bfd_elf32_create_pointer_linker_section
-  PARAMS ((bfd *, struct bfd_link_info *, elf_linker_section_t *,
-	   struct elf_link_hash_entry *, const Elf_Internal_Rela *));
-
-extern bfd_vma bfd_elf32_finish_pointer_linker_section
-  PARAMS ((bfd *, bfd *, struct bfd_link_info *, elf_linker_section_t *,
-	   struct elf_link_hash_entry *, bfd_vma,
-	   const Elf_Internal_Rela *, int));
-
-extern bfd_boolean bfd_elf64_create_pointer_linker_section
-  PARAMS ((bfd *, struct bfd_link_info *, elf_linker_section_t *,
-	   struct elf_link_hash_entry *, const Elf_Internal_Rela *));
-
-extern bfd_vma bfd_elf64_finish_pointer_linker_section
-  PARAMS ((bfd *, bfd *, struct bfd_link_info *, elf_linker_section_t *,
-	   struct elf_link_hash_entry *, bfd_vma,
-	   const Elf_Internal_Rela *, int));
-
-extern bfd_boolean _bfd_elf_make_linker_section_rela
-  PARAMS ((bfd *, elf_linker_section_t *, int));
-
 extern Elf_Internal_Rela *_bfd_elf_link_read_relocs
   PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, bfd_boolean));
 
Index: bfd/elfcode.h
===================================================================
RCS file: /cvs/src/src/bfd/elfcode.h,v
retrieving revision 1.44
diff -u -p -r1.44 elfcode.h
--- bfd/elfcode.h	25 Jun 2003 06:40:21 -0000	1.44
+++ bfd/elfcode.h	3 Jul 2003 04:57:08 -0000
@@ -125,8 +125,6 @@ Foundation, Inc., 59 Temple Place - Suit
 #define elf_reloc_symbol_deleted_p	NAME(_bfd_elf,reloc_symbol_deleted_p)
 #define elf_link_record_dynamic_symbol  _bfd_elf_link_record_dynamic_symbol
 #define elf_bfd_final_link		NAME(bfd_elf,bfd_final_link)
-#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section)
-#define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section)
 #define elf_gc_sections			NAME(_bfd_elf,gc_sections)
 #define elf_gc_common_finalize_got_offsets \
   NAME(_bfd_elf,gc_common_finalize_got_offsets)
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.35
diff -u -p -r1.35 elflink.c
--- bfd/elflink.c	30 May 2003 15:50:11 -0000	1.35
+++ bfd/elflink.c	3 Jul 2003 04:57:09 -0000
@@ -1896,179 +1896,6 @@ _bfd_elf_link_assign_sym_version (h, dat
   return TRUE;
 }
 
-/* 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;
-      bfd_size_type amt = sizeof (elf_linker_section_t);
-
-      lsect = (elf_linker_section_t *) bfd_alloc (dynobj, amt);
-
-      *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 too large to add hole of %ld bytes"),
-		 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;
-	  struct bfd_link_hash_entry *bh;
-
-#ifdef DEBUG
-	  fprintf (stderr, "Adding %s to section %s\n",
-		   lsect->sym_name,
-		   lsect->name);
-#endif
-	  bh = bfd_link_hash_lookup (info->hash, lsect->sym_name,
-				     FALSE, FALSE, FALSE);
-
-	  if ((bh == NULL || bh->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, &bh)))
-	    return (elf_linker_section_t *) 0;
-	  h = (struct elf_link_hash_entry *) bh;
-
-	  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;
-	}
-    }
-
-#if 0
-  /* This does not make sense.  The sections which may exist in the
-     object file have nothing to do with the sections we want to
-     create.  */
-
-  /* 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);
-#endif
-
-  return lsect;
-}
-
-/* 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_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;
-}
-
-/* Make the .rela section corresponding to the generated linker section.  */
-
-bfd_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;
-}
-
 /* Read and swap the relocs from the section indicated by SHDR.  This
    may be either a REL or a RELA section.  The relocations are
    translated into RELA relocations and stored in INTERNAL_RELOCS,
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.233
diff -u -p -r1.233 elflink.h
--- bfd/elflink.h	25 Jun 2003 06:40:21 -0000	1.233
+++ bfd/elflink.h	3 Jul 2003 04:57:13 -0000
@@ -5557,264 +5557,6 @@ elf_reloc_link_order (output_bfd, info, 
   return TRUE;
 }
 
-/* Allocate a pointer to live in a linker created section.  */
-
-bfd_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_size_type amt;
-
-  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)
-	{
-	  unsigned int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info;
-	  register unsigned int i;
-
-	  amt = num_symbols;
-	  amt *= sizeof (elf_linker_section_pointers_t *);
-	  ptr = (elf_linker_section_pointers_t **) bfd_alloc (abfd, amt);
-
-	  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);
-  amt = sizeof (elf_linker_section_pointers_t);
-  linker_section_ptr = (elf_linker_section_pointers_t *) bfd_alloc (abfd, amt);
-
-  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 0
-  if (lsect->hole_size && lsect->hole_offset < lsect->max_hole_offset)
-    {
-      linker_section_ptr->offset = (lsect->section->_raw_size
-				    - lsect->hole_size + (ARCH_SIZE / 8));
-      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;
-#ifdef DEBUG
-	  fprintf (stderr, "Bump up %s by %ld, current value = %ld\n",
-		   lsect->sym_hash->root.root.string,
-		   (long) ARCH_SIZE / 8,
-		   (long) lsect->sym_hash->root.u.def.value);
-#endif
-	}
-    }
-  else
-#endif
-    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;
-}
-
-#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 a linker 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)
-    {
-      /* Handle 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
-    {
-      /* Handle 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[MAX_INT_RELS_PER_EXT_REL];
-	      bfd_byte *erel;
-	      struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
-	      unsigned int i;
-
-	      /* We need to generate a relative reloc for the dynamic
-		 linker.  */
-	      if (!srel)
-		{
-		  srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
-						  lsect->rel_name);
-		  lsect->rel_section = srel;
-		}
-
-	      BFD_ASSERT (srel != NULL);
-
-	      for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
-		{
-		  outrel[i].r_offset = (lsect->section->output_section->vma
-					+ lsect->section->output_offset
-					+ linker_section_ptr->offset);
-		  outrel[i].r_info = 0;
-		  outrel[i].r_addend = 0;
-		}
-	      outrel[0].r_info = ELF_R_INFO (0, relative_reloc);
-	      erel = lsect->section->contents;
-	      erel += (elf_section_data (lsect->section)->rel_count++
-		       * sizeof (Elf_External_Rela));
-	      elf_swap_reloca_out (output_bfd, outrel, erel);
-	    }
-	}
-    }
-
-  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;
-}
-
 /* Garbage collect unused sections.  */
 
 static bfd_boolean elf_gc_mark
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.88
diff -u -p -r1.88 elf32-ppc.c
--- bfd/elf32-ppc.c	25 Jun 2003 11:05:58 -0000	1.88
+++ bfd/elf32-ppc.c	3 Jul 2003 06:53:39 -0000
@@ -2169,6 +2169,360 @@ ppc_elf_fake_sections (bfd *abfd ATTRIBU
   return TRUE;
 }
 
+/* Create a special linker section, or return a pointer to a linker
+   section already created */
+
+static elf_linker_section_t *
+elf_create_linker_section (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;
+      bfd_size_type amt = sizeof (elf_linker_section_t);
+
+      lsect = bfd_alloc (dynobj, amt);
+
+      *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 NULL;
+
+	  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 too large to add hole of %ld bytes"),
+		 bfd_get_filename (abfd),
+		 lsect->name,
+		 (long) lsect->hole_size);
+
+	      bfd_set_error (bfd_error_bad_value);
+	      return NULL;
+	    }
+	}
+
+#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;
+	  struct bfd_link_hash_entry *bh;
+
+#ifdef DEBUG
+	  fprintf (stderr, "Adding %s to section %s\n",
+		   lsect->sym_name,
+		   lsect->name);
+#endif
+	  bh = bfd_link_hash_lookup (info->hash, lsect->sym_name,
+				     FALSE, FALSE, FALSE);
+
+	  if ((bh == NULL || bh->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),
+		    NULL, FALSE,
+		    get_elf_backend_data (abfd)->collect, &bh)))
+	    return NULL;
+	  h = (struct elf_link_hash_entry *) bh;
+
+	  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 NULL;
+	}
+    }
+
+  return lsect;
+}
+
+/* Find a linker generated pointer with a given addend and type.  */
+
+static elf_linker_section_pointers_t *
+elf_find_pointer_linker_section
+  (elf_linker_section_pointers_t *linker_pointers,
+   bfd_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 NULL;
+}
+
+/* Allocate a pointer to live in a linker created section.  */
+
+static bfd_boolean
+elf_create_pointer_linker_section (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 = ELF32_R_SYM (rel->r_info);
+  bfd_size_type amt;
+
+  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 (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 (! _bfd_elf_link_record_dynamic_symbol (info, h))
+	    return FALSE;
+	}
+
+      if (lsect->rel_section)
+	lsect->rel_section->_raw_size += sizeof (Elf32_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)
+	{
+	  unsigned int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info;
+	  register unsigned int i;
+
+	  amt = num_symbols;
+	  amt *= sizeof (elf_linker_section_pointers_t *);
+	  ptr = bfd_alloc (abfd, amt);
+
+	  if (!ptr)
+	    return FALSE;
+
+	  elf_local_ptr_offsets (abfd) = ptr;
+	  for (i = 0; i < num_symbols; i++)
+	    ptr[i] = NULL;
+	}
+
+      /* Has this symbol already been allocated?  If so, our work is done.  */
+      if (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 (Elf32_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);
+  amt = sizeof (elf_linker_section_pointers_t);
+  linker_section_ptr = bfd_alloc (abfd, amt);
+
+  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;
+
+  linker_section_ptr->offset = lsect->section->_raw_size;
+  lsect->section->_raw_size += 4;
+
+#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;
+}
+
+#define bfd_put_ptr(BFD, VAL, ADDR) bfd_put_32 (BFD, VAL, ADDR)
+
+/* Fill in the address for a pointer generated in a linker section.  */
+
+static bfd_vma
+elf_finish_pointer_linker_section (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)
+    {
+      /* Handle global symbol.  */
+      linker_section_ptr
+	= 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
+    {
+      /* Handle local symbol.  */
+      unsigned long r_symndx = ELF32_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 = (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[MAX_INT_RELS_PER_EXT_REL];
+	      bfd_byte *erel;
+	      struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+	      unsigned int i;
+
+	      /* We need to generate a relative reloc for the dynamic
+		 linker.  */
+	      if (!srel)
+		{
+		  srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
+						  lsect->rel_name);
+		  lsect->rel_section = srel;
+		}
+
+	      BFD_ASSERT (srel != NULL);
+
+	      for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
+		{
+		  outrel[i].r_offset = (lsect->section->output_section->vma
+					+ lsect->section->output_offset
+					+ linker_section_ptr->offset);
+		  outrel[i].r_info = 0;
+		  outrel[i].r_addend = 0;
+		}
+	      outrel[0].r_info = ELF32_R_INFO (0, relative_reloc);
+	      erel = lsect->section->contents;
+	      erel += (elf_section_data (lsect->section)->rel_count++
+		       * sizeof (Elf32_External_Rela));
+	      bfd_elf32_swap_reloca_out (output_bfd, outrel, erel);
+	    }
+	}
+    }
+
+  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;
+}
+
 /* Create a special linker section */
 static elf_linker_section_t *
 ppc_elf_create_linker_section (bfd *abfd,
@@ -2233,7 +2587,7 @@ ppc_elf_create_linker_section (bfd *abfd
 	  break;
 	}
 
-      lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults);
+      lsect = elf_create_linker_section (abfd, info, which, &defaults);
     }
 
   return lsect;
@@ -3220,8 +3574,8 @@ ppc_elf_check_relocs (bfd *abfd,
 	      bad_shared_reloc (abfd, r_type);
 	      return FALSE;
 	    }
-	  if (!bfd_elf32_create_pointer_linker_section (abfd, info,
-							htab->sdata, h, rel))
+	  if (!elf_create_pointer_linker_section (abfd, info,
+						  htab->sdata, h, rel))
 	    return FALSE;
 	  break;
 
@@ -3232,8 +3586,8 @@ ppc_elf_check_relocs (bfd *abfd,
 	      bad_shared_reloc (abfd, r_type);
 	      return FALSE;
 	    }
-	  if (!bfd_elf32_create_pointer_linker_section (abfd, info,
-							htab->sdata2, h, rel))
+	  if (!elf_create_pointer_linker_section (abfd, info,
+						  htab->sdata2, h, rel))
 	    return FALSE;
 	  break;
 
@@ -5008,20 +5362,18 @@ ppc_elf_relocate_section (bfd *output_bf
 	case R_PPC_EMB_SDAI16:
 	  BFD_ASSERT (htab->sdata != NULL);
 	  relocation
-	    = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd,
-						       info, htab->sdata, h,
-						       relocation, rel,
-						       R_PPC_RELATIVE);
+	    = elf_finish_pointer_linker_section (output_bfd, input_bfd, info,
+						 htab->sdata, h, relocation,
+						 rel, R_PPC_RELATIVE);
 	  break;
 
 	  /* Indirect .sdata2 relocation.  */
 	case R_PPC_EMB_SDA2I16:
 	  BFD_ASSERT (htab->sdata2 != NULL);
 	  relocation
-	    = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd,
-						       info, htab->sdata2, h,
-						       relocation, rel,
-						       R_PPC_RELATIVE);
+	    = elf_finish_pointer_linker_section (output_bfd, input_bfd, info,
+						 htab->sdata2, h, relocation,
+						 rel, R_PPC_RELATIVE);
 	  break;
 
 	  /* Handle the TOC16 reloc.  We want to use the offset within the .got
Index: bfd/elf32-i370.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i370.c,v
retrieving revision 1.27
diff -u -p -r1.27 elf32-i370.c
--- bfd/elf32-i370.c	25 Jun 2003 06:40:22 -0000	1.27
+++ bfd/elf32-i370.c	3 Jul 2003 04:56:59 -0000
@@ -290,11 +290,6 @@ static bfd_boolean i370_elf_section_from
   PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
 static bfd_boolean i370_elf_fake_sections
   PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
-#if 0
-static elf_linker_section_t *i370_elf_create_linker_section
-  PARAMS ((bfd *abfd, struct bfd_link_info *info,
-	   enum elf_linker_section_enum));
-#endif
 static bfd_boolean i370_elf_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
 	   const Elf_Internal_Rela *));
@@ -433,84 +428,6 @@ i370_elf_fake_sections (abfd, shdr, asec
 
   return TRUE;
 }
-
-#if 0
-/* Create a special linker section */
-/* XXX hack alert bogus This routine is mostly all junk and almost
- * certainly does the wrong thing.  Its here simply because it does
- * just enough to allow glibc-2.1 ld.so to compile & link.
- */
-
-static elf_linker_section_t *
-i370_elf_create_linker_section (abfd, info, which)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     enum elf_linker_section_enum which;
-{
-  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)
-    {
-      elf_linker_section_t defaults;
-      static elf_linker_section_t zero_section;
-
-      defaults = zero_section;
-      defaults.which = which;
-      defaults.hole_written_p = FALSE;
-      defaults.alignment = 2;
-
-      /* Both of these sections are (technically) created by the user
-	 putting data in them, so they shouldn't be marked
-	 SEC_LINKER_CREATED.
-
-	 The linker creates them so it has somewhere to attach their
-	 respective symbols. In fact, if they were empty it would
-	 be OK to leave the symbol set to 0 (or any random number), because
-	 the appropriate register should never be used.  */
-      defaults.flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
-			| SEC_IN_MEMORY);
-
-      switch (which)
-	{
-	default:
-	  (*_bfd_error_handler) ("%s: Unknown special linker type %d",
-				 bfd_archive_filename (abfd),
-				 (int) which);
-
-	  bfd_set_error (bfd_error_bad_value);
-	  return (elf_linker_section_t *)0;
-
-	case LINKER_SECTION_SDATA:	/* .sdata/.sbss section */
-	  defaults.name		  = ".sdata";
-	  defaults.rel_name	  = ".rela.sdata";
-	  defaults.bss_name	  = ".sbss";
-	  defaults.sym_name	  = "_SDA_BASE_";
-	  defaults.sym_offset	  = 32768;
-	  break;
-
-	case LINKER_SECTION_SDATA2:	/* .sdata2/.sbss2 section */
-	  defaults.name		  = ".sdata2";
-	  defaults.rel_name	  = ".rela.sdata2";
-	  defaults.bss_name	  = ".sbss2";
-	  defaults.sym_name	  = "_SDA2_BASE_";
-	  defaults.sym_offset	  = 32768;
-	  defaults.flags	 |= SEC_READONLY;
-	  break;
-	}
-
-      lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults);
-    }
-
-  return lsect;
-}
-#endif
 
 /* We have to create .dynsbss and .rela.sbss here so that they get mapped
    to output sections (just like _bfd_elf_create_dynamic_sections has

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]