aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2018-05-08 13:49:00 -0700
committerMax Filippov <jcmvbkbc@gmail.com>2018-05-09 12:44:08 -0700
commitd0ad159d6848fbd42f5c213f8b051735793101e4 (patch)
tree9a242b794be15a22c8853954b7215babadfa4fe2
parent06cfb1c89510d08217da8b3ccea05ecd4cdb5bc6 (diff)
downloadfsf-binutils-gdb-d0ad159d6848fbd42f5c213f8b051735793101e4.zip
fsf-binutils-gdb-d0ad159d6848fbd42f5c213f8b051735793101e4.tar.gz
fsf-binutils-gdb-d0ad159d6848fbd42f5c213f8b051735793101e4.tar.bz2
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.
-rw-r--r--gas/ChangeLog18
-rw-r--r--gas/config/tc-xtensa.c51
-rw-r--r--gas/testsuite/gas/xtensa/all.exp3
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-3.d11
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-3.s6
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-4.d18
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-4.s6
-rw-r--r--gas/testsuite/gas/xtensa/text-section-literals-1.d18
-rw-r--r--gas/testsuite/gas/xtensa/text-section-literals-1.s6
9 files changed, 116 insertions, 21 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index b44c9e3..424baba 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index 4db7ef5..84211dd 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 650a932..beb6f35 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 0000000..ee9e901
--- /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 0000000..cd0fb5d
--- /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 0000000..ba58c3e
--- /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 0000000..d46c04d
--- /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 0000000..2c481f8
--- /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 0000000..d46c04d
--- /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