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