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