summaryrefslogtreecommitdiffstats
path: root/meta/packages/binutils/binutils-2.20/binutils-powerpc-pr11088.patch
diff options
context:
space:
mode:
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.patch275
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 @@
1Fix ld segfault when compiling Qt 4.6.0 on powerpc. See:
2
3http://sourceware.org/bugzilla/show_bug.cgi?id=11088
4
5===================================================================
6RCS file: /cvs/src/src/include/elf/ppc.h,v
7retrieving revision 1.26
8retrieving revision 1.27
9diff -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===================================================================
27RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
28retrieving revision 1.272
29retrieving revision 1.273
30diff -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;