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]

Avoid COPY relocs on hppa-elf


Do the same for hppa-elf as I've recently done for x86-elf.

bfd/ChangeLog
	* elf32-hppa.c (elf32_hppa_check_relocs): Don't make syms dynamic
	here..
	(elf32_hppa_adjust_dynamic_symbol): ..nor here..
	(allocate_plt_and_got_and_discard_relocs): .. instead do so here
	after gc has run.

	* elf32-hppa.c (RELATIVE_DYNAMIC_RELOCS): Delete.
	(IS_ABSOLUTE_RELOC): Define.
	(elf32_hppa_link_hash_entry): Always include reloc_entries field.
	(hppa_link_hash_newfunc): Always init it.
	(elf32_hppa_check_relocs): Mark symbols as ELF_LINK_NON_GOT_REF to
	create COPY relocs only when the reloc is in a read-only section.
	Instead, allocate space for a dynamic reloc to reference the
	library symbol directly.  Keep track of space we allocate using
	relocs_entries.
	(hppa_discard_copies): Delete, and move code to..
	(allocate_plt_and_got): ..here.  Rename to
	allocate_plt_and_got_and_discard_relocs.  Remove unneeded dynamic
	relocs for non-shared link.
	(elf32_hppa_size_dynamic_sections): Update calls to above.
	(elf32_hppa_relocate_section): Write out the dynamic relocs used
	in lieu of COPY relocs.

-- 
Alan Modra

Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.39
diff -u -p -r1.39 elf32-hppa.c
--- elf32-hppa.c	2001/06/21 05:47:12	1.39
+++ elf32-hppa.c	2001/06/27 02:18:30
@@ -149,9 +149,10 @@ static const bfd_byte plt_stub[] =
 #endif
 
 /* We don't need to copy any PC- or GP-relative dynamic relocs into a
-   shared object's dynamic section.  */
-#ifndef RELATIVE_DYNAMIC_RELOCS
-#define RELATIVE_DYNAMIC_RELOCS 0
+   shared object's dynamic section.  All the relocs of the limited
+   class we are interested in, are absolute.  See check_relocs.  */
+#ifndef IS_ABSOLUTE_RELOC
+#define IS_ABSOLUTE_RELOC(r_type) 1
 #endif
 
 enum elf32_hppa_stub_type {
@@ -208,7 +209,6 @@ struct elf32_hppa_link_hash_entry {
   asection *stub_reloc_sec;
 #endif
 
-#if ! LONG_BRANCH_PIC_IN_SHLIB || RELATIVE_DYNAMIC_RELOCS
   /* Used to count relocations for delayed sizing of relocation
      sections.  */
   struct elf32_hppa_dyn_reloc_entry {
@@ -222,7 +222,6 @@ struct elf32_hppa_link_hash_entry {
     /* Number of relocs copied in this section.  */
     bfd_size_type count;
   } *reloc_entries;
-#endif
 
   /* Set during a static link if we detect a function is PIC.  */
   unsigned int maybe_pic_call:1;
@@ -365,15 +364,9 @@ static boolean elf32_hppa_adjust_dynamic
 
 static boolean hppa_handle_PIC_calls
   PARAMS ((struct elf_link_hash_entry *, PTR));
-
-static boolean allocate_plt_and_got
-  PARAMS ((struct elf_link_hash_entry *, PTR));
 
-#if ((! LONG_BRANCH_PIC_IN_SHLIB && LONG_BRANCH_VIA_PLT) \
-     || RELATIVE_DYNAMIC_RELOCS)
-static boolean hppa_discard_copies
+static boolean allocate_plt_and_got_and_discard_relocs
   PARAMS ((struct elf_link_hash_entry *, PTR));
-#endif
 
 static boolean clobber_millicode_symbols
   PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *));
@@ -494,9 +487,7 @@ hppa_link_hash_newfunc (entry, table, st
       ret->stub_reloc_sec = NULL;
 #endif
       ret->stub_cache = NULL;
-#if ! LONG_BRANCH_PIC_IN_SHLIB || RELATIVE_DYNAMIC_RELOCS
       ret->reloc_entries = NULL;
-#endif
       ret->maybe_pic_call = 0;
       ret->pic_call = 0;
       ret->plabel = 0;
@@ -1452,17 +1443,7 @@ elf32_hppa_check_relocs (abfd, info, sec
 	  if (h != NULL)
 	    {
 	      if (h->elf.got.refcount == -1)
-		{
-		  h->elf.got.refcount = 1;
-
-		  /* Make sure this symbol is output as a dynamic symbol.  */
-		  if (h->elf.dynindx == -1)
-		    {
-		      if (! bfd_elf32_link_record_dynamic_symbol (info,
-								  &h->elf))
-			return false;
-		    }
-		}
+		h->elf.got.refcount = 1;
 	      else
 		h->elf.got.refcount += 1;
 	    }
@@ -1553,7 +1534,10 @@ elf32_hppa_check_relocs (abfd, info, sec
 	  /* Flag this symbol as having a non-got, non-plt reference
 	     so that we generate copy relocs if it turns out to be
 	     dynamic.  */
-	  if (h != NULL)
+	  if (need_entry == NEED_DYNREL
+	      && h != NULL
+	      && !info->shared
+	      && (sec->flags & SEC_READONLY) != 0)
 	    h->elf.elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
 
 	  /* If we are creating a shared library then we need to copy
@@ -1579,16 +1563,21 @@ elf32_hppa_check_relocs (abfd, info, sec
 	     is absolute too, as in that case it is the reloc in the
 	     stub we will be creating, rather than copying the PCREL
 	     reloc in the branch.  */
-	  if ((sec->flags & SEC_ALLOC) != 0
-	      && info->shared
-#if RELATIVE_DYNAMIC_RELOCS
-	      && (!info->symbolic
-		  || is_absolute_reloc (r_type)
-		  || (h != NULL
-		      && ((h->elf.elf_link_hash_flags
-			   & ELF_LINK_HASH_DEF_REGULAR) == 0)))
-#endif
-	      )
+	  if ((info->shared
+	       && (sec->flags & SEC_ALLOC) != 0
+	       && (IS_ABSOLUTE_RELOC (r_type)
+		   || (h != NULL
+		       && (!info->symbolic
+			   || h->elf.root.type == bfd_link_hash_defweak
+			   || (h->elf.elf_link_hash_flags
+			       & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+	      || (!info->shared
+		  && (sec->flags & SEC_ALLOC) != 0
+		  && h != NULL
+		  && (h->elf.elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
+		  && (h->elf.root.type == bfd_link_hash_defweak
+		      || (h->elf.elf_link_hash_flags
+			  & ELF_LINK_HASH_DEF_REGULAR) == 0)))
 	    {
 	      boolean doit;
 	      asection *srel;
@@ -1676,16 +1665,13 @@ elf32_hppa_check_relocs (abfd, info, sec
 		{
 		  srel->_raw_size += sizeof (Elf32_External_Rela);
 
-#if ! LONG_BRANCH_PIC_IN_SHLIB || RELATIVE_DYNAMIC_RELOCS
 		  /* Keep track of relocations we have entered for
 		     this global symbol, so that we can discard them
 		     later if necessary.  */
-		  if (h != NULL
-		      && (0
-#if RELATIVE_DYNAMIC_RELOCS
-			  || ! is_absolute_reloc (rtype)
-#endif
-			  || (need_entry & NEED_STUBREL)))
+		  if (!info->shared
+		      || (h != NULL
+			  && (! IS_ABSOLUTE_RELOC (rtype)
+			      || (need_entry & NEED_STUBREL))))
 		    {
 		      struct elf32_hppa_dyn_reloc_entry *p;
 
@@ -1709,11 +1695,10 @@ elf32_hppa_check_relocs (abfd, info, sec
 			 set.  Leave the count at zero for the
 			 NEED_STUBREL case as we only ever have one
 			 stub reloc per section per symbol, and this
-			 simplifies code in hppa_discard_copies.  */
+			 simplifies code to discard unneeded relocs.  */
 		      if (! (need_entry & NEED_STUBREL))
 			++p->count;
 		    }
-#endif
 		}
 	    }
 	}
@@ -1941,21 +1926,9 @@ elf32_hppa_adjust_dynamic_symbol (info, 
 	    {
 	      h->plt.offset = (bfd_vma) -1;
 	      h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
-	      return true;
 	    }
 	}
 
-      if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call)
-	{
-	  /* Make sure this symbol is output as a dynamic symbol.  */
-	  if (h->dynindx == -1
-	      && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
-	    {
-	      if (! bfd_elf32_link_record_dynamic_symbol (info, h))
-		return false;
-	    }
-	}
-
       return true;
     }
 
@@ -2070,13 +2043,14 @@ hppa_handle_PIC_calls (h, inf)
    global syms.  */
 
 static boolean
-allocate_plt_and_got (h, inf)
+allocate_plt_and_got_and_discard_relocs (h, inf)
      struct elf_link_hash_entry *h;
      PTR inf;
 {
   struct bfd_link_info *info;
   struct elf32_hppa_link_hash_table *hplink;
   asection *s;
+  struct elf32_hppa_link_hash_entry *eh;
 
   if (h->root.type == bfd_link_hash_indirect
       || h->root.type == bfd_link_hash_warning)
@@ -2088,6 +2062,17 @@ allocate_plt_and_got (h, inf)
        && h->plt.refcount > 0)
       || ((struct elf32_hppa_link_hash_entry *) h)->pic_call)
     {
+      /* Make sure this symbol is output as a dynamic symbol.
+	 Undefined weak syms won't yet be marked as dynamic.  */
+      if (h->dynindx == -1
+	  && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0
+	  && h->type != STT_PARISC_MILLI
+	  && !((struct elf32_hppa_link_hash_entry *) h)->pic_call)
+	{
+	  if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+	    return false;
+	}
+
       /* Make an entry in the .plt section.  */
       s = hplink->splt;
       h->plt.offset = s->_raw_size;
@@ -2119,6 +2104,16 @@ allocate_plt_and_got (h, inf)
     {
       boolean dyn;
 
+      /* Make sure this symbol is output as a dynamic symbol.
+	 Undefined weak syms won't yet be marked as dynamic.  */
+      if (h->dynindx == -1
+	  && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0
+	  && h->type != STT_PARISC_MILLI)
+	{
+	  if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+	    return false;
+	}
+
       s = hplink->sgot;
       h->got.offset = s->_raw_size;
       s->_raw_size += GOT_ENTRY_SIZE;
@@ -2129,58 +2124,75 @@ allocate_plt_and_got (h, inf)
   else
     h->got.offset = (bfd_vma) -1;
 
-  return true;
-}
+  /* If this is a -Bsymbolic shared link, then we need to discard all
+     space allocated for dynamic relocs against symbols defined in a
+     regular object.  For the normal shared case, discard space for
+     relocs that have become local due to symbol visibility changes.
+     For the non-shared case, discard space for symbols which turn out
+     to need copy relocs or are not dynamic.  We also need to lose
+     relocs we've allocated for long branch stubs if we know we won't
+     be generating a stub.  */
 
-#if ((! LONG_BRANCH_PIC_IN_SHLIB && LONG_BRANCH_VIA_PLT) \
-     || RELATIVE_DYNAMIC_RELOCS)
-/* This function is called via elf_link_hash_traverse to discard space
-   we allocated for relocs that it turned out we didn't need.  */
+  eh = (struct elf32_hppa_link_hash_entry *) h;
+  if (eh->reloc_entries == NULL)
+    return true;
 
-static boolean
-hppa_discard_copies (h, inf)
-     struct elf_link_hash_entry *h;
-     PTR inf;
-{
-  struct elf32_hppa_dyn_reloc_entry *s;
-  struct elf32_hppa_link_hash_entry *eh;
-  struct bfd_link_info *info;
+  /* First handle the non-shared case.  */
+  if (!info->shared
+      && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
+      && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+	  || h->root.type == bfd_link_hash_undefweak
+	  || h->root.type == bfd_link_hash_undefined))
+    {
+      /* Make sure this symbol is output as a dynamic symbol.
+	 Undefined weak syms won't yet be marked as dynamic.  */
+      if (h->dynindx == -1
+	  && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0
+	  && h->type != STT_PARISC_MILLI)
+	{
+	  if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+	    return false;
+	}
 
-  eh = (struct elf32_hppa_link_hash_entry *) h;
-  info = (struct bfd_link_info *) inf;
+      /* If that succeeded, we know we'll be keeping all the relocs.  */
+      if (h->dynindx != -1)
+	return true;
+    }
 
 #if ! LONG_BRANCH_PIC_IN_SHLIB && LONG_BRANCH_VIA_PLT
   /* Handle the stub reloc case.  If we have a plt entry for the
-     function, we won't be needing long branch stubs.  s->count will
+     function, we won't be needing long branch stubs.  c->count will
      only be zero for stub relocs, which provides a handy way of
      flagging these relocs, and means we need do nothing special for
      the forced local and symbolic link case.  */
   if (eh->stub_reloc_sec != NULL
       && eh->elf.plt.offset != (bfd_vma) -1)
     {
-      for (s = eh->reloc_entries; s != NULL; s = s->next)
-	if (s->count == 0)
-	  s->section->_raw_size -= sizeof (Elf32_External_Rela);
+      struct elf32_hppa_dyn_reloc_entry *c;
+
+      for (c = eh->reloc_entries; c != NULL; c = c->next)
+	if (c->count == 0)
+	  c->section->_raw_size -= sizeof (Elf32_External_Rela);
     }
 #endif
 
-#if RELATIVE_DYNAMIC_RELOCS
-  /* If a symbol has been forced local or we have found a regular
+  /* Discard any relocs in the non-shared case.  For the shared case,
+     if a symbol has been forced local or we have found a regular
      definition for the symbolic link case, then we won't be needing
      any relocs.  */
-  if (eh->elf.dynindx == -1
+  if (!info->shared
       || ((eh->elf.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
-	  && !is_absolute_reloc (r_type)
-	  && info->symbolic))
+	  && ((eh->elf.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
+	      || info->symbolic)))
     {
-      for (s = eh->reloc_entries; s != NULL; s = s->next)
-	s->section->_raw_size -= s->count * sizeof (Elf32_External_Rela);
+      struct elf32_hppa_dyn_reloc_entry *c;
+
+      for (c = eh->reloc_entries; c != NULL; c = c->next)
+	c->section->_raw_size -= c->count * sizeof (Elf32_External_Rela);
     }
-#endif
 
   return true;
 }
-#endif
 
 /* This function is called via elf_link_hash_traverse to force
    millicode symbols local so they do not end up as globals in the
@@ -2228,7 +2240,6 @@ elf32_hppa_size_dynamic_sections (output
 
   if (hplink->root.dynamic_sections_created)
     {
-
       /* Set the contents of the .interp section to the interpreter.  */
       if (! info->shared)
 	{
@@ -2318,23 +2329,12 @@ elf32_hppa_size_dynamic_sections (output
 	}
     }
 
-  /* Allocate global sym .plt and .got entries.  */
+  /* Allocate global sym .plt and .got entries.  Also discard all
+     unneeded relocs.  */
   elf_link_hash_traverse (&hplink->root,
-			  allocate_plt_and_got,
-			  info);
+			  allocate_plt_and_got_and_discard_relocs,
+			  (PTR) info);
 
-#if ((! LONG_BRANCH_PIC_IN_SHLIB && LONG_BRANCH_VIA_PLT) \
-     || RELATIVE_DYNAMIC_RELOCS)
-  /* If this is a -Bsymbolic shared link, then we need to discard all
-     relocs against symbols defined in a regular object.  We also need
-     to lose relocs we've allocated for long branch stubs if we know
-     we won't be generating a stub.  */
-  if (info->shared)
-    elf_link_hash_traverse (&hplink->root,
-			    hppa_discard_copies,
-			    info);
-#endif
-
   /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate
      memory for them.  */
@@ -3896,19 +3896,30 @@ elf32_hppa_relocate_section (output_bfd,
 	     hppa_discard_copies.  ie. We need exactly the same
 	     condition as in check_relocs, with some extra conditions
 	     (dynindx test in this case) to cater for relocs removed
-	     by hppa_discard_copies.  */
-	  if ((input_section->flags & SEC_ALLOC) != 0
-	      && info->shared
-#if RELATIVE_DYNAMIC_RELOCS
-	      && (is_absolute_reloc (r_type)
-		  || ((!info->symbolic
-		       || (h != NULL
-			   && ((h->elf.elf_link_hash_flags
-				& ELF_LINK_HASH_DEF_REGULAR) == 0
-			       || h->elf.root.type == bfd_link_hash_defweak)))
-		      && (h == NULL || h->elf.dynindx != -1)))
-#endif
-	      )
+	     by hppa_discard_copies.  If you squint, the non-shared
+	     test here does indeed match the one in check_relocs, the
+	     difference being that here we test DEF_DYNAMIC rather
+	     than a maybe-DEF_DYNAMIC via !DEF_REGULAR.  Common syms
+	     end up with !DEF_REGULAR, which is why we can't use that
+	     here.  Conversely, DEF_DYNAMIC can't be used in
+	     check_relocs as there all files have not been loaded.  */
+	  if ((info->shared
+	       && (input_section->flags & SEC_ALLOC) != 0
+	       && (IS_ABSOLUTE_RELOC (r_type)
+		   || (h != NULL
+		       && h->elf.dynindx != -1
+		       && (!info->symbolic
+			   || (h->elf.elf_link_hash_flags
+			       & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+	      || (!info->shared
+		  && (input_section->flags & SEC_ALLOC) != 0
+		  && h != NULL
+		  && h->elf.dynindx != -1
+		  && (h->elf.elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
+		  && ((h->elf.elf_link_hash_flags
+		       & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+		      || h->elf.root.type == bfd_link_hash_undefweak
+		      || h->elf.root.type == bfd_link_hash_undefined)))
 	    {
 	      Elf_Internal_Rela outrel;
 	      boolean skip;
@@ -3959,6 +3970,8 @@ elf32_hppa_relocate_section (output_bfd,
 	      else if (h != NULL
 		       && h->elf.dynindx != -1
 		       && (plabel
+			   || !IS_ABSOLUTE_RELOC (r_type)
+			   || !info->shared
 			   || !info->symbolic
 			   || (h->elf.elf_link_hash_flags
 			       & ELF_LINK_HASH_DEF_REGULAR) == 0))


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