2002-04-04 Daniel Jacobowitz <drow@mvista.com>
[external/binutils.git] / bfd / coff-arm.c
1 /* BFD back-end for ARM COFF files.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002
4    Free Software Foundation, Inc.
5    Written by Cygnus Support.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26
27 #include "coff/arm.h"
28
29 #include "coff/internal.h"
30
31 #ifdef COFF_WITH_PE
32 #include "coff/pe.h"
33 #endif
34
35 #include "libcoff.h"
36
37 /* Macros for manipulation the bits in the flags field of the coff data
38    structure.  */
39 #define APCS_26_FLAG(abfd) \
40   (coff_data (abfd)->flags & F_APCS_26)
41
42 #define APCS_FLOAT_FLAG(abfd) \
43   (coff_data (abfd)->flags & F_APCS_FLOAT)
44
45 #define PIC_FLAG(abfd) \
46   (coff_data (abfd)->flags & F_PIC)
47
48 #define APCS_SET(abfd) \
49   (coff_data (abfd)->flags & F_APCS_SET)
50
51 #define SET_APCS_FLAGS(abfd, flgs) \
52   do                                                                    \
53     {                                                                   \
54       coff_data (abfd)->flags &= ~(F_APCS_26 | F_APCS_FLOAT | F_PIC);   \
55       coff_data (abfd)->flags |= (flgs) | F_APCS_SET;                   \
56     }                                                                   \
57   while (0)
58
59 #define INTERWORK_FLAG(abfd) \
60   (coff_data (abfd)->flags & F_INTERWORK)
61
62 #define INTERWORK_SET(abfd) \
63   (coff_data (abfd)->flags & F_INTERWORK_SET)
64
65 #define SET_INTERWORK_FLAG(abfd, flg) \
66   do                                                                    \
67     {                                                                   \
68       coff_data (abfd)->flags &= ~F_INTERWORK;                          \
69       coff_data (abfd)->flags |= (flg) | F_INTERWORK_SET;               \
70     }                                                                   \
71   while (0)
72
73 #ifndef NUM_ELEM
74 #define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
75 #endif
76
77 typedef enum {bunknown, b9, b12, b23} thumb_pcrel_branchtype;
78 /* some typedefs for holding instructions */
79 typedef unsigned long int insn32;
80 typedef unsigned short int insn16;
81
82      /* Forward declarations for stupid compilers.  */
83 static boolean coff_arm_relocate_section
84   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
85            struct internal_reloc *, struct internal_syment *, asection **));
86 static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
87   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
88 static bfd_reloc_status_type aoutarm_fix_pcrel_26
89   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
90 static bfd_reloc_status_type coff_thumb_pcrel_23
91   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
92 static bfd_reloc_status_type coff_thumb_pcrel_12
93   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
94 static bfd_reloc_status_type coff_thumb_pcrel_9
95   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
96 static bfd_reloc_status_type coff_arm_reloc
97   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
98 static boolean coff_arm_adjust_symndx
99   PARAMS ((bfd *, struct bfd_link_info *, bfd *,
100            asection *, struct internal_reloc *, boolean *));
101 static reloc_howto_type * coff_arm_rtype_to_howto
102   PARAMS ((bfd *, asection *, struct internal_reloc *,
103            struct coff_link_hash_entry *, struct internal_syment *,
104            bfd_vma *));
105 static bfd_reloc_status_type coff_thumb_pcrel_common
106   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **,
107            thumb_pcrel_branchtype));
108 static const struct reloc_howto_struct * coff_arm_reloc_type_lookup
109   PARAMS ((bfd *, bfd_reloc_code_real_type));
110 static struct bfd_link_hash_table * coff_arm_link_hash_table_create
111   PARAMS ((bfd *));
112 static insn32 insert_thumb_branch
113   PARAMS ((insn32, int));
114 static struct coff_link_hash_entry * find_thumb_glue
115   PARAMS ((struct bfd_link_info *, const char *, bfd *));
116 static struct coff_link_hash_entry * find_arm_glue
117   PARAMS ((struct bfd_link_info *, const char *, bfd *));
118 #ifndef COFF_IMAGE_WITH_PE
119 static void record_arm_to_thumb_glue
120   PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *));
121 static void record_thumb_to_arm_glue
122   PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *));
123 #endif
124 static boolean coff_arm_merge_private_bfd_data
125   PARAMS ((bfd *, bfd *));
126 static boolean coff_arm_print_private_bfd_data
127   PARAMS ((bfd *, PTR));
128 static boolean _bfd_coff_arm_set_private_flags
129   PARAMS ((bfd *, flagword));
130 static boolean coff_arm_copy_private_bfd_data
131   PARAMS ((bfd *, bfd *));
132 static boolean coff_arm_is_local_label_name
133   PARAMS ((bfd *, const char *));
134 static boolean coff_arm_link_output_has_begun
135   PARAMS ((bfd *, struct coff_final_link_info *));
136 static boolean coff_arm_final_link_postscript
137   PARAMS ((bfd *, struct coff_final_link_info *));
138 static void arm_emit_base_file_entry
139   PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_vma));
140
141 /* The linker script knows the section names for placement.
142    The entry_names are used to do simple name mangling on the stubs.
143    Given a function name, and its type, the stub can be found. The
144    name can be changed. The only requirement is the %s be present.  */
145
146 #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
147 #define THUMB2ARM_GLUE_ENTRY_NAME   "__%s_from_thumb"
148
149 #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
150 #define ARM2THUMB_GLUE_ENTRY_NAME   "__%s_from_arm"
151
152 /* Used by the assembler.  */
153
154 static bfd_reloc_status_type
155 coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
156                  error_message)
157      bfd *abfd;
158      arelent *reloc_entry;
159      asymbol *symbol ATTRIBUTE_UNUSED;
160      PTR data;
161      asection *input_section ATTRIBUTE_UNUSED;
162      bfd *output_bfd;
163      char **error_message ATTRIBUTE_UNUSED;
164 {
165   symvalue diff;
166   if (output_bfd == (bfd *) NULL)
167     return bfd_reloc_continue;
168
169   diff = reloc_entry->addend;
170
171 #define DOIT(x)                                                 \
172   x = ((x & ~howto->dst_mask)                                   \
173        | (((x & howto->src_mask) + diff) & howto->dst_mask))
174
175     if (diff != 0)
176       {
177         reloc_howto_type *howto = reloc_entry->howto;
178         unsigned char *addr = (unsigned char *) data + reloc_entry->address;
179
180         switch (howto->size)
181           {
182           case 0:
183             {
184               char x = bfd_get_8 (abfd, addr);
185               DOIT (x);
186               bfd_put_8 (abfd, x, addr);
187             }
188             break;
189
190           case 1:
191             {
192               short x = bfd_get_16 (abfd, addr);
193               DOIT (x);
194               bfd_put_16 (abfd, (bfd_vma) x, addr);
195             }
196             break;
197
198           case 2:
199             {
200               long x = bfd_get_32 (abfd, addr);
201               DOIT (x);
202               bfd_put_32 (abfd, (bfd_vma) x, addr);
203             }
204             break;
205
206           default:
207             abort ();
208           }
209       }
210
211   /* Now let bfd_perform_relocation finish everything up.  */
212   return bfd_reloc_continue;
213 }
214
215 /* If USER_LABEL_PREFIX is defined as "_" (see coff_arm_is_local_label_name()
216    in this file), then TARGET_UNDERSCORE should be defined, otherwise it
217    should not.  */
218 #ifndef TARGET_UNDERSCORE
219 #define TARGET_UNDERSCORE '_'
220 #endif
221
222 #ifndef PCRELOFFSET
223 #define PCRELOFFSET true
224 #endif
225
226 /* These most certainly belong somewhere else. Just had to get rid of
227    the manifest constants in the code.  */
228 #define ARM_8        0
229 #define ARM_16       1
230 #define ARM_32       2
231 #define ARM_26       3
232 #define ARM_DISP8    4
233 #define ARM_DISP16   5
234 #define ARM_DISP32   6
235 #define ARM_26D      7
236 /* 8 is unused */
237 #define ARM_NEG16    9
238 #define ARM_NEG32   10
239 #define ARM_RVA32   11
240 #define ARM_THUMB9  12
241 #define ARM_THUMB12 13
242 #define ARM_THUMB23 14
243
244 #ifdef ARM_WINCE
245 #undef  ARM_32
246 #undef  ARM_RVA32
247 #undef  ARM_26
248 #undef  ARM_THUMB12
249 #undef  ARM_26D
250
251 #define ARM_32       1
252 #define ARM_RVA32    2
253 #define ARM_26       3
254 #define ARM_THUMB12  4
255 #define ARM_26D      5
256 #define ARM_SECTION  14
257 #define ARM_SECREL   15
258 #endif
259
260 static reloc_howto_type aoutarm_std_reloc_howto[] =
261   {
262 #ifdef ARM_WINCE
263     EMPTY_HOWTO (-1),
264     HOWTO (ARM_32,
265            0,
266            2,
267            32,
268            false,
269            0,
270            complain_overflow_bitfield,
271            coff_arm_reloc,
272            "ARM_32",
273            true,
274            0xffffffff,
275            0xffffffff,
276            PCRELOFFSET),
277     HOWTO (ARM_RVA32,
278            0,
279            2,
280            32,
281            false,
282            0,
283            complain_overflow_bitfield,
284            coff_arm_reloc,
285            "ARM_RVA32",
286            true,
287            0xffffffff,
288            0xffffffff,
289            PCRELOFFSET),
290     HOWTO (ARM_26,
291            2,
292            2,
293            24,
294            true,
295            0,
296            complain_overflow_signed,
297            aoutarm_fix_pcrel_26 ,
298            "ARM_26",
299            false,
300            0x00ffffff,
301            0x00ffffff,
302            PCRELOFFSET),
303     HOWTO (ARM_THUMB12,
304            1,
305            1,
306            11,
307            true,
308            0,
309            complain_overflow_signed,
310            coff_thumb_pcrel_12 ,
311            "ARM_THUMB12",
312            false,
313            0x000007ff,
314            0x000007ff,
315            PCRELOFFSET),
316     HOWTO (ARM_26D,
317            2,
318            2,
319            24,
320            false,
321            0,
322            complain_overflow_dont,
323            aoutarm_fix_pcrel_26_done,
324            "ARM_26D",
325            true,
326            0x00ffffff,
327            0x0,
328            false),
329     EMPTY_HOWTO (-1),
330     EMPTY_HOWTO (-1),
331     EMPTY_HOWTO (-1),
332     EMPTY_HOWTO (-1),
333     EMPTY_HOWTO (-1),
334     EMPTY_HOWTO (-1),
335     EMPTY_HOWTO (-1),
336     EMPTY_HOWTO (-1),
337     HOWTO (ARM_SECTION,
338            0,
339            1,
340            16,
341            false,
342            0,
343            complain_overflow_bitfield,
344            coff_arm_reloc,
345            "ARM_16",
346            true,
347            0x0000ffff,
348            0x0000ffff,
349            PCRELOFFSET),
350     HOWTO (ARM_SECREL,
351            0,
352            2,
353            32,
354            false,
355            0,
356            complain_overflow_bitfield,
357            coff_arm_reloc,
358            "ARM_32",
359            true,
360            0xffffffff,
361            0xffffffff,
362            PCRELOFFSET),
363 #else /* not ARM_WINCE */
364     HOWTO (ARM_8,                       /* type */
365            0,                   /* rightshift */
366            0,                   /* size */
367            8,                   /* bitsize */
368            false,                       /* pc_relative */
369            0,                   /* bitpos */
370            complain_overflow_bitfield, /* complain_on_overflow */
371            coff_arm_reloc,              /* special_function */
372            "ARM_8",             /* name */
373            true,                        /* partial_inplace */
374            0x000000ff,          /* src_mask */
375            0x000000ff,          /* dst_mask */
376            PCRELOFFSET          /* pcrel_offset */),
377     HOWTO (ARM_16,
378            0,
379            1,
380            16,
381            false,
382            0,
383            complain_overflow_bitfield,
384            coff_arm_reloc,
385            "ARM_16",
386            true,
387            0x0000ffff,
388            0x0000ffff,
389            PCRELOFFSET),
390     HOWTO (ARM_32,
391            0,
392            2,
393            32,
394            false,
395            0,
396            complain_overflow_bitfield,
397            coff_arm_reloc,
398            "ARM_32",
399            true,
400            0xffffffff,
401            0xffffffff,
402            PCRELOFFSET),
403     HOWTO (ARM_26,
404            2,
405            2,
406            24,
407            true,
408            0,
409            complain_overflow_signed,
410            aoutarm_fix_pcrel_26 ,
411            "ARM_26",
412            false,
413            0x00ffffff,
414            0x00ffffff,
415            PCRELOFFSET),
416     HOWTO (ARM_DISP8,
417            0,
418            0,
419            8,
420            true,
421            0,
422            complain_overflow_signed,
423            coff_arm_reloc,
424            "ARM_DISP8",
425            true,
426            0x000000ff,
427            0x000000ff,
428            true),
429     HOWTO (ARM_DISP16,
430            0,
431            1,
432            16,
433            true,
434            0,
435            complain_overflow_signed,
436            coff_arm_reloc,
437            "ARM_DISP16",
438            true,
439            0x0000ffff,
440            0x0000ffff,
441            true),
442     HOWTO (ARM_DISP32,
443            0,
444            2,
445            32,
446            true,
447            0,
448            complain_overflow_signed,
449            coff_arm_reloc,
450            "ARM_DISP32",
451            true,
452            0xffffffff,
453            0xffffffff,
454            true),
455     HOWTO (ARM_26D,
456            2,
457            2,
458            24,
459            false,
460            0,
461            complain_overflow_dont,
462            aoutarm_fix_pcrel_26_done,
463            "ARM_26D",
464            true,
465            0x00ffffff,
466            0x0,
467            false),
468     /* 8 is unused */
469     EMPTY_HOWTO (-1),
470     HOWTO (ARM_NEG16,
471            0,
472            -1,
473            16,
474            false,
475            0,
476            complain_overflow_bitfield,
477            coff_arm_reloc,
478            "ARM_NEG16",
479            true,
480            0x0000ffff,
481            0x0000ffff,
482            false),
483     HOWTO (ARM_NEG32,
484            0,
485            -2,
486            32,
487            false,
488            0,
489            complain_overflow_bitfield,
490            coff_arm_reloc,
491            "ARM_NEG32",
492            true,
493            0xffffffff,
494            0xffffffff,
495            false),
496     HOWTO (ARM_RVA32,
497            0,
498            2,
499            32,
500            false,
501            0,
502            complain_overflow_bitfield,
503            coff_arm_reloc,
504            "ARM_RVA32",
505            true,
506            0xffffffff,
507            0xffffffff,
508            PCRELOFFSET),
509     HOWTO (ARM_THUMB9,
510            1,
511            1,
512            8,
513            true,
514            0,
515            complain_overflow_signed,
516            coff_thumb_pcrel_9 ,
517            "ARM_THUMB9",
518            false,
519            0x000000ff,
520            0x000000ff,
521            PCRELOFFSET),
522     HOWTO (ARM_THUMB12,
523            1,
524            1,
525            11,
526            true,
527            0,
528            complain_overflow_signed,
529            coff_thumb_pcrel_12 ,
530            "ARM_THUMB12",
531            false,
532            0x000007ff,
533            0x000007ff,
534            PCRELOFFSET),
535     HOWTO (ARM_THUMB23,
536            1,
537            2,
538            22,
539            true,
540            0,
541            complain_overflow_signed,
542            coff_thumb_pcrel_23 ,
543            "ARM_THUMB23",
544            false,
545            0x07ff07ff,
546            0x07ff07ff,
547            PCRELOFFSET)
548 #endif /* not ARM_WINCE */
549   };
550
551 #define NUM_RELOCS NUM_ELEM (aoutarm_std_reloc_howto)
552
553 #ifdef COFF_WITH_PE
554 static boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
555 /* Return true if this relocation should
556    appear in the output .reloc section.  */
557
558 static boolean
559 in_reloc_p (abfd, howto)
560      bfd * abfd ATTRIBUTE_UNUSED;
561      reloc_howto_type * howto;
562 {
563   return !howto->pc_relative && howto->type != ARM_RVA32;
564 }
565 #endif
566
567 #define RTYPE2HOWTO(cache_ptr, dst)             \
568   (cache_ptr)->howto =                          \
569     (dst)->r_type < NUM_RELOCS                  \
570     ? aoutarm_std_reloc_howto + (dst)->r_type   \
571     : NULL
572
573 #define coff_rtype_to_howto coff_arm_rtype_to_howto
574
575 static reloc_howto_type *
576 coff_arm_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
577      bfd *abfd ATTRIBUTE_UNUSED;
578      asection *sec;
579      struct internal_reloc *rel;
580      struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
581      struct internal_syment *sym ATTRIBUTE_UNUSED;
582      bfd_vma *addendp;
583 {
584   reloc_howto_type * howto;
585
586   if (rel->r_type >= NUM_RELOCS)
587     return NULL;
588
589   howto = aoutarm_std_reloc_howto + rel->r_type;
590
591   if (rel->r_type == ARM_RVA32)
592     *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
593
594   return howto;
595 }
596
597 /* Used by the assembler.  */
598
599 static bfd_reloc_status_type
600 aoutarm_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
601                           output_bfd, error_message)
602      bfd *abfd ATTRIBUTE_UNUSED;
603      arelent *reloc_entry ATTRIBUTE_UNUSED;
604      asymbol *symbol ATTRIBUTE_UNUSED;
605      PTR data ATTRIBUTE_UNUSED;
606      asection *input_section ATTRIBUTE_UNUSED;
607      bfd *output_bfd ATTRIBUTE_UNUSED;
608      char **error_message ATTRIBUTE_UNUSED;
609 {
610   /* This is dead simple at present.  */
611   return bfd_reloc_ok;
612 }
613
614 /* Used by the assembler.  */
615
616 static bfd_reloc_status_type
617 aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section,
618                      output_bfd, error_message)
619      bfd *abfd;
620      arelent *reloc_entry;
621      asymbol *symbol;
622      PTR data;
623      asection *input_section;
624      bfd *output_bfd;
625      char **error_message ATTRIBUTE_UNUSED;
626 {
627   bfd_vma relocation;
628   bfd_size_type addr = reloc_entry->address;
629   long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
630   bfd_reloc_status_type flag = bfd_reloc_ok;
631
632   /* If this is an undefined symbol, return error.  */
633   if (symbol->section == &bfd_und_section
634       && (symbol->flags & BSF_WEAK) == 0)
635     return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
636
637   /* If the sections are different, and we are doing a partial relocation,
638      just ignore it for now.  */
639   if (symbol->section->name != input_section->name
640       && output_bfd != (bfd *)NULL)
641     return bfd_reloc_continue;
642
643   relocation = (target & 0x00ffffff) << 2;
644   relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend.  */
645   relocation += symbol->value;
646   relocation += symbol->section->output_section->vma;
647   relocation += symbol->section->output_offset;
648   relocation += reloc_entry->addend;
649   relocation -= input_section->output_section->vma;
650   relocation -= input_section->output_offset;
651   relocation -= addr;
652
653   if (relocation & 3)
654     return bfd_reloc_overflow;
655
656   /* Check for overflow.  */
657   if (relocation & 0x02000000)
658     {
659       if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
660         flag = bfd_reloc_overflow;
661     }
662   else if (relocation & ~(bfd_vma) 0x03ffffff)
663     flag = bfd_reloc_overflow;
664
665   target &= ~0x00ffffff;
666   target |= (relocation >> 2) & 0x00ffffff;
667   bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
668
669   /* Now the ARM magic... Change the reloc type so that it is marked as done.
670      Strictly this is only necessary if we are doing a partial relocation.  */
671   reloc_entry->howto = &aoutarm_std_reloc_howto[ARM_26D];
672
673   return flag;
674 }
675
676 static bfd_reloc_status_type
677 coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section,
678                      output_bfd, error_message, btype)
679      bfd *abfd;
680      arelent *reloc_entry;
681      asymbol *symbol;
682      PTR data;
683      asection *input_section;
684      bfd *output_bfd;
685      char **error_message ATTRIBUTE_UNUSED;
686      thumb_pcrel_branchtype btype;
687 {
688   bfd_vma relocation = 0;
689   bfd_size_type addr = reloc_entry->address;
690   long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
691   bfd_reloc_status_type flag = bfd_reloc_ok;
692   bfd_vma dstmsk;
693   bfd_vma offmsk;
694   bfd_vma signbit;
695
696   /* NOTE: This routine is currently used by GAS, but not by the link
697      phase.  */
698
699   switch (btype)
700     {
701     case b9:
702       dstmsk  = 0x000000ff;
703       offmsk  = 0x000001fe;
704       signbit = 0x00000100;
705       break;
706
707     case b12:
708       dstmsk  = 0x000007ff;
709       offmsk  = 0x00000ffe;
710       signbit = 0x00000800;
711       break;
712
713     case b23:
714       dstmsk  = 0x07ff07ff;
715       offmsk  = 0x007fffff;
716       signbit = 0x00400000;
717       break;
718
719     default:
720       abort ();
721     }
722
723   /* If this is an undefined symbol, return error.  */
724   if (symbol->section == &bfd_und_section
725       && (symbol->flags & BSF_WEAK) == 0)
726     return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
727
728   /* If the sections are different, and we are doing a partial relocation,
729      just ignore it for now.  */
730   if (symbol->section->name != input_section->name
731       && output_bfd != (bfd *)NULL)
732     return bfd_reloc_continue;
733
734   switch (btype)
735     {
736     case b9:
737     case b12:
738       relocation = ((target & dstmsk) << 1);
739       break;
740
741     case b23:
742       if (bfd_big_endian (abfd))
743         relocation = ((target & 0x7ff) << 1)  | ((target & 0x07ff0000) >> 4);
744       else
745         relocation = ((target & 0x7ff) << 12) | ((target & 0x07ff0000) >> 15);
746       break;
747
748     default:
749       abort ();
750     }
751
752   relocation = (relocation ^ signbit) - signbit; /* Sign extend.  */
753   relocation += symbol->value;
754   relocation += symbol->section->output_section->vma;
755   relocation += symbol->section->output_offset;
756   relocation += reloc_entry->addend;
757   relocation -= input_section->output_section->vma;
758   relocation -= input_section->output_offset;
759   relocation -= addr;
760
761   if (relocation & 1)
762     return bfd_reloc_overflow;
763
764   /* Check for overflow.  */
765   if (relocation & signbit)
766     {
767       if ((relocation & ~offmsk) != ~offmsk)
768         flag = bfd_reloc_overflow;
769     }
770   else if (relocation & ~offmsk)
771     flag = bfd_reloc_overflow;
772
773   target &= ~dstmsk;
774   switch (btype)
775    {
776    case b9:
777    case b12:
778      target |= (relocation >> 1);
779      break;
780
781    case b23:
782      if (bfd_big_endian (abfd))
783        target |= (((relocation & 0xfff) >> 1)
784                   | ((relocation << 4)  & 0x07ff0000));
785      else
786        target |= (((relocation & 0xffe) << 15)
787                   | ((relocation >> 12) & 0x7ff));
788      break;
789
790    default:
791      abort ();
792    }
793
794   bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
795
796   /* Now the ARM magic... Change the reloc type so that it is marked as done.
797      Strictly this is only necessary if we are doing a partial relocation.  */
798   reloc_entry->howto = & aoutarm_std_reloc_howto [ARM_26D];
799
800   /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations.  */
801   return flag;
802 }
803
804 static bfd_reloc_status_type
805 coff_thumb_pcrel_23 (abfd, reloc_entry, symbol, data, input_section,
806                      output_bfd, error_message)
807      bfd *abfd;
808      arelent *reloc_entry;
809      asymbol *symbol;
810      PTR data;
811      asection *input_section;
812      bfd *output_bfd;
813      char **error_message;
814 {
815   return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
816                                   input_section, output_bfd, error_message,
817                                   b23);
818 }
819
820 static bfd_reloc_status_type
821 coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section,
822                      output_bfd, error_message)
823      bfd *abfd;
824      arelent *reloc_entry;
825      asymbol *symbol;
826      PTR data;
827      asection *input_section;
828      bfd *output_bfd;
829      char **error_message;
830 {
831   return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
832                                   input_section, output_bfd, error_message,
833                                   b12);
834 }
835
836 static bfd_reloc_status_type
837 coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section,
838                      output_bfd, error_message)
839      bfd *abfd;
840      arelent *reloc_entry;
841      asymbol *symbol;
842      PTR data;
843      asection *input_section;
844      bfd *output_bfd;
845      char **error_message;
846 {
847   return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
848                                   input_section, output_bfd, error_message,
849                                   b9);
850 }
851
852 static const struct reloc_howto_struct *
853 coff_arm_reloc_type_lookup (abfd, code)
854       bfd * abfd;
855       bfd_reloc_code_real_type code;
856 {
857 #define ASTD(i,j)       case i: return aoutarm_std_reloc_howto + j
858
859   if (code == BFD_RELOC_CTOR)
860     switch (bfd_get_arch_info (abfd)->bits_per_address)
861       {
862       case 32:
863         code = BFD_RELOC_32;
864         break;
865       default:
866         return (const struct reloc_howto_struct *) 0;
867       }
868
869   switch (code)
870     {
871 #ifdef ARM_WINCE
872       ASTD (BFD_RELOC_32,                   ARM_32);
873       ASTD (BFD_RELOC_RVA,                  ARM_RVA32);
874       ASTD (BFD_RELOC_ARM_PCREL_BRANCH,     ARM_26);
875       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
876 #else
877       ASTD (BFD_RELOC_8,                    ARM_8);
878       ASTD (BFD_RELOC_16,                   ARM_16);
879       ASTD (BFD_RELOC_32,                   ARM_32);
880       ASTD (BFD_RELOC_ARM_PCREL_BRANCH,     ARM_26);
881       ASTD (BFD_RELOC_ARM_PCREL_BLX,        ARM_26);
882       ASTD (BFD_RELOC_8_PCREL,              ARM_DISP8);
883       ASTD (BFD_RELOC_16_PCREL,             ARM_DISP16);
884       ASTD (BFD_RELOC_32_PCREL,             ARM_DISP32);
885       ASTD (BFD_RELOC_RVA,                  ARM_RVA32);
886       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9,  ARM_THUMB9);
887       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
888       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23);
889       ASTD (BFD_RELOC_THUMB_PCREL_BLX,      ARM_THUMB23);
890 #endif
891     default: return (const struct reloc_howto_struct *) 0;
892     }
893 }
894
895 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
896 #define COFF_PAGE_SIZE 0x1000
897 /* Turn a howto into a reloc  nunmber */
898
899 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
900 #define BADMAG(x) ARMBADMAG(x)
901 #define ARM 1                   /* Customize coffcode.h */
902
903 /* Make sure that the 'r_offset' field is copied properly
904    so that identical binaries will compare the same.  */
905 #define SWAP_IN_RELOC_OFFSET    H_GET_32
906 #define SWAP_OUT_RELOC_OFFSET   H_PUT_32
907
908 /* Extend the coff_link_hash_table structure with a few ARM specific fields.
909    This allows us to store global data here without actually creating any
910    global variables, which is a no-no in the BFD world.  */
911 struct coff_arm_link_hash_table
912   {
913     /* The original coff_link_hash_table structure.  MUST be first field.  */
914     struct coff_link_hash_table root;
915
916     /* The size in bytes of the section containg the Thumb-to-ARM glue.  */
917     bfd_size_type               thumb_glue_size;
918
919     /* The size in bytes of the section containg the ARM-to-Thumb glue.  */
920     bfd_size_type               arm_glue_size;
921
922     /* An arbitary input BFD chosen to hold the glue sections.  */
923     bfd *                       bfd_of_glue_owner;
924
925     /* Support interworking with old, non-interworking aware ARM code.  */
926     int                         support_old_code;
927 };
928
929 /* Get the ARM coff linker hash table from a link_info structure.  */
930 #define coff_arm_hash_table(info) \
931   ((struct coff_arm_link_hash_table *) ((info)->hash))
932
933 /* Create an ARM coff linker hash table.  */
934
935 static struct bfd_link_hash_table *
936 coff_arm_link_hash_table_create (abfd)
937      bfd * abfd;
938 {
939   struct coff_arm_link_hash_table * ret;
940   bfd_size_type amt = sizeof (struct coff_arm_link_hash_table);
941
942   ret = (struct coff_arm_link_hash_table *) bfd_malloc (amt);
943   if (ret == (struct coff_arm_link_hash_table *) NULL)
944     return NULL;
945
946   if (! _bfd_coff_link_hash_table_init
947       (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
948     {
949       free (ret);
950       return (struct bfd_link_hash_table *) NULL;
951     }
952
953   ret->thumb_glue_size   = 0;
954   ret->arm_glue_size     = 0;
955   ret->bfd_of_glue_owner = NULL;
956
957   return & ret->root.root;
958 }
959
960 static void
961 arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
962       struct bfd_link_info *info;
963       bfd *output_bfd;
964       asection *input_section;
965       bfd_vma reloc_offset;
966 {
967   bfd_vma addr = reloc_offset
968                 - input_section->vma
969                 + input_section->output_offset
970                   + input_section->output_section->vma;
971
972   if (coff_data (output_bfd)->pe)
973      addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
974   fwrite (& addr, 1, sizeof (addr), (FILE *) info->base_file);
975
976 }
977 \f
978 /* The thumb form of a long branch is a bit finicky, because the offset
979    encoding is split over two fields, each in it's own instruction. They
980    can occur in any order. So given a thumb form of long branch, and an
981    offset, insert the offset into the thumb branch and return finished
982    instruction.
983
984    It takes two thumb instructions to encode the target address. Each has
985    11 bits to invest. The upper 11 bits are stored in one (identifed by
986    H-0.. see below), the lower 11 bits are stored in the other (identified
987    by H-1).
988
989    Combine together and shifted left by 1 (it's a half word address) and
990    there you have it.
991
992      Op: 1111 = F,
993      H-0, upper address-0 = 000
994      Op: 1111 = F,
995      H-1, lower address-0 = 800
996
997    They can be ordered either way, but the arm tools I've seen always put
998    the lower one first. It probably doesn't matter. krk@cygnus.com
999
1000    XXX:  Actually the order does matter.  The second instruction (H-1)
1001    moves the computed address into the PC, so it must be the second one
1002    in the sequence.  The problem, however is that whilst little endian code
1003    stores the instructions in HI then LOW order, big endian code does the
1004    reverse.  nickc@cygnus.com.  */
1005
1006 #define LOW_HI_ORDER 0xF800F000
1007 #define HI_LOW_ORDER 0xF000F800
1008
1009 static insn32
1010 insert_thumb_branch (br_insn, rel_off)
1011      insn32 br_insn;
1012      int rel_off;
1013 {
1014   unsigned int low_bits;
1015   unsigned int high_bits;
1016
1017   BFD_ASSERT((rel_off & 1) != 1);
1018
1019   rel_off >>= 1;                              /* half word aligned address */
1020   low_bits = rel_off & 0x000007FF;            /* the bottom 11 bits */
1021   high_bits = (rel_off >> 11) & 0x000007FF;   /* the top 11 bits */
1022
1023   if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1024     br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1025   else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1026     br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1027   else
1028     /* FIXME: the BFD library should never abort except for internal errors
1029        - it should return an error status.  */
1030     abort (); /* Error - not a valid branch instruction form.  */
1031
1032   return br_insn;
1033 }
1034 \f
1035 static struct coff_link_hash_entry *
1036 find_thumb_glue (info, name, input_bfd)
1037      struct bfd_link_info *info;
1038      const char *name;
1039      bfd *input_bfd;
1040 {
1041   char *tmp_name;
1042   struct coff_link_hash_entry *myh;
1043   bfd_size_type amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1044
1045   tmp_name = (char *) bfd_malloc (amt);
1046
1047   BFD_ASSERT (tmp_name);
1048
1049   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1050
1051   myh = coff_link_hash_lookup
1052     (coff_hash_table (info), tmp_name, false, false, true);
1053
1054   if (myh == NULL)
1055     /* xgettext:c-format */
1056     _bfd_error_handler (_("%s: unable to find THUMB glue '%s' for `%s'"),
1057                         bfd_archive_filename (input_bfd), tmp_name, name);
1058
1059   free (tmp_name);
1060
1061   return myh;
1062 }
1063
1064 static struct coff_link_hash_entry *
1065 find_arm_glue (info, name, input_bfd)
1066      struct bfd_link_info *info;
1067      const char *name;
1068      bfd *input_bfd;
1069 {
1070   char *tmp_name;
1071   struct coff_link_hash_entry * myh;
1072   bfd_size_type amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1073
1074   tmp_name = (char *) bfd_malloc (amt);
1075
1076   BFD_ASSERT (tmp_name);
1077
1078   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1079
1080   myh = coff_link_hash_lookup
1081     (coff_hash_table (info), tmp_name, false, false, true);
1082
1083   if (myh == NULL)
1084     /* xgettext:c-format */
1085     _bfd_error_handler (_("%s: unable to find ARM glue '%s' for `%s'"),
1086                         bfd_archive_filename (input_bfd), tmp_name, name);
1087
1088   free (tmp_name);
1089
1090   return myh;
1091 }
1092
1093 /*
1094   ARM->Thumb glue:
1095
1096        .arm
1097        __func_from_arm:
1098              ldr r12, __func_addr
1099              bx  r12
1100        __func_addr:
1101             .word func    @ behave as if you saw a ARM_32 reloc
1102 */
1103
1104 #define ARM2THUMB_GLUE_SIZE 12
1105 static const insn32 a2t1_ldr_insn       = 0xe59fc000;
1106 static const insn32 a2t2_bx_r12_insn    = 0xe12fff1c;
1107 static const insn32 a2t3_func_addr_insn = 0x00000001;
1108
1109 /*
1110    Thumb->ARM:                          Thumb->(non-interworking aware) ARM
1111
1112    .thumb                               .thumb
1113    .align 2                             .align 2
1114       __func_from_thumb:                   __func_from_thumb:
1115            bx pc                                push {r6, lr}
1116            nop                                  ldr  r6, __func_addr
1117    .arm                                         mov  lr, pc
1118       __func_change_to_arm:                     bx   r6
1119            b func                       .arm
1120                                            __func_back_to_thumb:
1121                                                 ldmia r13! {r6, lr}
1122                                                 bx    lr
1123                                            __func_addr:
1124                                                 .word   func
1125 */
1126
1127 #define THUMB2ARM_GLUE_SIZE (globals->support_old_code ? 20 : 8)
1128 static const insn16 t2a1_bx_pc_insn = 0x4778;
1129 static const insn16 t2a2_noop_insn  = 0x46c0;
1130 static const insn32 t2a3_b_insn     = 0xea000000;
1131
1132 static const insn16 t2a1_push_insn  = 0xb540;
1133 static const insn16 t2a2_ldr_insn   = 0x4e03;
1134 static const insn16 t2a3_mov_insn   = 0x46fe;
1135 static const insn16 t2a4_bx_insn    = 0x4730;
1136 static const insn32 t2a5_pop_insn   = 0xe8bd4040;
1137 static const insn32 t2a6_bx_insn    = 0xe12fff1e;
1138
1139 /* TODO:
1140      We should really create new local (static) symbols in destination
1141      object for each stub we create.  We should also create local
1142      (static) symbols within the stubs when switching between ARM and
1143      Thumb code.  This will ensure that the debugger and disassembler
1144      can present a better view of stubs.
1145
1146      We can treat stubs like literal sections, and for the THUMB9 ones
1147      (short addressing range) we should be able to insert the stubs
1148      between sections. i.e. the simplest approach (since relocations
1149      are done on a section basis) is to dump the stubs at the end of
1150      processing a section. That way we can always try and minimise the
1151      offset to and from a stub. However, this does not map well onto
1152      the way that the linker/BFD does its work: mapping all input
1153      sections to output sections via the linker script before doing
1154      all the processing.
1155
1156      Unfortunately it may be easier to just to disallow short range
1157      Thumb->ARM stubs (i.e. no conditional inter-working branches,
1158      only branch-and-link (BL) calls.  This will simplify the processing
1159      since we can then put all of the stubs into their own section.
1160
1161   TODO:
1162      On a different subject, rather than complaining when a
1163      branch cannot fit in the number of bits available for the
1164      instruction we should generate a trampoline stub (needed to
1165      address the complete 32bit address space).  */
1166
1167 /* The standard COFF backend linker does not cope with the special
1168    Thumb BRANCH23 relocation.  The alternative would be to split the
1169    BRANCH23 into seperate HI23 and LO23 relocations. However, it is a
1170    bit simpler simply providing our own relocation driver.  */
1171
1172 /* The reloc processing routine for the ARM/Thumb COFF linker.  NOTE:
1173    This code is a very slightly modified copy of
1174    _bfd_coff_generic_relocate_section.  It would be a much more
1175    maintainable solution to have a MACRO that could be expanded within
1176    _bfd_coff_generic_relocate_section that would only be provided for
1177    ARM/Thumb builds.  It is only the code marked THUMBEXTENSION that
1178    is different from the original.  */
1179
1180 static boolean
1181 coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1182                            contents, relocs, syms, sections)
1183      bfd *output_bfd;
1184      struct bfd_link_info *info;
1185      bfd *input_bfd;
1186      asection *input_section;
1187      bfd_byte *contents;
1188      struct internal_reloc *relocs;
1189      struct internal_syment *syms;
1190      asection **sections;
1191 {
1192   struct internal_reloc * rel;
1193   struct internal_reloc * relend;
1194
1195   rel = relocs;
1196   relend = rel + input_section->reloc_count;
1197
1198   for (; rel < relend; rel++)
1199     {
1200       int                            done = 0;
1201       long                           symndx;
1202       struct coff_link_hash_entry *  h;
1203       struct internal_syment *       sym;
1204       bfd_vma                        addend;
1205       bfd_vma                        val;
1206       reloc_howto_type *             howto;
1207       bfd_reloc_status_type          rstat;
1208       bfd_vma                        h_val;
1209
1210       symndx = rel->r_symndx;
1211
1212       if (symndx == -1)
1213         {
1214           h = NULL;
1215           sym = NULL;
1216         }
1217       else
1218         {
1219           h = obj_coff_sym_hashes (input_bfd)[symndx];
1220           sym = syms + symndx;
1221         }
1222
1223       /* COFF treats common symbols in one of two ways.  Either the
1224          size of the symbol is included in the section contents, or it
1225          is not.  We assume that the size is not included, and force
1226          the rtype_to_howto function to adjust the addend as needed.  */
1227
1228       if (sym != NULL && sym->n_scnum != 0)
1229         addend = - sym->n_value;
1230       else
1231         addend = 0;
1232
1233       howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
1234                                        sym, &addend);
1235       if (howto == NULL)
1236         return false;
1237
1238       /* The relocation_section function will skip pcrel_offset relocs
1239          when doing a relocateable link.  However, we want to convert
1240          ARM26 to ARM26D relocs if possible.  We return a fake howto in
1241          this case without pcrel_offset set, and adjust the addend to
1242          compensate.  */
1243       if (rel->r_type == ARM_26
1244           && h != NULL
1245           && info->relocateable
1246           && (h->root.type == bfd_link_hash_defined
1247               || h->root.type == bfd_link_hash_defweak)
1248           && (h->root.u.def.section->output_section
1249               == input_section->output_section))
1250         {
1251           static reloc_howto_type fake_arm26_reloc =
1252             HOWTO (ARM_26,
1253                2,
1254                2,
1255                24,
1256                true,
1257                0,
1258                complain_overflow_signed,
1259                aoutarm_fix_pcrel_26 ,
1260                "ARM_26",
1261                false,
1262                0x00ffffff,
1263                0x00ffffff,
1264                false);
1265
1266           addend -= rel->r_vaddr - input_section->vma;
1267           howto = &fake_arm26_reloc;
1268         }
1269
1270 #ifdef ARM_WINCE
1271       /* MS ARM-CE makes the reloc relative to the opcode's pc, not
1272          the next opcode's pc, so is off by one.  */
1273       if (howto->pc_relative && !info->relocateable)
1274         addend -= 8;
1275 #endif
1276
1277       /* If we are doing a relocateable link, then we can just ignore
1278          a PC relative reloc that is pcrel_offset.  It will already
1279          have the correct value.  If this is not a relocateable link,
1280          then we should ignore the symbol value.  */
1281       if (howto->pc_relative && howto->pcrel_offset)
1282         {
1283           if (info->relocateable)
1284             continue;
1285           /* FIXME - it is not clear which targets need this next test
1286              and which do not.  It is known that it is needed for the
1287              VxWorks and EPOC-PE targets, but it is also known that it
1288              was supressed for other ARM targets.  This ought to be
1289              sorted out one day.  */
1290 #ifdef ARM_COFF_BUGFIX
1291           /* We must not ignore the symbol value.  If the symbol is
1292              within the same section, the relocation should have already
1293              been fixed, but if it is not, we'll be handed a reloc into
1294              the beginning of the symbol's section, so we must not cancel
1295              out the symbol's value, otherwise we'll be adding it in
1296              twice.  */
1297           if (sym != NULL && sym->n_scnum != 0)
1298             addend += sym->n_value;
1299 #endif
1300         }
1301
1302       val = 0;
1303
1304       if (h == NULL)
1305         {
1306           asection *sec;
1307
1308           if (symndx == -1)
1309             {
1310               sec = bfd_abs_section_ptr;
1311               val = 0;
1312             }
1313           else
1314             {
1315               sec = sections[symndx];
1316               val = (sec->output_section->vma
1317                      + sec->output_offset
1318                      + sym->n_value
1319                      - sec->vma);
1320             }
1321         }
1322       else
1323         {
1324 #if 1 /* THUMBEXTENSION */
1325           /* We don't output the stubs if we are generating a
1326              relocatable output file, since we may as well leave the
1327              stub generation to the final linker pass. If we fail to
1328              verify that the name is defined, we'll try to build stubs
1329              for an undefined name...  */
1330           if (! info->relocateable
1331               && (   h->root.type == bfd_link_hash_defined
1332                   || h->root.type == bfd_link_hash_defweak))
1333             {
1334               asection *   h_sec = h->root.u.def.section;
1335               const char * name  = h->root.root.string;
1336
1337               /* h locates the symbol referenced in the reloc.  */
1338               h_val = (h->root.u.def.value
1339                        + h_sec->output_section->vma
1340                        + h_sec->output_offset);
1341
1342               if (howto->type == ARM_26)
1343                 {
1344                   if (   h->class == C_THUMBSTATFUNC
1345                       || h->class == C_THUMBEXTFUNC)
1346                     {
1347                       /* Arm code calling a Thumb function.  */
1348                       unsigned long int                 tmp;
1349                       bfd_vma                           my_offset;
1350                       asection *                        s;
1351                       long int                          ret_offset;
1352                       struct coff_link_hash_entry *     myh;
1353                       struct coff_arm_link_hash_table * globals;
1354
1355                       myh = find_arm_glue (info, name, input_bfd);
1356                       if (myh == NULL)
1357                         return false;
1358
1359                       globals = coff_arm_hash_table (info);
1360
1361                       BFD_ASSERT (globals != NULL);
1362                       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1363
1364                       my_offset = myh->root.u.def.value;
1365
1366                       s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1367                                                   ARM2THUMB_GLUE_SECTION_NAME);
1368                       BFD_ASSERT (s != NULL);
1369                       BFD_ASSERT (s->contents != NULL);
1370                       BFD_ASSERT (s->output_section != NULL);
1371
1372                       if ((my_offset & 0x01) == 0x01)
1373                         {
1374                           if (h_sec->owner != NULL
1375                               && INTERWORK_SET (h_sec->owner)
1376                               && ! INTERWORK_FLAG (h_sec->owner))
1377                             {
1378                               _bfd_error_handler
1379                                 /* xgettext:c-format */
1380                                 (_("%s(%s): warning: interworking not enabled."),
1381                                  bfd_archive_filename (h_sec->owner), name);
1382                               _bfd_error_handler
1383                                 /* xgettext:c-format */
1384                                 (_("  first occurrence: %s: arm call to thumb"),
1385                                  bfd_archive_filename (input_bfd));
1386                             }
1387
1388                           --my_offset;
1389                           myh->root.u.def.value = my_offset;
1390
1391                           bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn,
1392                                       s->contents + my_offset);
1393
1394                           bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn,
1395                                       s->contents + my_offset + 4);
1396
1397                           /* It's a thumb address.  Add the low order bit.  */
1398                           bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
1399                                       s->contents + my_offset + 8);
1400
1401                           if (info->base_file)
1402                             arm_emit_base_file_entry (info, output_bfd, s,
1403                                                       my_offset + 8);
1404
1405                         }
1406
1407                       BFD_ASSERT (my_offset <= globals->arm_glue_size);
1408
1409                       tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1410                                         - input_section->vma);
1411
1412                       tmp = tmp & 0xFF000000;
1413
1414                       /* Somehow these are both 4 too far, so subtract 8.  */
1415                       ret_offset =
1416                         s->output_offset
1417                         + my_offset
1418                         + s->output_section->vma
1419                         - (input_section->output_offset
1420                            + input_section->output_section->vma
1421                            + rel->r_vaddr)
1422                         - 8;
1423
1424                       tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1425
1426                       bfd_put_32 (output_bfd, (bfd_vma) tmp,
1427                                   contents + rel->r_vaddr - input_section->vma);
1428                       done = 1;
1429                     }
1430                 }
1431
1432 #ifndef ARM_WINCE
1433               /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12.  */
1434               else if (howto->type == ARM_THUMB23)
1435                 {
1436                   if (   h->class == C_EXT
1437                       || h->class == C_STAT
1438                       || h->class == C_LABEL)
1439                     {
1440                       /* Thumb code calling an ARM function */
1441                       asection *                         s = 0;
1442                       bfd_vma                            my_offset;
1443                       unsigned long int                  tmp;
1444                       long int                           ret_offset;
1445                       struct coff_link_hash_entry *      myh;
1446                       struct coff_arm_link_hash_table *  globals;
1447
1448                       myh = find_thumb_glue (info, name, input_bfd);
1449                       if (myh == NULL)
1450                         return false;
1451
1452                       globals = coff_arm_hash_table (info);
1453
1454                       BFD_ASSERT (globals != NULL);
1455                       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1456
1457                       my_offset = myh->root.u.def.value;
1458
1459                       s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1460                                                    THUMB2ARM_GLUE_SECTION_NAME);
1461
1462                       BFD_ASSERT (s != NULL);
1463                       BFD_ASSERT (s->contents != NULL);
1464                       BFD_ASSERT (s->output_section != NULL);
1465
1466                       if ((my_offset & 0x01) == 0x01)
1467                         {
1468                           if (h_sec->owner != NULL
1469                               && INTERWORK_SET (h_sec->owner)
1470                               && ! INTERWORK_FLAG (h_sec->owner)
1471                               && ! globals->support_old_code)
1472                             {
1473                               _bfd_error_handler
1474                                 /* xgettext:c-format */
1475                                 (_("%s(%s): warning: interworking not enabled."),
1476                                  bfd_archive_filename (h_sec->owner), name);
1477                               _bfd_error_handler
1478                                 /* xgettext:c-format */
1479                                 (_("  first occurrence: %s: thumb call to arm"),
1480                                  bfd_archive_filename (input_bfd));
1481                               _bfd_error_handler
1482                                 (_("  consider relinking with --support-old-code enabled"));
1483                             }
1484
1485                           -- my_offset;
1486                           myh->root.u.def.value = my_offset;
1487
1488                           if (globals->support_old_code)
1489                             {
1490                               bfd_put_16 (output_bfd, (bfd_vma) t2a1_push_insn,
1491                                           s->contents + my_offset);
1492
1493                               bfd_put_16 (output_bfd, (bfd_vma) t2a2_ldr_insn,
1494                                           s->contents + my_offset + 2);
1495
1496                               bfd_put_16 (output_bfd, (bfd_vma) t2a3_mov_insn,
1497                                           s->contents + my_offset + 4);
1498
1499                               bfd_put_16 (output_bfd, (bfd_vma) t2a4_bx_insn,
1500                                           s->contents + my_offset + 6);
1501
1502                               bfd_put_32 (output_bfd, (bfd_vma) t2a5_pop_insn,
1503                                           s->contents + my_offset + 8);
1504
1505                               bfd_put_32 (output_bfd, (bfd_vma) t2a6_bx_insn,
1506                                           s->contents + my_offset + 12);
1507
1508                               /* Store the address of the function in the last word of the stub.  */
1509                               bfd_put_32 (output_bfd, h_val,
1510                                           s->contents + my_offset + 16);
1511
1512                               if (info->base_file)
1513                                 arm_emit_base_file_entry (info, output_bfd, s,
1514                                                           my_offset + 16);
1515                             }
1516                           else
1517                             {
1518                               bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn,
1519                                           s->contents + my_offset);
1520
1521                               bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn,
1522                                           s->contents + my_offset + 2);
1523
1524                               ret_offset =
1525                                 ((bfd_signed_vma) h_val)        /* Address of destination of the stub.  */
1526                                 - ((bfd_signed_vma)
1527                                    (s->output_offset            /* Offset from the start of the current section to the start of the stubs.  */
1528                                     + my_offset                 /* Offset of the start of this stub from the start of the stubs.  */
1529                                     + s->output_section->vma)   /* Address of the start of the current section.  */
1530                                    + 4                          /* The branch instruction is 4 bytes into the stub.  */
1531                                    + 8);                        /* ARM branches work from the pc of the instruction + 8.  */
1532
1533                               bfd_put_32 (output_bfd,
1534                                           (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1535                                           s->contents + my_offset + 4);
1536
1537                             }
1538                         }
1539
1540                       BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1541
1542                       /* Now go back and fix up the original BL insn to point
1543                          to here.  */
1544                       ret_offset =
1545                         s->output_offset
1546                         + my_offset
1547                         - (input_section->output_offset
1548                            + rel->r_vaddr)
1549                         -4;
1550
1551                       tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1552                                         - input_section->vma);
1553
1554                       bfd_put_32 (output_bfd,
1555                                   (bfd_vma) insert_thumb_branch (tmp,
1556                                                                  ret_offset),
1557                                   contents + rel->r_vaddr - input_section->vma);
1558
1559                       done = 1;
1560                     }
1561                 }
1562 #endif
1563             }
1564
1565           /* If the relocation type and destination symbol does not
1566              fall into one of the above categories, then we can just
1567              perform a direct link.  */
1568
1569           if (done)
1570             rstat = bfd_reloc_ok;
1571           else
1572 #endif /* THUMBEXTENSION */
1573             if (   h->root.type == bfd_link_hash_defined
1574                 || h->root.type == bfd_link_hash_defweak)
1575             {
1576               asection *sec;
1577
1578               sec = h->root.u.def.section;
1579               val = (h->root.u.def.value
1580                      + sec->output_section->vma
1581                      + sec->output_offset);
1582               }
1583
1584           else if (! info->relocateable)
1585             {
1586               if (! ((*info->callbacks->undefined_symbol)
1587                      (info, h->root.root.string, input_bfd, input_section,
1588                       rel->r_vaddr - input_section->vma, true)))
1589                 return false;
1590             }
1591         }
1592
1593       if (info->base_file)
1594         {
1595           /* Emit a reloc if the backend thinks it needs it.  */
1596           if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
1597             arm_emit_base_file_entry (info, output_bfd, input_section,
1598                                       rel->r_vaddr);
1599         }
1600
1601 #if 1 /* THUMBEXTENSION */
1602       if (done)
1603         rstat = bfd_reloc_ok;
1604 #ifndef ARM_WINCE
1605       /* Only perform this fix during the final link, not a relocatable link.  nickc@cygnus.com  */
1606       else if (! info->relocateable
1607                && howto->type == ARM_THUMB23)
1608         {
1609           /* This is pretty much a copy of what the default
1610              _bfd_final_link_relocate and _bfd_relocate_contents
1611              routines do to perform a relocation, with special
1612              processing for the split addressing of the Thumb BL
1613              instruction.  Again, it would probably be simpler adding a
1614              ThumbBRANCH23 specific macro expansion into the default
1615              code.  */
1616
1617           bfd_vma address = rel->r_vaddr - input_section->vma;
1618
1619           if (address > input_section->_raw_size)
1620             rstat = bfd_reloc_outofrange;
1621           else
1622             {
1623               bfd_vma         relocation       = val + addend;
1624               int             size             = bfd_get_reloc_size (howto);
1625               boolean         overflow         = false;
1626               bfd_byte *      location         = contents + address;
1627               bfd_vma         x                = bfd_get_32 (input_bfd, location);
1628               bfd_vma         src_mask         = 0x007FFFFE;
1629               bfd_signed_vma  reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1630               bfd_signed_vma  reloc_signed_min = ~reloc_signed_max;
1631               bfd_vma         check;
1632               bfd_signed_vma  signed_check;
1633               bfd_vma         add;
1634               bfd_signed_vma  signed_add;
1635
1636               BFD_ASSERT (size == 4);
1637
1638               /* howto->pc_relative should be TRUE for type 14 BRANCH23.  */
1639               relocation -= (input_section->output_section->vma
1640                              + input_section->output_offset);
1641
1642               /* howto->pcrel_offset should be TRUE for type 14 BRANCH23.  */
1643               relocation -= address;
1644
1645               /* No need to negate the relocation with BRANCH23.  */
1646               /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23.  */
1647               /* howto->rightshift == 1 */
1648
1649               /* Drop unwanted bits from the value we are relocating to.  */
1650               check = relocation >> howto->rightshift;
1651
1652               /* If this is a signed value, the rightshift just dropped
1653                  leading 1 bits (assuming twos complement).  */
1654               if ((bfd_signed_vma) relocation >= 0)
1655                 signed_check = check;
1656               else
1657                 signed_check = (check
1658                                 | ((bfd_vma) - 1
1659                                    & ~((bfd_vma) - 1 >> howto->rightshift)));
1660
1661               /* Get the value from the object file.  */
1662               if (bfd_big_endian (input_bfd))
1663                 add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
1664               else
1665                 add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
1666
1667               /* Get the value from the object file with an appropriate sign.
1668                  The expression involving howto->src_mask isolates the upper
1669                  bit of src_mask.  If that bit is set in the value we are
1670                  adding, it is negative, and we subtract out that number times
1671                  two.  If src_mask includes the highest possible bit, then we
1672                  can not get the upper bit, but that does not matter since
1673                  signed_add needs no adjustment to become negative in that
1674                  case.  */
1675               signed_add = add;
1676
1677               if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
1678                 signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
1679
1680               /* howto->bitpos == 0 */
1681               /* Add the value from the object file, shifted so that it is a
1682                  straight number.  */
1683               signed_check += signed_add;
1684               relocation   += signed_add;
1685
1686               BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
1687
1688               /* Assumes two's complement.  */
1689               if (   signed_check > reloc_signed_max
1690                   || signed_check < reloc_signed_min)
1691                 overflow = true;
1692
1693               /* For the BLX(1) instruction remove bit 0 of the adjusted offset.
1694                  Bit 0 can only be set if the upper insn is at a half-word boundary,
1695                  since the destination address, an ARM instruction, must always be
1696                  on a word boundary.  The semantics of the BLX (1) instruction,
1697                  however, are that bit 0 in the offset must always be 0, and the
1698                  corresponding bit 1 in the target address will be set from bit
1699                  1 of the source address.  */
1700               if ((x & 0x18000000) == 0x08000000)
1701                 relocation &= ~0x2;
1702
1703               /* Put the relocation into the correct bits.  */
1704               if (bfd_big_endian (input_bfd))
1705                 relocation = (((relocation & 0xffe) >> 1)  | ((relocation << 4) & 0x07ff0000));
1706               else
1707                 relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1708
1709               /* Add the relocation to the correct bits of X.  */
1710               x = ((x & ~howto->dst_mask) | relocation);
1711
1712               /* Put the relocated value back in the object file.  */
1713               bfd_put_32 (input_bfd, x, location);
1714
1715               rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
1716             }
1717         }
1718 #endif
1719       else
1720 #endif /* THUMBEXTENSION */
1721         rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
1722                                           contents,
1723                                           rel->r_vaddr - input_section->vma,
1724                                           val, addend);
1725 #if 1 /* THUMBEXTENSION */
1726       /* FIXME:
1727          Is this the best way to fix up thumb addresses? krk@cygnus.com
1728          Probably not, but it works, and if it works it don't need fixing!  nickc@cygnus.com */
1729       /* Only perform this fix during the final link, not a relocatable link.  nickc@cygnus.com  */
1730       if (! info->relocateable
1731           && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
1732         {
1733           /* Determine if we need to set the bottom bit of a relocated address
1734              because the address is the address of a Thumb code symbol.  */
1735
1736           int patchit = false;
1737
1738           if (h != NULL
1739               && (   h->class == C_THUMBSTATFUNC
1740                   || h->class == C_THUMBEXTFUNC))
1741             {
1742               patchit = true;
1743             }
1744           else if (sym != NULL
1745                    && sym->n_scnum > N_UNDEF)
1746             {
1747               /* No hash entry - use the symbol instead.  */
1748
1749               if (   sym->n_sclass == C_THUMBSTATFUNC
1750                   || sym->n_sclass == C_THUMBEXTFUNC)
1751                 patchit = true;
1752             }
1753
1754           if (patchit)
1755             {
1756               bfd_byte * location = contents + rel->r_vaddr - input_section->vma;
1757               bfd_vma    x        = bfd_get_32 (input_bfd, location);
1758
1759               bfd_put_32 (input_bfd, x | 1, location);
1760             }
1761         }
1762 #endif /* THUMBEXTENSION */
1763
1764       switch (rstat)
1765         {
1766         default:
1767           abort ();
1768         case bfd_reloc_ok:
1769           break;
1770         case bfd_reloc_outofrange:
1771           (*_bfd_error_handler)
1772             (_("%s: bad reloc address 0x%lx in section `%s'"),
1773              bfd_archive_filename (input_bfd),
1774              (unsigned long) rel->r_vaddr,
1775              bfd_get_section_name (input_bfd, input_section));
1776           return false;
1777         case bfd_reloc_overflow:
1778           {
1779             const char *name;
1780             char buf[SYMNMLEN + 1];
1781
1782             if (symndx == -1)
1783               name = "*ABS*";
1784             else if (h != NULL)
1785               name = h->root.root.string;
1786             else
1787               {
1788                 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1789                 if (name == NULL)
1790                   return false;
1791               }
1792
1793             if (! ((*info->callbacks->reloc_overflow)
1794                    (info, name, howto->name, (bfd_vma) 0, input_bfd,
1795                     input_section, rel->r_vaddr - input_section->vma)))
1796               return false;
1797           }
1798         }
1799     }
1800
1801   return true;
1802 }
1803
1804 #ifndef COFF_IMAGE_WITH_PE
1805
1806 boolean
1807 bfd_arm_allocate_interworking_sections (info)
1808      struct bfd_link_info * info;
1809 {
1810   asection *                        s;
1811   bfd_byte *                        foo;
1812   struct coff_arm_link_hash_table * globals;
1813 #if 0
1814   static char                       test_char = '1';
1815 #endif
1816
1817   globals = coff_arm_hash_table (info);
1818
1819   BFD_ASSERT (globals != NULL);
1820
1821   if (globals->arm_glue_size != 0)
1822     {
1823       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1824
1825       s = bfd_get_section_by_name
1826         (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1827
1828       BFD_ASSERT (s != NULL);
1829
1830       foo = (bfd_byte *) bfd_alloc (globals->bfd_of_glue_owner,
1831                                     globals->arm_glue_size);
1832 #if 0
1833       memset (foo, test_char, (size_t) globals->arm_glue_size);
1834 #endif
1835
1836       s->_raw_size = s->_cooked_size = globals->arm_glue_size;
1837       s->contents = foo;
1838     }
1839
1840   if (globals->thumb_glue_size != 0)
1841     {
1842       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1843
1844       s = bfd_get_section_by_name
1845         (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1846
1847       BFD_ASSERT (s != NULL);
1848
1849       foo = (bfd_byte *) bfd_alloc (globals->bfd_of_glue_owner,
1850                                     globals->thumb_glue_size);
1851 #if 0
1852       memset (foo, test_char, (size_t) globals->thumb_glue_size);
1853 #endif
1854
1855       s->_raw_size = s->_cooked_size = globals->thumb_glue_size;
1856       s->contents = foo;
1857     }
1858
1859   return true;
1860 }
1861
1862 static void
1863 record_arm_to_thumb_glue (info, h)
1864      struct bfd_link_info *        info;
1865      struct coff_link_hash_entry * h;
1866 {
1867   const char *                      name = h->root.root.string;
1868   register asection *               s;
1869   char *                            tmp_name;
1870   struct coff_link_hash_entry *     myh;
1871   struct coff_arm_link_hash_table * globals;
1872   bfd_vma val;
1873   bfd_size_type amt;
1874
1875   globals = coff_arm_hash_table (info);
1876
1877   BFD_ASSERT (globals != NULL);
1878   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1879
1880   s = bfd_get_section_by_name
1881     (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1882
1883   BFD_ASSERT (s != NULL);
1884
1885   amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1886   tmp_name = (char *) bfd_malloc (amt);
1887
1888   BFD_ASSERT (tmp_name);
1889
1890   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1891
1892   myh = coff_link_hash_lookup
1893     (coff_hash_table (info), tmp_name, false, false, true);
1894
1895   if (myh != NULL)
1896     {
1897       free (tmp_name);
1898       return; /* we've already seen this guy */
1899     }
1900
1901   /* The only trick here is using globals->arm_glue_size as the value. Even
1902      though the section isn't allocated yet, this is where we will be putting
1903      it.  */
1904
1905   val = globals->arm_glue_size + 1;
1906   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1907                                 BSF_GLOBAL, s, val, NULL, true, false,
1908                                 (struct bfd_link_hash_entry **) & myh);
1909
1910   free (tmp_name);
1911
1912   globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
1913
1914   return;
1915 }
1916
1917 static void
1918 record_thumb_to_arm_glue (info, h)
1919      struct bfd_link_info *        info;
1920      struct coff_link_hash_entry * h;
1921 {
1922   const char *                       name = h->root.root.string;
1923   register asection *                s;
1924   char *                             tmp_name;
1925   struct coff_link_hash_entry *      myh;
1926   struct coff_arm_link_hash_table *  globals;
1927   bfd_vma val;
1928   bfd_size_type amt;
1929
1930   globals = coff_arm_hash_table (info);
1931
1932   BFD_ASSERT (globals != NULL);
1933   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1934
1935   s = bfd_get_section_by_name
1936     (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1937
1938   BFD_ASSERT (s != NULL);
1939
1940   amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1941   tmp_name = (char *) bfd_malloc (amt);
1942
1943   BFD_ASSERT (tmp_name);
1944
1945   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1946
1947   myh = coff_link_hash_lookup
1948     (coff_hash_table (info), tmp_name, false, false, true);
1949
1950   if (myh != NULL)
1951     {
1952       free (tmp_name);
1953       return; /* we've already seen this guy */
1954     }
1955
1956   val = globals->thumb_glue_size + 1;
1957   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1958                                 BSF_GLOBAL, s, val, NULL, true, false,
1959                                 (struct bfd_link_hash_entry **) &myh);
1960
1961   /* If we mark it 'thumb', the disassembler will do a better job.  */
1962   myh->class = C_THUMBEXTFUNC;
1963
1964   free (tmp_name);
1965
1966   /* Allocate another symbol to mark where we switch to arm mode.  */
1967
1968 #define CHANGE_TO_ARM "__%s_change_to_arm"
1969 #define BACK_FROM_ARM "__%s_back_from_arm"
1970
1971   amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1;
1972   tmp_name = (char *) bfd_malloc (amt);
1973
1974   BFD_ASSERT (tmp_name);
1975
1976   sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
1977
1978   myh = NULL;
1979   val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
1980   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1981                                 BSF_LOCAL, s, val, NULL, true, false,
1982                                 (struct bfd_link_hash_entry **) & myh);
1983
1984   free (tmp_name);
1985
1986   globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
1987
1988   return;
1989 }
1990
1991 /* Select a BFD to be used to hold the sections used by the glue code.
1992    This function is called from the linker scripts in ld/emultempl/
1993    {armcoff/pe}.em  */
1994
1995 boolean
1996 bfd_arm_get_bfd_for_interworking (abfd, info)
1997      bfd *                  abfd;
1998      struct bfd_link_info * info;
1999 {
2000   struct coff_arm_link_hash_table * globals;
2001   flagword                          flags;
2002   asection *                        sec;
2003
2004   /* If we are only performing a partial link do not bother
2005      getting a bfd to hold the glue.  */
2006   if (info->relocateable)
2007     return true;
2008
2009   globals = coff_arm_hash_table (info);
2010
2011   BFD_ASSERT (globals != NULL);
2012
2013   if (globals->bfd_of_glue_owner != NULL)
2014     return true;
2015
2016   sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
2017
2018   if (sec == NULL)
2019     {
2020       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
2021
2022       sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
2023
2024       if (sec == NULL
2025           || ! bfd_set_section_flags (abfd, sec, flags)
2026           || ! bfd_set_section_alignment (abfd, sec, 2))
2027         return false;
2028     }
2029
2030   sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
2031
2032   if (sec == NULL)
2033     {
2034       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
2035
2036       sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
2037
2038       if (sec == NULL
2039           || ! bfd_set_section_flags (abfd, sec, flags)
2040           || ! bfd_set_section_alignment (abfd, sec, 2))
2041         return false;
2042     }
2043
2044   /* Save the bfd for later use.  */
2045   globals->bfd_of_glue_owner = abfd;
2046
2047   return true;
2048 }
2049
2050 boolean
2051 bfd_arm_process_before_allocation (abfd, info, support_old_code)
2052      bfd *                   abfd;
2053      struct bfd_link_info *  info;
2054      int                     support_old_code;
2055 {
2056   asection * sec;
2057   struct coff_arm_link_hash_table * globals;
2058
2059   /* If we are only performing a partial link do not bother
2060      to construct any glue.  */
2061   if (info->relocateable)
2062     return true;
2063
2064   /* Here we have a bfd that is to be included on the link.  We have a hook
2065      to do reloc rummaging, before section sizes are nailed down.  */
2066
2067   _bfd_coff_get_external_symbols (abfd);
2068
2069   globals = coff_arm_hash_table (info);
2070
2071   BFD_ASSERT (globals != NULL);
2072   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
2073
2074   globals->support_old_code = support_old_code;
2075
2076   /* Rummage around all the relocs and map the glue vectors.  */
2077   sec = abfd->sections;
2078
2079   if (sec == NULL)
2080     return true;
2081
2082   for (; sec != NULL; sec = sec->next)
2083     {
2084       struct internal_reloc * i;
2085       struct internal_reloc * rel;
2086
2087       if (sec->reloc_count == 0)
2088         continue;
2089
2090       /* Load the relocs.  */
2091       /* FIXME: there may be a storage leak here.  */
2092
2093       i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0);
2094
2095       BFD_ASSERT (i != 0);
2096
2097       for (rel = i; rel < i + sec->reloc_count; ++rel)
2098         {
2099           unsigned short                 r_type  = rel->r_type;
2100           long                           symndx;
2101           struct coff_link_hash_entry *  h;
2102
2103           symndx = rel->r_symndx;
2104
2105           /* If the relocation is not against a symbol it cannot concern us.  */
2106           if (symndx == -1)
2107             continue;
2108
2109           /* If the index is outside of the range of our table, something has gone wrong.  */
2110           if (symndx >= obj_conv_table_size (abfd))
2111             {
2112               _bfd_error_handler (_("%s: illegal symbol index in reloc: %d"),
2113                                   bfd_archive_filename (abfd), symndx);
2114               continue;
2115             }
2116
2117           h = obj_coff_sym_hashes (abfd)[symndx];
2118
2119           /* If the relocation is against a static symbol it must be within
2120              the current section and so cannot be a cross ARM/Thumb relocation.  */
2121           if (h == NULL)
2122             continue;
2123
2124           switch (r_type)
2125             {
2126             case ARM_26:
2127               /* This one is a call from arm code.  We need to look up
2128                  the target of the call. If it is a thumb target, we
2129                  insert glue.  */
2130
2131               if (h->class == C_THUMBEXTFUNC)
2132                 record_arm_to_thumb_glue (info, h);
2133               break;
2134
2135 #ifndef ARM_WINCE
2136             case ARM_THUMB23:
2137               /* This one is a call from thumb code.  We used to look
2138                  for ARM_THUMB9 and ARM_THUMB12 as well.  We need to look
2139                  up the target of the call. If it is an arm target, we
2140                  insert glue.  If the symbol does not exist it will be
2141                  given a class of C_EXT and so we will generate a stub
2142                  for it.  This is not really a problem, since the link
2143                  is doomed anyway.  */
2144
2145               switch (h->class)
2146                 {
2147                 case C_EXT:
2148                 case C_STAT:
2149                 case C_LABEL:
2150                   record_thumb_to_arm_glue (info, h);
2151                   break;
2152                 default:
2153                   ;
2154                 }
2155               break;
2156 #endif
2157
2158             default:
2159               break;
2160             }
2161         }
2162     }
2163
2164   return true;
2165 }
2166
2167 #endif /* ! defined (COFF_IMAGE_WITH_PE) */
2168
2169 #define coff_bfd_reloc_type_lookup              coff_arm_reloc_type_lookup
2170 #define coff_relocate_section                   coff_arm_relocate_section
2171 #define coff_bfd_is_local_label_name            coff_arm_is_local_label_name
2172 #define coff_adjust_symndx                      coff_arm_adjust_symndx
2173 #define coff_link_output_has_begun              coff_arm_link_output_has_begun
2174 #define coff_final_link_postscript              coff_arm_final_link_postscript
2175 #define coff_bfd_merge_private_bfd_data         coff_arm_merge_private_bfd_data
2176 #define coff_bfd_print_private_bfd_data         coff_arm_print_private_bfd_data
2177 #define coff_bfd_set_private_flags              _bfd_coff_arm_set_private_flags
2178 #define coff_bfd_copy_private_bfd_data          coff_arm_copy_private_bfd_data
2179 #define coff_bfd_link_hash_table_create         coff_arm_link_hash_table_create
2180
2181 /* When doing a relocateable link, we want to convert ARM26 relocs
2182    into ARM26D relocs.  */
2183
2184 static boolean
2185 coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp)
2186      bfd *obfd ATTRIBUTE_UNUSED;
2187      struct bfd_link_info *info ATTRIBUTE_UNUSED;
2188      bfd *ibfd;
2189      asection *sec;
2190      struct internal_reloc *irel;
2191      boolean *adjustedp;
2192 {
2193   if (irel->r_type == 3)
2194     {
2195       struct coff_link_hash_entry *h;
2196
2197       h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
2198       if (h != NULL
2199           && (h->root.type == bfd_link_hash_defined
2200               || h->root.type == bfd_link_hash_defweak)
2201           && h->root.u.def.section->output_section == sec->output_section)
2202         irel->r_type = 7;
2203     }
2204   *adjustedp = false;
2205   return true;
2206 }
2207
2208 /* Called when merging the private data areas of two BFDs.
2209    This is important as it allows us to detect if we are
2210    attempting to merge binaries compiled for different ARM
2211    targets, eg different CPUs or differents APCS's.     */
2212
2213 static boolean
2214 coff_arm_merge_private_bfd_data (ibfd, obfd)
2215      bfd *   ibfd;
2216      bfd *   obfd;
2217 {
2218   BFD_ASSERT (ibfd != NULL && obfd != NULL);
2219
2220   if (ibfd == obfd)
2221     return true;
2222
2223   /* If the two formats are different we cannot merge anything.
2224      This is not an error, since it is permissable to change the
2225      input and output formats.  */
2226   if (   ibfd->xvec->flavour != bfd_target_coff_flavour
2227       || obfd->xvec->flavour != bfd_target_coff_flavour)
2228     return true;
2229
2230   /* Verify that the APCS is the same for the two BFDs */
2231   if (APCS_SET (ibfd))
2232     {
2233       if (APCS_SET (obfd))
2234         {
2235           /* If the src and dest have different APCS flag bits set, fail.  */
2236           if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
2237             {
2238               _bfd_error_handler
2239                 /* xgettext: c-format */
2240                 (_("ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
2241                  bfd_archive_filename (ibfd), APCS_26_FLAG (ibfd) ? 26 : 32,
2242                  bfd_get_filename (obfd), APCS_26_FLAG (obfd) ? 26 : 32
2243                  );
2244
2245               bfd_set_error (bfd_error_wrong_format);
2246               return false;
2247             }
2248
2249           if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
2250             {
2251               const char *msg;
2252
2253               if (APCS_FLOAT_FLAG (ibfd))
2254                 /* xgettext: c-format */
2255                 msg = _("ERROR: %s passes floats in float registers, whereas %s passes them in integer registers");
2256               else
2257                 /* xgettext: c-format */
2258                 msg = _("ERROR: %s passes floats in integer registers, whereas %s passes them in float registers");
2259
2260               _bfd_error_handler (msg, bfd_archive_filename (ibfd),
2261                                   bfd_get_filename (obfd));
2262
2263               bfd_set_error (bfd_error_wrong_format);
2264               return false;
2265             }
2266
2267           if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
2268             {
2269               const char * msg;
2270
2271               if (PIC_FLAG (ibfd))
2272                 /* xgettext: c-format */
2273                 msg = _("ERROR: %s is compiled as position independent code, whereas target %s is absolute position");
2274               else
2275                 /* xgettext: c-format */
2276                 msg = _("ERROR: %s is compiled as absolute position code, whereas target %s is position independent");
2277               _bfd_error_handler (msg, bfd_archive_filename (ibfd),
2278                                   bfd_get_filename (obfd));
2279
2280               bfd_set_error (bfd_error_wrong_format);
2281               return false;
2282             }
2283         }
2284       else
2285         {
2286           SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd));
2287
2288           /* Set up the arch and fields as well as these are probably wrong.  */
2289           bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2290         }
2291     }
2292
2293   /* Check the interworking support.  */
2294   if (INTERWORK_SET (ibfd))
2295     {
2296       if (INTERWORK_SET (obfd))
2297         {
2298           /* If the src and dest differ in their interworking issue a warning.  */
2299           if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
2300             {
2301               const char * msg;
2302
2303               if (INTERWORK_FLAG (ibfd))
2304                 /* xgettext: c-format */
2305                 msg = _("Warning: %s supports interworking, whereas %s does not");
2306               else
2307                 /* xgettext: c-format */
2308                 msg = _("Warning: %s does not support interworking, whereas %s does");
2309
2310               _bfd_error_handler (msg, bfd_archive_filename (ibfd),
2311                                   bfd_get_filename (obfd));
2312             }
2313         }
2314       else
2315         {
2316           SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
2317         }
2318     }
2319
2320   return true;
2321 }
2322
2323 /* Display the flags field.  */
2324
2325 static boolean
2326 coff_arm_print_private_bfd_data (abfd, ptr)
2327      bfd *   abfd;
2328      PTR     ptr;
2329 {
2330   FILE * file = (FILE *) ptr;
2331
2332   BFD_ASSERT (abfd != NULL && ptr != NULL);
2333
2334   /* xgettext:c-format */
2335   fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
2336
2337   if (APCS_SET (abfd))
2338     {
2339       /* xgettext: APCS is ARM Prodecure Call Standard, it should not be translated.  */
2340       fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32);
2341
2342       if (APCS_FLOAT_FLAG (abfd))
2343         fprintf (file, _(" [floats passed in float registers]"));
2344       else
2345         fprintf (file, _(" [floats passed in integer registers]"));
2346
2347       if (PIC_FLAG (abfd))
2348         fprintf (file, _(" [position independent]"));
2349       else
2350         fprintf (file, _(" [absolute position]"));
2351     }
2352
2353   if (! INTERWORK_SET (abfd))
2354     fprintf (file, _(" [interworking flag not initialised]"));
2355   else if (INTERWORK_FLAG (abfd))
2356     fprintf (file, _(" [interworking supported]"));
2357   else
2358     fprintf (file, _(" [interworking not supported]"));
2359
2360   fputc ('\n', file);
2361
2362   return true;
2363 }
2364
2365 /* Copies the given flags into the coff_tdata.flags field.
2366    Typically these flags come from the f_flags[] field of
2367    the COFF filehdr structure, which contains important,
2368    target specific information.
2369    Note: Although this function is static, it is explicitly
2370    called from both coffcode.h and peicode.h.  */
2371
2372 static boolean
2373 _bfd_coff_arm_set_private_flags (abfd, flags)
2374         bfd *      abfd;
2375         flagword   flags;
2376 {
2377   flagword flag;
2378
2379   BFD_ASSERT (abfd != NULL);
2380
2381   flag = (flags & F_APCS26) ? F_APCS_26 : 0;
2382
2383   /* Make sure that the APCS field has not been initialised to the opposite
2384      value.  */
2385   if (APCS_SET (abfd)
2386       && (   (APCS_26_FLAG    (abfd) != flag)
2387           || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
2388           || (PIC_FLAG        (abfd) != (flags & F_PIC))
2389           ))
2390     return false;
2391
2392   flag |= (flags & (F_APCS_FLOAT | F_PIC));
2393
2394   SET_APCS_FLAGS (abfd, flag);
2395
2396   flag = (flags & F_INTERWORK);
2397
2398   /* If the BFD has already had its interworking flag set, but it
2399      is different from the value that we have been asked to set,
2400      then assume that that merged code will not support interworking
2401      and set the flag accordingly.  */
2402   if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
2403     {
2404       if (flag)
2405         /* xgettext: c-format */
2406         _bfd_error_handler (_("Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"),
2407                             bfd_archive_filename (abfd));
2408       else
2409         /* xgettext: c-format */
2410         _bfd_error_handler (_("Warning: Clearing the interworking flag of %s due to outside request"),
2411                             bfd_archive_filename (abfd));
2412       flag = 0;
2413     }
2414
2415   SET_INTERWORK_FLAG (abfd, flag);
2416
2417   return true;
2418 }
2419
2420 /* Copy the important parts of the target specific data
2421    from one instance of a BFD to another.  */
2422
2423 static boolean
2424 coff_arm_copy_private_bfd_data (src, dest)
2425      bfd *  src;
2426      bfd *  dest;
2427 {
2428   BFD_ASSERT (src != NULL && dest != NULL);
2429
2430   if (src == dest)
2431     return true;
2432
2433   /* If the destination is not in the same format as the source, do not do
2434      the copy.  */
2435   if (src->xvec != dest->xvec)
2436     return true;
2437
2438   /* copy the flags field */
2439   if (APCS_SET (src))
2440     {
2441       if (APCS_SET (dest))
2442         {
2443           /* If the src and dest have different APCS flag bits set, fail.  */
2444           if (APCS_26_FLAG (dest) != APCS_26_FLAG (src))
2445             return false;
2446
2447           if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
2448             return false;
2449
2450           if (PIC_FLAG (dest) != PIC_FLAG (src))
2451             return false;
2452         }
2453       else
2454         SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src)
2455                         | PIC_FLAG (src));
2456     }
2457
2458   if (INTERWORK_SET (src))
2459     {
2460       if (INTERWORK_SET (dest))
2461         {
2462           /* If the src and dest have different interworking flags then turn
2463              off the interworking bit.  */
2464           if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src))
2465             {
2466               if (INTERWORK_FLAG (dest))
2467                 {
2468                   /* xgettext:c-format */
2469                   _bfd_error_handler (("\
2470 Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"),
2471                                       bfd_get_filename (dest),
2472                                       bfd_archive_filename (src));
2473                 }
2474
2475               SET_INTERWORK_FLAG (dest, 0);
2476             }
2477         }
2478       else
2479         {
2480           SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
2481         }
2482     }
2483
2484   return true;
2485 }
2486
2487 /* Note:  the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
2488    *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h.  */
2489 #define LOCAL_LABEL_PREFIX ""
2490 #ifndef USER_LABEL_PREFIX
2491 #define USER_LABEL_PREFIX "_"
2492 #endif
2493
2494 /* Like _bfd_coff_is_local_label_name, but
2495    a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
2496       non-local.
2497    b) Allow other prefixes than ".", e.g. an empty prefix would cause all
2498       labels of the form Lxxx to be stripped.  */
2499 static boolean
2500 coff_arm_is_local_label_name (abfd, name)
2501      bfd *        abfd ATTRIBUTE_UNUSED;
2502      const char * name;
2503 {
2504 #ifdef USER_LABEL_PREFIX
2505   if (USER_LABEL_PREFIX[0] != 0)
2506     {
2507       if (strncmp (name, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)) == 0)
2508         return false;
2509     }
2510 #endif
2511
2512 #ifdef LOCAL_LABEL_PREFIX
2513   /* If there is a prefix for local labels then look for this.
2514      If the prefix exists, but it is empty, then ignore the test.  */
2515
2516   if (LOCAL_LABEL_PREFIX[0] != 0)
2517     {
2518       size_t len = strlen (LOCAL_LABEL_PREFIX);
2519
2520       if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0)
2521         return false;
2522
2523       /* Perform the checks below for the rest of the name.  */
2524       name += len;
2525     }
2526 #endif
2527
2528   return name[0] == 'L';
2529 }
2530
2531 /* This piece of machinery exists only to guarantee that the bfd that holds
2532    the glue section is written last.
2533
2534    This does depend on bfd_make_section attaching a new section to the
2535    end of the section list for the bfd.
2536
2537    krk@cygnus.com  */
2538
2539 static boolean
2540 coff_arm_link_output_has_begun (sub, info)
2541      bfd * sub;
2542      struct coff_final_link_info * info;
2543 {
2544   return (sub->output_has_begun
2545           || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner);
2546 }
2547
2548 static boolean
2549 coff_arm_final_link_postscript (abfd, pfinfo)
2550      bfd * abfd ATTRIBUTE_UNUSED;
2551      struct coff_final_link_info * pfinfo;
2552 {
2553   struct coff_arm_link_hash_table * globals;
2554
2555   globals = coff_arm_hash_table (pfinfo->info);
2556
2557   BFD_ASSERT (globals != NULL);
2558
2559   if (globals->bfd_of_glue_owner != NULL)
2560     {
2561       if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner))
2562         return false;
2563
2564       globals->bfd_of_glue_owner->output_has_begun = true;
2565     }
2566
2567   return true;
2568 }
2569
2570 #include "coffcode.h"
2571
2572 #ifndef TARGET_LITTLE_SYM
2573 #define TARGET_LITTLE_SYM armcoff_little_vec
2574 #endif
2575 #ifndef TARGET_LITTLE_NAME
2576 #define TARGET_LITTLE_NAME "coff-arm-little"
2577 #endif
2578 #ifndef TARGET_BIG_SYM
2579 #define TARGET_BIG_SYM armcoff_big_vec
2580 #endif
2581 #ifndef TARGET_BIG_NAME
2582 #define TARGET_BIG_NAME "coff-arm-big"
2583 #endif
2584
2585 #ifndef TARGET_UNDERSCORE
2586 #define TARGET_UNDERSCORE 0
2587 #endif
2588
2589 #ifndef EXTRA_S_FLAGS
2590 #ifdef COFF_WITH_PE
2591 #define EXTRA_S_FLAGS (SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
2592 #else
2593 #define EXTRA_S_FLAGS 0
2594 #endif
2595 #endif
2596
2597 /* Forward declaration for use initialising alternative_target field.  */
2598 extern const bfd_target TARGET_BIG_SYM ;
2599
2600 /* Target vectors.  */
2601 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM)
2602 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM)