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
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
76typedef enum {bunknown, b9, b12, b23} thumb_pcrel_branchtype;
77/* Some typedefs for holding instructions.  */
78typedef unsigned long int insn32;
79typedef 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
94static bfd_reloc_status_type
95coff_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
198static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
199  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
200static bfd_reloc_status_type aoutarm_fix_pcrel_26
201  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
202static bfd_reloc_status_type coff_thumb_pcrel_12
203  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
204#ifndef ARM_WINCE
205static bfd_reloc_status_type coff_thumb_pcrel_9
206  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
207static bfd_reloc_status_type coff_thumb_pcrel_23
208  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
209#endif
210
211static 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
508static bfd_boolean
509in_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
524static reloc_howto_type *
525coff_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	  asection *sec;
553	  int i;
554
555	  /* Sigh, the only way to get the section to offset against
556	     is to find it the hard way.  */
557
558	  for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
559	    sec = sec->next;
560
561	  osect_vma = sec->output_section->vma;
562	}
563
564      *addendp -= osect_vma;
565    }
566#endif
567
568  return howto;
569}
570
571/* Used by the assembler.  */
572
573static bfd_reloc_status_type
574aoutarm_fix_pcrel_26_done (bfd *abfd ATTRIBUTE_UNUSED,
575			   arelent *reloc_entry ATTRIBUTE_UNUSED,
576			   asymbol *symbol ATTRIBUTE_UNUSED,
577			   void * data ATTRIBUTE_UNUSED,
578			   asection *input_section ATTRIBUTE_UNUSED,
579			   bfd *output_bfd ATTRIBUTE_UNUSED,
580			   char **error_message ATTRIBUTE_UNUSED)
581{
582  /* This is dead simple at present.  */
583  return bfd_reloc_ok;
584}
585
586/* Used by the assembler.  */
587
588static bfd_reloc_status_type
589aoutarm_fix_pcrel_26 (bfd *abfd,
590		      arelent *reloc_entry,
591		      asymbol *symbol,
592		      void * data,
593		      asection *input_section,
594		      bfd *output_bfd,
595		      char **error_message ATTRIBUTE_UNUSED)
596{
597  bfd_vma relocation;
598  bfd_size_type addr = reloc_entry->address;
599  long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
600  bfd_reloc_status_type flag = bfd_reloc_ok;
601
602  /* If this is an undefined symbol, return error.  */
603  if (symbol->section == &bfd_und_section
604      && (symbol->flags & BSF_WEAK) == 0)
605    return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
606
607  /* If the sections are different, and we are doing a partial relocation,
608     just ignore it for now.  */
609  if (symbol->section->name != input_section->name
610      && output_bfd != (bfd *)NULL)
611    return bfd_reloc_continue;
612
613  relocation = (target & 0x00ffffff) << 2;
614  relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend.  */
615  relocation += symbol->value;
616  relocation += symbol->section->output_section->vma;
617  relocation += symbol->section->output_offset;
618  relocation += reloc_entry->addend;
619  relocation -= input_section->output_section->vma;
620  relocation -= input_section->output_offset;
621  relocation -= addr;
622
623  if (relocation & 3)
624    return bfd_reloc_overflow;
625
626  /* Check for overflow.  */
627  if (relocation & 0x02000000)
628    {
629      if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
630	flag = bfd_reloc_overflow;
631    }
632  else if (relocation & ~(bfd_vma) 0x03ffffff)
633    flag = bfd_reloc_overflow;
634
635  target &= ~0x00ffffff;
636  target |= (relocation >> 2) & 0x00ffffff;
637  bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
638
639  /* Now the ARM magic... Change the reloc type so that it is marked as done.
640     Strictly this is only necessary if we are doing a partial relocation.  */
641  reloc_entry->howto = &aoutarm_std_reloc_howto[ARM_26D];
642
643  return flag;
644}
645
646static bfd_reloc_status_type
647coff_thumb_pcrel_common (bfd *abfd,
648			 arelent *reloc_entry,
649			 asymbol *symbol,
650			 void * data,
651			 asection *input_section,
652			 bfd *output_bfd,
653			 char **error_message ATTRIBUTE_UNUSED,
654			 thumb_pcrel_branchtype btype)
655{
656  bfd_vma relocation = 0;
657  bfd_size_type addr = reloc_entry->address;
658  long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
659  bfd_reloc_status_type flag = bfd_reloc_ok;
660  bfd_vma dstmsk;
661  bfd_vma offmsk;
662  bfd_vma signbit;
663
664  /* NOTE: This routine is currently used by GAS, but not by the link
665     phase.  */
666  switch (btype)
667    {
668    case b9:
669      dstmsk  = 0x000000ff;
670      offmsk  = 0x000001fe;
671      signbit = 0x00000100;
672      break;
673
674    case b12:
675      dstmsk  = 0x000007ff;
676      offmsk  = 0x00000ffe;
677      signbit = 0x00000800;
678      break;
679
680    case b23:
681      dstmsk  = 0x07ff07ff;
682      offmsk  = 0x007fffff;
683      signbit = 0x00400000;
684      break;
685
686    default:
687      abort ();
688    }
689
690  /* If this is an undefined symbol, return error.  */
691  if (symbol->section == &bfd_und_section
692      && (symbol->flags & BSF_WEAK) == 0)
693    return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
694
695  /* If the sections are different, and we are doing a partial relocation,
696     just ignore it for now.  */
697  if (symbol->section->name != input_section->name
698      && output_bfd != (bfd *)NULL)
699    return bfd_reloc_continue;
700
701  switch (btype)
702    {
703    case b9:
704    case b12:
705      relocation = ((target & dstmsk) << 1);
706      break;
707
708    case b23:
709      if (bfd_big_endian (abfd))
710	relocation = ((target & 0x7ff) << 1)  | ((target & 0x07ff0000) >> 4);
711      else
712	relocation = ((target & 0x7ff) << 12) | ((target & 0x07ff0000) >> 15);
713      break;
714
715    default:
716      abort ();
717    }
718
719  relocation = (relocation ^ signbit) - signbit; /* Sign extend.  */
720  relocation += symbol->value;
721  relocation += symbol->section->output_section->vma;
722  relocation += symbol->section->output_offset;
723  relocation += reloc_entry->addend;
724  relocation -= input_section->output_section->vma;
725  relocation -= input_section->output_offset;
726  relocation -= addr;
727
728  if (relocation & 1)
729    return bfd_reloc_overflow;
730
731  /* Check for overflow.  */
732  if (relocation & signbit)
733    {
734      if ((relocation & ~offmsk) != ~offmsk)
735	flag = bfd_reloc_overflow;
736    }
737  else if (relocation & ~offmsk)
738    flag = bfd_reloc_overflow;
739
740  target &= ~dstmsk;
741  switch (btype)
742   {
743   case b9:
744   case b12:
745     target |= (relocation >> 1);
746     break;
747
748   case b23:
749     if (bfd_big_endian (abfd))
750       target |= (((relocation & 0xfff) >> 1)
751		  | ((relocation << 4)  & 0x07ff0000));
752     else
753       target |= (((relocation & 0xffe) << 15)
754		  | ((relocation >> 12) & 0x7ff));
755     break;
756
757   default:
758     abort ();
759   }
760
761  bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
762
763  /* Now the ARM magic... Change the reloc type so that it is marked as done.
764     Strictly this is only necessary if we are doing a partial relocation.  */
765  reloc_entry->howto = & aoutarm_std_reloc_howto [ARM_26D];
766
767  /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations.  */
768  return flag;
769}
770
771#ifndef ARM_WINCE
772static bfd_reloc_status_type
773coff_thumb_pcrel_23 (bfd *abfd,
774		     arelent *reloc_entry,
775		     asymbol *symbol,
776		     void * data,
777		     asection *input_section,
778		     bfd *output_bfd,
779		     char **error_message)
780{
781  return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
782                                  input_section, output_bfd, error_message,
783				  b23);
784}
785
786static bfd_reloc_status_type
787coff_thumb_pcrel_9 (bfd *abfd,
788		    arelent *reloc_entry,
789		    asymbol *symbol,
790		    void * data,
791		    asection *input_section,
792		    bfd *output_bfd,
793		    char **error_message)
794{
795  return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
796                                  input_section, output_bfd, error_message,
797				  b9);
798}
799#endif /* not ARM_WINCE */
800
801static bfd_reloc_status_type
802coff_thumb_pcrel_12 (bfd *abfd,
803		     arelent *reloc_entry,
804		     asymbol *symbol,
805		     void * data,
806		     asection *input_section,
807		     bfd *output_bfd,
808		     char **error_message)
809{
810  return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
811                                  input_section, output_bfd, error_message,
812				  b12);
813}
814
815static const struct reloc_howto_struct *
816coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
817{
818#define ASTD(i,j)       case i: return aoutarm_std_reloc_howto + j
819
820  if (code == BFD_RELOC_CTOR)
821    switch (bfd_get_arch_info (abfd)->bits_per_address)
822      {
823      case 32:
824        code = BFD_RELOC_32;
825        break;
826      default:
827	return NULL;
828      }
829
830  switch (code)
831    {
832#ifdef ARM_WINCE
833      ASTD (BFD_RELOC_32,                   ARM_32);
834      ASTD (BFD_RELOC_RVA,                  ARM_RVA32);
835      ASTD (BFD_RELOC_ARM_PCREL_BRANCH,     ARM_26);
836      ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
837      ASTD (BFD_RELOC_32_SECREL,            ARM_SECREL);
838#else
839      ASTD (BFD_RELOC_8,                    ARM_8);
840      ASTD (BFD_RELOC_16,                   ARM_16);
841      ASTD (BFD_RELOC_32,                   ARM_32);
842      ASTD (BFD_RELOC_ARM_PCREL_BRANCH,     ARM_26);
843      ASTD (BFD_RELOC_ARM_PCREL_BLX,        ARM_26);
844      ASTD (BFD_RELOC_8_PCREL,              ARM_DISP8);
845      ASTD (BFD_RELOC_16_PCREL,             ARM_DISP16);
846      ASTD (BFD_RELOC_32_PCREL,             ARM_DISP32);
847      ASTD (BFD_RELOC_RVA,                  ARM_RVA32);
848      ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9,  ARM_THUMB9);
849      ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
850      ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23);
851      ASTD (BFD_RELOC_THUMB_PCREL_BLX,      ARM_THUMB23);
852#endif
853    default: return NULL;
854    }
855}
856
857static reloc_howto_type *
858coff_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
859			    const char *r_name)
860{
861  unsigned int i;
862
863  for (i = 0;
864       i < (sizeof (aoutarm_std_reloc_howto)
865	    / sizeof (aoutarm_std_reloc_howto[0]));
866       i++)
867    if (aoutarm_std_reloc_howto[i].name != NULL
868	&& strcasecmp (aoutarm_std_reloc_howto[i].name, r_name) == 0)
869      return &aoutarm_std_reloc_howto[i];
870
871  return NULL;
872}
873
874#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER  2
875#define COFF_PAGE_SIZE                        0x1000
876
877/* Turn a howto into a reloc  nunmber.  */
878#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
879#define BADMAG(x)             ARMBADMAG(x)
880#define ARM                   1			/* Customize coffcode.h.  */
881
882#ifndef ARM_WINCE
883/* Make sure that the 'r_offset' field is copied properly
884   so that identical binaries will compare the same.  */
885#define SWAP_IN_RELOC_OFFSET	H_GET_32
886#define SWAP_OUT_RELOC_OFFSET	H_PUT_32
887#endif
888
889/* Extend the coff_link_hash_table structure with a few ARM specific fields.
890   This allows us to store global data here without actually creating any
891   global variables, which is a no-no in the BFD world.  */
892struct coff_arm_link_hash_table
893  {
894    /* The original coff_link_hash_table structure.  MUST be first field.  */
895    struct coff_link_hash_table	root;
896
897    /* The size in bytes of the section containing the Thumb-to-ARM glue.  */
898    bfd_size_type		thumb_glue_size;
899
900    /* The size in bytes of the section containing the ARM-to-Thumb glue.  */
901    bfd_size_type		arm_glue_size;
902
903    /* An arbitrary input BFD chosen to hold the glue sections.  */
904    bfd *			bfd_of_glue_owner;
905
906    /* Support interworking with old, non-interworking aware ARM code.  */
907    int 			support_old_code;
908};
909
910/* Get the ARM coff linker hash table from a link_info structure.  */
911#define coff_arm_hash_table(info) \
912  ((struct coff_arm_link_hash_table *) ((info)->hash))
913
914/* Create an ARM coff linker hash table.  */
915
916static struct bfd_link_hash_table *
917coff_arm_link_hash_table_create (bfd * abfd)
918{
919  struct coff_arm_link_hash_table * ret;
920  bfd_size_type amt = sizeof (struct coff_arm_link_hash_table);
921
922  ret = bfd_malloc (amt);
923  if (ret == NULL)
924    return NULL;
925
926  if (!_bfd_coff_link_hash_table_init (&ret->root,
927				       abfd,
928				       _bfd_coff_link_hash_newfunc,
929				       sizeof (struct coff_link_hash_entry)))
930    {
931      free (ret);
932      return NULL;
933    }
934
935  ret->thumb_glue_size   = 0;
936  ret->arm_glue_size     = 0;
937  ret->bfd_of_glue_owner = NULL;
938
939  return & ret->root.root;
940}
941
942static void
943arm_emit_base_file_entry (struct bfd_link_info *info,
944			  bfd *output_bfd,
945			  asection *input_section,
946			  bfd_vma reloc_offset)
947{
948  bfd_vma addr = reloc_offset
949                - input_section->vma
950                + input_section->output_offset
951                  + input_section->output_section->vma;
952
953  if (coff_data (output_bfd)->pe)
954     addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
955  fwrite (& addr, 1, sizeof (addr), (FILE *) info->base_file);
956
957}
958
959#ifndef ARM_WINCE
960/* The thumb form of a long branch is a bit finicky, because the offset
961   encoding is split over two fields, each in it's own instruction. They
962   can occur in any order. So given a thumb form of long branch, and an
963   offset, insert the offset into the thumb branch and return finished
964   instruction.
965
966   It takes two thumb instructions to encode the target address. Each has
967   11 bits to invest. The upper 11 bits are stored in one (identified by
968   H-0.. see below), the lower 11 bits are stored in the other (identified
969   by H-1).
970
971   Combine together and shifted left by 1 (it's a half word address) and
972   there you have it.
973
974     Op: 1111 = F,
975     H-0, upper address-0 = 000
976     Op: 1111 = F,
977     H-1, lower address-0 = 800
978
979   They can be ordered either way, but the arm tools I've seen always put
980   the lower one first. It probably doesn't matter. krk@cygnus.com
981
982   XXX:  Actually the order does matter.  The second instruction (H-1)
983   moves the computed address into the PC, so it must be the second one
984   in the sequence.  The problem, however is that whilst little endian code
985   stores the instructions in HI then LOW order, big endian code does the
986   reverse.  nickc@cygnus.com.  */
987
988#define LOW_HI_ORDER 0xF800F000
989#define HI_LOW_ORDER 0xF000F800
990
991static insn32
992insert_thumb_branch (insn32 br_insn, int rel_off)
993{
994  unsigned int low_bits;
995  unsigned int high_bits;
996
997  BFD_ASSERT ((rel_off & 1) != 1);
998
999  rel_off >>= 1;                              /* Half word aligned address.  */
1000  low_bits = rel_off & 0x000007FF;            /* The bottom 11 bits.  */
1001  high_bits = (rel_off >> 11) & 0x000007FF;   /* The top 11 bits.  */
1002
1003  if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1004    br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1005  else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1006    br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1007  else
1008    /* FIXME: the BFD library should never abort except for internal errors
1009       - it should return an error status.  */
1010    abort (); /* Error - not a valid branch instruction form.  */
1011
1012  return br_insn;
1013}
1014
1015
1016static struct coff_link_hash_entry *
1017find_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
1045static struct coff_link_hash_entry *
1046find_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
1085static const insn32 a2t1_ldr_insn       = 0xe59fc000;
1086static const insn32 a2t2_bx_r12_insn    = 0xe12fff1c;
1087static 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
1109static const insn16 t2a1_bx_pc_insn = 0x4778;
1110static const insn16 t2a2_noop_insn  = 0x46c0;
1111static const insn32 t2a3_b_insn     = 0xea000000;
1112
1113static const insn16 t2a1_push_insn  = 0xb540;
1114static const insn16 t2a2_ldr_insn   = 0x4e03;
1115static const insn16 t2a3_mov_insn   = 0x46fe;
1116static const insn16 t2a4_bx_insn    = 0x4730;
1117static const insn32 t2a5_pop_insn   = 0xe8bd4040;
1118static 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
1162static bfd_boolean
1163coff_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->class == C_THUMBSTATFUNC
1333		      || h->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, s,
1386                                                      my_offset + 8);
1387
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->class == C_EXT
1420		      || h->class == C_STAT
1421		      || h->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, output_bfd, s,
1491							  my_offset + 16);
1492			    }
1493			  else
1494			    {
1495			      bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn,
1496					  s->contents + my_offset);
1497
1498			      bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn,
1499					  s->contents + my_offset + 2);
1500
1501			      ret_offset =
1502		/* Address of destination of the stub.  */
1503				((bfd_signed_vma) h_val)
1504				- ((bfd_signed_vma)
1505		/* Offset from the start of the current section to the start of the stubs.  */
1506				   (s->output_offset
1507		/* Offset of the start of this stub from the start of the stubs.  */
1508				    + my_offset
1509		/* Address of the start of the current section.  */
1510				    + s->output_section->vma)
1511		/* The branch instruction is 4 bytes into the stub.  */
1512				   + 4
1513		/* ARM branches work from the pc of the instruction + 8.  */
1514				   + 8);
1515
1516			      bfd_put_32 (output_bfd,
1517					  (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1518					  s->contents + my_offset + 4);
1519
1520			    }
1521			}
1522
1523		      BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1524
1525		      /* Now go back and fix up the original BL insn to point
1526			 to here.  */
1527		      ret_offset =
1528			s->output_offset
1529			+ my_offset
1530			- (input_section->output_offset
1531			   + rel->r_vaddr)
1532			-4;
1533
1534		      tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1535					- input_section->vma);
1536
1537		      bfd_put_32 (output_bfd,
1538				  (bfd_vma) insert_thumb_branch (tmp,
1539								 ret_offset),
1540				  contents + rel->r_vaddr - input_section->vma);
1541
1542		      done = 1;
1543                    }
1544                }
1545#endif
1546            }
1547
1548          /* If the relocation type and destination symbol does not
1549             fall into one of the above categories, then we can just
1550             perform a direct link.  */
1551
1552	  if (done)
1553	    rstat = bfd_reloc_ok;
1554	  else
1555	    if (   h->root.type == bfd_link_hash_defined
1556		|| h->root.type == bfd_link_hash_defweak)
1557	    {
1558	      asection *sec;
1559
1560	      sec = h->root.u.def.section;
1561	      val = (h->root.u.def.value
1562		     + sec->output_section->vma
1563		     + sec->output_offset);
1564	      }
1565
1566	  else if (! info->relocatable)
1567	    {
1568	      if (! ((*info->callbacks->undefined_symbol)
1569		     (info, h->root.root.string, input_bfd, input_section,
1570		      rel->r_vaddr - input_section->vma, TRUE)))
1571		return FALSE;
1572	    }
1573	}
1574
1575      if (info->base_file)
1576	{
1577	  /* Emit a reloc if the backend thinks it needs it.  */
1578	  if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
1579            arm_emit_base_file_entry (info, output_bfd, input_section,
1580				      rel->r_vaddr);
1581	}
1582
1583      if (done)
1584	rstat = bfd_reloc_ok;
1585#ifndef ARM_WINCE
1586      /* Only perform this fix during the final link, not a relocatable link.  */
1587      else if (! info->relocatable
1588	       && howto->type == ARM_THUMB23)
1589        {
1590          /* This is pretty much a copy of what the default
1591             _bfd_final_link_relocate and _bfd_relocate_contents
1592             routines do to perform a relocation, with special
1593             processing for the split addressing of the Thumb BL
1594             instruction.  Again, it would probably be simpler adding a
1595             ThumbBRANCH23 specific macro expansion into the default
1596             code.  */
1597
1598          bfd_vma address = rel->r_vaddr - input_section->vma;
1599
1600	  if (address > high_address)
1601	    rstat = bfd_reloc_outofrange;
1602          else
1603            {
1604              bfd_vma relocation = val + addend;
1605	      int size = bfd_get_reloc_size (howto);
1606	      bfd_boolean overflow = FALSE;
1607	      bfd_byte *location = contents + address;
1608	      bfd_vma x = bfd_get_32 (input_bfd, location);
1609	      bfd_vma src_mask = 0x007FFFFE;
1610	      bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1611	      bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1612	      bfd_vma check;
1613	      bfd_signed_vma signed_check;
1614	      bfd_vma add;
1615	      bfd_signed_vma signed_add;
1616
1617	      BFD_ASSERT (size == 4);
1618
1619              /* howto->pc_relative should be TRUE for type 14 BRANCH23.  */
1620              relocation -= (input_section->output_section->vma
1621                             + input_section->output_offset);
1622
1623              /* howto->pcrel_offset should be TRUE for type 14 BRANCH23.  */
1624              relocation -= address;
1625
1626	      /* No need to negate the relocation with BRANCH23.  */
1627	      /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23.  */
1628	      /* howto->rightshift == 1 */
1629
1630	      /* Drop unwanted bits from the value we are relocating to.  */
1631	      check = relocation >> howto->rightshift;
1632
1633	      /* If this is a signed value, the rightshift just dropped
1634		 leading 1 bits (assuming twos complement).  */
1635	      if ((bfd_signed_vma) relocation >= 0)
1636		signed_check = check;
1637	      else
1638		signed_check = (check
1639				| ((bfd_vma) - 1
1640				   & ~((bfd_vma) - 1 >> howto->rightshift)));
1641
1642	      /* Get the value from the object file.  */
1643	      if (bfd_big_endian (input_bfd))
1644		add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
1645	      else
1646		add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
1647
1648	      /* Get the value from the object file with an appropriate sign.
1649		 The expression involving howto->src_mask isolates the upper
1650		 bit of src_mask.  If that bit is set in the value we are
1651		 adding, it is negative, and we subtract out that number times
1652		 two.  If src_mask includes the highest possible bit, then we
1653		 can not get the upper bit, but that does not matter since
1654		 signed_add needs no adjustment to become negative in that
1655		 case.  */
1656	      signed_add = add;
1657
1658	      if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
1659		signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
1660
1661	      /* howto->bitpos == 0 */
1662	      /* Add the value from the object file, shifted so that it is a
1663		 straight number.  */
1664	      signed_check += signed_add;
1665	      relocation   += signed_add;
1666
1667	      BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
1668
1669	      /* Assumes two's complement.  */
1670	      if (   signed_check > reloc_signed_max
1671		  || signed_check < reloc_signed_min)
1672		overflow = TRUE;
1673
1674	      /* Put the relocation into the correct bits.
1675		 For a BLX instruction, make sure that the relocation is rounded up
1676		 to a word boundary.  This follows the semantics of the instruction
1677		 which specifies that bit 1 of the target address will come from bit
1678		 1 of the base address.  */
1679	      if (bfd_big_endian (input_bfd))
1680	        {
1681		  if ((x & 0x1800) == 0x0800 && (relocation & 0x02))
1682		    relocation += 2;
1683		  relocation = (((relocation & 0xffe) >> 1)  | ((relocation << 4) & 0x07ff0000));
1684		}
1685	      else
1686	        {
1687		  if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02))
1688		    relocation += 2;
1689		  relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1690		}
1691
1692	      /* Add the relocation to the correct bits of X.  */
1693	      x = ((x & ~howto->dst_mask) | relocation);
1694
1695	      /* Put the relocated value back in the object file.  */
1696	      bfd_put_32 (input_bfd, x, location);
1697
1698	      rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
1699            }
1700        }
1701#endif
1702      else
1703        if (info->relocatable && ! howto->partial_inplace)
1704            rstat = bfd_reloc_ok;
1705        else
1706	  rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
1707					    contents,
1708					    rel->r_vaddr - input_section->vma,
1709					    val, addend);
1710      /* Only perform this fix during the final link, not a relocatable link.  */
1711      if (! info->relocatable
1712	  && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
1713	{
1714	  /* Determine if we need to set the bottom bit of a relocated address
1715	     because the address is the address of a Thumb code symbol.  */
1716	  int patchit = FALSE;
1717
1718	  if (h != NULL
1719	      && (   h->class == C_THUMBSTATFUNC
1720		  || h->class == C_THUMBEXTFUNC))
1721	    {
1722	      patchit = TRUE;
1723	    }
1724	  else if (sym != NULL
1725		   && sym->n_scnum > N_UNDEF)
1726	    {
1727	      /* No hash entry - use the symbol instead.  */
1728	      if (   sym->n_sclass == C_THUMBSTATFUNC
1729		  || sym->n_sclass == C_THUMBEXTFUNC)
1730		patchit = TRUE;
1731	    }
1732
1733	  if (patchit)
1734	    {
1735	      bfd_byte * location = contents + rel->r_vaddr - input_section->vma;
1736	      bfd_vma    x        = bfd_get_32 (input_bfd, location);
1737
1738	      bfd_put_32 (input_bfd, x | 1, location);
1739	    }
1740	}
1741
1742      switch (rstat)
1743	{
1744	default:
1745	  abort ();
1746	case bfd_reloc_ok:
1747	  break;
1748	case bfd_reloc_outofrange:
1749	  (*_bfd_error_handler)
1750	    (_("%B: bad reloc address 0x%lx in section `%A'"),
1751	     input_bfd, input_section, (unsigned long) rel->r_vaddr);
1752	  return FALSE;
1753	case bfd_reloc_overflow:
1754	  {
1755	    const char *name;
1756	    char buf[SYMNMLEN + 1];
1757
1758	    if (symndx == -1)
1759	      name = "*ABS*";
1760	    else if (h != NULL)
1761	      name = NULL;
1762	    else
1763	      {
1764		name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1765		if (name == NULL)
1766		  return FALSE;
1767	      }
1768
1769	    if (! ((*info->callbacks->reloc_overflow)
1770		   (info, (h ? &h->root : NULL), name, howto->name,
1771		    (bfd_vma) 0, input_bfd, input_section,
1772		    rel->r_vaddr - input_section->vma)))
1773	      return FALSE;
1774	  }
1775	}
1776    }
1777
1778  return TRUE;
1779}
1780
1781#ifndef COFF_IMAGE_WITH_PE
1782
1783bfd_boolean
1784bfd_arm_allocate_interworking_sections (struct bfd_link_info * info)
1785{
1786  asection *                        s;
1787  bfd_byte *                        foo;
1788  struct coff_arm_link_hash_table * globals;
1789
1790  globals = coff_arm_hash_table (info);
1791
1792  BFD_ASSERT (globals != NULL);
1793
1794  if (globals->arm_glue_size != 0)
1795    {
1796      BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1797
1798      s = bfd_get_section_by_name
1799	(globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1800
1801      BFD_ASSERT (s != NULL);
1802
1803      foo = bfd_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size);
1804
1805      s->size = globals->arm_glue_size;
1806      s->contents = foo;
1807    }
1808
1809  if (globals->thumb_glue_size != 0)
1810    {
1811      BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1812
1813      s = bfd_get_section_by_name
1814	(globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1815
1816      BFD_ASSERT (s != NULL);
1817
1818      foo = bfd_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size);
1819
1820      s->size = globals->thumb_glue_size;
1821      s->contents = foo;
1822    }
1823
1824  return TRUE;
1825}
1826
1827static void
1828record_arm_to_thumb_glue (struct bfd_link_info *        info,
1829			  struct coff_link_hash_entry * h)
1830{
1831  const char *                      name = h->root.root.string;
1832  register asection *               s;
1833  char *                            tmp_name;
1834  struct coff_link_hash_entry *     myh;
1835  struct bfd_link_hash_entry *      bh;
1836  struct coff_arm_link_hash_table * globals;
1837  bfd_vma val;
1838  bfd_size_type amt;
1839
1840  globals = coff_arm_hash_table (info);
1841
1842  BFD_ASSERT (globals != NULL);
1843  BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1844
1845  s = bfd_get_section_by_name
1846    (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1847
1848  BFD_ASSERT (s != NULL);
1849
1850  amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1851  tmp_name = bfd_malloc (amt);
1852
1853  BFD_ASSERT (tmp_name);
1854
1855  sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1856
1857  myh = coff_link_hash_lookup
1858    (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE);
1859
1860  if (myh != NULL)
1861    {
1862      free (tmp_name);
1863      /* We've already seen this guy.  */
1864      return;
1865    }
1866
1867  /* The only trick here is using globals->arm_glue_size as the value. Even
1868     though the section isn't allocated yet, this is where we will be putting
1869     it.  */
1870  bh = NULL;
1871  val = globals->arm_glue_size + 1;
1872  bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1873				BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh);
1874
1875  free (tmp_name);
1876
1877  globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
1878
1879  return;
1880}
1881
1882#ifndef ARM_WINCE
1883static void
1884record_thumb_to_arm_glue (struct bfd_link_info *        info,
1885			  struct coff_link_hash_entry * h)
1886{
1887  const char *                       name = h->root.root.string;
1888  asection *                         s;
1889  char *                             tmp_name;
1890  struct coff_link_hash_entry *      myh;
1891  struct bfd_link_hash_entry *       bh;
1892  struct coff_arm_link_hash_table *  globals;
1893  bfd_vma val;
1894  bfd_size_type amt;
1895
1896  globals = coff_arm_hash_table (info);
1897
1898  BFD_ASSERT (globals != NULL);
1899  BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1900
1901  s = bfd_get_section_by_name
1902    (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1903
1904  BFD_ASSERT (s != NULL);
1905
1906  amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1907  tmp_name = bfd_malloc (amt);
1908
1909  BFD_ASSERT (tmp_name);
1910
1911  sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1912
1913  myh = coff_link_hash_lookup
1914    (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE);
1915
1916  if (myh != NULL)
1917    {
1918      free (tmp_name);
1919      /* We've already seen this guy.  */
1920      return;
1921    }
1922
1923  bh = NULL;
1924  val = globals->thumb_glue_size + 1;
1925  bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1926				BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh);
1927
1928  /* If we mark it 'thumb', the disassembler will do a better job.  */
1929  myh = (struct coff_link_hash_entry *) bh;
1930  myh->class = C_THUMBEXTFUNC;
1931
1932  free (tmp_name);
1933
1934  /* Allocate another symbol to mark where we switch to arm mode.  */
1935
1936#define CHANGE_TO_ARM "__%s_change_to_arm"
1937#define BACK_FROM_ARM "__%s_back_from_arm"
1938
1939  amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1;
1940  tmp_name = bfd_malloc (amt);
1941
1942  BFD_ASSERT (tmp_name);
1943
1944  sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
1945
1946  bh = NULL;
1947  val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
1948  bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1949				BSF_LOCAL, s, val, NULL, TRUE, FALSE, &bh);
1950
1951  free (tmp_name);
1952
1953  globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
1954
1955  return;
1956}
1957#endif /* not ARM_WINCE */
1958
1959/* Select a BFD to be used to hold the sections used by the glue code.
1960   This function is called from the linker scripts in ld/emultempl/
1961   {armcoff/pe}.em  */
1962
1963bfd_boolean
1964bfd_arm_get_bfd_for_interworking (bfd * 		 abfd,
1965				  struct bfd_link_info * info)
1966{
1967  struct coff_arm_link_hash_table * globals;
1968  flagword   			    flags;
1969  asection * 			    sec;
1970
1971  /* If we are only performing a partial link do not bother
1972     getting a bfd to hold the glue.  */
1973  if (info->relocatable)
1974    return TRUE;
1975
1976  globals = coff_arm_hash_table (info);
1977
1978  BFD_ASSERT (globals != NULL);
1979
1980  if (globals->bfd_of_glue_owner != NULL)
1981    return TRUE;
1982
1983  sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1984
1985  if (sec == NULL)
1986    {
1987      flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1988	       | SEC_CODE | SEC_READONLY);
1989      sec = bfd_make_section_with_flags (abfd, ARM2THUMB_GLUE_SECTION_NAME,
1990					 flags);
1991      if (sec == NULL
1992	  || ! bfd_set_section_alignment (abfd, sec, 2))
1993	return FALSE;
1994    }
1995
1996  sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
1997
1998  if (sec == NULL)
1999    {
2000      flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
2001	       | SEC_CODE | SEC_READONLY);
2002      sec = bfd_make_section_with_flags (abfd, THUMB2ARM_GLUE_SECTION_NAME,
2003					 flags);
2004
2005      if (sec == NULL
2006	  || ! bfd_set_section_alignment (abfd, sec, 2))
2007	return FALSE;
2008    }
2009
2010  /* Save the bfd for later use.  */
2011  globals->bfd_of_glue_owner = abfd;
2012
2013  return TRUE;
2014}
2015
2016bfd_boolean
2017bfd_arm_process_before_allocation (bfd *                   abfd,
2018				   struct bfd_link_info *  info,
2019				   int		           support_old_code)
2020{
2021  asection * sec;
2022  struct coff_arm_link_hash_table * globals;
2023
2024  /* If we are only performing a partial link do not bother
2025     to construct any glue.  */
2026  if (info->relocatable)
2027    return TRUE;
2028
2029  /* Here we have a bfd that is to be included on the link.  We have a hook
2030     to do reloc rummaging, before section sizes are nailed down.  */
2031  _bfd_coff_get_external_symbols (abfd);
2032
2033  globals = coff_arm_hash_table (info);
2034
2035  BFD_ASSERT (globals != NULL);
2036  BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
2037
2038  globals->support_old_code = support_old_code;
2039
2040  /* Rummage around all the relocs and map the glue vectors.  */
2041  sec = abfd->sections;
2042
2043  if (sec == NULL)
2044    return TRUE;
2045
2046  for (; sec != NULL; sec = sec->next)
2047    {
2048      struct internal_reloc * i;
2049      struct internal_reloc * rel;
2050
2051      if (sec->reloc_count == 0)
2052	continue;
2053
2054      /* Load the relocs.  */
2055      /* FIXME: there may be a storage leak here.  */
2056      i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0);
2057
2058      BFD_ASSERT (i != 0);
2059
2060      for (rel = i; rel < i + sec->reloc_count; ++rel)
2061	{
2062	  unsigned short                 r_type  = rel->r_type;
2063	  long                           symndx;
2064	  struct coff_link_hash_entry *  h;
2065
2066	  symndx = rel->r_symndx;
2067
2068	  /* If the relocation is not against a symbol it cannot concern us.  */
2069	  if (symndx == -1)
2070	    continue;
2071
2072	  /* If the index is outside of the range of our table, something has gone wrong.  */
2073	  if (symndx >= obj_conv_table_size (abfd))
2074	    {
2075	      _bfd_error_handler (_("%B: illegal symbol index in reloc: %d"),
2076				  abfd, symndx);
2077	      continue;
2078	    }
2079
2080	  h = obj_coff_sym_hashes (abfd)[symndx];
2081
2082	  /* If the relocation is against a static symbol it must be within
2083	     the current section and so cannot be a cross ARM/Thumb relocation.  */
2084	  if (h == NULL)
2085	    continue;
2086
2087	  switch (r_type)
2088	    {
2089	    case ARM_26:
2090	      /* This one is a call from arm code.  We need to look up
2091		 the target of the call. If it is a thumb target, we
2092		 insert glue.  */
2093
2094	      if (h->class == C_THUMBEXTFUNC)
2095		record_arm_to_thumb_glue (info, h);
2096	      break;
2097
2098#ifndef ARM_WINCE
2099	    case ARM_THUMB23:
2100	      /* This one is a call from thumb code.  We used to look
2101		 for ARM_THUMB9 and ARM_THUMB12 as well.  We need to look
2102		 up the target of the call. If it is an arm target, we
2103		 insert glue.  If the symbol does not exist it will be
2104		 given a class of C_EXT and so we will generate a stub
2105		 for it.  This is not really a problem, since the link
2106		 is doomed anyway.  */
2107
2108	      switch (h->class)
2109		{
2110		case C_EXT:
2111		case C_STAT:
2112		case C_LABEL:
2113		  record_thumb_to_arm_glue (info, h);
2114		  break;
2115		default:
2116		  ;
2117		}
2118	      break;
2119#endif
2120
2121	    default:
2122	      break;
2123	    }
2124	}
2125    }
2126
2127  return TRUE;
2128}
2129
2130#endif /* ! defined (COFF_IMAGE_WITH_PE) */
2131
2132#define coff_bfd_reloc_type_lookup 		coff_arm_reloc_type_lookup
2133#define coff_bfd_reloc_name_lookup	coff_arm_reloc_name_lookup
2134#define coff_relocate_section 			coff_arm_relocate_section
2135#define coff_bfd_is_local_label_name 		coff_arm_is_local_label_name
2136#define coff_adjust_symndx			coff_arm_adjust_symndx
2137#define coff_link_output_has_begun 		coff_arm_link_output_has_begun
2138#define coff_final_link_postscript		coff_arm_final_link_postscript
2139#define coff_bfd_merge_private_bfd_data		coff_arm_merge_private_bfd_data
2140#define coff_bfd_print_private_bfd_data		coff_arm_print_private_bfd_data
2141#define coff_bfd_set_private_flags              _bfd_coff_arm_set_private_flags
2142#define coff_bfd_copy_private_bfd_data          coff_arm_copy_private_bfd_data
2143#define coff_bfd_link_hash_table_create		coff_arm_link_hash_table_create
2144
2145/* When doing a relocatable link, we want to convert ARM_26 relocs
2146   into ARM_26D relocs.  */
2147
2148static bfd_boolean
2149coff_arm_adjust_symndx (bfd *obfd ATTRIBUTE_UNUSED,
2150			struct bfd_link_info *info ATTRIBUTE_UNUSED,
2151			bfd *ibfd,
2152			asection *sec,
2153			struct internal_reloc *irel,
2154			bfd_boolean *adjustedp)
2155{
2156  if (irel->r_type == ARM_26)
2157    {
2158      struct coff_link_hash_entry *h;
2159
2160      h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
2161      if (h != NULL
2162	  && (h->root.type == bfd_link_hash_defined
2163	      || h->root.type == bfd_link_hash_defweak)
2164	  && h->root.u.def.section->output_section == sec->output_section)
2165	irel->r_type = ARM_26D;
2166    }
2167  *adjustedp = FALSE;
2168  return TRUE;
2169}
2170
2171/* Called when merging the private data areas of two BFDs.
2172   This is important as it allows us to detect if we are
2173   attempting to merge binaries compiled for different ARM
2174   targets, eg different CPUs or different APCS's.     */
2175
2176static bfd_boolean
2177coff_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
2178{
2179  BFD_ASSERT (ibfd != NULL && obfd != NULL);
2180
2181  if (ibfd == obfd)
2182    return TRUE;
2183
2184  /* If the two formats are different we cannot merge anything.
2185     This is not an error, since it is permissable to change the
2186     input and output formats.  */
2187  if (   ibfd->xvec->flavour != bfd_target_coff_flavour
2188      || obfd->xvec->flavour != bfd_target_coff_flavour)
2189    return TRUE;
2190
2191  /* Determine what should happen if the input ARM architecture
2192     does not match the output ARM architecture.  */
2193  if (! bfd_arm_merge_machines (ibfd, obfd))
2194    return FALSE;
2195
2196  /* Verify that the APCS is the same for the two BFDs.  */
2197  if (APCS_SET (ibfd))
2198    {
2199      if (APCS_SET (obfd))
2200	{
2201	  /* If the src and dest have different APCS flag bits set, fail.  */
2202	  if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
2203	    {
2204	      _bfd_error_handler
2205		/* xgettext: c-format */
2206		(_("ERROR: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"),
2207		 ibfd, obfd,
2208		 APCS_26_FLAG (ibfd) ? 26 : 32,
2209		 APCS_26_FLAG (obfd) ? 26 : 32
2210		 );
2211
2212	      bfd_set_error (bfd_error_wrong_format);
2213	      return FALSE;
2214	    }
2215
2216	  if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
2217	    {
2218	      const char *msg;
2219
2220	      if (APCS_FLOAT_FLAG (ibfd))
2221		/* xgettext: c-format */
2222		msg = _("ERROR: %B passes floats in float registers, whereas %B passes them in integer registers");
2223	      else
2224		/* xgettext: c-format */
2225		msg = _("ERROR: %B passes floats in integer registers, whereas %B passes them in float registers");
2226
2227	      _bfd_error_handler (msg, ibfd, obfd);
2228
2229	      bfd_set_error (bfd_error_wrong_format);
2230	      return FALSE;
2231	    }
2232
2233	  if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
2234	    {
2235	      const char * msg;
2236
2237	      if (PIC_FLAG (ibfd))
2238		/* xgettext: c-format */
2239		msg = _("ERROR: %B is compiled as position independent code, whereas target %B is absolute position");
2240	      else
2241		/* xgettext: c-format */
2242		msg = _("ERROR: %B is compiled as absolute position code, whereas target %B is position independent");
2243	      _bfd_error_handler (msg, ibfd, obfd);
2244
2245	      bfd_set_error (bfd_error_wrong_format);
2246	      return FALSE;
2247	    }
2248	}
2249      else
2250	{
2251	  SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd));
2252
2253	  /* Set up the arch and fields as well as these are probably wrong.  */
2254	  bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2255	}
2256    }
2257
2258  /* Check the interworking support.  */
2259  if (INTERWORK_SET (ibfd))
2260    {
2261      if (INTERWORK_SET (obfd))
2262	{
2263	  /* If the src and dest differ in their interworking issue a warning.  */
2264	  if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
2265	    {
2266	      const char * msg;
2267
2268	      if (INTERWORK_FLAG (ibfd))
2269		/* xgettext: c-format */
2270		msg = _("Warning: %B supports interworking, whereas %B does not");
2271	      else
2272		/* xgettext: c-format */
2273		msg = _("Warning: %B does not support interworking, whereas %B does");
2274
2275	      _bfd_error_handler (msg, ibfd, obfd);
2276	    }
2277	}
2278      else
2279	{
2280	  SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
2281	}
2282    }
2283
2284  return TRUE;
2285}
2286
2287/* Display the flags field.  */
2288
2289static bfd_boolean
2290coff_arm_print_private_bfd_data (bfd * abfd, void * ptr)
2291{
2292  FILE * file = (FILE *) ptr;
2293
2294  BFD_ASSERT (abfd != NULL && ptr != NULL);
2295
2296  /* xgettext:c-format */
2297  fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
2298
2299  if (APCS_SET (abfd))
2300    {
2301      /* xgettext: APCS is ARM Procedure Call Standard, it should not be translated.  */
2302      fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32);
2303
2304      if (APCS_FLOAT_FLAG (abfd))
2305	fprintf (file, _(" [floats passed in float registers]"));
2306      else
2307	fprintf (file, _(" [floats passed in integer registers]"));
2308
2309      if (PIC_FLAG (abfd))
2310	fprintf (file, _(" [position independent]"));
2311      else
2312	fprintf (file, _(" [absolute position]"));
2313    }
2314
2315  if (! INTERWORK_SET (abfd))
2316    fprintf (file, _(" [interworking flag not initialised]"));
2317  else if (INTERWORK_FLAG (abfd))
2318    fprintf (file, _(" [interworking supported]"));
2319  else
2320    fprintf (file, _(" [interworking not supported]"));
2321
2322  fputc ('\n', file);
2323
2324  return TRUE;
2325}
2326
2327/* Copies the given flags into the coff_tdata.flags field.
2328   Typically these flags come from the f_flags[] field of
2329   the COFF filehdr structure, which contains important,
2330   target specific information.
2331   Note: Although this function is static, it is explicitly
2332   called from both coffcode.h and peicode.h.  */
2333
2334static bfd_boolean
2335_bfd_coff_arm_set_private_flags (bfd * abfd, flagword flags)
2336{
2337  flagword flag;
2338
2339  BFD_ASSERT (abfd != NULL);
2340
2341  flag = (flags & F_APCS26) ? F_APCS_26 : 0;
2342
2343  /* Make sure that the APCS field has not been initialised to the opposite
2344     value.  */
2345  if (APCS_SET (abfd)
2346      && (   (APCS_26_FLAG    (abfd) != flag)
2347	  || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
2348	  || (PIC_FLAG        (abfd) != (flags & F_PIC))
2349	  ))
2350    return FALSE;
2351
2352  flag |= (flags & (F_APCS_FLOAT | F_PIC));
2353
2354  SET_APCS_FLAGS (abfd, flag);
2355
2356  flag = (flags & F_INTERWORK);
2357
2358  /* If the BFD has already had its interworking flag set, but it
2359     is different from the value that we have been asked to set,
2360     then assume that that merged code will not support interworking
2361     and set the flag accordingly.  */
2362  if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
2363    {
2364      if (flag)
2365	/* xgettext: c-format */
2366	_bfd_error_handler (_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
2367			    abfd);
2368      else
2369	/* xgettext: c-format */
2370	_bfd_error_handler (_("Warning: Clearing the interworking flag of %B due to outside request"),
2371			    abfd);
2372      flag = 0;
2373    }
2374
2375  SET_INTERWORK_FLAG (abfd, flag);
2376
2377  return TRUE;
2378}
2379
2380/* Copy the important parts of the target specific data
2381   from one instance of a BFD to another.  */
2382
2383static bfd_boolean
2384coff_arm_copy_private_bfd_data (bfd * src, bfd * dest)
2385{
2386  BFD_ASSERT (src != NULL && dest != NULL);
2387
2388  if (src == dest)
2389    return TRUE;
2390
2391  /* If the destination is not in the same format as the source, do not do
2392     the copy.  */
2393  if (src->xvec != dest->xvec)
2394    return TRUE;
2395
2396  /* Copy the flags field.  */
2397  if (APCS_SET (src))
2398    {
2399      if (APCS_SET (dest))
2400	{
2401	  /* If the src and dest have different APCS flag bits set, fail.  */
2402	  if (APCS_26_FLAG (dest) != APCS_26_FLAG (src))
2403	    return FALSE;
2404
2405	  if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
2406	    return FALSE;
2407
2408	  if (PIC_FLAG (dest) != PIC_FLAG (src))
2409	    return FALSE;
2410	}
2411      else
2412	SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src)
2413			| PIC_FLAG (src));
2414    }
2415
2416  if (INTERWORK_SET (src))
2417    {
2418      if (INTERWORK_SET (dest))
2419	{
2420	  /* If the src and dest have different interworking flags then turn
2421	     off the interworking bit.  */
2422	  if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src))
2423	    {
2424	      if (INTERWORK_FLAG (dest))
2425		{
2426		  /* xgettext:c-format */
2427		  _bfd_error_handler (("\
2428Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"),
2429				      dest, src);
2430		}
2431
2432	      SET_INTERWORK_FLAG (dest, 0);
2433	    }
2434	}
2435      else
2436	{
2437	  SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
2438	}
2439    }
2440
2441  return TRUE;
2442}
2443
2444/* Note:  the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
2445   *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h.  */
2446#ifndef LOCAL_LABEL_PREFIX
2447#define LOCAL_LABEL_PREFIX ""
2448#endif
2449#ifndef USER_LABEL_PREFIX
2450#define USER_LABEL_PREFIX "_"
2451#endif
2452
2453/* Like _bfd_coff_is_local_label_name, but
2454   a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
2455      non-local.
2456   b) Allow other prefixes than ".", e.g. an empty prefix would cause all
2457      labels of the form Lxxx to be stripped.  */
2458
2459static bfd_boolean
2460coff_arm_is_local_label_name (bfd *        abfd ATTRIBUTE_UNUSED,
2461			      const char * name)
2462{
2463#ifdef USER_LABEL_PREFIX
2464  if (USER_LABEL_PREFIX[0] != 0)
2465    {
2466      size_t len = strlen (USER_LABEL_PREFIX);
2467
2468      if (strncmp (name, USER_LABEL_PREFIX, len) == 0)
2469	return FALSE;
2470    }
2471#endif
2472
2473#ifdef LOCAL_LABEL_PREFIX
2474  /* If there is a prefix for local labels then look for this.
2475     If the prefix exists, but it is empty, then ignore the test.  */
2476
2477  if (LOCAL_LABEL_PREFIX[0] != 0)
2478    {
2479      size_t len = strlen (LOCAL_LABEL_PREFIX);
2480
2481      if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0)
2482	return FALSE;
2483
2484      /* Perform the checks below for the rest of the name.  */
2485      name += len;
2486    }
2487#endif
2488
2489  return name[0] == 'L';
2490}
2491
2492/* This piece of machinery exists only to guarantee that the bfd that holds
2493   the glue section is written last.
2494
2495   This does depend on bfd_make_section attaching a new section to the
2496   end of the section list for the bfd.  */
2497
2498static bfd_boolean
2499coff_arm_link_output_has_begun (bfd * sub, struct coff_final_link_info * info)
2500{
2501  return (sub->output_has_begun
2502	  || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner);
2503}
2504
2505static bfd_boolean
2506coff_arm_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED,
2507				struct coff_final_link_info * pfinfo)
2508{
2509  struct coff_arm_link_hash_table * globals;
2510
2511  globals = coff_arm_hash_table (pfinfo->info);
2512
2513  BFD_ASSERT (globals != NULL);
2514
2515  if (globals->bfd_of_glue_owner != NULL)
2516    {
2517      if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner))
2518	return FALSE;
2519
2520      globals->bfd_of_glue_owner->output_has_begun = TRUE;
2521    }
2522
2523  return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
2524}
2525
2526#include "coffcode.h"
2527
2528#ifndef TARGET_LITTLE_SYM
2529#define TARGET_LITTLE_SYM armcoff_little_vec
2530#endif
2531#ifndef TARGET_LITTLE_NAME
2532#define TARGET_LITTLE_NAME "coff-arm-little"
2533#endif
2534#ifndef TARGET_BIG_SYM
2535#define TARGET_BIG_SYM armcoff_big_vec
2536#endif
2537#ifndef TARGET_BIG_NAME
2538#define TARGET_BIG_NAME "coff-arm-big"
2539#endif
2540
2541#ifndef TARGET_UNDERSCORE
2542#define TARGET_UNDERSCORE 0
2543#endif
2544
2545#ifndef EXTRA_S_FLAGS
2546#ifdef COFF_WITH_PE
2547#define EXTRA_S_FLAGS (SEC_CODE | SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
2548#else
2549#define EXTRA_S_FLAGS SEC_CODE
2550#endif
2551#endif
2552
2553/* Forward declaration for use initialising alternative_target field.  */
2554extern const bfd_target TARGET_BIG_SYM ;
2555
2556/* Target vectors.  */
2557CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM, COFF_SWAP_TABLE)
2558CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM, COFF_SWAP_TABLE)
2559