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