bfd/
authorJan Beulich <jbeulich@novell.com>
Fri, 17 Jun 2005 08:03:59 +0000 (08:03 +0000)
committerJan Beulich <jbeulich@novell.com>
Fri, 17 Jun 2005 08:03:59 +0000 (08:03 +0000)
2005-06-17  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-17  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-17  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-17  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.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf64-x86-64.c
bfd/libbfd.h
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/x86-64-pcrel.d
gas/testsuite/gas/i386/x86-64-pcrel.s
include/elf/ChangeLog
include/elf/x86-64.h

index 12e06b6..f374000 100644 (file)
@@ -1,3 +1,18 @@
+2005-06-17  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.
+
 2005-06-15  Mark Kettenis  <kettenis@gnu.org>
 
        * archive.c: Include "libiberty.h".
index 739277c..1107dc4 100644 (file)
@@ -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,
index 179530b..f63fd03 100644 (file)
@@ -103,6 +103,15 @@ static reloc_howto_type x86_64_elf_howto_table[] =
   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_reloc_map[] =
   { 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 ATTRIBUTE_UNUSED, arelent *cache_ptr,
   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, struct bfd_link_info *info, asection *sec,
          }
          /* 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, struct bfd_link_info *info, asection *sec,
        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, struct bfd_link_info *info, asection *sec,
              /* 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, struct bfd_link_info *info, asection *sec,
               && (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, struct bfd_link_info *info, asection *sec,
              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, struct bfd_link_info *info,
        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 *output_bfd, struct bfd_link_info *info,
 
          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 *output_bfd, struct bfd_link_info *info,
        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 *output_bfd, struct bfd_link_info *info,
                   || 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 *output_bfd, struct bfd_link_info *info,
                       && (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))
index a318744..df2fbca 100644 (file)
@@ -1049,6 +1049,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "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",
index 6ca9791..fc33e1b 100644 (file)
@@ -1,3 +1,26 @@
+2005-06-17  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.
+
 2005-06-13  Zack Weinberg  <zack@codesourcery.com>
 
        * config/tc-arm.c (find_real_start): Check S_IS_LOCAL on
index 0095797..18df9cf 100644 (file)
@@ -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_off)
 
              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_off)
                      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_off)
               * 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_off)
                      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));
index 35f59b9..1dd1ccf 100644 (file)
@@ -1,3 +1,9 @@
+2005-06-17  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.
+
 2005-06-13  Zack Weinberg  <zack@codesourcery.com>
 
        * gas/arm/thumb.s: Only branch to labels defined in this file.
index 3d647bf..3be86c7 100644 (file)
@@ -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
index c58e093..d4dcd9e 100644 (file)
@@ -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
index 8aa8fe7..40d7853 100644 (file)
@@ -1,3 +1,9 @@
+2005-06-17  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.
+
 2005-06-07  Aldy Hernandez  <aldyh@redhat.com>
            Michael Snyder  <msnyder@redhat.com>
            Stan Cox  <scox@redhat.com>
index ed6f0d9..d83fc20 100644 (file)
@@ -34,7 +34,7 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_type)
      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_type)
      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)