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]

[committed] Fix PR binutils/13476


The attached change fixes PR binutils/13476.  The original attempt at
converting the PIC TLS relocations to DP releative in non shared links
was flawed.  In some cases, the the TLS relocations were mishandled in
shared links.  Further, the R_PARISC_TLS_GD14R, R_PARISC_TLS_LDM14R
and R_PARISC_TLS_IE14R relocations were not converted.

Tested on hppa-unknown-linux-gnu with no observed regressions.  Committed
to trunk.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2011-12-11  John Davis Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	PR binutils/13476
	* elf32-hppa.c (final_link_relocate): Convert R_PARISC_TLS_GD21L,
	R_PARISC_TLS_LDM21L and R_PARISC_TLS_IE21L relocations to
	R_PARISC_DPREL21L when not doing a shared link.  Likewise convert
	R_PARISC_TLS_GD14R, R_PARISC_TLS_LDM14R and R_PARISC_TLS_IE14R to
	R_PARISC_DPREL14R.  Handle R_PARISC_TLS_GD21L, R_PARISC_TLS_LDM21L
	and R_PARISC_TLS_IE21L with R_PARISC_DLTIND21L.

Index: elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.182
diff -u -3 -p -r1.182 elf32-hppa.c
--- elf32-hppa.c	6 Nov 2011 20:25:17 -0000	1.182
+++ elf32-hppa.c	8 Dec 2011 11:47:53 -0000
@@ -3349,10 +3349,16 @@ final_link_relocate (asection *input_sec
       switch (r_type)
 	{
 	  case R_PARISC_DLTIND21L:
+	  case R_PARISC_TLS_GD21L:
+	  case R_PARISC_TLS_LDM21L:
+	  case R_PARISC_TLS_IE21L:
 	    r_type = R_PARISC_DPREL21L;
 	    break;
 
 	  case R_PARISC_DLTIND14R:
+	  case R_PARISC_TLS_GD14R:
+	  case R_PARISC_TLS_LDM14R:
+	  case R_PARISC_TLS_IE14R:
 	    r_type = R_PARISC_DPREL14R;
 	    break;
 
@@ -3418,53 +3424,48 @@ final_link_relocate (asection *input_sec
     case R_PARISC_DPREL21L:
     case R_PARISC_DPREL14R:
     case R_PARISC_DPREL14F:
-    case R_PARISC_TLS_GD21L:
-    case R_PARISC_TLS_LDM21L:
-    case R_PARISC_TLS_IE21L:
       /* Convert instructions that use the linkage table pointer (r19) to
 	 instructions that use the global data pointer (dp).  This is the
 	 most efficient way of using PIC code in an incomplete executable,
 	 but the user must follow the standard runtime conventions for
 	 accessing data for this to work.  */
-      if (orig_r_type == R_PARISC_DLTIND21L
-	  || (!info->shared
-	      && (r_type == R_PARISC_TLS_GD21L
-		  || r_type == R_PARISC_TLS_LDM21L
-		  || r_type == R_PARISC_TLS_IE21L)))
-	{
-	  /* Convert addil instructions if the original reloc was a
-	     DLTIND21L.  GCC sometimes uses a register other than r19 for
-	     the operation, so we must convert any addil instruction
-	     that uses this relocation.  */
-	  if ((insn & 0xfc000000) == ((int) OP_ADDIL << 26))
-	    insn = ADDIL_DP;
-	  else
-	    /* We must have a ldil instruction.  It's too hard to find
-	       and convert the associated add instruction, so issue an
-	       error.  */
-	    (*_bfd_error_handler)
-	      (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"),
-	       input_bfd,
-	       input_section,
-	       (long) offset,
-	       howto->name,
-	       insn);
-	}
-      else if (orig_r_type == R_PARISC_DLTIND14F)
-	{
-	  /* This must be a format 1 load/store.  Change the base
-	     register to dp.  */
-	  insn = (insn & 0xfc1ffff) | (27 << 21);
-	}
-
-    /* For all the DP relative relocations, we need to examine the symbol's
-       section.  If it has no section or if it's a code section, then
-       "data pointer relative" makes no sense.  In that case we don't
-       adjust the "value", and for 21 bit addil instructions, we change the
-       source addend register from %dp to %r0.  This situation commonly
-       arises for undefined weak symbols and when a variable's "constness"
-       is declared differently from the way the variable is defined.  For
-       instance: "extern int foo" with foo defined as "const int foo".  */
+      if (orig_r_type != r_type)
+	{
+	  if (r_type == R_PARISC_DPREL21L)
+	    {
+	      /* GCC sometimes uses a register other than r19 for the
+		 operation, so we must convert any addil instruction
+		 that uses this relocation.  */
+	      if ((insn & 0xfc000000) == ((int) OP_ADDIL << 26))
+		insn = ADDIL_DP;
+	      else
+		/* We must have a ldil instruction.  It's too hard to find
+		   and convert the associated add instruction, so issue an
+		   error.  */
+		(*_bfd_error_handler)
+		  (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"),
+		   input_bfd,
+		   input_section,
+		   (long) offset,
+		   howto->name,
+		   insn);
+	    }
+	  else if (r_type == R_PARISC_DPREL14F)
+	    {
+	      /* This must be a format 1 load/store.  Change the base
+		 register to dp.  */
+	      insn = (insn & 0xfc1ffff) | (27 << 21);
+	    }
+	}
+
+      /* For all the DP relative relocations, we need to examine the symbol's
+	 section.  If it has no section or if it's a code section, then
+	 "data pointer relative" makes no sense.  In that case we don't
+	 adjust the "value", and for 21 bit addil instructions, we change the
+	 source addend register from %dp to %r0.  This situation commonly
+	 arises for undefined weak symbols and when a variable's "constness"
+	 is declared differently from the way the variable is defined.  For
+	 instance: "extern int foo" with foo defined as "const int foo".  */
       if (sym_sec == NULL || (sym_sec->flags & SEC_CODE) != 0)
 	{
 	  if ((insn & ((0x3f << 26) | (0x1f << 21)))
@@ -3481,6 +3482,9 @@ final_link_relocate (asection *input_sec
     case R_PARISC_DLTIND21L:
     case R_PARISC_DLTIND14R:
     case R_PARISC_DLTIND14F:
+    case R_PARISC_TLS_GD21L:
+    case R_PARISC_TLS_LDM21L:
+    case R_PARISC_TLS_IE21L:
     case R_PARISC_TLS_GD14R:
     case R_PARISC_TLS_LDM14R:
     case R_PARISC_TLS_IE14R:


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