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] Add GPREL and SEGREL reloc support to hppa


The following change adds support to the hppa target for generating
handwritten GPREL and SEGREL data relocations.  For some unknown reason,
there is no R_PARISC_GPREL32 relocation although the case is handled
by the SOM target.

The motivation in adding this support is to improve the EH frame
data on hppa.

Tested on hppa-linux, hppa2.0w-hp-hpux11.11 and hppa64-hp-hpux11.11.

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

2008-08-27  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* elf-hppa.h (elf_hppa_reloc_final_type): Handle R_PARISC_GPREL64,
	R_PARISC_SEGREL32 and R_PARISC_SEGREL64.
	* som.c (som_fixup_formats): Add R_DATA_GPREL fixup.
	(som_hppa_howto_table): Likewise.
	(hppa_som_gen_reloc_type): In case R_HPPA_GOTOFF, detect R_DATA_GPREL
	final type.
	(som_write_fixups): Handle R_DATA_GPREL.

	* config/tc-hppa.c (is_SB_relative): New macro.
	(fix_new_hppa): Remove $segrel$ marker.
	(cons_fix_new_hppa): Set reloc type R_PARISC_SEGREL32 if expression is
	segment relative.
	* config/tc-hppa.h (tc_frob_symbol): Check for $segrel$.

Index: bfd/elf-hppa.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-hppa.h,v
retrieving revision 1.88
diff -u -3 -p -r1.88 elf-hppa.h
--- bfd/elf-hppa.h	12 Mar 2008 08:36:58 -0000	1.88
+++ bfd/elf-hppa.h	28 Aug 2008 01:15:48 -0000
@@ -745,6 +745,17 @@ elf_hppa_reloc_final_type (bfd *abfd,
 	    }
 	  break;
 
+	case 64:
+	  switch (field)
+	    {
+	    case e_fsel:
+	      final_type = R_PARISC_GPREL64;
+	      break;
+	    default:
+	      return R_PARISC_NONE;
+	    }
+	  break;
+
 	default:
 	  return R_PARISC_NONE;
 	}
@@ -930,9 +941,38 @@ elf_hppa_reloc_final_type (bfd *abfd,
 	}
       break;
 
+    case R_PARISC_SEGREL32:
+      switch (format)
+	{
+	case 32:
+	  switch (field)
+	    {
+	    case e_fsel:
+	      final_type = R_PARISC_SEGREL32;
+	      break;
+	    default:
+	      return R_PARISC_NONE;
+	    }
+	  break;
+
+	case 64:
+	  switch (field)
+	    {
+	    case e_fsel:
+	      final_type = R_PARISC_SEGREL64;
+	      break;
+	    default:
+	      return R_PARISC_NONE;
+	    }
+	  break;
+
+	default:
+	  return R_PARISC_NONE;
+	}
+      break;
+
     case R_PARISC_GNU_VTENTRY:
     case R_PARISC_GNU_VTINHERIT:
-    case R_PARISC_SEGREL32:
     case R_PARISC_SEGBASE:
       /* The defaults are fine for these cases.  */
       break;
Index: bfd/som.c
===================================================================
RCS file: /cvs/src/src/bfd/som.c,v
retrieving revision 1.70
diff -u -3 -p -r1.70 som.c
--- bfd/som.c	29 Dec 2007 01:36:40 -0000	1.70
+++ bfd/som.c	28 Aug 2008 01:15:50 -0000
@@ -353,7 +353,7 @@ static const struct fixup_format som_fix
   /* R_DATA_ONE_SYMBOL.  */
   {  0, "L4=Sb=" },		/* 0x25 */
   {  1, "L4=Sd=" },		/* 0x26 */
-  /* R_DATA_PLEBEL.  */
+  /* R_DATA_PLABEL.  */
   {  0, "L4=Sb=" },		/* 0x27 */
   {  1, "L4=Sd=" },		/* 0x28 */
   /* R_SPACE_REF.  */
@@ -437,8 +437,9 @@ static const struct fixup_format som_fix
   { 31, "L4=SD=" },		/* 0x6f */
   { 32, "L4=Sb=" },		/* 0x70 */
   { 33, "L4=Sd=" },		/* 0x71 */
+  /* R_DATA_GPREL.  */
+  {  0, "L4=Sd=" },		/* 0x72 */
   /* R_RESERVED.  */
-  {  0, "" },			/* 0x72 */
   {  0, "" },			/* 0x73 */
   {  0, "" },			/* 0x74 */
   {  0, "" },			/* 0x75 */
@@ -825,7 +826,7 @@ static reloc_howto_type som_hppa_howto_t
   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
-  SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+  SOM_HOWTO (R_DATA_GPREL, "R_DATA_GPREL"),
   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
@@ -1571,6 +1572,8 @@ hppa_som_gen_reloc_type (bfd *abfd,
 	  || field == e_lpsel
 	  || field == e_rpsel)
 	*final_type = R_DATA_PLABEL;
+      else if (field == e_fsel && format == 32)
+	*final_type = R_DATA_GPREL;
       break;
 
     case R_HPPA_COMPLEX:
@@ -2799,6 +2802,24 @@ som_write_fixups (bfd *abfd,
 		    abort ();
 		  break;
 
+		case R_DATA_GPREL:
+		  /* Account for any addend.  */
+		  if (bfd_reloc->addend)
+		    p = som_reloc_addend (abfd, bfd_reloc->addend, p,
+					  &subspace_reloc_size, reloc_queue);
+
+		  if (sym_num < 0x10000000)
+		    {
+		      bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+		      bfd_put_8 (abfd, sym_num >> 16, p + 1);
+		      bfd_put_16 (abfd, (bfd_vma) sym_num, p + 2);
+		      p = try_prev_fixup (abfd, &subspace_reloc_size,
+					  p, 4, reloc_queue);
+		    }
+		  else
+		    abort ();
+		  break;
+
 		case R_DATA_ONE_SYMBOL:
 		case R_DATA_PLABEL:
 		case R_CODE_PLABEL:
Index: gas/config/tc-hppa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-hppa.c,v
retrieving revision 1.140
diff -u -3 -p -r1.140 tc-hppa.c
--- gas/config/tc-hppa.c	22 Aug 2008 00:41:37 -0000	1.140
+++ gas/config/tc-hppa.c	28 Aug 2008 01:15:52 -0000
@@ -1050,6 +1050,10 @@ static struct default_space_dict pa_def_
   ((exp).X_op == O_subtract			\
    && strcmp (S_GET_NAME ((exp).X_op_symbol), "$global$") == 0)
 
+#define is_SB_relative(exp)			\
+  ((exp).X_op == O_subtract			\
+   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$segrel$") == 0)
+
 #define is_PC_relative(exp)			\
   ((exp).X_op == O_subtract			\
    && strcmp (S_GET_NAME ((exp).X_op_symbol), "$PIC_pcrel$0") == 0)
@@ -1233,6 +1237,7 @@ fix_new_hppa (fragS *frag,
      it now so as not to confuse write.c.  Ditto for $PIC_pcrel$0.  */
   if (new_fix->fx_subsy
       && (strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$") == 0
+	  || strcmp (S_GET_NAME (new_fix->fx_subsy), "$segrel$") == 0
 	  || strcmp (S_GET_NAME (new_fix->fx_subsy), "$PIC_pcrel$0") == 0
 	  || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_gdidx$") == 0
 	  || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_ldidx$") == 0
@@ -1256,6 +1261,8 @@ cons_fix_new_hppa (fragS *frag, int wher
   else if (is_PC_relative (*exp))
     rel_type = R_HPPA_PCREL_CALL;
 #ifdef OBJ_ELF
+  else if (is_SB_relative (*exp))
+    rel_type = R_PARISC_SEGREL32;
   else if (is_tls_gdidx (*exp))
     rel_type = R_PARISC_TLS_GD21L;
   else if (is_tls_ldidx (*exp))
Index: gas/config/tc-hppa.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-hppa.h,v
retrieving revision 1.36
diff -u -3 -p -r1.36 tc-hppa.h
--- gas/config/tc-hppa.h	21 Aug 2008 19:49:22 -0000	1.36
+++ gas/config/tc-hppa.h	28 Aug 2008 01:15:52 -0000
@@ -175,6 +177,7 @@ int hppa_fix_adjustable (struct fix *);
 	|| (S_GET_SEGMENT (sym) == &bfd_abs_section \
 	    && ! S_IS_EXTERNAL (sym)) \
 	|| strcmp (S_GET_NAME (sym), "$global$") == 0 \
+	|| strcmp (S_GET_NAME (sym), "$segrel$") == 0 \
 	|| strcmp (S_GET_NAME (sym), "$PIC_pcrel$0") == 0 \
 	|| strcmp (S_GET_NAME (sym), "$tls_gdidx$") == 0 \
 	|| strcmp (S_GET_NAME (sym), "$tls_ldidx$") == 0 \


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