From: Max Filippov Date: Wed, 22 Mar 2017 17:19:14 +0000 (-0700) Subject: gas: xtensa: make trampolines relaxation work with jumps in slots other than 0 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=24e5b4e682a92788ffa676e963b7f1dec2101333;p=binutils-gdb.git gas: xtensa: make trampolines relaxation work with jumps in slots other than 0 add_jump_to_trampoline assumes that jump instruction is in slot 0, when it's in other slot that results in fixup that references NULL symbol, which results in segfault later in xtensa_make_cached_fixup. Search for the non-NULL symbol in the tc_frag_data.slot_symbols and check that there's exactly one such slot. xtensa_relax_frag for RELAX_TRAMPOLINE reassigns fixup from the original instruction with jump to generated jump in the trampoline frag, but does not fix its fx_r_type or fx_size. That results in "undecodable fix" or "fixup not contained within frag" error messages during relaxation. Fix both these fields. gas/ 2017-03-22 Max Filippov * config/tc-xtensa.c (xtensa_relax_frag): Change fx_size of the reassigned fixup to size of jump instruction (3) and fx_r_type to BFD_RELOC_XTENSA_SLOT0_OP, as there's only one slot. (add_jump_to_trampoline): Search origfrag->tc_frag_data.slot_symbols for the slot with non-NULL symbol and use that slot instead of slot 0. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index e052bd820cd..75f6adca0b7 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2017-03-22 Max Filippov + + * config/tc-xtensa.c (xtensa_relax_frag): Change fx_size of the + reassigned fixup to size of jump instruction (3) and fx_r_type + to BFD_RELOC_XTENSA_SLOT0_OP, as there's only one slot. + (add_jump_to_trampoline): Search + origfrag->tc_frag_data.slot_symbols for the slot with non-NULL + symbol and use that slot instead of slot 0. + 2017-03-21 Andreas Krebbel * config/tc-s390.c (s390_parse_cpu): Remove S390_INSTR_FLAG_VX2 diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index 356c3197b9e..c45c70d5123 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -9414,7 +9414,9 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) /* Move the fix-up from the original j insn to this one. */ fixP->fx_frag = fragP; fixP->fx_where = fragP->fr_fix - 3; + fixP->fx_size = 3; fixP->tc_fix_data.slot = 0; + fixP->fx_r_type = BFD_RELOC_XTENSA_SLOT0_OP; xtensa_add_cached_fixup (&fixup_cache, fixP); @@ -10045,11 +10047,21 @@ add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) xtensa_format fmt; xtensa_isa isa = xtensa_default_isa; int growth = 0; + int i, slot = -1; + + for (i = 0; i < MAX_SLOTS; ++i) + if (origfrag->tc_frag_data.slot_symbols[i]) + { + gas_assert (slot == -1); + slot = i; + } + + gas_assert (slot >= 0 && slot < MAX_SLOTS); lsym = tramp->fr_symbol; /* Assemble a jump to the target label in the trampoline frag. */ - tsym = origfrag->tc_frag_data.slot_symbols[0]; - toffset = origfrag-> tc_frag_data.slot_offsets[0]; + tsym = origfrag->tc_frag_data.slot_symbols[slot]; + toffset = origfrag-> tc_frag_data.slot_offsets[slot]; tinsn_init (&insn); insn.insn_type = ITYPE_INSN; insn.opcode = xtensa_j_opcode; @@ -10069,8 +10081,8 @@ add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) if (fixP) fixP->fx_offset += 3; /* Modify the original j to point here. */ - origfrag->tc_frag_data.slot_symbols[0] = lsym; - origfrag->tc_frag_data.slot_offsets[0] = tramp->fr_fix - 3; + origfrag->tc_frag_data.slot_symbols[slot] = lsym; + origfrag->tc_frag_data.slot_offsets[slot] = tramp->fr_fix - 3; /* If trampoline is full, remove it from the list. */ check_and_update_trampolines ();