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 <jcmvbkbc@gmail.com> * 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.
This commit is contained in:
parent
06cfb1c895
commit
d0ad159d68
|
@ -1,3 +1,21 @@
|
|||
2018-05-09 Max Filippov <jcmvbkbc@gmail.com>
|
||||
|
||||
* 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 <dimitar@dinux.eu>
|
||||
|
||||
* config/tc-pru.c (md_apply_fix): Make LDI32 relocation conformant
|
||||
|
|
|
@ -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];
|
||||
/* 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. */
|
||||
|
||||
if (!litfrag->tc_frag_data.literal_frag)
|
||||
{
|
||||
struct litpool_frag *lp;
|
||||
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;
|
||||
}
|
||||
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. */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
#...
|
|
@ -0,0 +1,6 @@
|
|||
.data
|
||||
a:
|
||||
.word 0x12345678
|
||||
|
||||
.text
|
||||
l32r a2, a
|
|
@ -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.*
|
||||
#...
|
|
@ -0,0 +1,6 @@
|
|||
.section .init
|
||||
.literal a, 0x12345678
|
||||
movi a2, 0x12345679
|
||||
.section .fini
|
||||
.literal b, 0x1234567a
|
||||
movi a2, 0x1234567b
|
|
@ -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.*
|
||||
#...
|
|
@ -0,0 +1,6 @@
|
|||
.section .init
|
||||
.literal a, 0x12345678
|
||||
movi a2, 0x12345679
|
||||
.section .fini
|
||||
.literal b, 0x1234567a
|
||||
movi a2, 0x1234567b
|
Loading…
Reference in New Issue