From d0ad159d6848fbd42f5c213f8b051735793101e4 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 8 May 2018 13:49:00 -0700 Subject: [PATCH] gas: xtensa: fix literal movement Not all literals need to be moved in the presence of --text-section-literals or --auto-litpools, but only those created by .literal pseudo op or generated as a result of relaxation. Attempts to move other literals may result in abnormal termination of the assembler due to the following assertion failure: Internal error in xg_find_litpool at gas/config/tc-xtensa.c:11209. The same assertion may also be triggered by attempting to assign literal pools to literals in .init and .fini sections; don't try to do that. gas/ 2018-05-09 Max Filippov * config/tc-xtensa.c (xtensa_is_init_fini): New function. (xtensa_move_literals): Only attempt to assign literal pool to literals with tc_frag_data.is_literal mark and not in .init or .fini sections. Join nested 'if' conditions to simplify function structure. (xtensa_switch_to_non_abs_literal_fragment): Use xtensa_is_init_fini to test for .init/.fini sections. * testsuite/gas/xtensa/all.exp (auto-litpools-3) (auto-litpools-4, text-section-literals-1): New tests. * testsuite/gas/xtensa/auto-litpools-3.d: New test results. * testsuite/gas/xtensa/auto-litpools-3.s: New test source. * testsuite/gas/xtensa/auto-litpools-4.d: New test results. * testsuite/gas/xtensa/auto-litpools-4.s: New test source. * testsuite/gas/xtensa/text-section-literals-1.d: New test results. * testsuite/gas/xtensa/text-section-literals-1.s: New test source. --- gas/ChangeLog | 18 +++++++ gas/config/tc-xtensa.c | 51 +++++++++++-------- gas/testsuite/gas/xtensa/all.exp | 3 ++ gas/testsuite/gas/xtensa/auto-litpools-3.d | 11 ++++ gas/testsuite/gas/xtensa/auto-litpools-3.s | 6 +++ gas/testsuite/gas/xtensa/auto-litpools-4.d | 18 +++++++ gas/testsuite/gas/xtensa/auto-litpools-4.s | 6 +++ .../gas/xtensa/text-section-literals-1.d | 18 +++++++ .../gas/xtensa/text-section-literals-1.s | 6 +++ 9 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-3.d create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-3.s create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-4.d create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-4.s create mode 100644 gas/testsuite/gas/xtensa/text-section-literals-1.d create mode 100644 gas/testsuite/gas/xtensa/text-section-literals-1.s diff --git a/gas/ChangeLog b/gas/ChangeLog index b44c9e34dde..424babacd68 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,21 @@ +2018-05-09 Max Filippov + + * config/tc-xtensa.c (xtensa_is_init_fini): New function. + (xtensa_move_literals): Only attempt to assign literal pool to + literals with tc_frag_data.is_literal mark and not in .init or + .fini sections. + Join nested 'if' conditions to simplify function structure. + (xtensa_switch_to_non_abs_literal_fragment): Use + xtensa_is_init_fini to test for .init/.fini sections. + * testsuite/gas/xtensa/all.exp (auto-litpools-3) + (auto-litpools-4, text-section-literals-1): New tests. + * testsuite/gas/xtensa/auto-litpools-3.d: New test results. + * testsuite/gas/xtensa/auto-litpools-3.s: New test source. + * testsuite/gas/xtensa/auto-litpools-4.d: New test results. + * testsuite/gas/xtensa/auto-litpools-4.s: New test source. + * testsuite/gas/xtensa/text-section-literals-1.d: New test results. + * testsuite/gas/xtensa/text-section-literals-1.s: New test source. + 2018-05-09 Dimitar Dimitrov * config/tc-pru.c (md_apply_fix): Make LDI32 relocation conformant diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index 4db7ef57e8f..84211dd3e73 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -11260,6 +11260,14 @@ static struct litpool_frag *xg_find_litpool (struct litpool_seg *lps, return lp; } +static bfd_boolean xtensa_is_init_fini (segT seg) +{ + if (!seg) + return 0; + return strcmp (segment_name (seg), INIT_SECTION_NAME) == 0 + || strcmp (segment_name (seg), FINI_SECTION_NAME) == 0; +} + static void xtensa_move_literals (void) { @@ -11291,6 +11299,9 @@ xtensa_move_literals (void) struct litpool_frag *lpf = lps->frag_list.next; addressT addr = 0; + if (xtensa_is_init_fini (lps->seg)) + continue; + for ( ; frchP; frchP = frchP->frch_next) { fragS *fragP; @@ -11311,22 +11322,23 @@ xtensa_move_literals (void) int slot; for (slot = 0; slot < MAX_SLOTS; slot++) { - if (fragP->tc_frag_data.literal_frags[slot]) + fragS *litfrag = fragP->tc_frag_data.literal_frags[slot]; + + if (litfrag + && litfrag->tc_frag_data.is_literal + && !litfrag->tc_frag_data.literal_frag) { - /* L32R; point its literal to the nearest litpool - preferring non-"candidate" positions to avoid - the jump-around. */ - fragS *litfrag = fragP->tc_frag_data.literal_frags[slot]; - - if (!litfrag->tc_frag_data.literal_frag) - { - struct litpool_frag *lp; - - lp = xg_find_litpool (lps, lpf, addr); - /* Take earliest use of this literal to avoid - forward refs. */ - litfrag->tc_frag_data.literal_frag = lp->fragP; - } + /* L32R referring .literal or generated as a result + of relaxation. Point its literal to the nearest + litpool preferring non-"candidate" positions to + avoid the jump-around. */ + + struct litpool_frag *lp; + + lp = xg_find_litpool (lps, lpf, addr); + /* Take earliest use of this literal to avoid + forward refs. */ + litfrag->tc_frag_data.literal_frag = lp->fragP; } } } @@ -11594,14 +11606,11 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result) { fragS *pool_location = get_literal_pool_location (now_seg); segT lit_seg; - bfd_boolean is_init = - (now_seg && !strcmp (segment_name (now_seg), INIT_SECTION_NAME)); - bfd_boolean is_fini = - (now_seg && !strcmp (segment_name (now_seg), FINI_SECTION_NAME)); + bfd_boolean is_init_fini = xtensa_is_init_fini (now_seg); if (pool_location == NULL && !use_literal_section - && !is_init && ! is_fini) + && !is_init_fini) { if (!auto_litpools) { @@ -11615,7 +11624,7 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result) xtensa_switch_section_emit_state (result, lit_seg, 0); if (!use_literal_section - && !is_init && !is_fini + && !is_init_fini && get_literal_pool_location (now_seg) != pool_location) { /* Close whatever frag is there. */ diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp index 650a93223d4..beb6f35aad5 100644 --- a/gas/testsuite/gas/xtensa/all.exp +++ b/gas/testsuite/gas/xtensa/all.exp @@ -103,10 +103,13 @@ if [istarget xtensa*-*-*] then { run_dump_test "first_frag_align" run_dump_test "auto-litpools" run_dump_test "auto-litpools-2" + run_dump_test "auto-litpools-3" + run_dump_test "auto-litpools-4" run_dump_test "auto-litpools-first1" run_dump_test "auto-litpools-first2" run_dump_test "loc" run_dump_test "init-fini-literals" + run_dump_test "text-section-literals-1" } if [info exists errorInfo] then { diff --git a/gas/testsuite/gas/xtensa/auto-litpools-3.d b/gas/testsuite/gas/xtensa/auto-litpools-3.d new file mode 100644 index 00000000000..ee9e901535e --- /dev/null +++ b/gas/testsuite/gas/xtensa/auto-litpools-3.d @@ -0,0 +1,11 @@ +#as: --auto-litpools +#objdump: -dr +#name: auto-litpools-3 (don't move arbitrary data referenced by l32r) + +.*: +file format .*xtensa.* +#... +Disassembly of section .text: +#... + *0:.*l32r.* +.*0:.*\.data +#... diff --git a/gas/testsuite/gas/xtensa/auto-litpools-3.s b/gas/testsuite/gas/xtensa/auto-litpools-3.s new file mode 100644 index 00000000000..cd0fb5deafa --- /dev/null +++ b/gas/testsuite/gas/xtensa/auto-litpools-3.s @@ -0,0 +1,6 @@ + .data +a: + .word 0x12345678 + + .text + l32r a2, a diff --git a/gas/testsuite/gas/xtensa/auto-litpools-4.d b/gas/testsuite/gas/xtensa/auto-litpools-4.d new file mode 100644 index 00000000000..ba58c3e3e9d --- /dev/null +++ b/gas/testsuite/gas/xtensa/auto-litpools-4.d @@ -0,0 +1,18 @@ +#as: --auto-litpools +#objdump: -d +#name: auto-litpools-4 (handle auto literal pools in .init and .fini) + +.*: +file format .*xtensa.* +#... +Disassembly of section .init.literal: +#... +Disassembly of section .fini.literal: +#... +Disassembly of section .init: +#... + *0:.*l32r.* +#... +Disassembly of section .fini: +#... + *0:.*l32r.* +#... diff --git a/gas/testsuite/gas/xtensa/auto-litpools-4.s b/gas/testsuite/gas/xtensa/auto-litpools-4.s new file mode 100644 index 00000000000..d46c04d41d9 --- /dev/null +++ b/gas/testsuite/gas/xtensa/auto-litpools-4.s @@ -0,0 +1,6 @@ + .section .init + .literal a, 0x12345678 + movi a2, 0x12345679 + .section .fini + .literal b, 0x1234567a + movi a2, 0x1234567b diff --git a/gas/testsuite/gas/xtensa/text-section-literals-1.d b/gas/testsuite/gas/xtensa/text-section-literals-1.d new file mode 100644 index 00000000000..2c481f8d0c5 --- /dev/null +++ b/gas/testsuite/gas/xtensa/text-section-literals-1.d @@ -0,0 +1,18 @@ +#as: --text-section-literals +#objdump: -d +#name: text-section-literals (handle text section literal in .init and .fini without .literal_position) + +.*: +file format .*xtensa.* +#... +Disassembly of section .init.literal: +#... +Disassembly of section .fini.literal: +#... +Disassembly of section .init: +#... + *0:.*l32r.* +#... +Disassembly of section .fini: +#... + *0:.*l32r.* +#... diff --git a/gas/testsuite/gas/xtensa/text-section-literals-1.s b/gas/testsuite/gas/xtensa/text-section-literals-1.s new file mode 100644 index 00000000000..d46c04d41d9 --- /dev/null +++ b/gas/testsuite/gas/xtensa/text-section-literals-1.s @@ -0,0 +1,6 @@ + .section .init + .literal a, 0x12345678 + movi a2, 0x12345679 + .section .fini + .literal b, 0x1234567a + movi a2, 0x1234567b -- 2.30.2