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. */
28 #include "coff/internal.h"
36 /* Macros for manipulation the bits in the flags field of the coff data
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
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 *));
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,
130 arelent *reloc_entry;
131 asymbol *symbol ATTRIBUTE_UNUSED;
133 asection *input_section ATTRIBUTE_UNUSED;
135 char **error_message ATTRIBUTE_UNUSED;
138 if (output_bfd == (bfd *) NULL)
139 return bfd_reloc_continue;
141 diff = reloc_entry->addend;
144 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
148 reloc_howto_type *howto = reloc_entry->howto;
149 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
155 char x = bfd_get_8 (abfd, addr);
157 bfd_put_8 (abfd, x, addr);
163 short x = bfd_get_16 (abfd, addr);
165 bfd_put_16 (abfd, x, addr);
171 long x = bfd_get_32 (abfd, addr);
173 bfd_put_32 (abfd, x, addr);
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
189 #ifndef TARGET_UNDERSCORE
190 #define TARGET_UNDERSCORE '_'
194 #define PCRELOFFSET true
197 /* These most certainly belong somewhere else. Just had to get rid of
198 the manifest constants in the code. */
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 */
223 false, /* pc_relative */
225 complain_overflow_bitfield, /* complain_on_overflow */
226 coff_arm_reloc, /* special_function */
228 true, /* partial_inplace */
229 0x000000ff, /* src_mask */
230 0x000000ff, /* dst_mask */
231 PCRELOFFSET /* pcrel_offset */),
238 complain_overflow_bitfield,
251 complain_overflow_bitfield,
264 complain_overflow_signed,
265 aoutarm_fix_pcrel_26 ,
277 complain_overflow_signed,
290 complain_overflow_signed,
303 complain_overflow_signed,
316 complain_overflow_dont,
317 aoutarm_fix_pcrel_26_done,
331 complain_overflow_bitfield,
344 complain_overflow_bitfield,
357 complain_overflow_bitfield,
370 complain_overflow_signed,
383 complain_overflow_signed,
384 coff_thumb_pcrel_12 ,
396 complain_overflow_signed,
397 coff_thumb_pcrel_23 ,
406 /* Return true if this relocation should
407 appear in the output .reloc section. */
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;
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;
428 struct internal_reloc *rel;
429 struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
430 struct internal_syment *sym ATTRIBUTE_UNUSED;
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;
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. */
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)
468 arelent *reloc_entry;
471 asection *input_section;
473 char **error_message ATTRIBUTE_UNUSED;
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;
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];
524 static bfd_reloc_status_type
525 coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section,
526 output_bfd, error_message, btype)
528 arelent *reloc_entry;
531 asection *input_section;
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;
544 /* NOTE: This routine is currently used by GAS, but not by the link
552 signbit = 0x00000100;
558 signbit = 0x00000800;
564 signbit = 0x00400000;
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;
586 relocation = ((target & dstmsk) << 1);
590 if (bfd_big_endian (abfd))
591 relocation = ((target & 0x7ff) << 1) | ((target & 0x07ff0000) >> 4);
593 relocation = ((target & 0x7ff) << 12) | ((target & 0x07ff0000) >> 15);
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;
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;
626 target |= (relocation >> 1);
630 if (bfd_big_endian (abfd))
631 target |= ((relocation & 0xfff) >> 1) | ((relocation << 4) & 0x07ff0000);
633 target |= ((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff);
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 */
650 static bfd_reloc_status_type
651 coff_thumb_pcrel_23 (abfd, reloc_entry, symbol, data, input_section,
652 output_bfd, error_message)
654 arelent *reloc_entry;
657 asection *input_section;
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)
669 arelent *reloc_entry;
672 asection *input_section;
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)
684 arelent *reloc_entry;
687 asection *input_section;
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)
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)
708 default: return (CONST struct reloc_howto_struct *) 0;
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)
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)
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;
789 arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
790 struct bfd_link_info *info;
792 asection *input_section;
793 bfd_vma reloc_offset;
795 bfd_vma addr = reloc_offset
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
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
817 Combine together and shifted left by 1 (it's a half word address) and
821 H-0, upper address-0 = 000
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
838 insert_thumb_branch (br_insn, 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;
857 abort(); /* error - not a valid branch instruction form */
859 /* FIXME: abort is probably not the right call. krk@cygnus.com */
865 static struct coff_link_hash_entry *
866 find_thumb_glue (info, name, input_bfd)
867 struct bfd_link_info * info;
872 struct coff_link_hash_entry * myh;
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);
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);
894 static struct coff_link_hash_entry *
895 find_arm_glue (info, name, input_bfd)
896 struct bfd_link_info * info;
901 struct coff_link_hash_entry * myh;
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);
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);
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
944 __func_from_thumb: __func_from_thumb:
946 nop ldr r6, __func_addr
948 __func_change_to_arm: bx r6
950 __func_back_to_thumb:
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;
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
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.
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. */
1011 coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1012 contents, relocs, syms, sections)
1014 struct bfd_link_info *info;
1016 asection *input_section;
1018 struct internal_reloc *relocs;
1019 struct internal_syment *syms;
1020 asection **sections;
1022 struct internal_reloc * rel;
1023 struct internal_reloc * relend;
1026 relend = rel + input_section->reloc_count;
1028 for (; rel < relend; rel++)
1032 struct coff_link_hash_entry * h;
1033 struct internal_syment * sym;
1036 reloc_howto_type * howto;
1037 bfd_reloc_status_type rstat;
1040 symndx = rel->r_symndx;
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;
1064 howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
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
1074 if (rel->r_type == ARM_26
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 =
1088 complain_overflow_signed,
1089 aoutarm_fix_pcrel_26 ,
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)
1108 if (sym != NULL && sym->n_scnum != 0)
1109 addend += sym->n_value;
1120 sec = bfd_abs_section_ptr;
1125 sec = sections[symndx];
1126 val = (sec->output_section->vma
1127 + sec->output_offset
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;
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);
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))
1189 /* xgettext:c-format */
1190 (_("%s(%s): warning: interworking not enabled."),
1191 bfd_get_filename (h_sec->owner), name);
1193 /* xgettext:c-format */
1194 (_(" first occurrence: %s: arm call to thumb"),
1195 bfd_get_filename (input_bfd));
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,
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. */
1228 + s->output_section->vma
1229 - (input_section->output_offset
1230 + input_section->output_section->vma
1234 tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1236 bfd_put_32 (output_bfd, tmp, contents + rel->r_vaddr
1237 - input_section->vma);
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 */
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);
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)
1283 /* xgettext:c-format */
1284 (_("%s(%s): warning: interworking not enabled."),
1285 bfd_get_filename (h_sec->owner), name);
1287 /* xgettext:c-format */
1288 (_(" first occurrence: %s: thumb call to arm"),
1289 bfd_get_filename (input_bfd));
1291 (_(" consider relinking with --support-old-code enabled"));
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);
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);
1333 ((bfd_signed_vma) h_val) /* Address of destination of the stub */
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
1355 - (input_section->output_offset
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);
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. */
1377 rstat = bfd_reloc_ok;
1379 #endif /* THUMBEXTENSION */
1380 if ( h->root.type == bfd_link_hash_defined
1381 || h->root.type == bfd_link_hash_defweak)
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)))
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 */
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
1422 bfd_vma address = rel->r_vaddr - input_section->vma;
1424 if (address > input_section->_raw_size)
1425 rstat = bfd_reloc_outofrange;
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;
1437 bfd_signed_vma signed_check;
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;
1462 signed_check = (check
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);
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
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
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)
1504 /* Put RELOCATION into the correct bits: */
1506 if (bfd_big_endian (input_bfd))
1508 relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
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;
1525 #endif /* THUMBEXTENSION */
1526 rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
1528 rel->r_vaddr - input_section->vma,
1530 #if 1 /* THUMBEXTENSION */
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;
1544 && ( h->class == C_THUMBSTATFUNC
1545 || h->class == C_THUMBEXTFUNC))
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)
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 */
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));
1582 case bfd_reloc_overflow:
1585 char buf[SYMNMLEN + 1];
1590 name = h->root.root.string;
1593 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
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)))
1609 #ifndef COFF_IMAGE_WITH_PE
1612 bfd_arm_allocate_interworking_sections (info)
1613 struct bfd_link_info * info;
1617 struct coff_arm_link_hash_table * globals;
1619 static char test_char = '1';
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);
1638 memset (foo, test_char, globals->arm_glue_size);
1641 s->_raw_size = s->_cooked_size = globals->arm_glue_size;
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);
1657 memset (foo, test_char, globals->thumb_glue_size);
1660 s->_raw_size = s->_cooked_size = globals->thumb_glue_size;
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;
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);
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
1708 bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1710 s, globals->arm_glue_size + 1,
1712 (struct bfd_link_hash_entry **) & myh);
1716 globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
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;
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);
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,
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;
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);
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),
1785 (struct bfd_link_hash_entry **) & myh);
1789 globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
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/
1799 bfd_arm_get_bfd_for_interworking (abfd, info)
1801 struct bfd_link_info * info;
1803 struct coff_arm_link_hash_table * globals;
1807 /* If we are only performing a partial link do not bother
1808 getting a bfd to hold the glue. */
1809 if (info->relocateable)
1812 globals = coff_arm_hash_table (info);
1814 BFD_ASSERT (globals != NULL);
1816 if (globals->bfd_of_glue_owner != NULL)
1819 sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1823 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
1825 sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1828 || ! bfd_set_section_flags (abfd, sec, flags)
1829 || ! bfd_set_section_alignment (abfd, sec, 2))
1833 sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
1837 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
1839 sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
1842 || ! bfd_set_section_flags (abfd, sec, flags)
1843 || ! bfd_set_section_alignment (abfd, sec, 2))
1847 /* Save the bfd for later use. */
1848 globals->bfd_of_glue_owner = abfd;
1854 bfd_arm_process_before_allocation (abfd, info, support_old_code)
1856 struct bfd_link_info * info;
1857 int support_old_code;
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)
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;
1885 for (; sec != NULL; sec = sec->next)
1887 struct internal_reloc * i;
1888 struct internal_reloc * rel;
1890 if (sec->reloc_count == 0)
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;
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. */
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. */
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
1926 if (h->class == C_THUMBEXTFUNC)
1927 record_arm_to_thumb_glue (info, h);
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. */
1944 record_thumb_to_arm_glue (info, h);
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. */
1979 coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp)
1980 bfd *obfd ATTRIBUTE_UNUSED;
1981 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1984 struct internal_reloc *irel;
1987 if (irel->r_type == 3)
1989 struct coff_link_hash_entry *h;
1991 h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
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)
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. */
2008 coff_arm_merge_private_bfd_data (ibfd, obfd)
2012 BFD_ASSERT (ibfd != NULL && obfd != NULL);
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)
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))
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);
2043 if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
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");
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);
2061 if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
2065 if (PIC_FLAG (ibfd))
2066 /* xgettext: c-format */
2067 msg = _("%s: ERROR: compiled as position independent code, whereas target %s is absolute position");
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);
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))
2097 if (INTERWORK_FLAG (ibfd))
2098 /* xgettext: c-format */
2099 msg = _("Warning: input file %s supports interworking, whereas %s does not.");
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));
2110 SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
2118 /* Display the flags field. */
2121 coff_arm_print_private_bfd_data (abfd, 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]"));
2140 fprintf (file, _(" [floats passed in integer registers]"));
2142 if (PIC_FLAG (abfd))
2143 fprintf (file, _(" [position independent]"));
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]"));
2153 fprintf (file, _(" [interworking not supported]"));
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. */
2169 _bfd_coff_arm_set_private_flags (abfd, flags)
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
2182 && ( (APCS_26_FLAG (abfd) != flag)
2183 || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
2184 || (PIC_FLAG (abfd) != (flags & F_PIC))
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))
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));
2205 /* xgettext: c-format */
2206 _bfd_error_handler (_("Warning: Clearing the interworking flag of %s due to outside request"),
2207 bfd_get_filename (abfd));
2211 SET_INTERWORK_FLAG (abfd, flag);
2217 /* Copy the important parts of the target specific data
2218 from one instance of a BFD to another. */
2221 coff_arm_copy_private_bfd_data (src, dest)
2225 BFD_ASSERT (src != NULL && dest != NULL);
2230 /* If the destination is not in the same format as the source, do not do
2232 if (src->xvec != dest->xvec)
2235 /* copy the flags field */
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))
2244 if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
2247 if (PIC_FLAG (dest) != PIC_FLAG (src))
2251 SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_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);
2276 SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
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 "_"
2290 /* Like _bfd_coff_is_local_label_name, but
2291 a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
2293 b) Allow other prefixes than ".", e.g. an empty prefix would cause all
2294 labels of the form Lxxx to be stripped. */
2296 coff_arm_is_local_label_name (abfd, name)
2297 bfd * abfd ATTRIBUTE_UNUSED;
2300 #ifdef USER_LABEL_PREFIX
2301 if (USER_LABEL_PREFIX[0] != 0)
2303 if (strncmp (name, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)) == 0)
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)
2319 /* Perform the checks below for the rest of the name. */
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.
2336 coff_arm_link_output_has_begun (sub, info)
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);
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))
2360 globals->bfd_of_glue_owner->output_has_begun = true;
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. */
2374 arm_bfd_coff_swap_sym_in (abfd, ext1, in1)
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 */
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);
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);
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 */
2409 s = bfd_get_section_by_name (bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
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);
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 */
2430 #include "coffcode.h"
2432 #ifndef TARGET_LITTLE_SYM
2433 #define TARGET_LITTLE_SYM armcoff_little_vec
2435 #ifndef TARGET_LITTLE_NAME
2436 #define TARGET_LITTLE_NAME "coff-arm-little"
2438 #ifndef TARGET_BIG_SYM
2439 #define TARGET_BIG_SYM armcoff_big_vec
2441 #ifndef TARGET_BIG_NAME
2442 #define TARGET_BIG_NAME "coff-arm-big"
2445 #ifndef TARGET_UNDERSCORE
2446 #define TARGET_UNDERSCORE 0
2450 #define EXTRA_S_FLAGS (SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
2452 #define EXTRA_S_FLAGS 0
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)