* elf32-arm.c: Add prefix bfd_ to elf32_arm_get_bfd_for_interworking,
[deliverable/binutils-gdb.git] / bfd / elf32-arm.c
1 /* start-sanitize-armelf */
2 /* 32-bit ELF support for ARM
3 Copyright 1993, 1995, 1998 Free Software Foundation, Inc.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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. */
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
28 typedef unsigned long int insn32;
29 typedef unsigned short int insn16;
30
31 static reloc_howto_type *elf32_arm_reloc_type_lookup
32 PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
33 static void elf32_arm_info_to_howto
34 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
35 static boolean elf32_arm_set_private_flags
36 PARAMS ((bfd *, flagword));
37 static boolean elf32_arm_copy_private_bfd_data
38 PARAMS ((bfd *, bfd *));
39 static boolean elf32_arm_merge_private_bfd_data
40 PARAMS ((bfd *, bfd *));
41 static boolean elf32_arm_print_private_bfd_data
42 PARAMS ((bfd *, PTR));
43 static struct bfd_link_hash_table *elf32_arm_link_hash_table_create
44 PARAMS ((bfd *));
45
46
47 static insn32 insert_thumb_branch
48 PARAMS ((insn32, int));
49 static struct elf_link_hash_entry *find_thumb_glue
50 PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
51 static struct elf_link_hash_entry *find_arm_glue
52 PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
53 static void record_arm_to_thumb_glue
54 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
55 static 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 */
77 struct 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
97 static struct bfd_link_hash_table *
98 elf32_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
122 static struct elf_link_hash_entry *
123 find_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
156 static struct elf_link_hash_entry *
157 find_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
201 static const insn32 a2t1_ldr_insn = 0xe59fc000;
202 static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
203 static 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
224 static const insn16 t2a1_bx_pc_insn = 0x4778;
225 static const insn16 t2a2_noop_insn = 0x46c0;
226 static const insn32 t2a3_b_insn = 0xea000000;
227
228 static const insn16 t2a1_push_insn = 0xb540;
229 static const insn16 t2a2_ldr_insn = 0x4e03;
230 static const insn16 t2a3_mov_insn = 0x46fe;
231 static const insn16 t2a4_bx_insn = 0x4730;
232 static const insn32 t2a5_pop_insn = 0xe8bd4040;
233 static const insn32 t2a6_bx_insn = 0xe12fff1e;
234
235 boolean
236 bfd_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
282 static void
283 record_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
337 static void
338 record_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 */
411 boolean
412 bfd_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
466 boolean
467 bfd_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;
635 error_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 }
645
646 #define USE_RELA
647 #define TARGET_UNDERSCORE '_'
648
649 static reloc_howto_type elf32_arm_howto_table[] =
650 {
651 /* No relocation */
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 */
679
680 /* 32 bit absolute */
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 */
694
695 /* standard 32bit pc-relative reloc */
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 */
709
710 /* 8 bit absolute */
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 */
724
725 /* 16 bit absolute */
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 */
739
740 /* 12 bit absolute */
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 */
810
811 /* 12 bit pc relative */
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 */
825
826 /* 12 bit pc relative */
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 */
840
841 /* FILL ME IN (#13-249) */
842
843
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 */
899
900 };
901 struct elf32_arm_reloc_map
902 {
903 unsigned char bfd_reloc_val;
904 unsigned char elf_reloc_val;
905 };
906
907 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
908 {
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,}
922 };
923
924 static reloc_howto_type *
925 elf32_arm_reloc_type_lookup (abfd, code)
926 bfd *abfd;
927 bfd_reloc_code_real_type code;
928 {
929 unsigned int i;
930
931 for (i = 0;
932 i < sizeof (elf32_arm_reloc_map) / sizeof (struct elf32_arm_reloc_map);
933 i++)
934 {
935 if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
936 return &elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
937 }
938
939 return NULL;
940 }
941
942 static void
943 elf32_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
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
987 static insn32
988 insert_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 }
1013 elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
1014 hit_data, sym_sec, offset, addend, val)
1015 struct bfd_link_info *info;
1016 char *name;
1017 bfd *input_bfd;
1018 bfd *output_bfd;
1019 asection *input_section;
1020 bfd_byte *hit_data;
1021 asection *sym_sec;
1022 int offset;
1023 int addend;
1024 bfd_vma val;
1025 {
1026
1027 /* Thumb code calling an ARM function */
1028 asection *s = 0;
1029 long int my_offset;
1030 unsigned long int tmp;
1031 long int ret_offset;
1032 struct elf_link_hash_entry *myh;
1033 struct elf32_arm_link_hash_table *globals;
1034
1035 myh = find_thumb_glue (info, name, input_bfd);
1036 if (myh == NULL)
1037 return false;
1038
1039 globals = elf32_arm_hash_table (info);
1040
1041 BFD_ASSERT (globals != NULL);
1042 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1043
1044 my_offset = myh->root.u.def.value;
1045
1046 s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1047 THUMB2ARM_GLUE_SECTION_NAME);
1048
1049 BFD_ASSERT (s != NULL);
1050 BFD_ASSERT (s->contents != NULL);
1051 BFD_ASSERT (s->output_section != NULL);
1052
1053 if ((my_offset & 0x01) == 0x01)
1054 {
1055
1056 if (sym_sec->owner != NULL
1057 && !INTERWORK_FLAG (sym_sec->owner))
1058 {
1059 _bfd_error_handler
1060 (_ ("%s(%s): warning: interworking not enabled."),
1061 bfd_get_filename (sym_sec->owner), name);
1062 _bfd_error_handler
1063 (_ (" first occurrence: %s: thumb call to arm"),
1064 bfd_get_filename (input_bfd));
1065 }
1066
1067 --my_offset;
1068 myh->root.u.def.value = my_offset;
1069
1070 bfd_put_16 (output_bfd, t2a1_bx_pc_insn,
1071 s->contents + my_offset);
1072
1073 bfd_put_16 (output_bfd, t2a2_noop_insn,
1074 s->contents + my_offset + 2);
1075
1076 ret_offset =
1077 ((bfd_signed_vma) val) /* Address of destination of the stub */
1078 - ((bfd_signed_vma)
1079 (s->output_offset /* Offset from the start of the current section to the start of the stubs. */
1080 + my_offset /* Offset of the start of this stub from the start of the stubs. */
1081 + s->output_section->vma) /* Address of the start of the current section. */
1082 + 4 /* The branch instruction is 4 bytes into the stub. */
1083 + 8); /* ARM branches work from the pc of the instruction + 8. */
1084
1085 bfd_put_32 (output_bfd,
1086 t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1087 s->contents + my_offset + 4);
1088 }
1089
1090 BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1091
1092 /* Now go back and fix up the original BL insn to point
1093 to here. */
1094 ret_offset =
1095 s->output_offset
1096 + my_offset
1097 - (input_section->output_offset
1098 + offset + addend)
1099 - 4;
1100
1101 tmp = bfd_get_32 (input_bfd, hit_data
1102 - input_section->vma);
1103
1104 bfd_put_32 (output_bfd,
1105 insert_thumb_branch (tmp, ret_offset),
1106 hit_data - input_section->vma);
1107 }
1108 elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
1109 hit_data, sym_sec, offset, addend, val)
1110
1111 struct bfd_link_info *info;
1112 char *name;
1113 bfd *input_bfd;
1114 bfd *output_bfd;
1115 asection *input_section;
1116 bfd_byte *hit_data;
1117 asection *sym_sec;
1118 int offset;
1119 int addend;
1120 bfd_vma val;
1121 {
1122 /* Arm code calling a Thumb function */
1123 unsigned long int tmp;
1124 long int my_offset;
1125 asection *s;
1126 long int ret_offset;
1127 struct elf_link_hash_entry *myh;
1128 struct elf32_arm_link_hash_table *globals;
1129
1130 myh = find_arm_glue (info, name, input_bfd);
1131 if (myh == NULL)
1132 return false;
1133
1134 globals = elf32_arm_hash_table (info);
1135
1136 BFD_ASSERT (globals != NULL);
1137 BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1138
1139 my_offset = myh->root.u.def.value;
1140 s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1141 ARM2THUMB_GLUE_SECTION_NAME);
1142 BFD_ASSERT (s != NULL);
1143 BFD_ASSERT (s->contents != NULL);
1144 BFD_ASSERT (s->output_section != NULL);
1145
1146 if ((my_offset & 0x01) == 0x01)
1147 {
1148
1149 if (sym_sec->owner != NULL
1150 && !INTERWORK_FLAG (sym_sec->owner))
1151 {
1152 _bfd_error_handler
1153 (_ ("%s(%s): warning: interworking not enabled."),
1154 bfd_get_filename (sym_sec->owner), name);
1155 _bfd_error_handler
1156 (_ (" first occurrence: %s: arm call to thumb"),
1157 bfd_get_filename (input_bfd));
1158 }
1159 --my_offset;
1160 myh->root.u.def.value = my_offset;
1161
1162 bfd_put_32 (output_bfd, a2t1_ldr_insn,
1163 s->contents + my_offset);
1164
1165 bfd_put_32 (output_bfd, a2t2_bx_r12_insn,
1166 s->contents + my_offset + 4);
1167
1168 /* It's a thumb address. Add the low order bit. */
1169 bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
1170 s->contents + my_offset + 8);
1171 }
1172
1173 BFD_ASSERT (my_offset <= globals->arm_glue_size);
1174
1175 tmp = bfd_get_32 (input_bfd, hit_data);
1176 tmp = tmp & 0xFF000000;
1177
1178 /* Somehow these are both 4 too far, so subtract 8. */
1179 ret_offset = s->output_offset
1180 + my_offset
1181 + s->output_section->vma
1182 - (input_section->output_offset
1183 + input_section->output_section->vma
1184 + offset + addend)
1185 - 8;
1186
1187 tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1188
1189 bfd_put_32 (output_bfd, tmp, hit_data
1190 - input_section->vma);
1191
1192 }
1193 /* Perform a relocation as part of a final link. */
1194 static bfd_reloc_status_type
1195 elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1196 input_section, contents, offset, value,
1197 addend, info, sym_sec, sym_name, sym_flags)
1198 reloc_howto_type *howto;
1199 bfd *input_bfd;
1200 bfd *output_bfd;
1201 asection *input_section;
1202 bfd_byte *contents;
1203 bfd_vma offset;
1204 bfd_vma value;
1205 bfd_vma addend;
1206 struct bfd_link_info *info;
1207 asection *sym_sec;
1208 char *sym_name;
1209 unsigned char sym_flags;
1210 {
1211 unsigned long r_type = howto->type;
1212 bfd_byte *hit_data = contents + offset;
1213
1214 switch (r_type)
1215 {
1216
1217 case R_ARM_NONE:
1218 return bfd_reloc_ok;
1219
1220 case R_ARM_PC24:
1221 /* Arm B/BL instruction */
1222
1223 /* check for arm calling thumb function */
1224 if (sym_flags == C_THUMBSTATFUNC
1225 || sym_flags == C_THUMBEXTFUNC)
1226 {
1227 elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
1228 input_section, hit_data, sym_sec, offset, addend, value);
1229 return bfd_reloc_ok;
1230 }
1231
1232 value = value + addend;
1233 value -= (input_section->output_section->vma
1234 + input_section->output_offset + 8);
1235 value -= offset;
1236 value = value >> howto->rightshift;
1237
1238 value &= 0xffffff;
1239 value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
1240 bfd_put_32 (input_bfd, value, hit_data);
1241 return bfd_reloc_ok;
1242
1243 case R_ARM_ABS32:
1244 value += addend;
1245 if (sym_flags == C_THUMBSTATFUNC
1246 || sym_flags == C_THUMBEXTFUNC)
1247 value |= 1;
1248 bfd_put_32 (input_bfd, value, hit_data);
1249 return bfd_reloc_ok;
1250
1251 case R_ARM_REL32:
1252 value -= (input_section->output_section->vma
1253 + input_section->output_offset);
1254 value += addend;
1255
1256 bfd_put_32 (input_bfd, value, hit_data);
1257 return bfd_reloc_ok;
1258
1259 case R_ARM_ABS8:
1260 value += addend;
1261
1262 if ((long) value > 0x7f || (long) value < -0x80)
1263 return bfd_reloc_overflow;
1264
1265 bfd_put_8 (input_bfd, value, hit_data);
1266 return bfd_reloc_ok;
1267
1268 case R_ARM_ABS16:
1269 value += addend;
1270
1271 if ((long) value > 0x7fff || (long) value < -0x8000)
1272 return bfd_reloc_overflow;
1273
1274 bfd_put_16 (input_bfd, value, hit_data);
1275 return bfd_reloc_ok;
1276
1277 case R_ARM_ABS12:
1278 /* Support ldr and str instruction for the arm */
1279 /* Also thumb b (unconditional branch) */
1280 value += addend;
1281
1282 if ((long) value > 0x7ff || (long) value < -0x800)
1283 return bfd_reloc_overflow;
1284
1285 value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
1286 bfd_put_32 (input_bfd, value, hit_data);
1287 return bfd_reloc_ok;
1288
1289 case R_ARM_THM_ABS5:
1290 /* Support ldr and str instructions for the thumb. */
1291 value += addend;
1292
1293 if ((long) value > 0x1f || (long) value < -0x10)
1294 return bfd_reloc_overflow;
1295
1296 value |= bfd_get_16 (input_bfd, hit_data) & 0xf82f;
1297 bfd_put_16 (input_bfd, value, hit_data);
1298 return bfd_reloc_ok;
1299
1300
1301 case R_ARM_THM_PC22:
1302 /* thumb BL (branch long instruction). */
1303 {
1304 bfd_vma relocation;
1305 boolean overflow = false;
1306 bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
1307 bfd_vma src_mask = 0x007FFFFE;
1308 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1309 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1310 bfd_vma check;
1311 bfd_signed_vma signed_check;
1312 bfd_vma add;
1313 bfd_signed_vma signed_add;
1314
1315 if (sym_flags == C_EXT
1316 || sym_flags == C_STAT
1317 || sym_flags == C_LABEL)
1318 {
1319 elf32_thumb_to_arm_stub (info, sym_name, input_bfd, output_bfd, input_section,
1320 hit_data, sym_sec, offset, addend, value);
1321 return bfd_reloc_ok;
1322 }
1323
1324 relocation = value + addend;
1325 relocation -= (input_section->output_section->vma + input_section->output_offset);
1326 relocation -= offset;
1327
1328 check = relocation >> howto->rightshift;
1329
1330 /* If this is a signed value, the rightshift just dropped
1331 leading 1 bits (assuming twos complement). */
1332 if ((bfd_signed_vma) relocation >= 0)
1333 signed_check = check;
1334 else
1335 signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
1336
1337 /* Get the value from the object file. */
1338 if (bfd_big_endian (input_bfd))
1339 add = (((insn) & 0x07ff0000) >> 4) | (((insn) & 0x7ff) << 1);
1340 else
1341 add = ((((insn) & 0x7ff) << 12) | (((insn) & 0x07ff0000) >> 15));
1342
1343 /* Get the value from the object file with an appropriate sign.
1344 The expression involving howto->src_mask isolates the upper
1345 bit of src_mask. If that bit is set in the value we are
1346 adding, it is negative, and we subtract out that number times
1347 two. If src_mask includes the highest possible bit, then we
1348 can not get the upper bit, but that does not matter since
1349 signed_add needs no adjustment to become negative in that case. */
1350
1351 signed_add = add;
1352
1353 if ((add & (((~src_mask) >> 1) & src_mask)) != 0)
1354 signed_add -= (((~src_mask) >> 1) & src_mask) << 1;
1355
1356 /* Add the value from the object file, shifted so that it is a
1357 straight number. */
1358 /* howto->bitpos == 0 */
1359
1360 signed_check += signed_add;
1361 relocation += signed_add;
1362
1363 /* Assumes two's complement. */
1364 if (signed_check > reloc_signed_max
1365 || signed_check < reloc_signed_min)
1366 overflow = true;
1367
1368 /* Put RELOCATION into the correct bits: */
1369
1370 if (bfd_big_endian (input_bfd))
1371 relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1372 else
1373 relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1374
1375 /* Add RELOCATION to the correct bits of X: */
1376 insn = ((insn & ~howto->dst_mask) | relocation);
1377
1378 /* Put the relocated value back in the object file: */
1379 bfd_put_32 (input_bfd, insn, hit_data);
1380
1381 return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
1382 }
1383 break;
1384
1385 case R_ARM_SBREL32:
1386 return bfd_reloc_notsupported;
1387
1388 case R_ARM_AMP_VCALL9:
1389 return bfd_reloc_notsupported;
1390
1391 case R_ARM_RSBREL32:
1392 return bfd_reloc_notsupported;
1393
1394 case R_ARM_THM_RPC22:
1395 return bfd_reloc_notsupported;
1396
1397 case R_ARM_RREL32:
1398 return bfd_reloc_notsupported;
1399
1400 case R_ARM_RABS32:
1401 return bfd_reloc_notsupported;
1402
1403 case R_ARM_RPC24:
1404 return bfd_reloc_notsupported;
1405
1406 case R_ARM_RBASE:
1407 return bfd_reloc_notsupported;
1408
1409 default:
1410 return bfd_reloc_notsupported;
1411 }
1412 }
1413 /* Relocate an ARM ELF section. */
1414 static boolean
1415 elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1416 contents, relocs, local_syms, local_sections)
1417 bfd *output_bfd;
1418 struct bfd_link_info *info;
1419 bfd *input_bfd;
1420 asection *input_section;
1421 bfd_byte *contents;
1422 Elf_Internal_Rela *relocs;
1423 Elf_Internal_Sym *local_syms;
1424 asection **local_sections;
1425 {
1426 Elf_Internal_Shdr *symtab_hdr;
1427 struct elf_link_hash_entry **sym_hashes;
1428 Elf_Internal_Rela *rel, *relend;
1429
1430 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1431 sym_hashes = elf_sym_hashes (input_bfd);
1432
1433 rel = relocs;
1434 relend = relocs + input_section->reloc_count;
1435 for (; rel < relend; rel++)
1436 {
1437 int r_type;
1438 reloc_howto_type *howto;
1439 unsigned long r_symndx;
1440 Elf_Internal_Sym *sym;
1441 asection *sec;
1442 struct elf_link_hash_entry *h;
1443 bfd_vma relocation;
1444 bfd_reloc_status_type r;
1445
1446 r_symndx = ELF32_R_SYM (rel->r_info);
1447 r_type = ELF32_R_TYPE (rel->r_info);
1448 howto = elf32_arm_howto_table + r_type;
1449
1450 if (info->relocateable)
1451 {
1452 /* This is a relocateable link. We don't have to change
1453 anything, unless the reloc is against a section symbol,
1454 in which case we have to adjust according to where the
1455 section symbol winds up in the output section. */
1456 if (r_symndx < symtab_hdr->sh_info)
1457 {
1458 sym = local_syms + r_symndx;
1459 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1460 {
1461 sec = local_sections[r_symndx];
1462 rel->r_addend += sec->output_offset + sym->st_value;
1463 }
1464 }
1465
1466 continue;
1467 }
1468
1469 /* This is a final link. */
1470 h = NULL;
1471 sym = NULL;
1472 sec = NULL;
1473 if (r_symndx < symtab_hdr->sh_info)
1474 {
1475 sym = local_syms + r_symndx;
1476 sec = local_sections[r_symndx];
1477 relocation = (sec->output_section->vma
1478 + sec->output_offset
1479 + sym->st_value);
1480 }
1481 else
1482 {
1483 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1484 while (h->root.type == bfd_link_hash_indirect
1485 || h->root.type == bfd_link_hash_warning)
1486 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1487 if (h->root.type == bfd_link_hash_defined
1488 || h->root.type == bfd_link_hash_defweak)
1489 {
1490 sec = h->root.u.def.section;
1491 relocation = (h->root.u.def.value
1492 + sec->output_section->vma
1493 + sec->output_offset);
1494 }
1495 else if (h->root.type == bfd_link_hash_undefweak)
1496 relocation = 0;
1497 else
1498 {
1499 if (!((*info->callbacks->undefined_symbol)
1500 (info, h->root.root.string, input_bfd,
1501 input_section, rel->r_offset)))
1502 return false;
1503 relocation = 0;
1504 }
1505 }
1506
1507 r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1508 input_section,
1509 contents, rel->r_offset,
1510 relocation, rel->r_addend,
1511 info, sec, (h ? h->root.root.string : 0),
1512 (h ? h->other : sym->st_other));
1513
1514
1515 if (r != bfd_reloc_ok)
1516 {
1517 const char *name;
1518 const char *msg = (const char *) 0;
1519
1520 if (h != NULL)
1521 name = h->root.root.string;
1522 else
1523 {
1524 name = (bfd_elf_string_from_elf_section
1525 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1526 if (name == NULL || *name == '\0')
1527 name = bfd_section_name (input_bfd, sec);
1528 }
1529
1530 switch (r)
1531 {
1532 case bfd_reloc_overflow:
1533 if (!((*info->callbacks->reloc_overflow)
1534 (info, name, howto->name, (bfd_vma) 0,
1535 input_bfd, input_section, rel->r_offset)))
1536 return false;
1537 break;
1538
1539 case bfd_reloc_undefined:
1540 if (!((*info->callbacks->undefined_symbol)
1541 (info, name, input_bfd, input_section,
1542 rel->r_offset)))
1543 return false;
1544 break;
1545
1546 case bfd_reloc_outofrange:
1547 msg = _ ("internal error: out of range error");
1548 goto common_error;
1549
1550 case bfd_reloc_notsupported:
1551 msg = _ ("internal error: unsupported relocation error");
1552 goto common_error;
1553
1554 case bfd_reloc_dangerous:
1555 msg = _ ("internal error: dangerous error");
1556 goto common_error;
1557
1558 default:
1559 msg = _ ("internal error: unknown error");
1560 /* fall through */
1561
1562 common_error:
1563 if (!((*info->callbacks->warning)
1564 (info, msg, name, input_bfd, input_section,
1565 rel->r_offset)))
1566 return false;
1567 break;
1568 }
1569 }
1570 }
1571
1572 return true;
1573 }
1574
1575 /* Function to keep ARM specific flags in the ELF header. */
1576 static boolean
1577 elf32_arm_set_private_flags (abfd, flags)
1578 bfd *abfd;
1579 flagword flags;
1580 {
1581 if (elf_flags_init (abfd)
1582 && elf_elfheader (abfd)->e_flags != flags)
1583 {
1584 if (flags & EF_INTERWORK)
1585 _bfd_error_handler (_ ("\
1586 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
1587 bfd_get_filename (abfd));
1588 else
1589 _bfd_error_handler (_ ("\
1590 Warning: Clearing the interwork flag of %s due to outside request"),
1591 bfd_get_filename (abfd));
1592 }
1593 else
1594 {
1595 elf_elfheader (abfd)->e_flags = flags;
1596 elf_flags_init (abfd) = true;
1597 }
1598
1599 return true;
1600 }
1601
1602 /* Copy backend specific data from one object module to another */
1603 static boolean
1604 elf32_arm_copy_private_bfd_data (ibfd, obfd)
1605 bfd *ibfd;
1606 bfd *obfd;
1607 {
1608 flagword in_flags;
1609 flagword out_flags;
1610
1611 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1612 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1613 return true;
1614
1615 in_flags = elf_elfheader (ibfd)->e_flags;
1616 out_flags = elf_elfheader (obfd)->e_flags;
1617
1618 if (elf_flags_init (obfd) && in_flags != out_flags)
1619 {
1620 /* Cannot mix PIC and non-PIC code. */
1621 if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1622 return false;
1623
1624 /* Cannot mix APCS26 and APCS32 code. */
1625 if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1626 return false;
1627
1628 /* Cannot mix float APCS and non-float APCS code. */
1629 if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1630 return false;
1631
1632 /* If the src and dest have different interworking flags
1633 then turn off the interworking bit. */
1634 if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1635 {
1636 if (out_flags & EF_INTERWORK)
1637 _bfd_error_handler (_ ("\
1638 Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
1639 bfd_get_filename (obfd), bfd_get_filename (ibfd));
1640
1641 in_flags &= ~EF_INTERWORK;
1642 }
1643 }
1644
1645 elf_elfheader (obfd)->e_flags = in_flags;
1646 elf_flags_init (obfd) = true;
1647
1648 return true;
1649 }
1650
1651 /* Merge backend specific data from an object file to the output
1652 object file when linking. */
1653 static boolean
1654 elf32_arm_merge_private_bfd_data (ibfd, obfd)
1655 bfd *ibfd;
1656 bfd *obfd;
1657 {
1658 flagword out_flags;
1659 flagword in_flags;
1660
1661 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1662 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1663 return true;
1664
1665 /* The input BFD must have had its flags initialised. */
1666 /* The following seems bogus to me -- The flags are initialized in
1667 the assembler but I don't think an elf_flags_init field is
1668 written into the object */
1669 /* BFD_ASSERT (elf_flags_init (ibfd)); */
1670
1671 in_flags = elf_elfheader (ibfd)->e_flags;
1672 out_flags = elf_elfheader (obfd)->e_flags;
1673
1674 if (!elf_flags_init (obfd))
1675 {
1676 /* If the input is the default architecture then do not
1677 bother setting the flags for the output architecture,
1678 instead allow future merges to do this. If no future
1679 merges ever set these flags then they will retain their
1680 unitialised values, which surprise surprise, correspond
1681 to the default values. */
1682 if (bfd_get_arch_info (ibfd)->the_default)
1683 return true;
1684
1685 elf_flags_init (obfd) = true;
1686 elf_elfheader (obfd)->e_flags = in_flags;
1687
1688 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1689 && bfd_get_arch_info (obfd)->the_default)
1690 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1691
1692 return true;
1693 }
1694
1695 /* Check flag compatibility. */
1696 if (in_flags == out_flags)
1697 return true;
1698
1699 /* Complain about various flag mismatches. */
1700
1701 if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1702 _bfd_error_handler (_ ("\
1703 Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
1704 bfd_get_filename (ibfd),
1705 in_flags & EF_APCS_26 ? 26 : 32,
1706 bfd_get_filename (obfd),
1707 out_flags & EF_APCS_26 ? 26 : 32);
1708
1709 if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1710 _bfd_error_handler (_ ("\
1711 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
1712 bfd_get_filename (ibfd),
1713 in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
1714 bfd_get_filename (obfd),
1715 out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
1716
1717 if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1718 _bfd_error_handler (_ ("\
1719 Error: %s is compiled as position %s code, whereas %s is not"),
1720 bfd_get_filename (ibfd),
1721 in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
1722 bfd_get_filename (obfd));
1723
1724 /* Interworking mismatch is only a warning. */
1725 if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1726 {
1727 _bfd_error_handler (_ ("\
1728 Warning: %s %s interworking, whereas %s %s"),
1729 bfd_get_filename (ibfd),
1730 in_flags & EF_INTERWORK ? _ ("supports") : _ ("does not support"),
1731 bfd_get_filename (obfd),
1732 out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
1733 return true;
1734 }
1735
1736 return false;
1737 }
1738
1739 /* Display the flags field */
1740 static boolean
1741 elf32_arm_print_private_bfd_data (abfd, ptr)
1742 bfd *abfd;
1743 PTR ptr;
1744 {
1745 FILE *file = (FILE *) ptr;
1746
1747 BFD_ASSERT (abfd != NULL && ptr != NULL);
1748
1749 /* Print normal ELF private data. */
1750 _bfd_elf_print_private_bfd_data (abfd, ptr);
1751
1752 /* Ignore init flag - it may not be set, despite the flags field containing valid data. */
1753
1754 /* xgettext:c-format */
1755 fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1756
1757 if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
1758 fprintf (file, _ (" [interworking enabled]"));
1759 else
1760 fprintf (file, _ (" [interworking not enabled]"));
1761
1762 if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
1763 fprintf (file, _ (" [APCS-26]"));
1764 else
1765 fprintf (file, _ (" [APCS-32]"));
1766
1767 if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
1768 fprintf (file, _ (" [floats passed in float registers]"));
1769 else
1770 fprintf (file, _ (" [floats passed in integer registers]"));
1771
1772 if (elf_elfheader (abfd)->e_flags & EF_PIC)
1773 fprintf (file, _ (" [position independent]"));
1774 else
1775 fprintf (file, _ (" [absolute position]"));
1776
1777 fputc ('\n', file);
1778
1779 return true;
1780 }
1781
1782
1783 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec
1784 #define TARGET_LITTLE_NAME "elf32-littlearm"
1785 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec
1786 #define TARGET_BIG_NAME "elf32-bigarm"
1787 #define ELF_ARCH bfd_arch_arm
1788 #define ELF_MACHINE_CODE EM_ARM
1789
1790 #define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
1791 #define elf_info_to_howto elf32_arm_info_to_howto
1792 #define elf_info_to_howto_rel 0
1793 #define elf_backend_relocate_section elf32_arm_relocate_section
1794 #define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
1795 #define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
1796 #define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags
1797 #define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data
1798 #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
1799
1800 #define elf_symbol_leading_char '_'
1801
1802 #include "elf32-target.h"
1803 /* end-sanitize-armelf */
This page took 0.089537 seconds and 5 git commands to generate.