[PATCH] x86-64: support newer relocation types

Jan Hubicka hubicka@ucw.cz
Sun Jun 12 12:28:00 GMT 2005


> This adds support for the new x86-64 relocation types added in ABI draft
> 0.95 (or in a slightly earlier version). In addition, it fixes the overflow
> complaint types for two x86-64 and one i386 relocation types.
> 
> Built and tested on i686-pc-linux-gnu and x86_64-unknown-linux-gnu.

Hi,
as mentioned off-list, we (Jan and me) developed two implementations of
the binutils changes independently.  I was holding the patch as I wanted
to do the changes in sync with GCC that was frozen at that point (I will
update the GCC patch this week too as it is now good time to submit it).
I am sorry that this lead to diplicated effort.

My one also contains the changes to linker script needed to get medium
model working, but since Jan's implementation is more up-to-date I think
the best scheme is to go with his patch and I will break out remaining
pieces out of my patch once new relocations are in place.  Also I think
I can approve this patch as x86-64 maintainer, but I don't feel
competent to comment on linker script stuff.

I have however few problems with the patch...

> --- /home/jbeulich/src/binutils/mainline/2005-06-08/bfd/elf32-i386.c	2005-06-08 14:50:38.000000000 +0200
> +++ 2005-06-08/bfd/elf32-i386.c	2005-06-08 15:41:20.913778616 +0200
> @@ -95,7 +95,7 @@ static reloc_howto_type elf_howto_table[
>    HOWTO(R_386_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
>  	bfd_elf_generic_reloc, "R_386_16",
>  	TRUE, 0xffff, 0xffff, FALSE),
> -  HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
> +  HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_signed,

I would preffer to handle this via separate patch (even tought the
change looks correct to me, see bellow)
>  	bfd_elf_generic_reloc, "R_386_PC16",
>  	TRUE, 0xffff, 0xffff, TRUE),
>    HOWTO(R_386_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
> --- /home/jbeulich/src/binutils/mainline/2005-06-08/bfd/elf64-x86-64.c	2005-05-18 08:09:48.000000000 +0200
> +++ 2005-06-08/bfd/elf64-x86-64.c	2005-06-08 15:41:20.944773904 +0200
> @@ -73,9 +73,9 @@ static reloc_howto_type x86_64_elf_howto
>  	FALSE),
>    HOWTO(R_X86_64_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
>  	bfd_elf_generic_reloc, "R_X86_64_16", FALSE, 0xffff, 0xffff, FALSE),
> -  HOWTO(R_X86_64_PC16,0, 1, 16, TRUE, 0, complain_overflow_bitfield,
> +  HOWTO(R_X86_64_PC16,0, 1, 16, TRUE, 0, complain_overflow_signed,
>  	bfd_elf_generic_reloc, "R_X86_64_PC16", FALSE, 0xffff, 0xffff, TRUE),
> -  HOWTO(R_X86_64_8, 0, 0, 8, FALSE, 0, complain_overflow_signed,
> +  HOWTO(R_X86_64_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
>  	bfd_elf_generic_reloc, "R_X86_64_8", FALSE, 0xff, 0xff, FALSE),
>    HOWTO(R_X86_64_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
>  	bfd_elf_generic_reloc, "R_X86_64_PC8", FALSE, 0xff, 0xff, TRUE),
> @@ -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),


Well, mine version reads here:
+   HOWTO(R_X86_64_PC64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
+ 	bfd_elf_generic_reloc, "R_X86_64_PC64", FALSE, MINUS_ONE, MINUS_ONE,
+ 	TRUE),

I think Jan's patch is correct in this respect (as unlike for smaller
relocation times, the address "wrap around"), but please double check.

> +	  /* 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;


There is another difference relative to my implementation:

+ 	  /* Note that sgot->output_offset is not involved in this
+ 	     calculation.  We always want the start of .got.  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->sgot->output_section->vma;
+ 	  break;
+ 
+ 	case R_X86_64_GOTPC32:
+ 	  /* Use global offset table as symbol value.  */
+ 	  relocation = htab->sgot->output_section->vma;
+ 	  unresolved_reloc = FALSE;
+ 	  break;
+ 

Mine implementation went out from kind of trial and error process to get
the numbers in relocations right, so your's might be correct, but it
clearly shows that I am not competent to review this portion of patch so
I would preffer someone more BFD aware to comment here.

> +
>  	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-08/bfd/libbfd.h	2005-06-08 14:50:42.000000000 +0200
> +++ 2005-06-08/bfd/libbfd.h	2005-06-08 15:41:20.948773296 +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-08/gas/config/tc-i386.c	2005-06-08 14:50:49.000000000 +0200
> +++ 2005-06-08/gas/config/tc-i386.c	2005-06-08 15:41:20.962771168 +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);
>      }
> @@ -1294,6 +1295,7 @@ tc_i386_fix_adjustable (fixP)
>        || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32
>        || 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_GOTOFF64
>        || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
>        || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
>      return 0;

I think you need to add matching of GOT relative arithmetics:
*************** output_disp (insn_start_frag, insn_start
*** 3336,3353 ****
  
  	      p = frag_more (size);
  	      reloc_type = reloc (size, pcrel, sign, i.reloc[n]);
! 	      if (reloc_type == BFD_RELOC_32
! 		  && 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))))
  		{
  		  offsetT add;
  
! 		  if (insn_start_frag == frag_now)
  		    add = (p - frag_now->fr_literal) - insn_start_off;
  		  else
  		    {
--- 3338,3360 ----
  
  	      p = frag_more (size);
  	      reloc_type = reloc (size, pcrel, sign, i.reloc[n]);
! 	      if ((reloc_type == BFD_RELOC_32
! 		   && 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_PCREL
! 		      && GOT_symbol
! 		      && GOT_symbol == i.op[n].disps->X_add_symbol))
  		{
  		  offsetT add;
  
! 		  if (flag_code == CODE_64BIT)
! 		    add = 0;
! 		  else if (insn_start_frag == frag_now)
  		    add = (p - frag_now->fr_literal) - insn_start_off;
  		  else
  		    {

> @@ -3526,10 +3528,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,

And here too:
*************** output_imm (insn_start_frag, insn_start_
*** 3471,3484 ****
  	       * since the expression is not pcrel, I felt it would be
  	       * confusing to do it this way.  */
  
! 	      if (reloc_type == BFD_RELOC_32
! 		  && GOT_symbol
! 		  && GOT_symbol == i.op[n].imms->X_add_symbol
! 		  && (i.op[n].imms->X_op == O_symbol
! 		      || (i.op[n].imms->X_op == O_add
! 			  && ((symbol_get_value_expression
! 			       (i.op[n].imms->X_op_symbol)->X_op)
! 			      == O_subtract))))
  		{
  		  offsetT add;
  
--- 3478,3494 ----
  	       * since the expression is not pcrel, I felt it would be
  	       * confusing to do it this way.  */
  
! 	      if ((reloc_type == BFD_RELOC_32
! 		   && GOT_symbol
! 		   && GOT_symbol == i.op[n].imms->X_add_symbol
! 		   && (i.op[n].imms->X_op == O_symbol
! 		       || (i.op[n].imms->X_op == O_add
! 			   && ((symbol_get_value_expression
! 				(i.op[n].imms->X_op_symbol)->X_op)
! 			       == O_subtract))))
! 		  || (reloc_type == BFD_RELOC_32_PCREL
! 		      && GOT_symbol
! 		      && GOT_symbol == i.op[n].disps->X_add_symbol))
  		{
  		  offsetT add;
  
> @@ -3662,10 +3664,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 +3700,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 +3794,7 @@ x86_cons (exp, size)

And here the GOT relocation:
*************** lex_got (reloc, adjust)
*** 3542,3548 ****
      { "DTPOFF",   { BFD_RELOC_386_TLS_LDO_32, 0, BFD_RELOC_X86_64_DTPOFF32 } },
      { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE,  0, 0                         } },
      { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE,     0, 0                         } },
!     { "GOT",      { BFD_RELOC_386_GOT32,      0, BFD_RELOC_X86_64_GOT32    } }
    };
    char *cp;
    unsigned int j;
--- 3552,3558 ----
      { "DTPOFF",   { BFD_RELOC_386_TLS_LDO_32, 0, BFD_RELOC_X86_64_DTPOFF32 } },
      { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE,  0, 0                         } },
      { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE,     0, 0                         } },
!     { "GOT",      { BFD_RELOC_386_GOT32,      0, BFD_RELOC_X86_64_GOT32    } },
    };
    char *cp;
    unsigned int j;

>       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 +4106,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 +4125,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 +4817,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 +4835,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)
> @@ -5339,7 +5348,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 +5356,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;
>      }
> @@ -5386,6 +5395,8 @@ tc_gen_reloc (section, fixp)
>      case BFD_RELOC_X86_64_DTPOFF32:
>      case BFD_RELOC_X86_64_GOTTPOFF:
>      case BFD_RELOC_X86_64_TPOFF32:
> +    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 +5426,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
> @@ -5442,10 +5456,10 @@ tc_gen_reloc (section, fixp)
>        && 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));
And GOT arithmetic here...
*************** tc_gen_reloc (section, fixp)
*** 5252,5265 ****
        break;
      }
  
!   if (code == BFD_RELOC_32
        && 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;
      }
  
    rel = (arelent *) xmalloc (sizeof (arelent));
--- 5275,5288 ----
        break;
      }
  
!   if ((code == BFD_RELOC_32 || code == BFD_RELOC_32_PCREL)
        && GOT_symbol
        && fixp->fx_addsy == GOT_symbol)
      {
        if (flag_code == CODE_64BIT)
!         code = BFD_RELOC_X86_64_GOTPC32;
!       else
!         code = BFD_RELOC_386_GOTPC;
      }
  
    rel = (arelent *) xmalloc (sizeof (arelent));
> --- /home/jbeulich/src/binutils/mainline/2005-06-08/gas/testsuite/gas/i386/x86-64-pcrel.d	2005-04-11 08:11:28.000000000 +0200
> +++ 2005-06-08/gas/testsuite/gas/i386/x86-64-pcrel.d	2005-06-08 15:41:20.964770864 +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-08/gas/testsuite/gas/i386/x86-64-pcrel.s	2005-04-11 08:11:28.000000000 +0200
> +++ 2005-06-08/gas/testsuite/gas/i386/x86-64-pcrel.s	2005-06-08 15:41:20.966770560 +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-08/include/elf/x86-64.h	2005-05-13 12:17:11.000000000 +0200
> +++ 2005-06-08/include/elf/x86-64.h	2005-06-08 15:41:20.967770408 +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)
> 

Otherwise our patches are almost equivalent (so I believe they are
correct ;).  I would preffer the tc-i386.c changes  (even if the
arithmetic syntax can be added incrementally) to go in and someone BFD
aware to comment on the relocatino handling issues, but otherwise the
patch would be OK.

Thanks,
Honza



More information about the Binutils mailing list