This is the mail archive of the binutils@sources.redhat.com 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]

Re: [PATCH] x86-64: support newer relocation types


>> Hopefully I'll have a revised patch later today...
>
>Thanks!  I've updated the medium model patches for current GCC so I will
>give it some testing afterwards.

Updating the patch to support for the new x86-64 relocation types added in
ABI draft 0.95 (or a slightly earlier version).

Built and tested on i686-pc-linux-gnu and x86_64-unknown-linux-gnu.

Jan

bfd/
2005-06-16  Jan Beulich  <jbeulich@novell.com>

	* bfd-in2.h (elf_x86_64_reloc_type): Add BFD_RELOC_X86_64_GOTOFF64
	and BFD_RELOC_X86_64_GOTPC32.
	* libbfd.h (bfd_reloc_code_real_names): Likewise.
	* elf64-x86-64.c (x86_64_elf_howto_table): Add entries for
	R_X86_64_PC64, R_X86_64_GOTOFF64, and R_X86_64_GOTPC32.
	(x86_64_reloc_map): Add entries for R_X86_64_PC64, R_X86_64_GOTOFF64,
	and R_X86_64_GOTPC32.
	(elf64_x86_64_info_to_howto): Adjust bounding relocation type.
	(elf64_x86_64_check_relocs): Also handle R_X86_64_PC64,
	R_X86_64_GOTOFF64, and R_X86_64_GOTPC32.
	(elf64_x86_64_relocate_section): Likewise.
	(elf64_x86_64_gc_sweep_hook): Also handle R_X86_64_PC64.

gas/
2005-06-16  Jan Beulich  <jbeulich@novell.com>

	* config/tc-i386.c (reloc): Also handle BFD_RELOC_64_PCREL.
	(tc_i386_fix_adjustable): Include BFD_RELOC_X86_64_GOTOFF64,
	BFD_RELOC_X86_64_DTPOFF64, and BFD_RELOC_X86_64_TPOFF64.
	(output_disp): Do GOTPC conversion also for BFD_RELOC_X86_64_32S
	and BFD_RELOC_32_PCREL. Use BFD_RELOC_X86_64_GOTPC32 instead of
	aborting.
	(output_imm): Do GOTPC conversion also for BFD_RELOC_X86_64_32S.
	Use BFD_RELOC_X86_64_GOTPC32 instead of aborting.
	(tc_gen_reloc): Do GOTPC conversion also for BFD_RELOC_32_PCREL.
	Use BFD_RELOC_X86_64_GOTPC32 instead of aborting. Also handle
	BFD_RELOC_X86_64_GOTOFF64, BFD_RELOC_X86_64_GOTPC32,
	BFD_RELOC_X86_64_DTPOFF64, and BFD_RELOC_X86_64_TPOFF64. Also
	convert 8-byte pc-relative relocations.
	(lex_got): Use BFD_RELOC_X86_64_GOTOFF64 for 64-bit @gotoff.
	(i386_validate_fix): Likewise.
	(x86_cons): Also handle quad values in 64-bit mode.
	(i386_displacement): Also handle BFD_RELOC_X86_64_GOTOFF64.
	(md_apply_fix): Include BFD_RELOC_X86_64_DTPOFF64 and
	BFD_RELOC_X86_64_TPOFF64 in the TLS check. Also convert BFD_RELOC_64
	to pc-relative variant. Also check for BFD_RELOC_64_PCREL.

gas/testsuite/
2005-06-16  Jan Beulich  <jbeulich@novell.com>

	* gas/i386/x86-64-pcrel.s: Add insn requiring 64-bit pc-relative
	relocation. Add insns for all widths of non-pc-relative relocations.
	* gas/i386/x86-64-pcrel.d: Adjust.

include/elf/
2005-06-16  Jan Beulich  <jbeulich@novell.com>

	* x86-64.h (elf_x86_64_reloc_type): Adjust comment for
	R_X86_64_GOTPCREL. Add R_X86_64_PC64, R_X86_64_GOTOFF64, and
	R_X86_64_GOTPC32.

--- /home/jbeulich/src/binutils/mainline/2005-06-16/bfd/bfd-in2.h	2005-06-08 14:50:36.000000000 +0200
+++ 2005-06-16/bfd/bfd-in2.h	2005-06-08 15:41:21.000000000 +0200
@@ -2617,6 +2617,8 @@ in the instruction.  */
   BFD_RELOC_X86_64_DTPOFF32,
   BFD_RELOC_X86_64_GOTTPOFF,
   BFD_RELOC_X86_64_TPOFF32,
+  BFD_RELOC_X86_64_GOTOFF64,
+  BFD_RELOC_X86_64_GOTPC32,
 
 /* ns32k relocations  */
   BFD_RELOC_NS32K_IMM_8,
--- /home/jbeulich/src/binutils/mainline/2005-06-16/bfd/elf64-x86-64.c	2005-05-18 08:09:48.000000000 +0200
+++ 2005-06-16/bfd/elf64-x86-64.c	2005-06-08 15:41:21.000000000 +0200
@@ -103,6 +103,15 @@ static reloc_howto_type x86_64_elf_howto
   HOWTO(R_X86_64_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
 	bfd_elf_generic_reloc, "R_X86_64_TPOFF32", FALSE, 0xffffffff,
 	0xffffffff, FALSE),
+  HOWTO(R_X86_64_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
+	bfd_elf_generic_reloc, "R_X86_64_PC64", FALSE, MINUS_ONE, MINUS_ONE,
+	TRUE),
+  HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+	bfd_elf_generic_reloc, "R_X86_64_GOTOFF64",
+	FALSE, MINUS_ONE, MINUS_ONE, FALSE),
+  HOWTO(R_X86_64_GOTPC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+	bfd_elf_generic_reloc, "R_X86_64_GOTPC32",
+	FALSE, 0xffffffff, 0xffffffff, TRUE),
 
 /* GNU extension to record C++ vtable hierarchy.  */
   HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont,
@@ -147,6 +156,9 @@ static const struct elf_reloc_map x86_64
   { BFD_RELOC_X86_64_DTPOFF32,	R_X86_64_DTPOFF32, },
   { BFD_RELOC_X86_64_GOTTPOFF,	R_X86_64_GOTTPOFF, },
   { BFD_RELOC_X86_64_TPOFF32,	R_X86_64_TPOFF32, },
+  { BFD_RELOC_64_PCREL,		R_X86_64_PC64, },
+  { BFD_RELOC_X86_64_GOTOFF64,	R_X86_64_GOTOFF64, },
+  { BFD_RELOC_X86_64_GOTPC32,	R_X86_64_GOTPC32, },
   { BFD_RELOC_VTABLE_INHERIT,	R_X86_64_GNU_VTINHERIT, },
   { BFD_RELOC_VTABLE_ENTRY,	R_X86_64_GNU_VTENTRY, },
 };
@@ -179,13 +191,13 @@ elf64_x86_64_info_to_howto (bfd *abfd AT
   r_type = ELF64_R_TYPE (dst->r_info);
   if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT)
     {
-      BFD_ASSERT (r_type <= (unsigned int) R_X86_64_TPOFF32);
+      BFD_ASSERT (r_type <= (unsigned int) R_X86_64_GOTPC32);
       i = r_type;
     }
   else
     {
       BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);
-      i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_TPOFF32 - 1);
+      i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_GOTPC32 - 1);
     }
   cache_ptr->howto = &x86_64_elf_howto_table[i];
   BFD_ASSERT (r_type == cache_ptr->howto->type);
@@ -749,7 +761,8 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	  }
 	  /* Fall through */
 
-	  //case R_X86_64_GOTPCREL:
+	case R_X86_64_GOTOFF64:
+	case R_X86_64_GOTPC32:
 	create_got:
 	  if (htab->sgot == NULL)
 	    {
@@ -802,6 +815,7 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	case R_X86_64_PC8:
 	case R_X86_64_PC16:
 	case R_X86_64_PC32:
+	case R_X86_64_PC64:
 	case R_X86_64_64:
 	  if (h != NULL && !info->shared)
 	    {
@@ -816,7 +830,7 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	      /* We may need a .plt entry if the function this reloc
 		 refers to is in a shared lib.  */
 	      h->plt.refcount += 1;
-	      if (r_type != R_X86_64_PC32)
+	      if (r_type != R_X86_64_PC32 && r_type != R_X86_64_PC64)
 		h->pointer_equality_needed = 1;
 	    }
 
@@ -845,7 +859,8 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	       && (sec->flags & SEC_ALLOC) != 0
 	       && (((r_type != R_X86_64_PC8)
 		    && (r_type != R_X86_64_PC16)
-		    && (r_type != R_X86_64_PC32))
+		    && (r_type != R_X86_64_PC32)
+		    && (r_type != R_X86_64_PC64))
 		   || (h != NULL
 		       && (! info->symbolic
 			   || h->root.type == bfd_link_hash_defweak
@@ -948,7 +963,8 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	      p->count += 1;
 	      if (r_type == R_X86_64_PC8
 		  || r_type == R_X86_64_PC16
-		  || r_type == R_X86_64_PC32)
+		  || r_type == R_X86_64_PC32
+		  || r_type == R_X86_64_PC64)
 		p->pc_count += 1;
 	    }
 	  break;
@@ -1093,6 +1109,7 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, s
 	case R_X86_64_PC8:
 	case R_X86_64_PC16:
 	case R_X86_64_PC32:
+	case R_X86_64_PC64:
 	  if (info->shared)
 	    break;
 	  /* Fall thru */
@@ -1941,6 +1958,42 @@ elf64_x86_64_relocate_section (bfd *outp
 
 	  break;
 
+	case R_X86_64_GOTOFF64:
+	  /* Relocation is relative to the start of the global offset
+	     table.  */
+
+	  /* Check to make sure it isn't a protected function symbol
+	     for shared library since it may not be local when used
+	     as function address.  */
+	  if (info->shared
+	      && h
+	      && h->def_regular
+	      && h->type == STT_FUNC
+	      && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+	    {
+	      (*_bfd_error_handler)
+		(_("%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"),
+		 input_bfd, h->root.root.string);
+	      bfd_set_error (bfd_error_bad_value);
+	      return FALSE;
+	    }
+
+	  /* Note that sgot is not involved in this
+	     calculation.  We always want the start of .got.plt.  If we
+	     defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
+	     permitted by the ABI, we might have to change this
+	     calculation.  */
+	  relocation -= htab->sgotplt->output_section->vma
+			+ htab->sgotplt->output_offset;
+	  break;
+
+	case R_X86_64_GOTPC32:
+	  /* Use global offset table as symbol value.  */
+	  relocation = htab->sgotplt->output_section->vma
+		       + htab->sgotplt->output_offset;
+	  unresolved_reloc = FALSE;
+	  break;
+
 	case R_X86_64_PLT32:
 	  /* Relocation is to the entry for this symbol in the
 	     procedure linkage table.  */
@@ -1999,6 +2052,7 @@ elf64_x86_64_relocate_section (bfd *outp
 	case R_X86_64_8:
 	case R_X86_64_16:
 	case R_X86_64_32:
+	case R_X86_64_PC64:
 	case R_X86_64_64:
 	  /* FIXME: The ABI says the linker should make sure the value is
 	     the same when it's zeroextended to 64 bit.	 */
@@ -2016,7 +2070,8 @@ elf64_x86_64_relocate_section (bfd *outp
 		   || h->root.type != bfd_link_hash_undefweak)
 	       && ((r_type != R_X86_64_PC8
 		    && r_type != R_X86_64_PC16
-		    && r_type != R_X86_64_PC32)
+		    && r_type != R_X86_64_PC32
+		    && r_type != R_X86_64_PC64)
 		   || !SYMBOL_CALLS_LOCAL (info, h)))
 	      || (ELIMINATE_COPY_RELOCS
 		  && !info->shared
@@ -2060,6 +2115,7 @@ elf64_x86_64_relocate_section (bfd *outp
 		       && (r_type == R_X86_64_PC8
 			   || r_type == R_X86_64_PC16
 			   || r_type == R_X86_64_PC32
+			   || r_type == R_X86_64_PC64
 			   || !info->shared
 			   || !info->symbolic
 			   || !h->def_regular))
--- /home/jbeulich/src/binutils/mainline/2005-06-16/bfd/libbfd.h	2005-06-08 14:50:42.000000000 +0200
+++ 2005-06-16/bfd/libbfd.h	2005-06-08 15:41:21.000000000 +0200
@@ -1049,6 +1049,8 @@ static const char *const bfd_reloc_code_
   "BFD_RELOC_X86_64_DTPOFF32",
   "BFD_RELOC_X86_64_GOTTPOFF",
   "BFD_RELOC_X86_64_TPOFF32",
+  "BFD_RELOC_X86_64_GOTOFF64",
+  "BFD_RELOC_X86_64_GOTPC32",
   "BFD_RELOC_NS32K_IMM_8",
   "BFD_RELOC_NS32K_IMM_16",
   "BFD_RELOC_NS32K_IMM_32",
--- /home/jbeulich/src/binutils/mainline/2005-06-16/gas/config/tc-i386.c	2005-06-08 14:50:49.000000000 +0200
+++ 2005-06-16/gas/config/tc-i386.c	2005-06-16 15:43:25.923892176 +0200
@@ -1222,6 +1222,7 @@ reloc (size, pcrel, sign, other)
 	case 1: return BFD_RELOC_8_PCREL;
 	case 2: return BFD_RELOC_16_PCREL;
 	case 4: return BFD_RELOC_32_PCREL;
+	case 8: return BFD_RELOC_64_PCREL;
 	}
       as_bad (_("can not do %d byte pc-relative relocation"), size);
     }
@@ -1292,8 +1293,11 @@ tc_i386_fix_adjustable (fixP)
       || fixP->fx_r_type == BFD_RELOC_X86_64_TLSGD
       || fixP->fx_r_type == BFD_RELOC_X86_64_TLSLD
       || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32
+      || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF64
       || fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF
       || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32
+      || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF64
+      || fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64
       || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
     return 0;
@@ -3502,14 +3506,16 @@ output_disp (insn_start_frag, insn_start
 
 	      p = frag_more (size);
 	      reloc_type = reloc (size, pcrel, sign, i.reloc[n]);
-	      if (reloc_type == BFD_RELOC_32
-		  && GOT_symbol
+	      if (GOT_symbol
 		  && GOT_symbol == i.op[n].disps->X_add_symbol
-		  && (i.op[n].disps->X_op == O_symbol
-		      || (i.op[n].disps->X_op == O_add
-			  && ((symbol_get_value_expression
-			       (i.op[n].disps->X_op_symbol)->X_op)
-			      == O_subtract))))
+		  && (((reloc_type == BFD_RELOC_32
+			|| reloc_type == BFD_RELOC_X86_64_32S)
+		       && (i.op[n].disps->X_op == O_symbol
+			   || (i.op[n].disps->X_op == O_add
+			       && ((symbol_get_value_expression
+				    (i.op[n].disps->X_op_symbol)->X_op)
+				   == O_subtract))))
+		      || reloc_type == BFD_RELOC_32_PCREL))
 		{
 		  offsetT add;
 
@@ -3526,10 +3532,10 @@ output_disp (insn_start_frag, insn_start
 		      add += p - frag_now->fr_literal;
 		    }
 
-		  /* We don't support dynamic linking on x86-64 yet.  */
-		  if (flag_code == CODE_64BIT)
-		    abort ();
-		  reloc_type = BFD_RELOC_386_GOTPC;
+		  if (flag_code != CODE_64BIT)
+		    reloc_type = BFD_RELOC_386_GOTPC;
+		  else
+		    reloc_type = BFD_RELOC_X86_64_GOTPC32;
 		  i.op[n].disps->X_add_number += add;
 		}
 	      fix_new_exp (frag_now, p - frag_now->fr_literal, size,
@@ -3638,7 +3644,8 @@ output_imm (insn_start_frag, insn_start_
 	       * since the expression is not pcrel, I felt it would be
 	       * confusing to do it this way.  */
 
-	      if (reloc_type == BFD_RELOC_32
+	      if ((reloc_type == BFD_RELOC_32
+		   || reloc_type == BFD_RELOC_X86_64_32S)
 		  && GOT_symbol
 		  && GOT_symbol == i.op[n].imms->X_add_symbol
 		  && (i.op[n].imms->X_op == O_symbol
@@ -3662,10 +3669,10 @@ output_imm (insn_start_frag, insn_start_
 		      add += p - frag_now->fr_literal;
 		    }
 
-		  /* We don't support dynamic linking on x86-64 yet.  */
-		  if (flag_code == CODE_64BIT)
-		    abort ();
-		  reloc_type = BFD_RELOC_386_GOTPC;
+		  if (flag_code != CODE_64BIT)
+		    reloc_type = BFD_RELOC_386_GOTPC;
+		  else
+		    reloc_type = BFD_RELOC_X86_64_GOTPC32;
 		  i.op[n].imms->X_add_number += add;
 		}
 	      fix_new_exp (frag_now, p - frag_now->fr_literal, size,
@@ -3698,7 +3705,7 @@ lex_got (reloc, adjust)
     const enum bfd_reloc_code_real rel[NUM_FLAG_CODE];
   } gotrel[] = {
     { "PLT",      { BFD_RELOC_386_PLT32,      0, BFD_RELOC_X86_64_PLT32    } },
-    { "GOTOFF",   { BFD_RELOC_386_GOTOFF,     0, 0                         } },
+    { "GOTOFF",   { BFD_RELOC_386_GOTOFF,     0, BFD_RELOC_X86_64_GOTOFF64 } },
     { "GOTPCREL", { 0,                        0, BFD_RELOC_X86_64_GOTPCREL } },
     { "TLSGD",    { BFD_RELOC_386_TLS_GD,     0, BFD_RELOC_X86_64_TLSGD    } },
     { "TLSLDM",   { BFD_RELOC_386_TLS_LDM,    0, 0                         } },
@@ -3792,7 +3799,7 @@ x86_cons (exp, size)
      expressionS *exp;
      int size;
 {
-  if (size == 4)
+  if (size == 4 || (flag_code == CODE_64BIT && size == 8))
     {
       /* Handle @GOTOFF and the like in an expression.  */
       char *save;
@@ -4104,7 +4111,8 @@ i386_displacement (disp_start, disp_end)
      the symbol table.  We will ultimately change the relocation
      to be relative to the beginning of the section.  */
   if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF
-      || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
+      || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL
+      || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64)
     {
       if (exp->X_op != O_symbol)
 	{
@@ -4122,6 +4130,8 @@ i386_displacement (disp_start, disp_end)
       exp->X_op_symbol = GOT_symbol;
       if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
 	i.reloc[this_operand] = BFD_RELOC_32_PCREL;
+      else if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64)
+	i.reloc[this_operand] = BFD_RELOC_64;
       else
 	i.reloc[this_operand] = BFD_RELOC_32;
     }
@@ -4812,6 +4822,9 @@ md_apply_fix (fixP, valP, seg)
 	default:
 	  break;
 
+	case BFD_RELOC_64:
+	  fixP->fx_r_type = BFD_RELOC_64_PCREL;
+	  break;
 	case BFD_RELOC_32:
 	case BFD_RELOC_X86_64_32S:
 	  fixP->fx_r_type = BFD_RELOC_32_PCREL;
@@ -4827,6 +4840,7 @@ md_apply_fix (fixP, valP, seg)
 
   if (fixP->fx_addsy != NULL
       && (fixP->fx_r_type == BFD_RELOC_32_PCREL
+	  || fixP->fx_r_type == BFD_RELOC_64_PCREL
 	  || fixP->fx_r_type == BFD_RELOC_16_PCREL
 	  || fixP->fx_r_type == BFD_RELOC_8_PCREL)
       && !use_rela_relocations)
@@ -4901,7 +4915,9 @@ md_apply_fix (fixP, valP, seg)
       case BFD_RELOC_386_TLS_LDO_32:
       case BFD_RELOC_386_TLS_LE_32:
       case BFD_RELOC_X86_64_DTPOFF32:
+      case BFD_RELOC_X86_64_DTPOFF64:
       case BFD_RELOC_X86_64_TPOFF32:
+      case BFD_RELOC_X86_64_TPOFF64:
 	S_SET_THREAD_LOCAL (fixP->fx_addsy);
 	break;
 
@@ -5339,7 +5355,6 @@ i386_validate_fix (fixp)
 {
   if (fixp->fx_subsy && fixp->fx_subsy == GOT_symbol)
     {
-      /* GOTOFF relocation are nonsense in 64bit mode.  */
       if (fixp->fx_r_type == BFD_RELOC_32_PCREL)
 	{
 	  if (flag_code != CODE_64BIT)
@@ -5348,9 +5363,10 @@ i386_validate_fix (fixp)
 	}
       else
 	{
-	  if (flag_code == CODE_64BIT)
-	    abort ();
-	  fixp->fx_r_type = BFD_RELOC_386_GOTOFF;
+	  if (flag_code != CODE_64BIT)
+	    fixp->fx_r_type = BFD_RELOC_386_GOTOFF;
+	  else
+	    fixp->fx_r_type = BFD_RELOC_X86_64_GOTOFF64;
 	}
       fixp->fx_subsy = 0;
     }
@@ -5384,8 +5400,12 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_X86_64_TLSGD:
     case BFD_RELOC_X86_64_TLSLD:
     case BFD_RELOC_X86_64_DTPOFF32:
+    case BFD_RELOC_X86_64_DTPOFF64:
     case BFD_RELOC_X86_64_GOTTPOFF:
     case BFD_RELOC_X86_64_TPOFF32:
+    case BFD_RELOC_X86_64_TPOFF64:
+    case BFD_RELOC_X86_64_GOTOFF64:
+    case BFD_RELOC_X86_64_GOTPC32:
     case BFD_RELOC_RVA:
     case BFD_RELOC_VTABLE_ENTRY:
     case BFD_RELOC_VTABLE_INHERIT:
@@ -5415,6 +5435,9 @@ tc_gen_reloc (section, fixp)
 	    case 1: code = BFD_RELOC_8_PCREL;  break;
 	    case 2: code = BFD_RELOC_16_PCREL; break;
 	    case 4: code = BFD_RELOC_32_PCREL; break;
+#ifdef BFD64
+	    case 8: code = BFD_RELOC_64_PCREL; break;
+#endif
 	    }
 	}
       else
@@ -5438,14 +5461,14 @@ tc_gen_reloc (section, fixp)
       break;
     }
 
-  if (code == BFD_RELOC_32
+  if ((code == BFD_RELOC_32 || code == BFD_RELOC_32_PCREL)
       && GOT_symbol
       && fixp->fx_addsy == GOT_symbol)
     {
-      /* We don't support GOTPC on 64bit targets.  */
-      if (flag_code == CODE_64BIT)
-	abort ();
-      code = BFD_RELOC_386_GOTPC;
+      if (flag_code != CODE_64BIT)
+	code = BFD_RELOC_386_GOTPC;
+      else
+	code = BFD_RELOC_X86_64_GOTPC32;
     }
 
   rel = (arelent *) xmalloc (sizeof (arelent));
--- /home/jbeulich/src/binutils/mainline/2005-06-16/gas/testsuite/gas/i386/x86-64-pcrel.d	2005-04-11 08:11:28.000000000 +0200
+++ 2005-06-16/gas/testsuite/gas/i386/x86-64-pcrel.d	2005-06-08 15:41:21.000000000 +0200
@@ -8,7 +8,12 @@ Disassembly of section .text:
 0+000 <_start>:
 [	 ]*[0-9a-f]+:[	 ]+b0 00[	 ]+movb?[	 ]+\$(0x)?0,%al[	 ]*[0-9a-f]+:[	 ]+R_X86_64_PC8[	 ]+xtrn\+(0x)?1
 [	 ]*[0-9a-f]+:[	 ]+66 b8 00 00[	 ]+movw?[	 ]+\$(0x)?0,%ax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_PC16[	 ]+xtrn\+(0x)?2
-[	 ]*[0-9a-f]+:[	 ]+b8 00 00 00 00[	 ]+movl?[	 ]+\$(0x)?0,%eax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_PC32[	 ]+xtrn\+(0x)?1
-[	 ]*[0-9a-f]+:[	 ]+48 c7 c0 00 00 00 00[	 ]+movq?[	 ]+\$(0x)?0,%rax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_PC32[	 ]+xtrn\+(0x)?3
-[	 ]*[0-9a-f]+:[	 ]+48 c7 c0 00 00 00 00[	 ]+movq?[	 ]+\$(0x)?0,%rax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_32S[	 ]+xtrn
+[	 ]*[0-9a-f]+:[	 ]+b8( 00){4}[	 ]+movl?[	 ]+\$(0x)?0,%eax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_PC32[	 ]+xtrn\+(0x)?1
+[	 ]*[0-9a-f]+:[	 ]+48 c7 c0( 00){4}[	 ]+movq?[	 ]+\$(0x)?0,%rax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_PC32[	 ]+xtrn\+(0x)?3
+[	 ]*[0-9a-f]+:[	 ]+48 b8( 00){8}[	 ]+mov(abs)?q?[	 ]+\$(0x)?0,%rax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_PC64[	 ]+xtrn\+(0x)?2
+[	 ]*[0-9a-f]+:[	 ]+b0 00[	 ]+movb?[	 ]+\$(0x)?0,%al[	 ]*[0-9a-f]+:[	 ]+R_X86_64_8[	 ]+xtrn
+[	 ]*[0-9a-f]+:[	 ]+66 b8 00 00[	 ]+movw?[	 ]+\$(0x)?0,%ax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_16[	 ]+xtrn
+[	 ]*[0-9a-f]+:[	 ]+b8( 00){4}[	 ]+movl?[	 ]+\$(0x)?0,%eax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_32[	 ]+xtrn
+[	 ]*[0-9a-f]+:[	 ]+48 c7 c0( 00){4}[	 ]+movq?[	 ]+\$(0x)?0,%rax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_32S[	 ]+xtrn
+[	 ]*[0-9a-f]+:[	 ]+48 b8( 00){8}[	 ]+mov(abs)?q?[	 ]+\$(0x)?0,%rax[	 ]*[0-9a-f]+:[	 ]+R_X86_64_64[	 ]+xtrn
 #pass
--- /home/jbeulich/src/binutils/mainline/2005-06-16/gas/testsuite/gas/i386/x86-64-pcrel.s	2005-04-11 08:11:28.000000000 +0200
+++ 2005-06-16/gas/testsuite/gas/i386/x86-64-pcrel.s	2005-06-08 15:41:21.000000000 +0200
@@ -4,6 +4,12 @@ _start:
 	movw	$(xtrn - .), %ax
 	movl	$(xtrn - .), %eax
 	movq	$(xtrn - .), %rax
+	movabsq	$(xtrn - .), %rax
+
+	movb	$xtrn, %al
+	movw	$xtrn, %ax
+	movl	$xtrn, %eax
 	movq	$xtrn, %rax
+	movabsq	$xtrn, %rax
 
 	.p2align 4,0
--- /home/jbeulich/src/binutils/mainline/2005-06-16/include/elf/x86-64.h	2005-05-13 12:17:11.000000000 +0200
+++ 2005-06-16/include/elf/x86-64.h	2005-06-08 15:41:21.000000000 +0200
@@ -34,7 +34,7 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_ty
      RELOC_NUMBER (R_X86_64_JUMP_SLOT,7)      /* Create PLT entry */
      RELOC_NUMBER (R_X86_64_RELATIVE, 8)      /* Adjust by program base */
      RELOC_NUMBER (R_X86_64_GOTPCREL, 9)      /* 32 bit signed pc relative
-                                                 offset to GOT */
+                                                 offset to GOT entry */
      RELOC_NUMBER (R_X86_64_32,       10)     /* Direct 32 bit zero extended */
      RELOC_NUMBER (R_X86_64_32S,      11)     /* Direct 32 bit sign extended */
      RELOC_NUMBER (R_X86_64_16,       12)     /* Direct 16 bit zero extended */
@@ -49,6 +49,10 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_ty
      RELOC_NUMBER (R_X86_64_DTPOFF32, 21)     /* Offset in TLS block */
      RELOC_NUMBER (R_X86_64_GOTTPOFF, 22)     /* PC relative offset to IE GOT entry */
      RELOC_NUMBER (R_X86_64_TPOFF32,  23)     /* Offset in initial TLS block */
+     RELOC_NUMBER (R_X86_64_PC64,     24)     /* PC relative 64 bit */
+     RELOC_NUMBER (R_X86_64_GOTOFF64, 25)     /* 64 bit offset to GOT */
+     RELOC_NUMBER (R_X86_64_GOTPC32,  26)     /* 32 bit signed pc relative
+                                                 offset to GOT */
      RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250)       /* GNU C++ hack  */
      RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251)         /* GNU C++ hack  */
 END_RELOC_NUMBERS (R_X86_64_max)

Attachment: binutils-mainline-x86_64-abi095-relocs.patch
Description: Text document


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