Unify messages in coff-arm.c and elf32-arm.h.
[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
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 /* Extend the coff_link_hash_table structure with a few ARM specific fields.
904    This allows us to store global data here without actually creating any
905    global variables, which is a no-no in the BFD world.  */
906 struct coff_arm_link_hash_table
907   {
908     /* The original coff_link_hash_table structure.  MUST be first field.  */
909     struct coff_link_hash_table root;
910
911     /* The size in bytes of the section containg the Thumb-to-ARM glue.  */
912     bfd_size_type               thumb_glue_size;
913
914     /* The size in bytes of the section containg the ARM-to-Thumb glue.  */
915     bfd_size_type               arm_glue_size;
916
917     /* An arbitary input BFD chosen to hold the glue sections.  */
918     bfd *                       bfd_of_glue_owner;
919
920     /* Support interworking with old, non-interworking aware ARM code.  */
921     int                         support_old_code;
922 };
923
924 /* Get the ARM coff linker hash table from a link_info structure.  */
925 #define coff_arm_hash_table(info) \
926   ((struct coff_arm_link_hash_table *) ((info)->hash))
927
928 /* Create an ARM coff linker hash table.  */
929
930 static struct bfd_link_hash_table *
931 coff_arm_link_hash_table_create (abfd)
932      bfd * abfd;
933 {
934   struct coff_arm_link_hash_table * ret;
935   bfd_size_type amt = sizeof (struct coff_arm_link_hash_table);
936
937   ret = (struct coff_arm_link_hash_table *) bfd_alloc (abfd, amt);
938   if (ret == (struct coff_arm_link_hash_table *) NULL)
939     return NULL;
940
941   if (! _bfd_coff_link_hash_table_init
942       (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
943     {
944       bfd_release (abfd, ret);
945       return (struct bfd_link_hash_table *) NULL;
946     }
947
948   ret->thumb_glue_size   = 0;
949   ret->arm_glue_size     = 0;
950   ret->bfd_of_glue_owner = NULL;
951
952   return & ret->root.root;
953 }
954
955 static void
956 arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
957       struct bfd_link_info *info;
958       bfd *output_bfd;
959       asection *input_section;
960       bfd_vma reloc_offset;
961 {
962   bfd_vma addr = reloc_offset
963                 - input_section->vma
964                 + input_section->output_offset
965                   + input_section->output_section->vma;
966
967   if (coff_data (output_bfd)->pe)
968      addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
969   fwrite (& addr, 1, sizeof (addr), (FILE *) info->base_file);
970
971 }
972 \f
973 /* The thumb form of a long branch is a bit finicky, because the offset
974    encoding is split over two fields, each in it's own instruction. They
975    can occur in any order. So given a thumb form of long branch, and an
976    offset, insert the offset into the thumb branch and return finished
977    instruction.
978
979    It takes two thumb instructions to encode the target address. Each has
980    11 bits to invest. The upper 11 bits are stored in one (identifed by
981    H-0.. see below), the lower 11 bits are stored in the other (identified
982    by H-1).
983
984    Combine together and shifted left by 1 (it's a half word address) and
985    there you have it.
986
987      Op: 1111 = F,
988      H-0, upper address-0 = 000
989      Op: 1111 = F,
990      H-1, lower address-0 = 800
991
992    They can be ordered either way, but the arm tools I've seen always put
993    the lower one first. It probably doesn't matter. krk@cygnus.com
994
995    XXX:  Actually the order does matter.  The second instruction (H-1)
996    moves the computed address into the PC, so it must be the second one
997    in the sequence.  The problem, however is that whilst little endian code
998    stores the instructions in HI then LOW order, big endian code does the
999    reverse.  nickc@cygnus.com.  */
1000
1001 #define LOW_HI_ORDER 0xF800F000
1002 #define HI_LOW_ORDER 0xF000F800
1003
1004 static insn32
1005 insert_thumb_branch (br_insn, rel_off)
1006      insn32 br_insn;
1007      int rel_off;
1008 {
1009   unsigned int low_bits;
1010   unsigned int high_bits;
1011
1012   BFD_ASSERT((rel_off & 1) != 1);
1013
1014   rel_off >>= 1;                              /* half word aligned address */
1015   low_bits = rel_off & 0x000007FF;            /* the bottom 11 bits */
1016   high_bits = (rel_off >> 11) & 0x000007FF;   /* the top 11 bits */
1017
1018   if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1019     br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1020   else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1021     br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1022   else
1023     /* FIXME: the BFD library should never abort except for internal errors
1024        - it should return an error status.  */
1025     abort (); /* Error - not a valid branch instruction form.  */
1026
1027   return br_insn;
1028 }
1029 \f
1030 static struct coff_link_hash_entry *
1031 find_thumb_glue (info, name, input_bfd)
1032      struct bfd_link_info *info;
1033      const char *name;
1034      bfd *input_bfd;
1035 {
1036   char *tmp_name;
1037   struct coff_link_hash_entry *myh;
1038   bfd_size_type amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1039
1040   tmp_name = (char *) bfd_malloc (amt);
1041
1042   BFD_ASSERT (tmp_name);
1043
1044   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1045
1046   myh = coff_link_hash_lookup
1047     (coff_hash_table (info), tmp_name, false, false, true);
1048
1049   if (myh == NULL)
1050     /* xgettext:c-format */
1051     _bfd_error_handler (_("%s: unable to find THUMB glue '%s' for `%s'"),
1052                         bfd_archive_filename (input_bfd), tmp_name, name);
1053
1054   free (tmp_name);
1055
1056   return myh;
1057 }
1058
1059 static struct coff_link_hash_entry *
1060 find_arm_glue (info, name, input_bfd)
1061      struct bfd_link_info *info;
1062      const char *name;
1063      bfd *input_bfd;
1064 {
1065   char *tmp_name;
1066   struct coff_link_hash_entry * myh;
1067   bfd_size_type amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1068
1069   tmp_name = (char *) bfd_malloc (amt);
1070
1071   BFD_ASSERT (tmp_name);
1072
1073   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1074
1075   myh = coff_link_hash_lookup
1076     (coff_hash_table (info), tmp_name, false, false, true);
1077
1078   if (myh == NULL)
1079     /* xgettext:c-format */
1080     _bfd_error_handler (_("%s: unable to find ARM glue '%s' for `%s'"),
1081                         bfd_archive_filename (input_bfd), tmp_name, name);
1082
1083   free (tmp_name);
1084
1085   return myh;
1086 }
1087
1088 /*
1089   ARM->Thumb glue:
1090
1091        .arm
1092        __func_from_arm:
1093              ldr r12, __func_addr
1094              bx  r12
1095        __func_addr:
1096             .word func    @ behave as if you saw a ARM_32 reloc
1097 */
1098
1099 #define ARM2THUMB_GLUE_SIZE 12
1100 static const insn32 a2t1_ldr_insn       = 0xe59fc000;
1101 static const insn32 a2t2_bx_r12_insn    = 0xe12fff1c;
1102 static const insn32 a2t3_func_addr_insn = 0x00000001;
1103
1104 /*
1105    Thumb->ARM:                          Thumb->(non-interworking aware) ARM
1106
1107    .thumb                               .thumb
1108    .align 2                             .align 2
1109       __func_from_thumb:                   __func_from_thumb:
1110            bx pc                                push {r6, lr}
1111            nop                                  ldr  r6, __func_addr
1112    .arm                                         mov  lr, pc
1113       __func_change_to_arm:                     bx   r6
1114            b func                       .arm
1115                                            __func_back_to_thumb:
1116                                                 ldmia r13! {r6, lr}
1117                                                 bx    lr
1118                                            __func_addr:
1119                                                 .word   func
1120 */
1121
1122 #define THUMB2ARM_GLUE_SIZE (globals->support_old_code ? 20 : 8)
1123 static const insn16 t2a1_bx_pc_insn = 0x4778;
1124 static const insn16 t2a2_noop_insn  = 0x46c0;
1125 static const insn32 t2a3_b_insn     = 0xea000000;
1126
1127 static const insn16 t2a1_push_insn  = 0xb540;
1128 static const insn16 t2a2_ldr_insn   = 0x4e03;
1129 static const insn16 t2a3_mov_insn   = 0x46fe;
1130 static const insn16 t2a4_bx_insn    = 0x4730;
1131 static const insn32 t2a5_pop_insn   = 0xe8bd4040;
1132 static const insn32 t2a6_bx_insn    = 0xe12fff1e;
1133
1134 /* TODO:
1135      We should really create new local (static) symbols in destination
1136      object for each stub we create.  We should also create local
1137      (static) symbols within the stubs when switching between ARM and
1138      Thumb code.  This will ensure that the debugger and disassembler
1139      can present a better view of stubs.
1140
1141      We can treat stubs like literal sections, and for the THUMB9 ones
1142      (short addressing range) we should be able to insert the stubs
1143      between sections. i.e. the simplest approach (since relocations
1144      are done on a section basis) is to dump the stubs at the end of
1145      processing a section. That way we can always try and minimise the
1146      offset to and from a stub. However, this does not map well onto
1147      the way that the linker/BFD does its work: mapping all input
1148      sections to output sections via the linker script before doing
1149      all the processing.
1150
1151      Unfortunately it may be easier to just to disallow short range
1152      Thumb->ARM stubs (i.e. no conditional inter-working branches,
1153      only branch-and-link (BL) calls.  This will simplify the processing
1154      since we can then put all of the stubs into their own section.
1155
1156   TODO:
1157      On a different subject, rather than complaining when a
1158      branch cannot fit in the number of bits available for the
1159      instruction we should generate a trampoline stub (needed to
1160      address the complete 32bit address space).  */
1161
1162 /* The standard COFF backend linker does not cope with the special
1163    Thumb BRANCH23 relocation.  The alternative would be to split the
1164    BRANCH23 into seperate HI23 and LO23 relocations. However, it is a
1165    bit simpler simply providing our own relocation driver.  */
1166
1167 /* The reloc processing routine for the ARM/Thumb COFF linker.  NOTE:
1168    This code is a very slightly modified copy of
1169    _bfd_coff_generic_relocate_section.  It would be a much more
1170    maintainable solution to have a MACRO that could be expanded within
1171    _bfd_coff_generic_relocate_section that would only be provided for
1172    ARM/Thumb builds.  It is only the code marked THUMBEXTENSION that
1173    is different from the original.  */
1174
1175 static boolean
1176 coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1177                            contents, relocs, syms, sections)
1178      bfd *output_bfd;
1179      struct bfd_link_info *info;
1180      bfd *input_bfd;
1181      asection *input_section;
1182      bfd_byte *contents;
1183      struct internal_reloc *relocs;
1184      struct internal_syment *syms;
1185      asection **sections;
1186 {
1187   struct internal_reloc * rel;
1188   struct internal_reloc * relend;
1189
1190   rel = relocs;
1191   relend = rel + input_section->reloc_count;
1192
1193   for (; rel < relend; rel++)
1194     {
1195       int                            done = 0;
1196       long                           symndx;
1197       struct coff_link_hash_entry *  h;
1198       struct internal_syment *       sym;
1199       bfd_vma                        addend;
1200       bfd_vma                        val;
1201       reloc_howto_type *             howto;
1202       bfd_reloc_status_type          rstat;
1203       bfd_vma                        h_val;
1204
1205       symndx = rel->r_symndx;
1206
1207       if (symndx == -1)
1208         {
1209           h = NULL;
1210           sym = NULL;
1211         }
1212       else
1213         {
1214           h = obj_coff_sym_hashes (input_bfd)[symndx];
1215           sym = syms + symndx;
1216         }
1217
1218       /* COFF treats common symbols in one of two ways.  Either the
1219          size of the symbol is included in the section contents, or it
1220          is not.  We assume that the size is not included, and force
1221          the rtype_to_howto function to adjust the addend as needed.  */
1222
1223       if (sym != NULL && sym->n_scnum != 0)
1224         addend = - sym->n_value;
1225       else
1226         addend = 0;
1227
1228       howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
1229                                        sym, &addend);
1230       if (howto == NULL)
1231         return false;
1232
1233       /* The relocation_section function will skip pcrel_offset relocs
1234          when doing a relocateable link.  However, we want to convert
1235          ARM26 to ARM26D relocs if possible.  We return a fake howto in
1236          this case without pcrel_offset set, and adjust the addend to
1237          compensate.  */
1238       if (rel->r_type == ARM_26
1239           && h != NULL
1240           && info->relocateable
1241           && (h->root.type == bfd_link_hash_defined
1242               || h->root.type == bfd_link_hash_defweak)
1243           && (h->root.u.def.section->output_section
1244               == input_section->output_section))
1245         {
1246           static reloc_howto_type fake_arm26_reloc =
1247             HOWTO (ARM_26,
1248                2,
1249                2,
1250                24,
1251                true,
1252                0,
1253                complain_overflow_signed,
1254                aoutarm_fix_pcrel_26 ,
1255                "ARM_26",
1256                false,
1257                0x00ffffff,
1258                0x00ffffff,
1259                false);
1260
1261           addend -= rel->r_vaddr - input_section->vma;
1262           howto = &fake_arm26_reloc;
1263         }
1264
1265 #ifdef ARM_WINCE
1266       /* MS ARM-CE makes the reloc relative to the opcode's pc, not
1267          the next opcode's pc, so is off by one.  */
1268       if (howto->pc_relative && !info->relocateable)
1269         addend -= 8;
1270 #endif
1271
1272       /* If we are doing a relocateable link, then we can just ignore
1273          a PC relative reloc that is pcrel_offset.  It will already
1274          have the correct value.  If this is not a relocateable link,
1275          then we should ignore the symbol value.  */
1276       if (howto->pc_relative && howto->pcrel_offset)
1277         {
1278           if (info->relocateable)
1279             continue;
1280           /* FIXME - it is not clear which targets need this next test
1281              and which do not.  It is known that it is needed for the
1282              VxWorks and EPOC-PE targets, but it is also known that it
1283              was supressed for other ARM targets.  This ought to be
1284              sorted out one day.  */
1285 #ifdef ARM_COFF_BUGFIX
1286           /* We must not ignore the symbol value.  If the symbol is
1287              within the same section, the relocation should have already
1288              been fixed, but if it is not, we'll be handed a reloc into
1289              the beginning of the symbol's section, so we must not cancel
1290              out the symbol's value, otherwise we'll be adding it in
1291              twice.  */
1292           if (sym != NULL && sym->n_scnum != 0)
1293             addend += sym->n_value;
1294 #endif
1295         }
1296
1297       val = 0;
1298
1299       if (h == NULL)
1300         {
1301           asection *sec;
1302
1303           if (symndx == -1)
1304             {
1305               sec = bfd_abs_section_ptr;
1306               val = 0;
1307             }
1308           else
1309             {
1310               sec = sections[symndx];
1311               val = (sec->output_section->vma
1312                      + sec->output_offset
1313                      + sym->n_value
1314                      - sec->vma);
1315             }
1316         }
1317       else
1318         {
1319 #if 1 /* THUMBEXTENSION */
1320           /* We don't output the stubs if we are generating a
1321              relocatable output file, since we may as well leave the
1322              stub generation to the final linker pass. If we fail to
1323              verify that the name is defined, we'll try to build stubs
1324              for an undefined name...  */
1325           if (! info->relocateable
1326               && (   h->root.type == bfd_link_hash_defined
1327                   || h->root.type == bfd_link_hash_defweak))
1328             {
1329               asection *   h_sec = h->root.u.def.section;
1330               const char * name  = h->root.root.string;
1331
1332               /* h locates the symbol referenced in the reloc.  */
1333               h_val = (h->root.u.def.value
1334                        + h_sec->output_section->vma
1335                        + h_sec->output_offset);
1336
1337               if (howto->type == ARM_26)
1338                 {
1339                   if (   h->class == C_THUMBSTATFUNC
1340                       || h->class == C_THUMBEXTFUNC)
1341                     {
1342                       /* Arm code calling a Thumb function.  */
1343                       unsigned long int                 tmp;
1344                       bfd_vma                           my_offset;
1345                       asection *                        s;
1346                       long int                          ret_offset;
1347                       struct coff_link_hash_entry *     myh;
1348                       struct coff_arm_link_hash_table * globals;
1349
1350                       myh = find_arm_glue (info, name, input_bfd);
1351                       if (myh == NULL)
1352                         return false;
1353
1354                       globals = coff_arm_hash_table (info);
1355
1356                       BFD_ASSERT (globals != NULL);
1357                       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1358
1359                       my_offset = myh->root.u.def.value;
1360
1361                       s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1362                                                   ARM2THUMB_GLUE_SECTION_NAME);
1363                       BFD_ASSERT (s != NULL);
1364                       BFD_ASSERT (s->contents != NULL);
1365                       BFD_ASSERT (s->output_section != NULL);
1366
1367                       if ((my_offset & 0x01) == 0x01)
1368                         {
1369                           if (h_sec->owner != NULL
1370                               && INTERWORK_SET (h_sec->owner)
1371                               && ! INTERWORK_FLAG (h_sec->owner))
1372                             {
1373                               _bfd_error_handler
1374                                 /* xgettext:c-format */
1375                                 (_("%s(%s): warning: interworking not enabled."),
1376                                  bfd_archive_filename (h_sec->owner), name);
1377                               _bfd_error_handler
1378                                 /* xgettext:c-format */
1379                                 (_("  first occurrence: %s: arm call to thumb"),
1380                                  bfd_archive_filename (input_bfd));
1381                             }
1382
1383                           --my_offset;
1384                           myh->root.u.def.value = my_offset;
1385
1386                           bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn,
1387                                       s->contents + my_offset);
1388
1389                           bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn,
1390                                       s->contents + my_offset + 4);
1391
1392                           /* It's a thumb address.  Add the low order bit.  */
1393                           bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
1394                                       s->contents + my_offset + 8);
1395
1396                           if (info->base_file)
1397                             arm_emit_base_file_entry (info, output_bfd, s,
1398                                                       my_offset + 8);
1399
1400                         }
1401
1402                       BFD_ASSERT (my_offset <= globals->arm_glue_size);
1403
1404                       tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1405                                         - input_section->vma);
1406
1407                       tmp = tmp & 0xFF000000;
1408
1409                       /* Somehow these are both 4 too far, so subtract 8.  */
1410                       ret_offset =
1411                         s->output_offset
1412                         + my_offset
1413                         + s->output_section->vma
1414                         - (input_section->output_offset
1415                            + input_section->output_section->vma
1416                            + rel->r_vaddr)
1417                         - 8;
1418
1419                       tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1420
1421                       bfd_put_32 (output_bfd, (bfd_vma) tmp,
1422                                   contents + rel->r_vaddr - input_section->vma);
1423                       done = 1;
1424                     }
1425                 }
1426
1427 #ifndef ARM_WINCE
1428               /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12.  */
1429               else if (howto->type == ARM_THUMB23)
1430                 {
1431                   if (   h->class == C_EXT
1432                       || h->class == C_STAT
1433                       || h->class == C_LABEL)
1434                     {
1435                       /* Thumb code calling an ARM function */
1436                       asection *                         s = 0;
1437                       bfd_vma                            my_offset;
1438                       unsigned long int                  tmp;
1439                       long int                           ret_offset;
1440                       struct coff_link_hash_entry *      myh;
1441                       struct coff_arm_link_hash_table *  globals;
1442
1443                       myh = find_thumb_glue (info, name, input_bfd);
1444                       if (myh == NULL)
1445                         return false;
1446
1447                       globals = coff_arm_hash_table (info);
1448
1449                       BFD_ASSERT (globals != NULL);
1450                       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1451
1452                       my_offset = myh->root.u.def.value;
1453
1454                       s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1455                                                    THUMB2ARM_GLUE_SECTION_NAME);
1456
1457                       BFD_ASSERT (s != NULL);
1458                       BFD_ASSERT (s->contents != NULL);
1459                       BFD_ASSERT (s->output_section != NULL);
1460
1461                       if ((my_offset & 0x01) == 0x01)
1462                         {
1463                           if (h_sec->owner != NULL
1464                               && INTERWORK_SET (h_sec->owner)
1465                               && ! INTERWORK_FLAG (h_sec->owner)
1466                               && ! globals->support_old_code)
1467                             {
1468                               _bfd_error_handler
1469                                 /* xgettext:c-format */
1470                                 (_("%s(%s): warning: interworking not enabled."),
1471                                  bfd_archive_filename (h_sec->owner), name);
1472                               _bfd_error_handler
1473                                 /* xgettext:c-format */
1474                                 (_("  first occurrence: %s: thumb call to arm"),
1475                                  bfd_archive_filename (input_bfd));
1476                               _bfd_error_handler
1477                                 (_("  consider relinking with --support-old-code enabled"));
1478                             }
1479
1480                           -- my_offset;
1481                           myh->root.u.def.value = my_offset;
1482
1483                           if (globals->support_old_code)
1484                             {
1485                               bfd_put_16 (output_bfd, (bfd_vma) t2a1_push_insn,
1486                                           s->contents + my_offset);
1487
1488                               bfd_put_16 (output_bfd, (bfd_vma) t2a2_ldr_insn,
1489                                           s->contents + my_offset + 2);
1490
1491                               bfd_put_16 (output_bfd, (bfd_vma) t2a3_mov_insn,
1492                                           s->contents + my_offset + 4);
1493
1494                               bfd_put_16 (output_bfd, (bfd_vma) t2a4_bx_insn,
1495                                           s->contents + my_offset + 6);
1496
1497                               bfd_put_32 (output_bfd, (bfd_vma) t2a5_pop_insn,
1498                                           s->contents + my_offset + 8);
1499
1500                               bfd_put_32 (output_bfd, (bfd_vma) t2a6_bx_insn,
1501                                           s->contents + my_offset + 12);
1502
1503                               /* Store the address of the function in the last word of the stub.  */
1504                               bfd_put_32 (output_bfd, h_val,
1505                                           s->contents + my_offset + 16);
1506
1507                               if (info->base_file)
1508                                 arm_emit_base_file_entry (info, output_bfd, s,
1509                                                           my_offset + 16);
1510                             }
1511                           else
1512                             {
1513                               bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn,
1514                                           s->contents + my_offset);
1515
1516                               bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn,
1517                                           s->contents + my_offset + 2);
1518
1519                               ret_offset =
1520                                 ((bfd_signed_vma) h_val)        /* Address of destination of the stub.  */
1521                                 - ((bfd_signed_vma)
1522                                    (s->output_offset            /* Offset from the start of the current section to the start of the stubs.  */
1523                                     + my_offset                 /* Offset of the start of this stub from the start of the stubs.  */
1524                                     + s->output_section->vma)   /* Address of the start of the current section.  */
1525                                    + 4                          /* The branch instruction is 4 bytes into the stub.  */
1526                                    + 8);                        /* ARM branches work from the pc of the instruction + 8.  */
1527
1528                               bfd_put_32 (output_bfd,
1529                                           (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1530                                           s->contents + my_offset + 4);
1531
1532                             }
1533                         }
1534
1535                       BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1536
1537                       /* Now go back and fix up the original BL insn to point
1538                          to here.  */
1539                       ret_offset =
1540                         s->output_offset
1541                         + my_offset
1542                         - (input_section->output_offset
1543                            + rel->r_vaddr)
1544                         -4;
1545
1546                       tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1547                                         - input_section->vma);
1548
1549                       bfd_put_32 (output_bfd,
1550                                   (bfd_vma) insert_thumb_branch (tmp,
1551                                                                  ret_offset),
1552                                   contents + rel->r_vaddr - input_section->vma);
1553
1554                       done = 1;
1555                     }
1556                 }
1557 #endif
1558             }
1559
1560           /* If the relocation type and destination symbol does not
1561              fall into one of the above categories, then we can just
1562              perform a direct link.  */
1563
1564           if (done)
1565             rstat = bfd_reloc_ok;
1566           else
1567 #endif /* THUMBEXTENSION */
1568             if (   h->root.type == bfd_link_hash_defined
1569                 || h->root.type == bfd_link_hash_defweak)
1570             {
1571               asection *sec;
1572
1573               sec = h->root.u.def.section;
1574               val = (h->root.u.def.value
1575                      + sec->output_section->vma
1576                      + sec->output_offset);
1577               }
1578
1579           else if (! info->relocateable)
1580             {
1581               if (! ((*info->callbacks->undefined_symbol)
1582                      (info, h->root.root.string, input_bfd, input_section,
1583                       rel->r_vaddr - input_section->vma, true)))
1584                 return false;
1585             }
1586         }
1587
1588       if (info->base_file)
1589         {
1590           /* Emit a reloc if the backend thinks it needs it.  */
1591           if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
1592             arm_emit_base_file_entry (info, output_bfd, input_section,
1593                                       rel->r_vaddr);
1594         }
1595
1596 #if 1 /* THUMBEXTENSION */
1597       if (done)
1598         rstat = bfd_reloc_ok;
1599 #ifndef ARM_WINCE
1600       /* Only perform this fix during the final link, not a relocatable link.  nickc@cygnus.com  */
1601       else if (! info->relocateable
1602                && howto->type == ARM_THUMB23)
1603         {
1604           /* This is pretty much a copy of what the default
1605              _bfd_final_link_relocate and _bfd_relocate_contents
1606              routines do to perform a relocation, with special
1607              processing for the split addressing of the Thumb BL
1608              instruction.  Again, it would probably be simpler adding a
1609              ThumbBRANCH23 specific macro expansion into the default
1610              code.  */
1611
1612           bfd_vma address = rel->r_vaddr - input_section->vma;
1613
1614           if (address > input_section->_raw_size)
1615             rstat = bfd_reloc_outofrange;
1616           else
1617             {
1618               bfd_vma         relocation       = val + addend;
1619               int             size             = bfd_get_reloc_size (howto);
1620               boolean         overflow         = false;
1621               bfd_byte *      location         = contents + address;
1622               bfd_vma         x                = bfd_get_32 (input_bfd, location);
1623               bfd_vma         src_mask         = 0x007FFFFE;
1624               bfd_signed_vma  reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1625               bfd_signed_vma  reloc_signed_min = ~reloc_signed_max;
1626               bfd_vma         check;
1627               bfd_signed_vma  signed_check;
1628               bfd_vma         add;
1629               bfd_signed_vma  signed_add;
1630
1631               BFD_ASSERT (size == 4);
1632
1633               /* howto->pc_relative should be TRUE for type 14 BRANCH23.  */
1634               relocation -= (input_section->output_section->vma
1635                              + input_section->output_offset);
1636
1637               /* howto->pcrel_offset should be TRUE for type 14 BRANCH23.  */
1638               relocation -= address;
1639
1640               /* No need to negate the relocation with BRANCH23.  */
1641               /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23.  */
1642               /* howto->rightshift == 1 */
1643
1644               /* Drop unwanted bits from the value we are relocating to.  */
1645               check = relocation >> howto->rightshift;
1646
1647               /* If this is a signed value, the rightshift just dropped
1648                  leading 1 bits (assuming twos complement).  */
1649               if ((bfd_signed_vma) relocation >= 0)
1650                 signed_check = check;
1651               else
1652                 signed_check = (check
1653                                 | ((bfd_vma) - 1
1654                                    & ~((bfd_vma) - 1 >> howto->rightshift)));
1655
1656               /* Get the value from the object file.  */
1657               if (bfd_big_endian (input_bfd))
1658                 add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
1659               else
1660                 add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
1661
1662               /* Get the value from the object file with an appropriate sign.
1663                  The expression involving howto->src_mask isolates the upper
1664                  bit of src_mask.  If that bit is set in the value we are
1665                  adding, it is negative, and we subtract out that number times
1666                  two.  If src_mask includes the highest possible bit, then we
1667                  can not get the upper bit, but that does not matter since
1668                  signed_add needs no adjustment to become negative in that
1669                  case.  */
1670               signed_add = add;
1671
1672               if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
1673                 signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
1674
1675               /* howto->bitpos == 0 */
1676               /* Add the value from the object file, shifted so that it is a
1677                  straight number.  */
1678               signed_check += signed_add;
1679               relocation   += signed_add;
1680
1681               BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
1682
1683               /* Assumes two's complement.  */
1684               if (   signed_check > reloc_signed_max
1685                   || signed_check < reloc_signed_min)
1686                 overflow = true;
1687
1688               /* For the BLX(1) instruction remove bit 0 of the adjusted offset.
1689                  Bit 0 can only be set if the upper insn is at a half-word boundary,
1690                  since the destination address, an ARM instruction, must always be
1691                  on a word boundary.  The semantics of the BLX (1) instruction,
1692                  however, are that bit 0 in the offset must always be 0, and the
1693                  corresponding bit 1 in the target address will be set from bit
1694                  1 of the source address.  */
1695               if ((x & 0x18000000) == 0x08000000)
1696                 relocation &= ~0x2;
1697
1698               /* Put the relocation into the correct bits.  */
1699               if (bfd_big_endian (input_bfd))
1700                 relocation = (((relocation & 0xffe) >> 1)  | ((relocation << 4) & 0x07ff0000));
1701               else
1702                 relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1703
1704               /* Add the relocation to the correct bits of X.  */
1705               x = ((x & ~howto->dst_mask) | relocation);
1706
1707               /* Put the relocated value back in the object file.  */
1708               bfd_put_32 (input_bfd, x, location);
1709
1710               rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
1711             }
1712         }
1713 #endif
1714       else
1715 #endif /* THUMBEXTENSION */
1716         rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
1717                                           contents,
1718                                           rel->r_vaddr - input_section->vma,
1719                                           val, addend);
1720 #if 1 /* THUMBEXTENSION */
1721       /* FIXME:
1722          Is this the best way to fix up thumb addresses? krk@cygnus.com
1723          Probably not, but it works, and if it works it don't need fixing!  nickc@cygnus.com */
1724       /* Only perform this fix during the final link, not a relocatable link.  nickc@cygnus.com  */
1725       if (! info->relocateable
1726           && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
1727         {
1728           /* Determine if we need to set the bottom bit of a relocated address
1729              because the address is the address of a Thumb code symbol.  */
1730
1731           int patchit = false;
1732
1733           if (h != NULL
1734               && (   h->class == C_THUMBSTATFUNC
1735                   || h->class == C_THUMBEXTFUNC))
1736             {
1737               patchit = true;
1738             }
1739           else if (sym != NULL
1740                    && sym->n_scnum > N_UNDEF)
1741             {
1742               /* No hash entry - use the symbol instead.  */
1743
1744               if (   sym->n_sclass == C_THUMBSTATFUNC
1745                   || sym->n_sclass == C_THUMBEXTFUNC)
1746                 patchit = true;
1747             }
1748
1749           if (patchit)
1750             {
1751               bfd_byte * location = contents + rel->r_vaddr - input_section->vma;
1752               bfd_vma    x        = bfd_get_32 (input_bfd, location);
1753
1754               bfd_put_32 (input_bfd, x | 1, location);
1755             }
1756         }
1757 #endif /* THUMBEXTENSION */
1758
1759       switch (rstat)
1760         {
1761         default:
1762           abort ();
1763         case bfd_reloc_ok:
1764           break;
1765         case bfd_reloc_outofrange:
1766           (*_bfd_error_handler)
1767             (_("%s: bad reloc address 0x%lx in section `%s'"),
1768              bfd_archive_filename (input_bfd),
1769              (unsigned long) rel->r_vaddr,
1770              bfd_get_section_name (input_bfd, input_section));
1771           return false;
1772         case bfd_reloc_overflow:
1773           {
1774             const char *name;
1775             char buf[SYMNMLEN + 1];
1776
1777             if (symndx == -1)
1778               name = "*ABS*";
1779             else if (h != NULL)
1780               name = h->root.root.string;
1781             else
1782               {
1783                 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1784                 if (name == NULL)
1785                   return false;
1786               }
1787
1788             if (! ((*info->callbacks->reloc_overflow)
1789                    (info, name, howto->name, (bfd_vma) 0, input_bfd,
1790                     input_section, rel->r_vaddr - input_section->vma)))
1791               return false;
1792           }
1793         }
1794     }
1795
1796   return true;
1797 }
1798
1799 #ifndef COFF_IMAGE_WITH_PE
1800
1801 boolean
1802 bfd_arm_allocate_interworking_sections (info)
1803      struct bfd_link_info * info;
1804 {
1805   asection *                        s;
1806   bfd_byte *                        foo;
1807   struct coff_arm_link_hash_table * globals;
1808 #if 0
1809   static char                       test_char = '1';
1810 #endif
1811
1812   globals = coff_arm_hash_table (info);
1813
1814   BFD_ASSERT (globals != NULL);
1815
1816   if (globals->arm_glue_size != 0)
1817     {
1818       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1819
1820       s = bfd_get_section_by_name
1821         (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1822
1823       BFD_ASSERT (s != NULL);
1824
1825       foo = (bfd_byte *) bfd_alloc (globals->bfd_of_glue_owner,
1826                                     globals->arm_glue_size);
1827 #if 0
1828       memset (foo, test_char, (size_t) globals->arm_glue_size);
1829 #endif
1830
1831       s->_raw_size = s->_cooked_size = globals->arm_glue_size;
1832       s->contents = foo;
1833     }
1834
1835   if (globals->thumb_glue_size != 0)
1836     {
1837       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1838
1839       s = bfd_get_section_by_name
1840         (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1841
1842       BFD_ASSERT (s != NULL);
1843
1844       foo = (bfd_byte *) bfd_alloc (globals->bfd_of_glue_owner,
1845                                     globals->thumb_glue_size);
1846 #if 0
1847       memset (foo, test_char, (size_t) globals->thumb_glue_size);
1848 #endif
1849
1850       s->_raw_size = s->_cooked_size = globals->thumb_glue_size;
1851       s->contents = foo;
1852     }
1853
1854   return true;
1855 }
1856
1857 static void
1858 record_arm_to_thumb_glue (info, h)
1859      struct bfd_link_info *        info;
1860      struct coff_link_hash_entry * h;
1861 {
1862   const char *                      name = h->root.root.string;
1863   register asection *               s;
1864   char *                            tmp_name;
1865   struct coff_link_hash_entry *     myh;
1866   struct coff_arm_link_hash_table * globals;
1867   bfd_vma val;
1868   bfd_size_type amt;
1869
1870   globals = coff_arm_hash_table (info);
1871
1872   BFD_ASSERT (globals != NULL);
1873   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1874
1875   s = bfd_get_section_by_name
1876     (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1877
1878   BFD_ASSERT (s != NULL);
1879
1880   amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1881   tmp_name = (char *) bfd_malloc (amt);
1882
1883   BFD_ASSERT (tmp_name);
1884
1885   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1886
1887   myh = coff_link_hash_lookup
1888     (coff_hash_table (info), tmp_name, false, false, true);
1889
1890   if (myh != NULL)
1891     {
1892       free (tmp_name);
1893       return; /* we've already seen this guy */
1894     }
1895
1896   /* The only trick here is using globals->arm_glue_size as the value. Even
1897      though the section isn't allocated yet, this is where we will be putting
1898      it.  */
1899
1900   val = globals->arm_glue_size + 1;
1901   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1902                                 BSF_GLOBAL, s, val, NULL, true, false,
1903                                 (struct bfd_link_hash_entry **) & myh);
1904
1905   free (tmp_name);
1906
1907   globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
1908
1909   return;
1910 }
1911
1912 static void
1913 record_thumb_to_arm_glue (info, h)
1914      struct bfd_link_info *        info;
1915      struct coff_link_hash_entry * h;
1916 {
1917   const char *                       name = h->root.root.string;
1918   register asection *                s;
1919   char *                             tmp_name;
1920   struct coff_link_hash_entry *      myh;
1921   struct coff_arm_link_hash_table *  globals;
1922   bfd_vma val;
1923   bfd_size_type amt;
1924
1925   globals = coff_arm_hash_table (info);
1926
1927   BFD_ASSERT (globals != NULL);
1928   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1929
1930   s = bfd_get_section_by_name
1931     (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1932
1933   BFD_ASSERT (s != NULL);
1934
1935   amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1936   tmp_name = (char *) bfd_malloc (amt);
1937
1938   BFD_ASSERT (tmp_name);
1939
1940   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1941
1942   myh = coff_link_hash_lookup
1943     (coff_hash_table (info), tmp_name, false, false, true);
1944
1945   if (myh != NULL)
1946     {
1947       free (tmp_name);
1948       return; /* we've already seen this guy */
1949     }
1950
1951   val = globals->thumb_glue_size + 1;
1952   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1953                                 BSF_GLOBAL, s, val, NULL, true, false,
1954                                 (struct bfd_link_hash_entry **) &myh);
1955
1956   /* If we mark it 'thumb', the disassembler will do a better job.  */
1957   myh->class = C_THUMBEXTFUNC;
1958
1959   free (tmp_name);
1960
1961   /* Allocate another symbol to mark where we switch to arm mode.  */
1962
1963 #define CHANGE_TO_ARM "__%s_change_to_arm"
1964 #define BACK_FROM_ARM "__%s_back_from_arm"
1965
1966   amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1;
1967   tmp_name = (char *) bfd_malloc (amt);
1968
1969   BFD_ASSERT (tmp_name);
1970
1971   sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
1972
1973   myh = NULL;
1974   val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
1975   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1976                                 BSF_LOCAL, s, val, NULL, true, false,
1977                                 (struct bfd_link_hash_entry **) & myh);
1978
1979   free (tmp_name);
1980
1981   globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
1982
1983   return;
1984 }
1985
1986 /* Select a BFD to be used to hold the sections used by the glue code.
1987    This function is called from the linker scripts in ld/emultempl/
1988    {armcoff/pe}.em  */
1989
1990 boolean
1991 bfd_arm_get_bfd_for_interworking (abfd, info)
1992      bfd *                  abfd;
1993      struct bfd_link_info * info;
1994 {
1995   struct coff_arm_link_hash_table * globals;
1996   flagword                          flags;
1997   asection *                        sec;
1998
1999   /* If we are only performing a partial link do not bother
2000      getting a bfd to hold the glue.  */
2001   if (info->relocateable)
2002     return true;
2003
2004   globals = coff_arm_hash_table (info);
2005
2006   BFD_ASSERT (globals != NULL);
2007
2008   if (globals->bfd_of_glue_owner != NULL)
2009     return true;
2010
2011   sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
2012
2013   if (sec == NULL)
2014     {
2015       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
2016
2017       sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
2018
2019       if (sec == NULL
2020           || ! bfd_set_section_flags (abfd, sec, flags)
2021           || ! bfd_set_section_alignment (abfd, sec, 2))
2022         return false;
2023     }
2024
2025   sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
2026
2027   if (sec == NULL)
2028     {
2029       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
2030
2031       sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
2032
2033       if (sec == NULL
2034           || ! bfd_set_section_flags (abfd, sec, flags)
2035           || ! bfd_set_section_alignment (abfd, sec, 2))
2036         return false;
2037     }
2038
2039   /* Save the bfd for later use.  */
2040   globals->bfd_of_glue_owner = abfd;
2041
2042   return true;
2043 }
2044
2045 boolean
2046 bfd_arm_process_before_allocation (abfd, info, support_old_code)
2047      bfd *                   abfd;
2048      struct bfd_link_info *  info;
2049      int                     support_old_code;
2050 {
2051   asection * sec;
2052   struct coff_arm_link_hash_table * globals;
2053
2054   /* If we are only performing a partial link do not bother
2055      to construct any glue.  */
2056   if (info->relocateable)
2057     return true;
2058
2059   /* Here we have a bfd that is to be included on the link.  We have a hook
2060      to do reloc rummaging, before section sizes are nailed down.  */
2061
2062   _bfd_coff_get_external_symbols (abfd);
2063
2064   globals = coff_arm_hash_table (info);
2065
2066   BFD_ASSERT (globals != NULL);
2067   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
2068
2069   globals->support_old_code = support_old_code;
2070
2071   /* Rummage around all the relocs and map the glue vectors.  */
2072   sec = abfd->sections;
2073
2074   if (sec == NULL)
2075     return true;
2076
2077   for (; sec != NULL; sec = sec->next)
2078     {
2079       struct internal_reloc * i;
2080       struct internal_reloc * rel;
2081
2082       if (sec->reloc_count == 0)
2083         continue;
2084
2085       /* Load the relocs.  */
2086       /* FIXME: there may be a storage leak here.  */
2087
2088       i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0);
2089
2090       BFD_ASSERT (i != 0);
2091
2092       for (rel = i; rel < i + sec->reloc_count; ++rel)
2093         {
2094           unsigned short                 r_type  = rel->r_type;
2095           long                           symndx;
2096           struct coff_link_hash_entry *  h;
2097
2098           symndx = rel->r_symndx;
2099
2100           /* If the relocation is not against a symbol it cannot concern us.  */
2101           if (symndx == -1)
2102             continue;
2103
2104           /* If the index is outside of the range of our table, something has gone wrong.  */
2105           if (symndx >= obj_conv_table_size (abfd))
2106             {
2107               _bfd_error_handler (_("%s: illegal symbol index in reloc: %d"),
2108                                   bfd_archive_filename (abfd), symndx);
2109               continue;
2110             }
2111
2112           h = obj_coff_sym_hashes (abfd)[symndx];
2113
2114           /* If the relocation is against a static symbol it must be within
2115              the current section and so cannot be a cross ARM/Thumb relocation.  */
2116           if (h == NULL)
2117             continue;
2118
2119           switch (r_type)
2120             {
2121             case ARM_26:
2122               /* This one is a call from arm code.  We need to look up
2123                  the target of the call. If it is a thumb target, we
2124                  insert glue.  */
2125
2126               if (h->class == C_THUMBEXTFUNC)
2127                 record_arm_to_thumb_glue (info, h);
2128               break;
2129
2130 #ifndef ARM_WINCE
2131             case ARM_THUMB23:
2132               /* This one is a call from thumb code.  We used to look
2133                  for ARM_THUMB9 and ARM_THUMB12 as well.  We need to look
2134                  up the target of the call. If it is an arm target, we
2135                  insert glue.  If the symbol does not exist it will be
2136                  given a class of C_EXT and so we will generate a stub
2137                  for it.  This is not really a problem, since the link
2138                  is doomed anyway.  */
2139
2140               switch (h->class)
2141                 {
2142                 case C_EXT:
2143                 case C_STAT:
2144                 case C_LABEL:
2145                   record_thumb_to_arm_glue (info, h);
2146                   break;
2147                 default:
2148                   ;
2149                 }
2150               break;
2151 #endif
2152
2153             default:
2154               break;
2155             }
2156         }
2157     }
2158
2159   return true;
2160 }
2161
2162 #endif /* ! defined (COFF_IMAGE_WITH_PE) */
2163
2164 #define coff_bfd_reloc_type_lookup              coff_arm_reloc_type_lookup
2165 #define coff_relocate_section                   coff_arm_relocate_section
2166 #define coff_bfd_is_local_label_name            coff_arm_is_local_label_name
2167 #define coff_adjust_symndx                      coff_arm_adjust_symndx
2168 #define coff_link_output_has_begun              coff_arm_link_output_has_begun
2169 #define coff_final_link_postscript              coff_arm_final_link_postscript
2170 #define coff_bfd_merge_private_bfd_data         coff_arm_merge_private_bfd_data
2171 #define coff_bfd_print_private_bfd_data         coff_arm_print_private_bfd_data
2172 #define coff_bfd_set_private_flags              _bfd_coff_arm_set_private_flags
2173 #define coff_bfd_copy_private_bfd_data          coff_arm_copy_private_bfd_data
2174 #define coff_bfd_link_hash_table_create         coff_arm_link_hash_table_create
2175
2176 /* When doing a relocateable link, we want to convert ARM26 relocs
2177    into ARM26D relocs.  */
2178
2179 static boolean
2180 coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp)
2181      bfd *obfd ATTRIBUTE_UNUSED;
2182      struct bfd_link_info *info ATTRIBUTE_UNUSED;
2183      bfd *ibfd;
2184      asection *sec;
2185      struct internal_reloc *irel;
2186      boolean *adjustedp;
2187 {
2188   if (irel->r_type == 3)
2189     {
2190       struct coff_link_hash_entry *h;
2191
2192       h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
2193       if (h != NULL
2194           && (h->root.type == bfd_link_hash_defined
2195               || h->root.type == bfd_link_hash_defweak)
2196           && h->root.u.def.section->output_section == sec->output_section)
2197         irel->r_type = 7;
2198     }
2199   *adjustedp = false;
2200   return true;
2201 }
2202
2203 /* Called when merging the private data areas of two BFDs.
2204    This is important as it allows us to detect if we are
2205    attempting to merge binaries compiled for different ARM
2206    targets, eg different CPUs or differents APCS's.     */
2207
2208 static boolean
2209 coff_arm_merge_private_bfd_data (ibfd, obfd)
2210      bfd *   ibfd;
2211      bfd *   obfd;
2212 {
2213   BFD_ASSERT (ibfd != NULL && obfd != NULL);
2214
2215   if (ibfd == obfd)
2216     return true;
2217
2218   /* If the two formats are different we cannot merge anything.
2219      This is not an error, since it is permissable to change the
2220      input and output formats.  */
2221   if (   ibfd->xvec->flavour != bfd_target_coff_flavour
2222       || obfd->xvec->flavour != bfd_target_coff_flavour)
2223     return true;
2224
2225   /* Verify that the APCS is the same for the two BFDs */
2226   if (APCS_SET (ibfd))
2227     {
2228       if (APCS_SET (obfd))
2229         {
2230           /* If the src and dest have different APCS flag bits set, fail.  */
2231           if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
2232             {
2233               _bfd_error_handler
2234                 /* xgettext: c-format */
2235                 (_("%s: ERROR: compiled for APCS-%d whereas target %s uses APCS-%d"),
2236                  bfd_archive_filename (ibfd), APCS_26_FLAG (ibfd) ? 26 : 32,
2237                  bfd_get_filename (obfd), APCS_26_FLAG (obfd) ? 26 : 32
2238                  );
2239
2240               bfd_set_error (bfd_error_wrong_format);
2241               return false;
2242             }
2243
2244           if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
2245             {
2246               const char *msg;
2247
2248               if (APCS_FLOAT_FLAG (ibfd))
2249                 /* xgettext: c-format */
2250                 msg = _("%s: ERROR: passes floats in float registers whereas target %s uses integer registers");
2251               else
2252                 /* xgettext: c-format */
2253                 msg = _("%s: ERROR: passes floats in integer registers whereas target %s uses float registers");
2254
2255               _bfd_error_handler (msg, bfd_archive_filename (ibfd),
2256                                   bfd_get_filename (obfd));
2257
2258               bfd_set_error (bfd_error_wrong_format);
2259               return false;
2260             }
2261
2262           if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
2263             {
2264               const char * msg;
2265
2266               if (PIC_FLAG (ibfd))
2267                 /* xgettext: c-format */
2268                 msg = _("%s: ERROR: compiled as position independent code, whereas target %s is absolute position");
2269               else
2270                 /* xgettext: c-format */
2271                 msg = _("%s: ERROR: compiled as absolute position code, whereas target %s is position independent");
2272               _bfd_error_handler (msg, bfd_archive_filename (ibfd),
2273                                   bfd_get_filename (obfd));
2274
2275               bfd_set_error (bfd_error_wrong_format);
2276               return false;
2277             }
2278         }
2279       else
2280         {
2281           SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd));
2282
2283           /* Set up the arch and fields as well as these are probably wrong.  */
2284           bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2285         }
2286     }
2287
2288   /* Check the interworking support.  */
2289   if (INTERWORK_SET (ibfd))
2290     {
2291       if (INTERWORK_SET (obfd))
2292         {
2293           /* If the src and dest differ in their interworking issue a warning.  */
2294           if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
2295             {
2296               const char * msg;
2297
2298               if (INTERWORK_FLAG (ibfd))
2299                 /* xgettext: c-format */
2300                 msg = _("Warning: %s supports interworking, whereas %s does not.");
2301               else
2302                 /* xgettext: c-format */
2303                 msg = _("Warning: %s does not support interworking, whereas %s does.");
2304
2305               _bfd_error_handler (msg, bfd_archive_filename (ibfd),
2306                                   bfd_get_filename (obfd));
2307             }
2308         }
2309       else
2310         {
2311           SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
2312         }
2313     }
2314
2315   return true;
2316 }
2317
2318 /* Display the flags field.  */
2319
2320 static boolean
2321 coff_arm_print_private_bfd_data (abfd, ptr)
2322      bfd *   abfd;
2323      PTR     ptr;
2324 {
2325   FILE * file = (FILE *) ptr;
2326
2327   BFD_ASSERT (abfd != NULL && ptr != NULL);
2328
2329   /* xgettext:c-format */
2330   fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
2331
2332   if (APCS_SET (abfd))
2333     {
2334       /* xgettext: APCS is ARM Prodecure Call Standard, it should not be translated.  */
2335       fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32);
2336
2337       if (APCS_FLOAT_FLAG (abfd))
2338         fprintf (file, _(" [floats passed in float registers]"));
2339       else
2340         fprintf (file, _(" [floats passed in integer registers]"));
2341
2342       if (PIC_FLAG (abfd))
2343         fprintf (file, _(" [position independent]"));
2344       else
2345         fprintf (file, _(" [absolute position]"));
2346     }
2347
2348   if (! INTERWORK_SET (abfd))
2349     fprintf (file, _(" [interworking flag not initialised]"));
2350   else if (INTERWORK_FLAG (abfd))
2351     fprintf (file, _(" [interworking supported]"));
2352   else
2353     fprintf (file, _(" [interworking not supported]"));
2354
2355   fputc ('\n', file);
2356
2357   return true;
2358 }
2359
2360 /* Copies the given flags into the coff_tdata.flags field.
2361    Typically these flags come from the f_flags[] field of
2362    the COFF filehdr structure, which contains important,
2363    target specific information.
2364    Note: Although this function is static, it is explicitly
2365    called from both coffcode.h and peicode.h.  */
2366
2367 static boolean
2368 _bfd_coff_arm_set_private_flags (abfd, flags)
2369         bfd *      abfd;
2370         flagword   flags;
2371 {
2372   flagword flag;
2373
2374   BFD_ASSERT (abfd != NULL);
2375
2376   flag = (flags & F_APCS26) ? F_APCS_26 : 0;
2377
2378   /* Make sure that the APCS field has not been initialised to the opposite
2379      value.  */
2380   if (APCS_SET (abfd)
2381       && (   (APCS_26_FLAG    (abfd) != flag)
2382           || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
2383           || (PIC_FLAG        (abfd) != (flags & F_PIC))
2384           ))
2385     return false;
2386
2387   flag |= (flags & (F_APCS_FLOAT | F_PIC));
2388
2389   SET_APCS_FLAGS (abfd, flag);
2390
2391   flag = (flags & F_INTERWORK);
2392
2393   /* If the BFD has already had its interworking flag set, but it
2394      is different from the value that we have been asked to set,
2395      then assume that that merged code will not support interworking
2396      and set the flag accordingly.  */
2397   if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
2398     {
2399       if (flag)
2400         /* xgettext: c-format */
2401         _bfd_error_handler (_("Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"),
2402                             bfd_archive_filename (abfd));
2403       else
2404         /* xgettext: c-format */
2405         _bfd_error_handler (_("Warning: Clearing the interworking flag of %s due to outside request"),
2406                             bfd_archive_filename (abfd));
2407       flag = 0;
2408     }
2409
2410   SET_INTERWORK_FLAG (abfd, flag);
2411
2412   return true;
2413 }
2414
2415 /* Copy the important parts of the target specific data
2416    from one instance of a BFD to another.  */
2417
2418 static boolean
2419 coff_arm_copy_private_bfd_data (src, dest)
2420      bfd *  src;
2421      bfd *  dest;
2422 {
2423   BFD_ASSERT (src != NULL && dest != NULL);
2424
2425   if (src == dest)
2426     return true;
2427
2428   /* If the destination is not in the same format as the source, do not do
2429      the copy.  */
2430   if (src->xvec != dest->xvec)
2431     return true;
2432
2433   /* copy the flags field */
2434   if (APCS_SET (src))
2435     {
2436       if (APCS_SET (dest))
2437         {
2438           /* If the src and dest have different APCS flag bits set, fail.  */
2439           if (APCS_26_FLAG (dest) != APCS_26_FLAG (src))
2440             return false;
2441
2442           if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
2443             return false;
2444
2445           if (PIC_FLAG (dest) != PIC_FLAG (src))
2446             return false;
2447         }
2448       else
2449         SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src)
2450                         | PIC_FLAG (src));
2451     }
2452
2453   if (INTERWORK_SET (src))
2454     {
2455       if (INTERWORK_SET (dest))
2456         {
2457           /* If the src and dest have different interworking flags then turn
2458              off the interworking bit.  */
2459           if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src))
2460             {
2461               if (INTERWORK_FLAG (dest))
2462                 {
2463                   /* xgettext:c-format */
2464                   _bfd_error_handler (("\
2465 Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"),
2466                                       bfd_get_filename (dest),
2467                                       bfd_archive_filename (src));
2468                 }
2469
2470               SET_INTERWORK_FLAG (dest, 0);
2471             }
2472         }
2473       else
2474         {
2475           SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
2476         }
2477     }
2478
2479   return true;
2480 }
2481
2482 /* Note:  the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
2483    *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h.  */
2484 #define LOCAL_LABEL_PREFIX ""
2485 #ifndef USER_LABEL_PREFIX
2486 #define USER_LABEL_PREFIX "_"
2487 #endif
2488
2489 /* Like _bfd_coff_is_local_label_name, but
2490    a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
2491       non-local.
2492    b) Allow other prefixes than ".", e.g. an empty prefix would cause all
2493       labels of the form Lxxx to be stripped.  */
2494 static boolean
2495 coff_arm_is_local_label_name (abfd, name)
2496      bfd *        abfd ATTRIBUTE_UNUSED;
2497      const char * name;
2498 {
2499 #ifdef USER_LABEL_PREFIX
2500   if (USER_LABEL_PREFIX[0] != 0)
2501     {
2502       if (strncmp (name, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)) == 0)
2503         return false;
2504     }
2505 #endif
2506
2507 #ifdef LOCAL_LABEL_PREFIX
2508   /* If there is a prefix for local labels then look for this.
2509      If the prefix exists, but it is empty, then ignore the test.  */
2510
2511   if (LOCAL_LABEL_PREFIX[0] != 0)
2512     {
2513       size_t len = strlen (LOCAL_LABEL_PREFIX);
2514
2515       if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0)
2516         return false;
2517
2518       /* Perform the checks below for the rest of the name.  */
2519       name += len;
2520     }
2521 #endif
2522
2523   return name[0] == 'L';
2524 }
2525
2526 /* This piece of machinery exists only to guarantee that the bfd that holds
2527    the glue section is written last.
2528
2529    This does depend on bfd_make_section attaching a new section to the
2530    end of the section list for the bfd.
2531
2532    krk@cygnus.com  */
2533
2534 static boolean
2535 coff_arm_link_output_has_begun (sub, info)
2536      bfd * sub;
2537      struct coff_final_link_info * info;
2538 {
2539   return (sub->output_has_begun
2540           || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner);
2541 }
2542
2543 static boolean
2544 coff_arm_final_link_postscript (abfd, pfinfo)
2545      bfd * abfd ATTRIBUTE_UNUSED;
2546      struct coff_final_link_info * pfinfo;
2547 {
2548   struct coff_arm_link_hash_table * globals;
2549
2550   globals = coff_arm_hash_table (pfinfo->info);
2551
2552   BFD_ASSERT (globals != NULL);
2553
2554   if (globals->bfd_of_glue_owner != NULL)
2555     {
2556       if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner))
2557         return false;
2558
2559       globals->bfd_of_glue_owner->output_has_begun = true;
2560     }
2561
2562   return true;
2563 }
2564
2565 #include "coffcode.h"
2566
2567 #ifndef TARGET_LITTLE_SYM
2568 #define TARGET_LITTLE_SYM armcoff_little_vec
2569 #endif
2570 #ifndef TARGET_LITTLE_NAME
2571 #define TARGET_LITTLE_NAME "coff-arm-little"
2572 #endif
2573 #ifndef TARGET_BIG_SYM
2574 #define TARGET_BIG_SYM armcoff_big_vec
2575 #endif
2576 #ifndef TARGET_BIG_NAME
2577 #define TARGET_BIG_NAME "coff-arm-big"
2578 #endif
2579
2580 #ifndef TARGET_UNDERSCORE
2581 #define TARGET_UNDERSCORE 0
2582 #endif
2583
2584 #ifndef EXTRA_S_FLAGS
2585 #ifdef COFF_WITH_PE
2586 #define EXTRA_S_FLAGS (SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
2587 #else
2588 #define EXTRA_S_FLAGS 0
2589 #endif
2590 #endif
2591
2592 /* Forward declaration for use initialising alternative_target field.  */
2593 extern const bfd_target TARGET_BIG_SYM ;
2594
2595 /* Target vectors.  */
2596 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM)
2597 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM)