aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch
diff options
context:
space:
mode:
authorDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
committerDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
commit709c4d66e0b107ca606941b988bad717c0b45d9b (patch)
tree37ee08b1eb308f3b2b6426d5793545c38396b838 /recipes/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch
parentfa6cd5a3b993f16c27de4ff82b42684516d433ba (diff)
downloadopenembedded-709c4d66e0b107ca606941b988bad717c0b45d9b.tar.gz
rename packages/ to recipes/ per earlier agreement
See links below for more details: http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326 http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816 Signed-off-by: Denys Dmytriyenko <denis@denix.org> Acked-by: Mike Westerhof <mwester@dls.net> Acked-by: Philip Balister <philip@balister.org> Acked-by: Khem Raj <raj.khem@gmail.com> Acked-by: Marcin Juszkiewicz <hrw@openembedded.org> Acked-by: Koen Kooi <koen@openembedded.org> Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'recipes/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch')
-rw-r--r--recipes/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch292
1 files changed, 292 insertions, 0 deletions
diff --git a/recipes/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch b/recipes/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch
new file mode 100644
index 0000000000..a4f90a7254
--- /dev/null
+++ b/recipes/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch
@@ -0,0 +1,292 @@
+--- binutils-2.16/.pc/binutils-2.16-thumb-trampoline.patch/bfd/elf32-arm.c 2005-05-02 12:43:06.000000000 -0700
++++ binutils-2.16/bfd/elf32-arm.c 2005-09-19 22:58:49.834931044 -0700
+@@ -24,6 +24,8 @@
+ #include "libbfd.h"
+ #include "elf-bfd.h"
+
++#define NOTE_DEBUG 0
++
+ #ifndef NUM_ELEM
+ #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
+ #endif
+@@ -1127,6 +1129,10 @@
+ used, we need to record the index into .got.plt instead of
+ recomputing it from the PLT offset. */
+ bfd_signed_vma plt_got_offset;
++
++ /* This is used to sanity check that the Thumb trampoline space
++ really was allocated. */
++ int accomodate_trampoline;
+ };
+
+ /* Traverse an arm ELF linker hash table. */
+@@ -1219,9 +1225,15 @@
+ table, string));
+ if (ret != NULL)
+ {
++#if NOTE_DEBUG
++ _bfd_error_handler(
++ _("NOTE: %x(%s): New hash entry (plt refcount %d)"),
++ ret, string, ret->root.plt.refcount);
++#endif
+ ret->relocs_copied = NULL;
+ ret->plt_thumb_refcount = 0;
+ ret->plt_got_offset = -1;
++ ret->accomodate_trampoline = 0;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+@@ -1335,16 +1347,38 @@
+ eind->relocs_copied = NULL;
+ }
+
+- /* If the direct symbol already has an associated PLT entry, the
+- indirect symbol should not. If it doesn't, swap refcount information
+- from the indirect symbol. */
+- if (edir->plt_thumb_refcount == 0)
++ if (ind->root.type == bfd_link_hash_indirect)
+ {
+- edir->plt_thumb_refcount = eind->plt_thumb_refcount;
+- eind->plt_thumb_refcount = 0;
++ bfd_signed_vma tmp;
++ bfd_signed_vma lowest_valid = bed->can_refcount;
++
++ /* If the direct symbol already has an associated PLT entry, the
++ indirect symbol should not. If it doesn't, swap refcount information
++ from the indirect symbol. */
++#if NOTE_DEBUG
++ _bfd_error_handler(_("NOTE: %x(%s,%d,%d) <== %x(%s,%d,%d)"),
++ dir, dir->root.root.string, dir->plt.refcount, edir->plt_thumb_refcount,
++ ind, ind->root.root.string, ind->plt.refcount, eind->plt_thumb_refcount);
++#endif
++
++ /* Copy over the global and procedure linkage table refcount entries.
++ These may have been already set up by a check_relocs routine. This
++ code duplicates that for the plt refcount in elf.c
++ _bfd_elf_link_hash_copy_indirect */
++ tmp = dir->plt.refcount;
++ /* this obfuscated test evaluates to bed->can_refcount && plt.refcount == 0
++ * || plt.refcount < 0.
++ */
++ if (tmp < lowest_valid)
++ {
++ tmp = edir->plt_thumb_refcount;
++ edir->plt_thumb_refcount = eind->plt_thumb_refcount;
++ eind->plt_thumb_refcount = tmp;
++ BFD_ASSERT(eind->accomodate_trampoline == 0);
++ }
++ else
++ BFD_ASSERT (eind->plt_thumb_refcount == 0);
+ }
+- else
+- BFD_ASSERT (eind->plt_thumb_refcount == 0);
+
+ _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ }
+@@ -2060,7 +2094,7 @@
+ (*_bfd_error_handler)
+ (_("%B(%s): warning: interworking not enabled.\n"
+ " first occurrence: %B: thumb call to arm"),
+- sym_sec->owner, input_bfd, name);
++ sym_sec->owner, name, input_bfd);
+
+ return FALSE;
+ }
+@@ -2165,7 +2199,7 @@
+ (*_bfd_error_handler)
+ (_("%B(%s): warning: interworking not enabled.\n"
+ " first occurrence: %B: arm call to thumb"),
+- sym_sec->owner, input_bfd, name);
++ sym_sec->owner, name, input_bfd);
+ }
+
+ --my_offset;
+@@ -2481,7 +2515,7 @@
+ instruction instead ? */
+ if (sym_flags != STT_ARM_TFUNC)
+ (*_bfd_error_handler)
+- (_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
++ (_("%B: Warning: Arm BLX instruction targets Arm function '%s'."),
+ input_bfd,
+ h ? h->root.root.string : "(local)");
+ }
+@@ -2697,6 +2731,20 @@
+ /* Handle calls via the PLT. */
+ if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
+ {
++ struct elf32_arm_link_hash_entry *eh;
++ eh = (struct elf32_arm_link_hash_entry *) h;
++ if (!eh->accomodate_trampoline)
++ {
++ /* %B of output_bfd crashes here, so %x is used instead */
++ _bfd_error_handler(
++ _("ERROR: %B: %x(%s): missing thumb trampoline, refcount(thumb %d, plt %d) in %x at %x+%x+%x"),
++ input_bfd, h, h->root.root.string, eh->plt_thumb_refcount,
++ h->plt.refcount, output_bfd, splt->output_section->vma,
++ splt->output_offset, h->plt.offset);
++ /* The relocation would point to garbage, it gets skipped... */
++ return bfd_reloc_dangerous;
++ }
++
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+@@ -3525,8 +3573,9 @@
+ {
+ _bfd_error_handler
+ (_("ERROR: Source object %B has EABI version %d, but target %B has EABI version %d"),
+- ibfd, obfd,
++ ibfd,
+ (in_flags & EF_ARM_EABIMASK) >> 24,
++ obfd,
+ (out_flags & EF_ARM_EABIMASK) >> 24);
+ return FALSE;
+ }
+@@ -3538,8 +3587,9 @@
+ {
+ _bfd_error_handler
+ (_("ERROR: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"),
+- ibfd, obfd,
++ ibfd,
+ in_flags & EF_ARM_APCS_26 ? 26 : 32,
++ obfd,
+ out_flags & EF_ARM_APCS_26 ? 26 : 32);
+ flags_compatible = FALSE;
+ }
+@@ -3903,10 +3953,18 @@
+ eh = (struct elf32_arm_link_hash_entry *) h;
+
+ if (h->plt.refcount > 0)
++ h->plt.refcount -= 1;
++
++ if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22)
+ {
+- h->plt.refcount -= 1;
+- if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22)
+- eh->plt_thumb_refcount--;
++ BFD_ASSERT (eh->plt_thumb_refcount > 0);
++ eh->plt_thumb_refcount--;
++ BFD_ASSERT (eh->accomodate_trampoline == 0);
++#if NOTE_DEBUG
++ _bfd_error_handler(
++ _("NOTE: %B: %x(%s): Thumb refcount decremented to %d (plt refcount %d)"),
++ abfd, h, h->root.root.string, eh->plt_thumb_refcount, h->plt.refcount);
++#endif
+ }
+
+ if (r_type == R_ARM_ABS32
+@@ -3994,6 +4052,10 @@
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
++#if NOTE_DEBUG
++ if (h != NULL)
++ _bfd_error_handler(_("NOTE: %B: %x(%s): verify relocation"), abfd, h, h->root.root.string);
++#endif
+
+ switch (r_type)
+ {
+@@ -4078,10 +4140,30 @@
+
+ /* If we create a PLT entry, this relocation will reference
+ it, even if it's an ABS32 relocation. */
+- h->plt.refcount += 1;
++ if (h->plt.refcount >= 0)
++ h->plt.refcount += 1;
++ else
++ {
++ /* This happens, I suspect it happens with glue code because,
++ * somehow, the backend data had can_refcount==0. Expert required...
++ */
++ _bfd_error_handler(
++ _("WARNING: %B: %x(%s): PLT refcount was %d (set to 1)"),
++ abfd, h, h->root.root.string, h->plt.refcount);
++ h->plt.refcount = 1;
++ }
+
+ if (r_type == R_ARM_THM_PC22)
+- eh->plt_thumb_refcount += 1;
++ {
++ eh->plt_thumb_refcount += 1;
++ BFD_ASSERT (eh->plt_thumb_refcount <= h->plt.refcount);
++ BFD_ASSERT (eh->accomodate_trampoline == 0);
++#if NOTE_DEBUG
++ _bfd_error_handler(
++ _("NOTE: %B: %x(%s): Thumb refcount incremented to %d (plt refcount %d)"),
++ abfd, h, h->root.root.string, eh->plt_thumb_refcount, h->plt.refcount);
++#endif
++ }
+ }
+
+ /* If we are creating a shared library or relocatable executable,
+@@ -4376,8 +4458,15 @@
+ object, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC24 reloc instead. */
++#if NOTE_DEBUG
++ _bfd_error_handler(
++ _("NOTE: %x(%s): Thumb refcount zeroed (plt refcount %d, thumb %d) (%s)"),
++ h, h->root.root.string, h->plt.refcount, eh->plt_thumb_refcount,
++ SYMBOL_CALLS_LOCAL (info, h) ? "local call" : "invisible");
++#endif
+ h->plt.offset = (bfd_vma) -1;
+ eh->plt_thumb_refcount = 0;
++ BFD_ASSERT (eh->accomodate_trampoline == 0);
+ h->needs_plt = 0;
+ }
+
+@@ -4390,8 +4479,14 @@
+ in check_relocs. We can't decide accurately between function
+ and non-function syms in check-relocs; Objects loaded later in
+ the link may change h->type. So fix it now. */
++#if NOTE_DEBUG
++ _bfd_error_handler(
++ _("NOTE: %x(%s): Thumb refcount zeroed (%d, plt refcount %d)"),
++ h, h->root.root.string, eh->plt_thumb_refcount, h->plt.refcount);
++#endif
+ h->plt.offset = (bfd_vma) -1;
+ eh->plt_thumb_refcount = 0;
++ BFD_ASSERT (eh->accomodate_trampoline == 0);
+ }
+
+ /* If this is a weak symbol, and there is a real definition, the
+@@ -4521,8 +4616,14 @@
+ for it. */
+ if (!htab->symbian_p && eh->plt_thumb_refcount > 0)
+ {
++#if NOTE_DEBUG
++ _bfd_error_handler(_("NOTE: %x(%s): Thumb trampoline created at %x"),
++ h, h->root.root.string, h->plt.offset);
++#endif
+ h->plt.offset += PLT_THUMB_STUB_SIZE;
+ s->size += PLT_THUMB_STUB_SIZE;
++ BFD_ASSERT (eh->accomodate_trampoline == 0);
++ eh->accomodate_trampoline = 1;
+ }
+
+ /* If this symbol is not defined in a regular file, and we are
+@@ -5014,10 +5115,20 @@
+
+ if (eh->plt_thumb_refcount > 0)
+ {
+- bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[0],
+- splt->contents + h->plt.offset - 4);
+- bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[1],
+- splt->contents + h->plt.offset - 2);
++ if (eh->accomodate_trampoline == 1)
++ {
++ bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[0],
++ splt->contents + h->plt.offset - 4);
++ bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[1],
++ splt->contents + h->plt.offset - 2);
++ }
++ else
++ {
++ (*_bfd_error_handler) (
++ _("%B: no space for THUMB trampoline at %x[%x]"),
++ output_bfd, h->plt.offset, got_offset);
++ return FALSE;
++ }
+ }
+
+ bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20),