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]

hppa-elf32: non-PIC to PIC call stubs


We weren't getting non-PIC to PIC function call stubs if a plabel existed
for the function (ie it had its address taken).

bfd/ChangeLog
	* elf32-hppa.c (elf32_hppa_link_hash_entry): Add maybe_pic_call.
	(hppa_link_hash_newfunc): Init it.
	(hppa_type_of_stub): Only use non-PIC to PIC call stub if caller
	section appears to be non-PIC.
	(final_link_relocate): Likewise.
	(elf32_hppa_adjust_dynamic_symbol): Set maybe_pic_call for any
	possible candidate function, and set pic_call for those that will
	only have a .plt entry for the PIC call stub.
	(hppa_handle_PIC_calls): Set maybe_pic_call.

Committing to trunk, and I'll commit to the branch tomorrow as this bug
breaks c++.

Alan Modra
-- 
Linuxcare

Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.28
diff -u -p -r1.28 elf32-hppa.c
--- elf32-hppa.c	2001/03/08 21:03:58	1.28
+++ elf32-hppa.c	2001/03/15 13:26:03
@@ -225,6 +225,10 @@ struct elf32_hppa_link_hash_entry {
 #endif
 
   /* Set during a static link if we detect a function is PIC.  */
+  unsigned int maybe_pic_call:1;
+
+  /* Set if the only reason we need a .plt entry is for a non-PIC to
+     PIC function call.  */
   unsigned int pic_call:1;
 
   /* Set if this symbol is used by a plabel reloc.  */
@@ -490,6 +494,7 @@ hppa_link_hash_newfunc (entry, table, st
 #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;
       ret->plt_abs = 0;
@@ -721,7 +726,7 @@ hppa_type_of_stub (input_sec, rel, hash,
 	      && hash->elf.plt.offset != (bfd_vma) -1)
 	  || hash->elf.root.type == bfd_link_hash_undefweak
 	  || hash->elf.root.type == bfd_link_hash_undefined
-	  || hash->pic_call))
+	  || (hash->maybe_pic_call && !(input_sec->flags & SEC_HAS_GOT_REF))))
     {
       /* If output_section is NULL, then it's a symbol defined in a
 	 shared library.  We will need an import stub.  Decide between
@@ -1890,6 +1895,14 @@ elf32_hppa_adjust_dynamic_symbol (info, 
   if (h->type == STT_FUNC
       || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
     {
+      if (!info->shared
+	  && h->plt.refcount > 0
+	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
+	  && (h->root.u.def.section->flags & SEC_HAS_GOT_REF) != 0)
+	{
+	  ((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call = 1;
+	}
+
       if (h->plt.refcount <= 0
 	  || ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
 	      && h->root.type != bfd_link_hash_defweak
@@ -1906,14 +1919,8 @@ elf32_hppa_adjust_dynamic_symbol (info, 
 
 	  /* As a special sop to the hppa ABI, we keep a .plt entry
 	     for functions in sections containing PIC code.  */
-	  if (!info->shared
-	      && h->plt.refcount > 0
-	      && (h->root.type == bfd_link_hash_defined
-		  || h->root.type == bfd_link_hash_defweak)
-	      && (h->root.u.def.section->flags & SEC_HAS_GOT_REF) != 0)
-	    {
-	      ((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1;
-	    }
+	  if (((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call)
+	    ((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1;
 	  else
 	    {
 	      h->plt.offset = (bfd_vma) -1;
@@ -2059,6 +2066,7 @@ hppa_handle_PIC_calls (h, inf)
     }
 
   h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+  ((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call = 1;
   ((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1;
 
   info = (struct bfd_link_info *) inf;
@@ -3244,11 +3252,12 @@ final_link_relocate (input_section, cont
 	 find the import stub in the stub hash.  */
       if (sym_sec == NULL
 	  || sym_sec->output_section == NULL
-	  || (h != NULL &&
-	      (h->pic_call
-	       || (h->elf.root.type == bfd_link_hash_defweak
-		   && h->elf.dynindx != -1
-		   && h->elf.plt.offset != (bfd_vma) -1))))
+	  || (h != NULL
+	      && ((h->maybe_pic_call
+		   && !(input_section->flags & SEC_HAS_GOT_REF))
+		  || (h->elf.root.type == bfd_link_hash_defweak
+		      && h->elf.dynindx != -1
+		      && h->elf.plt.offset != (bfd_vma) -1))))
 	{
 	  stub_entry = hppa_get_stub_entry (input_section, sym_sec,
 					    h, rel, hplink);



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