]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/binutils/binutils-2.16/binutils-2.16-thumb-trampoline.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / binutils / binutils-2.16 / binutils-2.16-thumb-trampoline.patch
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),