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