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]

RFC: Possible tweak to MIPS16/microMIPS PLT choice


While writing some tests for the MIPS16 and microMIPS PLT stuff
to address http://article.gmane.org/gmane.comp.gnu.binutils/61257
there was one corner case where the handling seemed a bit counter-
intuitive.  If a function is referenced by both HI/LO relocations
and a JAL relocation, the ISA encoding of the JAL decides the encoding
of the PLT, as intended.  But if a function is referenced by both HI/LO
relocations and a GOT CALL relocation (but not by JAL relocations),
the ISA encoding of the GOT CALL reference doesn't influence the encoding
of the PLT.  This means that:

1. microMIPS CALL reloc + HI/LO ref -> microMIPS PLT
2. MIPS16 CALL reloc    + HI/LO ref -> MIPS PLT
3. MIPS CALL reloc      + HI/LO ref in non-microMIPS object -> MIPS PLT
4. MIPS CALL reloc      + HI/LO ref in microMIPS object     -> microMIPS PLT

(1) and (3) are obviously right, but (2) and (4) were less obvious.
With a patch like the attached, we'd use the GOT CALL relocs as a
fall-back when choosing the encoding.  No change log, since it's an RFC.

I don't really have a strong opinion either way.  It's just that these
things are harder to change once they're enshrined in tests, so I'd like
to be sure of the behaviour.

Thanks,
Richard


Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c	2013-10-05 15:50:03.060932500 +0100
+++ bfd/elfxx-mips.c	2013-10-05 16:23:39.625060153 +0100
@@ -341,6 +341,14 @@ struct plt_entry
 
   /* Whether we need a compressed PLT entry.  */
   unsigned int need_comp : 1;
+
+  /* Whether there are standard-encoding GOT CALL references
+     to the symbol.  */
+  unsigned int suggest_mips : 1;
+
+  /* Whether there are compressed-encoding GOT CALL references
+     to the symbol.  */
+  unsigned int suggest_comp : 1;
 };
 
 /* The MIPS ELF linker needs additional information for each symbol in
@@ -8181,6 +8189,15 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 		 _bfd_elf_adjust_dynamic_symbol.  */
 	      h->needs_plt = 1;
 	      h->type = STT_FUNC;
+
+	      if (h->plt.plist == NULL)
+		h->plt.plist = mips_elf_make_plt_record (abfd);
+	      if (h->plt.plist == NULL)
+		return FALSE;
+	      if (mips16_reloc_p (r_type) || micromips_reloc_p (r_type))
+		h->plt.plist->suggest_comp = TRUE;
+	      else
+		h->plt.plist->suggest_mips = TRUE;
 	    }
 	  break;
 
@@ -8882,14 +8899,19 @@ _bfd_mips_elf_adjust_dynamic_symbol (str
 	}
 
       /* Otherwise, if there are no direct calls to the function, we
-         have a free choice of whether to use standard or compressed
-         entries.  Prefer microMIPS entries if the object is known to
-         contain microMIPS code, so that it becomes possible to create
-         pure microMIPS binaries.  Prefer standard entries otherwise,
-         because MIPS16 ones are no smaller and are usually slower.  */
+	 have a free choice of whether to use standard or compressed
+	 entries.  If there were GOT CALL relocations to the symbol,
+	 and all references were from standard or compressed code,
+	 use the same form for the PLT entry.  Otherwise prefer microMIPS
+	 entries if the object is known to contain microMIPS code, so that
+	 it becomes possible to create pure microMIPS binaries.  Prefer
+	 standard entries otherwise, because MIPS16 ones are no smaller
+	 and are usually slower.  */
       if (!h->plt.plist->need_mips && !h->plt.plist->need_comp)
 	{
-	  if (micromips_p)
+	  if (h->plt.plist->suggest_mips && !h->plt.plist->suggest_comp)
+	    h->plt.plist->need_mips = TRUE;
+	  else if (micromips_p)
 	    h->plt.plist->need_comp = TRUE;
 	  else
 	    h->plt.plist->need_mips = TRUE;
@@ -9211,12 +9233,7 @@ mips_elf_allocate_lazy_stub (struct mips
 
       BFD_ASSERT (htab->root.dynobj != NULL);
       if (h->root.plt.plist == NULL)
-	h->root.plt.plist = mips_elf_make_plt_record (htab->sstubs->owner);
-      if (h->root.plt.plist == NULL)
-	{
-	  hti->error = TRUE;
-	  return FALSE;
-	}
+	abort ();
       h->root.root.u.def.section = htab->sstubs;
       h->root.root.u.def.value = htab->sstubs->size + isa_bit;
       h->root.plt.plist->stub_offset = htab->sstubs->size;


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