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