1 /* 32-bit ELF support for ARM
2 Copyright 1998, 1999 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. */
21 typedef unsigned long int insn32
;
22 typedef unsigned short int insn16
;
24 static void elf32_arm_info_to_howto
25 PARAMS ((bfd
*, arelent
*, Elf32_Internal_Rela
*));
26 static boolean elf32_arm_set_private_flags
27 PARAMS ((bfd
*, flagword
));
28 static boolean elf32_arm_copy_private_bfd_data
29 PARAMS ((bfd
*, bfd
*));
30 static boolean elf32_arm_merge_private_bfd_data
31 PARAMS ((bfd
*, bfd
*));
32 static boolean elf32_arm_print_private_bfd_data
33 PARAMS ((bfd
*, PTR
));
34 static int elf32_arm_get_symbol_type
35 PARAMS (( Elf_Internal_Sym
*, int));
36 static struct bfd_link_hash_table
*elf32_arm_link_hash_table_create
40 static insn32 insert_thumb_branch
41 PARAMS ((insn32
, int));
42 static struct elf_link_hash_entry
*find_thumb_glue
43 PARAMS ((struct bfd_link_info
*, CONST
char *, bfd
*));
44 static struct elf_link_hash_entry
*find_arm_glue
45 PARAMS ((struct bfd_link_info
*, CONST
char *, bfd
*));
46 static void record_arm_to_thumb_glue
47 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*));
48 static void record_thumb_to_arm_glue
49 PARAMS ((struct bfd_link_info
*, struct elf_link_hash_entry
*));
51 /* The linker script knows the section names for placement.
52 The entry_names are used to do simple name mangling on the stubs.
53 Given a function name, and its type, the stub can be found. The
54 name can be changed. The only requirement is the %s be present.
57 #define INTERWORK_FLAG( abfd ) (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
59 #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
60 #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
62 #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
63 #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
65 /* Get the ARM elf linker hash table from a link_info structure. */
66 #define elf32_arm_hash_table(info) \
67 ((struct elf32_arm_link_hash_table *) ((info)->hash))
69 /* ARM ELF linker hash table */
70 struct elf32_arm_link_hash_table
72 /* The main hash table. */
73 struct elf_link_hash_table root
;
75 /* The size in bytes of the section containg the Thumb-to-ARM glue. */
76 long int thumb_glue_size
;
78 /* The size in bytes of the section containg the ARM-to-Thumb glue. */
79 long int arm_glue_size
;
81 /* An arbitary input BFD chosen to hold the glue sections. */
82 bfd
*bfd_of_glue_owner
;
88 /* Create an ARM elf linker hash table */
90 static struct bfd_link_hash_table
*
91 elf32_arm_link_hash_table_create (abfd
)
94 struct elf32_arm_link_hash_table
*ret
;
96 ret
= ((struct elf32_arm_link_hash_table
*)
97 bfd_alloc (abfd
, sizeof (struct elf32_arm_link_hash_table
)));
98 if (ret
== (struct elf32_arm_link_hash_table
*) NULL
)
101 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
102 _bfd_elf_link_hash_newfunc
))
104 bfd_release (abfd
, ret
);
108 ret
->thumb_glue_size
= 0;
109 ret
->arm_glue_size
= 0;
110 ret
->bfd_of_glue_owner
= NULL
;
112 return &ret
->root
.root
;
115 static struct elf_link_hash_entry
*
116 find_thumb_glue (link_info
, name
, input_bfd
)
117 struct bfd_link_info
*link_info
;
122 struct elf_link_hash_entry
*hash
;
123 struct elf32_arm_link_hash_table
*hash_table
;
125 /* We need a pointer to the armelf specific hash table. */
126 hash_table
= elf32_arm_hash_table (link_info
);
130 bfd_malloc (strlen (name
) + strlen (THUMB2ARM_GLUE_ENTRY_NAME
) + 1));
132 BFD_ASSERT (tmp_name
);
134 sprintf (tmp_name
, THUMB2ARM_GLUE_ENTRY_NAME
, name
);
136 hash
= elf_link_hash_lookup
137 (&(hash_table
)->root
, tmp_name
, false, false, true);
140 /* xgettext:c-format */
141 _bfd_error_handler (_ ("%s: unable to find THUMB glue '%s' for `%s'"),
142 bfd_get_filename (input_bfd
), tmp_name
, name
);
149 static struct elf_link_hash_entry
*
150 find_arm_glue (link_info
, name
, input_bfd
)
151 struct bfd_link_info
*link_info
;
156 struct elf_link_hash_entry
*myh
;
157 struct elf32_arm_link_hash_table
*hash_table
;
159 /* We need a pointer to the elfarm specific hash table. */
160 hash_table
= elf32_arm_hash_table (link_info
);
163 bfd_malloc (strlen (name
) + strlen (ARM2THUMB_GLUE_ENTRY_NAME
) + 1));
165 BFD_ASSERT (tmp_name
);
167 sprintf (tmp_name
, ARM2THUMB_GLUE_ENTRY_NAME
, name
);
169 myh
= elf_link_hash_lookup
170 (&(hash_table
)->root
, tmp_name
, false, false, true);
173 /* xgettext:c-format */
174 _bfd_error_handler (_ ("%s: unable to find ARM glue '%s' for `%s'"),
175 bfd_get_filename (input_bfd
), tmp_name
, name
);
190 .word func @ behave as if you saw a ARM_32 reloc
193 #define ARM2THUMB_GLUE_SIZE 12
194 static const insn32 a2t1_ldr_insn
= 0xe59fc000;
195 static const insn32 a2t2_bx_r12_insn
= 0xe12fff1c;
196 static const insn32 a2t3_func_addr_insn
= 0x00000001;
199 Thumb->ARM: Thumb->(non-interworking aware) ARM
203 __func_from_thumb: __func_from_thumb:
205 nop ldr r6, __func_addr
207 __func_change_to_arm: bx r6
209 __func_back_to_thumb:
216 #define THUMB2ARM_GLUE_SIZE 8
217 static const insn16 t2a1_bx_pc_insn
= 0x4778;
218 static const insn16 t2a2_noop_insn
= 0x46c0;
219 static const insn32 t2a3_b_insn
= 0xea000000;
221 static const insn16 t2a1_push_insn
= 0xb540;
222 static const insn16 t2a2_ldr_insn
= 0x4e03;
223 static const insn16 t2a3_mov_insn
= 0x46fe;
224 static const insn16 t2a4_bx_insn
= 0x4730;
225 static const insn32 t2a5_pop_insn
= 0xe8bd4040;
226 static const insn32 t2a6_bx_insn
= 0xe12fff1e;
229 bfd_elf32_arm_allocate_interworking_sections (info
)
230 struct bfd_link_info
*info
;
234 struct elf32_arm_link_hash_table
*globals
;
236 globals
= elf32_arm_hash_table (info
);
238 BFD_ASSERT (globals
!= NULL
);
240 if (globals
->arm_glue_size
!= 0)
242 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
244 s
= bfd_get_section_by_name
245 (globals
->bfd_of_glue_owner
, ARM2THUMB_GLUE_SECTION_NAME
);
247 BFD_ASSERT (s
!= NULL
);
249 foo
= (bfd_byte
*) bfd_alloc
250 (globals
->bfd_of_glue_owner
, globals
->arm_glue_size
);
252 s
->_raw_size
= s
->_cooked_size
= globals
->arm_glue_size
;
256 if (globals
->thumb_glue_size
!= 0)
258 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
260 s
= bfd_get_section_by_name
261 (globals
->bfd_of_glue_owner
, THUMB2ARM_GLUE_SECTION_NAME
);
263 BFD_ASSERT (s
!= NULL
);
265 foo
= (bfd_byte
*) bfd_alloc
266 (globals
->bfd_of_glue_owner
, globals
->thumb_glue_size
);
268 s
->_raw_size
= s
->_cooked_size
= globals
->thumb_glue_size
;
276 record_arm_to_thumb_glue (link_info
, h
)
277 struct bfd_link_info
*link_info
;
278 struct elf_link_hash_entry
*h
;
280 const char *name
= h
->root
.root
.string
;
281 register asection
*s
;
283 struct elf_link_hash_entry
*myh
;
284 struct elf32_arm_link_hash_table
*globals
;
286 globals
= elf32_arm_hash_table (link_info
);
288 BFD_ASSERT (globals
!= NULL
);
289 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
291 s
= bfd_get_section_by_name
292 (globals
->bfd_of_glue_owner
, ARM2THUMB_GLUE_SECTION_NAME
);
295 BFD_ASSERT (s
!= NULL
);
298 bfd_malloc (strlen (name
) + strlen (ARM2THUMB_GLUE_ENTRY_NAME
) + 1));
300 BFD_ASSERT (tmp_name
);
302 sprintf (tmp_name
, ARM2THUMB_GLUE_ENTRY_NAME
, name
);
304 myh
= elf_link_hash_lookup
305 (&(globals
)->root
, tmp_name
, false, false, true);
310 return; /* we've already seen this guy */
313 /* The only trick here is using hash_table->arm_glue_size as the value. Even
314 though the section isn't allocated yet, this is where we will be putting
317 _bfd_generic_link_add_one_symbol (link_info
, globals
->bfd_of_glue_owner
, tmp_name
,
319 s
, globals
->arm_glue_size
+ 1,
321 (struct bfd_link_hash_entry
**) &myh
);
325 globals
->arm_glue_size
+= ARM2THUMB_GLUE_SIZE
;
331 record_thumb_to_arm_glue (link_info
, h
)
332 struct bfd_link_info
*link_info
;
333 struct elf_link_hash_entry
*h
;
335 const char *name
= h
->root
.root
.string
;
336 register asection
*s
;
338 struct elf_link_hash_entry
*myh
;
339 struct elf32_arm_link_hash_table
*hash_table
;
342 hash_table
= elf32_arm_hash_table (link_info
);
344 BFD_ASSERT (hash_table
!= NULL
);
345 BFD_ASSERT (hash_table
->bfd_of_glue_owner
!= NULL
);
347 s
= bfd_get_section_by_name
348 (hash_table
->bfd_of_glue_owner
, THUMB2ARM_GLUE_SECTION_NAME
);
350 BFD_ASSERT (s
!= NULL
);
352 tmp_name
= (char *) bfd_malloc (strlen (name
) + strlen (THUMB2ARM_GLUE_ENTRY_NAME
) + 1);
354 BFD_ASSERT (tmp_name
);
356 sprintf (tmp_name
, THUMB2ARM_GLUE_ENTRY_NAME
, name
);
358 myh
= elf_link_hash_lookup
359 (&(hash_table
)->root
, tmp_name
, false, false, true);
364 return; /* we've already seen this guy */
367 _bfd_generic_link_add_one_symbol (link_info
, hash_table
->bfd_of_glue_owner
, tmp_name
,
368 BSF_GLOBAL
, s
, hash_table
->thumb_glue_size
+ 1,
370 (struct bfd_link_hash_entry
**) &myh
);
372 /* If we mark it 'thumb', the disassembler will do a better job. */
373 bind
= ELF_ST_BIND (myh
->type
);
374 myh
->type
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
378 /* Allocate another symbol to mark where we switch to arm mode. */
380 #define CHANGE_TO_ARM "__%s_change_to_arm"
381 #define BACK_FROM_ARM "__%s_back_from_arm"
383 tmp_name
= (char *) bfd_malloc (strlen (name
) + strlen (CHANGE_TO_ARM
) + 1);
385 BFD_ASSERT (tmp_name
);
387 sprintf (tmp_name
, CHANGE_TO_ARM
, name
);
391 _bfd_generic_link_add_one_symbol (link_info
, hash_table
->bfd_of_glue_owner
, tmp_name
,
392 BSF_LOCAL
, s
, hash_table
->thumb_glue_size
+ 4,
394 (struct bfd_link_hash_entry
**) &myh
);
398 hash_table
->thumb_glue_size
+= THUMB2ARM_GLUE_SIZE
;
403 /* Select a BFD to be used to hold the sections used by the glue code.
404 This function is called from the linker scripts in ld/emultempl/
407 bfd_elf32_arm_get_bfd_for_interworking (abfd
, info
)
409 struct bfd_link_info
*info
;
411 struct elf32_arm_link_hash_table
*globals
;
415 /* If we are only performing a partial link do not bother
416 getting a bfd to hold the glue. */
417 if (info
->relocateable
)
420 globals
= elf32_arm_hash_table (info
);
422 BFD_ASSERT (globals
!= NULL
);
424 if (globals
->bfd_of_glue_owner
!= NULL
)
427 sec
= bfd_get_section_by_name (abfd
, ARM2THUMB_GLUE_SECTION_NAME
);
431 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
433 sec
= bfd_make_section (abfd
, ARM2THUMB_GLUE_SECTION_NAME
);
436 || !bfd_set_section_flags (abfd
, sec
, flags
)
437 || !bfd_set_section_alignment (abfd
, sec
, 2))
441 sec
= bfd_get_section_by_name (abfd
, THUMB2ARM_GLUE_SECTION_NAME
);
445 flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
;
447 sec
= bfd_make_section (abfd
, THUMB2ARM_GLUE_SECTION_NAME
);
450 || !bfd_set_section_flags (abfd
, sec
, flags
)
451 || !bfd_set_section_alignment (abfd
, sec
, 2))
455 /* Save the bfd for later use. */
456 globals
->bfd_of_glue_owner
= abfd
;
462 bfd_elf32_arm_process_before_allocation (abfd
, link_info
)
464 struct bfd_link_info
*link_info
;
466 Elf_Internal_Shdr
*symtab_hdr
;
467 Elf_Internal_Rela
*free_relocs
= NULL
;
468 Elf_Internal_Rela
*irel
, *irelend
;
469 bfd_byte
*contents
= NULL
;
470 bfd_byte
*free_contents
= NULL
;
471 Elf32_External_Sym
*extsyms
= NULL
;
472 Elf32_External_Sym
*free_extsyms
= NULL
;
475 struct elf32_arm_link_hash_table
*globals
;
477 /* If we are only performing a partial link do not bother
478 to construct any glue. */
479 if (link_info
->relocateable
)
482 /* Here we have a bfd that is to be included on the link. We have a hook
483 to do reloc rummaging, before section sizes are nailed down. */
485 globals
= elf32_arm_hash_table (link_info
);
487 BFD_ASSERT (globals
!= NULL
);
488 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
490 /* Rummage around all the relocs and map the glue vectors. */
491 sec
= abfd
->sections
;
496 for (; sec
!= NULL
; sec
= sec
->next
)
498 if (sec
->reloc_count
== 0)
501 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
502 /* Load the relocs. */
504 irel
= (_bfd_elf32_link_read_relocs (abfd
, sec
, (PTR
) NULL
,
505 (Elf_Internal_Rela
*) NULL
, false));
507 BFD_ASSERT (irel
!= 0);
509 irelend
= irel
+ sec
->reloc_count
;
510 for (; irel
< irelend
; irel
++)
513 unsigned long r_index
;
516 struct elf_link_hash_entry
*h
;
518 r_type
= ELF32_R_TYPE (irel
->r_info
);
519 r_index
= ELF32_R_SYM (irel
->r_info
);
521 /* These are the only relocation types we care about */
522 if (r_type
!= R_ARM_PC24
523 && r_type
!= R_ARM_THM_PC22
)
526 /* Get the section contents if we haven't done so already. */
527 if (contents
== NULL
)
529 /* Get cached copy if it exists. */
530 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
531 contents
= elf_section_data (sec
)->this_hdr
.contents
;
534 /* Go get them off disk. */
535 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
536 if (contents
== NULL
)
538 free_contents
= contents
;
540 if (!bfd_get_section_contents (abfd
, sec
, contents
,
541 (file_ptr
) 0, sec
->_raw_size
))
546 /* Read this BFD's symbols if we haven't done so already. */
549 /* Get cached copy if it exists. */
550 if (symtab_hdr
->contents
!= NULL
)
551 extsyms
= (Elf32_External_Sym
*) symtab_hdr
->contents
;
554 /* Go get them off disk. */
555 extsyms
= ((Elf32_External_Sym
*)
556 bfd_malloc (symtab_hdr
->sh_size
));
559 free_extsyms
= extsyms
;
560 if (bfd_seek (abfd
, symtab_hdr
->sh_offset
, SEEK_SET
) != 0
561 || (bfd_read (extsyms
, 1, symtab_hdr
->sh_size
, abfd
)
562 != symtab_hdr
->sh_size
))
567 /* If the relocation is not against a symbol it cannot concern us. */
571 /* We don't care about local symbols */
572 if (r_index
< symtab_hdr
->sh_info
)
575 /* This is an external symbol */
576 r_index
-= symtab_hdr
->sh_info
;
577 h
= (struct elf_link_hash_entry
*)
578 elf_sym_hashes (abfd
)[r_index
];
580 /* If the relocation is against a static symbol it must be within
581 the current section and so cannot be a cross ARM/Thumb relocation. */
588 /* This one is a call from arm code. We need to look up
589 the target of the call. If it is a thumb target, we
592 if (ELF_ST_TYPE(h
->type
) == STT_ARM_TFUNC
)
593 record_arm_to_thumb_glue (link_info
, h
);
597 /* This one is a call from thumb code. We look
598 up the target of the call. If it is not a thumb
599 target, we insert glue. */
601 if (ELF_ST_TYPE (h
->type
) != STT_ARM_TFUNC
)
602 record_thumb_to_arm_glue (link_info
, h
);
613 if (free_relocs
!= NULL
)
615 if (free_contents
!= NULL
)
616 free (free_contents
);
617 if (free_extsyms
!= NULL
)
623 /* The thumb form of a long branch is a bit finicky, because the offset
624 encoding is split over two fields, each in it's own instruction. They
625 can occur in any order. So given a thumb form of long branch, and an
626 offset, insert the offset into the thumb branch and return finished
629 It takes two thumb instructions to encode the target address. Each has
630 11 bits to invest. The upper 11 bits are stored in one (identifed by
631 H-0.. see below), the lower 11 bits are stored in the other (identified
634 Combine together and shifted left by 1 (it's a half word address) and
638 H-0, upper address-0 = 000
640 H-1, lower address-0 = 800
642 They can be ordered either way, but the arm tools I've seen always put
643 the lower one first. It probably doesn't matter. krk@cygnus.com
645 XXX: Actually the order does matter. The second instruction (H-1)
646 moves the computed address into the PC, so it must be the second one
647 in the sequence. The problem, however is that whilst little endian code
648 stores the instructions in HI then LOW order, big endian code does the
649 reverse. nickc@cygnus.com */
651 #define LOW_HI_ORDER 0xF800F000
652 #define HI_LOW_ORDER 0xF000F800
655 insert_thumb_branch (br_insn
, rel_off
)
659 unsigned int low_bits
;
660 unsigned int high_bits
;
663 BFD_ASSERT ((rel_off
& 1) != 1);
665 rel_off
>>= 1; /* half word aligned address */
666 low_bits
= rel_off
& 0x000007FF; /* the bottom 11 bits */
667 high_bits
= (rel_off
>> 11) & 0x000007FF; /* the top 11 bits */
669 if ((br_insn
& LOW_HI_ORDER
) == LOW_HI_ORDER
)
670 br_insn
= LOW_HI_ORDER
| (low_bits
<< 16) | high_bits
;
671 else if ((br_insn
& HI_LOW_ORDER
) == HI_LOW_ORDER
)
672 br_insn
= HI_LOW_ORDER
| (high_bits
<< 16) | low_bits
;
674 abort (); /* error - not a valid branch instruction form */
676 /* FIXME: abort is probably not the right call. krk@cygnus.com */
681 /* Thumb code calling an ARM function */
683 elf32_thumb_to_arm_stub (info
, name
, input_bfd
, output_bfd
, input_section
,
684 hit_data
, sym_sec
, offset
, addend
, val
)
685 struct bfd_link_info
*info
;
689 asection
*input_section
;
698 unsigned long int tmp
;
700 struct elf_link_hash_entry
*myh
;
701 struct elf32_arm_link_hash_table
*globals
;
703 myh
= find_thumb_glue (info
, name
, input_bfd
);
707 globals
= elf32_arm_hash_table (info
);
709 BFD_ASSERT (globals
!= NULL
);
710 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
712 my_offset
= myh
->root
.u
.def
.value
;
714 s
= bfd_get_section_by_name (globals
->bfd_of_glue_owner
,
715 THUMB2ARM_GLUE_SECTION_NAME
);
717 BFD_ASSERT (s
!= NULL
);
718 BFD_ASSERT (s
->contents
!= NULL
);
719 BFD_ASSERT (s
->output_section
!= NULL
);
721 if ((my_offset
& 0x01) == 0x01)
724 && sym_sec
->owner
!= NULL
725 && !INTERWORK_FLAG (sym_sec
->owner
))
728 (_ ("%s(%s): warning: interworking not enabled."),
729 bfd_get_filename (sym_sec
->owner
), name
);
731 (_ (" first occurrence: %s: thumb call to arm"),
732 bfd_get_filename (input_bfd
));
738 myh
->root
.u
.def
.value
= my_offset
;
740 bfd_put_16 (output_bfd
, t2a1_bx_pc_insn
,
741 s
->contents
+ my_offset
);
743 bfd_put_16 (output_bfd
, t2a2_noop_insn
,
744 s
->contents
+ my_offset
+ 2);
747 ((bfd_signed_vma
) val
) /* Address of destination of the stub */
749 (s
->output_offset
/* Offset from the start of the current section to the start of the stubs. */
750 + my_offset
/* Offset of the start of this stub from the start of the stubs. */
751 + s
->output_section
->vma
) /* Address of the start of the current section. */
752 + 4 /* The branch instruction is 4 bytes into the stub. */
753 + 8); /* ARM branches work from the pc of the instruction + 8. */
755 bfd_put_32 (output_bfd
,
756 t2a3_b_insn
| ((ret_offset
>> 2) & 0x00FFFFFF),
757 s
->contents
+ my_offset
+ 4);
760 BFD_ASSERT (my_offset
<= globals
->thumb_glue_size
);
762 /* Now go back and fix up the original BL insn to point
767 - (input_section
->output_offset
771 tmp
= bfd_get_32 (input_bfd
, hit_data
772 - input_section
->vma
);
774 bfd_put_32 (output_bfd
,
775 insert_thumb_branch (tmp
, ret_offset
),
776 hit_data
- input_section
->vma
);
781 /* Arm code calling a Thumb function */
783 elf32_arm_to_thumb_stub (info
, name
, input_bfd
, output_bfd
, input_section
,
784 hit_data
, sym_sec
, offset
, addend
, val
)
786 struct bfd_link_info
*info
;
790 asection
*input_section
;
797 unsigned long int tmp
;
801 struct elf_link_hash_entry
*myh
;
802 struct elf32_arm_link_hash_table
*globals
;
804 myh
= find_arm_glue (info
, name
, input_bfd
);
808 globals
= elf32_arm_hash_table (info
);
810 BFD_ASSERT (globals
!= NULL
);
811 BFD_ASSERT (globals
->bfd_of_glue_owner
!= NULL
);
813 my_offset
= myh
->root
.u
.def
.value
;
814 s
= bfd_get_section_by_name (globals
->bfd_of_glue_owner
,
815 ARM2THUMB_GLUE_SECTION_NAME
);
816 BFD_ASSERT (s
!= NULL
);
817 BFD_ASSERT (s
->contents
!= NULL
);
818 BFD_ASSERT (s
->output_section
!= NULL
);
820 if ((my_offset
& 0x01) == 0x01)
823 && sym_sec
->owner
!= NULL
824 && !INTERWORK_FLAG (sym_sec
->owner
))
827 (_ ("%s(%s): warning: interworking not enabled."),
828 bfd_get_filename (sym_sec
->owner
), name
);
830 (_ (" first occurrence: %s: arm call to thumb"),
831 bfd_get_filename (input_bfd
));
834 myh
->root
.u
.def
.value
= my_offset
;
836 bfd_put_32 (output_bfd
, a2t1_ldr_insn
,
837 s
->contents
+ my_offset
);
839 bfd_put_32 (output_bfd
, a2t2_bx_r12_insn
,
840 s
->contents
+ my_offset
+ 4);
842 /* It's a thumb address. Add the low order bit. */
843 bfd_put_32 (output_bfd
, val
| a2t3_func_addr_insn
,
844 s
->contents
+ my_offset
+ 8);
847 BFD_ASSERT (my_offset
<= globals
->arm_glue_size
);
849 tmp
= bfd_get_32 (input_bfd
, hit_data
);
850 tmp
= tmp
& 0xFF000000;
852 /* Somehow these are both 4 too far, so subtract 8. */
853 ret_offset
= s
->output_offset
855 + s
->output_section
->vma
856 - (input_section
->output_offset
857 + input_section
->output_section
->vma
861 tmp
= tmp
| ((ret_offset
>> 2) & 0x00FFFFFF);
863 bfd_put_32 (output_bfd
, tmp
, hit_data
864 - input_section
->vma
);
870 /* Perform a relocation as part of a final link. */
871 static bfd_reloc_status_type
872 elf32_arm_final_link_relocate (howto
, input_bfd
, output_bfd
,
873 input_section
, contents
, offset
, value
,
874 addend
, info
, sym_sec
, sym_name
, sym_flags
)
875 reloc_howto_type
*howto
;
878 asection
*input_section
;
883 struct bfd_link_info
*info
;
885 const char *sym_name
;
886 unsigned char sym_flags
;
888 unsigned long r_type
= howto
->type
;
889 bfd_byte
*hit_data
= contents
+ offset
;
898 /* Arm B/BL instruction */
901 addend
= (bfd_get_32 (input_bfd
, hit_data
) & howto
->src_mask
);
903 /* check for arm calling thumb function */
904 if (sym_flags
== STT_ARM_TFUNC
)
906 elf32_arm_to_thumb_stub (info
, sym_name
, input_bfd
, output_bfd
,
907 input_section
, hit_data
, sym_sec
, offset
, addend
, value
);
911 value
= value
+ addend
;
912 value
-= (input_section
->output_section
->vma
913 + input_section
->output_offset
+ 8);
915 value
= value
>> howto
->rightshift
;
918 value
|= (bfd_get_32 (input_bfd
, hit_data
) & 0xff000000);
919 bfd_put_32 (input_bfd
, value
, hit_data
);
924 addend
= (bfd_get_32 (input_bfd
, hit_data
) & howto
->src_mask
);
927 if (sym_flags
== STT_ARM_TFUNC
)
929 bfd_put_32 (input_bfd
, value
, hit_data
);
934 addend
= (bfd_get_32 (input_bfd
, hit_data
) & howto
->src_mask
);
936 value
-= (input_section
->output_section
->vma
937 + input_section
->output_offset
);
940 bfd_put_32 (input_bfd
, value
, hit_data
);
945 addend
= (bfd_get_32 (input_bfd
, hit_data
) & howto
->src_mask
);
948 if ((long) value
> 0x7f || (long) value
< -0x80)
949 return bfd_reloc_overflow
;
951 bfd_put_8 (input_bfd
, value
, hit_data
);
956 addend
= (bfd_get_32 (input_bfd
, hit_data
) & howto
->src_mask
);
960 if ((long) value
> 0x7fff || (long) value
< -0x8000)
961 return bfd_reloc_overflow
;
963 bfd_put_16 (input_bfd
, value
, hit_data
);
967 /* Support ldr and str instruction for the arm */
968 /* Also thumb b (unconditional branch) */
970 addend
= (bfd_get_32 (input_bfd
, hit_data
) & howto
->src_mask
);
974 if ((long) value
> 0x7ff || (long) value
< -0x800)
975 return bfd_reloc_overflow
;
977 value
|= (bfd_get_32 (input_bfd
, hit_data
) & 0xfffff000);
978 bfd_put_32 (input_bfd
, value
, hit_data
);
982 /* Support ldr and str instructions for the thumb. */
985 if ((long) value
> 0x1f || (long) value
< -0x10)
986 return bfd_reloc_overflow
;
988 value
|= bfd_get_16 (input_bfd
, hit_data
) & 0xf82f;
989 bfd_put_16 (input_bfd
, value
, hit_data
);
994 /* thumb BL (branch long instruction). */
997 boolean overflow
= false;
998 bfd_vma insn
= bfd_get_32 (input_bfd
, hit_data
);
999 bfd_vma src_mask
= 0x007FFFFE;
1000 bfd_signed_vma reloc_signed_max
= (1 << (howto
->bitsize
- 1)) - 1;
1001 bfd_signed_vma reloc_signed_min
= ~reloc_signed_max
;
1003 bfd_signed_vma signed_check
;
1005 bfd_signed_vma signed_add
;
1007 /* If it's not a call to thumb, assume call to arm */
1008 if (sym_flags
!= STT_ARM_TFUNC
)
1010 if (elf32_thumb_to_arm_stub
1011 (info
, sym_name
, input_bfd
, output_bfd
, input_section
,
1012 hit_data
, sym_sec
, offset
, addend
, value
))
1013 return bfd_reloc_ok
;
1015 return bfd_reloc_dangerous
;
1018 relocation
= value
+ addend
;
1019 relocation
-= (input_section
->output_section
->vma
+ input_section
->output_offset
);
1020 relocation
-= offset
;
1022 check
= relocation
>> howto
->rightshift
;
1024 /* If this is a signed value, the rightshift just dropped
1025 leading 1 bits (assuming twos complement). */
1026 if ((bfd_signed_vma
) relocation
>= 0)
1027 signed_check
= check
;
1029 signed_check
= (check
| ((bfd_vma
) - 1 & ~((bfd_vma
) - 1 >> howto
->rightshift
)));
1031 /* Get the value from the object file. */
1032 if (bfd_big_endian (input_bfd
))
1033 add
= (((insn
) & 0x07ff0000) >> 4) | (((insn
) & 0x7ff) << 1);
1035 add
= ((((insn
) & 0x7ff) << 12) | (((insn
) & 0x07ff0000) >> 15));
1037 /* Get the value from the object file with an appropriate sign.
1038 The expression involving howto->src_mask isolates the upper
1039 bit of src_mask. If that bit is set in the value we are
1040 adding, it is negative, and we subtract out that number times
1041 two. If src_mask includes the highest possible bit, then we
1042 can not get the upper bit, but that does not matter since
1043 signed_add needs no adjustment to become negative in that case. */
1047 if ((add
& (((~src_mask
) >> 1) & src_mask
)) != 0)
1048 signed_add
-= (((~src_mask
) >> 1) & src_mask
) << 1;
1050 /* Add the value from the object file, shifted so that it is a
1052 /* howto->bitpos == 0 */
1054 signed_check
+= signed_add
;
1055 relocation
+= signed_add
;
1057 /* Assumes two's complement. */
1058 if (signed_check
> reloc_signed_max
1059 || signed_check
< reloc_signed_min
)
1062 /* Put RELOCATION into the correct bits: */
1064 if (bfd_big_endian (input_bfd
))
1065 relocation
= (((relocation
& 0xffe) >> 1) | ((relocation
<< 4) & 0x07ff0000));
1067 relocation
= (((relocation
& 0xffe) << 15) | ((relocation
>> 12) & 0x7ff));
1069 /* Add RELOCATION to the correct bits of X: */
1070 insn
= ((insn
& ~howto
->dst_mask
) | relocation
);
1072 /* Put the relocated value back in the object file: */
1073 bfd_put_32 (input_bfd
, insn
, hit_data
);
1075 return (overflow
? bfd_reloc_overflow
: bfd_reloc_ok
);
1079 case R_ARM_GNU_VTINHERIT
:
1080 case R_ARM_GNU_VTENTRY
:
1081 return bfd_reloc_ok
;
1084 return bfd_reloc_notsupported
;
1086 case R_ARM_AMP_VCALL9
:
1087 return bfd_reloc_notsupported
;
1089 case R_ARM_RSBREL32
:
1090 return bfd_reloc_notsupported
;
1092 case R_ARM_THM_RPC22
:
1093 return bfd_reloc_notsupported
;
1096 return bfd_reloc_notsupported
;
1099 return bfd_reloc_notsupported
;
1102 return bfd_reloc_notsupported
;
1105 return bfd_reloc_notsupported
;
1108 return bfd_reloc_notsupported
;
1113 /* Relocate an ARM ELF section. */
1115 elf32_arm_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
1116 contents
, relocs
, local_syms
, local_sections
)
1118 struct bfd_link_info
*info
;
1120 asection
*input_section
;
1122 Elf_Internal_Rela
*relocs
;
1123 Elf_Internal_Sym
*local_syms
;
1124 asection
**local_sections
;
1126 Elf_Internal_Shdr
*symtab_hdr
;
1127 struct elf_link_hash_entry
**sym_hashes
;
1128 Elf_Internal_Rela
*rel
, *relend
;
1131 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
1132 sym_hashes
= elf_sym_hashes (input_bfd
);
1135 relend
= relocs
+ input_section
->reloc_count
;
1136 for (; rel
< relend
; rel
++)
1139 reloc_howto_type
*howto
;
1140 unsigned long r_symndx
;
1141 Elf_Internal_Sym
*sym
;
1143 struct elf_link_hash_entry
*h
;
1145 bfd_reloc_status_type r
;
1147 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1148 r_type
= ELF32_R_TYPE (rel
->r_info
);
1150 if (r_type
== R_ARM_GNU_VTENTRY
1151 || r_type
== R_ARM_GNU_VTINHERIT
)
1154 howto
= elf32_arm_howto_table
+ r_type
;
1156 if (info
->relocateable
)
1158 /* This is a relocateable link. We don't have to change
1159 anything, unless the reloc is against a section symbol,
1160 in which case we have to adjust according to where the
1161 section symbol winds up in the output section. */
1162 if (r_symndx
< symtab_hdr
->sh_info
)
1164 sym
= local_syms
+ r_symndx
;
1165 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1167 sec
= local_sections
[r_symndx
];
1168 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1175 /* This is a final link. */
1179 if (r_symndx
< symtab_hdr
->sh_info
)
1181 sym
= local_syms
+ r_symndx
;
1182 sec
= local_sections
[r_symndx
];
1183 relocation
= (sec
->output_section
->vma
1184 + sec
->output_offset
1189 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1190 while (h
->root
.type
== bfd_link_hash_indirect
1191 || h
->root
.type
== bfd_link_hash_warning
)
1192 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1193 if (h
->root
.type
== bfd_link_hash_defined
1194 || h
->root
.type
== bfd_link_hash_defweak
)
1196 sec
= h
->root
.u
.def
.section
;
1197 relocation
= (h
->root
.u
.def
.value
1198 + sec
->output_section
->vma
1199 + sec
->output_offset
);
1201 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1205 if (!((*info
->callbacks
->undefined_symbol
)
1206 (info
, h
->root
.root
.string
, input_bfd
,
1207 input_section
, rel
->r_offset
)))
1214 name
= h
->root
.root
.string
;
1217 name
= (bfd_elf_string_from_elf_section
1218 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1219 if (name
== NULL
|| *name
== '\0')
1220 name
= bfd_section_name (input_bfd
, sec
);
1223 r
= elf32_arm_final_link_relocate (howto
, input_bfd
, output_bfd
,
1225 contents
, rel
->r_offset
,
1226 relocation
, rel
->r_addend
,
1228 (h
? ELF_ST_TYPE (h
->type
) :
1229 ELF_ST_TYPE (sym
->st_info
)));
1231 if (r
!= bfd_reloc_ok
)
1233 const char * msg
= (const char *) 0;
1237 case bfd_reloc_overflow
:
1238 if (!((*info
->callbacks
->reloc_overflow
)
1239 (info
, name
, howto
->name
, (bfd_vma
) 0,
1240 input_bfd
, input_section
, rel
->r_offset
)))
1244 case bfd_reloc_undefined
:
1245 if (!((*info
->callbacks
->undefined_symbol
)
1246 (info
, name
, input_bfd
, input_section
,
1251 case bfd_reloc_outofrange
:
1252 msg
= _ ("internal error: out of range error");
1255 case bfd_reloc_notsupported
:
1256 msg
= _ ("internal error: unsupported relocation error");
1259 case bfd_reloc_dangerous
:
1260 msg
= _ ("internal error: dangerous error");
1264 msg
= _ ("internal error: unknown error");
1268 if (!((*info
->callbacks
->warning
)
1269 (info
, msg
, name
, input_bfd
, input_section
,
1280 /* Function to keep ARM specific flags in the ELF header. */
1282 elf32_arm_set_private_flags (abfd
, flags
)
1286 if (elf_flags_init (abfd
)
1287 && elf_elfheader (abfd
)->e_flags
!= flags
)
1289 if (flags
& EF_INTERWORK
)
1290 _bfd_error_handler (_ ("\
1291 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
1292 bfd_get_filename (abfd
));
1294 _bfd_error_handler (_ ("\
1295 Warning: Clearing the interwork flag of %s due to outside request"),
1296 bfd_get_filename (abfd
));
1300 elf_elfheader (abfd
)->e_flags
= flags
;
1301 elf_flags_init (abfd
) = true;
1307 /* Copy backend specific data from one object module to another */
1309 elf32_arm_copy_private_bfd_data (ibfd
, obfd
)
1316 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1317 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1320 in_flags
= elf_elfheader (ibfd
)->e_flags
;
1321 out_flags
= elf_elfheader (obfd
)->e_flags
;
1323 if (elf_flags_init (obfd
) && in_flags
!= out_flags
)
1325 /* Cannot mix PIC and non-PIC code. */
1326 if ((in_flags
& EF_PIC
) != (out_flags
& EF_PIC
))
1329 /* Cannot mix APCS26 and APCS32 code. */
1330 if ((in_flags
& EF_APCS_26
) != (out_flags
& EF_APCS_26
))
1333 /* Cannot mix float APCS and non-float APCS code. */
1334 if ((in_flags
& EF_APCS_FLOAT
) != (out_flags
& EF_APCS_FLOAT
))
1337 /* If the src and dest have different interworking flags
1338 then turn off the interworking bit. */
1339 if ((in_flags
& EF_INTERWORK
) != (out_flags
& EF_INTERWORK
))
1341 if (out_flags
& EF_INTERWORK
)
1342 _bfd_error_handler (_ ("\
1343 Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
1344 bfd_get_filename (obfd
), bfd_get_filename (ibfd
));
1346 in_flags
&= ~EF_INTERWORK
;
1350 elf_elfheader (obfd
)->e_flags
= in_flags
;
1351 elf_flags_init (obfd
) = true;
1356 /* Merge backend specific data from an object file to the output
1357 object file when linking. */
1359 elf32_arm_merge_private_bfd_data (ibfd
, obfd
)
1366 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1367 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1370 /* The input BFD must have had its flags initialised. */
1371 /* The following seems bogus to me -- The flags are initialized in
1372 the assembler but I don't think an elf_flags_init field is
1373 written into the object */
1374 /* BFD_ASSERT (elf_flags_init (ibfd)); */
1376 in_flags
= elf_elfheader (ibfd
)->e_flags
;
1377 out_flags
= elf_elfheader (obfd
)->e_flags
;
1379 if (!elf_flags_init (obfd
))
1381 /* If the input is the default architecture then do not
1382 bother setting the flags for the output architecture,
1383 instead allow future merges to do this. If no future
1384 merges ever set these flags then they will retain their
1385 unitialised values, which surprise surprise, correspond
1386 to the default values. */
1387 if (bfd_get_arch_info (ibfd
)->the_default
)
1390 elf_flags_init (obfd
) = true;
1391 elf_elfheader (obfd
)->e_flags
= in_flags
;
1393 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
1394 && bfd_get_arch_info (obfd
)->the_default
)
1395 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
1400 /* Check flag compatibility. */
1401 if (in_flags
== out_flags
)
1404 /* Complain about various flag mismatches. */
1406 if ((in_flags
& EF_APCS_26
) != (out_flags
& EF_APCS_26
))
1407 _bfd_error_handler (_ ("\
1408 Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
1409 bfd_get_filename (ibfd
),
1410 in_flags
& EF_APCS_26
? 26 : 32,
1411 bfd_get_filename (obfd
),
1412 out_flags
& EF_APCS_26
? 26 : 32);
1414 if ((in_flags
& EF_APCS_FLOAT
) != (out_flags
& EF_APCS_FLOAT
))
1415 _bfd_error_handler (_ ("\
1416 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
1417 bfd_get_filename (ibfd
),
1418 in_flags
& EF_APCS_FLOAT
? _ ("float") : _ ("integer"),
1419 bfd_get_filename (obfd
),
1420 out_flags
& EF_APCS_26
? _ ("float") : _ ("integer"));
1422 if ((in_flags
& EF_PIC
) != (out_flags
& EF_PIC
))
1423 _bfd_error_handler (_ ("\
1424 Error: %s is compiled as position %s code, whereas %s is not"),
1425 bfd_get_filename (ibfd
),
1426 in_flags
& EF_PIC
? _ ("independent") : _ ("dependent"),
1427 bfd_get_filename (obfd
));
1429 /* Interworking mismatch is only a warning. */
1430 if ((in_flags
& EF_INTERWORK
) != (out_flags
& EF_INTERWORK
))
1432 _bfd_error_handler (_ ("\
1433 Warning: %s %s interworking, whereas %s %s"),
1434 bfd_get_filename (ibfd
),
1435 in_flags
& EF_INTERWORK
? _ ("supports") : _ ("does not support"),
1436 bfd_get_filename (obfd
),
1437 out_flags
& EF_INTERWORK
? _ ("does not") : _ ("does"));
1444 /* Display the flags field */
1446 elf32_arm_print_private_bfd_data (abfd
, ptr
)
1450 FILE *file
= (FILE *) ptr
;
1452 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
1454 /* Print normal ELF private data. */
1455 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
1457 /* Ignore init flag - it may not be set, despite the flags field containing valid data. */
1459 /* xgettext:c-format */
1460 fprintf (file
, _ ("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
1462 if (elf_elfheader (abfd
)->e_flags
& EF_INTERWORK
)
1463 fprintf (file
, _ (" [interworking enabled]"));
1465 fprintf (file
, _ (" [interworking not enabled]"));
1467 if (elf_elfheader (abfd
)->e_flags
& EF_APCS_26
)
1468 fprintf (file
, _ (" [APCS-26]"));
1470 fprintf (file
, _ (" [APCS-32]"));
1472 if (elf_elfheader (abfd
)->e_flags
& EF_APCS_FLOAT
)
1473 fprintf (file
, _ (" [floats passed in float registers]"));
1475 fprintf (file
, _ (" [floats passed in integer registers]"));
1477 if (elf_elfheader (abfd
)->e_flags
& EF_PIC
)
1478 fprintf (file
, _ (" [position independent]"));
1480 fprintf (file
, _ (" [absolute position]"));
1488 elf32_arm_get_symbol_type (elf_sym
, type
)
1489 Elf_Internal_Sym
* elf_sym
;
1492 if (ELF_ST_TYPE (elf_sym
->st_info
) == STT_ARM_TFUNC
)
1493 return ELF_ST_TYPE (elf_sym
->st_info
);
1499 elf32_arm_gc_mark_hook (abfd
, info
, rel
, h
, sym
)
1501 struct bfd_link_info
*info
;
1502 Elf_Internal_Rela
*rel
;
1503 struct elf_link_hash_entry
*h
;
1504 Elf_Internal_Sym
*sym
;
1508 switch (ELF32_R_TYPE (rel
->r_info
))
1510 case R_ARM_GNU_VTINHERIT
:
1511 case R_ARM_GNU_VTENTRY
:
1515 switch (h
->root
.type
)
1517 case bfd_link_hash_defined
:
1518 case bfd_link_hash_defweak
:
1519 return h
->root
.u
.def
.section
;
1521 case bfd_link_hash_common
:
1522 return h
->root
.u
.c
.p
->section
;
1528 if (!(elf_bad_symtab (abfd
)
1529 && ELF_ST_BIND (sym
->st_info
) != STB_LOCAL
)
1530 && ! ((sym
->st_shndx
<= 0 || sym
->st_shndx
>= SHN_LORESERVE
)
1531 && sym
->st_shndx
!= SHN_COMMON
))
1533 return bfd_section_from_elf_index (abfd
, sym
->st_shndx
);
1540 elf32_arm_gc_sweep_hook (abfd
, info
, sec
, relocs
)
1542 struct bfd_link_info
*info
;
1544 const Elf_Internal_Rela
*relocs
;
1546 /* we don't use got and plt entries for armelf */
1550 /* Look through the relocs for a section during the first phase.
1551 Since we don't do .gots or .plts, we just need to consider the
1552 virtual table relocs for gc. */
1555 elf32_arm_check_relocs (abfd
, info
, sec
, relocs
)
1557 struct bfd_link_info
*info
;
1559 const Elf_Internal_Rela
*relocs
;
1561 Elf_Internal_Shdr
*symtab_hdr
;
1562 struct elf_link_hash_entry
**sym_hashes
, **sym_hashes_end
;
1563 const Elf_Internal_Rela
*rel
;
1564 const Elf_Internal_Rela
*rel_end
;
1566 if (info
->relocateable
)
1569 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1570 sym_hashes
= elf_sym_hashes (abfd
);
1571 sym_hashes_end
= sym_hashes
+ symtab_hdr
->sh_size
/sizeof(Elf32_External_Sym
);
1572 if (!elf_bad_symtab (abfd
))
1573 sym_hashes_end
-= symtab_hdr
->sh_info
;
1575 rel_end
= relocs
+ sec
->reloc_count
;
1576 for (rel
= relocs
; rel
< rel_end
; rel
++)
1578 struct elf_link_hash_entry
*h
;
1579 unsigned long r_symndx
;
1581 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1582 if (r_symndx
< symtab_hdr
->sh_info
)
1585 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1587 switch (ELF32_R_TYPE (rel
->r_info
))
1589 /* This relocation describes the C++ object vtable hierarchy.
1590 Reconstruct it for later use during GC. */
1591 case R_ARM_GNU_VTINHERIT
:
1592 if (!_bfd_elf32_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
1596 /* This relocation describes which C++ vtable entries are actually
1597 used. Record for later use during GC. */
1598 case R_ARM_GNU_VTENTRY
:
1599 if (!_bfd_elf32_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
1609 /* Find the nearest line to a particular section and offset, for error
1610 reporting. This code is a duplicate of the code in elf.c, except
1611 that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
1614 elf32_arm_find_nearest_line
1615 (abfd
, section
, symbols
, offset
, filename_ptr
, functionname_ptr
, line_ptr
)
1620 CONST
char ** filename_ptr
;
1621 CONST
char ** functionname_ptr
;
1622 unsigned int * line_ptr
;
1625 const char * filename
;
1630 if (_bfd_dwarf2_find_nearest_line (abfd
, section
, symbols
, offset
,
1631 filename_ptr
, functionname_ptr
,
1635 if (! _bfd_stab_section_find_nearest_line (abfd
, symbols
, section
, offset
,
1636 &found
, filename_ptr
,
1637 functionname_ptr
, line_ptr
,
1638 &elf_tdata (abfd
)->line_info
))
1644 if (symbols
== NULL
)
1651 for (p
= symbols
; *p
!= NULL
; p
++)
1655 q
= (elf_symbol_type
*) *p
;
1657 if (bfd_get_section (&q
->symbol
) != section
)
1660 switch (ELF_ST_TYPE (q
->internal_elf_sym
.st_info
))
1665 filename
= bfd_asymbol_name (&q
->symbol
);
1670 if (q
->symbol
.section
== section
1671 && q
->symbol
.value
>= low_func
1672 && q
->symbol
.value
<= offset
)
1674 func
= (asymbol
*) q
;
1675 low_func
= q
->symbol
.value
;
1684 *filename_ptr
= filename
;
1685 *functionname_ptr
= bfd_asymbol_name (func
);
1691 #define ELF_ARCH bfd_arch_arm
1692 #define ELF_MACHINE_CODE EM_ARM
1694 #define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
1695 #define elf_backend_relocate_section elf32_arm_relocate_section
1696 #define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
1697 #define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
1698 #define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags
1699 #define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data
1700 #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
1701 #define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
1702 #define elf_backend_get_symbol_type elf32_arm_get_symbol_type
1703 #define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
1704 #define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook
1705 #define elf_backend_check_relocs elf32_arm_check_relocs
1707 #define elf_backend_can_gc_sections 1
1709 #include "elf32-target.h"