diff options
Diffstat (limited to 'meta/packages/binutils/binutils-2.20/binutils-powerpc-pr11088.patch')
-rw-r--r-- | meta/packages/binutils/binutils-2.20/binutils-powerpc-pr11088.patch | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/meta/packages/binutils/binutils-2.20/binutils-powerpc-pr11088.patch b/meta/packages/binutils/binutils-2.20/binutils-powerpc-pr11088.patch new file mode 100644 index 0000000000..d5be1760e0 --- /dev/null +++ b/meta/packages/binutils/binutils-2.20/binutils-powerpc-pr11088.patch | |||
@@ -0,0 +1,275 @@ | |||
1 | Fix ld segfault when compiling Qt 4.6.0 on powerpc. See: | ||
2 | |||
3 | http://sourceware.org/bugzilla/show_bug.cgi?id=11088 | ||
4 | |||
5 | =================================================================== | ||
6 | RCS file: /cvs/src/src/include/elf/ppc.h,v | ||
7 | retrieving revision 1.26 | ||
8 | retrieving revision 1.27 | ||
9 | diff -u -r1.26 -r1.27 | ||
10 | --- src/include/elf/ppc.h 2009/09/21 11:51:01 1.26 | ||
11 | +++ src/include/elf/ppc.h 2009/12/17 05:45:25 1.27 | ||
12 | @@ -73,10 +73,9 @@ | ||
13 | |||
14 | #ifndef RELOC_MACROS_GEN_FUNC | ||
15 | /* Fake relocations for branch stubs, only used internally by ld. */ | ||
16 | - RELOC_NUMBER (R_PPC_RELAX32, 48) | ||
17 | - RELOC_NUMBER (R_PPC_RELAX32PC, 49) | ||
18 | - RELOC_NUMBER (R_PPC_RELAX32_PLT, 50) | ||
19 | - RELOC_NUMBER (R_PPC_RELAX32PC_PLT, 51) | ||
20 | + RELOC_NUMBER (R_PPC_RELAX, 48) | ||
21 | + RELOC_NUMBER (R_PPC_RELAX_PLT, 49) | ||
22 | + RELOC_NUMBER (R_PPC_RELAX_PLTREL24, 50) | ||
23 | #endif | ||
24 | |||
25 | /* Relocs added to support TLS. */ | ||
26 | =================================================================== | ||
27 | RCS file: /cvs/src/src/bfd/elf32-ppc.c,v | ||
28 | retrieving revision 1.272 | ||
29 | retrieving revision 1.273 | ||
30 | diff -u -r1.272 -r1.273 | ||
31 | --- src/bfd/elf32-ppc.c 2009/12/11 13:42:02 1.272 | ||
32 | +++ src/bfd/elf32-ppc.c 2009/12/17 05:45:25 1.273 | ||
33 | @@ -3323,6 +3323,8 @@ | ||
34 | { | ||
35 | struct plt_entry *ent; | ||
36 | |||
37 | + if (addend < 32768) | ||
38 | + sec = NULL; | ||
39 | for (ent = *plist; ent != NULL; ent = ent->next) | ||
40 | if (ent->sec == sec && ent->addend == addend) | ||
41 | break; | ||
42 | @@ -3508,8 +3510,7 @@ | ||
43 | if (info->shared) | ||
44 | addend = rel->r_addend; | ||
45 | } | ||
46 | - if (!update_plt_info (abfd, ifunc, | ||
47 | - addend < 32768 ? NULL : got2, addend)) | ||
48 | + if (!update_plt_info (abfd, ifunc, got2, addend)) | ||
49 | return FALSE; | ||
50 | } | ||
51 | } | ||
52 | @@ -3748,8 +3749,7 @@ | ||
53 | addend = rel->r_addend; | ||
54 | } | ||
55 | h->needs_plt = 1; | ||
56 | - if (!update_plt_info (abfd, &h->plt.plist, | ||
57 | - addend < 32768 ? NULL : got2, addend)) | ||
58 | + if (!update_plt_info (abfd, &h->plt.plist, got2, addend)) | ||
59 | return FALSE; | ||
60 | } | ||
61 | break; | ||
62 | @@ -3780,10 +3780,9 @@ | ||
63 | case R_PPC_EMB_MRKREF: | ||
64 | case R_PPC_NONE: | ||
65 | case R_PPC_max: | ||
66 | - case R_PPC_RELAX32: | ||
67 | - case R_PPC_RELAX32PC: | ||
68 | - case R_PPC_RELAX32_PLT: | ||
69 | - case R_PPC_RELAX32PC_PLT: | ||
70 | + case R_PPC_RELAX: | ||
71 | + case R_PPC_RELAX_PLT: | ||
72 | + case R_PPC_RELAX_PLTREL24: | ||
73 | break; | ||
74 | |||
75 | /* These should only appear in dynamic objects. */ | ||
76 | @@ -4486,7 +4485,7 @@ | ||
77 | struct plt_entry *ent; | ||
78 | |||
79 | ent = find_plt_ent (&h->plt.plist, NULL, 0); | ||
80 | - if (ent->plt.refcount > 0) | ||
81 | + if (ent != NULL && ent->plt.refcount > 0) | ||
82 | ent->plt.refcount -= 1; | ||
83 | } | ||
84 | } | ||
85 | @@ -4534,7 +4533,7 @@ | ||
86 | if (r_type == R_PPC_PLTREL24 && info->shared) | ||
87 | addend = rel->r_addend; | ||
88 | ent = find_plt_ent (&h->plt.plist, got2, addend); | ||
89 | - if (ent->plt.refcount > 0) | ||
90 | + if (ent != NULL && ent->plt.refcount > 0) | ||
91 | ent->plt.refcount -= 1; | ||
92 | } | ||
93 | break; | ||
94 | @@ -4582,9 +4581,10 @@ | ||
95 | && tga->root.type == bfd_link_hash_undefweak))) | ||
96 | { | ||
97 | struct plt_entry *ent; | ||
98 | - ent = find_plt_ent (&tga->plt.plist, NULL, 0); | ||
99 | - if (ent != NULL | ||
100 | - && ent->plt.refcount > 0) | ||
101 | + for (ent = tga->plt.plist; ent != NULL; ent = ent->next) | ||
102 | + if (ent->plt.refcount > 0) | ||
103 | + break; | ||
104 | + if (ent != NULL) | ||
105 | { | ||
106 | tga->root.type = bfd_link_hash_indirect; | ||
107 | tga->root.u.i.link = &opt->root; | ||
108 | @@ -4669,6 +4669,7 @@ | ||
109 | { | ||
110 | Elf_Internal_Sym *locsyms = NULL; | ||
111 | Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd); | ||
112 | + asection *got2 = bfd_get_section_by_name (ibfd, ".got2"); | ||
113 | |||
114 | for (sec = ibfd->sections; sec != NULL; sec = sec->next) | ||
115 | if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section)) | ||
116 | @@ -4762,6 +4763,13 @@ | ||
117 | else | ||
118 | continue; | ||
119 | |||
120 | + case R_PPC_TLSGD: | ||
121 | + case R_PPC_TLSLD: | ||
122 | + expecting_tls_get_addr = 2; | ||
123 | + tls_set = 0; | ||
124 | + tls_clear = 0; | ||
125 | + break; | ||
126 | + | ||
127 | default: | ||
128 | continue; | ||
129 | } | ||
130 | @@ -4769,7 +4777,8 @@ | ||
131 | if (pass == 0) | ||
132 | { | ||
133 | if (!expecting_tls_get_addr | ||
134 | - || !sec->has_tls_get_addr_call) | ||
135 | + || (expecting_tls_get_addr == 1 | ||
136 | + && !sec->has_tls_get_addr_call)) | ||
137 | continue; | ||
138 | |||
139 | if (rel + 1 < relend | ||
140 | @@ -4785,6 +4794,23 @@ | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | + if (expecting_tls_get_addr) | ||
145 | + { | ||
146 | + struct plt_entry *ent; | ||
147 | + bfd_vma addend = 0; | ||
148 | + | ||
149 | + if (info->shared | ||
150 | + && ELF32_R_TYPE (rel[1].r_info) == R_PPC_PLTREL24) | ||
151 | + addend = rel[1].r_addend; | ||
152 | + ent = find_plt_ent (&htab->tls_get_addr->plt.plist, | ||
153 | + got2, addend); | ||
154 | + if (ent != NULL && ent->plt.refcount > 0) | ||
155 | + ent->plt.refcount -= 1; | ||
156 | + | ||
157 | + if (expecting_tls_get_addr == 2) | ||
158 | + continue; | ||
159 | + } | ||
160 | + | ||
161 | if (h != NULL) | ||
162 | { | ||
163 | tls_mask = &ppc_elf_hash_entry (h)->tls_mask; | ||
164 | @@ -4829,16 +4855,6 @@ | ||
165 | *got_count -= 1; | ||
166 | } | ||
167 | |||
168 | - if (expecting_tls_get_addr) | ||
169 | - { | ||
170 | - struct plt_entry *ent; | ||
171 | - | ||
172 | - ent = find_plt_ent (&htab->tls_get_addr->plt.plist, | ||
173 | - NULL, 0); | ||
174 | - if (ent != NULL && ent->plt.refcount > 0) | ||
175 | - ent->plt.refcount -= 1; | ||
176 | - } | ||
177 | - | ||
178 | *tls_mask |= tls_set; | ||
179 | *tls_mask &= ~tls_clear; | ||
180 | } | ||
181 | @@ -6239,28 +6255,28 @@ | ||
182 | { | ||
183 | size = 4 * ARRAY_SIZE (shared_stub_entry); | ||
184 | insn_offset = 12; | ||
185 | - stub_rtype = R_PPC_RELAX32PC; | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | size = 4 * ARRAY_SIZE (stub_entry); | ||
190 | insn_offset = 0; | ||
191 | - stub_rtype = R_PPC_RELAX32; | ||
192 | } | ||
193 | - | ||
194 | - if (R_PPC_RELAX32_PLT - R_PPC_RELAX32 | ||
195 | - != R_PPC_RELAX32PC_PLT - R_PPC_RELAX32PC) | ||
196 | - abort (); | ||
197 | + stub_rtype = R_PPC_RELAX; | ||
198 | if (tsec == htab->plt | ||
199 | || tsec == htab->glink) | ||
200 | - stub_rtype += R_PPC_RELAX32_PLT - R_PPC_RELAX32; | ||
201 | + { | ||
202 | + stub_rtype = R_PPC_RELAX_PLT; | ||
203 | + if (r_type == R_PPC_PLTREL24) | ||
204 | + stub_rtype = R_PPC_RELAX_PLTREL24; | ||
205 | + } | ||
206 | |||
207 | /* Hijack the old relocation. Since we need two | ||
208 | relocations for this use a "composite" reloc. */ | ||
209 | irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), | ||
210 | stub_rtype); | ||
211 | irel->r_offset = trampoff + insn_offset; | ||
212 | - if (r_type == R_PPC_PLTREL24) | ||
213 | + if (r_type == R_PPC_PLTREL24 | ||
214 | + && stub_rtype != R_PPC_RELAX_PLTREL24) | ||
215 | irel->r_addend = 0; | ||
216 | |||
217 | /* Record the fixup so we don't do it again this section. */ | ||
218 | @@ -6430,7 +6446,7 @@ | ||
219 | { | ||
220 | /* Convert the internal relax relocs to external form. */ | ||
221 | for (irel = internal_relocs; irel < irelend; irel++) | ||
222 | - if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX32) | ||
223 | + if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX) | ||
224 | { | ||
225 | unsigned long r_symndx = ELF32_R_SYM (irel->r_info); | ||
226 | |||
227 | @@ -7669,12 +7685,20 @@ | ||
228 | } | ||
229 | break; | ||
230 | |||
231 | - case R_PPC_RELAX32PC_PLT: | ||
232 | - case R_PPC_RELAX32_PLT: | ||
233 | + case R_PPC_RELAX_PLT: | ||
234 | + case R_PPC_RELAX_PLTREL24: | ||
235 | if (h != NULL) | ||
236 | { | ||
237 | - struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2, | ||
238 | - info->shared ? addend : 0); | ||
239 | + struct plt_entry *ent; | ||
240 | + bfd_vma got2_addend = 0; | ||
241 | + | ||
242 | + if (r_type == R_PPC_RELAX_PLTREL24) | ||
243 | + { | ||
244 | + if (info->shared) | ||
245 | + got2_addend = addend; | ||
246 | + addend = 0; | ||
247 | + } | ||
248 | + ent = find_plt_ent (&h->plt.plist, got2, got2_addend); | ||
249 | if (htab->plt_type == PLT_NEW) | ||
250 | relocation = (htab->glink->output_section->vma | ||
251 | + htab->glink->output_offset | ||
252 | @@ -7684,18 +7708,14 @@ | ||
253 | + htab->plt->output_offset | ||
254 | + ent->plt.offset); | ||
255 | } | ||
256 | - if (r_type == R_PPC_RELAX32_PLT) | ||
257 | - goto relax32; | ||
258 | /* Fall thru */ | ||
259 | |||
260 | - case R_PPC_RELAX32PC: | ||
261 | - relocation -= (input_section->output_section->vma | ||
262 | - + input_section->output_offset | ||
263 | - + rel->r_offset - 4); | ||
264 | - /* Fall thru */ | ||
265 | + case R_PPC_RELAX: | ||
266 | + if (info->shared) | ||
267 | + relocation -= (input_section->output_section->vma | ||
268 | + + input_section->output_offset | ||
269 | + + rel->r_offset - 4); | ||
270 | |||
271 | - case R_PPC_RELAX32: | ||
272 | - relax32: | ||
273 | { | ||
274 | unsigned long t0; | ||
275 | unsigned long t1; | ||