From c842c9fd31b16f78cf11c1581beb0d084fb5e0f6 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 18 Feb 2016 02:16:25 +0300 Subject: binutils: fix .init/.fini literals moving in xtensa gas 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 fixes build errors seen with projects that have .init/.fini and use text-section-literals. Signed-off-by: Max Filippov diff --git a/patches/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch b/patches/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch new file mode 100644 index 0000000..62bc4b5 --- /dev/null +++ b/patches/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch @@ -0,0 +1,70 @@ +From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 16 Feb 2016 02:23:28 +0300 +Subject: [PATCH] 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 +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Fix check for + .init.literal/.fini.literal section name. + +Signed-off-by: Max Filippov +--- +Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 + + gas/config/tc-xtensa.c | 12 ++++++++++-- + 1 file 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 +@@ -10625,5 +10625,9 @@ xtensa_move_literals (void) + fixS *fix, *next_fix, **fix_splice; + sym_list *lit; ++ 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); + +@@ -10632,9 +10636,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; +-- +2.1.4 + diff --git a/patches/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch b/patches/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch new file mode 100644 index 0000000..656373f --- /dev/null +++ b/patches/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch @@ -0,0 +1,71 @@ +From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 16 Feb 2016 02:23:28 +0300 +Subject: [PATCH] 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 +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Fix check for + .init.literal/.fini.literal section name. + +Signed-off-by: Max Filippov +--- +Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 + + gas/config/tc-xtensa.c | 12 ++++++++++-- + 1 file 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; +-- +2.1.4 + diff --git a/patches/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch b/patches/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch new file mode 100644 index 0000000..ead3e42 --- /dev/null +++ b/patches/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch @@ -0,0 +1,149 @@ +From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 16 Feb 2016 02:23:28 +0300 +Subject: [PATCH] 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 +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. + +Signed-off-by: Max Filippov +--- +Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 + + gas/config/tc-xtensa.c | 12 ++++++++++-- + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/init-fini-literals.d | 24 ++++++++++++++++++++++++ + gas/testsuite/gas/xtensa/init-fini-literals.s | 19 +++++++++++++++++++ + 4 files changed, 54 insertions(+), 2 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.d + create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.s + +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; +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index 7ff7bd7..6b67320 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "first_frag_align" + run_dump_test "auto-litpools" + run_dump_test "loc" ++ run_dump_test "init-fini-literals" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.d b/gas/testsuite/gas/xtensa/init-fini-literals.d +new file mode 100644 +index 0000000..19ed121 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/init-fini-literals.d +@@ -0,0 +1,24 @@ ++#as: --text-section-literals ++#objdump: -r ++#name: check that literals for .init and .fini always go to separate sections ++ ++.*: +file format .*xtensa.* ++#... ++RELOCATION RECORDS FOR \[\.init\.literal\]: ++#... ++00000000 R_XTENSA_PLT init ++#... ++RELOCATION RECORDS FOR \[\.fini\.literal\]: ++#... ++00000000 R_XTENSA_PLT fini ++#... ++RELOCATION RECORDS FOR \[\.init\]: ++#... ++.* R_XTENSA_SLOT0_OP \.init\.literal ++.* R_XTENSA_SLOT0_OP \.init\.literal\+0x00000004 ++#... ++RELOCATION RECORDS FOR \[\.fini\]: ++#... ++.* R_XTENSA_SLOT0_OP \.fini\.literal ++.* R_XTENSA_SLOT0_OP \.fini\.literal\+0x00000004 ++#... +diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.s b/gas/testsuite/gas/xtensa/init-fini-literals.s +new file mode 100644 +index 0000000..7c9ec17 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/init-fini-literals.s +@@ -0,0 +1,19 @@ ++ .section .init,"ax",@progbits ++ .literal_position ++ .literal .LC0, init@PLT ++ .literal_position ++ .literal .LC1, 1 ++ .align 4 ++ ++ l32r a2, .LC0 ++ l32r a2, .LC1 ++ ++ .section .fini,"ax",@progbits ++ .literal_position ++ .literal .LC2, fini@PLT ++ .literal_position ++ .literal .LC3, 1 ++ .align 4 ++ ++ l32r a2, .LC2 ++ l32r a2, .LC3 +-- +2.1.4 + diff --git a/patches/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch b/patches/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch new file mode 100644 index 0000000..ead3e42 --- /dev/null +++ b/patches/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch @@ -0,0 +1,149 @@ +From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 16 Feb 2016 02:23:28 +0300 +Subject: [PATCH] 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 +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. + +Signed-off-by: Max Filippov +--- +Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 + + gas/config/tc-xtensa.c | 12 ++++++++++-- + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/init-fini-literals.d | 24 ++++++++++++++++++++++++ + gas/testsuite/gas/xtensa/init-fini-literals.s | 19 +++++++++++++++++++ + 4 files changed, 54 insertions(+), 2 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.d + create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.s + +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; +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index 7ff7bd7..6b67320 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "first_frag_align" + run_dump_test "auto-litpools" + run_dump_test "loc" ++ run_dump_test "init-fini-literals" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.d b/gas/testsuite/gas/xtensa/init-fini-literals.d +new file mode 100644 +index 0000000..19ed121 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/init-fini-literals.d +@@ -0,0 +1,24 @@ ++#as: --text-section-literals ++#objdump: -r ++#name: check that literals for .init and .fini always go to separate sections ++ ++.*: +file format .*xtensa.* ++#... ++RELOCATION RECORDS FOR \[\.init\.literal\]: ++#... ++00000000 R_XTENSA_PLT init ++#... ++RELOCATION RECORDS FOR \[\.fini\.literal\]: ++#... ++00000000 R_XTENSA_PLT fini ++#... ++RELOCATION RECORDS FOR \[\.init\]: ++#... ++.* R_XTENSA_SLOT0_OP \.init\.literal ++.* R_XTENSA_SLOT0_OP \.init\.literal\+0x00000004 ++#... ++RELOCATION RECORDS FOR \[\.fini\]: ++#... ++.* R_XTENSA_SLOT0_OP \.fini\.literal ++.* R_XTENSA_SLOT0_OP \.fini\.literal\+0x00000004 ++#... +diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.s b/gas/testsuite/gas/xtensa/init-fini-literals.s +new file mode 100644 +index 0000000..7c9ec17 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/init-fini-literals.s +@@ -0,0 +1,19 @@ ++ .section .init,"ax",@progbits ++ .literal_position ++ .literal .LC0, init@PLT ++ .literal_position ++ .literal .LC1, 1 ++ .align 4 ++ ++ l32r a2, .LC0 ++ l32r a2, .LC1 ++ ++ .section .fini,"ax",@progbits ++ .literal_position ++ .literal .LC2, fini@PLT ++ .literal_position ++ .literal .LC3, 1 ++ .align 4 ++ ++ l32r a2, .LC2 ++ l32r a2, .LC3 +-- +2.1.4 + -- cgit v0.10.2-6-g49f6