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
10 #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
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;
17 + /* This is used to sanity check that the Thumb trampoline space
18 + really was allocated. */
19 + int accomodate_trampoline;
22 /* Traverse an arm ELF linker hash table. */
23 @@ -1219,9 +1225,15 @@
29 + _("NOTE: %x(%s): New hash entry (plt refcount %d)"),
30 + ret, string, ret->root.plt.refcount);
32 ret->relocs_copied = NULL;
33 ret->plt_thumb_refcount = 0;
34 ret->plt_got_offset = -1;
35 + ret->accomodate_trampoline = 0;
38 return (struct bfd_hash_entry *) ret;
39 @@ -1335,16 +1347,38 @@
40 eind->relocs_copied = NULL;
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)
49 - edir->plt_thumb_refcount = eind->plt_thumb_refcount;
50 - eind->plt_thumb_refcount = 0;
52 + bfd_signed_vma lowest_valid = bed->can_refcount;
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. */
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);
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.
71 + if (tmp < lowest_valid)
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);
79 + BFD_ASSERT (eind->plt_thumb_refcount == 0);
82 - BFD_ASSERT (eind->plt_thumb_refcount == 0);
84 _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
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);
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);
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'."),
111 h ? h->root.root.string : "(local)");
113 @@ -2697,6 +2731,20 @@
114 /* Handle calls via the PLT. */
115 if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
117 + struct elf32_arm_link_hash_entry *eh;
118 + eh = (struct elf32_arm_link_hash_entry *) h;
119 + if (!eh->accomodate_trampoline)
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;
131 value = (splt->output_section->vma
132 + splt->output_offset
134 @@ -3525,8 +3573,9 @@
137 (_("ERROR: Source object %B has EABI version %d, but target %B has EABI version %d"),
140 (in_flags & EF_ARM_EABIMASK) >> 24,
142 (out_flags & EF_ARM_EABIMASK) >> 24);
145 @@ -3538,8 +3587,9 @@
148 (_("ERROR: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"),
151 in_flags & EF_ARM_APCS_26 ? 26 : 32,
153 out_flags & EF_ARM_APCS_26 ? 26 : 32);
154 flags_compatible = FALSE;
156 @@ -3903,10 +3953,18 @@
157 eh = (struct elf32_arm_link_hash_entry *) h;
159 if (h->plt.refcount > 0)
160 + h->plt.refcount -= 1;
162 + if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22)
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);
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);
177 if (r_type == R_ARM_ABS32
178 @@ -3994,6 +4052,10 @@
179 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
181 eh = (struct elf32_arm_link_hash_entry *) h;
184 + _bfd_error_handler(_("NOTE: %B: %x(%s): verify relocation"), abfd, h, h->root.root.string);
189 @@ -4078,10 +4140,30 @@
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;
198 + /* This happens, I suspect it happens with glue code because,
199 + * somehow, the backend data had can_refcount==0. Expert required...
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;
207 if (r_type == R_ARM_THM_PC22)
208 - eh->plt_thumb_refcount += 1;
210 + eh->plt_thumb_refcount += 1;
211 + BFD_ASSERT (eh->plt_thumb_refcount <= h->plt.refcount);
212 + BFD_ASSERT (eh->accomodate_trampoline == 0);
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);
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. */
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");
232 h->plt.offset = (bfd_vma) -1;
233 eh->plt_thumb_refcount = 0;
234 + BFD_ASSERT (eh->accomodate_trampoline == 0);
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. */
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);
247 h->plt.offset = (bfd_vma) -1;
248 eh->plt_thumb_refcount = 0;
249 + BFD_ASSERT (eh->accomodate_trampoline == 0);
252 /* If this is a weak symbol, and there is a real definition, the
253 @@ -4521,8 +4616,14 @@
255 if (!htab->symbian_p && eh->plt_thumb_refcount > 0)
258 + _bfd_error_handler(_("NOTE: %x(%s): Thumb trampoline created at %x"),
259 + h, h->root.root.string, h->plt.offset);
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;
267 /* If this symbol is not defined in a regular file, and we are
268 @@ -5014,10 +5115,20 @@
270 if (eh->plt_thumb_refcount > 0)
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)
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);
285 + (*_bfd_error_handler) (
286 + _("%B: no space for THUMB trampoline at %x[%x]"),
287 + output_bfd, h->plt.offset, got_offset);
292 bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20),