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