summaryrefslogtreecommitdiffstats
path: root/meta/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch')
-rw-r--r--meta/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch292
1 files changed, 292 insertions, 0 deletions
diff --git a/meta/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch b/meta/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch
new file mode 100644
index 0000000000..a4f90a7254
--- /dev/null
+++ b/meta/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch
@@ -0,0 +1,292 @@
1--- binutils-2.16/.pc/binutils-2.16-thumb-trampoline.patch/bfd/elf32-arm.c 2005-05-02 12:43:06.000000000 -0700
2+++ binutils-2.16/bfd/elf32-arm.c 2005-09-19 22:58:49.834931044 -0700
3@@ -24,6 +24,8 @@
4 #include "libbfd.h"
5 #include "elf-bfd.h"
6
7+#define NOTE_DEBUG 0
8+
9 #ifndef NUM_ELEM
10 #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
11 #endif
12@@ -1127,6 +1129,10 @@
13 used, we need to record the index into .got.plt instead of
14 recomputing it from the PLT offset. */
15 bfd_signed_vma plt_got_offset;
16+
17+ /* This is used to sanity check that the Thumb trampoline space
18+ really was allocated. */
19+ int accomodate_trampoline;
20 };
21
22 /* Traverse an arm ELF linker hash table. */
23@@ -1219,9 +1225,15 @@
24 table, string));
25 if (ret != NULL)
26 {
27+#if NOTE_DEBUG
28+ _bfd_error_handler(
29+ _("NOTE: %x(%s): New hash entry (plt refcount %d)"),
30+ ret, string, ret->root.plt.refcount);
31+#endif
32 ret->relocs_copied = NULL;
33 ret->plt_thumb_refcount = 0;
34 ret->plt_got_offset = -1;
35+ ret->accomodate_trampoline = 0;
36 }
37
38 return (struct bfd_hash_entry *) ret;
39@@ -1335,16 +1347,38 @@
40 eind->relocs_copied = NULL;
41 }
42
43- /* If the direct symbol already has an associated PLT entry, the
44- indirect symbol should not. If it doesn't, swap refcount information
45- from the indirect symbol. */
46- if (edir->plt_thumb_refcount == 0)
47+ if (ind->root.type == bfd_link_hash_indirect)
48 {
49- edir->plt_thumb_refcount = eind->plt_thumb_refcount;
50- eind->plt_thumb_refcount = 0;
51+ bfd_signed_vma tmp;
52+ bfd_signed_vma lowest_valid = bed->can_refcount;
53+
54+ /* If the direct symbol already has an associated PLT entry, the
55+ indirect symbol should not. If it doesn't, swap refcount information
56+ from the indirect symbol. */
57+#if NOTE_DEBUG
58+ _bfd_error_handler(_("NOTE: %x(%s,%d,%d) <== %x(%s,%d,%d)"),
59+ dir, dir->root.root.string, dir->plt.refcount, edir->plt_thumb_refcount,
60+ ind, ind->root.root.string, ind->plt.refcount, eind->plt_thumb_refcount);
61+#endif
62+
63+ /* Copy over the global and procedure linkage table refcount entries.
64+ These may have been already set up by a check_relocs routine. This
65+ code duplicates that for the plt refcount in elf.c
66+ _bfd_elf_link_hash_copy_indirect */
67+ tmp = dir->plt.refcount;
68+ /* this obfuscated test evaluates to bed->can_refcount && plt.refcount == 0
69+ * || plt.refcount < 0.
70+ */
71+ if (tmp < lowest_valid)
72+ {
73+ tmp = edir->plt_thumb_refcount;
74+ edir->plt_thumb_refcount = eind->plt_thumb_refcount;
75+ eind->plt_thumb_refcount = tmp;
76+ BFD_ASSERT(eind->accomodate_trampoline == 0);
77+ }
78+ else
79+ BFD_ASSERT (eind->plt_thumb_refcount == 0);
80 }
81- else
82- BFD_ASSERT (eind->plt_thumb_refcount == 0);
83
84 _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
85 }
86@@ -2060,7 +2094,7 @@
87 (*_bfd_error_handler)
88 (_("%B(%s): warning: interworking not enabled.\n"
89 " first occurrence: %B: thumb call to arm"),
90- sym_sec->owner, input_bfd, name);
91+ sym_sec->owner, name, input_bfd);
92
93 return FALSE;
94 }
95@@ -2165,7 +2199,7 @@
96 (*_bfd_error_handler)
97 (_("%B(%s): warning: interworking not enabled.\n"
98 " first occurrence: %B: arm call to thumb"),
99- sym_sec->owner, input_bfd, name);
100+ sym_sec->owner, name, input_bfd);
101 }
102
103 --my_offset;
104@@ -2481,7 +2515,7 @@
105 instruction instead ? */
106 if (sym_flags != STT_ARM_TFUNC)
107 (*_bfd_error_handler)
108- (_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
109+ (_("%B: Warning: Arm BLX instruction targets Arm function '%s'."),
110 input_bfd,
111 h ? h->root.root.string : "(local)");
112 }
113@@ -2697,6 +2731,20 @@
114 /* Handle calls via the PLT. */
115 if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
116 {
117+ struct elf32_arm_link_hash_entry *eh;
118+ eh = (struct elf32_arm_link_hash_entry *) h;
119+ if (!eh->accomodate_trampoline)
120+ {
121+ /* %B of output_bfd crashes here, so %x is used instead */
122+ _bfd_error_handler(
123+ _("ERROR: %B: %x(%s): missing thumb trampoline, refcount(thumb %d, plt %d) in %x at %x+%x+%x"),
124+ input_bfd, h, h->root.root.string, eh->plt_thumb_refcount,
125+ h->plt.refcount, output_bfd, splt->output_section->vma,
126+ splt->output_offset, h->plt.offset);
127+ /* The relocation would point to garbage, it gets skipped... */
128+ return bfd_reloc_dangerous;
129+ }
130+
131 value = (splt->output_section->vma
132 + splt->output_offset
133 + h->plt.offset);
134@@ -3525,8 +3573,9 @@
135 {
136 _bfd_error_handler
137 (_("ERROR: Source object %B has EABI version %d, but target %B has EABI version %d"),
138- ibfd, obfd,
139+ ibfd,
140 (in_flags & EF_ARM_EABIMASK) >> 24,
141+ obfd,
142 (out_flags & EF_ARM_EABIMASK) >> 24);
143 return FALSE;
144 }
145@@ -3538,8 +3587,9 @@
146 {
147 _bfd_error_handler
148 (_("ERROR: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"),
149- ibfd, obfd,
150+ ibfd,
151 in_flags & EF_ARM_APCS_26 ? 26 : 32,
152+ obfd,
153 out_flags & EF_ARM_APCS_26 ? 26 : 32);
154 flags_compatible = FALSE;
155 }
156@@ -3903,10 +3953,18 @@
157 eh = (struct elf32_arm_link_hash_entry *) h;
158
159 if (h->plt.refcount > 0)
160+ h->plt.refcount -= 1;
161+
162+ if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22)
163 {
164- h->plt.refcount -= 1;
165- if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22)
166- eh->plt_thumb_refcount--;
167+ BFD_ASSERT (eh->plt_thumb_refcount > 0);
168+ eh->plt_thumb_refcount--;
169+ BFD_ASSERT (eh->accomodate_trampoline == 0);
170+#if NOTE_DEBUG
171+ _bfd_error_handler(
172+ _("NOTE: %B: %x(%s): Thumb refcount decremented to %d (plt refcount %d)"),
173+ abfd, h, h->root.root.string, eh->plt_thumb_refcount, h->plt.refcount);
174+#endif
175 }
176
177 if (r_type == R_ARM_ABS32
178@@ -3994,6 +4052,10 @@
179 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
180
181 eh = (struct elf32_arm_link_hash_entry *) h;
182+#if NOTE_DEBUG
183+ if (h != NULL)
184+ _bfd_error_handler(_("NOTE: %B: %x(%s): verify relocation"), abfd, h, h->root.root.string);
185+#endif
186
187 switch (r_type)
188 {
189@@ -4078,10 +4140,30 @@
190
191 /* If we create a PLT entry, this relocation will reference
192 it, even if it's an ABS32 relocation. */
193- h->plt.refcount += 1;
194+ if (h->plt.refcount >= 0)
195+ h->plt.refcount += 1;
196+ else
197+ {
198+ /* This happens, I suspect it happens with glue code because,
199+ * somehow, the backend data had can_refcount==0. Expert required...
200+ */
201+ _bfd_error_handler(
202+ _("WARNING: %B: %x(%s): PLT refcount was %d (set to 1)"),
203+ abfd, h, h->root.root.string, h->plt.refcount);
204+ h->plt.refcount = 1;
205+ }
206
207 if (r_type == R_ARM_THM_PC22)
208- eh->plt_thumb_refcount += 1;
209+ {
210+ eh->plt_thumb_refcount += 1;
211+ BFD_ASSERT (eh->plt_thumb_refcount <= h->plt.refcount);
212+ BFD_ASSERT (eh->accomodate_trampoline == 0);
213+#if NOTE_DEBUG
214+ _bfd_error_handler(
215+ _("NOTE: %B: %x(%s): Thumb refcount incremented to %d (plt refcount %d)"),
216+ abfd, h, h->root.root.string, eh->plt_thumb_refcount, h->plt.refcount);
217+#endif
218+ }
219 }
220
221 /* If we are creating a shared library or relocatable executable,
222@@ -4376,8 +4458,15 @@
223 object, or if all references were garbage collected. In
224 such a case, we don't actually need to build a procedure
225 linkage table, and we can just do a PC24 reloc instead. */
226+#if NOTE_DEBUG
227+ _bfd_error_handler(
228+ _("NOTE: %x(%s): Thumb refcount zeroed (plt refcount %d, thumb %d) (%s)"),
229+ h, h->root.root.string, h->plt.refcount, eh->plt_thumb_refcount,
230+ SYMBOL_CALLS_LOCAL (info, h) ? "local call" : "invisible");
231+#endif
232 h->plt.offset = (bfd_vma) -1;
233 eh->plt_thumb_refcount = 0;
234+ BFD_ASSERT (eh->accomodate_trampoline == 0);
235 h->needs_plt = 0;
236 }
237
238@@ -4390,8 +4479,14 @@
239 in check_relocs. We can't decide accurately between function
240 and non-function syms in check-relocs; Objects loaded later in
241 the link may change h->type. So fix it now. */
242+#if NOTE_DEBUG
243+ _bfd_error_handler(
244+ _("NOTE: %x(%s): Thumb refcount zeroed (%d, plt refcount %d)"),
245+ h, h->root.root.string, eh->plt_thumb_refcount, h->plt.refcount);
246+#endif
247 h->plt.offset = (bfd_vma) -1;
248 eh->plt_thumb_refcount = 0;
249+ BFD_ASSERT (eh->accomodate_trampoline == 0);
250 }
251
252 /* If this is a weak symbol, and there is a real definition, the
253@@ -4521,8 +4616,14 @@
254 for it. */
255 if (!htab->symbian_p && eh->plt_thumb_refcount > 0)
256 {
257+#if NOTE_DEBUG
258+ _bfd_error_handler(_("NOTE: %x(%s): Thumb trampoline created at %x"),
259+ h, h->root.root.string, h->plt.offset);
260+#endif
261 h->plt.offset += PLT_THUMB_STUB_SIZE;
262 s->size += PLT_THUMB_STUB_SIZE;
263+ BFD_ASSERT (eh->accomodate_trampoline == 0);
264+ eh->accomodate_trampoline = 1;
265 }
266
267 /* If this symbol is not defined in a regular file, and we are
268@@ -5014,10 +5115,20 @@
269
270 if (eh->plt_thumb_refcount > 0)
271 {
272- bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[0],
273- splt->contents + h->plt.offset - 4);
274- bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[1],
275- splt->contents + h->plt.offset - 2);
276+ if (eh->accomodate_trampoline == 1)
277+ {
278+ bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[0],
279+ splt->contents + h->plt.offset - 4);
280+ bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[1],
281+ splt->contents + h->plt.offset - 2);
282+ }
283+ else
284+ {
285+ (*_bfd_error_handler) (
286+ _("%B: no space for THUMB trampoline at %x[%x]"),
287+ output_bfd, h->plt.offset, got_offset);
288+ return FALSE;
289+ }
290 }
291
292 bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20),