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]

Re: [RFA:] elflink.c: Hide _GLOBAL_OFFSET_TABLE_


> Actually, I think it would be better if it was hidden on all arches,
> but SPARC (and other backends that need it) would either unconditionally
> or only when needed emitted the STB_LOCAL _GLOBAL_OFFSET_TABLE_ into
> .dynsym even when it is not exported.  Another alternative would be
> to special case dynamic relocations against _GLOBAL_OFFSET_TABLE_,
> so that they would be against symbol 0 instead of .got or
> _GLOBAL_OFFSET_TABLE_ symbol.

It turned out that it's not a little breakage: you basically cannot create 
shared libraries with global data anymore!  This was exacerbated by HP's 
patch, but the problem had actually been introduced by your May 2004 patch 
that hides the .got section: it can be reproduced with

 local:
  *;

in the linker script prior to HP's patch.


I've attached a patch that unhides .got on the SPARC (bfd_sparc_got-4.diff).  
Tested on sparc64-sun-solaris2.9 and sparc-sun-solaris2.8, it is sufficient 
to cure the problem.


	* elf32-sparc.c (elf32_sparc_omit_section_dynsym): New function.
	(elf_backend_omit_section_dynsym): Define to it.
	* elf64-sparc.c (sparc64_elf_omit_section_dynsym): New function.
	(elf_backend_omit_section_dynsym): Define to it.	


I've also tried to implement your first suggestion, that is to emit _G_O_T_ 
as a local symbol in .dynsym unconditionally (bfd_sparc_got-5.diff).  Seems 
to work too, tested on sparc64-sun-solaris2.9 and sparc-sun-solaris2.8, but 
far more invasive.


	* elf-bfd.h (struct elf_link_local_dynamic_entry): New 'input_section' field.
	(bfd_elf_link_create_local_dynamic_entry): Declare.
	* elflink.c (bfd_elf_link_create_local_dynamic_entry): New function
	extracted from...
	(bfd_elf_link_record_local_dynamic_symbol): ...here.  Invoke it to
	create the local dynamic symbol and set input_section to NULL.
	(bfd_elf_final_link): For a local dynamic symbol, piggyback on input_section
	if the ELF section is undefined.
	* elf32-sparc.c (elf32_sparc_link_hash_table_create): Use bfd_zmalloc to
	zero the structure.
	(create_got_section): Use BFD_ASSERT instead of abort.  Create a local
	dynamic symbol for _GLOBAL_OFFSET_TABLE_.
	(elf32_sparc_relocate_section): In a shared object, use the index of the
	local dynamic symbol for relocations against _GLOBAL_OFFSET_TABLE_.
	* elf64-sparc.c (struct sparc64_elf_link_hash_table): New 'sgot' and
	'srelgot' fields.
	(create_got_section): New function.
	(sparc64_elf_create_dynamic_sections): Likewise.
	(sparc64_elf_check_relocs): Invoke create_got_section instead of
	_bfd_elf_create_got_section.  Use the sgot and srelgot shortcuts.
	(sparc64_elf_size_dynamic_sections): Use the srelgot shortcut.
	(sparc64_elf_relocate_section): In a shared object, use the index of the
	local dynamic symbol for relocations against _GLOBAL_OFFSET_TABLE_.
	Use the sgot and srelgot shortcuts.
	(sparc64_elf_finish_dynamic_symbol): Use the sgot and srelgot shortcuts.
	(sparc64_elf_finish_dynamic_sections): Use the sgot shortcut.
	(elf_backend_create_dynamic_sections): Define to
	sparc64_elf_create_dynamic_sections.


-- 
Eric Botcazou
Index: elf32-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sparc.c,v
retrieving revision 1.76
diff -u -p -r1.76 elf32-sparc.c
--- elf32-sparc.c	21 Oct 2004 15:28:25 -0000	1.76
+++ elf32-sparc.c	6 Jan 2005 12:15:42 -0000
@@ -39,6 +39,8 @@ static bfd_boolean allocate_dynrelocs
   PARAMS ((struct elf_link_hash_entry *, PTR));
 static bfd_boolean readonly_dynrelocs
   PARAMS ((struct elf_link_hash_entry *, PTR));
+static bfd_boolean elf32_sparc_omit_section_dynsym
+  PARAMS ((bfd *, struct bfd_link_info *, asection *));
 static bfd_boolean elf32_sparc_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 static bfd_boolean elf32_sparc_new_section_hook
@@ -1814,6 +1816,23 @@ readonly_dynrelocs (h, inf)
   return TRUE;
 }
 
+/* Return true if the dynamic symbol for a given section should be
+   omitted when creating a shared library.  */
+
+static bfd_boolean
+elf32_sparc_omit_section_dynsym (bfd *output_bfd,
+				 struct bfd_link_info *info,
+				 asection *p)
+{
+  /* We keep the .got section symbol so that explicit relocations
+     against the _GLOBAL_OFFSET_TABLE_ symbol emitted in PIC mode
+     can be turned into relocations against the .got symbol.  */
+  if (strcmp (p->name, ".got") == 0)
+    return FALSE;
+
+  return _bfd_elf_link_omit_section_dynsym (output_bfd, info, p);
+}
+
 /* Set the sizes of the dynamic sections.  */
 
 static bfd_boolean
@@ -3448,6 +3467,7 @@ elf32_sparc_plt_sym_val (bfd_vma i ATTRI
 #define elf_backend_check_relocs	elf32_sparc_check_relocs
 #define elf_backend_adjust_dynamic_symbol \
 					elf32_sparc_adjust_dynamic_symbol
+#define elf_backend_omit_section_dynsym	elf32_sparc_omit_section_dynsym
 #define elf_backend_size_dynamic_sections \
 					elf32_sparc_size_dynamic_sections
 #define elf_backend_relocate_section	elf32_sparc_relocate_section
Index: elf64-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-sparc.c,v
retrieving revision 1.98
diff -u -p -r1.98 elf64-sparc.c
--- elf64-sparc.c	5 Jan 2005 15:24:56 -0000	1.98
+++ elf64-sparc.c	6 Jan 2005 12:15:43 -0000
@@ -56,6 +56,8 @@ static bfd_boolean sparc64_elf_check_rel
 	   const Elf_Internal_Rela *));
 static bfd_boolean sparc64_elf_adjust_dynamic_symbol
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static bfd_boolean sparc64_elf_omit_section_dynsym
+  PARAMS ((bfd *, struct bfd_link_info *, asection *));
 static bfd_boolean sparc64_elf_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 static int sparc64_elf_get_symbol_type
@@ -1760,6 +1762,23 @@ sparc64_elf_adjust_dynamic_symbol (info,
   return TRUE;
 }
 
+/* Return true if the dynamic symbol for a given section should be
+   omitted when creating a shared library.  */
+
+static bfd_boolean
+sparc64_elf_omit_section_dynsym (bfd *output_bfd,
+				 struct bfd_link_info *info,
+				 asection *p)
+{
+  /* We keep the .got section symbol so that explicit relocations
+     against the _GLOBAL_OFFSET_TABLE_ symbol emitted in PIC mode
+     can be turned into relocations against the .got symbol.  */
+  if (strcmp (p->name, ".got") == 0)
+    return FALSE;
+
+  return _bfd_elf_link_omit_section_dynsym (output_bfd, info, p);
+}
+
 /* Set the sizes of the dynamic sections.  */
 
 static bfd_boolean
@@ -3198,6 +3217,8 @@ const struct elf_size_info sparc64_elf_s
   sparc64_elf_check_relocs
 #define elf_backend_adjust_dynamic_symbol \
   sparc64_elf_adjust_dynamic_symbol
+#define elf_backend_omit_section_dynsym \
+  sparc64_elf_omit_section_dynsym
 #define elf_backend_size_dynamic_sections \
   sparc64_elf_size_dynamic_sections
 #define elf_backend_relocate_section \
Index: elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.166
diff -c -p -r1.166 elf-bfd.h
*** elf-bfd.h	10 Dec 2004 14:04:56 -0000	1.166
--- elf-bfd.h	6 Jan 2005 17:30:50 -0000
*************** struct elf_link_local_dynamic_entry
*** 245,250 ****
--- 245,254 ----
    /* The index of the local symbol being copied.  */
    long input_indx;
  
+   /* The section this symbol came from.  Note that it need be set
+      only if the section index of the input symbol is SHN_UNDEF.  */
+   asection *input_section;
+ 
    /* The index in the outgoing dynamic symbol table.  */
    long dynindx;
  
*************** extern bfd_boolean _bfd_elf_add_dynamic_
*** 1712,1717 ****
--- 1716,1725 ----
  extern bfd_boolean bfd_elf_link_record_dynamic_symbol
    (struct bfd_link_info *, struct elf_link_hash_entry *);
  
+ extern struct elf_link_local_dynamic_entry *
+   bfd_elf_link_create_local_dynamic_entry
+     (struct bfd_link_info *, bfd *, const char *, Elf_Internal_Sym *);
+ 
  extern int bfd_elf_link_record_local_dynamic_symbol
    (struct bfd_link_info *, bfd *, long);
  
Index: elf32-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sparc.c,v
retrieving revision 1.76
diff -c -p -r1.76 elf32-sparc.c
*** elf32-sparc.c	21 Oct 2004 15:28:25 -0000	1.76
--- elf32-sparc.c	6 Jan 2005 17:30:51 -0000
*************** elf32_sparc_link_hash_table_create (abfd
*** 693,699 ****
    struct elf32_sparc_link_hash_table *ret;
    bfd_size_type amt = sizeof (struct elf32_sparc_link_hash_table);
  
!   ret = (struct elf32_sparc_link_hash_table *) bfd_malloc (amt);
    if (ret == NULL)
      return NULL;
  
--- 693,699 ----
    struct elf32_sparc_link_hash_table *ret;
    bfd_size_type amt = sizeof (struct elf32_sparc_link_hash_table);
  
!   ret = (struct elf32_sparc_link_hash_table *) bfd_zmalloc (amt);
    if (ret == NULL)
      return NULL;
  
*************** elf32_sparc_link_hash_table_create (abfd
*** 703,717 ****
        return NULL;
      }
  
-   ret->sgot = NULL;
-   ret->srelgot = NULL;
-   ret->splt = NULL;
-   ret->srelplt = NULL;
-   ret->sdynbss = NULL;
-   ret->srelbss = NULL;
-   ret->tls_ldm_got.refcount = 0;
-   ret->sym_sec.abfd = NULL;
- 
    return &ret->elf.root;
  }
  
--- 703,708 ----
*************** create_got_section (dynobj, info)
*** 724,743 ****
       struct bfd_link_info *info;
  {
    struct elf32_sparc_link_hash_table *htab;
  
    if (! _bfd_elf_create_got_section (dynobj, info))
      return FALSE;
  
    htab = elf32_sparc_hash_table (info);
    htab->sgot = bfd_get_section_by_name (dynobj, ".got");
!   if (!htab->sgot)
!     abort ();
  
    htab->srelgot = bfd_make_section (dynobj, ".rela.got");
    if (htab->srelgot == NULL
        || ! bfd_set_section_flags (dynobj, htab->srelgot,
! 				  (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
! 				   | SEC_IN_MEMORY | SEC_LINKER_CREATED
  				   | SEC_READONLY))
        || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
      return FALSE;
--- 715,752 ----
       struct bfd_link_info *info;
  {
    struct elf32_sparc_link_hash_table *htab;
+   struct elf_link_local_dynamic_entry *entry;
+   Elf_Internal_Sym sym;
  
    if (! _bfd_elf_create_got_section (dynobj, info))
      return FALSE;
  
    htab = elf32_sparc_hash_table (info);
    htab->sgot = bfd_get_section_by_name (dynobj, ".got");
!   BFD_ASSERT (htab->sgot != NULL);
! 
!   /* Make sure _GLOBAL_OFFSET_TABLE_ is in the dynamic symbol table.
!      We need this because we emit explicit relocations against it
!      in PIC mode.  */
!   memset (&sym, 0, sizeof (sym));
!   sym.st_info = ELF_ST_TYPE (STT_OBJECT);
!   sym.st_other = STV_HIDDEN;
!   sym.st_shndx = SHN_UNDEF;
!   entry = bfd_elf_link_create_local_dynamic_entry (info, dynobj,
! 						   "_GLOBAL_OFFSET_TABLE_",
! 						   &sym);
!   entry->input_bfd = NULL;
!   entry->input_indx = 0;
!   entry->input_section = htab->sgot;
  
    htab->srelgot = bfd_make_section (dynobj, ".rela.got");
    if (htab->srelgot == NULL
        || ! bfd_set_section_flags (dynobj, htab->srelgot,
! 				  (SEC_ALLOC
! 				   | SEC_LOAD
! 				   | SEC_HAS_CONTENTS
! 				   | SEC_IN_MEMORY
! 				   | SEC_LINKER_CREATED
  				   | SEC_READONLY))
        || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
      return FALSE;
*************** elf32_sparc_relocate_section (output_bfd
*** 2450,2455 ****
--- 2459,2472 ----
  		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
  		  outrel.r_addend = rel->r_addend;
  		}
+ 	      else if (h == elf_hash_table (info)->hgot)
+ 	        {
+ 		  long dynindx
+ 		    = _bfd_elf_link_lookup_local_dynindx (info, NULL, 0);
+ 		  BFD_ASSERT (dynindx != -1);
+ 		  outrel.r_info = ELF32_R_INFO (dynindx, r_type);
+ 		  outrel.r_addend = rel->r_addend;
+ 		}
  	      else
  		{
  		  if (r_type == R_SPARC_32)
Index: elf64-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-sparc.c,v
retrieving revision 1.98
diff -c -p -r1.98 elf64-sparc.c
*** elf64-sparc.c	5 Jan 2005 15:24:56 -0000	1.98
--- elf64-sparc.c	6 Jan 2005 17:30:53 -0000
***************
*** 36,41 ****
--- 36,45 ----
  
  static struct bfd_link_hash_table * sparc64_elf_bfd_link_hash_table_create
    PARAMS ((bfd *));
+ static bfd_boolean create_got_section
+   PARAMS ((bfd *, struct bfd_link_info *));
+ static bfd_boolean sparc64_elf_create_dynamic_sections
+   PARAMS ((bfd *, struct bfd_link_info *));
  static bfd_reloc_status_type init_insn_reloc
    PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *,
  	   bfd *, bfd_vma *, bfd_vma *));
*************** struct sparc64_elf_link_hash_table
*** 736,741 ****
--- 740,749 ----
  {
    struct elf_link_hash_table root;
  
+   /* Short-cuts to get to dynamic linker sections.  */
+   asection *sgot;
+   asection *srelgot;
+ 
    struct sparc64_elf_app_reg app_regs [4];
  };
  
*************** sparc64_elf_bfd_link_hash_table_create (
*** 766,771 ****
--- 774,847 ----
  
    return &ret->root.root;
  }
+ 
+ /* Create .got and .rela.got sections in DYNOBJ and set up
+    shortcuts to them in our hash table.  */
+ 
+ static bfd_boolean
+ create_got_section (dynobj, info)
+      bfd *dynobj;
+      struct bfd_link_info *info;
+ {
+   struct sparc64_elf_link_hash_table *htab;
+   struct elf_link_local_dynamic_entry *entry;
+   Elf_Internal_Sym sym;
+ 
+   if (! _bfd_elf_create_got_section (dynobj, info))
+     return FALSE;
+ 
+   htab = sparc64_elf_hash_table (info);
+   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
+   BFD_ASSERT (htab->sgot != NULL);
+ 
+   /* Make sure _GLOBAL_OFFSET_TABLE_ is in the dynamic symbol table.
+      We need this because we emit explicit relocations against it
+      in PIC mode.  */
+   memset (&sym, 0, sizeof (sym));
+   sym.st_info = ELF_ST_TYPE (STT_OBJECT);
+   sym.st_other = STV_HIDDEN;
+   sym.st_shndx = SHN_UNDEF;
+   entry = bfd_elf_link_create_local_dynamic_entry (info, dynobj,
+ 						   "_GLOBAL_OFFSET_TABLE_",
+ 						   &sym);
+   entry->input_bfd = NULL;
+   entry->input_indx = 0;
+   entry->input_section = htab->sgot;
+ 
+   htab->srelgot = bfd_make_section (dynobj, ".rela.got");
+   if (htab->srelgot == NULL
+       || ! bfd_set_section_flags (dynobj, htab->srelgot,
+ 				  (SEC_ALLOC
+ 				   | SEC_LOAD
+ 				   | SEC_HAS_CONTENTS
+ 				   | SEC_IN_MEMORY
+ 				   | SEC_LINKER_CREATED
+ 				   | SEC_READONLY))
+       || ! bfd_set_section_alignment (dynobj, htab->srelgot, 3))
+     return FALSE;
+   return TRUE;
+ }
+ 
+ /* Create .plt, .rela.plt, .got, .rela.got, .dynbss, and
+    .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
+    hash table.  */
+ 
+ static bfd_boolean
+ sparc64_elf_create_dynamic_sections (dynobj, info)
+      bfd *dynobj;
+      struct bfd_link_info *info;
+ {
+   struct sparc64_elf_link_hash_table *htab;
+ 
+   htab = sparc64_elf_hash_table (info);
+   if (!htab->sgot && !create_got_section (dynobj, info))
+     return FALSE;
+ 
+   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+     return FALSE;
+ 
+   return TRUE;
+ }
  
  /* Utility for performing the standard initial work of an instruction
     relocation.
*************** sparc64_elf_check_relocs (abfd, info, se
*** 1135,1169 ****
  
  	  if (dynobj == NULL)
  	    {
! 	      /* Create the .got section.  */
  	      elf_hash_table (info)->dynobj = dynobj = abfd;
! 	      if (! _bfd_elf_create_got_section (dynobj, info))
  		return FALSE;
  	    }
  
  	  if (sgot == NULL)
  	    {
! 	      sgot = bfd_get_section_by_name (dynobj, ".got");
  	      BFD_ASSERT (sgot != NULL);
  	    }
  
  	  if (srelgot == NULL && (h != NULL || info->shared))
  	    {
! 	      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
! 	      if (srelgot == NULL)
! 		{
! 		  srelgot = bfd_make_section (dynobj, ".rela.got");
! 		  if (srelgot == NULL
! 		      || ! bfd_set_section_flags (dynobj, srelgot,
! 						  (SEC_ALLOC
! 						   | SEC_LOAD
! 						   | SEC_HAS_CONTENTS
! 						   | SEC_IN_MEMORY
! 						   | SEC_LINKER_CREATED
! 						   | SEC_READONLY))
! 		      || ! bfd_set_section_alignment (dynobj, srelgot, 3))
! 		    return FALSE;
! 		}
  	    }
  
  	  if (h != NULL)
--- 1211,1232 ----
  
  	  if (dynobj == NULL)
  	    {
! 	      /* Create the .got and .rela.got sections.  */
  	      elf_hash_table (info)->dynobj = dynobj = abfd;
! 	      if (! create_got_section (dynobj, info))
  		return FALSE;
  	    }
  
  	  if (sgot == NULL)
  	    {
! 	      sgot = sparc64_elf_hash_table (info)->sgot;
  	      BFD_ASSERT (sgot != NULL);
  	    }
  
  	  if (srelgot == NULL && (h != NULL || info->shared))
  	    {
! 	      srelgot = sparc64_elf_hash_table (info)->srelgot;
! 	      BFD_ASSERT (srelgot != NULL);
  	    }
  
  	  if (h != NULL)
*************** sparc64_elf_size_dynamic_sections (outpu
*** 1792,1798 ****
           not actually use these entries.  Reset the size of .rela.got,
           which will cause it to get stripped from the output file
           below.  */
!       s = bfd_get_section_by_name (dynobj, ".rela.got");
        if (s != NULL)
  	s->size = 0;
      }
--- 1855,1861 ----
           not actually use these entries.  Reset the size of .rela.got,
           which will cause it to get stripped from the output file
           below.  */
!       s = sparc64_elf_hash_table (info)->srelgot;
        if (s != NULL)
  	s->size = 0;
      }
*************** sparc64_elf_relocate_section (output_bfd
*** 2229,2234 ****
--- 2292,2309 ----
  							   r_type));
  		    outrel.r_addend = rel->r_addend;
  		  }
+ 		else if (h == elf_hash_table (info)->hgot)
+ 	          {
+ 		    long dynindx
+ 		      = _bfd_elf_link_lookup_local_dynindx (info, NULL, 0);
+ 		    BFD_ASSERT (dynindx != -1);
+ 		    outrel.r_info
+ 		      = ELF64_R_INFO (dynindx,
+ 				      ELF64_R_TYPE_INFO (
+ 					ELF64_R_TYPE_DATA (rel->r_info),
+ 							   r_type));
+ 		    outrel.r_addend = rel->r_addend;
+ 		  }
  		else
  		  {
  		    outrel.r_addend = relocation + rel->r_addend;
*************** sparc64_elf_relocate_section (output_bfd
*** 2305,2311 ****
  	     offset table.  */
  	  if (sgot == NULL)
  	    {
! 	      sgot = bfd_get_section_by_name (dynobj, ".got");
  	      BFD_ASSERT (sgot != NULL);
  	    }
  
--- 2380,2386 ----
  	     offset table.  */
  	  if (sgot == NULL)
  	    {
! 	      sgot = sparc64_elf_hash_table (info)->sgot;
  	      BFD_ASSERT (sgot != NULL);
  	    }
  
*************** sparc64_elf_relocate_section (output_bfd
*** 2379,2385 ****
  
  		      /* We need to generate a R_SPARC_RELATIVE reloc
  			 for the dynamic linker.  */
! 		      s = bfd_get_section_by_name(dynobj, ".rela.got");
  		      BFD_ASSERT (s != NULL);
  
  		      outrel.r_offset = (sgot->output_section->vma
--- 2454,2460 ----
  
  		      /* We need to generate a R_SPARC_RELATIVE reloc
  			 for the dynamic linker.  */
! 		      s = sparc64_elf_hash_table (info)->srelgot;
  		      BFD_ASSERT (s != NULL);
  
  		      outrel.r_offset = (sgot->output_section->vma
*************** sparc64_elf_finish_dynamic_symbol (outpu
*** 2760,2767 ****
  
        /* This symbol has an entry in the GOT.  Set it up.  */
  
!       sgot = bfd_get_section_by_name (dynobj, ".got");
!       srela = bfd_get_section_by_name (dynobj, ".rela.got");
        BFD_ASSERT (sgot != NULL && srela != NULL);
  
        rela.r_offset = (sgot->output_section->vma
--- 2835,2842 ----
  
        /* This symbol has an entry in the GOT.  Set it up.  */
  
!       sgot = sparc64_elf_hash_table (info)->sgot;
!       srela = sparc64_elf_hash_table (info)->srelgot;
        BFD_ASSERT (sgot != NULL && srela != NULL);
  
        rela.r_offset = (sgot->output_section->vma
*************** sparc64_elf_finish_dynamic_sections (out
*** 2909,2915 ****
  
    /* Set the first entry in the global offset table to the address of
       the dynamic section.  */
!   sgot = bfd_get_section_by_name (dynobj, ".got");
    BFD_ASSERT (sgot != NULL);
    if (sgot->size > 0)
      {
--- 2984,2990 ----
  
    /* Set the first entry in the global offset table to the address of
       the dynamic section.  */
!   sgot = sparc64_elf_hash_table (info)->sgot;
    BFD_ASSERT (sgot != NULL);
    if (sgot->size > 0)
      {
*************** const struct elf_size_info sparc64_elf_s
*** 3187,3193 ****
    sparc64_elf_new_section_hook
  
  #define elf_backend_create_dynamic_sections \
!   _bfd_elf_create_dynamic_sections
  #define elf_backend_add_symbol_hook \
    sparc64_elf_add_symbol_hook
  #define elf_backend_get_symbol_type \
--- 3262,3268 ----
    sparc64_elf_new_section_hook
  
  #define elf_backend_create_dynamic_sections \
!   sparc64_elf_create_dynamic_sections
  #define elf_backend_add_symbol_hook \
    sparc64_elf_add_symbol_hook
  #define elf_backend_get_symbol_type \
Index: elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.122
diff -c -p -r1.122 elflink.c
*** elflink.c	22 Dec 2004 03:59:26 -0000	1.122
--- elflink.c	6 Jan 2005 17:30:57 -0000
*************** bfd_elf_record_link_assignment (bfd *out
*** 488,493 ****
--- 488,536 ----
    return TRUE;
  }
  
+ /* Create a new local dynamic entry for the specified symbol.
+    Return the entry on success or NULL on failure.  */
+ 
+ struct elf_link_local_dynamic_entry *
+ bfd_elf_link_create_local_dynamic_entry (struct bfd_link_info *info,
+ 					 bfd *input_bfd,
+ 					 const char *name,
+ 					 Elf_Internal_Sym *sym)
+ {
+   struct elf_link_local_dynamic_entry *entry;
+   struct elf_link_hash_table *eht;
+   bfd_size_type dynstr_index;
+ 
+   entry = bfd_alloc (input_bfd, sizeof (*entry));
+   if (entry == NULL)
+     return NULL;
+ 
+   eht = elf_hash_table (info);
+   if (eht->dynstr == NULL)
+     {
+       /* Create a strtab to hold the dynamic symbol names.  */
+       eht->dynstr = _bfd_elf_strtab_init ();
+       if (eht->dynstr == NULL)
+ 	return NULL;
+     }
+ 
+   dynstr_index = _bfd_elf_strtab_add (eht->dynstr, name, FALSE);
+   if (dynstr_index == (bfd_size_type) -1)
+     return NULL;
+ 
+   entry->next = eht->dynlocal;
+   eht->dynlocal = entry;
+   eht->dynsymcount++;
+ 
+   /* Whatever binding the symbol had before, it's now local.  */
+   memcpy (&entry->isym, sym, sizeof (*sym));
+   entry->isym.st_name = dynstr_index;
+   entry->isym.st_info
+     = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info));
+ 
+   return entry;
+ }
+ 
  /* Record a new local dynamic symbol.  Returns 0 on failure, 1 on
     success, and 2 on a failure caused by attempting to record a symbol
     in a discarded section, eg. a discarded link-once section symbol.  */
*************** bfd_elf_link_record_local_dynamic_symbol
*** 497,508 ****
  					  bfd *input_bfd,
  					  long input_indx)
  {
-   bfd_size_type amt;
    struct elf_link_local_dynamic_entry *entry;
-   struct elf_link_hash_table *eht;
-   struct elf_strtab_hash *dynstr;
-   unsigned long dynstr_index;
    char *name;
    Elf_External_Sym_Shndx eshndx;
    char esym[sizeof (Elf64_External_Sym)];
  
--- 540,548 ----
  					  bfd *input_bfd,
  					  long input_indx)
  {
    struct elf_link_local_dynamic_entry *entry;
    char *name;
+   Elf_Internal_Sym isym;
    Elf_External_Sym_Shndx eshndx;
    char esym[sizeof (Elf64_External_Sym)];
  
*************** bfd_elf_link_record_local_dynamic_symbol
*** 514,578 ****
      if (entry->input_bfd == input_bfd && entry->input_indx == input_indx)
        return 1;
  
-   amt = sizeof (*entry);
-   entry = bfd_alloc (input_bfd, amt);
-   if (entry == NULL)
-     return 0;
- 
    /* Go find the symbol, so that we can find it's name.  */
    if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr,
! 			     1, input_indx, &entry->isym, esym, &eshndx))
!     {
!       bfd_release (input_bfd, entry);
!       return 0;
!     }
  
!   if (entry->isym.st_shndx != SHN_UNDEF
!       && (entry->isym.st_shndx < SHN_LORESERVE
! 	  || entry->isym.st_shndx > SHN_HIRESERVE))
      {
        asection *s;
  
!       s = bfd_section_from_elf_index (input_bfd, entry->isym.st_shndx);
        if (s == NULL || bfd_is_abs_section (s->output_section))
! 	{
! 	  /* We can still bfd_release here as nothing has done another
! 	     bfd_alloc.  We can't do this later in this function.  */
! 	  bfd_release (input_bfd, entry);
! 	  return 2;
! 	}
      }
  
    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_strtab_init ();
!       if (dynstr == NULL)
! 	return 0;
!     }
! 
!   dynstr_index = _bfd_elf_strtab_add (dynstr, name, FALSE);
!   if (dynstr_index == (unsigned long) -1)
      return 0;
-   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++;
! 
!   /* Whatever binding the symbol had before, it's now local.  */
!   entry->isym.st_info
!     = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info));
! 
    /* The dynindx will be set at the end of size_dynamic_sections.  */
  
    return 1;
--- 554,587 ----
      if (entry->input_bfd == input_bfd && entry->input_indx == input_indx)
        return 1;
  
    /* Go find the symbol, so that we can find it's name.  */
    if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr,
! 			     1, input_indx, &isym, esym, &eshndx))
!     return 0;
  
!   if (isym.st_shndx != SHN_UNDEF
!       && (isym.st_shndx < SHN_LORESERVE
! 	  || isym.st_shndx > SHN_HIRESERVE))
      {
        asection *s;
  
!       s = bfd_section_from_elf_index (input_bfd, isym.st_shndx);
        if (s == NULL || bfd_is_abs_section (s->output_section))
! 	return 2;
      }
  
    name = (bfd_elf_string_from_elf_section
  	  (input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link,
! 	   isym.st_name));
  
!   entry = bfd_elf_link_create_local_dynamic_entry (info, input_bfd, name,
! 						   &isym);
!   if (!entry)
      return 0;
  
    entry->input_bfd = input_bfd;
    entry->input_indx = input_indx;
!   entry->input_section = NULL;
    /* The dynindx will be set at the end of size_dynamic_sections.  */
  
    return 1;
*************** bfd_elf_final_link (bfd *abfd, struct bf
*** 8065,8071 ****
  	  struct elf_link_local_dynamic_entry *e;
  	  for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
  	    {
! 	      asection *s;
  	      bfd_byte *dest;
  
  	      sym.st_size = e->isym.st_size;
--- 8074,8080 ----
  	  struct elf_link_local_dynamic_entry *e;
  	  for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
  	    {
! 	      asection *s = NULL;
  	      bfd_byte *dest;
  
  	      sym.st_size = e->isym.st_size;
*************** bfd_elf_final_link (bfd *abfd, struct bf
*** 8079,8088 ****
  	      if (e->isym.st_shndx != SHN_UNDEF
  		  && (e->isym.st_shndx < SHN_LORESERVE
  		      || e->isym.st_shndx > SHN_HIRESERVE))
! 		{
! 		  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
--- 8088,8101 ----
  	      if (e->isym.st_shndx != SHN_UNDEF
  		  && (e->isym.st_shndx < SHN_LORESERVE
  		      || e->isym.st_shndx > SHN_HIRESERVE))
! 		s = bfd_section_from_elf_index (e->input_bfd,
! 						e->isym.st_shndx);
! 	      else if (e->isym.st_shndx == SHN_UNDEF
! 		       && e->input_section)
! 		s = e->input_section;
  
+ 	      if (s)
+ 	        {
  		  sym.st_shndx =
  		    elf_section_data (s->output_section)->this_idx;
  		  sym.st_value = (s->output_section->vma

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