1 /* BFD back-end for ARM COFF files.
2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
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))
52 static boolean coff_arm_relocate_section
53 PARAMS ((bfd
*, struct bfd_link_info
*, bfd
*, asection
*, bfd_byte
*,
54 struct internal_reloc
*, struct internal_syment
*, asection
**));
56 static bfd_reloc_status_type
57 aoutarm_fix_pcrel_26_done
PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
,
58 asection
*, bfd
*, char **));
60 static bfd_reloc_status_type
61 aoutarm_fix_pcrel_26
PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
,
62 asection
*, bfd
*, char **));
64 static bfd_reloc_status_type
65 coff_thumb_pcrel_23
PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
,
66 asection
*, bfd
*, char **));
68 static bfd_reloc_status_type
69 coff_thumb_pcrel_12
PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
,
70 asection
*, bfd
*, char **));
72 static bfd_reloc_status_type
73 coff_thumb_pcrel_9
PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
,
74 asection
*, bfd
*, char **));
76 static bfd_reloc_status_type
77 coff_arm_reloc
PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*,
81 coff_arm_adjust_symndx
PARAMS ((bfd
*, struct bfd_link_info
*, bfd
*,
82 asection
*, struct internal_reloc
*,
85 /* The linker script knows the section names for placement.
86 The entry_names are used to do simple name mangling on the stubs.
87 Given a function name, and its type, the stub can be found. The
88 name can be changed. The only requirement is the %s be present.
91 #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
92 #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
94 #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
95 #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
97 /* Used by the assembler. */
98 static bfd_reloc_status_type
99 coff_arm_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
, output_bfd
,
102 arelent
*reloc_entry
;
105 asection
*input_section
;
107 char **error_message
;
110 if (output_bfd
== (bfd
*) NULL
)
111 return bfd_reloc_continue
;
113 diff
= reloc_entry
->addend
;
116 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
120 reloc_howto_type
*howto
= reloc_entry
->howto
;
121 unsigned char *addr
= (unsigned char *) data
+ reloc_entry
->address
;
127 char x
= bfd_get_8 (abfd
, addr
);
129 bfd_put_8 (abfd
, x
, addr
);
135 short x
= bfd_get_16 (abfd
, addr
);
137 bfd_put_16 (abfd
, x
, addr
);
143 long x
= bfd_get_32 (abfd
, addr
);
145 bfd_put_32 (abfd
, x
, addr
);
154 /* Now let bfd_perform_relocation finish everything up. */
155 return bfd_reloc_continue
;
158 #define TARGET_UNDERSCORE '_'
161 #define PCRELOFFSET true
164 /* These most certainly belong somewhere else. Just had to get rid of
165 the manifest constants in the code. */
179 #define ARM_THUMB9 12
180 #define ARM_THUMB12 13
181 #define ARM_THUMB23 14
183 static reloc_howto_type aoutarm_std_reloc_howto
[] =
185 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
186 HOWTO(ARM_8
, /* type */
190 false, /* pc_relative */
192 complain_overflow_bitfield
, /* complain_on_overflow */
193 coff_arm_reloc
, /* special_function */
195 true, /* partial_inplace */
196 0x000000ff, /* src_mask */
197 0x000000ff, /* dst_mask */
198 PCRELOFFSET
/* pcrel_offset */),
205 complain_overflow_bitfield
,
218 complain_overflow_bitfield
,
231 complain_overflow_signed
,
232 aoutarm_fix_pcrel_26
,
244 complain_overflow_signed
,
257 complain_overflow_signed
,
270 complain_overflow_signed
,
283 complain_overflow_signed
,
284 aoutarm_fix_pcrel_26_done
,
298 complain_overflow_bitfield
,
311 complain_overflow_bitfield
,
324 complain_overflow_bitfield
,
337 complain_overflow_signed
,
350 complain_overflow_signed
,
351 coff_thumb_pcrel_12
,
363 complain_overflow_signed
,
364 coff_thumb_pcrel_23
,
373 /* Return true if this relocation should
374 appear in the output .reloc section. */
377 in_reloc_p (abfd
, howto
)
379 reloc_howto_type
* howto
;
381 return !howto
->pc_relative
&& howto
->type
!= ARM_RVA32
;
386 #define RTYPE2HOWTO(cache_ptr, dst) \
387 (cache_ptr)->howto = aoutarm_std_reloc_howto + (dst)->r_type;
389 #define coff_rtype_to_howto coff_arm_rtype_to_howto
391 static reloc_howto_type
*
392 coff_arm_rtype_to_howto (abfd
, sec
, rel
, h
, sym
, addendp
)
395 struct internal_reloc
*rel
;
396 struct coff_link_hash_entry
*h
;
397 struct internal_syment
*sym
;
400 reloc_howto_type
*howto
;
402 howto
= aoutarm_std_reloc_howto
+ rel
->r_type
;
404 if (rel
->r_type
== ARM_RVA32
)
406 *addendp
-= pe_data(sec
->output_section
->owner
)->pe_opthdr
.ImageBase
;
409 /* The relocation_section function will skip pcrel_offset relocs
410 when doing a relocateable link. However, we want to convert
411 ARM26 to ARM26D relocs if possible. We return a fake howto in
412 this case without pcrel_offset set, and adjust the addend to
414 if (rel
->r_type
== ARM_26
416 && (h
->root
.type
== bfd_link_hash_defined
417 || h
->root
.type
== bfd_link_hash_defweak
)
418 && h
->root
.u
.def
.section
->output_section
== sec
->output_section
)
420 static reloc_howto_type fake_arm26_reloc
=
427 complain_overflow_signed
,
428 aoutarm_fix_pcrel_26
,
435 *addendp
-= rel
->r_vaddr
- sec
->vma
;
436 return & fake_arm26_reloc
;
442 /* Used by the assembler. */
444 static bfd_reloc_status_type
445 aoutarm_fix_pcrel_26_done (abfd
, reloc_entry
, symbol
, data
, input_section
,
446 output_bfd
, error_message
)
448 arelent
*reloc_entry
;
451 asection
*input_section
;
453 char **error_message
;
455 /* This is dead simple at present. */
459 /* Used by the assembler. */
461 static bfd_reloc_status_type
462 aoutarm_fix_pcrel_26 (abfd
, reloc_entry
, symbol
, data
, input_section
,
463 output_bfd
, error_message
)
465 arelent
*reloc_entry
;
468 asection
*input_section
;
470 char **error_message
;
473 bfd_size_type addr
= reloc_entry
->address
;
474 long target
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ addr
);
475 bfd_reloc_status_type flag
= bfd_reloc_ok
;
477 /* If this is an undefined symbol, return error */
478 if (symbol
->section
== &bfd_und_section
479 && (symbol
->flags
& BSF_WEAK
) == 0)
480 return output_bfd
? bfd_reloc_continue
: bfd_reloc_undefined
;
482 /* If the sections are different, and we are doing a partial relocation,
483 just ignore it for now. */
484 if (symbol
->section
->name
!= input_section
->name
485 && output_bfd
!= (bfd
*)NULL
)
486 return bfd_reloc_continue
;
488 relocation
= (target
& 0x00ffffff) << 2;
489 relocation
= (relocation
^ 0x02000000) - 0x02000000; /* Sign extend */
490 relocation
+= symbol
->value
;
491 relocation
+= symbol
->section
->output_section
->vma
;
492 relocation
+= symbol
->section
->output_offset
;
493 relocation
+= reloc_entry
->addend
;
494 relocation
-= input_section
->output_section
->vma
;
495 relocation
-= input_section
->output_offset
;
499 return bfd_reloc_overflow
;
501 /* Check for overflow */
502 if (relocation
& 0x02000000)
504 if ((relocation
& ~ (bfd_vma
) 0x03ffffff) != ~ (bfd_vma
) 0x03ffffff)
505 flag
= bfd_reloc_overflow
;
507 else if (relocation
& ~0x03ffffff)
508 flag
= bfd_reloc_overflow
;
510 target
&= ~0x00ffffff;
511 target
|= (relocation
>> 2) & 0x00ffffff;
512 bfd_put_32 (abfd
, target
, (bfd_byte
*) data
+ addr
);
514 /* Now the ARM magic... Change the reloc type so that it is marked as done.
515 Strictly this is only necessary if we are doing a partial relocation. */
516 reloc_entry
->howto
= &aoutarm_std_reloc_howto
[ARM_26D
];
521 typedef enum {bunknown
, b9
, b12
, b23
} thumb_pcrel_branchtype
;
523 static bfd_reloc_status_type
524 coff_thumb_pcrel_common (abfd
, reloc_entry
, symbol
, data
, input_section
,
525 output_bfd
, error_message
, btype
)
527 arelent
*reloc_entry
;
530 asection
*input_section
;
532 char **error_message
;
533 thumb_pcrel_branchtype btype
;
535 bfd_vma relocation
= 0;
536 bfd_size_type addr
= reloc_entry
->address
;
537 long target
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ addr
);
538 bfd_reloc_status_type flag
= bfd_reloc_ok
;
543 /* NOTE: This routine is currently used by GAS, but not by the link
551 signbit
= 0x00000100;
557 signbit
= 0x00000800;
563 signbit
= 0x00400000;
570 /* If this is an undefined symbol, return error */
571 if (symbol
->section
== &bfd_und_section
572 && (symbol
->flags
& BSF_WEAK
) == 0)
573 return output_bfd
? bfd_reloc_continue
: bfd_reloc_undefined
;
575 /* If the sections are different, and we are doing a partial relocation,
576 just ignore it for now. */
577 if (symbol
->section
->name
!= input_section
->name
578 && output_bfd
!= (bfd
*)NULL
)
579 return bfd_reloc_continue
;
585 relocation
= ((target
& dstmsk
) << 1);
589 if (bfd_big_endian (abfd
))
590 relocation
= ((target
& 0x7ff) << 1) | ((target
& 0x07ff0000) >> 4);
592 relocation
= ((target
& 0x7ff) << 12) | ((target
& 0x07ff0000) >> 15);
599 relocation
= (relocation
^ signbit
) - signbit
; /* Sign extend */
600 relocation
+= symbol
->value
;
601 relocation
+= symbol
->section
->output_section
->vma
;
602 relocation
+= symbol
->section
->output_offset
;
603 relocation
+= reloc_entry
->addend
;
604 relocation
-= input_section
->output_section
->vma
;
605 relocation
-= input_section
->output_offset
;
609 return bfd_reloc_overflow
;
611 /* Check for overflow */
612 if (relocation
& signbit
)
614 if ((relocation
& ~offmsk
) != ~offmsk
)
615 flag
= bfd_reloc_overflow
;
617 else if (relocation
& ~offmsk
)
618 flag
= bfd_reloc_overflow
;
625 target
|= (relocation
>> 1);
629 if (bfd_big_endian (abfd
))
630 target
|= ((relocation
& 0xfff) >> 1) | ((relocation
<< 4) & 0x07ff0000);
632 target
|= ((relocation
& 0xffe) << 15) | ((relocation
>> 12) & 0x7ff);
639 bfd_put_32 (abfd
, target
, (bfd_byte
*) data
+ addr
);
641 /* Now the ARM magic... Change the reloc type so that it is marked as done.
642 Strictly this is only necessary if we are doing a partial relocation. */
643 reloc_entry
->howto
= & aoutarm_std_reloc_howto
[ARM_26D
];
645 /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations */
649 static bfd_reloc_status_type
650 coff_thumb_pcrel_23 (abfd
, reloc_entry
, symbol
, data
, input_section
,
651 output_bfd
, error_message
)
653 arelent
*reloc_entry
;
656 asection
*input_section
;
658 char **error_message
;
660 return coff_thumb_pcrel_common (abfd
, reloc_entry
, symbol
, data
,
661 input_section
, output_bfd
, error_message
, b23
);
664 static bfd_reloc_status_type
665 coff_thumb_pcrel_12 (abfd
, reloc_entry
, symbol
, data
, input_section
,
666 output_bfd
, error_message
)
668 arelent
*reloc_entry
;
671 asection
*input_section
;
673 char **error_message
;
675 return coff_thumb_pcrel_common (abfd
, reloc_entry
, symbol
, data
,
676 input_section
, output_bfd
, error_message
, b12
);
679 static bfd_reloc_status_type
680 coff_thumb_pcrel_9 (abfd
, reloc_entry
, symbol
, data
, input_section
,
681 output_bfd
, error_message
)
683 arelent
*reloc_entry
;
686 asection
*input_section
;
688 char **error_message
;
690 return coff_thumb_pcrel_common (abfd
, reloc_entry
, symbol
, data
,
691 input_section
, output_bfd
, error_message
, b9
);
695 static CONST
struct reloc_howto_struct
*
696 coff_arm_reloc_type_lookup (abfd
, code
)
698 bfd_reloc_code_real_type code
;
700 #define ASTD(i,j) case i: return &aoutarm_std_reloc_howto[j]
701 if (code
== BFD_RELOC_CTOR
)
702 switch (bfd_get_arch_info (abfd
)->bits_per_address
)
707 default: return (CONST
struct reloc_howto_struct
*) 0;
712 ASTD (BFD_RELOC_8
, ARM_8
);
713 ASTD (BFD_RELOC_16
, ARM_16
);
714 ASTD (BFD_RELOC_32
, ARM_32
);
715 ASTD (BFD_RELOC_ARM_PCREL_BRANCH
, ARM_26
);
716 ASTD (BFD_RELOC_8_PCREL
, ARM_DISP8
);
717 ASTD (BFD_RELOC_16_PCREL
, ARM_DISP16
);
718 ASTD (BFD_RELOC_32_PCREL
, ARM_DISP32
);
719 ASTD (BFD_RELOC_RVA
, ARM_RVA32
);
720 ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9
, ARM_THUMB9
);
721 ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12
, ARM_THUMB12
);
722 ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23
, ARM_THUMB23
);
723 default: return (CONST
struct reloc_howto_struct
*) 0;
727 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
728 #define COFF_PAGE_SIZE 0x1000
729 /* Turn a howto into a reloc nunmber */
731 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
732 #define BADMAG(x) ARMBADMAG(x)
733 #define ARM 1 /* Customize coffcode.h */
735 /* Extend the coff_link_hash_table structure with a few ARM specific fields.
736 This allows us to store global data here without actually creating any
737 global variables, which is a no-no in the BFD world. */
738 struct coff_arm_link_hash_table
740 /* The original coff_link_hash_table structure. MUST be first field. */
741 struct coff_link_hash_table root
;
743 /* The size in bytes of the section containg the Thumb-to-ARM glue. */
744 long int thumb_glue_size
;
746 /* The size in bytes of the section containg the ARM-to-Thumb glue. */
747 long int arm_glue_size
;
749 /* An arbitary input BFD chosen to hold the glue sections. */
750 bfd
* bfd_of_glue_owner
;
753 /* Get the ARM coff linker hash table from a link_info structure. */
754 #define coff_arm_hash_table(info) \
755 ((struct coff_arm_link_hash_table *) ((info)->hash))
757 /* Create an ARM coff linker hash table. */
759 static struct bfd_link_hash_table
*
760 coff_arm_link_hash_table_create (abfd
)
763 struct coff_arm_link_hash_table
* ret
;
765 ret
= ((struct coff_arm_link_hash_table
*)
766 bfd_alloc (abfd
, sizeof (struct coff_arm_link_hash_table
)));
767 if (ret
== (struct coff_arm_link_hash_table
*) NULL
)
770 if (! _bfd_coff_link_hash_table_init
771 (& ret
->root
, abfd
, _bfd_coff_link_hash_newfunc
))
773 bfd_release (abfd
, ret
);
774 return (struct bfd_link_hash_table
*) NULL
;
777 ret
->thumb_glue_size
= 0;
778 ret
->arm_glue_size
= 0;
779 ret
->bfd_of_glue_owner
= NULL
;
781 return & ret
->root
.root
;
784 /* some typedefs for holding instructions */
785 typedef unsigned long int insn32
;
786 typedef unsigned short int insn16
;
789 /* The thumb form of a long branch is a bit finicky, because the offset
790 encoding is split over two fields, each in it's own instruction. They
791 can occur in any order. So given a thumb form of long branch, and an
792 offset, insert the offset into the thumb branch and return finished
795 It takes two thumb instructions to encode the target address. Each has
796 11 bits to invest. The upper 11 bits are stored in one (identifed by
797 H-0.. see below), the lower 11 bits are stored in the other (identified
800 Combine together and shifted left by 1 (it's a half word address) and
804 H-0, upper address-0 = 000
806 H-1, lower address-0 = 800
808 They can be ordered either way, but the arm tools I've seen always put
809 the lower one first. It probably doesn't matter. krk@cygnus.com
811 XXX: Actually the order does matter. The second instruction (H-1)
812 moves the computed address into the PC, so it must be the second one
813 in the sequence. The problem, however is that whilst little endian code
814 stores the instructions in HI then LOW order, big endian code does the
815 reverse. nickc@cygnus.com */
817 #define LOW_HI_ORDER 0xF800F000
818 #define HI_LOW_ORDER 0xF000F800
821 insert_thumb_branch (br_insn
, rel_off
)
825 unsigned int low_bits
;
826 unsigned int high_bits
;
829 BFD_ASSERT((rel_off
& 1) != 1);
831 rel_off
>>= 1; /* half word aligned address */
832 low_bits
= rel_off
& 0x000007FF; /* the bottom 11 bits */
833 high_bits
= (rel_off
>> 11) & 0x000007FF; /* the top 11 bits */
835 if ((br_insn
& LOW_HI_ORDER
) == LOW_HI_ORDER
)
836 br_insn
= LOW_HI_ORDER
| (low_bits
<< 16) | high_bits
;
837 else if ((br_insn
& HI_LOW_ORDER
) == HI_LOW_ORDER
)
838 br_insn
= HI_LOW_ORDER
| (high_bits
<< 16) | low_bits
;
840 abort(); /* error - not a valid branch instruction form */
842 /* FIXME: abort is probably not the right call. krk@cygnus.com */
848 static struct coff_link_hash_entry
*
849 find_thumb_glue (info
, name
, input_bfd
)
850 struct bfd_link_info
* info
;
855 struct coff_link_hash_entry
* myh
;
858 bfd_malloc (strlen (name
) + strlen (THUMB2ARM_GLUE_ENTRY_NAME
)));
860 BFD_ASSERT (tmp_name
);
862 sprintf (tmp_name
, THUMB2ARM_GLUE_ENTRY_NAME
, name
);
864 myh
= coff_link_hash_lookup
865 (coff_hash_table (info
), tmp_name
, false, false, true);
868 _bfd_error_handler (_("%s: unable to find THUMB glue '%s' for `%s'"),
869 bfd_get_filename (input_bfd
), tmp_name
, name
);
876 static struct coff_link_hash_entry
*
877 find_arm_glue (info
, name
, input_bfd
)
878 struct bfd_link_info
* info
;
883 struct coff_link_hash_entry
* myh
;
886 bfd_malloc (strlen (name
) + strlen (ARM2THUMB_GLUE_ENTRY_NAME
)));
888 BFD_ASSERT (tmp_name
);
890 sprintf (tmp_name
, ARM2THUMB_GLUE_ENTRY_NAME
, name
);
892 myh
= coff_link_hash_lookup
893 (coff_hash_table (info
), tmp_name
, false, false, true);
896 _bfd_error_handler (_("%s: unable to find ARM glue '%s' for `%s'"),
897 bfd_get_filename (input_bfd
), tmp_name
, name
);
912 .word func @ behave as if you saw a ARM_32 reloc
914 ldr ip,8 <__func_addr> e59fc000
920 #define ARM2THUMB_GLUE_SIZE 12
922 a2t1_ldr_insn
= 0xe59fc000,
923 a2t2_bx_r12_insn
= 0xe12fff1c,
924 a2t3_func_addr_insn
= 0x00000001;
935 __func_change_to_arm:
945 #define THUMB2ARM_GLUE_SIZE 8
947 t2a1_bx_pc_insn
= 0x4778,
948 t2a2_noop_insn
= 0x46c0;
950 t2a3_b_insn
= 0xea000000;
953 We should really create new local (static) symbols in destination
954 object for each stub we create. We should also create local
955 (static) symbols within the stubs when switching between ARM and
956 Thumb code. This will ensure that the debugger and disassembler
957 can present a better view of stubs.
959 We can treat stubs like literal sections, and for the THUMB9 ones
960 (short addressing range) we should be able to insert the stubs
961 between sections. i.e. the simplest approach (since relocations
962 are done on a section basis) is to dump the stubs at the end of
963 processing a section. That way we can always try and minimise the
964 offset to and from a stub. However, this does not map well onto
965 the way that the linker/BFD does its work: mapping all input
966 sections to output sections via the linker script before doing
969 Unfortunately it may be easier to just to disallow short range
970 Thumb->ARM stubs (i.e. no conditional inter-working branches,
971 only branch-and-link (BL) calls. This will simplify the processing
972 since we can then put all of the stubs into their own section.
975 On a different subject, rather than complaining when a
976 branch cannot fit in the number of bits available for the
977 instruction we should generate a trampoline stub (needed to
978 address the complete 32bit address space). */
980 /* The standard COFF backend linker does not cope with the special
981 Thumb BRANCH23 relocation. The alternative would be to split the
982 BRANCH23 into seperate HI23 and LO23 relocations. However, it is a
983 bit simpler simply providing our own relocation driver. */
985 /* The reloc processing routine for the ARM/Thumb COFF linker. NOTE:
986 This code is a very slightly modified copy of
987 _bfd_coff_generic_relocate_section. It would be a much more
988 maintainable solution to have a MACRO that could be expanded within
989 _bfd_coff_generic_relocate_section that would only be provided for
990 ARM/Thumb builds. It is only the code marked THUMBEXTENSION that
991 is different from the original. */
994 coff_arm_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
995 contents
, relocs
, syms
, sections
)
997 struct bfd_link_info
*info
;
999 asection
*input_section
;
1001 struct internal_reloc
*relocs
;
1002 struct internal_syment
*syms
;
1003 asection
**sections
;
1005 struct internal_reloc
* rel
;
1006 struct internal_reloc
* relend
;
1009 relend
= rel
+ input_section
->reloc_count
;
1011 for (; rel
< relend
; rel
++)
1015 struct coff_link_hash_entry
*h
;
1016 struct internal_syment
*sym
;
1019 reloc_howto_type
*howto
;
1020 bfd_reloc_status_type rstat
;
1023 symndx
= rel
->r_symndx
;
1032 h
= obj_coff_sym_hashes (input_bfd
)[symndx
];
1033 sym
= syms
+ symndx
;
1036 /* COFF treats common symbols in one of two ways. Either the
1037 size of the symbol is included in the section contents, or it
1038 is not. We assume that the size is not included, and force
1039 the rtype_to_howto function to adjust the addend as needed. */
1041 if (sym
!= NULL
&& sym
->n_scnum
!= 0)
1042 addend
= - sym
->n_value
;
1047 howto
= bfd_coff_rtype_to_howto (input_bfd
, input_section
, rel
, h
,
1052 /* If we are doing a relocateable link, then we can just ignore
1053 a PC relative reloc that is pcrel_offset. It will already
1054 have the correct value. If this is not a relocateable link,
1055 then we should ignore the symbol value. */
1056 if (howto
->pc_relative
&& howto
->pcrel_offset
)
1058 if (info
->relocateable
)
1060 if (sym
!= NULL
&& sym
->n_scnum
!= 0)
1061 addend
+= sym
->n_value
;
1064 /* If we are doing a relocateable link, then we can just ignore
1065 a PC relative reloc that is pcrel_offset. It will already
1066 have the correct value. */
1067 if (info
->relocateable
1068 && howto
->pc_relative
1069 && howto
->pcrel_offset
)
1080 sec
= bfd_abs_section_ptr
;
1085 sec
= sections
[symndx
];
1086 val
= (sec
->output_section
->vma
1087 + sec
->output_offset
1094 #if 1 /* THUMBEXTENSION */
1095 /* We don't output the stubs if we are generating a
1096 relocatable output file, since we may as well leave the
1097 stub generation to the final linker pass. If we fail to
1098 verify that the name is defined, we'll try to build stubs
1099 for an undefined name... */
1100 if (! info
->relocateable
1101 && ( h
->root
.type
== bfd_link_hash_defined
1102 || h
->root
.type
== bfd_link_hash_defweak
))
1104 asection
* h_sec
= h
->root
.u
.def
.section
;
1105 const char * name
= h
->root
.root
.string
;
1107 /* h locates the symbol referenced in the reloc. */
1108 h_val
= (h
->root
.u
.def
.value
1109 + h_sec
->output_section
->vma
1110 + h_sec
->output_offset
);
1112 if (howto
->type
== ARM_26
)
1114 if ( h
->class == C_THUMBSTATFUNC
1115 || h
->class == C_THUMBEXTFUNC
)
1117 /* Arm code calling a Thumb function */
1118 unsigned long int tmp
;
1121 long int ret_offset
;
1122 struct coff_link_hash_entry
* myh
;
1123 struct coff_arm_link_hash_table
* globals
;
1125 myh
= find_arm_glue (info
, name
, input_bfd
);
1129 globals
= coff_arm_hash_table (info
);
1131 BFD_ASSERT (globals
!= NULL
);
1132 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1134 my_offset
= myh
->root
.u
.def
.value
;
1136 s
= bfd_get_section_by_name (globals
->bfd_of_glue_owner
,
1137 ARM2THUMB_GLUE_SECTION_NAME
);
1138 BFD_ASSERT (s
!= NULL
);
1139 BFD_ASSERT (s
->contents
!= NULL
);
1140 BFD_ASSERT (s
->output_section
!= NULL
);
1142 if ((my_offset
& 0x01) == 0x01)
1144 if (h_sec
->owner
!= NULL
1145 && INTERWORK_SET (h_sec
->owner
)
1146 && ! INTERWORK_FLAG (h_sec
->owner
))
1149 (_("%s(%s): warning: interworking not enabled."),
1150 bfd_get_filename (h_sec
->owner
), name
);
1152 (_(" first occurrence: %s: arm call to thumb"),
1153 bfd_get_filename (input_bfd
));
1157 myh
->root
.u
.def
.value
= my_offset
;
1159 bfd_put_32 (output_bfd
, a2t1_ldr_insn
,
1160 s
->contents
+ my_offset
);
1162 bfd_put_32 (output_bfd
, a2t2_bx_r12_insn
,
1163 s
->contents
+ my_offset
+ 4);
1165 /* It's a thumb address. Add the low order bit. */
1166 bfd_put_32 (output_bfd
, h_val
| a2t3_func_addr_insn
,
1167 s
->contents
+ my_offset
+ 8);
1170 BFD_ASSERT (my_offset
<= globals
->arm_glue_size
);
1172 tmp
= bfd_get_32 (input_bfd
, contents
+ rel
->r_vaddr
1173 - input_section
->vma
);
1175 tmp
= tmp
& 0xFF000000;
1177 /* Somehow these are both 4 too far, so subtract 8. */
1181 + s
->output_section
->vma
1182 - (input_section
->output_offset
1183 + input_section
->output_section
->vma
1187 tmp
= tmp
| ((ret_offset
>> 2) & 0x00FFFFFF);
1189 bfd_put_32 (output_bfd
, tmp
, contents
+ rel
->r_vaddr
1190 - input_section
->vma
);
1196 /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12 */
1197 else if (howto
->type
== ARM_THUMB23
)
1199 if ( h
->class == C_EXT
1200 || h
->class == C_STAT
1201 || h
->class == C_LABEL
)
1203 /* Thumb code calling an ARM function */
1206 unsigned long int tmp
;
1207 long int ret_offset
;
1208 struct coff_link_hash_entry
* myh
;
1209 struct coff_arm_link_hash_table
* globals
;
1211 myh
= find_thumb_glue (info
, name
, input_bfd
);
1215 globals
= coff_arm_hash_table (info
);
1217 BFD_ASSERT (globals
!= NULL
);
1218 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1220 my_offset
= myh
->root
.u
.def
.value
;
1222 s
= bfd_get_section_by_name (globals
->bfd_of_glue_owner
,
1223 THUMB2ARM_GLUE_SECTION_NAME
);
1225 BFD_ASSERT (s
!= NULL
);
1226 BFD_ASSERT (s
->contents
!= NULL
);
1227 BFD_ASSERT (s
->output_section
!= NULL
);
1229 if ((my_offset
& 0x01) == 0x01)
1231 if (h_sec
->owner
!= NULL
1232 && INTERWORK_SET (h_sec
->owner
)
1233 && ! INTERWORK_FLAG (h_sec
->owner
))
1236 (_("%s(%s): warning: interworking not enabled."),
1237 bfd_get_filename (h_sec
->owner
), name
);
1239 (_(" first occurrence: %s: thumb call to arm"),
1240 bfd_get_filename (input_bfd
));
1244 myh
->root
.u
.def
.value
= my_offset
;
1246 bfd_put_16 (output_bfd
, t2a1_bx_pc_insn
,
1247 s
->contents
+ my_offset
);
1249 bfd_put_16 (output_bfd
, t2a2_noop_insn
,
1250 s
->contents
+ my_offset
+ 2);
1253 ((signed)h_val
) - /* Address of destination of the stub */
1254 ((signed)(s
->output_offset
/* Offset from the start of the current section to the start of the stubs. */
1255 + my_offset
/* Offset of the start of this stub from the start of the stubs. */
1256 + s
->output_section
->vma
) /* Address of the start of the current section. */
1257 + 4 /* The branch instruction is 4 bytes into the stub. */
1258 + 8); /* ARM branches work from the pc of the instruction + 8. */
1260 bfd_put_32 (output_bfd
,
1261 t2a3_b_insn
| ((ret_offset
>> 2) & 0x00FFFFFF),
1262 s
->contents
+ my_offset
+ 4);
1265 BFD_ASSERT (my_offset
<= globals
->thumb_glue_size
);
1267 /* Now go back and fix up the original BL insn to point
1272 - (input_section
->output_offset
1276 tmp
= bfd_get_32 (input_bfd
, contents
+ rel
->r_vaddr
1277 - input_section
->vma
);
1279 bfd_put_32 (output_bfd
,
1280 insert_thumb_branch (tmp
, ret_offset
),
1281 contents
+ rel
->r_vaddr
1282 - input_section
->vma
);
1289 /* If the relocation type and destination symbol does not
1290 fall into one of the above categories, then we can just
1291 perform a direct link. */
1294 rstat
= bfd_reloc_ok
;
1296 #endif /* THUMBEXTENSION */
1297 if ( h
->root
.type
== bfd_link_hash_defined
1298 || h
->root
.type
== bfd_link_hash_defweak
)
1302 sec
= h
->root
.u
.def
.section
;
1303 val
= (h
->root
.u
.def
.value
1304 + sec
->output_section
->vma
1305 + sec
->output_offset
);
1308 else if (! info
->relocateable
)
1310 if (! ((*info
->callbacks
->undefined_symbol
)
1311 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
1312 rel
->r_vaddr
- input_section
->vma
)))
1317 if (info
->base_file
)
1319 /* Emit a reloc if the backend thinks it needs it. */
1320 if (sym
&& pe_data(output_bfd
)->in_reloc_p(output_bfd
, howto
))
1322 /* relocation to a symbol in a section which
1323 isn't absolute - we output the address here
1325 bfd_vma addr
= rel
->r_vaddr
1326 - input_section
->vma
1327 + input_section
->output_offset
1328 + input_section
->output_section
->vma
;
1329 if (coff_data(output_bfd
)->pe
)
1330 addr
-= pe_data(output_bfd
)->pe_opthdr
.ImageBase
;
1331 /* FIXME: Shouldn't 4 be sizeof (addr)? */
1332 fwrite (&addr
, 1,4, (FILE *) info
->base_file
);
1336 #if 1 /* THUMBEXTENSION */
1338 rstat
= bfd_reloc_ok
;
1339 /* Only perform this fix during the final link, not a relocatable link. nickc@cygnus.com */
1340 else if (! info
->relocateable
1341 && howto
->type
== ARM_THUMB23
)
1343 /* This is pretty much a copy of what the default
1344 _bfd_final_link_relocate and _bfd_relocate_contents
1345 routines do to perform a relocation, with special
1346 processing for the split addressing of the Thumb BL
1347 instruction. Again, it would probably be simpler adding a
1348 ThumbBRANCH23 specific macro expansion into the default
1351 bfd_vma address
= rel
->r_vaddr
- input_section
->vma
;
1353 if (address
> input_section
->_raw_size
)
1354 rstat
= bfd_reloc_outofrange
;
1357 bfd_vma relocation
= val
+ addend
;
1358 int size
= bfd_get_reloc_size (howto
);
1359 boolean overflow
= false;
1360 bfd_byte
* location
= contents
+ address
;
1361 bfd_vma x
= bfd_get_32 (input_bfd
, location
);
1362 bfd_vma src_mask
= 0x007FFFFE;
1363 bfd_signed_vma reloc_signed_max
= (1 << (howto
->bitsize
- 1)) - 1;
1364 bfd_signed_vma reloc_signed_min
= ~reloc_signed_max
;
1366 bfd_signed_vma signed_check
;
1368 bfd_signed_vma signed_add
;
1370 BFD_ASSERT (size
== 4);
1372 /* howto->pc_relative should be TRUE for type 14 BRANCH23 */
1373 relocation
-= (input_section
->output_section
->vma
1374 + input_section
->output_offset
);
1376 /* howto->pcrel_offset should be TRUE for type 14 BRANCH23 */
1377 relocation
-= address
;
1379 /* No need to negate the relocation with BRANCH23. */
1380 /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23. */
1381 /* howto->rightshift == 1 */
1382 /* Drop unwanted bits from the value we are relocating to. */
1384 check
= relocation
>> howto
->rightshift
;
1386 /* If this is a signed value, the rightshift just dropped
1387 leading 1 bits (assuming twos complement). */
1388 if ((bfd_signed_vma
) relocation
>= 0)
1389 signed_check
= check
;
1391 signed_check
= (check
1393 & ~((bfd_vma
) - 1 >> howto
->rightshift
)));
1395 /* Get the value from the object file. */
1396 if (bfd_big_endian (input_bfd
))
1398 add
= (((x
) & 0x07ff0000) >> 4) | (((x
) & 0x7ff) << 1);
1402 add
= ((((x
) & 0x7ff) << 12) | (((x
) & 0x07ff0000) >> 15));
1405 /* Get the value from the object file with an appropriate sign.
1406 The expression involving howto->src_mask isolates the upper
1407 bit of src_mask. If that bit is set in the value we are
1408 adding, it is negative, and we subtract out that number times
1409 two. If src_mask includes the highest possible bit, then we
1410 can not get the upper bit, but that does not matter since
1411 signed_add needs no adjustment to become negative in that
1416 if ((add
& (((~ src_mask
) >> 1) & src_mask
)) != 0)
1417 signed_add
-= (((~ src_mask
) >> 1) & src_mask
) << 1;
1419 /* Add the value from the object file, shifted so that it is a
1421 /* howto->bitpos == 0 */
1423 signed_check
+= signed_add
;
1424 relocation
+= signed_add
;
1426 BFD_ASSERT (howto
->complain_on_overflow
== complain_overflow_signed
);
1428 /* Assumes two's complement. */
1429 if ( signed_check
> reloc_signed_max
1430 || signed_check
< reloc_signed_min
)
1433 /* Put RELOCATION into the correct bits: */
1435 if (bfd_big_endian (input_bfd
))
1437 relocation
= (((relocation
& 0xffe) >> 1) | ((relocation
<< 4) & 0x07ff0000));
1441 relocation
= (((relocation
& 0xffe) << 15) | ((relocation
>> 12) & 0x7ff));
1444 /* Add RELOCATION to the correct bits of X: */
1445 x
= ((x
& ~howto
->dst_mask
) | relocation
);
1447 /* Put the relocated value back in the object file: */
1448 bfd_put_32 (input_bfd
, x
, location
);
1450 rstat
= overflow
? bfd_reloc_overflow
: bfd_reloc_ok
;
1454 #endif /* THUMBEXTENSION */
1455 rstat
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1457 rel
->r_vaddr
- input_section
->vma
,
1459 #if 1 /* THUMBEXTENSION */
1461 Is this the best way to fix up thumb addresses? krk@cygnus.com
1462 Probably not, but it works, and if it works it don't need fixing! nickc@cygnus.com */
1463 /* Only perform this fix during the final link, not a relocatable link. nickc@cygnus.com */
1464 if (! info
->relocateable
1465 && rel
->r_type
== ARM_32
)
1467 /* Determine if we need to set the bottom bit of a relocated address
1468 because the address is the address of a Thumb code symbol. */
1470 int patchit
= false;
1473 && ( h
->class == C_THUMBSTATFUNC
1474 || h
->class == C_THUMBEXTFUNC
))
1478 else if (sym
!= NULL
1479 && sym
->n_scnum
> N_UNDEF
)
1481 /* No hash entry - use the symbol instead. */
1483 if ( sym
->n_sclass
== C_THUMBSTATFUNC
1484 || sym
->n_sclass
== C_THUMBEXTFUNC
)
1490 bfd_byte
* location
= contents
+ rel
->r_vaddr
- input_section
->vma
;
1491 bfd_vma x
= bfd_get_32 (input_bfd
, location
);
1493 bfd_put_32 (input_bfd
, x
| 1, location
);
1496 #endif /* THUMBEXTENSION */
1504 case bfd_reloc_outofrange
:
1505 (*_bfd_error_handler
)
1506 (_("%s: bad reloc address 0x%lx in section `%s'"),
1507 bfd_get_filename (input_bfd
),
1508 (unsigned long) rel
->r_vaddr
,
1509 bfd_get_section_name (input_bfd
, input_section
));
1511 case bfd_reloc_overflow
:
1514 char buf
[SYMNMLEN
+ 1];
1519 name
= h
->root
.root
.string
;
1522 name
= _bfd_coff_internal_syment_name (input_bfd
, sym
, buf
);
1527 if (! ((*info
->callbacks
->reloc_overflow
)
1528 (info
, name
, howto
->name
, (bfd_vma
) 0, input_bfd
,
1529 input_section
, rel
->r_vaddr
- input_section
->vma
)))
1538 #ifndef COFF_WITH_PE
1540 bfd_arm_allocate_interworking_sections (info
)
1541 struct bfd_link_info
* info
;
1545 struct coff_arm_link_hash_table
* globals
;
1547 static char test_char
= '1';
1550 globals
= coff_arm_hash_table (info
);
1552 BFD_ASSERT (globals
!= NULL
);
1554 if (globals
->arm_glue_size
!= 0)
1556 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1558 s
= bfd_get_section_by_name
1559 (globals
->bfd_of_glue_owner
, ARM2THUMB_GLUE_SECTION_NAME
);
1561 BFD_ASSERT (s
!= NULL
);
1563 foo
= (bfd_byte
*) bfd_alloc
1564 (globals
->bfd_of_glue_owner
, globals
->arm_glue_size
);
1566 memset (foo
, test_char
, globals
->arm_glue_size
);
1569 s
->_raw_size
= s
->_cooked_size
= globals
->arm_glue_size
;
1573 if (globals
->thumb_glue_size
!= 0)
1575 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1577 s
= bfd_get_section_by_name
1578 (globals
->bfd_of_glue_owner
, THUMB2ARM_GLUE_SECTION_NAME
);
1580 BFD_ASSERT (s
!= NULL
);
1582 foo
= (bfd_byte
*) bfd_alloc
1583 (globals
->bfd_of_glue_owner
, globals
->thumb_glue_size
);
1585 memset (foo
, test_char
, globals
->thumb_glue_size
);
1588 s
->_raw_size
= s
->_cooked_size
= globals
->thumb_glue_size
;
1596 record_arm_to_thumb_glue (info
, h
)
1597 struct bfd_link_info
* info
;
1598 struct coff_link_hash_entry
* h
;
1600 const char * name
= h
->root
.root
.string
;
1601 register asection
* s
;
1603 struct coff_link_hash_entry
* myh
;
1604 struct coff_arm_link_hash_table
* globals
;
1606 globals
= coff_arm_hash_table (info
);
1608 BFD_ASSERT (globals
!= NULL
);
1609 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1611 s
= bfd_get_section_by_name
1612 (globals
->bfd_of_glue_owner
, ARM2THUMB_GLUE_SECTION_NAME
);
1614 BFD_ASSERT (s
!= NULL
);
1616 tmp_name
= ((char *)
1617 bfd_malloc (strlen (name
) + strlen (ARM2THUMB_GLUE_ENTRY_NAME
)));
1619 BFD_ASSERT (tmp_name
);
1621 sprintf (tmp_name
, ARM2THUMB_GLUE_ENTRY_NAME
, name
);
1623 myh
= coff_link_hash_lookup
1624 (coff_hash_table (info
), tmp_name
, false, false, true);
1629 return; /* we've already seen this guy */
1632 /* The only trick here is using globals->arm_glue_size as the value. Even
1633 though the section isn't allocated yet, this is where we will be putting
1636 bfd_coff_link_add_one_symbol (info
, globals
->bfd_of_glue_owner
, tmp_name
,
1637 BSF_EXPORT
| BSF_GLOBAL
,
1638 s
, globals
->arm_glue_size
+ 1,
1640 (struct bfd_link_hash_entry
**) & myh
);
1642 globals
->arm_glue_size
+= ARM2THUMB_GLUE_SIZE
;
1650 record_thumb_to_arm_glue (info
, h
)
1651 struct bfd_link_info
* info
;
1652 struct coff_link_hash_entry
* h
;
1654 const char * name
= h
->root
.root
.string
;
1655 register asection
* s
;
1657 struct coff_link_hash_entry
* myh
;
1658 struct coff_arm_link_hash_table
* globals
;
1661 globals
= coff_arm_hash_table (info
);
1663 BFD_ASSERT (globals
!= NULL
);
1664 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1666 s
= bfd_get_section_by_name
1667 (globals
->bfd_of_glue_owner
, THUMB2ARM_GLUE_SECTION_NAME
);
1669 BFD_ASSERT (s
!= NULL
);
1671 tmp_name
= (char *) bfd_malloc (strlen (name
) + strlen (THUMB2ARM_GLUE_ENTRY_NAME
));
1673 BFD_ASSERT (tmp_name
);
1675 sprintf (tmp_name
, THUMB2ARM_GLUE_ENTRY_NAME
, name
);
1677 myh
= coff_link_hash_lookup
1678 (coff_hash_table (info
), tmp_name
, false, false, true);
1683 return; /* we've already seen this guy */
1686 bfd_coff_link_add_one_symbol (info
, globals
->bfd_of_glue_owner
, tmp_name
,
1687 BSF_LOCAL
, s
, globals
->thumb_glue_size
+ 1,
1689 (struct bfd_link_hash_entry
**) & myh
);
1691 /* If we mark it 'thumb', the disassembler will do a better job. */
1692 myh
->class = C_THUMBEXTFUNC
;
1696 #define CHANGE_TO_ARM "__%s_change_to_arm"
1698 tmp_name
= ((char *)
1699 bfd_malloc (strlen (name
) + strlen (CHANGE_TO_ARM
)));
1701 BFD_ASSERT (tmp_name
);
1703 sprintf (tmp_name
, CHANGE_TO_ARM
, name
);
1707 /* Now allocate another symbol to switch back to arm mode. */
1708 bfd_coff_link_add_one_symbol (info
, globals
->bfd_of_glue_owner
, tmp_name
,
1709 BSF_LOCAL
, s
, globals
->thumb_glue_size
+ 4,
1711 (struct bfd_link_hash_entry
**) & myh
);
1715 globals
->thumb_glue_size
+= THUMB2ARM_GLUE_SIZE
;
1720 /* Select a BFD to be used to hold the sections used by the glue code.
1721 This function is called from the linker scripts in ld/emultempl/
1724 bfd_arm_get_bfd_for_interworking (abfd
, info
)
1726 struct bfd_link_info
* info
;
1728 struct coff_arm_link_hash_table
* globals
;
1732 /* If we are only performing a partial link do not bother
1733 getting a bfd to hold the glue. */
1734 if (info
->relocateable
)
1737 globals
= coff_arm_hash_table (info
);
1739 BFD_ASSERT (globals
!= NULL
);
1741 if (globals
->bfd_of_glue_owner
!= NULL
)
1744 sec
= bfd_get_section_by_name (abfd
, ARM2THUMB_GLUE_SECTION_NAME
);
1748 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
1750 sec
= bfd_make_section (abfd
, ARM2THUMB_GLUE_SECTION_NAME
);
1753 || ! bfd_set_section_flags (abfd
, sec
, flags
)
1754 || ! bfd_set_section_alignment (abfd
, sec
, 2))
1758 sec
= bfd_get_section_by_name (abfd
, THUMB2ARM_GLUE_SECTION_NAME
);
1762 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
1764 sec
= bfd_make_section (abfd
, THUMB2ARM_GLUE_SECTION_NAME
);
1767 || ! bfd_set_section_flags (abfd
, sec
, flags
)
1768 || ! bfd_set_section_alignment (abfd
, sec
, 2))
1772 /* Save the bfd for later use. */
1773 globals
->bfd_of_glue_owner
= abfd
;
1779 bfd_arm_process_before_allocation (abfd
, info
)
1781 struct bfd_link_info
* info
;
1784 struct coff_arm_link_hash_table
* globals
;
1786 /* If we are only performing a partial link do not bother
1787 to construct any glue. */
1788 if (info
->relocateable
)
1791 /* Here we have a bfd that is to be included on the link. We have a hook
1792 to do reloc rummaging, before section sizes are nailed down. */
1794 _bfd_coff_get_external_symbols (abfd
);
1796 globals
= coff_arm_hash_table (info
);
1798 BFD_ASSERT (globals
!= NULL
);
1799 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1801 /* Rummage around all the relocs and map the glue vectors. */
1802 sec
= abfd
->sections
;
1807 for (; sec
!= NULL
; sec
= sec
->next
)
1809 struct internal_reloc
* i
;
1810 struct internal_reloc
* rel
;
1812 if (sec
->reloc_count
== 0)
1815 /* Load the relocs. */
1816 /* FIXME: there may be a storage leak here. */
1818 i
= _bfd_coff_read_internal_relocs (abfd
, sec
, 1, 0, 0, 0);
1820 BFD_ASSERT (i
!= 0);
1822 for (rel
= i
; rel
< i
+ sec
->reloc_count
; ++rel
)
1824 unsigned short r_type
= rel
->r_type
;
1826 struct coff_link_hash_entry
* h
;
1828 symndx
= rel
->r_symndx
;
1830 /* If the relocation is not against a symbol it cannot concern us. */
1834 h
= obj_coff_sym_hashes (abfd
)[symndx
];
1836 /* If the relocation is against a static symbol it must be within
1837 the current section and so cannot be a cross ARM/Thumb relocation. */
1844 /* This one is a call from arm code. We need to look up
1845 the target of the call. If it is a thumb target, we
1848 if (h
->class == C_THUMBEXTFUNC
)
1849 record_arm_to_thumb_glue (info
, h
);
1853 /* This one is a call from thumb code. We used to look
1854 for ARM_THUMB9 and ARM_THUMB12 as well. We need to look
1855 up the target of the call. If it is an arm target, we
1856 insert glue. If the symbol does not exist it will be
1857 given a class of C_EXT and so we will generate a stub
1858 for it. This is not really a problem, since the link
1859 is doomed anyway. */
1866 record_thumb_to_arm_glue (info
, h
);
1881 #endif /* ! COFF_WITH_PE */
1883 #define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
1884 #define coff_relocate_section coff_arm_relocate_section
1885 #define coff_bfd_is_local_label_name coff_arm_is_local_label_name
1886 #define coff_adjust_symndx coff_arm_adjust_symndx
1887 #define coff_link_output_has_begun coff_arm_link_output_has_begun
1888 #define coff_final_link_postscript coff_arm_final_link_postscript
1889 #define coff_bfd_merge_private_bfd_data coff_arm_merge_private_bfd_data
1890 #define coff_bfd_print_private_bfd_data coff_arm_print_private_bfd_data
1891 #define coff_bfd_set_private_flags _bfd_coff_arm_set_private_flags
1892 #define coff_bfd_copy_private_bfd_data coff_arm_copy_private_bfd_data
1893 #define coff_bfd_link_hash_table_create coff_arm_link_hash_table_create
1896 /* When doing a relocateable link, we want to convert ARM26 relocs
1897 into ARM26D relocs. */
1900 coff_arm_adjust_symndx (obfd
, info
, ibfd
, sec
, irel
, adjustedp
)
1902 struct bfd_link_info
*info
;
1905 struct internal_reloc
*irel
;
1908 if (irel
->r_type
== 3)
1910 struct coff_link_hash_entry
*h
;
1912 h
= obj_coff_sym_hashes (ibfd
)[irel
->r_symndx
];
1914 && (h
->root
.type
== bfd_link_hash_defined
1915 || h
->root
.type
== bfd_link_hash_defweak
)
1916 && h
->root
.u
.def
.section
->output_section
== sec
->output_section
)
1923 /* Called when merging the private data areas of two BFDs.
1924 This is important as it allows us to detect if we are
1925 attempting to merge binaries compiled for different ARM
1926 targets, eg different CPUs or differents APCS's. */
1929 coff_arm_merge_private_bfd_data (ibfd
, obfd
)
1933 BFD_ASSERT (ibfd
!= NULL
&& obfd
!= NULL
);
1938 /* If the two formats are different we cannot merge anything.
1939 This is not an error, since it is permissable to change the
1940 input and output formats. */
1941 if ( ibfd
->xvec
->flavour
!= bfd_target_coff_flavour
1942 || obfd
->xvec
->flavour
!= bfd_target_coff_flavour
)
1945 /* Verify that the APCS is the same for the two BFDs */
1946 if (APCS_SET (ibfd
))
1948 if (APCS_SET (obfd
))
1950 /* If the src and dest have different APCS flag bits set, fail. */
1951 if (APCS_26_FLAG (obfd
) != APCS_26_FLAG (ibfd
))
1954 (_("%s: ERROR: compiled for APCS-%d whereas target %s uses APCS-%d"),
1955 bfd_get_filename (ibfd
), APCS_26_FLAG (ibfd
) ? 26 : 32,
1956 bfd_get_filename (obfd
), APCS_26_FLAG (obfd
) ? 26 : 32
1959 bfd_set_error (bfd_error_wrong_format
);
1963 if (APCS_FLOAT_FLAG (obfd
) != APCS_FLOAT_FLAG (ibfd
))
1967 if (APCS_FLOAT_FLAG (ibfd
))
1968 msg
= _("%s: ERROR: passes floats in float registers whereas target %s uses integer registers");
1970 msg
= _("%s: ERROR: passes floats in integer registers whereas target %s uses float registers");
1971 _bfd_error_handler (msg
, bfd_get_filename (ibfd
),
1972 bfd_get_filename (obfd
));
1974 bfd_set_error (bfd_error_wrong_format
);
1978 if (PIC_FLAG (obfd
) != PIC_FLAG (ibfd
))
1982 if (PIC_FLAG (ibfd
))
1983 msg
= _("%s: ERROR: compiled as position independent code, whereas target %s is absolute position");
1985 msg
= _("%s: ERROR: compiled as absolute position code, whereas target %s is position independent");
1986 _bfd_error_handler (msg
, bfd_get_filename (ibfd
),
1987 bfd_get_filename (obfd
));
1989 bfd_set_error (bfd_error_wrong_format
);
1995 SET_APCS_FLAGS (obfd
, APCS_26_FLAG (ibfd
) | APCS_FLOAT_FLAG (ibfd
) | PIC_FLAG (ibfd
));
1997 /* Set up the arch and fields as well as these are probably wrong. */
1998 bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
2002 /* Check the interworking support. */
2003 if (INTERWORK_SET (ibfd
))
2005 if (INTERWORK_SET (obfd
))
2007 /* If the src and dest differ in their interworking issue a warning. */
2008 if (INTERWORK_FLAG (obfd
) != INTERWORK_FLAG (ibfd
))
2012 if (INTERWORK_FLAG (ibfd
))
2013 msg
= _("Warning: input file %s supports internetworking, whereas %s does not.");
2015 msg
= _("Warning: input file %s does not support internetworking, whereas %s does.");
2016 _bfd_error_handler (msg
, bfd_get_filename (ibfd
),
2017 bfd_get_filename (obfd
));
2022 SET_INTERWORK_FLAG (obfd
, INTERWORK_FLAG (ibfd
));
2030 /* Display the flags field. */
2033 coff_arm_print_private_bfd_data (abfd
, ptr
)
2037 FILE * file
= (FILE *) ptr
;
2039 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
2041 /* xgettext:c-format */
2042 fprintf (file
, _("private flags = %x:"), coff_data (abfd
)->flags
);
2044 if (APCS_SET (abfd
))
2046 /* xgettext: APCS is ARM Prodecure Call Standard, it should not be translated. */
2047 fprintf (file
, " [APCS-%d]", APCS_26_FLAG (abfd
) ? 26 : 32);
2049 if (APCS_FLOAT_FLAG (abfd
))
2050 fprintf (file
, _(" [floats passed in float registers]"));
2052 fprintf (file
, _(" [floats passed in integer registers]"));
2054 if (PIC_FLAG (abfd
))
2055 fprintf (file
, _(" [position independent]"));
2057 fprintf (file
, _(" [absolute position]"));
2060 if (! INTERWORK_SET (abfd
))
2061 fprintf (file
, _(" [interworking flag not initialised]"));
2062 else if (INTERWORK_FLAG (abfd
))
2063 fprintf (file
, _(" [interworking supported]"));
2065 fprintf (file
, _(" [interworking not supported]"));
2073 /* Copies the given flags into the coff_tdata.flags field.
2074 Typically these flags come from the f_flags[] field of
2075 the COFF filehdr structure, which contains important,
2076 target specific information.
2077 Note: Although this function is static, it is explicitly
2078 called from both coffcode.h and peicode.h. */
2081 _bfd_coff_arm_set_private_flags (abfd
, flags
)
2087 BFD_ASSERT (abfd
!= NULL
);
2089 flag
= (flags
& F_APCS26
) ? F_APCS_26
: 0;
2091 /* Make sure that the APCS field has not been initialised to the opposite
2094 && ( (APCS_26_FLAG (abfd
) != flag
)
2095 || (APCS_FLOAT_FLAG (abfd
) != (flags
& F_APCS_FLOAT
))
2096 || (PIC_FLAG (abfd
) != (flags
& F_PIC
))
2100 flag
|= (flags
& (F_APCS_FLOAT
| F_PIC
));
2102 SET_APCS_FLAGS (abfd
, flag
);
2104 flag
= (flags
& F_INTERWORK
);
2106 /* If either the flags or the BFD do support interworking then do not
2107 set the interworking flag. */
2108 if (INTERWORK_SET (abfd
) && (INTERWORK_FLAG (abfd
) != flag
))
2111 SET_INTERWORK_FLAG (abfd
, flag
);
2117 /* Copy the important parts of the target specific data
2118 from one instance of a BFD to another. */
2121 coff_arm_copy_private_bfd_data (src
, dest
)
2125 BFD_ASSERT (src
!= NULL
&& dest
!= NULL
);
2130 /* If the destination is not in the same format as the source, do not do
2132 if (src
->xvec
!= dest
->xvec
)
2135 /* copy the flags field */
2138 if (APCS_SET (dest
))
2140 /* If the src and dest have different APCS flag bits set, fail. */
2141 if (APCS_26_FLAG (dest
) != APCS_26_FLAG (src
))
2144 if (APCS_FLOAT_FLAG (dest
) != APCS_FLOAT_FLAG (src
))
2147 if (PIC_FLAG (dest
) != PIC_FLAG (src
))
2151 SET_APCS_FLAGS (dest
, APCS_26_FLAG (src
) | APCS_FLOAT_FLAG (src
)
2155 if (INTERWORK_SET (src
))
2157 if (INTERWORK_SET (dest
))
2159 /* If the src and dest have different interworking flags then turn
2160 off the interworking bit. */
2161 if (INTERWORK_FLAG (dest
) != INTERWORK_FLAG (src
))
2162 SET_INTERWORK_FLAG (dest
, 0);
2166 SET_INTERWORK_FLAG (dest
, INTERWORK_FLAG (src
));
2173 /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
2174 *must* match the definitions on gcc/config/arm/semi.h. */
2175 #define LOCAL_LABEL_PREFIX "."
2176 #define USER_LABEL_PREFIX "_"
2179 coff_arm_is_local_label_name (abfd
, name
)
2183 #ifdef LOCAL_LABEL_PREFIX
2184 /* If there is a prefix for local labels then look for this.
2185 If the prefix exists, but it is empty, then ignore the test. */
2187 if (LOCAL_LABEL_PREFIX
[0] != 0)
2189 if (strncmp (name
, LOCAL_LABEL_PREFIX
, strlen (LOCAL_LABEL_PREFIX
)) == 0)
2193 #ifdef USER_LABEL_PREFIX
2194 if (USER_LABEL_PREFIX
[0] != 0)
2196 if (strncmp (name
, USER_LABEL_PREFIX
, strlen (USER_LABEL_PREFIX
)) == 0)
2201 /* devo/gcc/config/dbxcoff.h defines ASM_OUTPUT_SOURCE_LINE to generate
2202 local line numbers as .LM<number>, so treat these as local. */
2206 case 'L': return true;
2207 case '.': return (name
[1] == 'L' && name
[2] == 'M') ? true : false;
2208 default: return false; /* Cannot make our minds up - default to
2209 false so that it will not be stripped
2214 /* This piece of machinery exists only to guarantee that the bfd that holds
2215 the glue section is written last.
2217 This does depend on bfd_make_section attaching a new section to the
2218 end of the section list for the bfd.
2223 coff_arm_link_output_has_begun (sub
, info
)
2225 struct coff_final_link_info
* info
;
2227 return (sub
->output_has_begun
2228 || sub
== coff_arm_hash_table (info
->info
)->bfd_of_glue_owner
);
2232 coff_arm_final_link_postscript (abfd
, pfinfo
)
2234 struct coff_final_link_info
* pfinfo
;
2236 struct coff_arm_link_hash_table
* globals
;
2238 globals
= coff_arm_hash_table (pfinfo
->info
);
2240 BFD_ASSERT (globals
!= NULL
);
2242 if (globals
->bfd_of_glue_owner
!= NULL
)
2244 if (! _bfd_coff_link_input_bfd (pfinfo
, globals
->bfd_of_glue_owner
))
2247 globals
->bfd_of_glue_owner
->output_has_begun
= true;
2254 #define coff_SWAP_sym_in arm_bfd_coff_swap_sym_in
2256 static void coff_swap_sym_in
PARAMS ((bfd
*, PTR
, PTR
));
2258 /* Sepcial version of symbol swapper, used to grab a bfd
2259 onto which the glue sections can be attached. */
2261 arm_bfd_coff_swap_sym_in (abfd
, ext1
, in1
)
2267 register asection
* s
;
2269 /* Do the normal swap in. */
2270 coff_swap_sym_in (abfd
, ext1
, in1
);
2272 if (bfd_of_glue_owner
!= NULL
) /* we already have a toc, so go home */
2275 /* Save the bfd for later allocation. */
2276 bfd_of_glue_owner
= abfd
;
2278 s
= bfd_get_section_by_name (bfd_of_glue_owner
,
2279 ARM2THUMB_GLUE_SECTION_NAME
);
2283 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
2285 s
= bfd_make_section (bfd_of_glue_owner
, ARM2THUMB_GLUE_SECTION_NAME
);
2288 || !bfd_set_section_flags (bfd_of_glue_owner
, s
, flags
)
2289 || !bfd_set_section_alignment (bfd_of_glue_owner
, s
, 2))
2291 /* FIXME: set appropriate bfd error */
2296 s
= bfd_get_section_by_name (bfd_of_glue_owner
, THUMB2ARM_GLUE_SECTION_NAME
);
2300 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
2302 s
= bfd_make_section (bfd_of_glue_owner
, THUMB2ARM_GLUE_SECTION_NAME
);
2305 || !bfd_set_section_flags (bfd_of_glue_owner
, s
, flags
)
2306 || !bfd_set_section_alignment (bfd_of_glue_owner
, s
, 2))
2308 /* FIXME: set appropriate bfd error krk@cygnus.com */
2317 #include "coffcode.h"
2320 #ifdef TARGET_LITTLE_SYM
2323 armcoff_little_vec
=
2326 #ifdef TARGET_LITTLE_NAME
2331 bfd_target_coff_flavour
,
2332 BFD_ENDIAN_LITTLE
, /* data byte order is little */
2333 BFD_ENDIAN_LITTLE
, /* header byte order is little */
2335 (HAS_RELOC
| EXEC_P
| /* object flags */
2336 HAS_LINENO
| HAS_DEBUG
|
2337 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
2339 #ifndef COFF_WITH_PE
2340 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
2342 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* section flags */
2343 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
),
2346 #ifdef TARGET_UNDERSCORE
2347 TARGET_UNDERSCORE
, /* leading underscore */
2349 0, /* leading underscore */
2351 '/', /* ar_pad_char */
2352 15, /* ar_max_namelen */
2354 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
2355 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
2356 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* data */
2357 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
2358 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
2359 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* hdrs */
2361 /* Note that we allow an object file to be treated as a core file as well. */
2362 {_bfd_dummy_target
, coff_object_p
, /* bfd_check_format */
2363 bfd_generic_archive_p
, coff_object_p
},
2364 {bfd_false
, coff_mkobject
, _bfd_generic_mkarchive
, /* bfd_set_format */
2366 {bfd_false
, coff_write_object_contents
, /* bfd_write_contents */
2367 _bfd_write_archive_contents
, bfd_false
},
2369 BFD_JUMP_TABLE_GENERIC (coff
),
2370 BFD_JUMP_TABLE_COPY (coff
),
2371 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
2372 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
2373 BFD_JUMP_TABLE_SYMBOLS (coff
),
2374 BFD_JUMP_TABLE_RELOCS (coff
),
2375 BFD_JUMP_TABLE_WRITE (coff
),
2376 BFD_JUMP_TABLE_LINK (coff
),
2377 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
2379 (PTR
) & bfd_coff_std_swap_table
,
2383 #ifdef TARGET_BIG_SYM
2389 #ifdef TARGET_BIG_NAME
2394 bfd_target_coff_flavour
,
2395 BFD_ENDIAN_BIG
, /* data byte order is big */
2396 BFD_ENDIAN_BIG
, /* header byte order is big */
2398 (HAS_RELOC
| EXEC_P
| /* object flags */
2399 HAS_LINENO
| HAS_DEBUG
|
2400 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
2402 #ifndef COFF_WITH_PE
2403 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
2405 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* section flags */
2406 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
),
2409 #ifdef TARGET_UNDERSCORE
2410 TARGET_UNDERSCORE
, /* leading underscore */
2412 0, /* leading underscore */
2414 '/', /* ar_pad_char */
2415 15, /* ar_max_namelen */
2417 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
2418 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
2419 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
2420 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
2421 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
2422 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
2424 /* Note that we allow an object file to be treated as a core file as well. */
2425 {_bfd_dummy_target
, coff_object_p
, /* bfd_check_format */
2426 bfd_generic_archive_p
, coff_object_p
},
2427 {bfd_false
, coff_mkobject
, _bfd_generic_mkarchive
, /* bfd_set_format */
2429 {bfd_false
, coff_write_object_contents
, /* bfd_write_contents */
2430 _bfd_write_archive_contents
, bfd_false
},
2432 BFD_JUMP_TABLE_GENERIC (coff
),
2433 BFD_JUMP_TABLE_COPY (coff
),
2434 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
2435 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
2436 BFD_JUMP_TABLE_SYMBOLS (coff
),
2437 BFD_JUMP_TABLE_RELOCS (coff
),
2438 BFD_JUMP_TABLE_WRITE (coff
),
2439 BFD_JUMP_TABLE_LINK (coff
),
2440 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
2442 (PTR
) & bfd_coff_std_swap_table
,