toolchain/binutils: backport stable patches
[openwrt/staging/svanheule.git] / toolchain / binutils / patches / 2.39 / 009-PR29462-internal-error-in-relocate-at-powerpc.cc-107.patch
1 From e3b5d935247084dca057dea72be61b063fe2357a Mon Sep 17 00:00:00 2001
2 From: Alan Modra <amodra@gmail.com>
3 Date: Wed, 10 Aug 2022 10:38:52 +0930
4 Subject: [PATCH 009/160] PR29462, internal error in relocate, at
5 powerpc.cc:10796
6
7 Prior to the inline plt call support (commit 08be322439), the only
8 local syms with plt entries were local ifunc symbols. There shouldn't
9 be stubs for other local symbols so don't look for them. The patch
10 also fixes minor bugs in get_reference_flags; Many relocs are valid
11 only for ppc64 and a couple only for ppc32.
12
13 PR 29462
14 * powerpc.cc (Target_powerpc::Relocate::relocate): Rename
15 use_plt_offset to pltcal_to_direct, invert logic. For relocs
16 not used with inline plt sequences against local symbols, only
17 look for stubs when the symbol is an ifunc.
18 (Target_powerpc::Scan::get_reference_flags): Correct reloc
19 handling for relocs not valid for both 32-bit and 64-bit.
20
21 (cherry picked from commit 6158b25f77db11712b84e6a4609898f2615ac749)
22 ---
23 gold/powerpc.cc | 129 ++++++++++++++++++++++++++++--------------------
24 1 file changed, 75 insertions(+), 54 deletions(-)
25
26 --- a/gold/powerpc.cc
27 +++ b/gold/powerpc.cc
28 @@ -7675,22 +7675,18 @@ Target_powerpc<size, big_endian>::Scan::
29
30 switch (r_type)
31 {
32 + case elfcpp::R_PPC64_TOC:
33 + if (size != 64)
34 + break;
35 + // Fall through.
36 case elfcpp::R_POWERPC_NONE:
37 case elfcpp::R_POWERPC_GNU_VTINHERIT:
38 case elfcpp::R_POWERPC_GNU_VTENTRY:
39 - case elfcpp::R_PPC64_TOC:
40 // No symbol reference.
41 break;
42
43 case elfcpp::R_PPC64_ADDR64:
44 case elfcpp::R_PPC64_UADDR64:
45 - case elfcpp::R_POWERPC_ADDR32:
46 - case elfcpp::R_POWERPC_UADDR32:
47 - case elfcpp::R_POWERPC_ADDR16:
48 - case elfcpp::R_POWERPC_UADDR16:
49 - case elfcpp::R_POWERPC_ADDR16_LO:
50 - case elfcpp::R_POWERPC_ADDR16_HI:
51 - case elfcpp::R_POWERPC_ADDR16_HA:
52 case elfcpp::R_PPC64_ADDR16_HIGHER34:
53 case elfcpp::R_PPC64_ADDR16_HIGHERA34:
54 case elfcpp::R_PPC64_ADDR16_HIGHEST34:
55 @@ -7700,6 +7696,16 @@ Target_powerpc<size, big_endian>::Scan::
56 case elfcpp::R_PPC64_D34_HI30:
57 case elfcpp::R_PPC64_D34_HA30:
58 case elfcpp::R_PPC64_D28:
59 + if (size != 64)
60 + break;
61 + // Fall through.
62 + case elfcpp::R_POWERPC_ADDR32:
63 + case elfcpp::R_POWERPC_UADDR32:
64 + case elfcpp::R_POWERPC_ADDR16:
65 + case elfcpp::R_POWERPC_UADDR16:
66 + case elfcpp::R_POWERPC_ADDR16_LO:
67 + case elfcpp::R_POWERPC_ADDR16_HI:
68 + case elfcpp::R_POWERPC_ADDR16_HA:
69 ref = Symbol::ABSOLUTE_REF;
70 break;
71
72 @@ -7710,13 +7716,14 @@ Target_powerpc<size, big_endian>::Scan::
73 ref = Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;
74 break;
75
76 - case elfcpp::R_PPC64_REL64:
77 - case elfcpp::R_POWERPC_REL32:
78 case elfcpp::R_PPC_LOCAL24PC:
79 - case elfcpp::R_POWERPC_REL16:
80 - case elfcpp::R_POWERPC_REL16_LO:
81 - case elfcpp::R_POWERPC_REL16_HI:
82 - case elfcpp::R_POWERPC_REL16_HA:
83 + if (size != 32)
84 + break;
85 + // Fall through.
86 + ref = Symbol::RELATIVE_REF;
87 + break;
88 +
89 + case elfcpp::R_PPC64_REL64:
90 case elfcpp::R_PPC64_REL16_HIGH:
91 case elfcpp::R_PPC64_REL16_HIGHA:
92 case elfcpp::R_PPC64_REL16_HIGHER:
93 @@ -7729,36 +7736,45 @@ Target_powerpc<size, big_endian>::Scan::
94 case elfcpp::R_PPC64_REL16_HIGHEST34:
95 case elfcpp::R_PPC64_REL16_HIGHESTA34:
96 case elfcpp::R_PPC64_PCREL28:
97 + if (size != 64)
98 + break;
99 + // Fall through.
100 + case elfcpp::R_POWERPC_REL32:
101 + case elfcpp::R_POWERPC_REL16:
102 + case elfcpp::R_POWERPC_REL16_LO:
103 + case elfcpp::R_POWERPC_REL16_HI:
104 + case elfcpp::R_POWERPC_REL16_HA:
105 ref = Symbol::RELATIVE_REF;
106 break;
107
108 + case elfcpp::R_PPC_PLTREL24:
109 + if (size != 32)
110 + break;
111 + ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
112 + break;
113 +
114 case elfcpp::R_PPC64_REL24_NOTOC:
115 - if (size == 32)
116 + case elfcpp::R_PPC64_REL24_P9NOTOC:
117 + case elfcpp::R_PPC64_PLT16_LO_DS:
118 + case elfcpp::R_PPC64_PLTSEQ_NOTOC:
119 + case elfcpp::R_PPC64_PLTCALL_NOTOC:
120 + case elfcpp::R_PPC64_PLT_PCREL34:
121 + case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
122 + if (size != 64)
123 break;
124 // Fall through.
125 - case elfcpp::R_PPC64_REL24_P9NOTOC:
126 case elfcpp::R_POWERPC_REL24:
127 - case elfcpp::R_PPC_PLTREL24:
128 case elfcpp::R_POWERPC_REL14:
129 case elfcpp::R_POWERPC_REL14_BRTAKEN:
130 case elfcpp::R_POWERPC_REL14_BRNTAKEN:
131 case elfcpp::R_POWERPC_PLT16_LO:
132 case elfcpp::R_POWERPC_PLT16_HI:
133 case elfcpp::R_POWERPC_PLT16_HA:
134 - case elfcpp::R_PPC64_PLT16_LO_DS:
135 case elfcpp::R_POWERPC_PLTSEQ:
136 - case elfcpp::R_PPC64_PLTSEQ_NOTOC:
137 case elfcpp::R_POWERPC_PLTCALL:
138 - case elfcpp::R_PPC64_PLTCALL_NOTOC:
139 - case elfcpp::R_PPC64_PLT_PCREL34:
140 - case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
141 ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
142 break;
143
144 - case elfcpp::R_POWERPC_GOT16:
145 - case elfcpp::R_POWERPC_GOT16_LO:
146 - case elfcpp::R_POWERPC_GOT16_HI:
147 - case elfcpp::R_POWERPC_GOT16_HA:
148 case elfcpp::R_PPC64_GOT16_DS:
149 case elfcpp::R_PPC64_GOT16_LO_DS:
150 case elfcpp::R_PPC64_GOT_PCREL34:
151 @@ -7768,11 +7784,16 @@ Target_powerpc<size, big_endian>::Scan::
152 case elfcpp::R_PPC64_TOC16_HA:
153 case elfcpp::R_PPC64_TOC16_DS:
154 case elfcpp::R_PPC64_TOC16_LO_DS:
155 + if (size != 64)
156 + break;
157 + // Fall through.
158 + case elfcpp::R_POWERPC_GOT16:
159 + case elfcpp::R_POWERPC_GOT16_LO:
160 + case elfcpp::R_POWERPC_GOT16_HI:
161 + case elfcpp::R_POWERPC_GOT16_HA:
162 ref = Symbol::RELATIVE_REF;
163 break;
164
165 - case elfcpp::R_POWERPC_GOT_TPREL16:
166 - case elfcpp::R_POWERPC_TLS:
167 case elfcpp::R_PPC64_TLSGD:
168 case elfcpp::R_PPC64_TLSLD:
169 case elfcpp::R_PPC64_TPREL34:
170 @@ -7781,6 +7802,11 @@ Target_powerpc<size, big_endian>::Scan::
171 case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
172 case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
173 case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
174 + if (size != 64)
175 + break;
176 + // Fall through.
177 + case elfcpp::R_POWERPC_GOT_TPREL16:
178 + case elfcpp::R_POWERPC_TLS:
179 ref = Symbol::TLS_REF;
180 break;
181
182 @@ -10671,10 +10697,8 @@ Target_powerpc<size, big_endian>::Reloca
183 bool has_stub_value = false;
184 bool localentry0 = false;
185 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
186 - bool use_plt_offset
187 - = (gsym != NULL
188 - ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target))
189 - : object->local_has_plt_offset(r_sym));
190 + bool pltcall_to_direct = false;
191 +
192 if (is_plt16_reloc<size>(r_type)
193 || r_type == elfcpp::R_PPC64_PLT_PCREL34
194 || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC
195 @@ -10688,21 +10712,18 @@ Target_powerpc<size, big_endian>::Reloca
196 // that the decision depends on the PLTCALL reloc, and we don't
197 // know the address of that instruction when processing others
198 // in the sequence. So the decision needs to be made in
199 - // do_relax(). For now, don't optimise inline plt calls.
200 - if (gsym)
201 - use_plt_offset = gsym->has_plt_offset();
202 - }
203 - if (use_plt_offset
204 - && !is_got_reloc(r_type)
205 - && !is_plt16_reloc<size>(r_type)
206 - && r_type != elfcpp::R_PPC64_PLT_PCREL34
207 - && r_type != elfcpp::R_PPC64_PLT_PCREL34_NOTOC
208 - && r_type != elfcpp::R_POWERPC_PLTSEQ
209 - && r_type != elfcpp::R_POWERPC_PLTCALL
210 - && r_type != elfcpp::R_PPC64_PLTSEQ_NOTOC
211 - && r_type != elfcpp::R_PPC64_PLTCALL_NOTOC
212 - && (!psymval->is_ifunc_symbol()
213 - || Scan::reloc_needs_plt_for_ifunc(target, object, r_type, false)))
214 + // do_relax().
215 + pltcall_to_direct = !(gsym != NULL
216 + ? gsym->has_plt_offset()
217 + : object->local_has_plt_offset(r_sym));
218 + }
219 + else if ((gsym != NULL
220 + ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target))
221 + : psymval->is_ifunc_symbol() && object->local_has_plt_offset(r_sym))
222 + && !is_got_reloc(r_type)
223 + && (!psymval->is_ifunc_symbol()
224 + || Scan::reloc_needs_plt_for_ifunc(target, object, r_type,
225 + false)))
226 {
227 if (size == 64
228 && gsym != NULL
229 @@ -10796,9 +10817,9 @@ Target_powerpc<size, big_endian>::Reloca
230 gold_assert(has_stub_value || !(os->flags() & elfcpp::SHF_ALLOC));
231 }
232
233 - if (use_plt_offset && (is_plt16_reloc<size>(r_type)
234 - || r_type == elfcpp::R_PPC64_PLT_PCREL34
235 - || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
236 + if (!pltcall_to_direct && (is_plt16_reloc<size>(r_type)
237 + || r_type == elfcpp::R_PPC64_PLT_PCREL34
238 + || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
239 {
240 const Output_data_plt_powerpc<size, big_endian>* plt;
241 if (gsym)
242 @@ -10826,7 +10847,7 @@ Target_powerpc<size, big_endian>::Reloca
243 value -= target->toc_pointer();
244 }
245 }
246 - else if (!use_plt_offset
247 + else if (pltcall_to_direct
248 && (is_plt16_reloc<size>(r_type)
249 || r_type == elfcpp::R_POWERPC_PLTSEQ
250 || r_type == elfcpp::R_PPC64_PLTSEQ_NOTOC))
251 @@ -10835,7 +10856,7 @@ Target_powerpc<size, big_endian>::Reloca
252 elfcpp::Swap<32, big_endian>::writeval(iview, nop);
253 r_type = elfcpp::R_POWERPC_NONE;
254 }
255 - else if (!use_plt_offset
256 + else if (pltcall_to_direct
257 && (r_type == elfcpp::R_PPC64_PLT_PCREL34
258 || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
259 {
260 @@ -11316,8 +11337,8 @@ Target_powerpc<size, big_endian>::Reloca
261 }
262 else if (!has_stub_value)
263 {
264 - if (!use_plt_offset && (r_type == elfcpp::R_POWERPC_PLTCALL
265 - || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC))
266 + if (pltcall_to_direct && (r_type == elfcpp::R_POWERPC_PLTCALL
267 + || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC))
268 {
269 // PLTCALL without plt entry => convert to direct call
270 Insn* iview = reinterpret_cast<Insn*>(view);