summaryrefslogtreecommitdiff
path: root/patches/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch
blob: ead3e42b7527b0c585c2a156c9ff15ae75ea5258 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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  <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.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
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