[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#792921: [sparc64] linking against libx264 crashes runtime linker



Control: forwarded -1 https://www.sourceware.org/ml/binutils/2016-05/msg00128.html

On Wed, May 11, 2016 at 03:45:24PM +0100, James Clarke wrote:
> Control: reassign -1 binutils
> Control: retitle -1 ld on sparc64 converts R_SPARC_32 to R_SPARC_RELATIVE
> Control: affects -1 src:x264
> Control: tags -1 upstream patch
> Control: forwarded -1 asdf
>
> On Tue, 21 Jul 2015 22:35:49 +0200 Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> > On 21.07.2015 21:44, Carlos O'Donell wrote:
> > > Does the problem always reproduce or just sometimes?
> >
> > Always.
> >
> > > If it's just sometimes then it's much much harder to figure out what's wrong.
> >
> > If it were just sometimes, I wouldn't have been able to trace it to libx264...
> >
> > > You'll need a dedicated person to track down exactly what is the
> > > concurrency issue and why it's failing.
> >
> > What I don't understand is why it only fails for libx264, but e.g. libx265 is fine.
> > Also, I don't see how the code, where the crash happens, can possibly crash:
> > From do-rel.h [1]:
> >  85:      const ElfW(Rel) *relative = r;
> >  86:      r += nrelative;
> > [...]
> > 111:            for (; relative < r; ++relative)
> > 112:              DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative);
> >
> > gdb claims it crashes at line 111.
>
> It does indeed crash there, although on line 112 not line 111.
> DO_ELF_MACHINE_REL_RELATIVE is defined to be elf_machine_rel_relative, which in
> this case has been defined to elf_machine_rela_relative, which is an
> always-inline function that will just perform some calculations and a single
> assignment to the relocation address.
>
> The reason it crashes is that libx264 has R_SPARC_RELATIVE relocations which
> are not 8-byte aligned. This is because ld incorrectly converts some R_SPARC_32
> relocations into R_SPARC_RELATIVE ones, which is only valid for 32-bit Sparc.
>
> I have attached a patch which seems to fix this particular case; recompiling
> libx264, linking main.c with it and running the resulting main no longer
> leads to a bus error, and terminates with exit code 0.

Patch actually attached this time (and Control header fixed...).

James
From c96e69b522c8fd0c54762c4b07c36313da414333 Mon Sep 17 00:00:00 2001
From: James Clarke <jrtc27@jrtc27.com>
Date: Wed, 11 May 2016 09:18:01 +0100
Subject: [PATCH 1/1] Don't convert R_SPARC_32 to R_SPARC_RELATIVE if class is
 ELFCLASS64
To: binutils@sourceware.org

bfd/
 * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Don't convert
 R_SPARC_32 to R_SPARC_RELATIVE if class is ELFCLASS64.

gold/
 * sparc.cc (Target_sparc::Scan::local): Don't convert R_SPARC_32 to
 R_SPARC_RELATIVE if class is ELFCLASS64.
 (Target_sparc::Scan::global): Likewise.
---
 bfd/elfxx-sparc.c |  3 ++-
 gold/sparc.cc     | 12 +++++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index fc12805..db2d127 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -3481,7 +3481,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 		}
 	      else
 		{
-		  if (r_type == R_SPARC_32 || r_type == R_SPARC_64)
+		  if ((!ABI_64_P (output_bfd) && r_type == R_SPARC_32)
+		      || (ABI_64_P (output_bfd) && r_type == R_SPARC_64))
 		    {
 		      outrel.r_info = SPARC_ELF_R_INFO (htab, NULL,
 							0, R_SPARC_RELATIVE);
diff --git a/gold/sparc.cc b/gold/sparc.cc
index 10a5031..e5e0146 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -2292,7 +2292,9 @@ Target_sparc<size, big_endian>::Scan::local(
       // apply the link-time value, so we flag the location with
       // an R_SPARC_RELATIVE relocation so the dynamic loader can
       // relocate it easily.
-      if (parameters->options().output_is_position_independent())
+      if (parameters->options().output_is_position_independent()
+	  && ((size == 64 && r_type == elfcpp::R_SPARC_64)
+	      || (size == 32 && r_type == elfcpp::R_SPARC_32)))
 	{
 	  Reloc_section* rela_dyn = target->rela_dyn_section(layout);
 	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
@@ -2300,9 +2302,9 @@ Target_sparc<size, big_endian>::Scan::local(
 				       output_section, data_shndx,
 				       reloc.get_r_offset(),
 				       reloc.get_r_addend(), is_ifunc);
+	  break;
 	}
-      break;
-
+      /* Fall through */
     case elfcpp::R_SPARC_HIX22:
     case elfcpp::R_SPARC_LOX10:
     case elfcpp::R_SPARC_H34:
@@ -2766,8 +2768,8 @@ Target_sparc<size, big_endian>::Scan::global(
 						       reloc.get_r_offset(),
 						       reloc.get_r_addend());
 	      }
-	    else if ((r_type == elfcpp::R_SPARC_32
-		      || r_type == elfcpp::R_SPARC_64)
+	    else if (((size == 64 && r_type == elfcpp::R_SPARC_64)
+		      || (size == 32 && r_type == elfcpp::R_SPARC_32))
 		     && gsym->can_use_relative_reloc(false))
 	      {
 		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
-- 
2.8.2

Attachment: signature.asc
Description: PGP signature


Reply to: