Sun Aug 30 00:49:18 1998 Martin M. Hunt <hunt@cygnus.com>
[deliverable/binutils-gdb.git] / bfd / elf32-arm.c
CommitLineData
2c3c46ad 1 /* start-sanitize-armelf */
efaa65c9
CM
2/* 32-bit ELF support for ARM
3 Copyright 1993, 1995, 1998 Free Software Foundation, Inc.
4
2c3c46ad 5 This file is part of BFD, the Binary File Descriptor library.
efaa65c9 6
2c3c46ad
CM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
efaa65c9 11
2c3c46ad
CM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
efaa65c9 16
2c3c46ad
CM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
efaa65c9
CM
20
21#include "bfd.h"
22#include "sysdep.h"
23#include "libbfd.h"
24#include "elf-bfd.h"
25
26#include "elf/arm.h"
27
2c3c46ad
CM
28typedef unsigned long int insn32;
29typedef unsigned short int insn16;
30
efaa65c9 31static reloc_howto_type *elf32_arm_reloc_type_lookup
2c3c46ad 32 PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
efaa65c9
CM
33static void elf32_arm_info_to_howto
34 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
0e7361bc
NC
35static boolean elf32_arm_set_private_flags
36 PARAMS ((bfd *, flagword));
37static boolean elf32_arm_copy_private_bfd_data
38 PARAMS ((bfd *, bfd *));
39static boolean elf32_arm_merge_private_bfd_data
40 PARAMS ((bfd *, bfd *));
41static boolean elf32_arm_print_private_bfd_data
42 PARAMS ((bfd *, PTR));
2c3c46ad
CM
43static struct bfd_link_hash_table *elf32_arm_link_hash_table_create
44 PARAMS ((bfd *));
45
46
47static insn32 insert_thumb_branch
48 PARAMS ((insn32, int));
49static struct elf_link_hash_entry *find_thumb_glue
50 PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
51static struct elf_link_hash_entry *find_arm_glue
52 PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
53static void record_arm_to_thumb_glue
54 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
55static void record_thumb_to_arm_glue
56 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
57
58/* The linker script knows the section names for placement.
59 The entry_names are used to do simple name mangling on the stubs.
60 Given a function name, and its type, the stub can be found. The
61 name can be changed. The only requirement is the %s be present.
62 */
63
64#define INTERWORK_FLAG( abfd ) (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
65
66#define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
67#define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
68
69#define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
70#define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
71
72/* Get the ARM elf linker hash table from a link_info structure. */
73#define elf32_arm_hash_table(info) \
74 ((struct elf32_arm_link_hash_table *) ((info)->hash))
75
76/* ARM ELF linker hash table */
77struct elf32_arm_link_hash_table
78 {
79 /* The main hash table. */
80 struct elf_link_hash_table root;
81
82 /* The size in bytes of the section containg the Thumb-to-ARM glue. */
83 long int thumb_glue_size;
84
85 /* The size in bytes of the section containg the ARM-to-Thumb glue. */
86 long int arm_glue_size;
87
88 /* An arbitary input BFD chosen to hold the glue sections. */
89 bfd *bfd_of_glue_owner;
90
91 };
92
93
94
95/* Create an ARM elf linker hash table */
96
97static struct bfd_link_hash_table *
98elf32_arm_link_hash_table_create (abfd)
99 bfd *abfd;
100{
101 struct elf32_arm_link_hash_table *ret;
102
103 ret = ((struct elf32_arm_link_hash_table *)
104 bfd_alloc (abfd, sizeof (struct elf32_arm_link_hash_table)));
105 if (ret == (struct elf32_arm_link_hash_table *) NULL)
106 return NULL;
107
108 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
109 _bfd_elf_link_hash_newfunc))
110 {
111 bfd_release (abfd, ret);
112 return NULL;
113 }
114
115 ret->thumb_glue_size = 0;
116 ret->arm_glue_size = 0;
117 ret->bfd_of_glue_owner = NULL;
118
119 return &ret->root.root;
120}
121
122static struct elf_link_hash_entry *
123find_thumb_glue (link_info, name, input_bfd)
124 struct bfd_link_info *link_info;
125 CONST char *name;
126 bfd *input_bfd;
127{
128 char *tmp_name;
129 struct elf_link_hash_entry *hash;
130 struct elf32_arm_link_hash_table *hash_table;
131
132 /* We need a pointer to the armelf specific hash table. */
133 hash_table = elf32_arm_hash_table (link_info);
134
135
136 tmp_name = ((char *)
137 bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1));
138
139 BFD_ASSERT (tmp_name);
140
141 sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
142
143 hash = elf_link_hash_lookup
144 (&(hash_table)->root, tmp_name, false, false, true);
145
146 if (hash == NULL)
147 /* xgettext:c-format */
148 _bfd_error_handler (_ ("%s: unable to find THUMB glue '%s' for `%s'"),
149 bfd_get_filename (input_bfd), tmp_name, name);
150
151 free (tmp_name);
152
153 return hash;
154}
155
156static struct elf_link_hash_entry *
157find_arm_glue (link_info, name, input_bfd)
158 struct bfd_link_info *link_info;
159 CONST char *name;
160 bfd *input_bfd;
161{
162 char *tmp_name;
163 struct elf_link_hash_entry *myh;
164 struct elf32_arm_link_hash_table *hash_table;
165
166 /* We need a pointer to the elfarm specific hash table. */
167 hash_table = elf32_arm_hash_table (link_info);
168
169 tmp_name = ((char *)
170 bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
171
172 BFD_ASSERT (tmp_name);
173
174 sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
175
176 myh = elf_link_hash_lookup
177 (&(hash_table)->root, tmp_name, false, false, true);
178
179 if (myh == NULL)
180 /* xgettext:c-format */
181 _bfd_error_handler (_ ("%s: unable to find ARM glue '%s' for `%s'"),
182 bfd_get_filename (input_bfd), tmp_name, name);
183
184 free (tmp_name);
185
186 return myh;
187}
188
189/*
190 ARM->Thumb glue:
191
192 .arm
193 __func_from_arm:
194 ldr r12, __func_addr
195 bx r12
196 __func_addr:
197 .word func @ behave as if you saw a ARM_32 reloc
198 */
199
200#define ARM2THUMB_GLUE_SIZE 12
201static const insn32 a2t1_ldr_insn = 0xe59fc000;
202static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
203static const insn32 a2t3_func_addr_insn = 0x00000001;
204
205/*
206 Thumb->ARM: Thumb->(non-interworking aware) ARM
207
208 .thumb .thumb
209 .align 2 .align 2
210 __func_from_thumb: __func_from_thumb:
211 bx pc push {r6, lr}
212 nop ldr r6, __func_addr
213 .arm mov lr, pc
214 __func_change_to_arm: bx r6
215 b func .arm
216 __func_back_to_thumb:
217 ldmia r13! {r6, lr}
218 bx lr
219 __func_addr:
220 .word func
221 */
222
223#define THUMB2ARM_GLUE_SIZE 8
224static const insn16 t2a1_bx_pc_insn = 0x4778;
225static const insn16 t2a2_noop_insn = 0x46c0;
226static const insn32 t2a3_b_insn = 0xea000000;
227
228static const insn16 t2a1_push_insn = 0xb540;
229static const insn16 t2a2_ldr_insn = 0x4e03;
230static const insn16 t2a3_mov_insn = 0x46fe;
231static const insn16 t2a4_bx_insn = 0x4730;
232static const insn32 t2a5_pop_insn = 0xe8bd4040;
233static const insn32 t2a6_bx_insn = 0xe12fff1e;
234
235boolean
236bfd_elf32_arm_allocate_interworking_sections (info)
237 struct bfd_link_info *info;
238{
239 asection *s;
240 bfd_byte *foo;
241 struct elf32_arm_link_hash_table *globals;
242
243 globals = elf32_arm_hash_table (info);
244
245 BFD_ASSERT (globals != NULL);
246
247 if (globals->arm_glue_size != 0)
248 {
249 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
250
251 s = bfd_get_section_by_name
252 (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
253
254 BFD_ASSERT (s != NULL);
255
256 foo = (bfd_byte *) bfd_alloc
257 (globals->bfd_of_glue_owner, globals->arm_glue_size);
258
259 s->_raw_size = s->_cooked_size = globals->arm_glue_size;
260 s->contents = foo;
261 }
262
263 if (globals->thumb_glue_size != 0)
264 {
265 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
266
267 s = bfd_get_section_by_name
268 (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
269
270 BFD_ASSERT (s != NULL);
271
272 foo = (bfd_byte *) bfd_alloc
273 (globals->bfd_of_glue_owner, globals->thumb_glue_size);
274
275 s->_raw_size = s->_cooked_size = globals->thumb_glue_size;
276 s->contents = foo;
277 }
278
279 return true;
280}
281
282static void
283record_arm_to_thumb_glue (link_info, h)
284 struct bfd_link_info *link_info;
285 struct elf_link_hash_entry *h;
286{
287 const char *name = h->root.root.string;
288 register asection *s;
289 char *tmp_name;
290 struct elf_link_hash_entry *myh;
291 struct elf32_arm_link_hash_table *globals;
292
293 globals = elf32_arm_hash_table (link_info);
294
295 BFD_ASSERT (globals != NULL);
296 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
297
298 s = bfd_get_section_by_name
299 (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
300
301
302 BFD_ASSERT (s != NULL);
303
304 tmp_name = ((char *)
305 bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
306
307 BFD_ASSERT (tmp_name);
308
309 sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
310
311 myh = elf_link_hash_lookup
312 (&(globals)->root, tmp_name, false, false, true);
313
314 if (myh != NULL)
315 {
316 free (tmp_name);
317 return; /* we've already seen this guy */
318 }
319
320 /* The only trick here is using hash_table->arm_glue_size as the value. Even
321 though the section isn't allocated yet, this is where we will be putting
322 it. */
323
324 _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner, tmp_name,
325 BSF_GLOBAL,
326 s, globals->arm_glue_size + 1,
327 NULL, true, false,
328 (struct bfd_link_hash_entry **) &myh);
329
330 free (tmp_name);
331
332 globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
333
334 return;
335}
336
337static void
338record_thumb_to_arm_glue (link_info, h)
339 struct bfd_link_info *link_info;
340 struct elf_link_hash_entry *h;
341{
342 const char *name = h->root.root.string;
343 register asection *s;
344 char *tmp_name;
345 struct elf_link_hash_entry *myh;
346 struct elf32_arm_link_hash_table *hash_table;
347
348 hash_table = elf32_arm_hash_table (link_info);
349
350 BFD_ASSERT (hash_table != NULL);
351 BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
352
353 s = bfd_get_section_by_name
354 (hash_table->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
355
356 BFD_ASSERT (s != NULL);
357
358 tmp_name = (char *) bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
359
360 BFD_ASSERT (tmp_name);
361
362 sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
363
364 myh = elf_link_hash_lookup
365 (&(hash_table)->root, tmp_name, false, false, true);
366
367 if (myh != NULL)
368 {
369 free (tmp_name);
370 return; /* we've already seen this guy */
371 }
372
373 _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner, tmp_name,
374 BSF_GLOBAL, s, hash_table->thumb_glue_size + 1,
375 NULL, true, false,
376 (struct bfd_link_hash_entry **) &myh);
377
378 /* If we mark it 'thumb', the disassembler will do a better job. */
379 myh->other = C_THUMBEXTFUNC;
380
381 free (tmp_name);
382
383 /* Allocate another symbol to mark where we switch to arm mode. */
384
385#define CHANGE_TO_ARM "__%s_change_to_arm"
386#define BACK_FROM_ARM "__%s_back_from_arm"
387
388 tmp_name = (char *) bfd_malloc (strlen (name) + strlen (CHANGE_TO_ARM) + 1);
389
390 BFD_ASSERT (tmp_name);
391
392 sprintf (tmp_name, CHANGE_TO_ARM, name);
393
394 myh = NULL;
395
396 _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner, tmp_name,
397 BSF_LOCAL, s, hash_table->thumb_glue_size + 4,
398 NULL, true, false,
399 (struct bfd_link_hash_entry **) &myh);
400
401 free (tmp_name);
402
403 hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
404
405 return;
406}
407
408/* Select a BFD to be used to hold the sections used by the glue code.
409 This function is called from the linker scripts in ld/emultempl/
410 {armelf/pe}.em */
411boolean
412bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
413 bfd *abfd;
414 struct bfd_link_info *info;
415{
416 struct elf32_arm_link_hash_table *globals;
417 flagword flags;
418 asection *sec;
419
420 /* If we are only performing a partial link do not bother
421 getting a bfd to hold the glue. */
422 if (info->relocateable)
423 return true;
424
425 globals = elf32_arm_hash_table (info);
426
427 BFD_ASSERT (globals != NULL);
428
429 if (globals->bfd_of_glue_owner != NULL)
430 return true;
431
432 sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
433
434 if (sec == NULL)
435 {
436 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
437
438 sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
439
440 if (sec == NULL
441 || !bfd_set_section_flags (abfd, sec, flags)
442 || !bfd_set_section_alignment (abfd, sec, 2))
443 return false;
444 }
445
446 sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
447
448 if (sec == NULL)
449 {
450 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
451
452 sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
453
454 if (sec == NULL
455 || !bfd_set_section_flags (abfd, sec, flags)
456 || !bfd_set_section_alignment (abfd, sec, 2))
457 return false;
458 }
459
460 /* Save the bfd for later use. */
461 globals->bfd_of_glue_owner = abfd;
462
463 return true;
464}
465
466boolean
467bfd_elf32_arm_process_before_allocation (abfd, link_info)
468 bfd *abfd;
469 struct bfd_link_info *link_info;
470{
471 Elf_Internal_Shdr *symtab_hdr;
472 Elf_Internal_Rela *free_relocs = NULL;
473 Elf_Internal_Rela *irel, *irelend;
474 bfd_byte *contents = NULL;
475 bfd_byte *free_contents = NULL;
476 Elf32_External_Sym *extsyms = NULL;
477 Elf32_External_Sym *free_extsyms = NULL;
478
479 asection *sec;
480 struct elf32_arm_link_hash_table *globals;
481
482 /* If we are only performing a partial link do not bother
483 to construct any glue. */
484 if (link_info->relocateable)
485 return true;
486
487 /* Here we have a bfd that is to be included on the link. We have a hook
488 to do reloc rummaging, before section sizes are nailed down. */
489
490 /* _bfd_coff_get_external_symbols (abfd); */
491
492 globals = elf32_arm_hash_table (link_info);
493
494 BFD_ASSERT (globals != NULL);
495 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
496
497 /* Rummage around all the relocs and map the glue vectors. */
498 sec = abfd->sections;
499
500 if (sec == NULL)
501 return true;
502
503 for (; sec != NULL; sec = sec->next)
504 {
505 struct internal_reloc *i;
506 struct internal_reloc *rel;
507
508 if (sec->reloc_count == 0)
509 continue;
510
511 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
512 /* Load the relocs. */
513
514 irel = (_bfd_elf32_link_read_relocs (abfd, sec, (PTR) NULL,
515 (Elf_Internal_Rela *) NULL, false));
516
517 BFD_ASSERT (i != 0);
518
519 irelend = irel + sec->reloc_count;
520 for (; irel < irelend; irel++)
521 {
522 long r_type;
523 unsigned long r_index;
524 unsigned char code;
525
526 struct elf_link_hash_entry *h;
527
528 r_type = ELF32_R_TYPE (irel->r_info);
529 r_index = ELF32_R_SYM (irel->r_info);
530
531 /* These are the only relocation types we care about */
532 if (r_type != R_ARM_PC24
533 && r_type != R_ARM_THM_PC22)
534 continue;
535
536 /* Get the section contents if we haven't done so already. */
537 if (contents == NULL)
538 {
539 /* Get cached copy if it exists. */
540 if (elf_section_data (sec)->this_hdr.contents != NULL)
541 contents = elf_section_data (sec)->this_hdr.contents;
542 else
543 {
544 /* Go get them off disk. */
545 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
546 if (contents == NULL)
547 goto error_return;
548 free_contents = contents;
549
550 if (!bfd_get_section_contents (abfd, sec, contents,
551 (file_ptr) 0, sec->_raw_size))
552 goto error_return;
553 }
554 }
555
556 /* Read this BFD's symbols if we haven't done so already. */
557 if (extsyms == NULL)
558 {
559 /* Get cached copy if it exists. */
560 if (symtab_hdr->contents != NULL)
561 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
562 else
563 {
564 /* Go get them off disk. */
565 extsyms = ((Elf32_External_Sym *)
566 bfd_malloc (symtab_hdr->sh_size));
567 if (extsyms == NULL)
568 goto error_return;
569 free_extsyms = extsyms;
570 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
571 || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
572 != symtab_hdr->sh_size))
573 goto error_return;
574 }
575 }
576
577 /* If the relocation is not against a symbol it cannot concern us. */
578
579 h = NULL;
580
581 /* We don't care about local symbols */
582 if (r_index < symtab_hdr->sh_info)
583 continue;
584
585 /* This is an external symbol */
586 r_index -= symtab_hdr->sh_info;
587 h = (struct elf_link_hash_entry *)
588 elf_sym_hashes (abfd)[r_index];
589
590 /* If the relocation is against a static symbol it must be within
591 the current section and so cannot be a cross ARM/Thumb relocation. */
592 if (h == NULL)
593 continue;
594
595 switch (r_type)
596 {
597 case R_ARM_PC24:
598 /* This one is a call from arm code. We need to look up
599 the target of the call. If it is a thumb target, we
600 insert glue. */
601
602 if (h->other == C_THUMBEXTFUNC)
603 record_arm_to_thumb_glue (link_info, h);
604 break;
605
606 case R_ARM_THM_PC22:
607
608 /* This one is a call from thumb code. We used to look
609 for ARM_THUMB9 and ARM_THUMB12 as well. We need to look
610 up the target of the call. If it is an arm target, we
611 insert glue. If the symbol does not exist it will be
612 given a class of C_EXT and so we will generate a stub
613 for it. This is not really a problem, since the link
614 is doomed anyway. */
615
616 switch (h->other)
617 {
618 case C_EXT:
619 case C_STAT:
620 case C_LABEL:
621 record_thumb_to_arm_glue (link_info, h);
622 break;
623 default:
624 ;
625 }
626 break;
627
628 default:
629 break;
630 }
631 }
632 }
633
634 return true;
635error_return:
636 if (free_relocs != NULL)
637 free (free_relocs);
638 if (free_contents != NULL)
639 free (free_contents);
640 if (free_extsyms != NULL)
641 free (free_extsyms);
642 return false;
643
644}
efaa65c9
CM
645
646#define USE_RELA
647#define TARGET_UNDERSCORE '_'
648
649static reloc_howto_type elf32_arm_howto_table[] =
650{
651 /* No relocation */
2c3c46ad
CM
652 HOWTO (R_ARM_NONE, /* type */
653 0, /* rightshift */
654 0, /* size (0 = byte, 1 = short, 2 = long) */
655 0, /* bitsize */
656 false, /* pc_relative */
657 0, /* bitpos */
658 complain_overflow_dont, /* complain_on_overflow */
659 bfd_elf_generic_reloc, /* special_function */
660 "R_ARM_NONE", /* name */
661 false, /* partial_inplace */
662 0, /* src_mask */
663 0, /* dst_mask */
664 false), /* pcrel_offset */
665
666 HOWTO (R_ARM_PC24, /* type */
667 2, /* rightshift */
668 2, /* size (0 = byte, 1 = short, 2 = long) */
669 24, /* bitsize */
670 true, /* pc_relative */
671 0, /* bitpos */
672 complain_overflow_signed, /* complain_on_overflow */
673 bfd_elf_generic_reloc, /* special_function */
674 "R_ARM_PC24", /* name */
675 false, /* partial_inplace */
676 0x00ffffff, /* src_mask */
677 0x00ffffff, /* dst_mask */
678 true), /* pcrel_offset */
efaa65c9
CM
679
680 /* 32 bit absolute */
2c3c46ad
CM
681 HOWTO (R_ARM_ABS32, /* type */
682 0, /* rightshift */
683 2, /* size (0 = byte, 1 = short, 2 = long) */
684 32, /* bitsize */
685 false, /* pc_relative */
686 0, /* bitpos */
687 complain_overflow_bitfield, /* complain_on_overflow */
688 bfd_elf_generic_reloc, /* special_function */
689 "R_ARM_ABS32", /* name */
690 false, /* partial_inplace */
691 0xffffffff, /* src_mask */
692 0xffffffff, /* dst_mask */
693 false), /* pcrel_offset */
efaa65c9
CM
694
695 /* standard 32bit pc-relative reloc */
2c3c46ad
CM
696 HOWTO (R_ARM_REL32, /* type */
697 0, /* rightshift */
698 2, /* size (0 = byte, 1 = short, 2 = long) */
699 32, /* bitsize */
700 true, /* pc_relative */
701 0, /* bitpos */
702 complain_overflow_bitfield, /* complain_on_overflow */
703 bfd_elf_generic_reloc, /* special_function */
704 "R_ARM_REL32", /* name */
705 false, /* partial_inplace */
706 0xffffffff, /* src_mask */
707 0xffffffff, /* dst_mask */
708 true), /* pcrel_offset */
efaa65c9
CM
709
710 /* 8 bit absolute */
2c3c46ad
CM
711 HOWTO (R_ARM_ABS8, /* type */
712 0, /* rightshift */
713 0, /* size (0 = byte, 1 = short, 2 = long) */
714 8, /* bitsize */
715 false, /* pc_relative */
716 0, /* bitpos */
717 complain_overflow_bitfield, /* complain_on_overflow */
718 bfd_elf_generic_reloc, /* special_function */
719 "R_ARM_ABS8", /* name */
720 false, /* partial_inplace */
721 0x000000ff, /* src_mask */
722 0x000000ff, /* dst_mask */
723 false), /* pcrel_offset */
efaa65c9
CM
724
725 /* 16 bit absolute */
2c3c46ad
CM
726 HOWTO (R_ARM_ABS16, /* type */
727 0, /* rightshift */
728 1, /* size (0 = byte, 1 = short, 2 = long) */
729 16, /* bitsize */
730 false, /* pc_relative */
731 0, /* bitpos */
732 complain_overflow_bitfield, /* complain_on_overflow */
733 bfd_elf_generic_reloc, /* special_function */
734 "R_ARM_ABS16", /* name */
735 false, /* partial_inplace */
736 0, /* src_mask */
737 0, /* dst_mask */
738 false), /* pcrel_offset */
efaa65c9
CM
739
740 /* 12 bit absolute */
2c3c46ad
CM
741 HOWTO (R_ARM_ABS12, /* type */
742 0, /* rightshift */
743 2, /* size (0 = byte, 1 = short, 2 = long) */
744 12, /* bitsize */
745 false, /* pc_relative */
746 0, /* bitpos */
747 complain_overflow_bitfield, /* complain_on_overflow */
748 bfd_elf_generic_reloc, /* special_function */
749 "R_ARM_ABS12", /* name */
750 false, /* partial_inplace */
751 0x000008ff, /* src_mask */
752 0x000008ff, /* dst_mask */
753 false), /* pcrel_offset */
754
755 HOWTO (R_ARM_THM_ABS5, /* type */
756 0, /* rightshift */
757 2, /* size (0 = byte, 1 = short, 2 = long) */
758 5, /* bitsize */
759 false, /* pc_relative */
760 0, /* bitpos */
761 complain_overflow_bitfield, /* complain_on_overflow */
762 bfd_elf_generic_reloc, /* special_function */
763 "R_ARM_THM_ABS5", /* name */
764 false, /* partial_inplace */
765 0x000007e0, /* src_mask */
766 0x000007e0, /* dst_mask */
767 false), /* pcrel_offset */
768
769 HOWTO (R_ARM_THM_PC22, /* type */
770 1, /* rightshift */
771 2, /* size (0 = byte, 1 = short, 2 = long) */
772 22, /* bitsize */
773 true, /* pc_relative */
774 0, /* bitpos */
775 complain_overflow_signed, /* complain_on_overflow */
776 bfd_elf_generic_reloc, /* special_function */
777 "R_ARM_THM_PC22", /* name */
778 false, /* partial_inplace */
779 0x07ff07ff, /* src_mask */
780 0x07ff07ff, /* dst_mask */
781 true), /* pcrel_offset */
782
783 HOWTO (R_ARM_SBREL32, /* type */
784 0, /* rightshift */
785 0, /* size (0 = byte, 1 = short, 2 = long) */
786 0, /* bitsize */
787 false, /* pc_relative */
788 0, /* bitpos */
789 complain_overflow_dont, /* complain_on_overflow */
790 bfd_elf_generic_reloc, /* special_function */
791 "R_ARM_SBREL32", /* name */
792 false, /* partial_inplace */
793 0, /* src_mask */
794 0, /* dst_mask */
795 false), /* pcrel_offset */
796
797 HOWTO (R_ARM_AMP_VCALL9, /* type */
798 1, /* rightshift */
799 1, /* size (0 = byte, 1 = short, 2 = long) */
800 8, /* bitsize */
801 true, /* pc_relative */
802 0, /* bitpos */
803 complain_overflow_signed, /* complain_on_overflow */
804 bfd_elf_generic_reloc, /* special_function */
805 "R_ARM_AMP_VCALL9", /* name */
806 false, /* partial_inplace */
807 0x000000ff, /* src_mask */
808 0x000000ff, /* dst_mask */
809 true), /* pcrel_offset */
efaa65c9
CM
810
811 /* 12 bit pc relative */
2c3c46ad
CM
812 HOWTO (R_ARM_THM_PC11, /* type */
813 1, /* rightshift */
814 1, /* size (0 = byte, 1 = short, 2 = long) */
815 11, /* bitsize */
816 true, /* pc_relative */
817 0, /* bitpos */
818 complain_overflow_signed, /* complain_on_overflow */
819 bfd_elf_generic_reloc, /* special_function */
820 "R_ARM_THM_PC11", /* name */
821 false, /* partial_inplace */
822 0x000007ff, /* src_mask */
823 0x000007ff, /* dst_mask */
824 true), /* pcrel_offset */
efaa65c9
CM
825
826 /* 12 bit pc relative */
2c3c46ad
CM
827 HOWTO (R_ARM_THM_PC9, /* type */
828 1, /* rightshift */
829 1, /* size (0 = byte, 1 = short, 2 = long) */
830 8, /* bitsize */
831 true, /* pc_relative */
832 0, /* bitpos */
833 complain_overflow_signed, /* complain_on_overflow */
834 bfd_elf_generic_reloc, /* special_function */
835 "R_ARM_THM_PC9", /* name */
836 false, /* partial_inplace */
837 0x000000ff, /* src_mask */
838 0x000000ff, /* dst_mask */
839 true), /* pcrel_offset */
efaa65c9
CM
840
841/* FILL ME IN (#13-249) */
842
843
2c3c46ad
CM
844 HOWTO (R_ARM_RREL32, /* type */
845 0, /* rightshift */
846 0, /* size (0 = byte, 1 = short, 2 = long) */
847 0, /* bitsize */
848 false, /* pc_relative */
849 0, /* bitpos */
850 complain_overflow_dont, /* complain_on_overflow */
851 bfd_elf_generic_reloc, /* special_function */
852 "R_ARM_RREL32", /* name */
853 false, /* partial_inplace */
854 0, /* src_mask */
855 0, /* dst_mask */
856 false), /* pcrel_offset */
857
858 HOWTO (R_ARM_RABS32, /* type */
859 0, /* rightshift */
860 0, /* size (0 = byte, 1 = short, 2 = long) */
861 0, /* bitsize */
862 false, /* pc_relative */
863 0, /* bitpos */
864 complain_overflow_dont, /* complain_on_overflow */
865 bfd_elf_generic_reloc, /* special_function */
866 "R_ARM_RABS32", /* name */
867 false, /* partial_inplace */
868 0, /* src_mask */
869 0, /* dst_mask */
870 false), /* pcrel_offset */
871
872 HOWTO (R_ARM_RPC24, /* type */
873 0, /* rightshift */
874 0, /* size (0 = byte, 1 = short, 2 = long) */
875 0, /* bitsize */
876 false, /* pc_relative */
877 0, /* bitpos */
878 complain_overflow_dont, /* complain_on_overflow */
879 bfd_elf_generic_reloc, /* special_function */
880 "R_ARM_RPC24", /* name */
881 false, /* partial_inplace */
882 0, /* src_mask */
883 0, /* dst_mask */
884 false), /* pcrel_offset */
885
886 HOWTO (R_ARM_RBASE, /* type */
887 0, /* rightshift */
888 0, /* size (0 = byte, 1 = short, 2 = long) */
889 0, /* bitsize */
890 false, /* pc_relative */
891 0, /* bitpos */
892 complain_overflow_dont, /* complain_on_overflow */
893 bfd_elf_generic_reloc, /* special_function */
894 "R_ARM_RBASE", /* name */
895 false, /* partial_inplace */
896 0, /* src_mask */
897 0, /* dst_mask */
898 false), /* pcrel_offset */
efaa65c9
CM
899
900};
901struct elf32_arm_reloc_map
2c3c46ad
CM
902 {
903 unsigned char bfd_reloc_val;
904 unsigned char elf_reloc_val;
905 };
efaa65c9
CM
906
907static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
908{
2c3c46ad
CM
909 {BFD_RELOC_NONE, R_ARM_NONE,},
910 {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24,},
911 {BFD_RELOC_32, R_ARM_ABS32,},
912 {BFD_RELOC_32_PCREL, R_ARM_REL32,},
913 {BFD_RELOC_8, R_ARM_ABS8,},
914 {BFD_RELOC_16, R_ARM_ABS16,},
915 {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12,},
916 {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5,},
917 {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22,},
918 {BFD_RELOC_NONE, R_ARM_SBREL32,},
919 {BFD_RELOC_NONE, R_ARM_AMP_VCALL9,},
920 {BFD_RELOC_THUMB_PCREL_BRANCH12, R_ARM_THM_PC11,},
921 {BFD_RELOC_THUMB_PCREL_BRANCH9, R_ARM_THM_PC9,}
efaa65c9
CM
922};
923
924static reloc_howto_type *
925elf32_arm_reloc_type_lookup (abfd, code)
926 bfd *abfd;
927 bfd_reloc_code_real_type code;
928{
929 unsigned int i;
2c3c46ad 930
efaa65c9 931 for (i = 0;
2c3c46ad 932 i < sizeof (elf32_arm_reloc_map) / sizeof (struct elf32_arm_reloc_map);
efaa65c9
CM
933 i++)
934 {
935 if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
2c3c46ad 936 return &elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
efaa65c9 937 }
2c3c46ad 938
efaa65c9
CM
939 return NULL;
940}
941
942static void
943elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
944 bfd *abfd;
945 arelent *bfd_reloc;
946 Elf32_Internal_Rela *elf_reloc;
947{
948 unsigned int r_type;
949
950 r_type = ELF32_R_TYPE (elf_reloc->r_info);
951 /* fixme: need range test */
952 /* BFD_ASSERT (r_type < (unsigned int) R_ELF32_ARM_MAX); */
953 bfd_reloc->howto = &elf32_arm_howto_table[r_type];
954}
955
2c3c46ad
CM
956/* The thumb form of a long branch is a bit finicky, because the offset
957 encoding is split over two fields, each in it's own instruction. They
958 can occur in any order. So given a thumb form of long branch, and an
959 offset, insert the offset into the thumb branch and return finished
960 instruction.
961
962 It takes two thumb instructions to encode the target address. Each has
963 11 bits to invest. The upper 11 bits are stored in one (identifed by
964 H-0.. see below), the lower 11 bits are stored in the other (identified
965 by H-1).
966
967 Combine together and shifted left by 1 (it's a half word address) and
968 there you have it.
969
970 Op: 1111 = F,
971 H-0, upper address-0 = 000
972 Op: 1111 = F,
973 H-1, lower address-0 = 800
974
975 They can be ordered either way, but the arm tools I've seen always put
976 the lower one first. It probably doesn't matter. krk@cygnus.com
977
978 XXX: Actually the order does matter. The second instruction (H-1)
979 moves the computed address into the PC, so it must be the second one
980 in the sequence. The problem, however is that whilst little endian code
981 stores the instructions in HI then LOW order, big endian code does the
982 reverse. nickc@cygnus.com */
983
984#define LOW_HI_ORDER 0xF800F000
985#define HI_LOW_ORDER 0xF000F800
986
987static insn32
988insert_thumb_branch (br_insn, rel_off)
989 insn32 br_insn;
990 int rel_off;
991{
992 unsigned int low_bits;
993 unsigned int high_bits;
994
995
996 BFD_ASSERT ((rel_off & 1) != 1);
997
998 rel_off >>= 1; /* half word aligned address */
999 low_bits = rel_off & 0x000007FF; /* the bottom 11 bits */
1000 high_bits = (rel_off >> 11) & 0x000007FF; /* the top 11 bits */
1001
1002 if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1003 br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1004 else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1005 br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1006 else
1007 abort (); /* error - not a valid branch instruction form */
1008
1009 /* FIXME: abort is probably not the right call. krk@cygnus.com */
1010
1011 return br_insn;
1012}
774852e9
NC
1013
1014/* Thumb code calling an ARM function */
1015int
2c3c46ad
CM
1016elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
1017 hit_data, sym_sec, offset, addend, val)
1018 struct bfd_link_info *info;
1019 char *name;
1020 bfd *input_bfd;
1021 bfd *output_bfd;
1022 asection *input_section;
1023 bfd_byte *hit_data;
1024 asection *sym_sec;
1025 int offset;
1026 int addend;
1027 bfd_vma val;
1028{
2c3c46ad
CM
1029 asection *s = 0;
1030 long int my_offset;
1031 unsigned long int tmp;
1032 long int ret_offset;
1033 struct elf_link_hash_entry *myh;
1034 struct elf32_arm_link_hash_table *globals;
1035
1036 myh = find_thumb_glue (info, name, input_bfd);
1037 if (myh == NULL)
1038 return false;
1039
1040 globals = elf32_arm_hash_table (info);
1041
1042 BFD_ASSERT (globals != NULL);
1043 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1044
1045 my_offset = myh->root.u.def.value;
1046
1047 s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1048 THUMB2ARM_GLUE_SECTION_NAME);
1049
1050 BFD_ASSERT (s != NULL);
1051 BFD_ASSERT (s->contents != NULL);
1052 BFD_ASSERT (s->output_section != NULL);
1053
1054 if ((my_offset & 0x01) == 0x01)
1055 {
774852e9
NC
1056 if (sym_sec != NULL
1057 && sym_sec->owner != NULL
2c3c46ad
CM
1058 && !INTERWORK_FLAG (sym_sec->owner))
1059 {
1060 _bfd_error_handler
1061 (_ ("%s(%s): warning: interworking not enabled."),
1062 bfd_get_filename (sym_sec->owner), name);
1063 _bfd_error_handler
1064 (_ (" first occurrence: %s: thumb call to arm"),
1065 bfd_get_filename (input_bfd));
1066 }
1067
1068 --my_offset;
1069 myh->root.u.def.value = my_offset;
1070
1071 bfd_put_16 (output_bfd, t2a1_bx_pc_insn,
1072 s->contents + my_offset);
1073
1074 bfd_put_16 (output_bfd, t2a2_noop_insn,
1075 s->contents + my_offset + 2);
1076
1077 ret_offset =
1078 ((bfd_signed_vma) val) /* Address of destination of the stub */
1079 - ((bfd_signed_vma)
1080 (s->output_offset /* Offset from the start of the current section to the start of the stubs. */
1081 + my_offset /* Offset of the start of this stub from the start of the stubs. */
1082 + s->output_section->vma) /* Address of the start of the current section. */
1083 + 4 /* The branch instruction is 4 bytes into the stub. */
1084 + 8); /* ARM branches work from the pc of the instruction + 8. */
1085
1086 bfd_put_32 (output_bfd,
1087 t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1088 s->contents + my_offset + 4);
1089 }
1090
1091 BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1092
1093 /* Now go back and fix up the original BL insn to point
1094 to here. */
1095 ret_offset =
1096 s->output_offset
1097 + my_offset
1098 - (input_section->output_offset
1099 + offset + addend)
1100 - 4;
1101
1102 tmp = bfd_get_32 (input_bfd, hit_data
1103 - input_section->vma);
1104
1105 bfd_put_32 (output_bfd,
1106 insert_thumb_branch (tmp, ret_offset),
1107 hit_data - input_section->vma);
1108}
774852e9
NC
1109
1110/* Arm code calling a Thumb function */
1111int
2c3c46ad
CM
1112elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
1113 hit_data, sym_sec, offset, addend, val)
1114
1115 struct bfd_link_info *info;
1116 char *name;
1117 bfd *input_bfd;
1118 bfd *output_bfd;
1119 asection *input_section;
1120 bfd_byte *hit_data;
1121 asection *sym_sec;
1122 int offset;
1123 int addend;
1124 bfd_vma val;
1125{
2c3c46ad
CM
1126 unsigned long int tmp;
1127 long int my_offset;
1128 asection *s;
1129 long int ret_offset;
1130 struct elf_link_hash_entry *myh;
1131 struct elf32_arm_link_hash_table *globals;
1132
1133 myh = find_arm_glue (info, name, input_bfd);
1134 if (myh == NULL)
1135 return false;
1136
1137 globals = elf32_arm_hash_table (info);
1138
1139 BFD_ASSERT (globals != NULL);
1140 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1141
1142 my_offset = myh->root.u.def.value;
1143 s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1144 ARM2THUMB_GLUE_SECTION_NAME);
1145 BFD_ASSERT (s != NULL);
1146 BFD_ASSERT (s->contents != NULL);
1147 BFD_ASSERT (s->output_section != NULL);
1148
1149 if ((my_offset & 0x01) == 0x01)
1150 {
774852e9
NC
1151 if (sym_sec != NULL
1152 && sym_sec->owner != NULL
2c3c46ad
CM
1153 && !INTERWORK_FLAG (sym_sec->owner))
1154 {
1155 _bfd_error_handler
1156 (_ ("%s(%s): warning: interworking not enabled."),
1157 bfd_get_filename (sym_sec->owner), name);
1158 _bfd_error_handler
1159 (_ (" first occurrence: %s: arm call to thumb"),
1160 bfd_get_filename (input_bfd));
1161 }
1162 --my_offset;
1163 myh->root.u.def.value = my_offset;
1164
1165 bfd_put_32 (output_bfd, a2t1_ldr_insn,
1166 s->contents + my_offset);
1167
1168 bfd_put_32 (output_bfd, a2t2_bx_r12_insn,
1169 s->contents + my_offset + 4);
1170
1171 /* It's a thumb address. Add the low order bit. */
1172 bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
1173 s->contents + my_offset + 8);
1174 }
1175
1176 BFD_ASSERT (my_offset <= globals->arm_glue_size);
1177
1178 tmp = bfd_get_32 (input_bfd, hit_data);
1179 tmp = tmp & 0xFF000000;
1180
1181 /* Somehow these are both 4 too far, so subtract 8. */
1182 ret_offset = s->output_offset
1183 + my_offset
1184 + s->output_section->vma
1185 - (input_section->output_offset
1186 + input_section->output_section->vma
1187 + offset + addend)
1188 - 8;
1189
1190 tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1191
1192 bfd_put_32 (output_bfd, tmp, hit_data
1193 - input_section->vma);
1194
1195}
774852e9 1196
efaa65c9
CM
1197/* Perform a relocation as part of a final link. */
1198static bfd_reloc_status_type
1199elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
2c3c46ad
CM
1200 input_section, contents, offset, value,
1201 addend, info, sym_sec, sym_name, sym_flags)
efaa65c9
CM
1202 reloc_howto_type *howto;
1203 bfd *input_bfd;
1204 bfd *output_bfd;
1205 asection *input_section;
1206 bfd_byte *contents;
1207 bfd_vma offset;
1208 bfd_vma value;
1209 bfd_vma addend;
1210 struct bfd_link_info *info;
1211 asection *sym_sec;
774852e9 1212 const char *sym_name;
a17e14c1 1213 unsigned char sym_flags;
efaa65c9
CM
1214{
1215 unsigned long r_type = howto->type;
1216 bfd_byte *hit_data = contents + offset;
1217
1218 switch (r_type)
1219 {
1220
1221 case R_ARM_NONE:
1222 return bfd_reloc_ok;
1223
1224 case R_ARM_PC24:
2c3c46ad
CM
1225 /* Arm B/BL instruction */
1226
1227 /* check for arm calling thumb function */
1228 if (sym_flags == C_THUMBSTATFUNC
1229 || sym_flags == C_THUMBEXTFUNC)
1230 {
1231 elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
1232 input_section, hit_data, sym_sec, offset, addend, value);
1233 return bfd_reloc_ok;
1234 }
1235
1236 value = value + addend;
1237 value -= (input_section->output_section->vma
1238 + input_section->output_offset + 8);
1239 value -= offset;
1240 value = value >> howto->rightshift;
efaa65c9 1241
efaa65c9
CM
1242 value &= 0xffffff;
1243 value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
1244 bfd_put_32 (input_bfd, value, hit_data);
1245 return bfd_reloc_ok;
1246
1247 case R_ARM_ABS32:
1248 value += addend;
a17e14c1 1249 if (sym_flags == C_THUMBSTATFUNC
2c3c46ad
CM
1250 || sym_flags == C_THUMBEXTFUNC)
1251 value |= 1;
efaa65c9
CM
1252 bfd_put_32 (input_bfd, value, hit_data);
1253 return bfd_reloc_ok;
1254
1255 case R_ARM_REL32:
1256 value -= (input_section->output_section->vma
2c3c46ad 1257 + input_section->output_offset);
efaa65c9
CM
1258 value += addend;
1259
1260 bfd_put_32 (input_bfd, value, hit_data);
1261 return bfd_reloc_ok;
1262
1263 case R_ARM_ABS8:
1264 value += addend;
2c3c46ad 1265
efaa65c9 1266 if ((long) value > 0x7f || (long) value < -0x80)
2c3c46ad
CM
1267 return bfd_reloc_overflow;
1268
efaa65c9
CM
1269 bfd_put_8 (input_bfd, value, hit_data);
1270 return bfd_reloc_ok;
1271
1272 case R_ARM_ABS16:
1273 value += addend;
1274
1275 if ((long) value > 0x7fff || (long) value < -0x8000)
2c3c46ad
CM
1276 return bfd_reloc_overflow;
1277
efaa65c9
CM
1278 bfd_put_16 (input_bfd, value, hit_data);
1279 return bfd_reloc_ok;
1280
1281 case R_ARM_ABS12:
1282 /* Support ldr and str instruction for the arm */
1283 /* Also thumb b (unconditional branch) */
1284 value += addend;
1285
1286 if ((long) value > 0x7ff || (long) value < -0x800)
2c3c46ad 1287 return bfd_reloc_overflow;
efaa65c9
CM
1288
1289 value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
1290 bfd_put_32 (input_bfd, value, hit_data);
1291 return bfd_reloc_ok;
1292
1293 case R_ARM_THM_ABS5:
1294 /* Support ldr and str instructions for the thumb. */
1295 value += addend;
1296
1297 if ((long) value > 0x1f || (long) value < -0x10)
2c3c46ad 1298 return bfd_reloc_overflow;
efaa65c9
CM
1299
1300 value |= bfd_get_16 (input_bfd, hit_data) & 0xf82f;
1301 bfd_put_16 (input_bfd, value, hit_data);
1302 return bfd_reloc_ok;
efaa65c9 1303
efaa65c9 1304
efaa65c9 1305 case R_ARM_THM_PC22:
2c3c46ad 1306 /* thumb BL (branch long instruction). */
efaa65c9 1307 {
2c3c46ad
CM
1308 bfd_vma relocation;
1309 boolean overflow = false;
1310 bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
1311 bfd_vma src_mask = 0x007FFFFE;
1312 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1313 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1314 bfd_vma check;
1315 bfd_signed_vma signed_check;
1316 bfd_vma add;
1317 bfd_signed_vma signed_add;
1318
1319 if (sym_flags == C_EXT
1320 || sym_flags == C_STAT
1321 || sym_flags == C_LABEL)
1322 {
1323 elf32_thumb_to_arm_stub (info, sym_name, input_bfd, output_bfd, input_section,
1324 hit_data, sym_sec, offset, addend, value);
1325 return bfd_reloc_ok;
1326 }
1327
1328 relocation = value + addend;
1329 relocation -= (input_section->output_section->vma + input_section->output_offset);
1330 relocation -= offset;
1331
1332 check = relocation >> howto->rightshift;
1333
1334 /* If this is a signed value, the rightshift just dropped
1335 leading 1 bits (assuming twos complement). */
1336 if ((bfd_signed_vma) relocation >= 0)
1337 signed_check = check;
1338 else
1339 signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
1340
1341 /* Get the value from the object file. */
1342 if (bfd_big_endian (input_bfd))
1343 add = (((insn) & 0x07ff0000) >> 4) | (((insn) & 0x7ff) << 1);
1344 else
1345 add = ((((insn) & 0x7ff) << 12) | (((insn) & 0x07ff0000) >> 15));
1346
1347 /* Get the value from the object file with an appropriate sign.
1348 The expression involving howto->src_mask isolates the upper
1349 bit of src_mask. If that bit is set in the value we are
1350 adding, it is negative, and we subtract out that number times
1351 two. If src_mask includes the highest possible bit, then we
1352 can not get the upper bit, but that does not matter since
1353 signed_add needs no adjustment to become negative in that case. */
1354
1355 signed_add = add;
1356
1357 if ((add & (((~src_mask) >> 1) & src_mask)) != 0)
1358 signed_add -= (((~src_mask) >> 1) & src_mask) << 1;
1359
1360 /* Add the value from the object file, shifted so that it is a
1361 straight number. */
1362 /* howto->bitpos == 0 */
1363
1364 signed_check += signed_add;
1365 relocation += signed_add;
1366
1367 /* Assumes two's complement. */
1368 if (signed_check > reloc_signed_max
1369 || signed_check < reloc_signed_min)
1370 overflow = true;
1371
1372 /* Put RELOCATION into the correct bits: */
1373
1374 if (bfd_big_endian (input_bfd))
1375 relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1376 else
1377 relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1378
1379 /* Add RELOCATION to the correct bits of X: */
1380 insn = ((insn & ~howto->dst_mask) | relocation);
1381
1382 /* Put the relocated value back in the object file: */
1383 bfd_put_32 (input_bfd, insn, hit_data);
1384
1385 return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
efaa65c9
CM
1386 }
1387 break;
2c3c46ad 1388
efaa65c9 1389 case R_ARM_SBREL32:
a17e14c1 1390 return bfd_reloc_notsupported;
efaa65c9
CM
1391
1392 case R_ARM_AMP_VCALL9:
1393 return bfd_reloc_notsupported;
1394
1395 case R_ARM_RSBREL32:
1396 return bfd_reloc_notsupported;
1397
1398 case R_ARM_THM_RPC22:
1399 return bfd_reloc_notsupported;
1400
1401 case R_ARM_RREL32:
1402 return bfd_reloc_notsupported;
1403
1404 case R_ARM_RABS32:
1405 return bfd_reloc_notsupported;
1406
1407 case R_ARM_RPC24:
1408 return bfd_reloc_notsupported;
1409
1410 case R_ARM_RBASE:
1411 return bfd_reloc_notsupported;
1412
1413 default:
1414 return bfd_reloc_notsupported;
1415 }
1416}
774852e9
NC
1417
1418
efaa65c9
CM
1419/* Relocate an ARM ELF section. */
1420static boolean
1421elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
2c3c46ad 1422 contents, relocs, local_syms, local_sections)
efaa65c9
CM
1423 bfd *output_bfd;
1424 struct bfd_link_info *info;
1425 bfd *input_bfd;
1426 asection *input_section;
1427 bfd_byte *contents;
1428 Elf_Internal_Rela *relocs;
1429 Elf_Internal_Sym *local_syms;
1430 asection **local_sections;
1431{
1432 Elf_Internal_Shdr *symtab_hdr;
1433 struct elf_link_hash_entry **sym_hashes;
1434 Elf_Internal_Rela *rel, *relend;
774852e9 1435 const char *name;
efaa65c9
CM
1436
1437 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1438 sym_hashes = elf_sym_hashes (input_bfd);
1439
1440 rel = relocs;
1441 relend = relocs + input_section->reloc_count;
1442 for (; rel < relend; rel++)
1443 {
1444 int r_type;
1445 reloc_howto_type *howto;
1446 unsigned long r_symndx;
1447 Elf_Internal_Sym *sym;
1448 asection *sec;
1449 struct elf_link_hash_entry *h;
1450 bfd_vma relocation;
1451 bfd_reloc_status_type r;
1452
1453 r_symndx = ELF32_R_SYM (rel->r_info);
1454 r_type = ELF32_R_TYPE (rel->r_info);
1455 howto = elf32_arm_howto_table + r_type;
1456
1457 if (info->relocateable)
1458 {
1459 /* This is a relocateable link. We don't have to change
2c3c46ad
CM
1460 anything, unless the reloc is against a section symbol,
1461 in which case we have to adjust according to where the
1462 section symbol winds up in the output section. */
efaa65c9
CM
1463 if (r_symndx < symtab_hdr->sh_info)
1464 {
1465 sym = local_syms + r_symndx;
1466 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1467 {
1468 sec = local_sections[r_symndx];
1469 rel->r_addend += sec->output_offset + sym->st_value;
1470 }
1471 }
1472
1473 continue;
1474 }
1475
1476 /* This is a final link. */
1477 h = NULL;
1478 sym = NULL;
1479 sec = NULL;
1480 if (r_symndx < symtab_hdr->sh_info)
1481 {
1482 sym = local_syms + r_symndx;
1483 sec = local_sections[r_symndx];
1484 relocation = (sec->output_section->vma
1485 + sec->output_offset
1486 + sym->st_value);
1487 }
1488 else
1489 {
1490 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1491 while (h->root.type == bfd_link_hash_indirect
1492 || h->root.type == bfd_link_hash_warning)
1493 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1494 if (h->root.type == bfd_link_hash_defined
1495 || h->root.type == bfd_link_hash_defweak)
1496 {
1497 sec = h->root.u.def.section;
1498 relocation = (h->root.u.def.value
1499 + sec->output_section->vma
1500 + sec->output_offset);
1501 }
1502 else if (h->root.type == bfd_link_hash_undefweak)
1503 relocation = 0;
1504 else
1505 {
2c3c46ad
CM
1506 if (!((*info->callbacks->undefined_symbol)
1507 (info, h->root.root.string, input_bfd,
1508 input_section, rel->r_offset)))
efaa65c9
CM
1509 return false;
1510 relocation = 0;
1511 }
1512 }
1513
774852e9
NC
1514 if (h != NULL)
1515 name = h->root.root.string;
1516 else
1517 {
1518 name = (bfd_elf_string_from_elf_section
1519 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1520 if (name == NULL || *name == '\0')
1521 name = bfd_section_name (input_bfd, sec);
1522 }
1523
efaa65c9 1524 r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
2c3c46ad
CM
1525 input_section,
1526 contents, rel->r_offset,
1527 relocation, rel->r_addend,
774852e9 1528 info, sec, name,
2c3c46ad 1529 (h ? h->other : sym->st_other));
efaa65c9
CM
1530
1531
1532 if (r != bfd_reloc_ok)
1533 {
2c3c46ad 1534 const char *msg = (const char *) 0;
efaa65c9 1535
efaa65c9
CM
1536 switch (r)
1537 {
1538 case bfd_reloc_overflow:
2c3c46ad
CM
1539 if (!((*info->callbacks->reloc_overflow)
1540 (info, name, howto->name, (bfd_vma) 0,
1541 input_bfd, input_section, rel->r_offset)))
efaa65c9
CM
1542 return false;
1543 break;
1544
1545 case bfd_reloc_undefined:
2c3c46ad
CM
1546 if (!((*info->callbacks->undefined_symbol)
1547 (info, name, input_bfd, input_section,
1548 rel->r_offset)))
efaa65c9
CM
1549 return false;
1550 break;
1551
1552 case bfd_reloc_outofrange:
2c3c46ad 1553 msg = _ ("internal error: out of range error");
efaa65c9
CM
1554 goto common_error;
1555
1556 case bfd_reloc_notsupported:
2c3c46ad 1557 msg = _ ("internal error: unsupported relocation error");
efaa65c9
CM
1558 goto common_error;
1559
1560 case bfd_reloc_dangerous:
2c3c46ad 1561 msg = _ ("internal error: dangerous error");
efaa65c9
CM
1562 goto common_error;
1563
1564 default:
2c3c46ad 1565 msg = _ ("internal error: unknown error");
efaa65c9
CM
1566 /* fall through */
1567
1568 common_error:
1569 if (!((*info->callbacks->warning)
1570 (info, msg, name, input_bfd, input_section,
1571 rel->r_offset)))
1572 return false;
1573 break;
1574 }
1575 }
1576 }
1577
1578 return true;
1579}
1580
0e7361bc
NC
1581/* Function to keep ARM specific flags in the ELF header. */
1582static boolean
1583elf32_arm_set_private_flags (abfd, flags)
2c3c46ad 1584 bfd *abfd;
0e7361bc
NC
1585 flagword flags;
1586{
1587 if (elf_flags_init (abfd)
1588 && elf_elfheader (abfd)->e_flags != flags)
1589 {
1590 if (flags & EF_INTERWORK)
2c3c46ad 1591 _bfd_error_handler (_ ("\
0e7361bc
NC
1592Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
1593 bfd_get_filename (abfd));
1594 else
2c3c46ad 1595 _bfd_error_handler (_ ("\
0e7361bc 1596Warning: Clearing the interwork flag of %s due to outside request"),
2c3c46ad 1597 bfd_get_filename (abfd));
0e7361bc
NC
1598 }
1599 else
1600 {
1601 elf_elfheader (abfd)->e_flags = flags;
1602 elf_flags_init (abfd) = true;
1603 }
2c3c46ad 1604
0e7361bc
NC
1605 return true;
1606}
1607
1608/* Copy backend specific data from one object module to another */
1609static boolean
1610elf32_arm_copy_private_bfd_data (ibfd, obfd)
2c3c46ad
CM
1611 bfd *ibfd;
1612 bfd *obfd;
0e7361bc
NC
1613{
1614 flagword in_flags;
1615 flagword out_flags;
2c3c46ad
CM
1616
1617 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
0e7361bc
NC
1618 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1619 return true;
1620
2c3c46ad 1621 in_flags = elf_elfheader (ibfd)->e_flags;
0e7361bc 1622 out_flags = elf_elfheader (obfd)->e_flags;
2c3c46ad
CM
1623
1624 if (elf_flags_init (obfd) && in_flags != out_flags)
0e7361bc
NC
1625 {
1626 /* Cannot mix PIC and non-PIC code. */
1627 if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1628 return false;
2c3c46ad 1629
0e7361bc
NC
1630 /* Cannot mix APCS26 and APCS32 code. */
1631 if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1632 return false;
2c3c46ad 1633
0e7361bc
NC
1634 /* Cannot mix float APCS and non-float APCS code. */
1635 if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1636 return false;
1637
1638 /* If the src and dest have different interworking flags
2c3c46ad 1639 then turn off the interworking bit. */
0e7361bc
NC
1640 if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1641 {
1642 if (out_flags & EF_INTERWORK)
2c3c46ad 1643 _bfd_error_handler (_ ("\
0e7361bc 1644Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
2c3c46ad
CM
1645 bfd_get_filename (obfd), bfd_get_filename (ibfd));
1646
1647 in_flags &= ~EF_INTERWORK;
0e7361bc
NC
1648 }
1649 }
1650
1651 elf_elfheader (obfd)->e_flags = in_flags;
1652 elf_flags_init (obfd) = true;
2c3c46ad 1653
0e7361bc
NC
1654 return true;
1655}
1656
1657/* Merge backend specific data from an object file to the output
1658 object file when linking. */
1659static boolean
1660elf32_arm_merge_private_bfd_data (ibfd, obfd)
2c3c46ad
CM
1661 bfd *ibfd;
1662 bfd *obfd;
0e7361bc
NC
1663{
1664 flagword out_flags;
1665 flagword in_flags;
1666
2c3c46ad 1667 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
0e7361bc
NC
1668 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1669 return true;
1670
1671 /* The input BFD must have had its flags initialised. */
a17e14c1
CM
1672 /* The following seems bogus to me -- The flags are initialized in
1673 the assembler but I don't think an elf_flags_init field is
1674 written into the object */
1675 /* BFD_ASSERT (elf_flags_init (ibfd)); */
2c3c46ad
CM
1676
1677 in_flags = elf_elfheader (ibfd)->e_flags;
0e7361bc
NC
1678 out_flags = elf_elfheader (obfd)->e_flags;
1679
2c3c46ad 1680 if (!elf_flags_init (obfd))
0e7361bc
NC
1681 {
1682 /* If the input is the default architecture then do not
2c3c46ad
CM
1683 bother setting the flags for the output architecture,
1684 instead allow future merges to do this. If no future
1685 merges ever set these flags then they will retain their
1686 unitialised values, which surprise surprise, correspond
1687 to the default values. */
0e7361bc
NC
1688 if (bfd_get_arch_info (ibfd)->the_default)
1689 return true;
2c3c46ad 1690
0e7361bc
NC
1691 elf_flags_init (obfd) = true;
1692 elf_elfheader (obfd)->e_flags = in_flags;
1693
1694 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1695 && bfd_get_arch_info (obfd)->the_default)
1696 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1697
1698 return true;
1699 }
1700
1701 /* Check flag compatibility. */
1702 if (in_flags == out_flags)
1703 return true;
1704
1705 /* Complain about various flag mismatches. */
2c3c46ad 1706
0e7361bc 1707 if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
2c3c46ad 1708 _bfd_error_handler (_ ("\
0e7361bc
NC
1709Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
1710 bfd_get_filename (ibfd),
1711 in_flags & EF_APCS_26 ? 26 : 32,
1712 bfd_get_filename (obfd),
1713 out_flags & EF_APCS_26 ? 26 : 32);
2c3c46ad 1714
0e7361bc 1715 if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
2c3c46ad 1716 _bfd_error_handler (_ ("\
0e7361bc
NC
1717Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
1718 bfd_get_filename (ibfd),
2c3c46ad 1719 in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
0e7361bc 1720 bfd_get_filename (obfd),
2c3c46ad
CM
1721 out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
1722
0e7361bc 1723 if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
2c3c46ad 1724 _bfd_error_handler (_ ("\
0e7361bc
NC
1725Error: %s is compiled as position %s code, whereas %s is not"),
1726 bfd_get_filename (ibfd),
2c3c46ad 1727 in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
0e7361bc
NC
1728 bfd_get_filename (obfd));
1729
1730 /* Interworking mismatch is only a warning. */
1731 if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1732 {
2c3c46ad 1733 _bfd_error_handler (_ ("\
0e7361bc
NC
1734Warning: %s %s interworking, whereas %s %s"),
1735 bfd_get_filename (ibfd),
2c3c46ad 1736 in_flags & EF_INTERWORK ? _ ("supports") : _ ("does not support"),
0e7361bc 1737 bfd_get_filename (obfd),
2c3c46ad 1738 out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
0e7361bc
NC
1739 return true;
1740 }
1741
1742 return false;
1743}
1744
1745/* Display the flags field */
1746static boolean
1747elf32_arm_print_private_bfd_data (abfd, ptr)
2c3c46ad
CM
1748 bfd *abfd;
1749 PTR ptr;
0e7361bc 1750{
2c3c46ad
CM
1751 FILE *file = (FILE *) ptr;
1752
0e7361bc
NC
1753 BFD_ASSERT (abfd != NULL && ptr != NULL);
1754
1755 /* Print normal ELF private data. */
1756 _bfd_elf_print_private_bfd_data (abfd, ptr);
1757
1758 /* Ignore init flag - it may not be set, despite the flags field containing valid data. */
2c3c46ad 1759
0e7361bc 1760 /* xgettext:c-format */
2c3c46ad 1761 fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
0e7361bc
NC
1762
1763 if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
2c3c46ad 1764 fprintf (file, _ (" [interworking enabled]"));
0e7361bc 1765 else
2c3c46ad
CM
1766 fprintf (file, _ (" [interworking not enabled]"));
1767
0e7361bc 1768 if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
2c3c46ad 1769 fprintf (file, _ (" [APCS-26]"));
0e7361bc 1770 else
2c3c46ad
CM
1771 fprintf (file, _ (" [APCS-32]"));
1772
0e7361bc 1773 if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
2c3c46ad 1774 fprintf (file, _ (" [floats passed in float registers]"));
0e7361bc 1775 else
2c3c46ad
CM
1776 fprintf (file, _ (" [floats passed in integer registers]"));
1777
0e7361bc 1778 if (elf_elfheader (abfd)->e_flags & EF_PIC)
2c3c46ad 1779 fprintf (file, _ (" [position independent]"));
0e7361bc 1780 else
2c3c46ad
CM
1781 fprintf (file, _ (" [absolute position]"));
1782
0e7361bc 1783 fputc ('\n', file);
2c3c46ad 1784
0e7361bc
NC
1785 return true;
1786}
1787
1788
efaa65c9
CM
1789#define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec
1790#define TARGET_LITTLE_NAME "elf32-littlearm"
1791#define TARGET_BIG_SYM bfd_elf32_bigarm_vec
1792#define TARGET_BIG_NAME "elf32-bigarm"
1793#define ELF_ARCH bfd_arch_arm
1794#define ELF_MACHINE_CODE EM_ARM
1795
0e7361bc
NC
1796#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
1797#define elf_info_to_howto elf32_arm_info_to_howto
1798#define elf_info_to_howto_rel 0
1799#define elf_backend_relocate_section elf32_arm_relocate_section
1800#define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
1801#define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
1802#define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags
1803#define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data
2c3c46ad 1804#define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
efaa65c9
CM
1805
1806#define elf_symbol_leading_char '_'
1807
1808#include "elf32-target.h"
1809/* end-sanitize-armelf */
This page took 0.104183 seconds and 4 git commands to generate.