[committed] Add GPREL and SEGREL reloc support to hppa

John David Anglin dave@hiauly1.hia.nrc.ca
Fri Aug 29 04:26:00 GMT 2008


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 \



More information about the Binutils mailing list