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