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 *));
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 /* FILL ME IN (#13-249) */
829 HOWTO (R_ARM_RREL32, /* type */
831 0, /* size (0 = byte, 1 = short, 2 = long) */
833 false, /* pc_relative */
835 complain_overflow_dont, /* complain_on_overflow */
836 bfd_elf_generic_reloc, /* special_function */
837 "R_ARM_RREL32", /* name */
838 false, /* partial_inplace */
841 false), /* pcrel_offset */
843 HOWTO (R_ARM_RABS32, /* type */
845 0, /* size (0 = byte, 1 = short, 2 = long) */
847 false, /* pc_relative */
849 complain_overflow_dont, /* complain_on_overflow */
850 bfd_elf_generic_reloc, /* special_function */
851 "R_ARM_RABS32", /* name */
852 false, /* partial_inplace */
855 false), /* pcrel_offset */
857 HOWTO (R_ARM_RPC24, /* 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_RPC24", /* name */
866 false, /* partial_inplace */
869 false), /* pcrel_offset */
871 HOWTO (R_ARM_RBASE, /* 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_RBASE", /* name */
880 false, /* partial_inplace */
883 false), /* pcrel_offset */
886 struct elf32_arm_reloc_map
888 unsigned char bfd_reloc_val;
889 unsigned char elf_reloc_val;
892 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
894 {BFD_RELOC_NONE, R_ARM_NONE,},
895 {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24,},
896 {BFD_RELOC_32, R_ARM_ABS32,},
897 {BFD_RELOC_32_PCREL, R_ARM_REL32,},
898 {BFD_RELOC_8, R_ARM_ABS8,},
899 {BFD_RELOC_16, R_ARM_ABS16,},
900 {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12,},
901 {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5,},
902 {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22,},
903 {BFD_RELOC_NONE, R_ARM_SBREL32,},
904 {BFD_RELOC_NONE, R_ARM_AMP_VCALL9,},
905 {BFD_RELOC_THUMB_PCREL_BRANCH12, R_ARM_THM_PC11,},
906 {BFD_RELOC_THUMB_PCREL_BRANCH9, R_ARM_THM_PC9,}
909 static reloc_howto_type *
910 elf32_arm_reloc_type_lookup (abfd, code)
912 bfd_reloc_code_real_type code;
917 i < sizeof (elf32_arm_reloc_map) / sizeof (struct elf32_arm_reloc_map);
920 if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
921 return &elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
928 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
931 Elf32_Internal_Rela *elf_reloc;
935 r_type = ELF32_R_TYPE (elf_reloc->r_info);
936 /* fixme: need range test */
937 /* BFD_ASSERT (r_type < (unsigned int) R_ELF32_ARM_MAX); */
938 bfd_reloc->howto = &elf32_arm_howto_table[r_type];
941 /* The thumb form of a long branch is a bit finicky, because the offset
942 encoding is split over two fields, each in it's own instruction. They
943 can occur in any order. So given a thumb form of long branch, and an
944 offset, insert the offset into the thumb branch and return finished
947 It takes two thumb instructions to encode the target address. Each has
948 11 bits to invest. The upper 11 bits are stored in one (identifed by
949 H-0.. see below), the lower 11 bits are stored in the other (identified
952 Combine together and shifted left by 1 (it's a half word address) and
956 H-0, upper address-0 = 000
958 H-1, lower address-0 = 800
960 They can be ordered either way, but the arm tools I've seen always put
963 XXX: Actually the order does matter. The second instruction (H-1)
964 moves the computed address into the PC, so it must be the second one
965 in the sequence. The problem, however is that whilst little endian code
966 stores the instructions in HI then LOW order, big endian code does the
969 #define LOW_HI_ORDER 0xF800F000
970 #define HI_LOW_ORDER 0xF000F800
973 insert_thumb_branch (br_insn, rel_off)
977 unsigned int low_bits;
978 unsigned int high_bits;
981 BFD_ASSERT ((rel_off & 1) != 1);
983 rel_off >>= 1; /* half word aligned address */
984 low_bits = rel_off & 0x000007FF; /* the bottom 11 bits */
985 high_bits = (rel_off >> 11) & 0x000007FF; /* the top 11 bits */
987 if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
988 br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
989 else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
990 br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
992 abort (); /* error - not a valid branch instruction form */
999 /* Thumb code calling an ARM function */
1001 elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
1002 hit_data, sym_sec, offset, addend, val)
1003 struct bfd_link_info *info;
1007 asection *input_section;
1016 unsigned long int tmp;
1017 long int ret_offset;
1018 struct elf_link_hash_entry *myh;
1019 struct elf32_arm_link_hash_table *globals;
1021 myh = find_thumb_glue (info, name, input_bfd);
1025 globals = elf32_arm_hash_table (info);
1027 BFD_ASSERT (globals != NULL);
1028 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1030 my_offset = myh->root.u.def.value;
1032 s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1033 THUMB2ARM_GLUE_SECTION_NAME);
1035 BFD_ASSERT (s != NULL);
1036 BFD_ASSERT (s->contents != NULL);
1037 BFD_ASSERT (s->output_section != NULL);
1039 if ((my_offset & 0x01) == 0x01)
1042 && sym_sec->owner != NULL
1043 && !INTERWORK_FLAG (sym_sec->owner))
1046 (_ ("%s(%s): warning: interworking not enabled."),
1047 bfd_get_filename (sym_sec->owner), name);
1049 (_ (" first occurrence: %s: thumb call to arm"),
1050 bfd_get_filename (input_bfd));
1056 myh->root.u.def.value = my_offset;
1058 bfd_put_16 (output_bfd, t2a1_bx_pc_insn,
1059 s->contents + my_offset);
1061 bfd_put_16 (output_bfd, t2a2_noop_insn,
1062 s->contents + my_offset + 2);
1065 ((bfd_signed_vma) val) /* Address of destination of the stub */
1067 (s->output_offset /* Offset from the start of the current section to the start of the stubs. */
1068 + my_offset /* Offset of the start of this stub from the start of the stubs. */
1069 + s->output_section->vma) /* Address of the start of the current section. */
1070 + 4 /* The branch instruction is 4 bytes into the stub. */
1071 + 8); /* ARM branches work from the pc of the instruction + 8. */
1073 bfd_put_32 (output_bfd,
1074 t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1075 s->contents + my_offset + 4);
1078 BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1080 /* Now go back and fix up the original BL insn to point
1085 - (input_section->output_offset
1089 tmp = bfd_get_32 (input_bfd, hit_data
1090 - input_section->vma);
1092 bfd_put_32 (output_bfd,
1093 insert_thumb_branch (tmp, ret_offset),
1094 hit_data - input_section->vma);
1099 /* Arm code calling a Thumb function */
1101 elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
1102 hit_data, sym_sec, offset, addend, val)
1104 struct bfd_link_info *info;
1108 asection *input_section;
1115 unsigned long int tmp;
1118 long int ret_offset;
1119 struct elf_link_hash_entry *myh;
1120 struct elf32_arm_link_hash_table *globals;
1122 myh = find_arm_glue (info, name, input_bfd);
1126 globals = elf32_arm_hash_table (info);
1128 BFD_ASSERT (globals != NULL);
1129 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1131 my_offset = myh->root.u.def.value;
1132 s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1133 ARM2THUMB_GLUE_SECTION_NAME);
1134 BFD_ASSERT (s != NULL);
1135 BFD_ASSERT (s->contents != NULL);
1136 BFD_ASSERT (s->output_section != NULL);
1138 if ((my_offset & 0x01) == 0x01)
1141 && sym_sec->owner != NULL
1142 && !INTERWORK_FLAG (sym_sec->owner))
1145 (_ ("%s(%s): warning: interworking not enabled."),
1146 bfd_get_filename (sym_sec->owner), name);
1148 (_ (" first occurrence: %s: arm call to thumb"),
1149 bfd_get_filename (input_bfd));
1152 myh->root.u.def.value = my_offset;
1154 bfd_put_32 (output_bfd, a2t1_ldr_insn,
1155 s->contents + my_offset);
1157 bfd_put_32 (output_bfd, a2t2_bx_r12_insn,
1158 s->contents + my_offset + 4);
1160 /* It's a thumb address. Add the low order bit. */
1161 bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
1162 s->contents + my_offset + 8);
1165 BFD_ASSERT (my_offset <= globals->arm_glue_size);
1167 tmp = bfd_get_32 (input_bfd, hit_data);
1168 tmp = tmp & 0xFF000000;
1170 /* Somehow these are both 4 too far, so subtract 8. */
1171 ret_offset = s->output_offset
1173 + s->output_section->vma
1174 - (input_section->output_offset
1175 + input_section->output_section->vma
1179 tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1181 bfd_put_32 (output_bfd, tmp, hit_data
1182 - input_section->vma);
1188 /* Perform a relocation as part of a final link. */
1189 static bfd_reloc_status_type
1190 elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1191 input_section, contents, offset, value,
1192 addend, info, sym_sec, sym_name, sym_flags)
1193 reloc_howto_type *howto;
1196 asection *input_section;
1201 struct bfd_link_info *info;
1203 const char *sym_name;
1204 unsigned char sym_flags;
1206 unsigned long r_type = howto->type;
1207 bfd_byte *hit_data = contents + offset;
1213 return bfd_reloc_ok;
1216 /* Arm B/BL instruction */
1218 /* check for arm calling thumb function */
1219 if (sym_flags == STT_ARM_TFUNC)
1221 elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
1222 input_section, hit_data, sym_sec, offset, addend, value);
1223 return bfd_reloc_ok;
1226 value = value + addend;
1227 value -= (input_section->output_section->vma
1228 + input_section->output_offset + 8);
1230 value = value >> howto->rightshift;
1233 value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
1234 bfd_put_32 (input_bfd, value, hit_data);
1235 return bfd_reloc_ok;
1239 if (sym_flags == STT_ARM_TFUNC)
1241 bfd_put_32 (input_bfd, value, hit_data);
1242 return bfd_reloc_ok;
1245 value -= (input_section->output_section->vma
1246 + input_section->output_offset);
1249 bfd_put_32 (input_bfd, value, hit_data);
1250 return bfd_reloc_ok;
1255 if ((long) value > 0x7f || (long) value < -0x80)
1256 return bfd_reloc_overflow;
1258 bfd_put_8 (input_bfd, value, hit_data);
1259 return bfd_reloc_ok;
1264 if ((long) value > 0x7fff || (long) value < -0x8000)
1265 return bfd_reloc_overflow;
1267 bfd_put_16 (input_bfd, value, hit_data);
1268 return bfd_reloc_ok;
1271 /* Support ldr and str instruction for the arm */
1272 /* Also thumb b (unconditional branch) */
1275 if ((long) value > 0x7ff || (long) value < -0x800)
1276 return bfd_reloc_overflow;
1278 value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
1279 bfd_put_32 (input_bfd, value, hit_data);
1280 return bfd_reloc_ok;
1282 case R_ARM_THM_ABS5:
1283 /* Support ldr and str instructions for the thumb. */
1286 if ((long) value > 0x1f || (long) value < -0x10)
1287 return bfd_reloc_overflow;
1289 value |= bfd_get_16 (input_bfd, hit_data) & 0xf82f;
1290 bfd_put_16 (input_bfd, value, hit_data);
1291 return bfd_reloc_ok;
1294 case R_ARM_THM_PC22:
1295 /* thumb BL (branch long instruction). */
1298 boolean overflow = false;
1299 bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
1300 bfd_vma src_mask = 0x007FFFFE;
1301 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1302 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1304 bfd_signed_vma signed_check;
1306 bfd_signed_vma signed_add;
1308 /* If it's not a call to thumb, assume call to arm */
1309 if (sym_flags != STT_ARM_TFUNC)
1311 if (elf32_thumb_to_arm_stub
1312 (info, sym_name, input_bfd, output_bfd, input_section,
1313 hit_data, sym_sec, offset, addend, value))
1314 return bfd_reloc_ok;
1316 return bfd_reloc_dangerous;
1319 relocation = value + addend;
1320 relocation -= (input_section->output_section->vma + input_section->output_offset);
1321 relocation -= offset;
1323 check = relocation >> howto->rightshift;
1325 /* If this is a signed value, the rightshift just dropped
1326 leading 1 bits (assuming twos complement). */
1327 if ((bfd_signed_vma) relocation >= 0)
1328 signed_check = check;
1330 signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
1332 /* Get the value from the object file. */
1333 if (bfd_big_endian (input_bfd))
1334 add = (((insn) & 0x07ff0000) >> 4) | (((insn) & 0x7ff) << 1);
1336 add = ((((insn) & 0x7ff) << 12) | (((insn) & 0x07ff0000) >> 15));
1338 /* Get the value from the object file with an appropriate sign.
1339 The expression involving howto->src_mask isolates the upper
1340 bit of src_mask. If that bit is set in the value we are
1341 adding, it is negative, and we subtract out that number times
1342 two. If src_mask includes the highest possible bit, then we
1343 can not get the upper bit, but that does not matter since
1344 signed_add needs no adjustment to become negative in that case. */
1348 if ((add & (((~src_mask) >> 1) & src_mask)) != 0)
1349 signed_add -= (((~src_mask) >> 1) & src_mask) << 1;
1351 /* Add the value from the object file, shifted so that it is a
1353 /* howto->bitpos == 0 */
1355 signed_check += signed_add;
1356 relocation += signed_add;
1358 /* Assumes two's complement. */
1359 if (signed_check > reloc_signed_max
1360 || signed_check < reloc_signed_min)
1363 /* Put RELOCATION into the correct bits: */
1365 if (bfd_big_endian (input_bfd))
1366 relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1368 relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1370 /* Add RELOCATION to the correct bits of X: */
1371 insn = ((insn & ~howto->dst_mask) | relocation);
1373 /* Put the relocated value back in the object file: */
1374 bfd_put_32 (input_bfd, insn, hit_data);
1376 return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
1381 return bfd_reloc_notsupported;
1383 case R_ARM_AMP_VCALL9:
1384 return bfd_reloc_notsupported;
1386 case R_ARM_RSBREL32:
1387 return bfd_reloc_notsupported;
1389 case R_ARM_THM_RPC22:
1390 return bfd_reloc_notsupported;
1393 return bfd_reloc_notsupported;
1396 return bfd_reloc_notsupported;
1399 return bfd_reloc_notsupported;
1402 return bfd_reloc_notsupported;
1405 return bfd_reloc_notsupported;
1410 /* Relocate an ARM ELF section. */
1412 elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1413 contents, relocs, local_syms, local_sections)
1415 struct bfd_link_info *info;
1417 asection *input_section;
1419 Elf_Internal_Rela *relocs;
1420 Elf_Internal_Sym *local_syms;
1421 asection **local_sections;
1423 Elf_Internal_Shdr *symtab_hdr;
1424 struct elf_link_hash_entry **sym_hashes;
1425 Elf_Internal_Rela *rel, *relend;
1428 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1429 sym_hashes = elf_sym_hashes (input_bfd);
1432 relend = relocs + input_section->reloc_count;
1433 for (; rel < relend; rel++)
1436 reloc_howto_type *howto;
1437 unsigned long r_symndx;
1438 Elf_Internal_Sym *sym;
1440 struct elf_link_hash_entry *h;
1442 bfd_reloc_status_type r;
1444 r_symndx = ELF32_R_SYM (rel->r_info);
1445 r_type = ELF32_R_TYPE (rel->r_info);
1446 howto = elf32_arm_howto_table + r_type;
1448 if (info->relocateable)
1450 /* This is a relocateable link. We don't have to change
1451 anything, unless the reloc is against a section symbol,
1452 in which case we have to adjust according to where the
1453 section symbol winds up in the output section. */
1454 if (r_symndx < symtab_hdr->sh_info)
1456 sym = local_syms + r_symndx;
1457 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1459 sec = local_sections[r_symndx];
1460 rel->r_addend += sec->output_offset + sym->st_value;
1467 /* This is a final link. */
1471 if (r_symndx < symtab_hdr->sh_info)
1473 sym = local_syms + r_symndx;
1474 sec = local_sections[r_symndx];
1475 relocation = (sec->output_section->vma
1476 + sec->output_offset
1481 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1482 while (h->root.type == bfd_link_hash_indirect
1483 || h->root.type == bfd_link_hash_warning)
1484 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1485 if (h->root.type == bfd_link_hash_defined
1486 || h->root.type == bfd_link_hash_defweak)
1488 sec = h->root.u.def.section;
1489 relocation = (h->root.u.def.value
1490 + sec->output_section->vma
1491 + sec->output_offset);
1493 else if (h->root.type == bfd_link_hash_undefweak)
1497 if (!((*info->callbacks->undefined_symbol)
1498 (info, h->root.root.string, input_bfd,
1499 input_section, rel->r_offset)))
1506 name = h->root.root.string;
1509 name = (bfd_elf_string_from_elf_section
1510 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1511 if (name == NULL || *name == '\0')
1512 name = bfd_section_name (input_bfd, sec);
1515 r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1517 contents, rel->r_offset,
1518 relocation, rel->r_addend,
1520 (h ? ELF_ST_TYPE (h->type) :
1521 ELF_ST_TYPE (sym->st_info)));
1523 if (r != bfd_reloc_ok)
1525 const char * msg = (const char *) 0;
1529 case bfd_reloc_overflow:
1530 if (!((*info->callbacks->reloc_overflow)
1531 (info, name, howto->name, (bfd_vma) 0,
1532 input_bfd, input_section, rel->r_offset)))
1536 case bfd_reloc_undefined:
1537 if (!((*info->callbacks->undefined_symbol)
1538 (info, name, input_bfd, input_section,
1543 case bfd_reloc_outofrange:
1544 msg = _ ("internal error: out of range error");
1547 case bfd_reloc_notsupported:
1548 msg = _ ("internal error: unsupported relocation error");
1551 case bfd_reloc_dangerous:
1552 msg = _ ("internal error: dangerous error");
1556 msg = _ ("internal error: unknown error");
1560 if (!((*info->callbacks->warning)
1561 (info, msg, name, input_bfd, input_section,
1572 /* Function to keep ARM specific flags in the ELF header. */
1574 elf32_arm_set_private_flags (abfd, flags)
1578 if (elf_flags_init (abfd)
1579 && elf_elfheader (abfd)->e_flags != flags)
1581 if (flags & EF_INTERWORK)
1582 _bfd_error_handler (_ ("\
1583 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
1584 bfd_get_filename (abfd));
1586 _bfd_error_handler (_ ("\
1587 Warning: Clearing the interwork flag of %s due to outside request"),
1588 bfd_get_filename (abfd));
1592 elf_elfheader (abfd)->e_flags = flags;
1593 elf_flags_init (abfd) = true;
1599 /* Copy backend specific data from one object module to another */
1601 elf32_arm_copy_private_bfd_data (ibfd, obfd)
1608 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1609 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1612 in_flags = elf_elfheader (ibfd)->e_flags;
1613 out_flags = elf_elfheader (obfd)->e_flags;
1615 if (elf_flags_init (obfd) && in_flags != out_flags)
1617 /* Cannot mix PIC and non-PIC code. */
1618 if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1621 /* Cannot mix APCS26 and APCS32 code. */
1622 if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1625 /* Cannot mix float APCS and non-float APCS code. */
1626 if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1629 /* If the src and dest have different interworking flags
1630 then turn off the interworking bit. */
1631 if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1633 if (out_flags & EF_INTERWORK)
1634 _bfd_error_handler (_ ("\
1635 Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
1636 bfd_get_filename (obfd), bfd_get_filename (ibfd));
1638 in_flags &= ~EF_INTERWORK;
1642 elf_elfheader (obfd)->e_flags = in_flags;
1643 elf_flags_init (obfd) = true;
1648 /* Merge backend specific data from an object file to the output
1649 object file when linking. */
1651 elf32_arm_merge_private_bfd_data (ibfd, obfd)
1658 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1659 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1662 /* The input BFD must have had its flags initialised. */
1663 /* The following seems bogus to me -- The flags are initialized in
1664 the assembler but I don't think an elf_flags_init field is
1665 written into the object */
1666 /* BFD_ASSERT (elf_flags_init (ibfd)); */
1668 in_flags = elf_elfheader (ibfd)->e_flags;
1669 out_flags = elf_elfheader (obfd)->e_flags;
1671 if (!elf_flags_init (obfd))
1673 /* If the input is the default architecture then do not
1674 bother setting the flags for the output architecture,
1675 instead allow future merges to do this. If no future
1676 merges ever set these flags then they will retain their
1677 unitialised values, which surprise surprise, correspond
1678 to the default values. */
1679 if (bfd_get_arch_info (ibfd)->the_default)
1682 elf_flags_init (obfd) = true;
1683 elf_elfheader (obfd)->e_flags = in_flags;
1685 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1686 && bfd_get_arch_info (obfd)->the_default)
1687 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1692 /* Check flag compatibility. */
1693 if (in_flags == out_flags)
1696 /* Complain about various flag mismatches. */
1698 if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1699 _bfd_error_handler (_ ("\
1700 Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
1701 bfd_get_filename (ibfd),
1702 in_flags & EF_APCS_26 ? 26 : 32,
1703 bfd_get_filename (obfd),
1704 out_flags & EF_APCS_26 ? 26 : 32);
1706 if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1707 _bfd_error_handler (_ ("\
1708 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
1709 bfd_get_filename (ibfd),
1710 in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
1711 bfd_get_filename (obfd),
1712 out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
1714 if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1715 _bfd_error_handler (_ ("\
1716 Error: %s is compiled as position %s code, whereas %s is not"),
1717 bfd_get_filename (ibfd),
1718 in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
1719 bfd_get_filename (obfd));
1721 /* Interworking mismatch is only a warning. */
1722 if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1724 _bfd_error_handler (_ ("\
1725 Warning: %s %s interworking, whereas %s %s"),
1726 bfd_get_filename (ibfd),
1727 in_flags & EF_INTERWORK ? _ ("supports") : _ ("does not support"),
1728 bfd_get_filename (obfd),
1729 out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
1736 /* Display the flags field */
1738 elf32_arm_print_private_bfd_data (abfd, ptr)
1742 FILE *file = (FILE *) ptr;
1744 BFD_ASSERT (abfd != NULL && ptr != NULL);
1746 /* Print normal ELF private data. */
1747 _bfd_elf_print_private_bfd_data (abfd, ptr);
1749 /* Ignore init flag - it may not be set, despite the flags field containing valid data. */
1751 /* xgettext:c-format */
1752 fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1754 if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
1755 fprintf (file, _ (" [interworking enabled]"));
1757 fprintf (file, _ (" [interworking not enabled]"));
1759 if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
1760 fprintf (file, _ (" [APCS-26]"));
1762 fprintf (file, _ (" [APCS-32]"));
1764 if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
1765 fprintf (file, _ (" [floats passed in float registers]"));
1767 fprintf (file, _ (" [floats passed in integer registers]"));
1769 if (elf_elfheader (abfd)->e_flags & EF_PIC)
1770 fprintf (file, _ (" [position independent]"));
1772 fprintf (file, _ (" [absolute position]"));
1780 elf32_arm_get_symbol_type (elf_sym)
1781 Elf_Internal_Sym * elf_sym;
1783 return ELF_ST_TYPE (elf_sym->st_info);
1789 /* Find the nearest line to a particular section and offset, for error
1790 reporting. This code is a duplicate of the code in elf.c, except
1791 that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
1794 elf32_arm_find_nearest_line
1795 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
1800 CONST char ** filename_ptr;
1801 CONST char ** functionname_ptr;
1802 unsigned int * line_ptr;
1805 const char * filename;
1810 if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
1811 filename_ptr, functionname_ptr,
1815 if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
1816 &found, filename_ptr,
1817 functionname_ptr, line_ptr,
1818 &elf_tdata (abfd)->line_info))
1824 if (symbols == NULL)
1831 for (p = symbols; *p != NULL; p++)
1835 q = (elf_symbol_type *) *p;
1837 if (bfd_get_section (&q->symbol) != section)
1840 switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
1845 filename = bfd_asymbol_name (&q->symbol);
1850 if (q->symbol.section == section
1851 && q->symbol.value >= low_func
1852 && q->symbol.value <= offset)
1854 func = (asymbol *) q;
1855 low_func = q->symbol.value;
1864 *filename_ptr = filename;
1865 *functionname_ptr = bfd_asymbol_name (func);
1872 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec
1873 #define TARGET_LITTLE_NAME "elf32-littlearm"
1874 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec
1875 #define TARGET_BIG_NAME "elf32-bigarm"
1876 #define ELF_ARCH bfd_arch_arm
1877 #define ELF_MACHINE_CODE EM_ARM
1879 #define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
1880 #define elf_info_to_howto elf32_arm_info_to_howto
1881 #define elf_info_to_howto_rel 0
1882 #define elf_backend_relocate_section elf32_arm_relocate_section
1883 #define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
1884 #define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
1885 #define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags
1886 #define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data
1887 #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
1888 #define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
1889 #define elf_backend_get_symbol_type elf32_arm_get_symbol_type
1890 #define elf_symbol_leading_char '_'
1892 #include "elf32-target.h"