This is the mail archive of the binutils@sourceware.org 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: x86 ifunc related excessive memory use


On Thu, Jun 18, 2009 at 05:52:45AM -0700, H.J. Lu wrote:
> On Thu, Jun 18, 2009 at 5:24 AM, Alan Modra<amodra@bigpond.net.au> wrote:
> > HJ, since your ifunc patches I can't even run "make check" on my x86
> > box successfully.
> >
> > tmpdir/dump53.o: could not read symbols: Memory exhausted
> > FAIL: ld-elf/64ksec
> >
> > A quick look says it is likely to be the fact that you don't free
> > isymbuf in check_relocs.
> >
> 
> I checked in this fix.

Thanks, that's better.  Reading the syms for each section processed
was a little excessive.  :)

You might like to use bfd_sym_from_r_symndx instead of reading
all the locals in check_relocs.  It's a small change I made as part
of implementing ifunc support for powerpc.

If you decide to stay with reading all the locals then you probably
ought to get rid of bfd_sym_from_r_symndx in the x86 and x86_64
check_relocs.

	* elf-bfd.h (struct sym_sec_cache): Delete.
	(struct sym_cache): New.
	(bfd_section_from_r_symndx): Delete prototype.
	(bfd_sym_from_r_symndx): Define prototype.
	* elf.c (bfd_section_from_r_symndx): Delete, replace with..
	(bfd_sym_from_r_symndx): ..new function.
	* elf32-arm.c: Update all uses of struct sym_sec_cache and
	bfd_section_from_r_symndx to new struct and function.
	* elf32-bfin.c: Likewise.
	* elf32-hppa.c: Likewise.
	* elf32-i386.c: Likewise.
	* elf32-m32r.c: Likewise.
	* elf32-m68hc1x.c: Likewise.
	* elf32-m68hc1x.h: Likewise.
	* elf32-m68k.c: Likewise.
	* elf32-ppc.c: Likewise.
	* elf32-s390.c: Likewise.
	* elf32-sh.c: Likewise.
	* elf64-ppc.c: Likewise.
	* elf64-s390.c: Likewise.
	* elf64-x86-64.c: Likewise.
	* elfxx-sparc.c: Likewise.
	* elfxx-sparc.h: Likewise.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.289
diff -u -p -r1.289 elf-bfd.h
--- bfd/elf-bfd.h	18 Jun 2009 00:45:14 -0000	1.289
+++ bfd/elf-bfd.h	18 Jun 2009 13:58:42 -0000
@@ -493,14 +493,14 @@ struct elf_link_hash_table
 #define is_elf_hash_table(htab)					      	\
   (((struct bfd_link_hash_table *) (htab))->type == bfd_link_elf_hash_table)
 
-/* Used by bfd_section_from_r_symndx to cache a small number of local
-   symbol to section mappings.  */
+/* Used by bfd_sym_from_r_symndx to cache a small number of local
+   symbols.  */
 #define LOCAL_SYM_CACHE_SIZE 32
-struct sym_sec_cache
+struct sym_cache
 {
   bfd *abfd;
   unsigned long indx[LOCAL_SYM_CACHE_SIZE];
-  unsigned int shndx[LOCAL_SYM_CACHE_SIZE];
+  Elf_Internal_Sym sym[LOCAL_SYM_CACHE_SIZE];
 };
 
 /* Constant information held for an ELF backend.  */
@@ -1807,8 +1807,8 @@ extern bfd_boolean bfd_section_from_phdr
 extern int _bfd_elf_symbol_from_bfd_symbol
   (bfd *, asymbol **);
 
-extern asection *bfd_section_from_r_symndx
-  (bfd *, struct sym_sec_cache *, asection *, unsigned long);
+extern Elf_Internal_Sym *bfd_sym_from_r_symndx 
+  (struct sym_cache *, bfd *, unsigned long);
 extern asection *bfd_section_from_elf_index
   (bfd *, unsigned int);
 extern struct bfd_strtab_hash *_bfd_elf_stringtab_init
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.481
diff -u -p -r1.481 elf.c
--- bfd/elf.c	30 Apr 2009 15:47:09 -0000	1.481
+++ bfd/elf.c	18 Jun 2009 13:58:50 -0000
@@ -1921,28 +1921,24 @@ bfd_section_from_shdr (bfd *abfd, unsign
   return TRUE;
 }
 
-/* Return the section for the local symbol specified by ABFD, R_SYMNDX.
-   Return SEC for sections that have no elf section, and NULL on error.  */
+/* Return the local symbol specified by ABFD, R_SYMNDX.  */
 
-asection *
-bfd_section_from_r_symndx (bfd *abfd,
-			   struct sym_sec_cache *cache,
-			   asection *sec,
-			   unsigned long r_symndx)
+Elf_Internal_Sym *
+bfd_sym_from_r_symndx (struct sym_cache *cache,
+		       bfd *abfd,
+		       unsigned long r_symndx)
 {
   unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
-  asection *s;
 
   if (cache->abfd != abfd || cache->indx[ent] != r_symndx)
     {
       Elf_Internal_Shdr *symtab_hdr;
       unsigned char esym[sizeof (Elf64_External_Sym)];
       Elf_External_Sym_Shndx eshndx;
-      Elf_Internal_Sym isym;
 
       symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
       if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
-				&isym, esym, &eshndx) == NULL)
+				&cache->sym[ent], esym, &eshndx) == NULL)
 	return NULL;
 
       if (cache->abfd != abfd)
@@ -1951,14 +1947,9 @@ bfd_section_from_r_symndx (bfd *abfd,
 	  cache->abfd = abfd;
 	}
       cache->indx[ent] = r_symndx;
-      cache->shndx[ent] = isym.st_shndx;
     }
 
-  s = bfd_section_from_elf_index (abfd, cache->shndx[ent]);
-  if (s != NULL)
-    return s;
-
-  return sec;
+  return &cache->sym[ent];
 }
 
 /* Given an ELF section number, retrieve the corresponding BFD
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.200
diff -u -p -r1.200 elf32-arm.c
--- bfd/elf32-arm.c	17 Jun 2009 18:08:34 -0000	1.200
+++ bfd/elf32-arm.c	18 Jun 2009 13:58:54 -0000
@@ -2618,8 +2618,8 @@ struct elf32_arm_link_hash_table
     bfd_vma offset;
   } tls_ldm_got;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 
   /* For convenience in allocate_dynrelocs.  */
   bfd * obfd;
@@ -2921,7 +2921,7 @@ elf32_arm_link_hash_table_create (bfd *a
   ret->vxworks_p = 0;
   ret->symbian_p = 0;
   ret->use_rel = 1;
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
   ret->obfd = abfd;
   ret->tls_ldm_got.refcount = 0;
   ret->stub_bfd = NULL;
@@ -10836,15 +10836,19 @@ elf32_arm_check_relocs (bfd *abfd, struc
 		    /* Track dynamic relocs needed for local syms too.
 		       We really need local syms available to do this
 		       easily.  Oh well.  */
-
 		    asection *s;
 		    void *vpp;
+		    Elf_Internal_Sym *isym;
 
-		    s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						   sec, r_symndx);
-		    if (s == NULL)
+		    isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						  abfd, r_symndx);
+		    if (isym == NULL)
 		      return FALSE;
 
+		    s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		    if (s == NULL)
+		      s = sec;
+
 		    vpp = &elf_section_data (s)->local_dynrel;
 		    head = (struct elf32_arm_relocs_copied **) vpp;
 		  }
Index: bfd/elf32-bfin.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-bfin.c,v
retrieving revision 1.36
diff -u -p -r1.36 elf32-bfin.c
--- bfd/elf32-bfin.c	10 May 2009 23:33:50 -0000	1.36
+++ bfd/elf32-bfin.c	18 Jun 2009 13:58:57 -0000
@@ -4966,8 +4966,8 @@ struct bfin_link_hash_table
 {
   struct elf_link_hash_table root;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 };
 
 #define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
@@ -5013,7 +5013,7 @@ bfin_link_hash_table_create (bfd * abfd)
       return NULL;
     }
 
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
 
   return &ret->root.root;
 }
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.167
diff -u -p -r1.167 elf32-hppa.c
--- bfd/elf32-hppa.c	17 Jun 2009 18:08:34 -0000	1.167
+++ bfd/elf32-hppa.c	18 Jun 2009 13:58:59 -0000
@@ -301,8 +301,8 @@ struct elf32_hppa_link_hash_table
   /* Set if we need a .plt stub to support lazy dynamic linking.  */
   unsigned int need_plt_stub:1;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 
   /* Data for LDM relocations.  */
   union
@@ -460,7 +460,7 @@ elf32_hppa_link_hash_table_create (bfd *
   htab->has_17bit_branch = 0;
   htab->has_22bit_branch = 0;
   htab->need_plt_stub = 0;
-  htab->sym_sec.abfd = NULL;
+  htab->sym_cache.abfd = NULL;
   htab->tls_ldm_got.refcount = 0;
 
   return &htab->etab.root;
@@ -1522,15 +1522,19 @@ elf32_hppa_check_relocs (bfd *abfd,
 		  /* Track dynamic relocs needed for local syms too.
 		     We really need local syms available to do this
 		     easily.  Oh well.  */
-
 		  asection *sr;
 		  void *vpp;
+		  Elf_Internal_Sym *isym;
 
-		  sr = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						       sec, r_symndx);
-		  if (sr == NULL)
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
 		    return FALSE;
 
+		  sr = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (sr == NULL)
+		    sr = sec;
+
 		  vpp = &elf_section_data (sr)->local_dynrel;
 		  hdh_head = (struct elf32_hppa_dyn_reloc_entry **) vpp;
 		}
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.214
diff -u -p -r1.214 elf32-i386.c
--- bfd/elf32-i386.c	18 Jun 2009 12:49:41 -0000	1.214
+++ bfd/elf32-i386.c	18 Jun 2009 13:59:01 -0000
@@ -674,8 +674,8 @@ struct elf_i386_link_hash_table
      section, plus whatever space is used by the jump slots.  */
   bfd_vma sgotplt_jump_table_size;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 
   /* _TLS_MODULE_BASE_ symbol.  */
   struct bfd_link_hash_entry *tls_module_base;
@@ -819,7 +819,7 @@ elf_i386_link_hash_table_create (bfd *ab
   ret->tls_ldm_got.refcount = 0;
   ret->next_tls_desc_index = 0;
   ret->sgotplt_jump_table_size = 0;
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
   ret->is_vxworks = 0;
   ret->srelplt2 = NULL;
   ret->plt0_pad_byte = 0;
@@ -1650,16 +1650,21 @@ elf_i386_check_relocs (bfd *abfd,
 		}
 	      else
 		{
-		  void **vpp;
 		  /* Track dynamic relocs needed for local syms too.
 		     We really need local syms available to do this
 		     easily.  Oh well.  */
-
+		  void **vpp;
 		  asection *s;
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						 sec, r_symndx);
+		  Elf_Internal_Sym *isym;
+
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
+		    return FALSE;
+
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
 		  if (s == NULL)
-		    goto error_return;
+		    s = sec;
 
 		  vpp = &elf_section_data (s)->local_dynrel;
 		  head = (struct elf_dyn_relocs **)vpp;
Index: bfd/elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.93
diff -u -p -r1.93 elf32-m32r.c
--- bfd/elf32-m32r.c	17 Jun 2009 18:08:34 -0000	1.93
+++ bfd/elf32-m32r.c	18 Jun 2009 13:59:04 -0000
@@ -1526,8 +1526,8 @@ struct elf_m32r_link_hash_table
   asection *sdynbss;
   asection *srelbss;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 };
 
 /* Traverse an m32r ELF linker hash table.  */
@@ -1604,7 +1604,7 @@ m32r_elf_link_hash_table_create (bfd *ab
   ret->srelplt = NULL;
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
 
   return &ret->root.root;
 }
@@ -3941,14 +3941,19 @@ m32r_elf_check_relocs (bfd *abfd,
                 head = &((struct elf_m32r_link_hash_entry *) h)->dyn_relocs;
               else
                 {
+                  /* Track dynamic relocs needed for local syms too.  */
                   asection *s;
                   void *vpp;
+		  Elf_Internal_Sym *isym;
 
-                  /* Track dynamic relocs needed for local syms too.  */
-                  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-                                                 sec, r_symndx);
-                  if (s == NULL)
-                    return FALSE;
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
+		    return FALSE;
+
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (s == NULL)
+		    s = sec;
 
 		  vpp = &elf_section_data (s)->local_dynrel;
                   head = (struct elf_m32r_dyn_relocs **) vpp;
Index: bfd/elf32-m68hc1x.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68hc1x.c,v
retrieving revision 1.34
diff -u -p -r1.34 elf32-m68hc1x.c
--- bfd/elf32-m68hc1x.c	18 Mar 2009 11:27:17 -0000	1.34
+++ bfd/elf32-m68hc1x.c	18 Jun 2009 13:59:04 -0000
@@ -95,7 +95,7 @@ m68hc11_elf_hash_table_create (bfd *abfd
   ret->stub_bfd = NULL;
   ret->stub_section = 0;
   ret->add_stub_section = NULL;
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
 
   return ret;
 }
Index: bfd/elf32-m68hc1x.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68hc1x.h,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-m68hc1x.h
--- bfd/elf32-m68hc1x.h	3 Jul 2007 14:26:41 -0000	1.8
+++ bfd/elf32-m68hc1x.h	18 Jun 2009 13:59:04 -0000
@@ -120,8 +120,8 @@ struct m68hc11_elf_link_hash_table
   int top_index;
   asection **input_list;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 
   bfd_boolean (* size_one_stub) PARAMS((struct bfd_hash_entry*, void*));
   bfd_boolean (* build_one_stub) PARAMS((struct bfd_hash_entry*, void*));
Index: bfd/elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.111
diff -u -p -r1.111 elf32-m68k.c
--- bfd/elf32-m68k.c	3 Feb 2009 14:36:46 -0000	1.111
+++ bfd/elf32-m68k.c	18 Jun 2009 13:59:06 -0000
@@ -909,8 +909,8 @@ struct elf_m68k_link_hash_table
 {
   struct elf_link_hash_table root;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 
   /* The PLT format used by this link, or NULL if the format has not
      yet been chosen.  */
@@ -989,7 +989,7 @@ elf_m68k_link_hash_table_create (abfd)
       return NULL;
     }
 
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
   ret->plt_info = NULL;
   ret->local_gp_p = FALSE;
   ret->use_neg_got_offsets_p = FALSE;
@@ -2793,13 +2793,17 @@ elf_m68k_check_relocs (abfd, info, sec, 
 		    {
 		      asection *s;
 		      void *vpp;
+		      Elf_Internal_Sym *isym;
 
-		      s = (bfd_section_from_r_symndx
-			   (abfd, &elf_m68k_hash_table (info)->sym_sec,
-			    sec, r_symndx));
-		      if (s == NULL)
+		      isym = bfd_sym_from_r_symndx (&elf_m68k_hash_table (info)->sym_cache,
+						    abfd, r_symndx);
+		      if (isym == NULL)
 			return FALSE;
 
+		      s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		      if (s == NULL)
+			s = sec;
+
 		      vpp = &elf_section_data (s)->local_dynrel;
 		      head = (struct elf_m68k_pcrel_relocs_copied **) vpp;
 		    }
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.255
diff -u -p -r1.255 elf32-ppc.c
--- bfd/elf32-ppc.c	17 Jun 2009 18:08:34 -0000	1.255
+++ bfd/elf32-ppc.c	18 Jun 2009 13:59:11 -0000
@@ -2735,8 +2735,8 @@ struct ppc_elf_link_hash_table
   /* The size of the first PLT entry.  */
   int plt_initial_entry_size;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 };
 
 /* Get the PPC ELF linker hash table from a link_info structure.  */
@@ -3713,9 +3713,14 @@ ppc_elf_check_relocs (bfd *abfd,
 		 reliably deduce the GOT pointer value needed for
 		 PLT call stubs.  */
 	      asection *s;
+	      Elf_Internal_Sym *isym;
 
-	      s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
-					     r_symndx);
+	      isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+					    abfd, r_symndx);
+	      if (isym == NULL)
+		return FALSE;
+
+	      s = bfd_section_from_elf_index (abfd, isym->st_shndx);
 	      if (s == got2)
 		{
 		  htab->plt_type = PLT_OLD;
@@ -3843,15 +3848,19 @@ ppc_elf_check_relocs (bfd *abfd,
 		  /* Track dynamic relocs needed for local syms too.
 		     We really need local syms available to do this
 		     easily.  Oh well.  */
-
 		  asection *s;
 		  void *vpp;
+		  Elf_Internal_Sym *isym;
 
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						 sec, r_symndx);
-		  if (s == NULL)
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
 		    return FALSE;
 
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (s == NULL)
+		    s = sec;
+
 		  vpp = &elf_section_data (s)->local_dynrel;
 		  head = (struct ppc_elf_dyn_relocs **) vpp;
 		}
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.100
diff -u -p -r1.100 elf32-s390.c
--- bfd/elf32-s390.c	17 Jun 2009 18:08:35 -0000	1.100
+++ bfd/elf32-s390.c	18 Jun 2009 13:59:12 -0000
@@ -730,8 +730,8 @@ struct elf_s390_link_hash_table
     bfd_vma offset;
   } tls_ldm_got;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 };
 
 /* Get the s390 ELF linker hash table from a link_info structure.  */
@@ -800,7 +800,7 @@ elf_s390_link_hash_table_create (abfd)
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
   ret->tls_ldm_got.refcount = 0;
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
 
   return &ret->elf.root;
 }
@@ -1294,12 +1294,17 @@ elf_s390_check_relocs (abfd, info, sec, 
 		     easily.  Oh well.  */
 		  asection *s;
 		  void *vpp;
+		  Elf_Internal_Sym *isym;
 
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						 sec, r_symndx);
-		  if (s == NULL)
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
 		    return FALSE;
 
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (s == NULL)
+		    s = sec;
+
 		  vpp = &elf_section_data (s)->local_dynrel;
 		  head = (struct elf_s390_dyn_relocs **) vpp;
 		}
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.159
diff -u -p -r1.159 elf32-sh.c
--- bfd/elf32-sh.c	17 Jun 2009 18:08:35 -0000	1.159
+++ bfd/elf32-sh.c	18 Jun 2009 13:59:17 -0000
@@ -2187,8 +2187,8 @@ struct elf_sh_link_hash_table
   /* The (unloaded but important) VxWorks .rela.plt.unloaded section.  */
   asection *srelplt2;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 
   /* A counter or offset to track a TLS got entry.  */
   union
@@ -2281,7 +2281,7 @@ sh_elf_link_hash_table_create (bfd *abfd
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
   ret->srelplt2 = NULL;
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
   ret->tls_ldm_got.refcount = 0;
   ret->plt_info = NULL;
   ret->vxworks_p = vxworks_object_p (abfd);
@@ -5203,15 +5203,20 @@ sh_elf_check_relocs (bfd *abfd, struct b
 		head = &((struct elf_sh_link_hash_entry *) h)->dyn_relocs;
 	      else
 		{
+		  /* Track dynamic relocs needed for local syms too.  */
 		  asection *s;
 		  void *vpp;
+		  Elf_Internal_Sym *isym;
 
-		  /* Track dynamic relocs needed for local syms too.  */
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						 sec, r_symndx);
-		  if (s == NULL)
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
 		    return FALSE;
 
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (s == NULL)
+		    s = sec;
+
 		  vpp = &elf_section_data (s)->local_dynrel;
 		  head = (struct elf_sh_dyn_relocs **) vpp;
 		}
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.295
diff -u -p -r1.295 elf64-ppc.c
--- bfd/elf64-ppc.c	21 May 2009 14:15:48 -0000	1.295
+++ bfd/elf64-ppc.c	18 Jun 2009 13:59:21 -0000
@@ -3671,8 +3671,8 @@ struct ppc_link_hash_table
   /* Incremented every time we size stubs.  */
   unsigned int stub_iteration;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 };
 
 /* Rename some of the generic section flags to better document how they
@@ -4897,8 +4897,17 @@ ppc64_elf_check_relocs (bfd *abfd, struc
 		  dest = h->root.u.def.section;
 	      }
 	    else
-	      dest = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						sec, r_symndx);
+	      {
+		Elf_Internal_Sym *isym;
+
+		isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+					      abfd, r_symndx);
+		if (isym == NULL)
+		  return FALSE;
+
+		dest = bfd_section_from_elf_index (abfd, isym->st_shndx);
+	      }
+
 	    if (dest != sec)
 	      ppc64_elf_section_data (sec)->has_14bit_branch = 1;
 	  }
@@ -5018,12 +5027,15 @@ ppc64_elf_check_relocs (bfd *abfd, struc
 	      else
 		{
 		  asection *s;
+		  Elf_Internal_Sym *isym;
 
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
-						 r_symndx);
-		  if (s == NULL)
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
 		    return FALSE;
-		  else if (s != sec)
+
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (s != NULL && s != sec)
 		    opd_sym_map[rel->r_offset / 8] = s;
 		}
 	    }
@@ -5119,15 +5131,19 @@ ppc64_elf_check_relocs (bfd *abfd, struc
 		  /* Track dynamic relocs needed for local syms too.
 		     We really need local syms available to do this
 		     easily.  Oh well.  */
-
 		  asection *s;
 		  void *vpp;
+		  Elf_Internal_Sym *isym;
 
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						 sec, r_symndx);
-		  if (s == NULL)
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
 		    return FALSE;
 
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (s == NULL)
+		    s = sec;
+
 		  vpp = &elf_section_data (s)->local_dynrel;
 		  head = (struct ppc_dyn_relocs **) vpp;
 		}
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.102
diff -u -p -r1.102 elf64-s390.c
--- bfd/elf64-s390.c	17 Jun 2009 18:08:35 -0000	1.102
+++ bfd/elf64-s390.c	18 Jun 2009 13:59:23 -0000
@@ -685,8 +685,8 @@ struct elf_s390_link_hash_table
     bfd_vma offset;
   } tls_ldm_got;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 };
 
 /* Get the s390 ELF linker hash table from a link_info structure.  */
@@ -755,7 +755,7 @@ elf_s390_link_hash_table_create (abfd)
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
   ret->tls_ldm_got.refcount = 0;
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
 
   return &ret->elf.root;
 }
@@ -1258,15 +1258,19 @@ elf_s390_check_relocs (abfd, info, sec, 
 		  /* Track dynamic relocs needed for local syms too.
 		     We really need local syms available to do this
 		     easily.  Oh well.  */
-
 		  asection *s;
 		  void *vpp;
+		  Elf_Internal_Sym *isym;
 
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						 sec, r_symndx);
-		  if (s == NULL)
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
 		    return FALSE;
 
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (s == NULL)
+		    s = sec;
+
 		  vpp = &elf_section_data (s)->local_dynrel;
 		  head = (struct elf_s390_dyn_relocs **) vpp;
 		}
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.172
diff -u -p -r1.172 elf64-x86-64.c
--- bfd/elf64-x86-64.c	18 Jun 2009 12:49:41 -0000	1.172
+++ bfd/elf64-x86-64.c	18 Jun 2009 13:59:25 -0000
@@ -487,8 +487,8 @@ struct elf64_x86_64_link_hash_table
   /* The amount of space used by the jump slots in the GOT.  */
   bfd_vma sgotplt_jump_table_size;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 
   /* _TLS_MODULE_BASE_ symbol.  */
   struct bfd_link_hash_entry *tls_module_base;
@@ -629,7 +629,7 @@ elf64_x86_64_link_hash_table_create (bfd
 
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
-  ret->sym_sec.abfd = NULL;
+  ret->sym_cache.abfd = NULL;
   ret->tlsdesc_plt = 0;
   ret->tlsdesc_got = 0;
   ret->tls_ld_got.refcount = 0;
@@ -1478,16 +1478,21 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 		}
 	      else
 		{
-		  void **vpp;
 		  /* Track dynamic relocs needed for local syms too.
 		     We really need local syms available to do this
 		     easily.  Oh well.  */
-
 		  asection *s;
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						 sec, r_symndx);
+		  void **vpp;
+		  Elf_Internal_Sym *isym;
+
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
+		    return FALSE;
+
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
 		  if (s == NULL)
-		    goto error_return;
+		    s = sec;
 
 		  /* Beware of type punned pointers vs strict aliasing
 		     rules.  */
Index: bfd/elfxx-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v
retrieving revision 1.44
diff -u -p -r1.44 elfxx-sparc.c
--- bfd/elfxx-sparc.c	17 Jun 2009 18:08:35 -0000	1.44
+++ bfd/elfxx-sparc.c	18 Jun 2009 13:59:27 -0000
@@ -1465,15 +1465,19 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, 
 		  /* Track dynamic relocs needed for local syms too.
 		     We really need local syms available to do this
 		     easily.  Oh well.  */
-
 		  asection *s;
 		  void *vpp;
+		  Elf_Internal_Sym *isym;
 
-		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
-						 sec, r_symndx);
-		  if (s == NULL)
+		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+						abfd, r_symndx);
+		  if (isym == NULL)
 		    return FALSE;
 
+		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		  if (s == NULL)
+		    s = sec;
+
 		  vpp = &elf_section_data (s)->local_dynrel;
 		  head = (struct _bfd_sparc_elf_dyn_relocs **) vpp;
 		}
Index: bfd/elfxx-sparc.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.h,v
retrieving revision 1.9
diff -u -p -r1.9 elfxx-sparc.h
--- bfd/elfxx-sparc.h	3 Jul 2007 14:26:42 -0000	1.9
+++ bfd/elfxx-sparc.h	18 Jun 2009 13:59:27 -0000
@@ -59,8 +59,8 @@ struct _bfd_sparc_elf_link_hash_table
     bfd_vma offset;
   } tls_ldm_got;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
+  /* Small local sym cache.  */
+  struct sym_cache sym_cache;
 
   /* True if the target system is VxWorks.  */
   int is_vxworks;

-- 
Alan Modra
Australia Development Lab, IBM


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