diff options
Diffstat (limited to 'openembedded/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch')
| -rw-r--r-- | openembedded/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch | 292 |
1 files changed, 0 insertions, 292 deletions
diff --git a/openembedded/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch b/openembedded/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch deleted file mode 100644 index a4f90a7254..0000000000 --- a/openembedded/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch +++ /dev/null | |||
| @@ -1,292 +0,0 @@ | |||
| 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), | ||
