public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Richard Henderson <rth@cygnus.com>
To: binutils@sourceware.cygnus.com
Subject: Re: .dynsym pain
Date: Tue, 13 Jul 1999 18:20:00 -0000	[thread overview]
Message-ID: <19990713182017.A4034@cygnus.com> (raw)
In-Reply-To: <19990713033625.1347.qmail@daffy.airs.com>

On Mon, Jul 12, 1999 at 11:36:25PM -0400, Ian Lance Taylor wrote:
> I assume you mean by this that dynamic relocations can refer to them.

Yep.

> I gather there is some reason that you can't convert the dynamic
> relocations to refer to section symbols instead; presumably there is
> extra information attached to the STB_LOCAL dynamic symbols somehow.

Not quite -- just a bit of ABI silliness that requires r_addend
to be zero for the relocations in question.

>    Which gets in the way of the fact that I need it to have an index, but
>    to be pushed out with STB_LOCAL rather than whatever it had had before.
> 
> I'm not sure why this matters, but I agree with it.

Explained in a comment I added in elf-bfd.h.

> What type are you going to be put on the linked list?

The pair <input_bfd, input_symbol_index> is the unique token.  I'm
also keeping around the entire Elf_Internal_Sym, just because it's
painful to acquire, and I didn't want to have to do it twice.

> You'll then need to run through the list specially at some point;

Yep.  In final_link, just before we call elf_link_output_extsym.

For reference, here's the patch I checked in.  I've tested it
against my new target and on Alpha.  It also fixes a bug on x86,
since we were failing to output the section symbols in shared
libraries there.


r~


	* elf-bfd.h (struct elf_link_local_dynamic_entry): New.
	(struct elf_link_hash_table): Add dynlocal.
	(_bfd_elf_link_lookup_local_dynindx): Prototype.
	(_bfd_elf_link_adjust_dynindx): Delete.
	(_bfd_elf_link_renumber_dynsyms): Prototype.
	(_bfd_elf,link_record_local_dynamic_symbol): Prototype.
	* elfcode.h (elf_link_record_local_dynamic_symbol): New alias.
	* elflink.c (_bfd_elf_link_adjust_dynindx): Delete.
	(_bfd_elf_link_lookup_local_dynindx): New function.
	(elf_link_renumber_hash_table_dynsyms): New function.
	(_bfd_elf_link_renumber_dynsyms): New function.
	* elflink.h (elf_link_record_local_dynamic_symbol): New function.
	(struct elf_assign_sym_version_info): Delete removed_dynamic.
	(bfd_elf,size_dynamic_sections): Use _bfd_strip_section_from_output
	instead of elf_link_remove_section_and_adjust_dynindices.
	Remove removed_dynamic code.  Use _bfd_elf_link_renumber_dynsyms.
	(elf_link_assign_sym_version): Remove removed_dynamic code.
	(elf_link_renumber_dynsyms): Delete.
	(elf_bfd_final_link): Install section and local symbols into .dynsym.

	* elf32-m68k.c (elf_m68k_adjust_dynindx): Delete.
	(elf_m68k_size_dynamic_sections): Don't set section dynindicies.
	(elf_m68k_finish_dynamic_sections): Don't write section dynsyms.
	* elf32-mips.c: Similarly.
	* elf32-ppc.c: Similarly.
	* elf32-sparc.c: Similarly.
	* elf64-alpha.c: Similarly.
	* elf64-sparc.c: Similarly.

Index: elf-bfd.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf-bfd.h,v
retrieving revision 1.10
diff -c -p -d -r1.10 elf-bfd.h
*** elf-bfd.h	1999/07/11 17:13:34	1.10
--- elf-bfd.h	1999/07/14 01:04:15
*************** struct elf_link_hash_entry
*** 86,91 ****
--- 86,101 ----
  
    /* Symbol index as a dynamic symbol.  Initialized to -1, and remains
       -1 if this is not a dynamic symbol.  */
+   /* ??? Note that this is consistently used as a synonym for tests
+      against whether we can perform various simplifying transformations
+      to the code.  (E.g. changing a pc-relative jump to a PLT entry
+      into a pc-relative jump to the target function.)  That test, which
+      is often relatively complex, and someplaces wrong or incomplete,
+      should really be replaced by a predicate in elflink.c.
+ 
+      End result: this field -1 does not indicate that the symbol is
+      not in the dynamic symbol table, but rather that the symbol is
+      not visible outside this DSO.  */
    long dynindx;
  
    /* String table index in .dynstr if this is a dynamic symbol.  */
*************** struct elf_link_hash_entry
*** 181,186 ****
--- 191,215 ----
  #define ELF_LINK_HASH_MARK 04000
  };
  
+ /* Records local symbols to be emitted in the dynamic symbol table.  */
+ 
+ struct elf_link_local_dynamic_entry
+ {
+   struct elf_link_local_dynamic_entry *next;
+ 
+   /* The input bfd this symbol came from.  */
+   bfd *input_bfd;
+ 
+   /* The index of the local symbol being copied.  */
+   long input_indx;
+ 
+   /* The index in the outgoing dynamic symbol table.  */
+   long dynindx;
+   
+   /* A copy of the input symbol.  */
+   Elf_Internal_Sym isym;
+ };
+ 
  /* ELF linker hash table.  */
  
  struct elf_link_hash_table
*************** struct elf_link_hash_table
*** 209,214 ****
--- 238,245 ----
    struct elf_link_hash_entry *hgot;
    /* A pointer to information used to link stabs in sections.  */
    PTR stab_info;
+   /* A linked list of local symbols to be added to .dynsym.  */
+   struct elf_link_local_dynamic_entry *dynlocal;
  };
  
  /* Look up an entry in an ELF linker hash table.  */
*************** struct bfd_strtab_hash *_bfd_elf_stringt
*** 956,961 ****
--- 987,995 ----
  boolean
  _bfd_elf_link_record_dynamic_symbol PARAMS ((struct bfd_link_info *,
  					     struct elf_link_hash_entry *));
+ long
+ _bfd_elf_link_lookup_local_dynindx PARAMS ((struct bfd_link_info *,
+ 					    bfd *, long));
  boolean
  _bfd_elf_compute_section_file_positions PARAMS ((bfd *,
  						 struct bfd_link_info *));
*************** boolean _bfd_elf_create_dynamic_sections
*** 970,977 ****
  						  struct bfd_link_info *));
  boolean _bfd_elf_create_got_section PARAMS ((bfd *,
  					     struct bfd_link_info *));
! boolean _bfd_elf_link_adjust_dynindx PARAMS ((struct elf_link_hash_entry *,
! 					      PTR));
  
  elf_linker_section_t *_bfd_elf_create_linker_section
    PARAMS ((bfd *abfd,
--- 1004,1011 ----
  						  struct bfd_link_info *));
  boolean _bfd_elf_create_got_section PARAMS ((bfd *,
  					     struct bfd_link_info *));
! unsigned long _bfd_elf_link_renumber_dynsyms PARAMS ((bfd *,
! 						      struct bfd_link_info *));
  
  elf_linker_section_t *_bfd_elf_create_linker_section
    PARAMS ((bfd *abfd,
*************** extern boolean bfd_elf64_link_create_dyn
*** 1113,1120 ****
  extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
    PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
  
! #define bfd_elf32_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
! #define bfd_elf64_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
  
  extern boolean _bfd_elf_close_and_cleanup PARAMS ((bfd *));
  extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
--- 1147,1161 ----
  extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
    PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
  
! #define bfd_elf32_link_record_dynamic_symbol \
!   _bfd_elf_link_record_dynamic_symbol
! #define bfd_elf64_link_record_dynamic_symbol \
!   _bfd_elf_link_record_dynamic_symbol
! 
! boolean _bfd_elf32_link_record_local_dynamic_symbol
!   PARAMS ((struct bfd_link_info *, bfd *, long));
! boolean _bfd_elf64_link_record_local_dynamic_symbol
!   PARAMS ((struct bfd_link_info *, bfd *, long));
  
  extern boolean _bfd_elf_close_and_cleanup PARAMS ((bfd *));
  extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
Index: elf32-m68k.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-m68k.c,v
retrieving revision 1.6
diff -c -p -d -r1.6 elf32-m68k.c
*** elf32-m68k.c	1999/07/12 08:15:16	1.6
--- elf32-m68k.c	1999/07/14 01:04:15
*************** static boolean elf_m68k_gc_sweep_hook
*** 43,50 ****
  	   const Elf_Internal_Rela *));
  static boolean elf_m68k_adjust_dynamic_symbol
    PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
- static boolean elf_m68k_adjust_dynindx
-   PARAMS ((struct elf_link_hash_entry *, PTR));
  static boolean elf_m68k_size_dynamic_sections
    PARAMS ((bfd *, struct bfd_link_info *));
  static boolean elf_m68k_relocate_section
--- 43,48 ----
*************** elf_m68k_size_dynamic_sections (output_b
*** 1312,1365 ****
  	}
      }
  
-   /* If we are generating a shared library, we generate a section
-      symbol for each output section for which we might need to copy
-      relocs.  These are local symbols, which means that they must come
-      first in the dynamic symbol table.  That means we must increment
-      the dynamic symbol index of every other dynamic symbol.  */
-   if (info->shared)
-     {
-       int c;
- 
-       c = 0;
-       for (s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  if ((s->flags & SEC_LINKER_CREATED) != 0
- 	      || (s->flags & SEC_ALLOC) == 0)
- 	    continue;
- 
- 	  elf_section_data (s)->dynindx = c + 1;
- 
- 	  /* These symbols will have no names, so we don't need to
-              fiddle with dynstr_index.  */
- 
- 	  ++c;
- 	}
- 
-       elf_link_hash_traverse (elf_hash_table (info),
- 			      elf_m68k_adjust_dynindx,
- 			      (PTR) &c);
-       elf_hash_table (info)->dynsymcount += c;
-     }
- 
    return true;
  }
  
- /* Increment the index of a dynamic symbol by a given amount.  Called
-    via elf_link_hash_traverse.  */
- 
- static boolean
- elf_m68k_adjust_dynindx (h, cparg)
-      struct elf_link_hash_entry *h;
-      PTR cparg;
- {
-   int *cp = (int *) cparg;
- 
-   if (h->dynindx != -1)
-     h->dynindx += *cp;
-   return true;
- }
- 
  /* This function is called via elf_m68k_link_hash_traverse if we are
     creating a shared object with -Bsymbolic.  It discards the space
     allocated to copy PC relative relocs against symbols which are defined
--- 1310,1318 ----
*************** elf_m68k_finish_dynamic_sections (output
*** 2212,2261 ****
      }
  
    elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
- 
-   if (info->shared)
-     {
-       asection *sdynsym;
-       asection *s;
-       Elf_Internal_Sym sym;
-       int c;
- 
-       /* Set up the section symbols for the output sections.  */
- 
-       sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
-       BFD_ASSERT (sdynsym != NULL);
- 
-       sym.st_size = 0;
-       sym.st_name = 0;
-       sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
-       sym.st_other = 0;
- 
-       c = 0;
-       for (s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  int indx;
- 
- 	  if (elf_section_data (s)->dynindx == 0)
- 	    continue;
- 
- 	  sym.st_value = s->vma;
- 
- 	  indx = elf_section_data (s)->this_idx;
- 	  BFD_ASSERT (indx > 0);
- 	  sym.st_shndx = indx;
- 
- 	  bfd_elf32_swap_symbol_out (output_bfd, &sym,
- 				     (PTR) (((Elf32_External_Sym *)
- 					     sdynsym->contents)
- 					    + elf_section_data (s)->dynindx));
- 
- 	  ++c;
- 	}
- 
-       /* Set the sh_info field of the output .dynsym section to the
-          index of the first global symbol.  */
-       elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
-     }
  
    return true;
  }
--- 2165,2170 ----
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.20
diff -c -p -d -r1.20 elf32-mips.c
*** elf32-mips.c	1999/07/13 15:23:22	1.20
--- elf32-mips.c	1999/07/14 01:04:15
*************** _bfd_mips_elf_size_dynamic_sections (out
*** 7693,7724 ****
  	return false;
      }
  
-   /* If we use dynamic linking, we generate a section symbol for each
-      output section.  These are local symbols, which means that they
-      must come first in the dynamic symbol table.
-      That means we must increment the dynamic symbol index of every
-      other dynamic symbol.  */
-   {
-     unsigned int c, i;
- 
-     c = 0;
-     if (elf_hash_table (info)->dynamic_sections_created)
-       {
- 	c = bfd_count_sections (output_bfd);
- 	elf_link_hash_traverse (elf_hash_table (info),
- 				_bfd_elf_link_adjust_dynindx,
- 				(PTR) &c);
- 	elf_hash_table (info)->dynsymcount += c;
- 
- 	for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++)
- 	  {
- 	    elf_section_data (s)->dynindx = i;
- 	    /* These symbols will have no names, so we don't need to
- 	       fiddle with dynstr_index.  */
- 	  }
-       }
-   }
- 
    return true;
  }
  
--- 7693,7698 ----
*************** _bfd_mips_elf_finish_dynamic_sections (o
*** 8163,8221 ****
        = MIPS_ELF_GOT_SIZE (output_bfd);
  
    {
-     asection *sdynsym;
      asection *smsym;
      asection *s;
-     Elf_Internal_Sym sym;
      Elf32_compact_rel cpt;
  
!     /* Set up the section symbols for the output sections. SGI sets
!        the STT_NOTYPE attribute for these symbols.  Should we do so?  */
  
-     sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
      smsym = bfd_get_section_by_name (dynobj, 
  				     MIPS_ELF_MSYM_SECTION_NAME (dynobj));
!     if (sdynsym != NULL)
        {
  	Elf32_Internal_Msym msym;
  
- 	sym.st_size = 0;
- 	sym.st_name = 0;
- 	sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
- 	sym.st_other = 0;
- 
  	msym.ms_hash_value = 0;
  	msym.ms_info = ELF32_MS_INFO (0, 1);
  
  	for (s = output_bfd->sections; s != NULL; s = s->next)
  	  {
! 	    int indx;
! 	    long dynindx;
! 
! 	    sym.st_value = s->vma;
! 
! 	    indx = elf_section_data (s)->this_idx;
! 	    BFD_ASSERT (indx > 0);
! 	    sym.st_shndx = indx;
! 		
! 	    dynindx  = elf_section_data (s)->dynindx;
  
! 	    (*get_elf_backend_data (output_bfd)->s->swap_symbol_out)
! 	      (output_bfd, &sym, 
! 	       sdynsym->contents 
! 	       + (dynindx * MIPS_ELF_SYM_SIZE (output_bfd)));
! 		
! 	    if (smsym)
! 	      bfd_mips_elf_swap_msym_out 
! 		(output_bfd, &msym,
! 		 (((Elf32_External_Msym *) smsym->contents)
! 		  + dynindx));
  	  }
- 
- 	/* Set the sh_info field of the output .dynsym section to
- 	       the index of the first global symbol.  */
- 	elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
- 	  bfd_count_sections (output_bfd) + 1;
        }
  
      if (SGI_COMPAT (output_bfd))
--- 8137,8168 ----
        = MIPS_ELF_GOT_SIZE (output_bfd);
  
    {
      asection *smsym;
      asection *s;
      Elf32_compact_rel cpt;
  
!     /* ??? The section symbols for the output sections were set up in
!        _bfd_elf_final_link.  SGI sets the STT_NOTYPE attribute for these
!        symbols.  Should we do so?  */
  
      smsym = bfd_get_section_by_name (dynobj, 
  				     MIPS_ELF_MSYM_SECTION_NAME (dynobj));
!     if (smsym != NULL)
        {
  	Elf32_Internal_Msym msym;
  
  	msym.ms_hash_value = 0;
  	msym.ms_info = ELF32_MS_INFO (0, 1);
  
  	for (s = output_bfd->sections; s != NULL; s = s->next)
  	  {
! 	    long dynindx = elf_section_data (s)->dynindx;
  
! 	    bfd_mips_elf_swap_msym_out 
! 	      (output_bfd, &msym,
! 	       (((Elf32_External_Msym *) smsym->contents)
! 		+ dynindx));
  	  }
        }
  
      if (SGI_COMPAT (output_bfd))
Index: elf32-ppc.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-ppc.c,v
retrieving revision 1.5
diff -c -p -d -r1.5 elf32-ppc.c
*** elf32-ppc.c	1999/07/12 10:29:28	1.5
--- elf32-ppc.c	1999/07/14 01:04:15
*************** static boolean ppc_elf_gc_sweep_hook PAR
*** 80,87 ****
  static boolean ppc_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *,
  						      struct elf_link_hash_entry *));
  
- static boolean ppc_elf_adjust_dynindx PARAMS ((struct elf_link_hash_entry *, PTR));
- 
  static boolean ppc_elf_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
  
  static boolean ppc_elf_relocate_section PARAMS ((bfd *,
--- 80,85 ----
*************** ppc_elf_adjust_dynamic_symbol (info, h)
*** 1881,1907 ****
  }
  
  \f
- /* Increment the index of a dynamic symbol by a given amount.  Called
-    via elf_link_hash_traverse.  */
- 
- static boolean
- ppc_elf_adjust_dynindx (h, cparg)
-      struct elf_link_hash_entry *h;
-      PTR cparg;
- {
-   int *cp = (int *) cparg;
- 
- #ifdef DEBUG
-   fprintf (stderr, "ppc_elf_adjust_dynindx called, h->dynindx = %d, *cp = %d\n", h->dynindx, *cp);
- #endif
- 
-   if (h->dynindx != -1)
-     h->dynindx += *cp;
- 
-   return true;
- }
- 
- \f
  /* Set the sizes of the dynamic sections.  */
  
  static boolean
--- 1879,1884 ----
*************** ppc_elf_size_dynamic_sections (output_bf
*** 2083,2125 ****
  	}
      }
  
-   /* If we are generating a shared library, we generate a section
-      symbol for each output section.  These are local symbols, which
-      means that they must come first in the dynamic symbol table.
-      That means we must increment the dynamic symbol index of every
-      other dynamic symbol.
- 
-      FIXME: We assume that there will never be relocations to
-      locations in linker-created sections that do not have
-      externally-visible names. Instead, we should work out precisely
-      which sections relocations are targetted at.  */
-   if (info->shared)
-     {
-       int c;
- 
-       for (c = 0, s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  if ((s->flags & SEC_LINKER_CREATED) != 0
- 	      || (s->flags & SEC_ALLOC) == 0)
- 	    {
- 	      elf_section_data (s)->dynindx = 0;
- 	      continue;
- 	    }
- 
- 	  /* These symbols will have no names, so we don't need to
- 	     fiddle with dynstr_index.  */
- 
- 	  elf_section_data (s)->dynindx = c + 1;
- 
- 	  c++;
- 	}
- 
-       elf_link_hash_traverse (elf_hash_table (info),
- 			      ppc_elf_adjust_dynindx,
- 			      (PTR) &c);
-       elf_hash_table (info)->dynsymcount += c;
-     }
- 
    return true;
  }
  
--- 2060,2065 ----
*************** ppc_elf_finish_dynamic_sections (output_
*** 2922,2975 ****
  		    contents+4);
  
        elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
-     }
- 
-   if (info->shared)
-     {
-       asection *sdynsym;
-       asection *s;
-       Elf_Internal_Sym sym;
-       int maxdindx = 0;
- 
-       /* Set up the section symbols for the output sections.  */
- 
-       sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
-       BFD_ASSERT (sdynsym != NULL);
- 
-       sym.st_size = 0;
-       sym.st_name = 0;
-       sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
-       sym.st_other = 0;
- 
-       for (s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  int indx, dindx;
- 
- 	  sym.st_value = s->vma;
- 
- 	  indx = elf_section_data (s)->this_idx;
- 	  dindx = elf_section_data (s)->dynindx;
- 	  if (dindx > 0)
- 	    {
- 	      BFD_ASSERT(indx > 0);
- 	      BFD_ASSERT(dindx > 0);
- 
- 	      if (dindx > maxdindx)
- 		maxdindx = dindx;
- 
- 	      sym.st_shndx = indx;
- 
- 	      bfd_elf32_swap_symbol_out (output_bfd, &sym,
- 					 (PTR) (((Elf32_External_Sym *)
- 						 sdynsym->contents)
- 						+ dindx));
- 	    }
- 	}
- 
-       /* Set the sh_info field of the output .dynsym section to the
-          index of the first global symbol.  */
-       elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
- 	maxdindx + 1;
      }
  
    return true;
--- 2862,2867 ----
Index: elf32-sparc.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-sparc.c,v
retrieving revision 1.4
diff -c -p -d -r1.4 elf32-sparc.c
*** elf32-sparc.c	1999/07/12 10:29:33	1.4
--- elf32-sparc.c	1999/07/14 01:04:16
*************** static boolean elf32_sparc_check_relocs
*** 33,40 ****
  	   const Elf_Internal_Rela *));
  static boolean elf32_sparc_adjust_dynamic_symbol
    PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
- static boolean elf32_sparc_adjust_dynindx
-   PARAMS ((struct elf_link_hash_entry *, PTR));
  static boolean elf32_sparc_size_dynamic_sections
    PARAMS ((bfd *, struct bfd_link_info *));
  static boolean elf32_sparc_relocate_section
--- 33,38 ----
*************** elf32_sparc_size_dynamic_sections (outpu
*** 1043,1096 ****
  	}
      }
  
-   /* If we are generating a shared library, we generate a section
-      symbol for each output section for which we might need to copy
-      relocs.  These are local symbols, which means that they must come
-      first in the dynamic symbol table.  That means we must increment
-      the dynamic symbol index of every other dynamic symbol.  */
-   if (info->shared)
-     {
-       int c;
- 
-       c = 0;
-       for (s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  if ((s->flags & SEC_LINKER_CREATED) != 0
- 	      || (s->flags & SEC_ALLOC) == 0)
- 	    continue;
- 
- 	  elf_section_data (s)->dynindx = c + 1;
- 
- 	  /* These symbols will have no names, so we don't need to
-              fiddle with dynstr_index.  */
- 
- 	  ++c;
- 	}
- 
-       elf_link_hash_traverse (elf_hash_table (info),
- 			      elf32_sparc_adjust_dynindx,
- 			      (PTR) &c);
-       elf_hash_table (info)->dynsymcount += c;
-     }
- 
    return true;
  }
  
- /* Increment the index of a dynamic symbol by a given amount.  Called
-    via elf_link_hash_traverse.  */
- 
- static boolean
- elf32_sparc_adjust_dynindx (h, cparg)
-      struct elf_link_hash_entry *h;
-      PTR cparg;
- {
-   int *cp = (int *) cparg;
- 
-   if (h->dynindx != -1)
-     h->dynindx += *cp;
-   return true;
- }
- 
  /* Relocate a SPARC ELF section.  */
  
  static boolean
--- 1041,1049 ----
*************** elf32_sparc_finish_dynamic_sections (out
*** 1849,1898 ****
      }
  
    elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
- 
-   if (info->shared)
-     {
-       asection *sdynsym;
-       asection *s;
-       Elf_Internal_Sym sym;
-       int c;
- 
-       /* Set up the section symbols for the output sections.  */
- 
-       sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
-       BFD_ASSERT (sdynsym != NULL);
- 
-       sym.st_size = 0;
-       sym.st_name = 0;
-       sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
-       sym.st_other = 0;
- 
-       c = 0;
-       for (s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  int indx;
- 
- 	  if (elf_section_data (s)->dynindx == 0)
- 	    continue;
- 
- 	  sym.st_value = s->vma;
- 
- 	  indx = elf_section_data (s)->this_idx;
- 	  BFD_ASSERT (indx > 0);
- 	  sym.st_shndx = indx;
- 
- 	  bfd_elf32_swap_symbol_out (output_bfd, &sym,
- 				     (PTR) (((Elf32_External_Sym *)
- 					     sdynsym->contents)
- 					    + elf_section_data (s)->dynindx));
- 
- 	  ++c;
- 	}
- 
-       /* Set the sh_info field of the output .dynsym section to the
-          index of the first global symbol.  */
-       elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
-     }
  
    return true;
  }
--- 1802,1807 ----
Index: elf64-alpha.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf64-alpha.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 elf64-alpha.c
*** elf64-alpha.c	1999/06/18 04:25:56	1.2
--- elf64-alpha.c	1999/07/14 01:04:16
*************** static boolean elf64_alpha_adjust_dynami
*** 115,122 ****
    PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
  static boolean elf64_alpha_size_dynamic_sections
    PARAMS((bfd *, struct bfd_link_info *));
- static boolean elf64_alpha_adjust_dynindx
-   PARAMS((struct elf_link_hash_entry *, PTR));
  static boolean elf64_alpha_relocate_section
    PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
  	  Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
--- 115,120 ----
*************** elf64_alpha_size_dynamic_sections (outpu
*** 3264,3297 ****
  	}
      }
  
-   /* If we are generating a shared library, we generate a section
-      symbol for each output section.  These are local symbols, which
-      means that they must come first in the dynamic symbol table.
-      That means we must increment the dynamic symbol index of every
-      other dynamic symbol.  */
-   if (info->shared)
-     {
-       long c[2], i;
-       asection *p;
- 
-       c[0] = 0;
-       c[1] = bfd_count_sections (output_bfd);
- 
-       elf_hash_table (info)->dynsymcount += c[1];
-       elf_link_hash_traverse (elf_hash_table(info),
- 			      elf64_alpha_adjust_dynindx,
- 			      (PTR) c);
- 
-       for (i = 1, p = output_bfd->sections;
- 	   p != NULL;
- 	   p = p->next, i++)
- 	{
- 	  elf_section_data (p)->dynindx = i;
- 	  /* These symbols will have no names, so we don't need to
- 	     fiddle with dynstr_index.  */
- 	}
-     }
- 
    if (elf_hash_table (info)->dynamic_sections_created)
      {
        /* Add some entries to the .dynamic section.  We fill in the
--- 3262,3267 ----
*************** elf64_alpha_size_dynamic_sections (outpu
*** 3332,3353 ****
    return true;
  }
  
- /* Increment the index of a dynamic symbol by a given amount.  Called
-    via elf_link_hash_traverse.  */
- 
- static boolean
- elf64_alpha_adjust_dynindx (h, cparg)
-      struct elf_link_hash_entry *h;
-      PTR cparg;
- {
-   long *cp = (long *)cparg;
- 
-   if (h->dynindx >= cp[0])
-     h->dynindx += cp[1];
- 
-   return true;
- }
- 
  /* Relocate an Alpha ELF section.  */
  
  static boolean
--- 3302,3307 ----
*************** elf64_alpha_finish_dynamic_sections (out
*** 3989,4032 ****
  	  elf_section_data (splt->output_section)->this_hdr.sh_entsize =
  	    PLT_HEADER_SIZE;
  	}
-     }
- 
-   if (info->shared)
-     {
-       asection *sdynsym;
-       asection *s;
-       Elf_Internal_Sym sym;
- 
-       /* Set up the section symbols for the output sections.  */
- 
-       sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
-       BFD_ASSERT (sdynsym != NULL);
- 
-       sym.st_size = 0;
-       sym.st_name = 0;
-       sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
-       sym.st_other = 0;
- 
-       for (s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  int indx;
- 
- 	  sym.st_value = s->vma;
- 
- 	  indx = elf_section_data (s)->this_idx;
- 	  BFD_ASSERT (indx > 0);
- 	  sym.st_shndx = indx;
- 
- 	  bfd_elf64_swap_symbol_out (output_bfd, &sym,
- 				     (PTR) (((Elf64_External_Sym *)
- 					     sdynsym->contents)
- 					    + elf_section_data (s)->dynindx));
- 	}
- 
-       /* Set the sh_info field of the output .dynsym section to the
-          index of the first global symbol.  */
-       elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
- 	bfd_count_sections (output_bfd) + 1;
      }
  
    return true;
--- 3943,3948 ----
Index: elf64-sparc.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf64-sparc.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 elf64-sparc.c
*** elf64-sparc.c	1999/06/10 20:59:54	1.2
--- elf64-sparc.c	1999/07/14 01:04:16
*************** static boolean sparc64_elf_adjust_dynami
*** 51,58 ****
    PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
  static boolean sparc64_elf_size_dynamic_sections
    PARAMS((bfd *, struct bfd_link_info *));
- static boolean sparc64_elf_adjust_dynindx
-   PARAMS((struct elf_link_hash_entry *, PTR));
  
  static boolean sparc64_elf_merge_private_bfd_data
    PARAMS ((bfd *, bfd *));
--- 51,56 ----
*************** sparc64_elf_size_dynamic_sections (outpu
*** 1146,1199 ****
  	}
      }
  
-   /* If we are generating a shared library, we generate a section
-      symbol for each output section for which we might need to copy
-      relocs.  These are local symbols, which means that they must come
-      first in the dynamic symbol table.  That means we must increment
-      the dynamic symbol index of every other dynamic symbol.  */
-   if (info->shared)
-     {
-       int c;
- 
-       c = 0;
-       for (s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  if ((s->flags & SEC_LINKER_CREATED) != 0
- 	      || (s->flags & SEC_ALLOC) == 0)
- 	    continue;
- 
- 	  elf_section_data (s)->dynindx = c + 1;
- 
- 	  /* These symbols will have no names, so we don't need to
-              fiddle with dynstr_index.  */
- 
- 	  ++c;
- 	}
- 
-       elf_link_hash_traverse (elf_hash_table (info),
- 			      sparc64_elf_adjust_dynindx,
- 			      (PTR) &c);
-       elf_hash_table (info)->dynsymcount += c;
-     }
- 
-   return true;
- }
- 
- /* Increment the index of a dynamic symbol by a given amount.  Called
-    via elf_link_hash_traverse.  */
- 
- static boolean
- sparc64_elf_adjust_dynindx (h, cparg)
-      struct elf_link_hash_entry *h;
-      PTR cparg;
- {
-   int *cp = (int *) cparg;
- 
-   if (h->dynindx != -1)
-     h->dynindx += *cp;
    return true;
  }
- 
  \f
  /* Relocate a SPARC64 ELF section.  */
  
--- 1144,1151 ----
*************** sparc64_elf_finish_dynamic_sections (out
*** 2089,2138 ****
      }
  
    elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 8;
- 
-   if (info->shared)
-     {
-       asection *sdynsym;
-       asection *s;
-       Elf_Internal_Sym sym;
-       int c;
- 
-       /* Set up the section symbols for the output sections.  */
- 
-       sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
-       BFD_ASSERT (sdynsym != NULL);
- 
-       sym.st_size = 0;
-       sym.st_name = 0;
-       sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
-       sym.st_other = 0;
- 
-       c = 0;
-       for (s = output_bfd->sections; s != NULL; s = s->next)
- 	{
- 	  int indx;
- 
- 	  if (elf_section_data (s)->dynindx == 0)
- 	    continue;
- 
- 	  sym.st_value = s->vma;
- 
- 	  indx = elf_section_data (s)->this_idx;
- 	  BFD_ASSERT (indx > 0);
- 	  sym.st_shndx = indx;
- 
- 	  bfd_elf64_swap_symbol_out (output_bfd, &sym,
- 				     (PTR) (((Elf64_External_Sym *)
- 					     sdynsym->contents)
- 					    + elf_section_data (s)->dynindx));
- 
- 	  ++c;
- 	}
- 
-       /* Set the sh_info field of the output .dynsym section to the
-          index of the first global symbol.  */
-       elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
-     }
  
    return true;
  }
--- 2041,2046 ----
Index: elfcode.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elfcode.h,v
retrieving revision 1.5
diff -c -p -d -r1.5 elfcode.h
*** elfcode.h	1999/07/07 17:50:55	1.5
--- elfcode.h	1999/07/14 01:04:16
*************** Foundation, Inc., 59 Temple Place - Suit
*** 130,135 ****
--- 130,137 ----
  #define elf_gc_common_final_link	NAME(_bfd_elf,gc_common_final_link)
  #define elf_gc_record_vtinherit		NAME(_bfd_elf,gc_record_vtinherit)
  #define elf_gc_record_vtentry		NAME(_bfd_elf,gc_record_vtentry)
+ #define elf_link_record_local_dynamic_symbol \
+   NAME(_bfd_elf,link_record_local_dynamic_symbol)
  
  #if ARCH_SIZE == 64
  #define ELF_R_INFO(X,Y)	ELF64_R_INFO(X,Y)
Index: elflink.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elflink.c,v
retrieving revision 1.5
diff -c -p -d -r1.5 elflink.c
*** elflink.c	1999/07/11 19:49:34	1.5
--- elflink.c	1999/07/14 01:04:16
*************** _bfd_elf_link_record_dynamic_symbol (inf
*** 260,281 ****
    return true;
  }
  
! /* Increase the index at which H will appear in the dynamic symbol
!    table by INCREMENT (which is really an `int *').  Called via
!    elf_link_hash_traverse.  */
  
! boolean
! _bfd_elf_link_adjust_dynindx (h, increment)
       struct elf_link_hash_entry *h;
!      PTR increment;
  {
    if (h->dynindx != -1)
!     h->dynindx += *((int *) increment);
!     
    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)
--- 260,342 ----
    return true;
  }
  
! /* Return the dynindex of a local dynamic symbol.  */
  
! long
! _bfd_elf_link_lookup_local_dynindx (info, input_bfd, input_indx)
!      struct bfd_link_info *info;
!      bfd *input_bfd;
!      long input_indx;
! {
!   struct elf_link_local_dynamic_entry *e;
! 
!   for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
!     if (e->input_bfd == input_bfd && e->input_indx == input_indx)
!       return e->dynindx;
!   return -1;
! }
! 
! /* This function is used to renumber the dynamic symbols, if some of
!    them are removed because they are marked as local.  This is called
!    via elf_link_hash_traverse.  */
! 
! static boolean elf_link_renumber_hash_table_dynsyms
!   PARAMS ((struct elf_link_hash_entry *, PTR));
! 
! static boolean
! elf_link_renumber_hash_table_dynsyms (h, data)
       struct elf_link_hash_entry *h;
!      PTR data;
  {
+   size_t *count = (size_t *) data;
+ 
    if (h->dynindx != -1)
!     h->dynindx = ++(*count);
! 
    return true;
  }
+ 
+ /* Assign dynsym indicies.  In a shared library we generate a section
+    symbol for each output section, which come first.  Next come all of
+    the back-end allocated local dynamic syms, followed by the rest of
+    the global symbols.  */
+ 
+ unsigned long
+ _bfd_elf_link_renumber_dynsyms (output_bfd, info)
+      bfd *output_bfd;
+      struct bfd_link_info *info;
+ {
+   unsigned long dynsymcount = 0;
+ 
+   if (info->shared)
+     {
+       asection *p;
+       for (p = output_bfd->sections; p ; p = p->next)
+ 	elf_section_data (p)->dynindx = ++dynsymcount;
+     }
+ 
+   if (elf_hash_table (info)->dynlocal)
+     {
+       struct elf_link_local_dynamic_entry *p;
+       for (p = elf_hash_table (info)->dynlocal; p ; p = p->next)
+ 	p->dynindx = ++dynsymcount;
+     }
+ 
+   elf_link_hash_traverse (elf_hash_table (info),
+ 			  elf_link_renumber_hash_table_dynsyms,
+ 			  &dynsymcount);
+ 
+   /* There is an unused NULL entry at the head of the table which
+      we must account for in our count.  Unless there weren't any
+      symbols, which means we'll have no table at all.  */
+   if (dynsymcount != 0)
+     ++dynsymcount;
+ 
+   return elf_hash_table (info)->dynsymcount = dynsymcount;
+ }
  \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)
Index: elflink.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elflink.h,v
retrieving revision 1.15
diff -c -p -d -r1.15 elflink.h
*** elflink.h	1999/07/11 19:49:35	1.15
--- elflink.h	1999/07/14 01:04:16
*************** static boolean elf_link_find_version_dep
*** 48,61 ****
    PARAMS ((struct elf_link_hash_entry *, PTR));
  static boolean elf_link_assign_sym_version
    PARAMS ((struct elf_link_hash_entry *, PTR));
- static boolean elf_link_renumber_dynsyms
-   PARAMS ((struct elf_link_hash_entry *, PTR));
  static boolean elf_collect_hash_codes
    PARAMS ((struct elf_link_hash_entry *, PTR));
  static boolean elf_link_read_relocs_from_section 
    PARAMS ((bfd *, Elf_Internal_Shdr *, PTR, Elf_Internal_Rela *));
- static void elf_link_remove_section_and_adjust_dynindices 
-   PARAMS ((struct bfd_link_info *, asection *));
  static void elf_link_output_relocs
    PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
  static boolean elf_link_size_reloc_section
--- 48,57 ----
*************** elf_add_dynamic_entry (info, tag, val)
*** 2051,2056 ****
--- 2047,2119 ----
  
    return true;
  }
+ 
+ /* Record a new local dynamic symbol.  */
+ 
+ boolean
+ elf_link_record_local_dynamic_symbol (info, input_bfd, input_indx)
+      struct bfd_link_info *info;
+      bfd *input_bfd;
+      long input_indx;
+ {
+   struct elf_link_local_dynamic_entry *entry;
+   struct elf_link_hash_table *eht;
+   struct bfd_strtab_hash *dynstr;
+   Elf_External_Sym esym;
+   unsigned long dynstr_index;
+   char *name;
+   int elfsec, link;
+ 
+   /* See if the entry exists already.  */
+   for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next)
+     if (entry->input_bfd == input_bfd && entry->input_indx == input_indx)
+       return true;
+ 
+   entry = (struct elf_link_local_dynamic_entry *)
+     bfd_alloc (input_bfd, sizeof (*entry));
+   if (entry == NULL)
+     return false;
+ 
+   /* Go find the symbol, so that we can find it's name.  */
+   if (bfd_seek (input_bfd,
+ 		(elf_tdata (input_bfd)->symtab_hdr.sh_offset
+ 		 + input_indx * sizeof (Elf_External_Sym)),
+ 		SEEK_SET) != 0
+       || (bfd_read (&esym, sizeof (Elf_External_Sym), 1, input_bfd)
+ 	  != sizeof (Elf_External_Sym)))
+     return false;
+   elf_swap_symbol_in (input_bfd, &esym, &entry->isym);
+ 
+   name = (bfd_elf_string_from_elf_section
+ 	  (input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link,
+ 	   entry->isym.st_name));
+ 
+   dynstr = elf_hash_table (info)->dynstr;
+   if (dynstr == NULL)
+     {
+       /* Create a strtab to hold the dynamic symbol names.  */
+       elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init ();
+       if (dynstr == NULL)
+ 	return false;
+     }
+ 
+   dynstr_index = _bfd_stringtab_add (dynstr, name, true, false);
+   if (dynstr_index == (unsigned long) -1)
+     return false;
+   entry->isym.st_name = dynstr_index;
+ 
+   eht = elf_hash_table (info);
+ 
+   entry->next = eht->dynlocal;
+   eht->dynlocal = entry;
+   entry->input_bfd = input_bfd;
+   entry->input_indx = input_indx;
+   eht->dynsymcount++;
+ 
+   /* The dynindx will be set at the end of size_dynamic_sections.  */
+ 
+   return true;
+ }
  \f
  
  /* Read and swap the relocs from the section indicated by SHDR.  This
*************** struct elf_assign_sym_version_info
*** 2310,2317 ****
    struct bfd_elf_version_tree *verdefs;
    /* Whether we are exporting all dynamic symbols.  */
    boolean export_dynamic;
-   /* Whether we removed any symbols from the dynamic symbol table.  */
-   boolean removed_dynamic;
    /* Whether we had a failure.  */
    boolean failed;
  };
--- 2373,2378 ----
*************** compute_bucket_count (info)
*** 2486,2527 ****
    return best_size;
  }
  
- /* Remove SECTION from the BFD.  If a symbol for SECTION was going to
-    be put into the dynamic symbol table, remove it, and renumber
-    subsequent entries.  */
- 
- static void
- elf_link_remove_section_and_adjust_dynindices (info, section)
-      struct bfd_link_info *info;
-      asection *section;
- {
-   /* Remove the section from the output list.  */
-   _bfd_strip_section_from_output (section);
- 
-   if (elf_section_data (section->output_section)->dynindx)
-     {
-       asection *s;
-       int increment = -1;
- 
-       /* We were going to output an entry in the dynamic symbol table
- 	 for the symbol corresponding to this section.  Now, the
- 	 section is gone.  So, we must renumber the dynamic indices of
- 	 all subsequent sections and all other entries in the dynamic
- 	 symbol table.  */
-       elf_section_data (section->output_section)->dynindx = 0;
-       for (s = section->output_section->next; s; s = s->next)
- 	if (elf_section_data (s)->dynindx)
- 	  --elf_section_data (s)->dynindx;
-       
-       elf_link_hash_traverse (elf_hash_table (info),
- 			      _bfd_elf_link_adjust_dynindx,
- 			      &increment);
- 
-       /* There is one less dynamic symbol than there was before.  */
-       --elf_hash_table (info)->dynsymcount;
-     }
- }
- 
  /* Set up the sizes and contents of the ELF dynamic sections.  This is
     called by the ELF linker emulation before_allocation routine.  We
     must set the sizes of the sections before the linker sets the
--- 2547,2552 ----
*************** NAME(bfd_elf,size_dynamic_sections) (out
*** 2545,2551 ****
    bfd_size_type soname_indx;
    bfd *dynobj;
    struct elf_backend_data *bed;
-   bfd_size_type old_dynsymcount;
    struct elf_assign_sym_version_info asvinfo;
  
    *sinterpptr = NULL;
--- 2570,2575 ----
*************** NAME(bfd_elf,size_dynamic_sections) (out
*** 2650,2656 ****
        asvinfo.info = info;
        asvinfo.verdefs = verdefs;
        asvinfo.export_dynamic = export_dynamic;
-       asvinfo.removed_dynamic = false;
        asvinfo.failed = false;
  
        elf_link_hash_traverse (elf_hash_table (info),
--- 2674,2679 ----
*************** NAME(bfd_elf,size_dynamic_sections) (out
*** 2712,2718 ****
  
    /* The backend must work out the sizes of all the other dynamic
       sections.  */
-   old_dynsymcount = elf_hash_table (info)->dynsymcount;
    if (bed->elf_backend_size_dynamic_sections
        && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
      return false;
--- 2735,2740 ----
*************** NAME(bfd_elf,size_dynamic_sections) (out
*** 2734,2740 ****
        verdefs = asvinfo.verdefs;
  
        if (verdefs == NULL)
! 	elf_link_remove_section_and_adjust_dynindices (info, s);
        else
  	{
  	  unsigned int cdefs;
--- 2756,2762 ----
        verdefs = asvinfo.verdefs;
  
        if (verdefs == NULL)
! 	_bfd_strip_section_from_output (s);
        else
  	{
  	  unsigned int cdefs;
*************** NAME(bfd_elf,size_dynamic_sections) (out
*** 2744,2766 ****
  	  Elf_Internal_Verdef def;
  	  Elf_Internal_Verdaux defaux;
  
- 	  if (asvinfo.removed_dynamic)
- 	    {
- 	      /* Some dynamic symbols were changed to be local
- 		 symbols.  In this case, we renumber all of the
- 		 dynamic symbols, so that we don't have a hole.  If
- 		 the backend changed dynsymcount, then assume that the
- 		 new symbols are at the start.  This is the case on
- 		 the MIPS.  FIXME: The names of the removed symbols
- 		 will still be in the dynamic string table, wasting
- 		 space.  */
- 	      elf_hash_table (info)->dynsymcount =
- 		1 + (elf_hash_table (info)->dynsymcount - old_dynsymcount);
- 	      elf_link_hash_traverse (elf_hash_table (info),
- 				      elf_link_renumber_dynsyms,
- 				      (PTR) info);
- 	    }
- 
  	  cdefs = 0;
  	  size = 0;
  
--- 2766,2771 ----
*************** NAME(bfd_elf,size_dynamic_sections) (out
*** 2927,2933 ****
  				(PTR) &sinfo);
  
  	if (elf_tdata (output_bfd)->verref == NULL)
! 	  elf_link_remove_section_and_adjust_dynindices (info, s);
  	else
  	  {
  	    Elf_Internal_Verneed *t;
--- 2932,2938 ----
  				(PTR) &sinfo);
  
  	if (elf_tdata (output_bfd)->verref == NULL)
! 	  _bfd_strip_section_from_output (s);
  	else
  	  {
  	    Elf_Internal_Verneed *t;
*************** NAME(bfd_elf,size_dynamic_sections) (out
*** 3018,3024 ****
  	  }
        }
  
!       dynsymcount = elf_hash_table (info)->dynsymcount;
  
        /* Work out the size of the symbol version section.  */
        s = bfd_get_section_by_name (dynobj, ".gnu.version");
--- 3023,3034 ----
  	  }
        }
  
!       /* Assign dynsym indicies.  In a shared library we generate a 
! 	 section symbol for each output section, which come first.
! 	 Next come all of the back-end allocated local dynamic syms,
! 	 followed by the rest of the global symbols.  */
! 
!       dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
  
        /* Work out the size of the symbol version section.  */
        s = bfd_get_section_by_name (dynobj, ".gnu.version");
*************** NAME(bfd_elf,size_dynamic_sections) (out
*** 3026,3035 ****
        if (dynsymcount == 0
  	  || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
  	{
! 	  elf_link_remove_section_and_adjust_dynindices (info, s);
  	  /* The DYNSYMCOUNT might have changed if we were going to
  	     output a dynamic symbol table entry for S.  */
! 	  dynsymcount = elf_hash_table (info)->dynsymcount;
  	}
        else
  	{
--- 3036,3045 ----
        if (dynsymcount == 0
  	  || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
  	{
! 	  _bfd_strip_section_from_output (s);
  	  /* The DYNSYMCOUNT might have changed if we were going to
  	     output a dynamic symbol table entry for S.  */
! 	  dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
  	}
        else
  	{
*************** elf_link_assign_sym_version (h, data)
*** 3513,3519 ****
  			      && info->shared
  			      && ! sinfo->export_dynamic)
  			    {
- 			      sinfo->removed_dynamic = true;
  			      h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
  			      h->elf_link_hash_flags &=~
  				ELF_LINK_HASH_NEEDS_PLT;
--- 3523,3528 ----
*************** elf_link_assign_sym_version (h, data)
*** 3629,3635 ****
  			  && info->shared
  			  && ! sinfo->export_dynamic)
  			{
- 			  sinfo->removed_dynamic = true;
  			  h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
  			  h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
  			  h->dynindx = -1;
--- 3638,3643 ----
*************** elf_link_assign_sym_version (h, data)
*** 3654,3660 ****
  	      && info->shared
  	      && ! sinfo->export_dynamic)
  	    {
- 	      sinfo->removed_dynamic = true;
  	      h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
  	      h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
  	      h->dynindx = -1;
--- 3662,3667 ----
*************** elf_link_assign_sym_version (h, data)
*** 3667,3692 ****
  
    return true;
  }
- 
- /* This function is used to renumber the dynamic symbols, if some of
-    them are removed because they are marked as local.  This is called
-    via elf_link_hash_traverse.  */
- 
- static boolean
- elf_link_renumber_dynsyms (h, data)
-      struct elf_link_hash_entry *h;
-      PTR data;
- {
-   struct bfd_link_info *info = (struct bfd_link_info *) data;
- 
-   if (h->dynindx != -1)
-     {
-       h->dynindx = elf_hash_table (info)->dynsymcount;
-       ++elf_hash_table (info)->dynsymcount;
-     }
- 
-   return true;
- }
  \f
  /* Final phase of ELF linker.  */
  
--- 3674,3679 ----
*************** elf_bfd_final_link (abfd, info)
*** 4161,4171 ****
  	return false;
      }
  
!   /* The sh_info field records the index of the first non local
!      symbol.  */
    symtab_hdr->sh_info = bfd_get_symcount (abfd);
    if (dynamic)
!     elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 1;
  
    /* We get the global symbols from the hash table.  */
    eoinfo.failed = false;
--- 4148,4224 ----
  	return false;
      }
  
!   /* The sh_info field records the index of the first non local symbol.  */
    symtab_hdr->sh_info = bfd_get_symcount (abfd);
+ 
    if (dynamic)
!     {
!       Elf_Internal_Sym sym;
!       Elf_External_Sym *dynsym =
! 	(Elf_External_Sym *)finfo.dynsym_sec->contents;
!       unsigned long last_local = 0;
! 
!       /* Write out the section symbols for the output sections.  */
!       if (info->shared)
! 	{
! 	  asection *s;
! 
! 	  sym.st_size = 0;
! 	  sym.st_name = 0;
! 	  sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
! 	  sym.st_other = 0;
! 
! 	  for (s = abfd->sections; s != NULL; s = s->next)
! 	    {
! 	      int indx;
! 	      indx = elf_section_data (s)->this_idx;
! 	      BFD_ASSERT (indx > 0);
! 	      sym.st_shndx = indx;
! 	      sym.st_value = s->vma;
! 
! 	      elf_swap_symbol_out (abfd, &sym,
! 				   dynsym + elf_section_data (s)->dynindx);
! 	    }
! 
! 	  last_local = bfd_count_sections (abfd);
! 	}
! 
!       /* Write out the local dynsyms.  */
!       if (elf_hash_table (info)->dynlocal)
! 	{
! 	  struct elf_link_local_dynamic_entry *e;
! 	  for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
! 	    {
! 	      asection *s, *os;
! 
! 	      sym.st_size = e->isym.st_size;
! 	      sym.st_other = e->isym.st_other;
! 
! 	      /* Note that we saved a word of storage and overwrote
!                  the original st_name with the dynstr_index.  */
! 	      sym.st_name = e->isym.st_name;
! 
! 	      /* Whatever binding the symbol had before, it's now local.  */
! 	      sym.st_info = ELF_ST_INFO (STB_LOCAL,
! 					 ELF_ST_TYPE (e->isym.st_info));
! 
! 	      s = bfd_section_from_elf_index (e->input_bfd, e->isym.st_shndx);
! 
! 	      sym.st_shndx = elf_section_data (s->output_section)->this_idx;
! 	      sym.st_value = (s->output_section->vma
! 			      + s->output_offset
! 			      + e->isym.st_value);
! 
! 	      if (last_local < e->dynindx)
! 		last_local = e->dynindx;
! 
! 	      elf_swap_symbol_out (abfd, &sym, dynsym + e->dynindx);
! 	    }
! 	}
! 
!       elf_section_data (finfo.dynsym_sec->output_section)
! 	->this_hdr.sh_info = last_local;
!     }
  
    /* We get the global symbols from the hash table.  */
    eoinfo.failed = false;

  reply	other threads:[~1999-07-13 18:20 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-07-12 18:05 Richard Henderson
1999-07-12 20:37 ` Ian Lance Taylor
1999-07-13 18:20   ` Richard Henderson [this message]
1999-07-12 21:57 ` Mark Mitchell
1999-07-13 19:12   ` Richard Henderson
1999-07-13 22:42     ` Mark Mitchell
1999-07-14  0:20       ` Richard Henderson
1999-07-14  1:03         ` Mark Mitchell
1999-07-14  2:17           ` Richard Henderson
1999-07-14  8:35             ` Mark Mitchell
1999-07-14 17:04               ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19990713182017.A4034@cygnus.com \
    --to=rth@cygnus.com \
    --cc=binutils@sourceware.cygnus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).