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