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]

[PATCH] MIPS/BFD: Handle MIPS16 stub symbols with n64 relocs


Hello,

 While sorting out test suite failures in a modified mips64-linux-gnu 
configuration that defaults to n64 (that probably applies to a pristine 
mips64-openbsd configuration too) I have noticed that we have a problem 
with MIPS16 stub symbols referred to by compound relocation.  We try to 
locate the symbol in a MIPS16 stub section by checking the first 
R_MIPS_NONE relocation against the section, but we fail to disregard 
subsequent R_MIPS_NONE relocations of any non-R_MIPS_NONE relocation that 
do not refer to any symbol.  Only a genuine R_MIPS_NONE relocation must be 
accepted for this purpose and in an n64 object that'll be one that has the 
type of the first relocation in the triplet set to R_MIPS_NONE.

 While our support for MIPS16 stubs in n64 binaries is incomplete, I think 
some cases, such as static msym32 binaries, can work and therefore I 
propose the problem to be fixed, as below.  The problem can be seen with 
one of the ld test cases as follows:

./ld-new: tmpdir/dump0.o: Warning: cannot determine the target function for stub section `.mips16.call.F1'
tmpdir/dump0.o: could not read symbols: Bad value
failed with: <./ld-new: tmpdir/dump0.o: Warning: cannot determine the target function for stub section `.mips16.call.F1'
tmpdir/dump0.o: could not read symbols: Bad value>, expected: <>
./ld-new: tmpdir/dump0.o: Warning: cannot determine the target function for stub section `.mips16.call.F1'
tmpdir/dump0.o: could not read symbols: Bad value
failed with: <./ld-new: tmpdir/dump0.o: Warning: cannot determine the target function for stub section `.mips16.call.F1'
tmpdir/dump0.o: could not read symbols: Bad value>, expected: <>
FAIL: MIPS16 interlinking for local functions 1

with a configuration that defaults to n64 and 
ld/testsuite/ld-mips-elf/mips16-local-stubs-1.s modified so that DLA is 
used rather than LA as appropriate.

 The fix removes the problem and causes no regressions with said modified 
mips64-linux-gnu configuration nor a pristine mips-linux-gnu one.  OK to 
apply?

2012-04-10  Maciej W. Rozycki  <macro@linux-mips.org>

	bfd/
	* elfxx-mips.c (mips16_stub_symndx): Handle n64 compound relocs.
	(_bfd_mips_elf_check_relocs): Update accordingly.

  Maciej

binutils-mips16-stub64.patch
Index: binutils/bfd/elfxx-mips.c
===================================================================
--- binutils.orig/bfd/elfxx-mips.c
+++ binutils/bfd/elfxx-mips.c
@@ -1460,14 +1460,17 @@ section_allows_mips16_refs_p (asection *
    function, or 0 if we can't decide which function that is.  */
 
 static unsigned long
-mips16_stub_symndx (asection *sec ATTRIBUTE_UNUSED,
+mips16_stub_symndx (const struct elf_backend_data *bed,
+		    asection *sec ATTRIBUTE_UNUSED,
 		    const Elf_Internal_Rela *relocs,
 		    const Elf_Internal_Rela *relend)
 {
+  int int_rels_per_ext_rel = bed->s->int_rels_per_ext_rel;
   const Elf_Internal_Rela *rel;
 
-  /* Trust the first R_MIPS_NONE relocation, if any.  */
-  for (rel = relocs; rel < relend; rel++)
+  /* Trust the first R_MIPS_NONE relocation, if any, but not a subsequent
+     one in a compound relocation.  */
+  for (rel = relocs; rel < relend; rel += int_rels_per_ext_rel)
     if (ELF_R_TYPE (sec->owner, rel->r_info) == R_MIPS_NONE)
       return ELF_R_SYM (sec->owner, rel->r_info);
 
@@ -7569,7 +7572,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
       /* Look at the relocation information to figure out which symbol
          this is for.  */
 
-      r_symndx = mips16_stub_symndx (sec, relocs, rel_end);
+      r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end);
       if (r_symndx == 0)
 	{
 	  (*_bfd_error_handler)
@@ -7694,7 +7697,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
       /* Look at the relocation information to figure out which symbol
          this is for.  */
 
-      r_symndx = mips16_stub_symndx (sec, relocs, rel_end);
+      r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end);
       if (r_symndx == 0)
 	{
 	  (*_bfd_error_handler)


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