* elf32-mips.c (mips_elf_calculate_relocation): Fix unfortunate
[binutils.git] / bfd / coff-arm.c
blobf50cf8cc026f4423a42e0d7082d325a38f24cd97
1 /* BFD back-end for ARM COFF files.
2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
4 Written by Cygnus Support.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
26 #include "coff/arm.h"
28 #include "coff/internal.h"
30 #ifdef COFF_WITH_PE
31 #include "coff/pe.h"
32 #endif
34 #include "libcoff.h"
36 /* Macros for manipulation the bits in the flags field of the coff data
37 structure. */
38 #define APCS_26_FLAG( abfd ) (coff_data (abfd)->flags & F_APCS_26)
39 #define APCS_FLOAT_FLAG( abfd ) (coff_data (abfd)->flags & F_APCS_FLOAT)
40 #define PIC_FLAG( abfd ) (coff_data (abfd)->flags & F_PIC)
41 #define APCS_SET( abfd ) (coff_data (abfd)->flags & F_APCS_SET)
42 #define SET_APCS_FLAGS( abfd, flgs) (coff_data (abfd)->flags = \
43 (coff_data (abfd)->flags & ~ (F_APCS_26 | F_APCS_FLOAT | F_PIC)) \
44 | (flgs | F_APCS_SET))
45 #define INTERWORK_FLAG( abfd ) (coff_data (abfd)->flags & F_INTERWORK)
46 #define INTERWORK_SET( abfd ) (coff_data (abfd)->flags & F_INTERWORK_SET)
47 #define SET_INTERWORK_FLAG( abfd, flg ) (coff_data (abfd)->flags = \
48 (coff_data (abfd)->flags & ~ F_INTERWORK) \
49 | (flg | F_INTERWORK_SET))
51 typedef enum {bunknown, b9, b12, b23} thumb_pcrel_branchtype;
52 /* some typedefs for holding instructions */
53 typedef unsigned long int insn32;
54 typedef unsigned short int insn16;
57 /* Forward declarations for stupid compilers. */
58 static boolean coff_arm_relocate_section
59 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
60 struct internal_reloc *, struct internal_syment *, asection **));
61 static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
62 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
63 static bfd_reloc_status_type aoutarm_fix_pcrel_26
64 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
65 static bfd_reloc_status_type coff_thumb_pcrel_23
66 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
67 static bfd_reloc_status_type coff_thumb_pcrel_12
68 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
69 static bfd_reloc_status_type coff_thumb_pcrel_9
70 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
71 static bfd_reloc_status_type coff_arm_reloc
72 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
73 static boolean coff_arm_adjust_symndx
74 PARAMS ((bfd *, struct bfd_link_info *, bfd *,
75 asection *, struct internal_reloc *, boolean *));
76 static reloc_howto_type * coff_arm_rtype_to_howto
77 PARAMS ((bfd *, asection *, struct internal_reloc *,
78 struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
79 static bfd_reloc_status_type coff_thumb_pcrel_common
80 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **,
81 thumb_pcrel_branchtype));
82 static CONST struct reloc_howto_struct * coff_arm_reloc_type_lookup
83 PARAMS ((bfd *, bfd_reloc_code_real_type));
84 static struct bfd_link_hash_table * coff_arm_link_hash_table_create
85 PARAMS ((bfd *));
86 static insn32 insert_thumb_branch
87 PARAMS ((insn32, int));
88 static struct coff_link_hash_entry * find_thumb_glue
89 PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
90 static struct coff_link_hash_entry * find_arm_glue
91 PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
92 #ifndef COFF_IMAGE_WITH_PE
93 static void record_arm_to_thumb_glue
94 PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *));
95 static void record_thumb_to_arm_glue
96 PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *));
97 #endif
98 static boolean coff_arm_merge_private_bfd_data
99 PARAMS ((bfd *, bfd *));
100 static boolean coff_arm_print_private_bfd_data
101 PARAMS ((bfd *, PTR));
102 static boolean _bfd_coff_arm_set_private_flags
103 PARAMS ((bfd *, flagword));
104 static boolean coff_arm_copy_private_bfd_data
105 PARAMS ((bfd *, bfd *));
106 static boolean coff_arm_is_local_label_name
107 PARAMS ((bfd *, const char *));
108 static boolean coff_arm_link_output_has_begun
109 PARAMS ((bfd *, struct coff_final_link_info *));
110 static boolean coff_arm_final_link_postscript
111 PARAMS ((bfd *, struct coff_final_link_info *));
113 /* The linker script knows the section names for placement.
114 The entry_names are used to do simple name mangling on the stubs.
115 Given a function name, and its type, the stub can be found. The
116 name can be changed. The only requirement is the %s be present.
119 #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
120 #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
122 #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
123 #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
125 /* Used by the assembler. */
126 static bfd_reloc_status_type
127 coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
128 error_message)
129 bfd *abfd;
130 arelent *reloc_entry;
131 asymbol *symbol ATTRIBUTE_UNUSED;
132 PTR data;
133 asection *input_section ATTRIBUTE_UNUSED;
134 bfd *output_bfd;
135 char **error_message ATTRIBUTE_UNUSED;
137 symvalue diff;
138 if (output_bfd == (bfd *) NULL)
139 return bfd_reloc_continue;
141 diff = reloc_entry->addend;
143 #define DOIT(x) \
144 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
146 if (diff != 0)
148 reloc_howto_type *howto = reloc_entry->howto;
149 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
151 switch (howto->size)
153 case 0:
155 char x = bfd_get_8 (abfd, addr);
156 DOIT (x);
157 bfd_put_8 (abfd, x, addr);
159 break;
161 case 1:
163 short x = bfd_get_16 (abfd, addr);
164 DOIT (x);
165 bfd_put_16 (abfd, x, addr);
167 break;
169 case 2:
171 long x = bfd_get_32 (abfd, addr);
172 DOIT (x);
173 bfd_put_32 (abfd, x, addr);
175 break;
177 default:
178 abort ();
182 /* Now let bfd_perform_relocation finish everything up. */
183 return bfd_reloc_continue;
186 /* If USER_LABEL_PREFIX is defined as "_" (see coff_arm_is_local_label_name()
187 in this file), then TARGET_UNDERSCORE should be defined, otherwise it
188 should not. */
189 #ifndef TARGET_UNDERSCORE
190 #define TARGET_UNDERSCORE '_'
191 #endif
193 #ifndef PCRELOFFSET
194 #define PCRELOFFSET true
195 #endif
197 /* These most certainly belong somewhere else. Just had to get rid of
198 the manifest constants in the code. */
200 #define ARM_8 0
201 #define ARM_16 1
202 #define ARM_32 2
203 #define ARM_26 3
204 #define ARM_DISP8 4
205 #define ARM_DISP16 5
206 #define ARM_DISP32 6
207 #define ARM_26D 7
208 /* 8 is unused */
209 #define ARM_NEG16 9
210 #define ARM_NEG32 10
211 #define ARM_RVA32 11
212 #define ARM_THUMB9 12
213 #define ARM_THUMB12 13
214 #define ARM_THUMB23 14
216 static reloc_howto_type aoutarm_std_reloc_howto[] =
218 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
219 HOWTO(ARM_8, /* type */
220 0, /* rightshift */
221 0, /* size */
222 8, /* bitsize */
223 false, /* pc_relative */
224 0, /* bitpos */
225 complain_overflow_bitfield, /* complain_on_overflow */
226 coff_arm_reloc, /* special_function */
227 "ARM_8", /* name */
228 true, /* partial_inplace */
229 0x000000ff, /* src_mask */
230 0x000000ff, /* dst_mask */
231 PCRELOFFSET /* pcrel_offset */),
232 HOWTO(ARM_16,
235 16,
236 false,
238 complain_overflow_bitfield,
239 coff_arm_reloc,
240 "ARM_16",
241 true,
242 0x0000ffff,
243 0x0000ffff,
244 PCRELOFFSET),
245 HOWTO(ARM_32,
249 false,
251 complain_overflow_bitfield,
252 coff_arm_reloc,
253 "ARM_32",
254 true,
255 0xffffffff,
256 0xffffffff,
257 PCRELOFFSET),
258 HOWTO(ARM_26,
262 true,
264 complain_overflow_signed,
265 aoutarm_fix_pcrel_26 ,
266 "ARM_26",
267 false,
268 0x00ffffff,
269 0x00ffffff,
270 PCRELOFFSET),
271 HOWTO(ARM_DISP8,
275 true,
277 complain_overflow_signed,
278 coff_arm_reloc,
279 "ARM_DISP8",
280 true,
281 0x000000ff,
282 0x000000ff,
283 true),
284 HOWTO( ARM_DISP16,
288 true,
290 complain_overflow_signed,
291 coff_arm_reloc,
292 "ARM_DISP16",
293 true,
294 0x0000ffff,
295 0x0000ffff,
296 true),
297 HOWTO( ARM_DISP32,
301 true,
303 complain_overflow_signed,
304 coff_arm_reloc,
305 "ARM_DISP32",
306 true,
307 0xffffffff,
308 0xffffffff,
309 true),
310 HOWTO( ARM_26D,
314 false,
316 complain_overflow_dont,
317 aoutarm_fix_pcrel_26_done,
318 "ARM_26D",
319 true,
320 0x00ffffff,
321 0x0,
322 false),
323 /* 8 is unused */
324 EMPTY_HOWTO (-1),
325 HOWTO( ARM_NEG16,
329 false,
331 complain_overflow_bitfield,
332 coff_arm_reloc,
333 "ARM_NEG16",
334 true,
335 0x0000ffff,
336 0x0000ffff,
337 false),
338 HOWTO( ARM_NEG32,
342 false,
344 complain_overflow_bitfield,
345 coff_arm_reloc,
346 "ARM_NEG32",
347 true,
348 0xffffffff,
349 0xffffffff,
350 false),
351 HOWTO( ARM_RVA32,
355 false,
357 complain_overflow_bitfield,
358 coff_arm_reloc,
359 "ARM_RVA32",
360 true,
361 0xffffffff,
362 0xffffffff,
363 PCRELOFFSET),
364 HOWTO( ARM_THUMB9,
368 true,
370 complain_overflow_signed,
371 coff_thumb_pcrel_9 ,
372 "ARM_THUMB9",
373 false,
374 0x000000ff,
375 0x000000ff,
376 PCRELOFFSET),
377 HOWTO( ARM_THUMB12,
381 true,
383 complain_overflow_signed,
384 coff_thumb_pcrel_12 ,
385 "ARM_THUMB12",
386 false,
387 0x000007ff,
388 0x000007ff,
389 PCRELOFFSET),
390 HOWTO( ARM_THUMB23,
394 true,
396 complain_overflow_signed,
397 coff_thumb_pcrel_23 ,
398 "ARM_THUMB23",
399 false,
400 0x07ff07ff,
401 0x07ff07ff,
402 PCRELOFFSET),
405 #ifdef COFF_WITH_PE
406 /* Return true if this relocation should
407 appear in the output .reloc section. */
409 static boolean
410 in_reloc_p (abfd, howto)
411 bfd * abfd ATTRIBUTE_UNUSED;
412 reloc_howto_type * howto;
414 return !howto->pc_relative && howto->type != ARM_RVA32;
416 #endif
419 #define RTYPE2HOWTO(cache_ptr, dst) \
420 (cache_ptr)->howto = aoutarm_std_reloc_howto + (dst)->r_type;
422 #define coff_rtype_to_howto coff_arm_rtype_to_howto
424 static reloc_howto_type *
425 coff_arm_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
426 bfd *abfd ATTRIBUTE_UNUSED;
427 asection *sec;
428 struct internal_reloc *rel;
429 struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
430 struct internal_syment *sym ATTRIBUTE_UNUSED;
431 bfd_vma *addendp;
433 reloc_howto_type *howto;
435 howto = aoutarm_std_reloc_howto + rel->r_type;
437 if (rel->r_type == ARM_RVA32)
439 *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
442 return howto;
445 /* Used by the assembler. */
447 static bfd_reloc_status_type
448 aoutarm_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
449 output_bfd, error_message)
450 bfd *abfd ATTRIBUTE_UNUSED;
451 arelent *reloc_entry ATTRIBUTE_UNUSED;
452 asymbol *symbol ATTRIBUTE_UNUSED;
453 PTR data ATTRIBUTE_UNUSED;
454 asection *input_section ATTRIBUTE_UNUSED;
455 bfd *output_bfd ATTRIBUTE_UNUSED;
456 char **error_message ATTRIBUTE_UNUSED;
458 /* This is dead simple at present. */
459 return bfd_reloc_ok;
462 /* Used by the assembler. */
464 static bfd_reloc_status_type
465 aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section,
466 output_bfd, error_message)
467 bfd *abfd;
468 arelent *reloc_entry;
469 asymbol *symbol;
470 PTR data;
471 asection *input_section;
472 bfd *output_bfd;
473 char **error_message ATTRIBUTE_UNUSED;
475 bfd_vma relocation;
476 bfd_size_type addr = reloc_entry->address;
477 long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
478 bfd_reloc_status_type flag = bfd_reloc_ok;
480 /* If this is an undefined symbol, return error */
481 if (symbol->section == &bfd_und_section
482 && (symbol->flags & BSF_WEAK) == 0)
483 return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
485 /* If the sections are different, and we are doing a partial relocation,
486 just ignore it for now. */
487 if (symbol->section->name != input_section->name
488 && output_bfd != (bfd *)NULL)
489 return bfd_reloc_continue;
491 relocation = (target & 0x00ffffff) << 2;
492 relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */
493 relocation += symbol->value;
494 relocation += symbol->section->output_section->vma;
495 relocation += symbol->section->output_offset;
496 relocation += reloc_entry->addend;
497 relocation -= input_section->output_section->vma;
498 relocation -= input_section->output_offset;
499 relocation -= addr;
501 if (relocation & 3)
502 return bfd_reloc_overflow;
504 /* Check for overflow */
505 if (relocation & 0x02000000)
507 if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
508 flag = bfd_reloc_overflow;
510 else if (relocation & ~0x03ffffff)
511 flag = bfd_reloc_overflow;
513 target &= ~0x00ffffff;
514 target |= (relocation >> 2) & 0x00ffffff;
515 bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
517 /* Now the ARM magic... Change the reloc type so that it is marked as done.
518 Strictly this is only necessary if we are doing a partial relocation. */
519 reloc_entry->howto = &aoutarm_std_reloc_howto[ARM_26D];
521 return flag;
524 static bfd_reloc_status_type
525 coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section,
526 output_bfd, error_message, btype)
527 bfd *abfd;
528 arelent *reloc_entry;
529 asymbol *symbol;
530 PTR data;
531 asection *input_section;
532 bfd *output_bfd;
533 char **error_message ATTRIBUTE_UNUSED;
534 thumb_pcrel_branchtype btype;
536 bfd_vma relocation = 0;
537 bfd_size_type addr = reloc_entry->address;
538 long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
539 bfd_reloc_status_type flag = bfd_reloc_ok;
540 bfd_vma dstmsk;
541 bfd_vma offmsk;
542 bfd_vma signbit;
544 /* NOTE: This routine is currently used by GAS, but not by the link
545 phase. */
547 switch (btype)
549 case b9:
550 dstmsk = 0x000000ff;
551 offmsk = 0x000001fe;
552 signbit = 0x00000100;
553 break;
555 case b12:
556 dstmsk = 0x000007ff;
557 offmsk = 0x00000ffe;
558 signbit = 0x00000800;
559 break;
561 case b23:
562 dstmsk = 0x07ff07ff;
563 offmsk = 0x007fffff;
564 signbit = 0x00400000;
565 break;
567 default:
568 abort ();
571 /* If this is an undefined symbol, return error */
572 if (symbol->section == &bfd_und_section
573 && (symbol->flags & BSF_WEAK) == 0)
574 return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
576 /* If the sections are different, and we are doing a partial relocation,
577 just ignore it for now. */
578 if (symbol->section->name != input_section->name
579 && output_bfd != (bfd *)NULL)
580 return bfd_reloc_continue;
582 switch (btype)
584 case b9:
585 case b12:
586 relocation = ((target & dstmsk) << 1);
587 break;
589 case b23:
590 if (bfd_big_endian (abfd))
591 relocation = ((target & 0x7ff) << 1) | ((target & 0x07ff0000) >> 4);
592 else
593 relocation = ((target & 0x7ff) << 12) | ((target & 0x07ff0000) >> 15);
594 break;
596 default:
597 abort ();
600 relocation = (relocation ^ signbit) - signbit; /* Sign extend */
601 relocation += symbol->value;
602 relocation += symbol->section->output_section->vma;
603 relocation += symbol->section->output_offset;
604 relocation += reloc_entry->addend;
605 relocation -= input_section->output_section->vma;
606 relocation -= input_section->output_offset;
607 relocation -= addr;
609 if (relocation & 1)
610 return bfd_reloc_overflow;
612 /* Check for overflow */
613 if (relocation & signbit)
615 if ((relocation & ~offmsk) != ~offmsk)
616 flag = bfd_reloc_overflow;
618 else if (relocation & ~offmsk)
619 flag = bfd_reloc_overflow;
621 target &= ~dstmsk;
622 switch (btype)
624 case b9:
625 case b12:
626 target |= (relocation >> 1);
627 break;
629 case b23:
630 if (bfd_big_endian (abfd))
631 target |= ((relocation & 0xfff) >> 1) | ((relocation << 4) & 0x07ff0000);
632 else
633 target |= ((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff);
634 break;
636 default:
637 abort ();
640 bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
642 /* Now the ARM magic... Change the reloc type so that it is marked as done.
643 Strictly this is only necessary if we are doing a partial relocation. */
644 reloc_entry->howto = & aoutarm_std_reloc_howto [ARM_26D];
646 /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations */
647 return flag;
650 static bfd_reloc_status_type
651 coff_thumb_pcrel_23 (abfd, reloc_entry, symbol, data, input_section,
652 output_bfd, error_message)
653 bfd *abfd;
654 arelent *reloc_entry;
655 asymbol *symbol;
656 PTR data;
657 asection *input_section;
658 bfd *output_bfd;
659 char **error_message;
661 return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
662 input_section, output_bfd, error_message, b23);
665 static bfd_reloc_status_type
666 coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section,
667 output_bfd, error_message)
668 bfd *abfd;
669 arelent *reloc_entry;
670 asymbol *symbol;
671 PTR data;
672 asection *input_section;
673 bfd *output_bfd;
674 char **error_message;
676 return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
677 input_section, output_bfd, error_message, b12);
680 static bfd_reloc_status_type
681 coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section,
682 output_bfd, error_message)
683 bfd *abfd;
684 arelent *reloc_entry;
685 asymbol *symbol;
686 PTR data;
687 asection *input_section;
688 bfd *output_bfd;
689 char **error_message;
691 return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
692 input_section, output_bfd, error_message, b9);
696 static CONST struct reloc_howto_struct *
697 coff_arm_reloc_type_lookup (abfd, code)
698 bfd * abfd;
699 bfd_reloc_code_real_type code;
701 #define ASTD(i,j) case i: return &aoutarm_std_reloc_howto[j]
702 if (code == BFD_RELOC_CTOR)
703 switch (bfd_get_arch_info (abfd)->bits_per_address)
705 case 32:
706 code = BFD_RELOC_32;
707 break;
708 default: return (CONST struct reloc_howto_struct *) 0;
711 switch (code)
713 ASTD (BFD_RELOC_8, ARM_8);
714 ASTD (BFD_RELOC_16, ARM_16);
715 ASTD (BFD_RELOC_32, ARM_32);
716 ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26);
717 ASTD (BFD_RELOC_8_PCREL, ARM_DISP8);
718 ASTD (BFD_RELOC_16_PCREL, ARM_DISP16);
719 ASTD (BFD_RELOC_32_PCREL, ARM_DISP32);
720 ASTD (BFD_RELOC_RVA, ARM_RVA32);
721 ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9, ARM_THUMB9);
722 ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
723 ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23);
724 default: return (CONST struct reloc_howto_struct *) 0;
728 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
729 #define COFF_PAGE_SIZE 0x1000
730 /* Turn a howto into a reloc nunmber */
732 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
733 #define BADMAG(x) ARMBADMAG(x)
734 #define ARM 1 /* Customize coffcode.h */
736 /* Extend the coff_link_hash_table structure with a few ARM specific fields.
737 This allows us to store global data here without actually creating any
738 global variables, which is a no-no in the BFD world. */
739 struct coff_arm_link_hash_table
741 /* The original coff_link_hash_table structure. MUST be first field. */
742 struct coff_link_hash_table root;
744 /* The size in bytes of the section containg the Thumb-to-ARM glue. */
745 long int thumb_glue_size;
747 /* The size in bytes of the section containg the ARM-to-Thumb glue. */
748 long int arm_glue_size;
750 /* An arbitary input BFD chosen to hold the glue sections. */
751 bfd * bfd_of_glue_owner;
753 /* Support interworking with old, non-interworking aware ARM code. */
754 int support_old_code;
757 /* Get the ARM coff linker hash table from a link_info structure. */
758 #define coff_arm_hash_table(info) \
759 ((struct coff_arm_link_hash_table *) ((info)->hash))
761 /* Create an ARM coff linker hash table. */
763 static struct bfd_link_hash_table *
764 coff_arm_link_hash_table_create (abfd)
765 bfd * abfd;
767 struct coff_arm_link_hash_table * ret;
769 ret = ((struct coff_arm_link_hash_table *)
770 bfd_alloc (abfd, sizeof (struct coff_arm_link_hash_table)));
771 if (ret == (struct coff_arm_link_hash_table *) NULL)
772 return NULL;
774 if (! _bfd_coff_link_hash_table_init
775 (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
777 bfd_release (abfd, ret);
778 return (struct bfd_link_hash_table *) NULL;
781 ret->thumb_glue_size = 0;
782 ret->arm_glue_size = 0;
783 ret->bfd_of_glue_owner = NULL;
785 return & ret->root.root;
788 static void
789 arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
790 struct bfd_link_info *info;
791 bfd *output_bfd;
792 asection *input_section;
793 bfd_vma reloc_offset;
795 bfd_vma addr = reloc_offset
796 - input_section->vma
797 + input_section->output_offset
798 + input_section->output_section->vma;
800 if (coff_data(output_bfd)->pe)
801 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
802 fwrite (&addr, 1, sizeof (addr), (FILE *) info->base_file);
806 /* The thumb form of a long branch is a bit finicky, because the offset
807 encoding is split over two fields, each in it's own instruction. They
808 can occur in any order. So given a thumb form of long branch, and an
809 offset, insert the offset into the thumb branch and return finished
810 instruction.
812 It takes two thumb instructions to encode the target address. Each has
813 11 bits to invest. The upper 11 bits are stored in one (identifed by
814 H-0.. see below), the lower 11 bits are stored in the other (identified
815 by H-1).
817 Combine together and shifted left by 1 (it's a half word address) and
818 there you have it.
820 Op: 1111 = F,
821 H-0, upper address-0 = 000
822 Op: 1111 = F,
823 H-1, lower address-0 = 800
825 They can be ordered either way, but the arm tools I've seen always put
826 the lower one first. It probably doesn't matter. krk@cygnus.com
828 XXX: Actually the order does matter. The second instruction (H-1)
829 moves the computed address into the PC, so it must be the second one
830 in the sequence. The problem, however is that whilst little endian code
831 stores the instructions in HI then LOW order, big endian code does the
832 reverse. nickc@cygnus.com */
834 #define LOW_HI_ORDER 0xF800F000
835 #define HI_LOW_ORDER 0xF000F800
837 static insn32
838 insert_thumb_branch (br_insn, rel_off)
839 insn32 br_insn;
840 int rel_off;
842 unsigned int low_bits;
843 unsigned int high_bits;
846 BFD_ASSERT((rel_off & 1) != 1);
848 rel_off >>= 1; /* half word aligned address */
849 low_bits = rel_off & 0x000007FF; /* the bottom 11 bits */
850 high_bits = (rel_off >> 11) & 0x000007FF; /* the top 11 bits */
852 if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
853 br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
854 else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
855 br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
856 else
857 abort(); /* error - not a valid branch instruction form */
859 /* FIXME: abort is probably not the right call. krk@cygnus.com */
861 return br_insn;
865 static struct coff_link_hash_entry *
866 find_thumb_glue (info, name, input_bfd)
867 struct bfd_link_info * info;
868 CONST char * name;
869 bfd * input_bfd;
871 char * tmp_name;
872 struct coff_link_hash_entry * myh;
874 tmp_name = ((char *)
875 bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1));
877 BFD_ASSERT (tmp_name);
879 sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
881 myh = coff_link_hash_lookup
882 (coff_hash_table (info), tmp_name, false, false, true);
884 if (myh == NULL)
885 /* xgettext:c-format */
886 _bfd_error_handler (_("%s: unable to find THUMB glue '%s' for `%s'"),
887 bfd_get_filename (input_bfd), tmp_name, name);
889 free (tmp_name);
891 return myh;
894 static struct coff_link_hash_entry *
895 find_arm_glue (info, name, input_bfd)
896 struct bfd_link_info * info;
897 CONST char * name;
898 bfd * input_bfd;
900 char * tmp_name;
901 struct coff_link_hash_entry * myh;
903 tmp_name = ((char *)
904 bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
906 BFD_ASSERT (tmp_name);
908 sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
910 myh = coff_link_hash_lookup
911 (coff_hash_table (info), tmp_name, false, false, true);
913 if (myh == NULL)
914 /* xgettext:c-format */
915 _bfd_error_handler (_("%s: unable to find ARM glue '%s' for `%s'"),
916 bfd_get_filename (input_bfd), tmp_name, name);
918 free (tmp_name);
920 return myh;
924 ARM->Thumb glue:
926 .arm
927 __func_from_arm:
928 ldr r12, __func_addr
929 bx r12
930 __func_addr:
931 .word func @ behave as if you saw a ARM_32 reloc
934 #define ARM2THUMB_GLUE_SIZE 12
935 static const insn32 a2t1_ldr_insn = 0xe59fc000;
936 static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
937 static const insn32 a2t3_func_addr_insn = 0x00000001;
940 Thumb->ARM: Thumb->(non-interworking aware) ARM
942 .thumb .thumb
943 .align 2 .align 2
944 __func_from_thumb: __func_from_thumb:
945 bx pc push {r6, lr}
946 nop ldr r6, __func_addr
947 .arm mov lr, pc
948 __func_change_to_arm: bx r6
949 b func .arm
950 __func_back_to_thumb:
951 ldmia r13! {r6, lr}
952 bx lr
953 __func_addr:
954 .word func
957 #define THUMB2ARM_GLUE_SIZE (globals->support_old_code ? 20 : 8)
958 static const insn16 t2a1_bx_pc_insn = 0x4778;
959 static const insn16 t2a2_noop_insn = 0x46c0;
960 static const insn32 t2a3_b_insn = 0xea000000;
962 static const insn16 t2a1_push_insn = 0xb540;
963 static const insn16 t2a2_ldr_insn = 0x4e03;
964 static const insn16 t2a3_mov_insn = 0x46fe;
965 static const insn16 t2a4_bx_insn = 0x4730;
966 static const insn32 t2a5_pop_insn = 0xe8bd4040;
967 static const insn32 t2a6_bx_insn = 0xe12fff1e;
969 /* TODO:
970 We should really create new local (static) symbols in destination
971 object for each stub we create. We should also create local
972 (static) symbols within the stubs when switching between ARM and
973 Thumb code. This will ensure that the debugger and disassembler
974 can present a better view of stubs.
976 We can treat stubs like literal sections, and for the THUMB9 ones
977 (short addressing range) we should be able to insert the stubs
978 between sections. i.e. the simplest approach (since relocations
979 are done on a section basis) is to dump the stubs at the end of
980 processing a section. That way we can always try and minimise the
981 offset to and from a stub. However, this does not map well onto
982 the way that the linker/BFD does its work: mapping all input
983 sections to output sections via the linker script before doing
984 all the processing.
986 Unfortunately it may be easier to just to disallow short range
987 Thumb->ARM stubs (i.e. no conditional inter-working branches,
988 only branch-and-link (BL) calls. This will simplify the processing
989 since we can then put all of the stubs into their own section.
991 TODO:
992 On a different subject, rather than complaining when a
993 branch cannot fit in the number of bits available for the
994 instruction we should generate a trampoline stub (needed to
995 address the complete 32bit address space). */
997 /* The standard COFF backend linker does not cope with the special
998 Thumb BRANCH23 relocation. The alternative would be to split the
999 BRANCH23 into seperate HI23 and LO23 relocations. However, it is a
1000 bit simpler simply providing our own relocation driver. */
1002 /* The reloc processing routine for the ARM/Thumb COFF linker. NOTE:
1003 This code is a very slightly modified copy of
1004 _bfd_coff_generic_relocate_section. It would be a much more
1005 maintainable solution to have a MACRO that could be expanded within
1006 _bfd_coff_generic_relocate_section that would only be provided for
1007 ARM/Thumb builds. It is only the code marked THUMBEXTENSION that
1008 is different from the original. */
1010 static boolean
1011 coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1012 contents, relocs, syms, sections)
1013 bfd *output_bfd;
1014 struct bfd_link_info *info;
1015 bfd *input_bfd;
1016 asection *input_section;
1017 bfd_byte *contents;
1018 struct internal_reloc *relocs;
1019 struct internal_syment *syms;
1020 asection **sections;
1022 struct internal_reloc * rel;
1023 struct internal_reloc * relend;
1025 rel = relocs;
1026 relend = rel + input_section->reloc_count;
1028 for (; rel < relend; rel++)
1030 int done = 0;
1031 long symndx;
1032 struct coff_link_hash_entry * h;
1033 struct internal_syment * sym;
1034 bfd_vma addend;
1035 bfd_vma val;
1036 reloc_howto_type * howto;
1037 bfd_reloc_status_type rstat;
1038 bfd_vma h_val;
1040 symndx = rel->r_symndx;
1042 if (symndx == -1)
1044 h = NULL;
1045 sym = NULL;
1047 else
1049 h = obj_coff_sym_hashes (input_bfd)[symndx];
1050 sym = syms + symndx;
1053 /* COFF treats common symbols in one of two ways. Either the
1054 size of the symbol is included in the section contents, or it
1055 is not. We assume that the size is not included, and force
1056 the rtype_to_howto function to adjust the addend as needed. */
1058 if (sym != NULL && sym->n_scnum != 0)
1059 addend = - sym->n_value;
1060 else
1061 addend = 0;
1064 howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
1065 sym, &addend);
1066 if (howto == NULL)
1067 return false;
1069 /* The relocation_section function will skip pcrel_offset relocs
1070 when doing a relocateable link. However, we want to convert
1071 ARM26 to ARM26D relocs if possible. We return a fake howto in
1072 this case without pcrel_offset set, and adjust the addend to
1073 compensate. */
1074 if (rel->r_type == ARM_26
1075 && h != NULL
1076 && info->relocateable
1077 && (h->root.type == bfd_link_hash_defined
1078 || h->root.type == bfd_link_hash_defweak)
1079 && h->root.u.def.section->output_section == input_section->output_section)
1081 static reloc_howto_type fake_arm26_reloc =
1082 HOWTO (ARM_26,
1086 true,
1088 complain_overflow_signed,
1089 aoutarm_fix_pcrel_26 ,
1090 "ARM_26",
1091 false,
1092 0x00ffffff,
1093 0x00ffffff,
1094 false);
1096 addend -= rel->r_vaddr - input_section->vma;
1097 howto = &fake_arm26_reloc;
1100 /* If we are doing a relocateable link, then we can just ignore
1101 a PC relative reloc that is pcrel_offset. It will already
1102 have the correct value. If this is not a relocateable link,
1103 then we should ignore the symbol value. */
1104 if (howto->pc_relative && howto->pcrel_offset)
1106 if (info->relocateable)
1107 continue;
1108 if (sym != NULL && sym->n_scnum != 0)
1109 addend += sym->n_value;
1112 val = 0;
1114 if (h == NULL)
1116 asection *sec;
1118 if (symndx == -1)
1120 sec = bfd_abs_section_ptr;
1121 val = 0;
1123 else
1125 sec = sections[symndx];
1126 val = (sec->output_section->vma
1127 + sec->output_offset
1128 + sym->n_value
1129 - sec->vma);
1132 else
1134 #if 1 /* THUMBEXTENSION */
1135 /* We don't output the stubs if we are generating a
1136 relocatable output file, since we may as well leave the
1137 stub generation to the final linker pass. If we fail to
1138 verify that the name is defined, we'll try to build stubs
1139 for an undefined name... */
1140 if (! info->relocateable
1141 && ( h->root.type == bfd_link_hash_defined
1142 || h->root.type == bfd_link_hash_defweak))
1144 asection * h_sec = h->root.u.def.section;
1145 const char * name = h->root.root.string;
1147 /* h locates the symbol referenced in the reloc. */
1148 h_val = (h->root.u.def.value
1149 + h_sec->output_section->vma
1150 + h_sec->output_offset);
1152 if (howto->type == ARM_26)
1154 if ( h->class == C_THUMBSTATFUNC
1155 || h->class == C_THUMBEXTFUNC)
1157 /* Arm code calling a Thumb function */
1158 unsigned long int tmp;
1159 long int my_offset;
1160 asection * s;
1161 long int ret_offset;
1162 struct coff_link_hash_entry * myh;
1163 struct coff_arm_link_hash_table * globals;
1165 myh = find_arm_glue (info, name, input_bfd);
1166 if (myh == NULL)
1167 return false;
1169 globals = coff_arm_hash_table (info);
1171 BFD_ASSERT (globals != NULL);
1172 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1174 my_offset = myh->root.u.def.value;
1176 s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1177 ARM2THUMB_GLUE_SECTION_NAME);
1178 BFD_ASSERT (s != NULL);
1179 BFD_ASSERT (s->contents != NULL);
1180 BFD_ASSERT (s->output_section != NULL);
1182 if ((my_offset & 0x01) == 0x01)
1184 if (h_sec->owner != NULL
1185 && INTERWORK_SET (h_sec->owner)
1186 && ! INTERWORK_FLAG (h_sec->owner))
1188 _bfd_error_handler
1189 /* xgettext:c-format */
1190 (_("%s(%s): warning: interworking not enabled."),
1191 bfd_get_filename (h_sec->owner), name);
1192 _bfd_error_handler
1193 /* xgettext:c-format */
1194 (_(" first occurrence: %s: arm call to thumb"),
1195 bfd_get_filename (input_bfd));
1198 --my_offset;
1199 myh->root.u.def.value = my_offset;
1201 bfd_put_32 (output_bfd, a2t1_ldr_insn,
1202 s->contents + my_offset);
1204 bfd_put_32 (output_bfd, a2t2_bx_r12_insn,
1205 s->contents + my_offset + 4);
1207 /* It's a thumb address. Add the low order bit. */
1208 bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
1209 s->contents + my_offset + 8);
1211 if (info->base_file)
1212 arm_emit_base_file_entry (info, output_bfd, s,
1213 my_offset + 8);
1217 BFD_ASSERT (my_offset <= globals->arm_glue_size);
1219 tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1220 - input_section->vma);
1222 tmp = tmp & 0xFF000000;
1224 /* Somehow these are both 4 too far, so subtract 8. */
1225 ret_offset =
1226 s->output_offset
1227 + my_offset
1228 + s->output_section->vma
1229 - (input_section->output_offset
1230 + input_section->output_section->vma
1231 + rel->r_vaddr)
1232 - 8;
1234 tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1236 bfd_put_32 (output_bfd, tmp, contents + rel->r_vaddr
1237 - input_section->vma);
1238 done = 1;
1242 /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12 */
1243 else if (howto->type == ARM_THUMB23)
1245 if ( h->class == C_EXT
1246 || h->class == C_STAT
1247 || h->class == C_LABEL)
1249 /* Thumb code calling an ARM function */
1250 asection * s = 0;
1251 long int my_offset;
1252 unsigned long int tmp;
1253 long int ret_offset;
1254 struct coff_link_hash_entry * myh;
1255 struct coff_arm_link_hash_table * globals;
1257 myh = find_thumb_glue (info, name, input_bfd);
1258 if (myh == NULL)
1259 return false;
1261 globals = coff_arm_hash_table (info);
1263 BFD_ASSERT (globals != NULL);
1264 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1266 my_offset = myh->root.u.def.value;
1268 s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1269 THUMB2ARM_GLUE_SECTION_NAME);
1271 BFD_ASSERT (s != NULL);
1272 BFD_ASSERT (s->contents != NULL);
1273 BFD_ASSERT (s->output_section != NULL);
1275 if ((my_offset & 0x01) == 0x01)
1277 if (h_sec->owner != NULL
1278 && INTERWORK_SET (h_sec->owner)
1279 && ! INTERWORK_FLAG (h_sec->owner)
1280 && ! globals->support_old_code)
1282 _bfd_error_handler
1283 /* xgettext:c-format */
1284 (_("%s(%s): warning: interworking not enabled."),
1285 bfd_get_filename (h_sec->owner), name);
1286 _bfd_error_handler
1287 /* xgettext:c-format */
1288 (_(" first occurrence: %s: thumb call to arm"),
1289 bfd_get_filename (input_bfd));
1290 _bfd_error_handler
1291 (_(" consider relinking with --support-old-code enabled"));
1294 -- my_offset;
1295 myh->root.u.def.value = my_offset;
1297 if (globals->support_old_code)
1299 bfd_put_16 (output_bfd, t2a1_push_insn,
1300 s->contents + my_offset);
1302 bfd_put_16 (output_bfd, t2a2_ldr_insn,
1303 s->contents + my_offset + 2);
1305 bfd_put_16 (output_bfd, t2a3_mov_insn,
1306 s->contents + my_offset + 4);
1308 bfd_put_16 (output_bfd, t2a4_bx_insn,
1309 s->contents + my_offset + 6);
1311 bfd_put_32 (output_bfd, t2a5_pop_insn,
1312 s->contents + my_offset + 8);
1314 bfd_put_32 (output_bfd, t2a6_bx_insn,
1315 s->contents + my_offset + 12);
1317 /* Store the address of the function in the last word of the stub. */
1318 bfd_put_32 (output_bfd, h_val,
1319 s->contents + my_offset + 16);
1321 if (info->base_file)
1322 arm_emit_base_file_entry (info, output_bfd, s, my_offset + 16);
1324 else
1326 bfd_put_16 (output_bfd, t2a1_bx_pc_insn,
1327 s->contents + my_offset);
1329 bfd_put_16 (output_bfd, t2a2_noop_insn,
1330 s->contents + my_offset + 2);
1332 ret_offset =
1333 ((bfd_signed_vma) h_val) /* Address of destination of the stub */
1334 - ((bfd_signed_vma)
1335 (s->output_offset /* Offset from the start of the current section to the start of the stubs. */
1336 + my_offset /* Offset of the start of this stub from the start of the stubs. */
1337 + s->output_section->vma) /* Address of the start of the current section. */
1338 + 4 /* The branch instruction is 4 bytes into the stub. */
1339 + 8); /* ARM branches work from the pc of the instruction + 8. */
1341 bfd_put_32 (output_bfd,
1342 t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1343 s->contents + my_offset + 4);
1348 BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1350 /* Now go back and fix up the original BL insn to point
1351 to here. */
1352 ret_offset =
1353 s->output_offset
1354 + my_offset
1355 - (input_section->output_offset
1356 + rel->r_vaddr)
1359 tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1360 - input_section->vma);
1362 bfd_put_32 (output_bfd,
1363 insert_thumb_branch (tmp, ret_offset),
1364 contents + rel->r_vaddr
1365 - input_section->vma);
1367 done = 1;
1372 /* If the relocation type and destination symbol does not
1373 fall into one of the above categories, then we can just
1374 perform a direct link. */
1376 if (done)
1377 rstat = bfd_reloc_ok;
1378 else
1379 #endif /* THUMBEXTENSION */
1380 if ( h->root.type == bfd_link_hash_defined
1381 || h->root.type == bfd_link_hash_defweak)
1383 asection *sec;
1385 sec = h->root.u.def.section;
1386 val = (h->root.u.def.value
1387 + sec->output_section->vma
1388 + sec->output_offset);
1391 else if (! info->relocateable)
1393 if (! ((*info->callbacks->undefined_symbol)
1394 (info, h->root.root.string, input_bfd, input_section,
1395 rel->r_vaddr - input_section->vma)))
1396 return false;
1400 if (info->base_file)
1402 /* Emit a reloc if the backend thinks it needs it. */
1403 if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
1404 arm_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr);
1407 #if 1 /* THUMBEXTENSION */
1408 if (done)
1409 rstat = bfd_reloc_ok;
1410 /* Only perform this fix during the final link, not a relocatable link. nickc@cygnus.com */
1411 else if (! info->relocateable
1412 && howto->type == ARM_THUMB23)
1414 /* This is pretty much a copy of what the default
1415 _bfd_final_link_relocate and _bfd_relocate_contents
1416 routines do to perform a relocation, with special
1417 processing for the split addressing of the Thumb BL
1418 instruction. Again, it would probably be simpler adding a
1419 ThumbBRANCH23 specific macro expansion into the default
1420 code. */
1422 bfd_vma address = rel->r_vaddr - input_section->vma;
1424 if (address > input_section->_raw_size)
1425 rstat = bfd_reloc_outofrange;
1426 else
1428 bfd_vma relocation = val + addend;
1429 int size = bfd_get_reloc_size (howto);
1430 boolean overflow = false;
1431 bfd_byte * location = contents + address;
1432 bfd_vma x = bfd_get_32 (input_bfd, location);
1433 bfd_vma src_mask = 0x007FFFFE;
1434 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1435 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1436 bfd_vma check;
1437 bfd_signed_vma signed_check;
1438 bfd_vma add;
1439 bfd_signed_vma signed_add;
1441 BFD_ASSERT (size == 4);
1443 /* howto->pc_relative should be TRUE for type 14 BRANCH23 */
1444 relocation -= (input_section->output_section->vma
1445 + input_section->output_offset);
1447 /* howto->pcrel_offset should be TRUE for type 14 BRANCH23 */
1448 relocation -= address;
1450 /* No need to negate the relocation with BRANCH23. */
1451 /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23. */
1452 /* howto->rightshift == 1 */
1453 /* Drop unwanted bits from the value we are relocating to. */
1455 check = relocation >> howto->rightshift;
1457 /* If this is a signed value, the rightshift just dropped
1458 leading 1 bits (assuming twos complement). */
1459 if ((bfd_signed_vma) relocation >= 0)
1460 signed_check = check;
1461 else
1462 signed_check = (check
1463 | ((bfd_vma) - 1
1464 & ~((bfd_vma) - 1 >> howto->rightshift)));
1466 /* Get the value from the object file. */
1467 if (bfd_big_endian (input_bfd))
1469 add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
1471 else
1473 add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
1476 /* Get the value from the object file with an appropriate sign.
1477 The expression involving howto->src_mask isolates the upper
1478 bit of src_mask. If that bit is set in the value we are
1479 adding, it is negative, and we subtract out that number times
1480 two. If src_mask includes the highest possible bit, then we
1481 can not get the upper bit, but that does not matter since
1482 signed_add needs no adjustment to become negative in that
1483 case. */
1485 signed_add = add;
1487 if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
1488 signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
1490 /* Add the value from the object file, shifted so that it is a
1491 straight number. */
1492 /* howto->bitpos == 0 */
1494 signed_check += signed_add;
1495 relocation += signed_add;
1497 BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
1499 /* Assumes two's complement. */
1500 if ( signed_check > reloc_signed_max
1501 || signed_check < reloc_signed_min)
1502 overflow = true;
1504 /* Put RELOCATION into the correct bits: */
1506 if (bfd_big_endian (input_bfd))
1508 relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1510 else
1512 relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1515 /* Add RELOCATION to the correct bits of X: */
1516 x = ((x & ~howto->dst_mask) | relocation);
1518 /* Put the relocated value back in the object file: */
1519 bfd_put_32 (input_bfd, x, location);
1521 rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
1524 else
1525 #endif /* THUMBEXTENSION */
1526 rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
1527 contents,
1528 rel->r_vaddr - input_section->vma,
1529 val, addend);
1530 #if 1 /* THUMBEXTENSION */
1531 /* FIXME:
1532 Is this the best way to fix up thumb addresses? krk@cygnus.com
1533 Probably not, but it works, and if it works it don't need fixing! nickc@cygnus.com */
1534 /* Only perform this fix during the final link, not a relocatable link. nickc@cygnus.com */
1535 if (! info->relocateable
1536 && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
1538 /* Determine if we need to set the bottom bit of a relocated address
1539 because the address is the address of a Thumb code symbol. */
1541 int patchit = false;
1543 if (h != NULL
1544 && ( h->class == C_THUMBSTATFUNC
1545 || h->class == C_THUMBEXTFUNC))
1547 patchit = true;
1549 else if (sym != NULL
1550 && sym->n_scnum > N_UNDEF)
1552 /* No hash entry - use the symbol instead. */
1554 if ( sym->n_sclass == C_THUMBSTATFUNC
1555 || sym->n_sclass == C_THUMBEXTFUNC)
1556 patchit = true;
1559 if (patchit)
1561 bfd_byte * location = contents + rel->r_vaddr - input_section->vma;
1562 bfd_vma x = bfd_get_32 (input_bfd, location);
1564 bfd_put_32 (input_bfd, x | 1, location);
1567 #endif /* THUMBEXTENSION */
1569 switch (rstat)
1571 default:
1572 abort ();
1573 case bfd_reloc_ok:
1574 break;
1575 case bfd_reloc_outofrange:
1576 (*_bfd_error_handler)
1577 (_("%s: bad reloc address 0x%lx in section `%s'"),
1578 bfd_get_filename (input_bfd),
1579 (unsigned long) rel->r_vaddr,
1580 bfd_get_section_name (input_bfd, input_section));
1581 return false;
1582 case bfd_reloc_overflow:
1584 const char *name;
1585 char buf[SYMNMLEN + 1];
1587 if (symndx == -1)
1588 name = "*ABS*";
1589 else if (h != NULL)
1590 name = h->root.root.string;
1591 else
1593 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1594 if (name == NULL)
1595 return false;
1598 if (! ((*info->callbacks->reloc_overflow)
1599 (info, name, howto->name, (bfd_vma) 0, input_bfd,
1600 input_section, rel->r_vaddr - input_section->vma)))
1601 return false;
1606 return true;
1609 #ifndef COFF_IMAGE_WITH_PE
1611 boolean
1612 bfd_arm_allocate_interworking_sections (info)
1613 struct bfd_link_info * info;
1615 asection * s;
1616 bfd_byte * foo;
1617 struct coff_arm_link_hash_table * globals;
1618 #if 0
1619 static char test_char = '1';
1620 #endif
1622 globals = coff_arm_hash_table (info);
1624 BFD_ASSERT (globals != NULL);
1626 if (globals->arm_glue_size != 0)
1628 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1630 s = bfd_get_section_by_name
1631 (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1633 BFD_ASSERT (s != NULL);
1635 foo = (bfd_byte *) bfd_alloc
1636 (globals->bfd_of_glue_owner, globals->arm_glue_size);
1637 #if 0
1638 memset (foo, test_char, globals->arm_glue_size);
1639 #endif
1641 s->_raw_size = s->_cooked_size = globals->arm_glue_size;
1642 s->contents = foo;
1645 if (globals->thumb_glue_size != 0)
1647 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1649 s = bfd_get_section_by_name
1650 (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1652 BFD_ASSERT (s != NULL);
1654 foo = (bfd_byte *) bfd_alloc
1655 (globals->bfd_of_glue_owner, globals->thumb_glue_size);
1656 #if 0
1657 memset (foo, test_char, globals->thumb_glue_size);
1658 #endif
1660 s->_raw_size = s->_cooked_size = globals->thumb_glue_size;
1661 s->contents = foo;
1664 return true;
1667 static void
1668 record_arm_to_thumb_glue (info, h)
1669 struct bfd_link_info * info;
1670 struct coff_link_hash_entry * h;
1672 const char * name = h->root.root.string;
1673 register asection * s;
1674 char * tmp_name;
1675 struct coff_link_hash_entry * myh;
1676 struct coff_arm_link_hash_table * globals;
1678 globals = coff_arm_hash_table (info);
1680 BFD_ASSERT (globals != NULL);
1681 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1683 s = bfd_get_section_by_name
1684 (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1686 BFD_ASSERT (s != NULL);
1688 tmp_name = ((char *)
1689 bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
1691 BFD_ASSERT (tmp_name);
1693 sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1695 myh = coff_link_hash_lookup
1696 (coff_hash_table (info), tmp_name, false, false, true);
1698 if (myh != NULL)
1700 free (tmp_name);
1701 return; /* we've already seen this guy */
1704 /* The only trick here is using globals->arm_glue_size as the value. Even
1705 though the section isn't allocated yet, this is where we will be putting
1706 it. */
1708 bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1709 BSF_GLOBAL,
1710 s, globals->arm_glue_size + 1,
1711 NULL, true, false,
1712 (struct bfd_link_hash_entry **) & myh);
1714 free (tmp_name);
1716 globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
1718 return;
1721 static void
1722 record_thumb_to_arm_glue (info, h)
1723 struct bfd_link_info * info;
1724 struct coff_link_hash_entry * h;
1726 const char * name = h->root.root.string;
1727 register asection * s;
1728 char * tmp_name;
1729 struct coff_link_hash_entry * myh;
1730 struct coff_arm_link_hash_table * globals;
1733 globals = coff_arm_hash_table (info);
1735 BFD_ASSERT (globals != NULL);
1736 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1738 s = bfd_get_section_by_name
1739 (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1741 BFD_ASSERT (s != NULL);
1743 tmp_name = (char *) bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
1745 BFD_ASSERT (tmp_name);
1747 sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1749 myh = coff_link_hash_lookup
1750 (coff_hash_table (info), tmp_name, false, false, true);
1752 if (myh != NULL)
1754 free (tmp_name);
1755 return; /* we've already seen this guy */
1758 bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1759 BSF_GLOBAL, s, globals->thumb_glue_size + 1,
1760 NULL, true, false,
1761 (struct bfd_link_hash_entry **) & myh);
1763 /* If we mark it 'thumb', the disassembler will do a better job. */
1764 myh->class = C_THUMBEXTFUNC;
1766 free (tmp_name);
1768 /* Allocate another symbol to mark where we switch to arm mode. */
1770 #define CHANGE_TO_ARM "__%s_change_to_arm"
1771 #define BACK_FROM_ARM "__%s_back_from_arm"
1773 tmp_name = (char *) bfd_malloc (strlen (name) + strlen (CHANGE_TO_ARM) + 1);
1775 BFD_ASSERT (tmp_name);
1777 sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
1779 myh = NULL;
1781 bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1782 BSF_LOCAL, s, globals->thumb_glue_size
1783 + (globals->support_old_code ? 8 : 4),
1784 NULL, true, false,
1785 (struct bfd_link_hash_entry **) & myh);
1787 free (tmp_name);
1789 globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
1791 return;
1794 /* Select a BFD to be used to hold the sections used by the glue code.
1795 This function is called from the linker scripts in ld/emultempl/
1796 {armcoff/pe}.em */
1798 boolean
1799 bfd_arm_get_bfd_for_interworking (abfd, info)
1800 bfd * abfd;
1801 struct bfd_link_info * info;
1803 struct coff_arm_link_hash_table * globals;
1804 flagword flags;
1805 asection * sec;
1807 /* If we are only performing a partial link do not bother
1808 getting a bfd to hold the glue. */
1809 if (info->relocateable)
1810 return true;
1812 globals = coff_arm_hash_table (info);
1814 BFD_ASSERT (globals != NULL);
1816 if (globals->bfd_of_glue_owner != NULL)
1817 return true;
1819 sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1821 if (sec == NULL)
1823 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
1825 sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1827 if (sec == NULL
1828 || ! bfd_set_section_flags (abfd, sec, flags)
1829 || ! bfd_set_section_alignment (abfd, sec, 2))
1830 return false;
1833 sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
1835 if (sec == NULL)
1837 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
1839 sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
1841 if (sec == NULL
1842 || ! bfd_set_section_flags (abfd, sec, flags)
1843 || ! bfd_set_section_alignment (abfd, sec, 2))
1844 return false;
1847 /* Save the bfd for later use. */
1848 globals->bfd_of_glue_owner = abfd;
1850 return true;
1853 boolean
1854 bfd_arm_process_before_allocation (abfd, info, support_old_code)
1855 bfd * abfd;
1856 struct bfd_link_info * info;
1857 int support_old_code;
1859 asection * sec;
1860 struct coff_arm_link_hash_table * globals;
1862 /* If we are only performing a partial link do not bother
1863 to construct any glue. */
1864 if (info->relocateable)
1865 return true;
1867 /* Here we have a bfd that is to be included on the link. We have a hook
1868 to do reloc rummaging, before section sizes are nailed down. */
1870 _bfd_coff_get_external_symbols (abfd);
1872 globals = coff_arm_hash_table (info);
1874 BFD_ASSERT (globals != NULL);
1875 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1877 globals->support_old_code = support_old_code;
1879 /* Rummage around all the relocs and map the glue vectors. */
1880 sec = abfd->sections;
1882 if (sec == NULL)
1883 return true;
1885 for (; sec != NULL; sec = sec->next)
1887 struct internal_reloc * i;
1888 struct internal_reloc * rel;
1890 if (sec->reloc_count == 0)
1891 continue;
1893 /* Load the relocs. */
1894 /* FIXME: there may be a storage leak here. */
1896 i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0);
1898 BFD_ASSERT (i != 0);
1900 for (rel = i; rel < i + sec->reloc_count; ++rel)
1902 unsigned short r_type = rel->r_type;
1903 long symndx;
1904 struct coff_link_hash_entry * h;
1906 symndx = rel->r_symndx;
1908 /* If the relocation is not against a symbol it cannot concern us. */
1909 if (symndx == -1)
1910 continue;
1912 h = obj_coff_sym_hashes (abfd)[symndx];
1914 /* If the relocation is against a static symbol it must be within
1915 the current section and so cannot be a cross ARM/Thumb relocation. */
1916 if (h == NULL)
1917 continue;
1919 switch (r_type)
1921 case ARM_26:
1922 /* This one is a call from arm code. We need to look up
1923 the target of the call. If it is a thumb target, we
1924 insert glue. */
1926 if (h->class == C_THUMBEXTFUNC)
1927 record_arm_to_thumb_glue (info, h);
1928 break;
1930 case ARM_THUMB23:
1931 /* This one is a call from thumb code. We used to look
1932 for ARM_THUMB9 and ARM_THUMB12 as well. We need to look
1933 up the target of the call. If it is an arm target, we
1934 insert glue. If the symbol does not exist it will be
1935 given a class of C_EXT and so we will generate a stub
1936 for it. This is not really a problem, since the link
1937 is doomed anyway. */
1939 switch (h->class)
1941 case C_EXT:
1942 case C_STAT:
1943 case C_LABEL:
1944 record_thumb_to_arm_glue (info, h);
1945 break;
1946 default:
1949 break;
1951 default:
1952 break;
1957 return true;
1960 #endif /* ! defined (COFF_IMAGE_WITH_PE) */
1962 #define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
1963 #define coff_relocate_section coff_arm_relocate_section
1964 #define coff_bfd_is_local_label_name coff_arm_is_local_label_name
1965 #define coff_adjust_symndx coff_arm_adjust_symndx
1966 #define coff_link_output_has_begun coff_arm_link_output_has_begun
1967 #define coff_final_link_postscript coff_arm_final_link_postscript
1968 #define coff_bfd_merge_private_bfd_data coff_arm_merge_private_bfd_data
1969 #define coff_bfd_print_private_bfd_data coff_arm_print_private_bfd_data
1970 #define coff_bfd_set_private_flags _bfd_coff_arm_set_private_flags
1971 #define coff_bfd_copy_private_bfd_data coff_arm_copy_private_bfd_data
1972 #define coff_bfd_link_hash_table_create coff_arm_link_hash_table_create
1975 /* When doing a relocateable link, we want to convert ARM26 relocs
1976 into ARM26D relocs. */
1978 static boolean
1979 coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp)
1980 bfd *obfd ATTRIBUTE_UNUSED;
1981 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1982 bfd *ibfd;
1983 asection *sec;
1984 struct internal_reloc *irel;
1985 boolean *adjustedp;
1987 if (irel->r_type == 3)
1989 struct coff_link_hash_entry *h;
1991 h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
1992 if (h != NULL
1993 && (h->root.type == bfd_link_hash_defined
1994 || h->root.type == bfd_link_hash_defweak)
1995 && h->root.u.def.section->output_section == sec->output_section)
1996 irel->r_type = 7;
1998 *adjustedp = false;
1999 return true;
2002 /* Called when merging the private data areas of two BFDs.
2003 This is important as it allows us to detect if we are
2004 attempting to merge binaries compiled for different ARM
2005 targets, eg different CPUs or differents APCS's. */
2007 static boolean
2008 coff_arm_merge_private_bfd_data (ibfd, obfd)
2009 bfd * ibfd;
2010 bfd * obfd;
2012 BFD_ASSERT (ibfd != NULL && obfd != NULL);
2014 if (ibfd == obfd)
2015 return true;
2017 /* If the two formats are different we cannot merge anything.
2018 This is not an error, since it is permissable to change the
2019 input and output formats. */
2020 if ( ibfd->xvec->flavour != bfd_target_coff_flavour
2021 || obfd->xvec->flavour != bfd_target_coff_flavour)
2022 return true;
2024 /* Verify that the APCS is the same for the two BFDs */
2025 if (APCS_SET (ibfd))
2027 if (APCS_SET (obfd))
2029 /* If the src and dest have different APCS flag bits set, fail. */
2030 if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
2032 _bfd_error_handler
2033 /* xgettext: c-format */
2034 (_("%s: ERROR: compiled for APCS-%d whereas target %s uses APCS-%d"),
2035 bfd_get_filename (ibfd), APCS_26_FLAG (ibfd) ? 26 : 32,
2036 bfd_get_filename (obfd), APCS_26_FLAG (obfd) ? 26 : 32
2039 bfd_set_error (bfd_error_wrong_format);
2040 return false;
2043 if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
2045 const char *msg;
2047 if (APCS_FLOAT_FLAG (ibfd))
2048 /* xgettext: c-format */
2049 msg = _("%s: ERROR: passes floats in float registers whereas target %s uses integer registers");
2050 else
2051 /* xgettext: c-format */
2052 msg = _("%s: ERROR: passes floats in integer registers whereas target %s uses float registers");
2054 _bfd_error_handler (msg, bfd_get_filename (ibfd),
2055 bfd_get_filename (obfd));
2057 bfd_set_error (bfd_error_wrong_format);
2058 return false;
2061 if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
2063 const char * msg;
2065 if (PIC_FLAG (ibfd))
2066 /* xgettext: c-format */
2067 msg = _("%s: ERROR: compiled as position independent code, whereas target %s is absolute position");
2068 else
2069 /* xgettext: c-format */
2070 msg = _("%s: ERROR: compiled as absolute position code, whereas target %s is position independent");
2071 _bfd_error_handler (msg, bfd_get_filename (ibfd),
2072 bfd_get_filename (obfd));
2074 bfd_set_error (bfd_error_wrong_format);
2075 return false;
2078 else
2080 SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd));
2082 /* Set up the arch and fields as well as these are probably wrong. */
2083 bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2087 /* Check the interworking support. */
2088 if (INTERWORK_SET (ibfd))
2090 if (INTERWORK_SET (obfd))
2092 /* If the src and dest differ in their interworking issue a warning. */
2093 if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
2095 const char * msg;
2097 if (INTERWORK_FLAG (ibfd))
2098 /* xgettext: c-format */
2099 msg = _("Warning: input file %s supports interworking, whereas %s does not.");
2100 else
2101 /* xgettext: c-format */
2102 msg = _("Warning: input file %s does not support interworking, whereas %s does.");
2104 _bfd_error_handler (msg, bfd_get_filename (ibfd),
2105 bfd_get_filename (obfd));
2108 else
2110 SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
2114 return true;
2118 /* Display the flags field. */
2120 static boolean
2121 coff_arm_print_private_bfd_data (abfd, ptr)
2122 bfd * abfd;
2123 PTR ptr;
2125 FILE * file = (FILE *) ptr;
2127 BFD_ASSERT (abfd != NULL && ptr != NULL);
2129 /* xgettext:c-format */
2130 fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
2132 if (APCS_SET (abfd))
2134 /* xgettext: APCS is ARM Prodecure Call Standard, it should not be translated. */
2135 fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32);
2137 if (APCS_FLOAT_FLAG (abfd))
2138 fprintf (file, _(" [floats passed in float registers]"));
2139 else
2140 fprintf (file, _(" [floats passed in integer registers]"));
2142 if (PIC_FLAG (abfd))
2143 fprintf (file, _(" [position independent]"));
2144 else
2145 fprintf (file, _(" [absolute position]"));
2148 if (! INTERWORK_SET (abfd))
2149 fprintf (file, _(" [interworking flag not initialised]"));
2150 else if (INTERWORK_FLAG (abfd))
2151 fprintf (file, _(" [interworking supported]"));
2152 else
2153 fprintf (file, _(" [interworking not supported]"));
2155 fputc ('\n', file);
2157 return true;
2161 /* Copies the given flags into the coff_tdata.flags field.
2162 Typically these flags come from the f_flags[] field of
2163 the COFF filehdr structure, which contains important,
2164 target specific information.
2165 Note: Although this function is static, it is explicitly
2166 called from both coffcode.h and peicode.h. */
2168 static boolean
2169 _bfd_coff_arm_set_private_flags (abfd, flags)
2170 bfd * abfd;
2171 flagword flags;
2173 flagword flag;
2175 BFD_ASSERT (abfd != NULL);
2177 flag = (flags & F_APCS26) ? F_APCS_26 : 0;
2179 /* Make sure that the APCS field has not been initialised to the opposite
2180 value. */
2181 if (APCS_SET (abfd)
2182 && ( (APCS_26_FLAG (abfd) != flag)
2183 || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
2184 || (PIC_FLAG (abfd) != (flags & F_PIC))
2186 return false;
2188 flag |= (flags & (F_APCS_FLOAT | F_PIC));
2190 SET_APCS_FLAGS (abfd, flag);
2192 flag = (flags & F_INTERWORK);
2194 /* If the BFD has already had its interworking flag set, but it
2195 is different from the value that we have been asked to set,
2196 then assume that that merged code will not support interworking
2197 and set the flag accordingly. */
2198 if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
2200 if (flag)
2201 /* xgettext: c-format */
2202 _bfd_error_handler (_("Warning: Not setting interworking flag of %s, since it has already been specified as non-interworking"),
2203 bfd_get_filename (abfd));
2204 else
2205 /* xgettext: c-format */
2206 _bfd_error_handler (_("Warning: Clearing the interworking flag of %s due to outside request"),
2207 bfd_get_filename (abfd));
2208 flag = 0;
2211 SET_INTERWORK_FLAG (abfd, flag);
2213 return true;
2217 /* Copy the important parts of the target specific data
2218 from one instance of a BFD to another. */
2220 static boolean
2221 coff_arm_copy_private_bfd_data (src, dest)
2222 bfd * src;
2223 bfd * dest;
2225 BFD_ASSERT (src != NULL && dest != NULL);
2227 if (src == dest)
2228 return true;
2230 /* If the destination is not in the same format as the source, do not do
2231 the copy. */
2232 if (src->xvec != dest->xvec)
2233 return true;
2235 /* copy the flags field */
2236 if (APCS_SET (src))
2238 if (APCS_SET (dest))
2240 /* If the src and dest have different APCS flag bits set, fail. */
2241 if (APCS_26_FLAG (dest) != APCS_26_FLAG (src))
2242 return false;
2244 if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
2245 return false;
2247 if (PIC_FLAG (dest) != PIC_FLAG (src))
2248 return false;
2250 else
2251 SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src)
2252 | PIC_FLAG (src));
2255 if (INTERWORK_SET (src))
2257 if (INTERWORK_SET (dest))
2259 /* If the src and dest have different interworking flags then turn
2260 off the interworking bit. */
2261 if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src))
2263 if (INTERWORK_FLAG (dest))
2265 /* xgettext:c-format */
2266 _bfd_error_handler (("Warning: Clearing the interworking bit of %s, because the non-interworking code in %s has been copied into it"),
2267 bfd_get_filename (dest),
2268 bfd_get_filename (src));
2271 SET_INTERWORK_FLAG (dest, 0);
2274 else
2276 SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
2280 return true;
2283 /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
2284 *must* match the definitions in gcc/config/arm/coff.h and semi.h */
2285 #define LOCAL_LABEL_PREFIX "."
2286 #ifndef USER_LABEL_PREFIX
2287 #define USER_LABEL_PREFIX "_"
2288 #endif
2290 /* Like _bfd_coff_is_local_label_name, but
2291 a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
2292 non-local.
2293 b) Allow other prefixes than ".", e.g. an empty prefix would cause all
2294 labels of the form Lxxx to be stripped. */
2295 static boolean
2296 coff_arm_is_local_label_name (abfd, name)
2297 bfd * abfd ATTRIBUTE_UNUSED;
2298 const char * name;
2300 #ifdef USER_LABEL_PREFIX
2301 if (USER_LABEL_PREFIX[0] != 0)
2303 if (strncmp (name, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)) == 0)
2304 return false;
2306 #endif
2308 #ifdef LOCAL_LABEL_PREFIX
2309 /* If there is a prefix for local labels then look for this.
2310 If the prefix exists, but it is empty, then ignore the test. */
2312 if (LOCAL_LABEL_PREFIX[0] != 0)
2314 int len = strlen (LOCAL_LABEL_PREFIX);
2316 if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0)
2317 return false;
2319 /* Perform the checks below for the rest of the name. */
2320 name += len;
2322 #endif
2324 return name[0] == 'L';
2327 /* This piece of machinery exists only to guarantee that the bfd that holds
2328 the glue section is written last.
2330 This does depend on bfd_make_section attaching a new section to the
2331 end of the section list for the bfd.
2333 krk@cygnus.com */
2335 static boolean
2336 coff_arm_link_output_has_begun (sub, info)
2337 bfd * sub;
2338 struct coff_final_link_info * info;
2340 return (sub->output_has_begun
2341 || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner);
2344 static boolean
2345 coff_arm_final_link_postscript (abfd, pfinfo)
2346 bfd * abfd ATTRIBUTE_UNUSED;
2347 struct coff_final_link_info * pfinfo;
2349 struct coff_arm_link_hash_table * globals;
2351 globals = coff_arm_hash_table (pfinfo->info);
2353 BFD_ASSERT (globals != NULL);
2355 if (globals->bfd_of_glue_owner != NULL)
2357 if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner))
2358 return false;
2360 globals->bfd_of_glue_owner->output_has_begun = true;
2363 return true;
2366 #if 0
2367 #define coff_SWAP_sym_in arm_bfd_coff_swap_sym_in
2369 static void coff_swap_sym_in PARAMS ((bfd *, PTR, PTR));
2371 /* Sepcial version of symbol swapper, used to grab a bfd
2372 onto which the glue sections can be attached. */
2373 static void
2374 arm_bfd_coff_swap_sym_in (abfd, ext1, in1)
2375 bfd * abfd;
2376 PTR ext1;
2377 PTR in1;
2379 flagword flags;
2380 register asection * s;
2382 /* Do the normal swap in. */
2383 coff_swap_sym_in (abfd, ext1, in1);
2385 if (bfd_of_glue_owner != NULL) /* we already have a toc, so go home */
2386 return;
2388 /* Save the bfd for later allocation. */
2389 bfd_of_glue_owner = abfd;
2391 s = bfd_get_section_by_name (bfd_of_glue_owner ,
2392 ARM2THUMB_GLUE_SECTION_NAME);
2394 if (s == NULL)
2396 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
2398 s = bfd_make_section (bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
2400 if (s == NULL
2401 || !bfd_set_section_flags (bfd_of_glue_owner, s, flags)
2402 || !bfd_set_section_alignment (bfd_of_glue_owner, s, 2))
2404 /* FIXME: set appropriate bfd error */
2405 abort();
2409 s = bfd_get_section_by_name (bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
2411 if (s == NULL)
2413 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
2415 s = bfd_make_section (bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
2417 if (s == NULL
2418 || !bfd_set_section_flags (bfd_of_glue_owner, s, flags)
2419 || !bfd_set_section_alignment (bfd_of_glue_owner, s, 2))
2421 /* FIXME: set appropriate bfd error krk@cygnus.com */
2422 abort();
2426 return;
2428 #endif
2430 #include "coffcode.h"
2432 #ifndef TARGET_LITTLE_SYM
2433 #define TARGET_LITTLE_SYM armcoff_little_vec
2434 #endif
2435 #ifndef TARGET_LITTLE_NAME
2436 #define TARGET_LITTLE_NAME "coff-arm-little"
2437 #endif
2438 #ifndef TARGET_BIG_SYM
2439 #define TARGET_BIG_SYM armcoff_big_vec
2440 #endif
2441 #ifndef TARGET_BIG_NAME
2442 #define TARGET_BIG_NAME "coff-arm-big"
2443 #endif
2445 #ifndef TARGET_UNDERSCORE
2446 #define TARGET_UNDERSCORE 0
2447 #endif
2449 #ifdef COFF_WITH_PE
2450 #define EXTRA_S_FLAGS (SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
2451 #else
2452 #define EXTRA_S_FLAGS 0
2453 #endif
2455 /* Forward declaration for use initialising alternative_target field. */
2456 extern const bfd_target TARGET_BIG_SYM ;
2458 /* Target vectors. */
2459 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM)
2460 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM)