diff options
-rw-r--r-- | bfd/ChangeLog | 12 | ||||
-rw-r--r-- | bfd/elf32-xtensa.c | 83 | ||||
-rw-r--r-- | gas/ChangeLog | 12 | ||||
-rw-r--r-- | gas/config/tc-xtensa.c | 51 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/all.exp | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/err-pcrel.s | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/pcrel.d | 19 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/pcrel.s | 9 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/xtensa-err.exp | 30 | ||||
-rw-r--r-- | include/elf/ChangeLog | 4 | ||||
-rw-r--r-- | include/elf/xtensa.h | 3 |
12 files changed, 161 insertions, 77 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index fbe5928..75e1c2f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index c45a18c..b7e4121 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -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; diff --git a/gas/ChangeLog b/gas/ChangeLog index ba26d2d..f16ae72 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index 66ff380..5599a1d 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -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; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 3f06e0e..aa5e20c 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -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. diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp index 89b3cdf..d4b2493 100644 --- a/gas/testsuite/gas/xtensa/all.exp +++ b/gas/testsuite/gas/xtensa/all.exp @@ -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 index 0000000..5b32538 --- /dev/null +++ b/gas/testsuite/gas/xtensa/err-pcrel.s @@ -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 index 0000000..0e5f757 --- /dev/null +++ b/gas/testsuite/gas/xtensa/pcrel.d @@ -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 index 0000000..5e832b4 --- /dev/null +++ b/gas/testsuite/gas/xtensa/pcrel.s @@ -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 index 0000000..60ffd36 --- /dev/null +++ b/gas/testsuite/gas/xtensa/xtensa-err.exp @@ -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 diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index dd46a11..dc7908d 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -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. diff --git a/include/elf/xtensa.h b/include/elf/xtensa.h index bd83a14..7e70cb5 100644 --- a/include/elf/xtensa.h +++ b/include/elf/xtensa.h @@ -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) |