aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2016-02-16 02:23:28 +0300
committerMax Filippov <jcmvbkbc@gmail.com>2016-02-17 23:08:15 +0300
commit4111950f363221c4641dc2f33bea61cc94f34906 (patch)
tree6da128f81f8682f41715183037ef564051781b68 /gas/config
parent8f79b794ce055b3b4041788182080f4ce3f9048e (diff)
downloadfsf-binutils-gdb-4111950f363221c4641dc2f33bea61cc94f34906.zip
fsf-binutils-gdb-4111950f363221c4641dc2f33bea61cc94f34906.tar.gz
fsf-binutils-gdb-4111950f363221c4641dc2f33bea61cc94f34906.tar.bz2
xtensa: fix .init/.fini literals moving
Despite the documentation and the comment in xtensa_move_literals, in the presence of --text-section-literals and --auto-litpools literals are moved from the separate literal sections into .init and .fini, because the check in the xtensa_move_literals is incorrect. This moving was broken with introduction of auto litpools: some literals now may be lost. This happens because literal frags emitted from .init and .fini are not closed when new .literal_position marks new literal pool. Then frag_align(2, 0, 0) changes type of the last literal frag to rs_align. rs_align frags are skipped in the xtensa_move_literals. As a result fixups against such literals are not moved out of .init.literal/ .fini.literal sections producing the following assembler error: test.S: Warning: fixes not all moved from .init.literal test.S: Internal error! Fix check for .init.literal/.fini.literal in the xtensa_move_literals and don't let it move literals from there in the presence of --text-section-literals or --auto-litpools. 2016-02-17 Max Filippov <jcmvbkbc@gmail.com> gas/ * config/tc-xtensa.c (xtensa_move_literals): Fix check for .init.literal/.fini.literal section name. * testsuite/gas/xtensa/all.exp: Add init-fini-literals to the list of xtensa tests. * testsuite/gas/xtensa/init-fini-literals.d: New file: init-fini-literals test result patterns. * testsuite/gas/xtensa/init-fini-literals.s: New file: init-fini-literals test.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-xtensa.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index 36a06cc..5773634 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -11061,6 +11061,10 @@ xtensa_move_literals (void)
fixS *fix, *next_fix, **fix_splice;
sym_list *lit;
struct litpool_seg *lps;
+ const char *init_name = INIT_SECTION_NAME;
+ const char *fini_name = FINI_SECTION_NAME;
+ int init_name_len = strlen(init_name);
+ int fini_name_len = strlen(fini_name);
mark_literal_frags (literal_head->next);
@@ -11171,9 +11175,13 @@ xtensa_move_literals (void)
for (segment = literal_head->next; segment; segment = segment->next)
{
+ const char *seg_name = segment_name (segment->seg);
+
/* Keep the literals for .init and .fini in separate sections. */
- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME)
- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME))
+ if ((!memcmp (seg_name, init_name, init_name_len) &&
+ !strcmp (seg_name + init_name_len, ".literal")) ||
+ (!memcmp (seg_name, fini_name, fini_name_len) &&
+ !strcmp (seg_name + fini_name_len, ".literal")))
continue;
frchain_from = seg_info (segment->seg)->frchainP;