1 /* 32-bit ELF support for ARM
2 Copyright 1993, 1995, 1998 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 typedef unsigned long int insn32
;
28 typedef unsigned short int insn16
;
30 static reloc_howto_type
*elf32_arm_reloc_type_lookup
31 PARAMS ((bfd
* abfd
, bfd_reloc_code_real_type code
));
32 static void elf32_arm_info_to_howto
33 PARAMS ((bfd
*, arelent
*, Elf32_Internal_Rela
*));
34 static boolean elf32_arm_set_private_flags
35 PARAMS ((bfd
*, flagword
));
36 static boolean elf32_arm_copy_private_bfd_data
37 PARAMS ((bfd
*, bfd
*));
38 static boolean elf32_arm_merge_private_bfd_data
39 PARAMS ((bfd
*, bfd
*));
40 static boolean elf32_arm_print_private_bfd_data
41 PARAMS ((bfd
*, PTR
));
42 static int elf32_arm_get_symbol_type
43 PARAMS (( Elf_Internal_Sym
*, int));
44 static struct bfd_link_hash_table
*elf32_arm_link_hash_table_create
48 static insn32 insert_thumb_branch
49 PARAMS ((insn32
, int));
50 static struct elf_link_hash_entry
*find_thumb_glue
51 PARAMS ((struct bfd_link_info
*, CONST
char *, bfd
*));
52 static struct elf_link_hash_entry
*find_arm_glue
53 PARAMS ((struct bfd_link_info
*, CONST
char *, bfd
*));
54 static void record_arm_to_thumb_glue
55 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*));
56 static void record_thumb_to_arm_glue
57 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*));
59 /* The linker script knows the section names for placement.
60 The entry_names are used to do simple name mangling on the stubs.
61 Given a function name, and its type, the stub can be found. The
62 name can be changed. The only requirement is the %s be present.
65 #define INTERWORK_FLAG( abfd ) (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
67 #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
68 #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
70 #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
71 #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
73 /* Get the ARM elf linker hash table from a link_info structure. */
74 #define elf32_arm_hash_table(info) \
75 ((struct elf32_arm_link_hash_table *) ((info)->hash))
77 /* ARM ELF linker hash table */
78 struct elf32_arm_link_hash_table
80 /* The main hash table. */
81 struct elf_link_hash_table root
;
83 /* The size in bytes of the section containg the Thumb-to-ARM glue. */
84 long int thumb_glue_size
;
86 /* The size in bytes of the section containg the ARM-to-Thumb glue. */
87 long int arm_glue_size
;
89 /* An arbitary input BFD chosen to hold the glue sections. */
90 bfd
*bfd_of_glue_owner
;
96 /* Create an ARM elf linker hash table */
98 static struct bfd_link_hash_table
*
99 elf32_arm_link_hash_table_create (abfd
)
102 struct elf32_arm_link_hash_table
*ret
;
104 ret
= ((struct elf32_arm_link_hash_table
*)
105 bfd_alloc (abfd
, sizeof (struct elf32_arm_link_hash_table
)));
106 if (ret
== (struct elf32_arm_link_hash_table
*) NULL
)
109 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
110 _bfd_elf_link_hash_newfunc
))
112 bfd_release (abfd
, ret
);
116 ret
->thumb_glue_size
= 0;
117 ret
->arm_glue_size
= 0;
118 ret
->bfd_of_glue_owner
= NULL
;
120 return &ret
->root
.root
;
123 static struct elf_link_hash_entry
*
124 find_thumb_glue (link_info
, name
, input_bfd
)
125 struct bfd_link_info
*link_info
;
130 struct elf_link_hash_entry
*hash
;
131 struct elf32_arm_link_hash_table
*hash_table
;
133 /* We need a pointer to the armelf specific hash table. */
134 hash_table
= elf32_arm_hash_table (link_info
);
138 bfd_malloc (strlen (name
) + strlen (THUMB2ARM_GLUE_ENTRY_NAME
) + 1));
140 BFD_ASSERT (tmp_name
);
142 sprintf (tmp_name
, THUMB2ARM_GLUE_ENTRY_NAME
, name
);
144 hash
= elf_link_hash_lookup
145 (&(hash_table
)->root
, tmp_name
, false, false, true);
148 /* xgettext:c-format */
149 _bfd_error_handler (_ ("%s: unable to find THUMB glue '%s' for `%s'"),
150 bfd_get_filename (input_bfd
), tmp_name
, name
);
157 static struct elf_link_hash_entry
*
158 find_arm_glue (link_info
, name
, input_bfd
)
159 struct bfd_link_info
*link_info
;
164 struct elf_link_hash_entry
*myh
;
165 struct elf32_arm_link_hash_table
*hash_table
;
167 /* We need a pointer to the elfarm specific hash table. */
168 hash_table
= elf32_arm_hash_table (link_info
);
171 bfd_malloc (strlen (name
) + strlen (ARM2THUMB_GLUE_ENTRY_NAME
) + 1));
173 BFD_ASSERT (tmp_name
);
175 sprintf (tmp_name
, ARM2THUMB_GLUE_ENTRY_NAME
, name
);
177 myh
= elf_link_hash_lookup
178 (&(hash_table
)->root
, tmp_name
, false, false, true);
181 /* xgettext:c-format */
182 _bfd_error_handler (_ ("%s: unable to find ARM glue '%s' for `%s'"),
183 bfd_get_filename (input_bfd
), tmp_name
, name
);
198 .word func @ behave as if you saw a ARM_32 reloc
201 #define ARM2THUMB_GLUE_SIZE 12
202 static const insn32 a2t1_ldr_insn
= 0xe59fc000;
203 static const insn32 a2t2_bx_r12_insn
= 0xe12fff1c;
204 static const insn32 a2t3_func_addr_insn
= 0x00000001;
207 Thumb->ARM: Thumb->(non-interworking aware) ARM
211 __func_from_thumb: __func_from_thumb:
213 nop ldr r6, __func_addr
215 __func_change_to_arm: bx r6
217 __func_back_to_thumb:
224 #define THUMB2ARM_GLUE_SIZE 8
225 static const insn16 t2a1_bx_pc_insn
= 0x4778;
226 static const insn16 t2a2_noop_insn
= 0x46c0;
227 static const insn32 t2a3_b_insn
= 0xea000000;
229 static const insn16 t2a1_push_insn
= 0xb540;
230 static const insn16 t2a2_ldr_insn
= 0x4e03;
231 static const insn16 t2a3_mov_insn
= 0x46fe;
232 static const insn16 t2a4_bx_insn
= 0x4730;
233 static const insn32 t2a5_pop_insn
= 0xe8bd4040;
234 static const insn32 t2a6_bx_insn
= 0xe12fff1e;
237 bfd_elf32_arm_allocate_interworking_sections (info
)
238 struct bfd_link_info
*info
;
242 struct elf32_arm_link_hash_table
*globals
;
244 globals
= elf32_arm_hash_table (info
);
246 BFD_ASSERT (globals
!= NULL
);
248 if (globals
->arm_glue_size
!= 0)
250 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
252 s
= bfd_get_section_by_name
253 (globals
->bfd_of_glue_owner
, ARM2THUMB_GLUE_SECTION_NAME
);
255 BFD_ASSERT (s
!= NULL
);
257 foo
= (bfd_byte
*) bfd_alloc
258 (globals
->bfd_of_glue_owner
, globals
->arm_glue_size
);
260 s
->_raw_size
= s
->_cooked_size
= globals
->arm_glue_size
;
264 if (globals
->thumb_glue_size
!= 0)
266 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
268 s
= bfd_get_section_by_name
269 (globals
->bfd_of_glue_owner
, THUMB2ARM_GLUE_SECTION_NAME
);
271 BFD_ASSERT (s
!= NULL
);
273 foo
= (bfd_byte
*) bfd_alloc
274 (globals
->bfd_of_glue_owner
, globals
->thumb_glue_size
);
276 s
->_raw_size
= s
->_cooked_size
= globals
->thumb_glue_size
;
284 record_arm_to_thumb_glue (link_info
, h
)
285 struct bfd_link_info
*link_info
;
286 struct elf_link_hash_entry
*h
;
288 const char *name
= h
->root
.root
.string
;
289 register asection
*s
;
291 struct elf_link_hash_entry
*myh
;
292 struct elf32_arm_link_hash_table
*globals
;
294 globals
= elf32_arm_hash_table (link_info
);
296 BFD_ASSERT (globals
!= NULL
);
297 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
299 s
= bfd_get_section_by_name
300 (globals
->bfd_of_glue_owner
, ARM2THUMB_GLUE_SECTION_NAME
);
303 BFD_ASSERT (s
!= NULL
);
306 bfd_malloc (strlen (name
) + strlen (ARM2THUMB_GLUE_ENTRY_NAME
) + 1));
308 BFD_ASSERT (tmp_name
);
310 sprintf (tmp_name
, ARM2THUMB_GLUE_ENTRY_NAME
, name
);
312 myh
= elf_link_hash_lookup
313 (&(globals
)->root
, tmp_name
, false, false, true);
318 return; /* we've already seen this guy */
321 /* The only trick here is using hash_table->arm_glue_size as the value. Even
322 though the section isn't allocated yet, this is where we will be putting
325 _bfd_generic_link_add_one_symbol (link_info
, globals
->bfd_of_glue_owner
, tmp_name
,
327 s
, globals
->arm_glue_size
+ 1,
329 (struct bfd_link_hash_entry
**) &myh
);
333 globals
->arm_glue_size
+= ARM2THUMB_GLUE_SIZE
;
339 record_thumb_to_arm_glue (link_info
, h
)
340 struct bfd_link_info
*link_info
;
341 struct elf_link_hash_entry
*h
;
343 const char *name
= h
->root
.root
.string
;
344 register asection
*s
;
346 struct elf_link_hash_entry
*myh
;
347 struct elf32_arm_link_hash_table
*hash_table
;
350 hash_table
= elf32_arm_hash_table (link_info
);
352 BFD_ASSERT (hash_table
!= NULL
);
353 BFD_ASSERT (hash_table
->bfd_of_glue_owner
!= NULL
);
355 s
= bfd_get_section_by_name
356 (hash_table
->bfd_of_glue_owner
, THUMB2ARM_GLUE_SECTION_NAME
);
358 BFD_ASSERT (s
!= NULL
);
360 tmp_name
= (char *) bfd_malloc (strlen (name
) + strlen (THUMB2ARM_GLUE_ENTRY_NAME
) + 1);
362 BFD_ASSERT (tmp_name
);
364 sprintf (tmp_name
, THUMB2ARM_GLUE_ENTRY_NAME
, name
);
366 myh
= elf_link_hash_lookup
367 (&(hash_table
)->root
, tmp_name
, false, false, true);
372 return; /* we've already seen this guy */
375 _bfd_generic_link_add_one_symbol (link_info
, hash_table
->bfd_of_glue_owner
, tmp_name
,
376 BSF_GLOBAL
, s
, hash_table
->thumb_glue_size
+ 1,
378 (struct bfd_link_hash_entry
**) &myh
);
380 /* If we mark it 'thumb', the disassembler will do a better job. */
381 bind
= ELF_ST_BIND (myh
->type
);
382 myh
->type
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
386 /* Allocate another symbol to mark where we switch to arm mode. */
388 #define CHANGE_TO_ARM "__%s_change_to_arm"
389 #define BACK_FROM_ARM "__%s_back_from_arm"
391 tmp_name
= (char *) bfd_malloc (strlen (name
) + strlen (CHANGE_TO_ARM
) + 1);
393 BFD_ASSERT (tmp_name
);
395 sprintf (tmp_name
, CHANGE_TO_ARM
, name
);
399 _bfd_generic_link_add_one_symbol (link_info
, hash_table
->bfd_of_glue_owner
, tmp_name
,
400 BSF_LOCAL
, s
, hash_table
->thumb_glue_size
+ 4,
402 (struct bfd_link_hash_entry
**) &myh
);
406 hash_table
->thumb_glue_size
+= THUMB2ARM_GLUE_SIZE
;
411 /* Select a BFD to be used to hold the sections used by the glue code.
412 This function is called from the linker scripts in ld/emultempl/
415 bfd_elf32_arm_get_bfd_for_interworking (abfd
, info
)
417 struct bfd_link_info
*info
;
419 struct elf32_arm_link_hash_table
*globals
;
423 /* If we are only performing a partial link do not bother
424 getting a bfd to hold the glue. */
425 if (info
->relocateable
)
428 globals
= elf32_arm_hash_table (info
);
430 BFD_ASSERT (globals
!= NULL
);
432 if (globals
->bfd_of_glue_owner
!= NULL
)
435 sec
= bfd_get_section_by_name (abfd
, ARM2THUMB_GLUE_SECTION_NAME
);
439 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
441 sec
= bfd_make_section (abfd
, ARM2THUMB_GLUE_SECTION_NAME
);
444 || !bfd_set_section_flags (abfd
, sec
, flags
)
445 || !bfd_set_section_alignment (abfd
, sec
, 2))
449 sec
= bfd_get_section_by_name (abfd
, THUMB2ARM_GLUE_SECTION_NAME
);
453 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
455 sec
= bfd_make_section (abfd
, THUMB2ARM_GLUE_SECTION_NAME
);
458 || !bfd_set_section_flags (abfd
, sec
, flags
)
459 || !bfd_set_section_alignment (abfd
, sec
, 2))
463 /* Save the bfd for later use. */
464 globals
->bfd_of_glue_owner
= abfd
;
470 bfd_elf32_arm_process_before_allocation (abfd
, link_info
)
472 struct bfd_link_info
*link_info
;
474 Elf_Internal_Shdr
*symtab_hdr
;
475 Elf_Internal_Rela
*free_relocs
= NULL
;
476 Elf_Internal_Rela
*irel
, *irelend
;
477 bfd_byte
*contents
= NULL
;
478 bfd_byte
*free_contents
= NULL
;
479 Elf32_External_Sym
*extsyms
= NULL
;
480 Elf32_External_Sym
*free_extsyms
= NULL
;
483 struct elf32_arm_link_hash_table
*globals
;
485 /* If we are only performing a partial link do not bother
486 to construct any glue. */
487 if (link_info
->relocateable
)
490 /* Here we have a bfd that is to be included on the link. We have a hook
491 to do reloc rummaging, before section sizes are nailed down. */
493 globals
= elf32_arm_hash_table (link_info
);
495 BFD_ASSERT (globals
!= NULL
);
496 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
498 /* Rummage around all the relocs and map the glue vectors. */
499 sec
= abfd
->sections
;
504 for (; sec
!= NULL
; sec
= sec
->next
)
506 if (sec
->reloc_count
== 0)
509 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
510 /* Load the relocs. */
512 irel
= (_bfd_elf32_link_read_relocs (abfd
, sec
, (PTR
) NULL
,
513 (Elf_Internal_Rela
*) NULL
, false));
515 BFD_ASSERT (irel
!= 0);
517 irelend
= irel
+ sec
->reloc_count
;
518 for (; irel
< irelend
; irel
++)
521 unsigned long r_index
;
524 struct elf_link_hash_entry
*h
;
526 r_type
= ELF32_R_TYPE (irel
->r_info
);
527 r_index
= ELF32_R_SYM (irel
->r_info
);
529 /* These are the only relocation types we care about */
530 if (r_type
!= R_ARM_PC24
531 && r_type
!= R_ARM_THM_PC22
)
534 /* Get the section contents if we haven't done so already. */
535 if (contents
== NULL
)
537 /* Get cached copy if it exists. */
538 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
539 contents
= elf_section_data (sec
)->this_hdr
.contents
;
542 /* Go get them off disk. */
543 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
544 if (contents
== NULL
)
546 free_contents
= contents
;
548 if (!bfd_get_section_contents (abfd
, sec
, contents
,
549 (file_ptr
) 0, sec
->_raw_size
))
554 /* Read this BFD's symbols if we haven't done so already. */
557 /* Get cached copy if it exists. */
558 if (symtab_hdr
->contents
!= NULL
)
559 extsyms
= (Elf32_External_Sym
*) symtab_hdr
->contents
;
562 /* Go get them off disk. */
563 extsyms
= ((Elf32_External_Sym
*)
564 bfd_malloc (symtab_hdr
->sh_size
));
567 free_extsyms
= extsyms
;
568 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
569 || (bfd_read (extsyms
, 1, symtab_hdr
->sh_size
, abfd
)
570 != symtab_hdr
->sh_size
))
575 /* If the relocation is not against a symbol it cannot concern us. */
579 /* We don't care about local symbols */
580 if (r_index
< symtab_hdr
->sh_info
)
583 /* This is an external symbol */
584 r_index
-= symtab_hdr
->sh_info
;
585 h
= (struct elf_link_hash_entry
*)
586 elf_sym_hashes (abfd
)[r_index
];
588 /* If the relocation is against a static symbol it must be within
589 the current section and so cannot be a cross ARM/Thumb relocation. */
596 /* This one is a call from arm code. We need to look up
597 the target of the call. If it is a thumb target, we
600 if (ELF_ST_TYPE(h
->type
) == STT_ARM_TFUNC
)
601 record_arm_to_thumb_glue (link_info
, h
);
605 /* This one is a call from thumb code. We look
606 up the target of the call. If it is not a thumb
607 target, we insert glue. */
609 if (ELF_ST_TYPE (h
->type
) != STT_ARM_TFUNC
)
610 record_thumb_to_arm_glue (link_info
, h
);
621 if (free_relocs
!= NULL
)
623 if (free_contents
!= NULL
)
624 free (free_contents
);
625 if (free_extsyms
!= NULL
)
632 #define TARGET_UNDERSCORE '_'
634 static reloc_howto_type elf32_arm_howto_table
[] =
637 HOWTO (R_ARM_NONE
, /* type */
639 0, /* size (0 = byte, 1 = short, 2 = long) */
641 false, /* pc_relative */
643 complain_overflow_dont
, /* complain_on_overflow */
644 bfd_elf_generic_reloc
, /* special_function */
645 "R_ARM_NONE", /* name */
646 false, /* partial_inplace */
649 false), /* pcrel_offset */
651 HOWTO (R_ARM_PC24
, /* type */
653 2, /* size (0 = byte, 1 = short, 2 = long) */
655 true, /* pc_relative */
657 complain_overflow_signed
, /* complain_on_overflow */
658 bfd_elf_generic_reloc
, /* special_function */
659 "R_ARM_PC24", /* name */
660 false, /* partial_inplace */
661 0x00ffffff, /* src_mask */
662 0x00ffffff, /* dst_mask */
663 true), /* pcrel_offset */
665 /* 32 bit absolute */
666 HOWTO (R_ARM_ABS32
, /* type */
668 2, /* size (0 = byte, 1 = short, 2 = long) */
670 false, /* pc_relative */
672 complain_overflow_bitfield
, /* complain_on_overflow */
673 bfd_elf_generic_reloc
, /* special_function */
674 "R_ARM_ABS32", /* name */
675 false, /* partial_inplace */
676 0xffffffff, /* src_mask */
677 0xffffffff, /* dst_mask */
678 false), /* pcrel_offset */
680 /* standard 32bit pc-relative reloc */
681 HOWTO (R_ARM_REL32
, /* type */
683 2, /* size (0 = byte, 1 = short, 2 = long) */
685 true, /* pc_relative */
687 complain_overflow_bitfield
, /* complain_on_overflow */
688 bfd_elf_generic_reloc
, /* special_function */
689 "R_ARM_REL32", /* name */
690 false, /* partial_inplace */
691 0xffffffff, /* src_mask */
692 0xffffffff, /* dst_mask */
693 true), /* pcrel_offset */
696 HOWTO (R_ARM_ABS8
, /* type */
698 0, /* size (0 = byte, 1 = short, 2 = long) */
700 false, /* pc_relative */
702 complain_overflow_bitfield
, /* complain_on_overflow */
703 bfd_elf_generic_reloc
, /* special_function */
704 "R_ARM_ABS8", /* name */
705 false, /* partial_inplace */
706 0x000000ff, /* src_mask */
707 0x000000ff, /* dst_mask */
708 false), /* pcrel_offset */
710 /* 16 bit absolute */
711 HOWTO (R_ARM_ABS16
, /* type */
713 1, /* size (0 = byte, 1 = short, 2 = long) */
715 false, /* pc_relative */
717 complain_overflow_bitfield
, /* complain_on_overflow */
718 bfd_elf_generic_reloc
, /* special_function */
719 "R_ARM_ABS16", /* name */
720 false, /* partial_inplace */
723 false), /* pcrel_offset */
725 /* 12 bit absolute */
726 HOWTO (R_ARM_ABS12
, /* type */
728 2, /* size (0 = byte, 1 = short, 2 = long) */
730 false, /* pc_relative */
732 complain_overflow_bitfield
, /* complain_on_overflow */
733 bfd_elf_generic_reloc
, /* special_function */
734 "R_ARM_ABS12", /* name */
735 false, /* partial_inplace */
736 0x000008ff, /* src_mask */
737 0x000008ff, /* dst_mask */
738 false), /* pcrel_offset */
740 HOWTO (R_ARM_THM_ABS5
, /* type */
742 2, /* size (0 = byte, 1 = short, 2 = long) */
744 false, /* pc_relative */
746 complain_overflow_bitfield
, /* complain_on_overflow */
747 bfd_elf_generic_reloc
, /* special_function */
748 "R_ARM_THM_ABS5", /* name */
749 false, /* partial_inplace */
750 0x000007e0, /* src_mask */
751 0x000007e0, /* dst_mask */
752 false), /* pcrel_offset */
754 HOWTO (R_ARM_THM_PC22
, /* type */
756 2, /* size (0 = byte, 1 = short, 2 = long) */
758 true, /* pc_relative */
760 complain_overflow_signed
, /* complain_on_overflow */
761 bfd_elf_generic_reloc
, /* special_function */
762 "R_ARM_THM_PC22", /* name */
763 false, /* partial_inplace */
764 0x07ff07ff, /* src_mask */
765 0x07ff07ff, /* dst_mask */
766 true), /* pcrel_offset */
768 HOWTO (R_ARM_SBREL32
, /* type */
770 0, /* size (0 = byte, 1 = short, 2 = long) */
772 false, /* pc_relative */
774 complain_overflow_dont
, /* complain_on_overflow */
775 bfd_elf_generic_reloc
, /* special_function */
776 "R_ARM_SBREL32", /* name */
777 false, /* partial_inplace */
780 false), /* pcrel_offset */
782 HOWTO (R_ARM_AMP_VCALL9
, /* type */
784 1, /* size (0 = byte, 1 = short, 2 = long) */
786 true, /* pc_relative */
788 complain_overflow_signed
, /* complain_on_overflow */
789 bfd_elf_generic_reloc
, /* special_function */
790 "R_ARM_AMP_VCALL9", /* name */
791 false, /* partial_inplace */
792 0x000000ff, /* src_mask */
793 0x000000ff, /* dst_mask */
794 true), /* pcrel_offset */
796 /* 12 bit pc relative */
797 HOWTO (R_ARM_THM_PC11
, /* type */
799 1, /* size (0 = byte, 1 = short, 2 = long) */
801 true, /* pc_relative */
803 complain_overflow_signed
, /* complain_on_overflow */
804 bfd_elf_generic_reloc
, /* special_function */
805 "R_ARM_THM_PC11", /* name */
806 false, /* partial_inplace */
807 0x000007ff, /* src_mask */
808 0x000007ff, /* dst_mask */
809 true), /* pcrel_offset */
811 /* 12 bit pc relative */
812 HOWTO (R_ARM_THM_PC9
, /* type */
814 1, /* size (0 = byte, 1 = short, 2 = long) */
816 true, /* pc_relative */
818 complain_overflow_signed
, /* complain_on_overflow */
819 bfd_elf_generic_reloc
, /* special_function */
820 "R_ARM_THM_PC9", /* name */
821 false, /* partial_inplace */
822 0x000000ff, /* src_mask */
823 0x000000ff, /* dst_mask */
824 true), /* pcrel_offset */
826 /* GNU extension to record C++ vtable hierarchy */
827 HOWTO (R_ARM_GNU_VTINHERIT
, /* type */
829 2, /* size (0 = byte, 1 = short, 2 = long) */
831 false, /* pc_relative */
833 complain_overflow_dont
, /* complain_on_overflow */
834 NULL
, /* special_function */
835 "R_ARM_GNU_VTINHERIT", /* name */
836 false, /* partial_inplace */
839 false), /* pcrel_offset */
841 /* GNU extension to record C++ vtable member usage */
842 HOWTO (R_ARM_GNU_VTENTRY
, /* type */
844 2, /* size (0 = byte, 1 = short, 2 = long) */
846 false, /* pc_relative */
848 complain_overflow_dont
, /* complain_on_overflow */
849 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
850 "R_ARM_GNU_VTENTRY", /* name */
851 false, /* partial_inplace */
854 false), /* pcrel_offset */
857 HOWTO (R_ARM_RREL32
, /* type */
859 0, /* size (0 = byte, 1 = short, 2 = long) */
861 false, /* pc_relative */
863 complain_overflow_dont
, /* complain_on_overflow */
864 bfd_elf_generic_reloc
, /* special_function */
865 "R_ARM_RREL32", /* name */
866 false, /* partial_inplace */
869 false), /* pcrel_offset */
871 HOWTO (R_ARM_RABS32
, /* type */
873 0, /* size (0 = byte, 1 = short, 2 = long) */
875 false, /* pc_relative */
877 complain_overflow_dont
, /* complain_on_overflow */
878 bfd_elf_generic_reloc
, /* special_function */
879 "R_ARM_RABS32", /* name */
880 false, /* partial_inplace */
883 false), /* pcrel_offset */
885 HOWTO (R_ARM_RPC24
, /* type */
887 0, /* size (0 = byte, 1 = short, 2 = long) */
889 false, /* pc_relative */
891 complain_overflow_dont
, /* complain_on_overflow */
892 bfd_elf_generic_reloc
, /* special_function */
893 "R_ARM_RPC24", /* name */
894 false, /* partial_inplace */
897 false), /* pcrel_offset */
899 HOWTO (R_ARM_RBASE
, /* type */
901 0, /* size (0 = byte, 1 = short, 2 = long) */
903 false, /* pc_relative */
905 complain_overflow_dont
, /* complain_on_overflow */
906 bfd_elf_generic_reloc
, /* special_function */
907 "R_ARM_RBASE", /* name */
908 false, /* partial_inplace */
911 false), /* pcrel_offset */
914 struct elf32_arm_reloc_map
916 unsigned char bfd_reloc_val
;
917 unsigned char elf_reloc_val
;
920 static const struct elf32_arm_reloc_map elf32_arm_reloc_map
[] =
922 {BFD_RELOC_NONE
, R_ARM_NONE
,},
923 {BFD_RELOC_ARM_PCREL_BRANCH
, R_ARM_PC24
,},
924 {BFD_RELOC_32
, R_ARM_ABS32
,},
925 {BFD_RELOC_32_PCREL
, R_ARM_REL32
,},
926 {BFD_RELOC_8
, R_ARM_ABS8
,},
927 {BFD_RELOC_16
, R_ARM_ABS16
,},
928 {BFD_RELOC_ARM_OFFSET_IMM
, R_ARM_ABS12
,},
929 {BFD_RELOC_ARM_THUMB_OFFSET
, R_ARM_THM_ABS5
,},
930 {BFD_RELOC_THUMB_PCREL_BRANCH23
, R_ARM_THM_PC22
,},
931 {BFD_RELOC_VTABLE_INHERIT
, R_ARM_GNU_VTINHERIT
},
932 {BFD_RELOC_VTABLE_ENTRY
, R_ARM_GNU_VTENTRY
},
933 {BFD_RELOC_NONE
, R_ARM_SBREL32
,},
934 {BFD_RELOC_NONE
, R_ARM_AMP_VCALL9
,},
935 {BFD_RELOC_THUMB_PCREL_BRANCH12
, R_ARM_THM_PC11
,},
936 {BFD_RELOC_THUMB_PCREL_BRANCH9
, R_ARM_THM_PC9
,}
939 static reloc_howto_type
*
940 elf32_arm_reloc_type_lookup (abfd
, code
)
942 bfd_reloc_code_real_type code
;
947 i
< sizeof (elf32_arm_reloc_map
) / sizeof (struct elf32_arm_reloc_map
);
950 if (elf32_arm_reloc_map
[i
].bfd_reloc_val
== code
)
951 return &elf32_arm_howto_table
[elf32_arm_reloc_map
[i
].elf_reloc_val
];
958 elf32_arm_info_to_howto (abfd
, bfd_reloc
, elf_reloc
)
961 Elf32_Internal_Rela
*elf_reloc
;
965 r_type
= ELF32_R_TYPE (elf_reloc
->r_info
);
966 /* fixme: need range test */
967 /* BFD_ASSERT (r_type < (unsigned int) R_ELF32_ARM_MAX); */
968 bfd_reloc
->howto
= &elf32_arm_howto_table
[r_type
];
971 /* The thumb form of a long branch is a bit finicky, because the offset
972 encoding is split over two fields, each in it's own instruction. They
973 can occur in any order. So given a thumb form of long branch, and an
974 offset, insert the offset into the thumb branch and return finished
977 It takes two thumb instructions to encode the target address. Each has
978 11 bits to invest. The upper 11 bits are stored in one (identifed by
979 H-0.. see below), the lower 11 bits are stored in the other (identified
982 Combine together and shifted left by 1 (it's a half word address) and
986 H-0, upper address-0 = 000
988 H-1, lower address-0 = 800
990 They can be ordered either way, but the arm tools I've seen always put
991 the lower one first. It probably doesn't matter. krk@cygnus.com
993 XXX: Actually the order does matter. The second instruction (H-1)
994 moves the computed address into the PC, so it must be the second one
995 in the sequence. The problem, however is that whilst little endian code
996 stores the instructions in HI then LOW order, big endian code does the
997 reverse. nickc@cygnus.com */
999 #define LOW_HI_ORDER 0xF800F000
1000 #define HI_LOW_ORDER 0xF000F800
1003 insert_thumb_branch (br_insn
, rel_off
)
1007 unsigned int low_bits
;
1008 unsigned int high_bits
;
1011 BFD_ASSERT ((rel_off
& 1) != 1);
1013 rel_off
>>= 1; /* half word aligned address */
1014 low_bits
= rel_off
& 0x000007FF; /* the bottom 11 bits */
1015 high_bits
= (rel_off
>> 11) & 0x000007FF; /* the top 11 bits */
1017 if ((br_insn
& LOW_HI_ORDER
) == LOW_HI_ORDER
)
1018 br_insn
= LOW_HI_ORDER
| (low_bits
<< 16) | high_bits
;
1019 else if ((br_insn
& HI_LOW_ORDER
) == HI_LOW_ORDER
)
1020 br_insn
= HI_LOW_ORDER
| (high_bits
<< 16) | low_bits
;
1022 abort (); /* error - not a valid branch instruction form */
1024 /* FIXME: abort is probably not the right call. krk@cygnus.com */
1029 /* Thumb code calling an ARM function */
1031 elf32_thumb_to_arm_stub (info
, name
, input_bfd
, output_bfd
, input_section
,
1032 hit_data
, sym_sec
, offset
, addend
, val
)
1033 struct bfd_link_info
*info
;
1037 asection
*input_section
;
1046 unsigned long int tmp
;
1047 long int ret_offset
;
1048 struct elf_link_hash_entry
*myh
;
1049 struct elf32_arm_link_hash_table
*globals
;
1051 myh
= find_thumb_glue (info
, name
, input_bfd
);
1055 globals
= elf32_arm_hash_table (info
);
1057 BFD_ASSERT (globals
!= NULL
);
1058 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1060 my_offset
= myh
->root
.u
.def
.value
;
1062 s
= bfd_get_section_by_name (globals
->bfd_of_glue_owner
,
1063 THUMB2ARM_GLUE_SECTION_NAME
);
1065 BFD_ASSERT (s
!= NULL
);
1066 BFD_ASSERT (s
->contents
!= NULL
);
1067 BFD_ASSERT (s
->output_section
!= NULL
);
1069 if ((my_offset
& 0x01) == 0x01)
1072 && sym_sec
->owner
!= NULL
1073 && !INTERWORK_FLAG (sym_sec
->owner
))
1076 (_ ("%s(%s): warning: interworking not enabled."),
1077 bfd_get_filename (sym_sec
->owner
), name
);
1079 (_ (" first occurrence: %s: thumb call to arm"),
1080 bfd_get_filename (input_bfd
));
1086 myh
->root
.u
.def
.value
= my_offset
;
1088 bfd_put_16 (output_bfd
, t2a1_bx_pc_insn
,
1089 s
->contents
+ my_offset
);
1091 bfd_put_16 (output_bfd
, t2a2_noop_insn
,
1092 s
->contents
+ my_offset
+ 2);
1095 ((bfd_signed_vma
) val
) /* Address of destination of the stub */
1097 (s
->output_offset
/* Offset from the start of the current section to the start of the stubs. */
1098 + my_offset
/* Offset of the start of this stub from the start of the stubs. */
1099 + s
->output_section
->vma
) /* Address of the start of the current section. */
1100 + 4 /* The branch instruction is 4 bytes into the stub. */
1101 + 8); /* ARM branches work from the pc of the instruction + 8. */
1103 bfd_put_32 (output_bfd
,
1104 t2a3_b_insn
| ((ret_offset
>> 2) & 0x00FFFFFF),
1105 s
->contents
+ my_offset
+ 4);
1108 BFD_ASSERT (my_offset
<= globals
->thumb_glue_size
);
1110 /* Now go back and fix up the original BL insn to point
1115 - (input_section
->output_offset
1119 tmp
= bfd_get_32 (input_bfd
, hit_data
1120 - input_section
->vma
);
1122 bfd_put_32 (output_bfd
,
1123 insert_thumb_branch (tmp
, ret_offset
),
1124 hit_data
- input_section
->vma
);
1129 /* Arm code calling a Thumb function */
1131 elf32_arm_to_thumb_stub (info
, name
, input_bfd
, output_bfd
, input_section
,
1132 hit_data
, sym_sec
, offset
, addend
, val
)
1134 struct bfd_link_info
*info
;
1138 asection
*input_section
;
1145 unsigned long int tmp
;
1148 long int ret_offset
;
1149 struct elf_link_hash_entry
*myh
;
1150 struct elf32_arm_link_hash_table
*globals
;
1152 myh
= find_arm_glue (info
, name
, input_bfd
);
1156 globals
= elf32_arm_hash_table (info
);
1158 BFD_ASSERT (globals
!= NULL
);
1159 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
1161 my_offset
= myh
->root
.u
.def
.value
;
1162 s
= bfd_get_section_by_name (globals
->bfd_of_glue_owner
,
1163 ARM2THUMB_GLUE_SECTION_NAME
);
1164 BFD_ASSERT (s
!= NULL
);
1165 BFD_ASSERT (s
->contents
!= NULL
);
1166 BFD_ASSERT (s
->output_section
!= NULL
);
1168 if ((my_offset
& 0x01) == 0x01)
1171 && sym_sec
->owner
!= NULL
1172 && !INTERWORK_FLAG (sym_sec
->owner
))
1175 (_ ("%s(%s): warning: interworking not enabled."),
1176 bfd_get_filename (sym_sec
->owner
), name
);
1178 (_ (" first occurrence: %s: arm call to thumb"),
1179 bfd_get_filename (input_bfd
));
1182 myh
->root
.u
.def
.value
= my_offset
;
1184 bfd_put_32 (output_bfd
, a2t1_ldr_insn
,
1185 s
->contents
+ my_offset
);
1187 bfd_put_32 (output_bfd
, a2t2_bx_r12_insn
,
1188 s
->contents
+ my_offset
+ 4);
1190 /* It's a thumb address. Add the low order bit. */
1191 bfd_put_32 (output_bfd
, val
| a2t3_func_addr_insn
,
1192 s
->contents
+ my_offset
+ 8);
1195 BFD_ASSERT (my_offset
<= globals
->arm_glue_size
);
1197 tmp
= bfd_get_32 (input_bfd
, hit_data
);
1198 tmp
= tmp
& 0xFF000000;
1200 /* Somehow these are both 4 too far, so subtract 8. */
1201 ret_offset
= s
->output_offset
1203 + s
->output_section
->vma
1204 - (input_section
->output_offset
1205 + input_section
->output_section
->vma
1209 tmp
= tmp
| ((ret_offset
>> 2) & 0x00FFFFFF);
1211 bfd_put_32 (output_bfd
, tmp
, hit_data
1212 - input_section
->vma
);
1218 /* Perform a relocation as part of a final link. */
1219 static bfd_reloc_status_type
1220 elf32_arm_final_link_relocate (howto
, input_bfd
, output_bfd
,
1221 input_section
, contents
, offset
, value
,
1222 addend
, info
, sym_sec
, sym_name
, sym_flags
)
1223 reloc_howto_type
*howto
;
1226 asection
*input_section
;
1231 struct bfd_link_info
*info
;
1233 const char *sym_name
;
1234 unsigned char sym_flags
;
1236 unsigned long r_type
= howto
->type
;
1237 bfd_byte
*hit_data
= contents
+ offset
;
1243 return bfd_reloc_ok
;
1246 /* Arm B/BL instruction */
1248 /* check for arm calling thumb function */
1249 if (sym_flags
== STT_ARM_TFUNC
)
1251 elf32_arm_to_thumb_stub (info
, sym_name
, input_bfd
, output_bfd
,
1252 input_section
, hit_data
, sym_sec
, offset
, addend
, value
);
1253 return bfd_reloc_ok
;
1256 value
= value
+ addend
;
1257 value
-= (input_section
->output_section
->vma
1258 + input_section
->output_offset
+ 8);
1260 value
= value
>> howto
->rightshift
;
1263 value
|= (bfd_get_32 (input_bfd
, hit_data
) & 0xff000000);
1264 bfd_put_32 (input_bfd
, value
, hit_data
);
1265 return bfd_reloc_ok
;
1269 if (sym_flags
== STT_ARM_TFUNC
)
1271 bfd_put_32 (input_bfd
, value
, hit_data
);
1272 return bfd_reloc_ok
;
1275 value
-= (input_section
->output_section
->vma
1276 + input_section
->output_offset
);
1279 bfd_put_32 (input_bfd
, value
, hit_data
);
1280 return bfd_reloc_ok
;
1285 if ((long) value
> 0x7f || (long) value
< -0x80)
1286 return bfd_reloc_overflow
;
1288 bfd_put_8 (input_bfd
, value
, hit_data
);
1289 return bfd_reloc_ok
;
1294 if ((long) value
> 0x7fff || (long) value
< -0x8000)
1295 return bfd_reloc_overflow
;
1297 bfd_put_16 (input_bfd
, value
, hit_data
);
1298 return bfd_reloc_ok
;
1301 /* Support ldr and str instruction for the arm */
1302 /* Also thumb b (unconditional branch) */
1305 if ((long) value
> 0x7ff || (long) value
< -0x800)
1306 return bfd_reloc_overflow
;
1308 value
|= (bfd_get_32 (input_bfd
, hit_data
) & 0xfffff000);
1309 bfd_put_32 (input_bfd
, value
, hit_data
);
1310 return bfd_reloc_ok
;
1312 case R_ARM_THM_ABS5
:
1313 /* Support ldr and str instructions for the thumb. */
1316 if ((long) value
> 0x1f || (long) value
< -0x10)
1317 return bfd_reloc_overflow
;
1319 value
|= bfd_get_16 (input_bfd
, hit_data
) & 0xf82f;
1320 bfd_put_16 (input_bfd
, value
, hit_data
);
1321 return bfd_reloc_ok
;
1324 case R_ARM_THM_PC22
:
1325 /* thumb BL (branch long instruction). */
1328 boolean overflow
= false;
1329 bfd_vma insn
= bfd_get_32 (input_bfd
, hit_data
);
1330 bfd_vma src_mask
= 0x007FFFFE;
1331 bfd_signed_vma reloc_signed_max
= (1 << (howto
->bitsize
- 1)) - 1;
1332 bfd_signed_vma reloc_signed_min
= ~reloc_signed_max
;
1334 bfd_signed_vma signed_check
;
1336 bfd_signed_vma signed_add
;
1338 /* If it's not a call to thumb, assume call to arm */
1339 if (sym_flags
!= STT_ARM_TFUNC
)
1341 if (elf32_thumb_to_arm_stub
1342 (info
, sym_name
, input_bfd
, output_bfd
, input_section
,
1343 hit_data
, sym_sec
, offset
, addend
, value
))
1344 return bfd_reloc_ok
;
1346 return bfd_reloc_dangerous
;
1349 relocation
= value
+ addend
;
1350 relocation
-= (input_section
->output_section
->vma
+ input_section
->output_offset
);
1351 relocation
-= offset
;
1353 check
= relocation
>> howto
->rightshift
;
1355 /* If this is a signed value, the rightshift just dropped
1356 leading 1 bits (assuming twos complement). */
1357 if ((bfd_signed_vma
) relocation
>= 0)
1358 signed_check
= check
;
1360 signed_check
= (check
| ((bfd_vma
) - 1 & ~((bfd_vma
) - 1 >> howto
->rightshift
)));
1362 /* Get the value from the object file. */
1363 if (bfd_big_endian (input_bfd
))
1364 add
= (((insn
) & 0x07ff0000) >> 4) | (((insn
) & 0x7ff) << 1);
1366 add
= ((((insn
) & 0x7ff) << 12) | (((insn
) & 0x07ff0000) >> 15));
1368 /* Get the value from the object file with an appropriate sign.
1369 The expression involving howto->src_mask isolates the upper
1370 bit of src_mask. If that bit is set in the value we are
1371 adding, it is negative, and we subtract out that number times
1372 two. If src_mask includes the highest possible bit, then we
1373 can not get the upper bit, but that does not matter since
1374 signed_add needs no adjustment to become negative in that case. */
1378 if ((add
& (((~src_mask
) >> 1) & src_mask
)) != 0)
1379 signed_add
-= (((~src_mask
) >> 1) & src_mask
) << 1;
1381 /* Add the value from the object file, shifted so that it is a
1383 /* howto->bitpos == 0 */
1385 signed_check
+= signed_add
;
1386 relocation
+= signed_add
;
1388 /* Assumes two's complement. */
1389 if (signed_check
> reloc_signed_max
1390 || signed_check
< reloc_signed_min
)
1393 /* Put RELOCATION into the correct bits: */
1395 if (bfd_big_endian (input_bfd
))
1396 relocation
= (((relocation
& 0xffe) >> 1) | ((relocation
<< 4) & 0x07ff0000));
1398 relocation
= (((relocation
& 0xffe) << 15) | ((relocation
>> 12) & 0x7ff));
1400 /* Add RELOCATION to the correct bits of X: */
1401 insn
= ((insn
& ~howto
->dst_mask
) | relocation
);
1403 /* Put the relocated value back in the object file: */
1404 bfd_put_32 (input_bfd
, insn
, hit_data
);
1406 return (overflow
? bfd_reloc_overflow
: bfd_reloc_ok
);
1410 case R_ARM_GNU_VTINHERIT
:
1411 case R_ARM_GNU_VTENTRY
:
1412 return bfd_reloc_ok
;
1415 return bfd_reloc_notsupported
;
1417 case R_ARM_AMP_VCALL9
:
1418 return bfd_reloc_notsupported
;
1420 case R_ARM_RSBREL32
:
1421 return bfd_reloc_notsupported
;
1423 case R_ARM_THM_RPC22
:
1424 return bfd_reloc_notsupported
;
1427 return bfd_reloc_notsupported
;
1430 return bfd_reloc_notsupported
;
1433 return bfd_reloc_notsupported
;
1436 return bfd_reloc_notsupported
;
1439 return bfd_reloc_notsupported
;
1444 /* Relocate an ARM ELF section. */
1446 elf32_arm_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
1447 contents
, relocs
, local_syms
, local_sections
)
1449 struct bfd_link_info
*info
;
1451 asection
*input_section
;
1453 Elf_Internal_Rela
*relocs
;
1454 Elf_Internal_Sym
*local_syms
;
1455 asection
**local_sections
;
1457 Elf_Internal_Shdr
*symtab_hdr
;
1458 struct elf_link_hash_entry
**sym_hashes
;
1459 Elf_Internal_Rela
*rel
, *relend
;
1462 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
1463 sym_hashes
= elf_sym_hashes (input_bfd
);
1466 relend
= relocs
+ input_section
->reloc_count
;
1467 for (; rel
< relend
; rel
++)
1470 reloc_howto_type
*howto
;
1471 unsigned long r_symndx
;
1472 Elf_Internal_Sym
*sym
;
1474 struct elf_link_hash_entry
*h
;
1476 bfd_reloc_status_type r
;
1478 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1479 r_type
= ELF32_R_TYPE (rel
->r_info
);
1481 if (r_type
== R_ARM_GNU_VTENTRY
1482 || r_type
== R_ARM_GNU_VTINHERIT
)
1485 howto
= elf32_arm_howto_table
+ r_type
;
1487 if (info
->relocateable
)
1489 /* This is a relocateable link. We don't have to change
1490 anything, unless the reloc is against a section symbol,
1491 in which case we have to adjust according to where the
1492 section symbol winds up in the output section. */
1493 if (r_symndx
< symtab_hdr
->sh_info
)
1495 sym
= local_syms
+ r_symndx
;
1496 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1498 sec
= local_sections
[r_symndx
];
1499 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1506 /* This is a final link. */
1510 if (r_symndx
< symtab_hdr
->sh_info
)
1512 sym
= local_syms
+ r_symndx
;
1513 sec
= local_sections
[r_symndx
];
1514 relocation
= (sec
->output_section
->vma
1515 + sec
->output_offset
1520 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1521 while (h
->root
.type
== bfd_link_hash_indirect
1522 || h
->root
.type
== bfd_link_hash_warning
)
1523 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1524 if (h
->root
.type
== bfd_link_hash_defined
1525 || h
->root
.type
== bfd_link_hash_defweak
)
1527 sec
= h
->root
.u
.def
.section
;
1528 relocation
= (h
->root
.u
.def
.value
1529 + sec
->output_section
->vma
1530 + sec
->output_offset
);
1532 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1536 if (!((*info
->callbacks
->undefined_symbol
)
1537 (info
, h
->root
.root
.string
, input_bfd
,
1538 input_section
, rel
->r_offset
)))
1545 name
= h
->root
.root
.string
;
1548 name
= (bfd_elf_string_from_elf_section
1549 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1550 if (name
== NULL
|| *name
== '\0')
1551 name
= bfd_section_name (input_bfd
, sec
);
1554 r
= elf32_arm_final_link_relocate (howto
, input_bfd
, output_bfd
,
1556 contents
, rel
->r_offset
,
1557 relocation
, rel
->r_addend
,
1559 (h
? ELF_ST_TYPE (h
->type
) :
1560 ELF_ST_TYPE (sym
->st_info
)));
1562 if (r
!= bfd_reloc_ok
)
1564 const char * msg
= (const char *) 0;
1568 case bfd_reloc_overflow
:
1569 if (!((*info
->callbacks
->reloc_overflow
)
1570 (info
, name
, howto
->name
, (bfd_vma
) 0,
1571 input_bfd
, input_section
, rel
->r_offset
)))
1575 case bfd_reloc_undefined
:
1576 if (!((*info
->callbacks
->undefined_symbol
)
1577 (info
, name
, input_bfd
, input_section
,
1582 case bfd_reloc_outofrange
:
1583 msg
= _ ("internal error: out of range error");
1586 case bfd_reloc_notsupported
:
1587 msg
= _ ("internal error: unsupported relocation error");
1590 case bfd_reloc_dangerous
:
1591 msg
= _ ("internal error: dangerous error");
1595 msg
= _ ("internal error: unknown error");
1599 if (!((*info
->callbacks
->warning
)
1600 (info
, msg
, name
, input_bfd
, input_section
,
1611 /* Function to keep ARM specific flags in the ELF header. */
1613 elf32_arm_set_private_flags (abfd
, flags
)
1617 if (elf_flags_init (abfd
)
1618 && elf_elfheader (abfd
)->e_flags
!= flags
)
1620 if (flags
& EF_INTERWORK
)
1621 _bfd_error_handler (_ ("\
1622 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
1623 bfd_get_filename (abfd
));
1625 _bfd_error_handler (_ ("\
1626 Warning: Clearing the interwork flag of %s due to outside request"),
1627 bfd_get_filename (abfd
));
1631 elf_elfheader (abfd
)->e_flags
= flags
;
1632 elf_flags_init (abfd
) = true;
1638 /* Copy backend specific data from one object module to another */
1640 elf32_arm_copy_private_bfd_data (ibfd
, obfd
)
1647 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1648 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1651 in_flags
= elf_elfheader (ibfd
)->e_flags
;
1652 out_flags
= elf_elfheader (obfd
)->e_flags
;
1654 if (elf_flags_init (obfd
) && in_flags
!= out_flags
)
1656 /* Cannot mix PIC and non-PIC code. */
1657 if ((in_flags
& EF_PIC
) != (out_flags
& EF_PIC
))
1660 /* Cannot mix APCS26 and APCS32 code. */
1661 if ((in_flags
& EF_APCS_26
) != (out_flags
& EF_APCS_26
))
1664 /* Cannot mix float APCS and non-float APCS code. */
1665 if ((in_flags
& EF_APCS_FLOAT
) != (out_flags
& EF_APCS_FLOAT
))
1668 /* If the src and dest have different interworking flags
1669 then turn off the interworking bit. */
1670 if ((in_flags
& EF_INTERWORK
) != (out_flags
& EF_INTERWORK
))
1672 if (out_flags
& EF_INTERWORK
)
1673 _bfd_error_handler (_ ("\
1674 Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
1675 bfd_get_filename (obfd
), bfd_get_filename (ibfd
));
1677 in_flags
&= ~EF_INTERWORK
;
1681 elf_elfheader (obfd
)->e_flags
= in_flags
;
1682 elf_flags_init (obfd
) = true;
1687 /* Merge backend specific data from an object file to the output
1688 object file when linking. */
1690 elf32_arm_merge_private_bfd_data (ibfd
, obfd
)
1697 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1698 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1701 /* The input BFD must have had its flags initialised. */
1702 /* The following seems bogus to me -- The flags are initialized in
1703 the assembler but I don't think an elf_flags_init field is
1704 written into the object */
1705 /* BFD_ASSERT (elf_flags_init (ibfd)); */
1707 in_flags
= elf_elfheader (ibfd
)->e_flags
;
1708 out_flags
= elf_elfheader (obfd
)->e_flags
;
1710 if (!elf_flags_init (obfd
))
1712 /* If the input is the default architecture then do not
1713 bother setting the flags for the output architecture,
1714 instead allow future merges to do this. If no future
1715 merges ever set these flags then they will retain their
1716 unitialised values, which surprise surprise, correspond
1717 to the default values. */
1718 if (bfd_get_arch_info (ibfd
)->the_default
)
1721 elf_flags_init (obfd
) = true;
1722 elf_elfheader (obfd
)->e_flags
= in_flags
;
1724 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
1725 && bfd_get_arch_info (obfd
)->the_default
)
1726 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
1731 /* Check flag compatibility. */
1732 if (in_flags
== out_flags
)
1735 /* Complain about various flag mismatches. */
1737 if ((in_flags
& EF_APCS_26
) != (out_flags
& EF_APCS_26
))
1738 _bfd_error_handler (_ ("\
1739 Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
1740 bfd_get_filename (ibfd
),
1741 in_flags
& EF_APCS_26
? 26 : 32,
1742 bfd_get_filename (obfd
),
1743 out_flags
& EF_APCS_26
? 26 : 32);
1745 if ((in_flags
& EF_APCS_FLOAT
) != (out_flags
& EF_APCS_FLOAT
))
1746 _bfd_error_handler (_ ("\
1747 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
1748 bfd_get_filename (ibfd
),
1749 in_flags
& EF_APCS_FLOAT
? _ ("float") : _ ("integer"),
1750 bfd_get_filename (obfd
),
1751 out_flags
& EF_APCS_26
? _ ("float") : _ ("integer"));
1753 if ((in_flags
& EF_PIC
) != (out_flags
& EF_PIC
))
1754 _bfd_error_handler (_ ("\
1755 Error: %s is compiled as position %s code, whereas %s is not"),
1756 bfd_get_filename (ibfd
),
1757 in_flags
& EF_PIC
? _ ("independent") : _ ("dependent"),
1758 bfd_get_filename (obfd
));
1760 /* Interworking mismatch is only a warning. */
1761 if ((in_flags
& EF_INTERWORK
) != (out_flags
& EF_INTERWORK
))
1763 _bfd_error_handler (_ ("\
1764 Warning: %s %s interworking, whereas %s %s"),
1765 bfd_get_filename (ibfd
),
1766 in_flags
& EF_INTERWORK
? _ ("supports") : _ ("does not support"),
1767 bfd_get_filename (obfd
),
1768 out_flags
& EF_INTERWORK
? _ ("does not") : _ ("does"));
1775 /* Display the flags field */
1777 elf32_arm_print_private_bfd_data (abfd
, ptr
)
1781 FILE *file
= (FILE *) ptr
;
1783 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
1785 /* Print normal ELF private data. */
1786 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
1788 /* Ignore init flag - it may not be set, despite the flags field containing valid data. */
1790 /* xgettext:c-format */
1791 fprintf (file
, _ ("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
1793 if (elf_elfheader (abfd
)->e_flags
& EF_INTERWORK
)
1794 fprintf (file
, _ (" [interworking enabled]"));
1796 fprintf (file
, _ (" [interworking not enabled]"));
1798 if (elf_elfheader (abfd
)->e_flags
& EF_APCS_26
)
1799 fprintf (file
, _ (" [APCS-26]"));
1801 fprintf (file
, _ (" [APCS-32]"));
1803 if (elf_elfheader (abfd
)->e_flags
& EF_APCS_FLOAT
)
1804 fprintf (file
, _ (" [floats passed in float registers]"));
1806 fprintf (file
, _ (" [floats passed in integer registers]"));
1808 if (elf_elfheader (abfd
)->e_flags
& EF_PIC
)
1809 fprintf (file
, _ (" [position independent]"));
1811 fprintf (file
, _ (" [absolute position]"));
1819 elf32_arm_get_symbol_type (elf_sym
, type
)
1820 Elf_Internal_Sym
* elf_sym
;
1823 if (ELF_ST_TYPE (elf_sym
->st_info
) == STT_ARM_TFUNC
)
1824 return ELF_ST_TYPE (elf_sym
->st_info
);
1830 elf32_arm_gc_mark_hook (abfd
, info
, rel
, h
, sym
)
1832 struct bfd_link_info
*info
;
1833 Elf_Internal_Rela
*rel
;
1834 struct elf_link_hash_entry
*h
;
1835 Elf_Internal_Sym
*sym
;
1839 switch (ELF32_R_TYPE (rel
->r_info
))
1841 case R_ARM_GNU_VTINHERIT
:
1842 case R_ARM_GNU_VTENTRY
:
1846 printf("h is %s\n", h
->root
.root
.string
);
1847 switch (h
->root
.type
)
1849 case bfd_link_hash_defined
:
1850 case bfd_link_hash_defweak
:
1851 return h
->root
.u
.def
.section
;
1853 case bfd_link_hash_common
:
1854 return h
->root
.u
.c
.p
->section
;
1860 if (!(elf_bad_symtab (abfd
)
1861 && ELF_ST_BIND (sym
->st_info
) != STB_LOCAL
)
1862 && ! ((sym
->st_shndx
<= 0 || sym
->st_shndx
>= SHN_LORESERVE
)
1863 && sym
->st_shndx
!= SHN_COMMON
))
1865 return bfd_section_from_elf_index (abfd
, sym
->st_shndx
);
1872 elf32_arm_gc_sweep_hook (abfd
, info
, sec
, relocs
)
1874 struct bfd_link_info
*info
;
1876 const Elf_Internal_Rela
*relocs
;
1878 /* we don't use got and plt entries for armelf */
1882 /* Look through the relocs for a section during the first phase.
1883 Since we don't do .gots or .plts, we just need to consider the
1884 virtual table relocs for gc. */
1887 elf32_arm_check_relocs (abfd
, info
, sec
, relocs
)
1889 struct bfd_link_info
*info
;
1891 const Elf_Internal_Rela
*relocs
;
1893 Elf_Internal_Shdr
*symtab_hdr
;
1894 struct elf_link_hash_entry
**sym_hashes
, **sym_hashes_end
;
1895 const Elf_Internal_Rela
*rel
;
1896 const Elf_Internal_Rela
*rel_end
;
1898 if (info
->relocateable
)
1901 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1902 sym_hashes
= elf_sym_hashes (abfd
);
1903 sym_hashes_end
= sym_hashes
+ symtab_hdr
->sh_size
/sizeof(Elf32_External_Sym
);
1904 if (!elf_bad_symtab (abfd
))
1905 sym_hashes_end
-= symtab_hdr
->sh_info
;
1907 rel_end
= relocs
+ sec
->reloc_count
;
1908 for (rel
= relocs
; rel
< rel_end
; rel
++)
1910 struct elf_link_hash_entry
*h
;
1911 unsigned long r_symndx
;
1913 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1914 if (r_symndx
< symtab_hdr
->sh_info
)
1917 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1919 switch (ELF32_R_TYPE (rel
->r_info
))
1921 /* This relocation describes the C++ object vtable hierarchy.
1922 Reconstruct it for later use during GC. */
1923 case R_ARM_GNU_VTINHERIT
:
1924 if (!_bfd_elf32_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
1928 /* This relocation describes which C++ vtable entries are actually
1929 used. Record for later use during GC. */
1930 case R_ARM_GNU_VTENTRY
:
1931 if (!_bfd_elf32_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
1941 /* Find the nearest line to a particular section and offset, for error
1942 reporting. This code is a duplicate of the code in elf.c, except
1943 that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
1946 elf32_arm_find_nearest_line
1947 (abfd
, section
, symbols
, offset
, filename_ptr
, functionname_ptr
, line_ptr
)
1952 CONST
char ** filename_ptr
;
1953 CONST
char ** functionname_ptr
;
1954 unsigned int * line_ptr
;
1957 const char * filename
;
1962 if (_bfd_dwarf2_find_nearest_line (abfd
, section
, symbols
, offset
,
1963 filename_ptr
, functionname_ptr
,
1967 if (! _bfd_stab_section_find_nearest_line (abfd
, symbols
, section
, offset
,
1968 &found
, filename_ptr
,
1969 functionname_ptr
, line_ptr
,
1970 &elf_tdata (abfd
)->line_info
))
1976 if (symbols
== NULL
)
1983 for (p
= symbols
; *p
!= NULL
; p
++)
1987 q
= (elf_symbol_type
*) *p
;
1989 if (bfd_get_section (&q
->symbol
) != section
)
1992 switch (ELF_ST_TYPE (q
->internal_elf_sym
.st_info
))
1997 filename
= bfd_asymbol_name (&q
->symbol
);
2002 if (q
->symbol
.section
== section
2003 && q
->symbol
.value
>= low_func
2004 && q
->symbol
.value
<= offset
)
2006 func
= (asymbol
*) q
;
2007 low_func
= q
->symbol
.value
;
2016 *filename_ptr
= filename
;
2017 *functionname_ptr
= bfd_asymbol_name (func
);
2024 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec
2025 #define TARGET_LITTLE_NAME "elf32-littlearm"
2026 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec
2027 #define TARGET_BIG_NAME "elf32-bigarm"
2028 #define ELF_ARCH bfd_arch_arm
2029 #define ELF_MACHINE_CODE EM_ARM
2031 #define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
2032 #define elf_info_to_howto elf32_arm_info_to_howto
2033 #define elf_info_to_howto_rel 0
2034 #define elf_backend_relocate_section elf32_arm_relocate_section
2035 #define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
2036 #define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
2037 #define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags
2038 #define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data
2039 #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
2040 #define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
2041 #define elf_backend_get_symbol_type elf32_arm_get_symbol_type
2042 #define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
2043 #define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook
2044 #define elf_backend_check_relocs elf32_arm_check_relocs
2046 #define elf_backend_can_gc_sections 1
2047 #define elf_symbol_leading_char '_'
2049 #include "elf32-target.h"