]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2007-12-07 Bob Wilson <bob.wilson@acm.org>
authorBob Wilson <bob.wilson@acm.org>
Fri, 7 Dec 2007 22:52:10 +0000 (22:52 +0000)
committerBob Wilson <bob.wilson@acm.org>
Fri, 7 Dec 2007 22:52:10 +0000 (22:52 +0000)
include/elf/
* xtensa.h (R_XTENSA_32_PCREL): New.

bfd/
* elf32-xtensa.c (elf_howto_table): Add R_XTENSA_32_PCREL.
(elf_xtensa_reloc_type_lookup): Handle BFD_RELOC_32_PCREL.
(elf_xtensa_check_relocs): Use default case for all relocations that
need nothing done here.
(elf_xtensa_do_reloc): Compute self_address for all relocation types.
Handle R_XTENSA_32_PCREL.
(elf_xtensa_relocate_section): Check for R_XTENSA_32_PCREL for dynamic
symbols.
(check_section_ebb_pcrels_fit): Ignore R_XTENSA_32_PCREL relocations.

gas/
* config/tc-xtensa.c (O_pcrel): Define.
(suffix_relocs): Add pcrel suffix.
(md_pseudo_table): Add 4byte and 2byte directives.
(xtensa_elf_cons): Pass correct pcrel argument to fix_new_exp.
(xg_assemble_literal): Likewise.  Check for O_pcrel.
(expression_maybe_register): Reorganize.  Handle BFD_RELOC_32_PCREL.
(xg_valid_literal_expression): Allow O_pcrel.
(md_pcrel_from, md_apply_fix): Handle BFD_RELOC_32_PCREL.
(tc_gen_reloc): Fix punctuation in error message.

gas/testsuite/
* gas/xtensa/all.exp: Run new pcrel test.
* gas/xtensa/err-pcrel.s: New.
* gas/xtensa/pcrel.d: New.
* gas/xtensa/pcrel.s: New.
* gas/xtensa/xtensa-err.exp: New.

12 files changed:
bfd/ChangeLog
bfd/elf32-xtensa.c
gas/ChangeLog
gas/config/tc-xtensa.c
gas/testsuite/ChangeLog
gas/testsuite/gas/xtensa/all.exp
gas/testsuite/gas/xtensa/err-pcrel.s [new file with mode: 0644]
gas/testsuite/gas/xtensa/pcrel.d [new file with mode: 0644]
gas/testsuite/gas/xtensa/pcrel.s [new file with mode: 0644]
gas/testsuite/gas/xtensa/xtensa-err.exp [new file with mode: 0644]
include/elf/ChangeLog
include/elf/xtensa.h

index fbe5928c06721072bb4e3976c236531d2562471f..75e1c2f4addacf237d99a8bdf6f62f05b64d677d 100644 (file)
@@ -1,3 +1,15 @@
+2007-12-07  Bob Wilson  <bob.wilson@acm.org>
+
+       * elf32-xtensa.c (elf_howto_table): Add R_XTENSA_32_PCREL.
+       (elf_xtensa_reloc_type_lookup): Handle BFD_RELOC_32_PCREL.
+       (elf_xtensa_check_relocs): Use default case for all relocations that
+       need nothing done here.
+       (elf_xtensa_do_reloc): Compute self_address for all relocation types.
+       Handle R_XTENSA_32_PCREL.
+       (elf_xtensa_relocate_section): Check for R_XTENSA_32_PCREL for dynamic
+       symbols.
+       (check_section_ebb_pcrels_fit): Ignore R_XTENSA_32_PCREL relocations.
+       
 2007-12-05  Alan Modra  <amodra@bigpond.net.au>
 
        * elf32-spu.c (spu_elf_size_stubs): Do consider branches to
index c45a18c5bbfdd93832bb1bdc4e8197624cd5f89e..b7e4121fc7f42f5bfc7815ab2f9e3cea3ceb5c67 100644 (file)
@@ -202,7 +202,10 @@ static reloc_howto_type elf_howto_table[] =
         bfd_elf_xtensa_reloc, "R_XTENSA_ASM_SIMPLIFY", FALSE, 0, 0, TRUE),
 
   EMPTY_HOWTO (13),
-  EMPTY_HOWTO (14),
+
+  HOWTO (R_XTENSA_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+        bfd_elf_xtensa_reloc, "R_XTENSA_32_PCREL",
+        FALSE, 0, 0xffffffff, TRUE),
 
   /* GNU extension to record C++ vtable hierarchy.  */
   HOWTO (R_XTENSA_GNU_VTINHERIT, 0, 2, 0, FALSE, 0, complain_overflow_dont,
@@ -307,6 +310,10 @@ elf_xtensa_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
       TRACE ("BFD_RELOC_32");
       return &elf_howto_table[(unsigned) R_XTENSA_32 ];
 
+    case BFD_RELOC_32_PCREL:
+      TRACE ("BFD_RELOC_32_PCREL");
+      return &elf_howto_table[(unsigned) R_XTENSA_32_PCREL ];
+
     case BFD_RELOC_XTENSA_DIFF8:
       TRACE ("BFD_RELOC_XTENSA_DIFF8");
       return &elf_howto_table[(unsigned) R_XTENSA_DIFF8 ];
@@ -893,47 +900,6 @@ elf_xtensa_check_relocs (bfd *abfd,
            }
          break;
 
-       case R_XTENSA_OP0:
-       case R_XTENSA_OP1:
-       case R_XTENSA_OP2:
-       case R_XTENSA_SLOT0_OP:
-       case R_XTENSA_SLOT1_OP:
-       case R_XTENSA_SLOT2_OP:
-       case R_XTENSA_SLOT3_OP:
-       case R_XTENSA_SLOT4_OP:
-       case R_XTENSA_SLOT5_OP:
-       case R_XTENSA_SLOT6_OP:
-       case R_XTENSA_SLOT7_OP:
-       case R_XTENSA_SLOT8_OP:
-       case R_XTENSA_SLOT9_OP:
-       case R_XTENSA_SLOT10_OP:
-       case R_XTENSA_SLOT11_OP:
-       case R_XTENSA_SLOT12_OP:
-       case R_XTENSA_SLOT13_OP:
-       case R_XTENSA_SLOT14_OP:
-       case R_XTENSA_SLOT0_ALT:
-       case R_XTENSA_SLOT1_ALT:
-       case R_XTENSA_SLOT2_ALT:
-       case R_XTENSA_SLOT3_ALT:
-       case R_XTENSA_SLOT4_ALT:
-       case R_XTENSA_SLOT5_ALT:
-       case R_XTENSA_SLOT6_ALT:
-       case R_XTENSA_SLOT7_ALT:
-       case R_XTENSA_SLOT8_ALT:
-       case R_XTENSA_SLOT9_ALT:
-       case R_XTENSA_SLOT10_ALT:
-       case R_XTENSA_SLOT11_ALT:
-       case R_XTENSA_SLOT12_ALT:
-       case R_XTENSA_SLOT13_ALT:
-       case R_XTENSA_SLOT14_ALT:
-       case R_XTENSA_ASM_EXPAND:
-       case R_XTENSA_ASM_SIMPLIFY:
-       case R_XTENSA_DIFF8:
-       case R_XTENSA_DIFF16:
-       case R_XTENSA_DIFF32:
-         /* Nothing to do for these.  */
-         break;
-
        case R_XTENSA_GNU_VTINHERIT:
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
@@ -1552,7 +1518,7 @@ elf_xtensa_do_reloc (reloc_howto_type *howto,
   xtensa_isa isa = xtensa_default_isa;
   static xtensa_insnbuf ibuff = NULL;
   static xtensa_insnbuf sbuff = NULL;
-  bfd_vma self_address = 0;
+  bfd_vma self_address;
   bfd_size_type input_size;
   int opnd, slot;
   uint32 newval;
@@ -1565,6 +1531,11 @@ elf_xtensa_do_reloc (reloc_howto_type *howto,
 
   input_size = bfd_get_section_limit (abfd, input_section);
 
+  /* Calculate the PC address for this instruction.  */
+  self_address = (input_section->output_section->vma
+                 + input_section->output_offset
+                 + address);
+
   switch (howto->type)
     {
     case R_XTENSA_NONE:
@@ -1582,9 +1553,6 @@ elf_xtensa_do_reloc (reloc_howto_type *howto,
                                      input_size - address, 0);
          if (is_windowed_call_opcode (opcode))
            {
-             self_address = (input_section->output_section->vma
-                             + input_section->output_offset
-                             + address);
              if ((self_address >> CALL_SEGMENT_BITS)
                  != (relocation >> CALL_SEGMENT_BITS)) 
                {
@@ -1620,6 +1588,10 @@ elf_xtensa_do_reloc (reloc_howto_type *howto,
        bfd_put_32 (abfd, x, contents + address);
       }
       return bfd_reloc_ok;
+
+    case R_XTENSA_32_PCREL:
+      bfd_put_32 (abfd, relocation - self_address, contents + address);
+      return bfd_reloc_ok;
     }
 
   /* Only instruction slot-specific relocations handled below.... */
@@ -1705,11 +1677,6 @@ elf_xtensa_do_reloc (reloc_howto_type *howto,
              return bfd_reloc_dangerous;
            }
 
-         /* Calculate the PC address for this instruction.  */
-         self_address = (input_section->output_section->vma
-                         + input_section->output_offset
-                         + address);
-
          newval = relocation;
        }
     }
@@ -2182,14 +2149,13 @@ elf_xtensa_relocate_section (bfd *output_bfd,
        {
          bfd_boolean dynamic_symbol = elf_xtensa_dynamic_symbol_p (h, info);
 
-         if (dynamic_symbol && is_operand_relocation (r_type))
+         if (dynamic_symbol && (is_operand_relocation (r_type)
+                                || r_type == R_XTENSA_32_PCREL))
            {
-             /* This is an error.  The symbol's real value won't be known
-                until runtime and it's likely to be out of range anyway.  */
              const char *name = h->root.root.string;
-             error_message = vsprint_msg ("invalid relocation for dynamic "
-                                          "symbol", ": %s",
-                                          strlen (name) + 2, name);
+             error_message =
+               vsprint_msg ("invalid relocation for dynamic symbol", ": %s",
+                            strlen (name) + 2, name);
              if (!((*info->callbacks->reloc_dangerous)
                    (info, error_message, input_bfd, input_section,
                     rel->r_offset)))
@@ -7175,7 +7141,8 @@ check_section_ebb_pcrels_fit (bfd *abfd,
         that fit before linking must fit after linking.  Thus we only
         need to deal with relocations to the same section that are
         PC-relative.  */
-      if (ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_SIMPLIFY
+      if (r_type == R_XTENSA_ASM_SIMPLIFY
+         || r_type == R_XTENSA_32_PCREL
          || !howto->pc_relative)
        continue;
 
index ba26d2d03ebfd5fddad81916084ab759dcb9b288..f16ae7230dbb5f0fbd4a25a6df00a1eff9c4e1a6 100644 (file)
@@ -1,3 +1,15 @@
+2007-12-07  Bob Wilson  <bob.wilson@acm.org>
+       
+       * config/tc-xtensa.c (O_pcrel): Define.
+       (suffix_relocs): Add pcrel suffix.
+       (md_pseudo_table): Add 4byte and 2byte directives.
+       (xtensa_elf_cons): Pass correct pcrel argument to fix_new_exp.
+       (xg_assemble_literal): Likewise.  Check for O_pcrel.
+       (expression_maybe_register): Reorganize.  Handle BFD_RELOC_32_PCREL.
+       (xg_valid_literal_expression): Allow O_pcrel.
+       (md_pcrel_from, md_apply_fix): Handle BFD_RELOC_32_PCREL.
+       (tc_gen_reloc): Fix punctuation in error message.
+       
 2007-12-06  Bob Wilson  <bob.wilson@acm.org>
 
        * config/tc-xtensa.c (xg_force_frag_space): Delete.
index 66ff3808f894ee1949d89cd0a80f66aefadf855b..5599a1dfd2501184c94cacd24bc7abfa9810a0f4 100644 (file)
@@ -354,6 +354,7 @@ op_placement_info_table op_placement_table;
 #define O_pltrel       O_md1   /* like O_symbol but use a PLT reloc */
 #define O_hi16         O_md2   /* use high 16 bits of symbolic value */
 #define O_lo16         O_md3   /* use low 16 bits of symbolic value */
+#define O_pcrel                O_md4   /* value is a PC-relative offset */
 
 struct suffix_reloc_map
 {
@@ -370,6 +371,7 @@ static struct suffix_reloc_map suffix_relocs[] =
   SUFFIX_MAP ("l",     BFD_RELOC_LO16,                 O_lo16),
   SUFFIX_MAP ("h",     BFD_RELOC_HI16,                 O_hi16),
   SUFFIX_MAP ("plt",   BFD_RELOC_XTENSA_PLT,           O_pltrel),
+  SUFFIX_MAP ("pcrel", BFD_RELOC_32_PCREL,             O_pcrel),
   { (char *) 0, 0,     BFD_RELOC_UNUSED,               0 }
 };
 
@@ -999,7 +1001,9 @@ const pseudo_typeS md_pseudo_table[] =
   { "frame", s_ignore, 0 },    /* Formerly used for STABS debugging.  */
   { "long", xtensa_elf_cons, 4 },
   { "word", xtensa_elf_cons, 4 },
+  { "4byte", xtensa_elf_cons, 4 },
   { "short", xtensa_elf_cons, 2 },
+  { "2byte", xtensa_elf_cons, 2 },
   { "begin", xtensa_begin_directive, 0 },
   { "end", xtensa_end_directive, 0 },
   { "literal", xtensa_literal_pseudo, 0 },
@@ -1550,7 +1554,7 @@ xtensa_elf_cons (int nbytes)
              char *p = frag_more ((int) nbytes);
              xtensa_set_frag_assembly_state (frag_now);
              fix_new_exp (frag_now, p - frag_now->fr_literal,
-                          nbytes, &exp, 0, reloc);
+                          nbytes, &exp, reloc_howto->pc_relative, reloc);
            }
        }
       else
@@ -1768,27 +1772,30 @@ expression_maybe_register (xtensa_opcode opc, int opnd, expressionS *tok)
          && ((reloc = xtensa_elf_suffix (&input_line_pointer, tok))
              != BFD_RELOC_NONE))
        {
-         if (reloc == BFD_RELOC_UNUSED)
+         switch (reloc)
            {
-             as_bad (_("unsupported relocation"));
-             return;
-           }
-
-         if (tok->X_op == O_constant)
-           {
-             switch (reloc)
+           case BFD_RELOC_LO16:
+             if (tok->X_op == O_constant)
                {
-               case BFD_RELOC_LO16:
                  tok->X_add_number &= 0xffff;
                  return;
-
-               case BFD_RELOC_HI16:
+               }
+             break;
+           case BFD_RELOC_HI16:
+             if (tok->X_op == O_constant)
+               {
                  tok->X_add_number = ((unsigned) tok->X_add_number) >> 16;
                  return;
-
-               default:
-                 break;
                }
+             break;
+           case BFD_RELOC_UNUSED:
+             as_bad (_("unsupported relocation"));
+             return;
+           case BFD_RELOC_32_PCREL:
+             as_bad (_("pcrel relocation not allowed in an instruction"));
+             return;
+           default:
+             break;
            }
          tok->X_op = map_suffix_reloc_to_operator (reloc);
        }
@@ -3124,6 +3131,7 @@ xg_valid_literal_expression (const expressionS *exp)
     case O_uminus:
     case O_subtract:
     case O_pltrel:
+    case O_pcrel:
       return TRUE;
     default:
       return FALSE;
@@ -3992,6 +4000,7 @@ xg_assemble_literal (/* const */ TInsn *insn)
   emit_state state;
   symbolS *lit_sym = NULL;
   bfd_reloc_code_real_type reloc;
+  bfd_boolean pcrel = FALSE;
   char *p;
 
   /* size = 4 for L32R.  It could easily be larger when we move to
@@ -4030,6 +4039,9 @@ xg_assemble_literal (/* const */ TInsn *insn)
 
   switch (emit_val->X_op)
     {
+    case O_pcrel:
+      pcrel = TRUE;
+      /* fall through */
     case O_pltrel:
       p = frag_more (litsize);
       xtensa_set_frag_assembly_state (frag_now);
@@ -4039,7 +4051,7 @@ xg_assemble_literal (/* const */ TInsn *insn)
       else
        emit_val->X_op = O_constant;
       fix_new_exp (frag_now, p - frag_now->fr_literal,
-                  litsize, emit_val, 0, reloc);
+                  litsize, emit_val, pcrel, reloc);
       break;
 
     default:
@@ -5430,6 +5442,9 @@ md_pcrel_from (fixS *fixP)
   if (fixP->fx_r_type == BFD_RELOC_XTENSA_ASM_EXPAND)
     return 0;
 
+  if (fixP->fx_r_type == BFD_RELOC_32_PCREL)
+    return addr;
+
   if (!insnbuf)
     {
       insnbuf = xtensa_insnbuf_alloc (isa);
@@ -5604,7 +5619,6 @@ xtensa_symbol_new_hook (symbolS *sym)
 }
 
 
-
 void
 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 {
@@ -5620,6 +5634,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 
   switch (fixP->fx_r_type)
     {
+    case BFD_RELOC_32_PCREL:
     case BFD_RELOC_32:
     case BFD_RELOC_16:
     case BFD_RELOC_8:
@@ -5786,7 +5801,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
     }
 
   if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
-    as_fatal (_("internal error? cannot generate `%s' relocation"),
+    as_fatal (_("internal error; cannot generate `%s' relocation"),
              bfd_get_reloc_code_name (fixp->fx_r_type));
 
   return reloc;
index 3f06e0eeda624269a4b2320bca22c2b8bd4319b8..aa5e20c4641d67b589b2cfad94a35ee3e1ea2f74 100644 (file)
@@ -1,3 +1,11 @@
+2007-12-07  Bob Wilson  <bob.wilson@acm.org>
+
+       * gas/xtensa/all.exp: Run new pcrel test.
+       * gas/xtensa/err-pcrel.s: New.
+       * gas/xtensa/pcrel.d: New.
+       * gas/xtensa/pcrel.s: New.
+       * gas/xtensa/xtensa-err.exp: New.
+       
 2007-11-30  Bob Wilson  <bob.wilson@acm.org>
 
        * gas/elf/elf.exp: Disable ehopt test for Xtensa.
index 89b3cdf1e518b91d351490e96ff3f01e733c615f..d4b24930fed6cbcab2847edf7e5986ef8f0728fa 100644 (file)
@@ -79,6 +79,7 @@ if [istarget xtensa*-*-*] then {
     if [all_ones $x1] then { pass $testname } else { fail $testname }
 
     run_dump_test "short_branch_offset"
+    run_dump_test "pcrel"
 }
 
 if [info exists errorInfo] then {
diff --git a/gas/testsuite/gas/xtensa/err-pcrel.s b/gas/testsuite/gas/xtensa/err-pcrel.s
new file mode 100644 (file)
index 0000000..5b32538
--- /dev/null
@@ -0,0 +1,6 @@
+# { dg-do assemble { target xtensa*-*-* } }
+       .text
+       .global foo
+       beqz    a2, 1f@pcrel    # { dg-error "relocation not allowed" "" }
+1:     movi    a2, foo@pcrel   # { dg-error "relocation not allowed" "" }
+foo:   .short  foo@pcrel       # { dg-error "relocations do not fit" "" }
diff --git a/gas/testsuite/gas/xtensa/pcrel.d b/gas/testsuite/gas/xtensa/pcrel.d
new file mode 100644 (file)
index 0000000..0e5f757
--- /dev/null
@@ -0,0 +1,19 @@
+#as: 
+#objdump: -r -j .literal -j .text
+#name: pc-relative relocs
+
+.*: +file format .*xtensa.*
+
+RELOCATION RECORDS FOR \[\.literal\]:
+OFFSET   TYPE              VALUE 
+00000000 R_XTENSA_32_PCREL  foo
+
+
+RELOCATION RECORDS FOR \[\.text\]:
+OFFSET   TYPE              VALUE 
+00000003 R_XTENSA_SLOT0_OP  \.literal
+00000006 R_XTENSA_32_PCREL  foo
+0000000a R_XTENSA_32_PCREL  \.text\+0x00000003
+0000000e R_XTENSA_32_PCREL  \.text\+0x00000006
+
+
diff --git a/gas/testsuite/gas/xtensa/pcrel.s b/gas/testsuite/gas/xtensa/pcrel.s
new file mode 100644 (file)
index 0000000..5e832b4
--- /dev/null
@@ -0,0 +1,9 @@
+       .text
+       .align 4
+       .global foo
+foo:   entry   sp, 16
+       .literal .Lit0, foo@pcrel
+1:     l32r    a2, .Lit0
+.L2:   .word   foo@pcrel
+       .long   1b@pcrel
+       .4byte  .L2@pcrel
diff --git a/gas/testsuite/gas/xtensa/xtensa-err.exp b/gas/testsuite/gas/xtensa/xtensa-err.exp
new file mode 100644 (file)
index 0000000..60ffd36
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright (C) 2001, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+if { ! [istarget "xtensa*-*-*"] } {
+    return
+}
+
+proc run_xtensa_err_tests { } {
+    global srcdir subdir runtests
+
+    load_lib gas-dg.exp
+    dg-init
+    dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/err-*.s]] "" ""
+    dg-finish
+}
+
+run_xtensa_err_tests
index dd46a1187f3af716edea8b45a834baeeb8c0aa85..dc7908df15ebaa69b118db484da7f1c5e0ed33d4 100644 (file)
@@ -1,3 +1,7 @@
+2007-12-07  Bob Wilson  <bob.wilson@acm.org>
+       
+       * xtensa.h (R_XTENSA_32_PCREL): New.
+       
 2007-11-29  Mark Shinwell  <shinwell@codesourcery.com>
 
        * mips.h (E_MIPS_MACH_LS2E): New.
index bd83a140b2e88691d29bad3d8d9b148bfd721152..7e70cb58821e170cc639e48f1181bacf3ebb52d9 100644 (file)
@@ -1,5 +1,5 @@
 /* Xtensa ELF support for BFD.
-   Copyright 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2003, 2004, 2007 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -40,6 +40,7 @@ START_RELOC_NUMBERS (elf_xtensa_reloc_type)
      RELOC_NUMBER (R_XTENSA_OP2, 10) 
      RELOC_NUMBER (R_XTENSA_ASM_EXPAND, 11)
      RELOC_NUMBER (R_XTENSA_ASM_SIMPLIFY, 12)
+     RELOC_NUMBER (R_XTENSA_32_PCREL, 14)
      RELOC_NUMBER (R_XTENSA_GNU_VTINHERIT, 15)
      RELOC_NUMBER (R_XTENSA_GNU_VTENTRY, 16)
      RELOC_NUMBER (R_XTENSA_DIFF8, 17)