70000bd3b09c3039c8ff4981150e252700f1b384
[deliverable/binutils-gdb.git] / bfd / elf32-arm.c
1 /* 32-bit ELF support for ARM
2 Copyright 1993, 1995, 1998 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
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.
10
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.
15
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. */
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
27 typedef unsigned long int insn32;
28 typedef unsigned short int insn16;
29
30 static reloc_howto_type *elf32_arm_reloc_type_lookup
31 PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
32 static void elf32_arm_info_to_howto
33 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
34 static boolean elf32_arm_set_private_flags
35 PARAMS ((bfd *, flagword));
36 static boolean elf32_arm_copy_private_bfd_data
37 PARAMS ((bfd *, bfd *));
38 static boolean elf32_arm_merge_private_bfd_data
39 PARAMS ((bfd *, bfd *));
40 static boolean elf32_arm_print_private_bfd_data
41 PARAMS ((bfd *, PTR));
42 static int elf32_arm_get_symbol_type
43 PARAMS (( Elf_Internal_Sym *, int));
44 static struct bfd_link_hash_table *elf32_arm_link_hash_table_create
45 PARAMS ((bfd *));
46
47
48 static insn32 insert_thumb_branch
49 PARAMS ((insn32, int));
50 static struct elf_link_hash_entry *find_thumb_glue
51 PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
52 static struct elf_link_hash_entry *find_arm_glue
53 PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
54 static void record_arm_to_thumb_glue
55 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
56 static void record_thumb_to_arm_glue
57 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
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 */
78 struct 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
98 static struct bfd_link_hash_table *
99 elf32_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
123 static struct elf_link_hash_entry *
124 find_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
157 static struct elf_link_hash_entry *
158 find_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
202 static const insn32 a2t1_ldr_insn = 0xe59fc000;
203 static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
204 static const insn32 a2t3_func_addr_insn = 0x00000001;
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
225 static const insn16 t2a1_bx_pc_insn = 0x4778;
226 static const insn16 t2a2_noop_insn = 0x46c0;
227 static const insn32 t2a3_b_insn = 0xea000000;
228
229 static const insn16 t2a1_push_insn = 0xb540;
230 static const insn16 t2a2_ldr_insn = 0x4e03;
231 static const insn16 t2a3_mov_insn = 0x46fe;
232 static const insn16 t2a4_bx_insn = 0x4730;
233 static const insn32 t2a5_pop_insn = 0xe8bd4040;
234 static const insn32 t2a6_bx_insn = 0xe12fff1e;
235
236 boolean
237 bfd_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
283 static void
284 record_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
338 static void
339 record_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;
348 char bind;
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. */
381 bind = ELF_ST_BIND (myh->type);
382 myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC);
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 */
414 boolean
415 bfd_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
469 boolean
470 bfd_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
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 {
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
515 BFD_ASSERT (irel != 0);
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
600 if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC)
601 record_arm_to_thumb_glue (link_info, h);
602 break;
603
604 case R_ARM_THM_PC22:
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. */
608
609 if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC)
610 record_thumb_to_arm_glue (link_info, h);
611 break;
612
613 default:
614 break;
615 }
616 }
617 }
618
619 return true;
620 error_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 }
630
631 #define USE_RELA
632 #define TARGET_UNDERSCORE '_'
633
634 static reloc_howto_type elf32_arm_howto_table[] =
635 {
636 /* No relocation */
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 */
664
665 /* 32 bit absolute */
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 */
679
680 /* standard 32bit pc-relative reloc */
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 */
694
695 /* 8 bit absolute */
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 */
709
710 /* 16 bit absolute */
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 */
724
725 /* 12 bit absolute */
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 */
795
796 /* 12 bit pc relative */
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 */
810
811 /* 12 bit pc relative */
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 */
825
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
856
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 */
912
913 };
914 struct elf32_arm_reloc_map
915 {
916 unsigned char bfd_reloc_val;
917 unsigned char elf_reloc_val;
918 };
919
920 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
921 {
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,},
931 {BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT },
932 {BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY },
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,}
937 };
938
939 static reloc_howto_type *
940 elf32_arm_reloc_type_lookup (abfd, code)
941 bfd *abfd;
942 bfd_reloc_code_real_type code;
943 {
944 unsigned int i;
945
946 for (i = 0;
947 i < sizeof (elf32_arm_reloc_map) / sizeof (struct elf32_arm_reloc_map);
948 i++)
949 {
950 if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
951 return &elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
952 }
953
954 return NULL;
955 }
956
957 static void
958 elf32_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
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
1002 static insn32
1003 insert_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 }
1028
1029 /* Thumb code calling an ARM function */
1030 int
1031 elf32_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 {
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 {
1071 if (sym_sec != NULL
1072 && sym_sec->owner != NULL
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));
1081
1082 return false;
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);
1125
1126 return true;
1127 }
1128
1129 /* Arm code calling a Thumb function */
1130 int
1131 elf32_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 {
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 {
1170 if (sym_sec != NULL
1171 && sym_sec->owner != NULL
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
1214
1215 return true;
1216 }
1217
1218 /* Perform a relocation as part of a final link. */
1219 static bfd_reloc_status_type
1220 elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1221 input_section, contents, offset, value,
1222 addend, info, sym_sec, sym_name, sym_flags)
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;
1233 const char *sym_name;
1234 unsigned char sym_flags;
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:
1246 /* Arm B/BL instruction */
1247
1248 /* check for arm calling thumb function */
1249 if (sym_flags == STT_ARM_TFUNC)
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;
1261
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;
1269 if (sym_flags == STT_ARM_TFUNC)
1270 value |= 1;
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
1276 + input_section->output_offset);
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;
1284
1285 if ((long) value > 0x7f || (long) value < -0x80)
1286 return bfd_reloc_overflow;
1287
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)
1295 return bfd_reloc_overflow;
1296
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)
1306 return bfd_reloc_overflow;
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)
1317 return bfd_reloc_overflow;
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;
1322
1323
1324 case R_ARM_THM_PC22:
1325 /* thumb BL (branch long instruction). */
1326 {
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
1338 /* If it's not a call to thumb, assume call to arm */
1339 if (sym_flags != STT_ARM_TFUNC)
1340 {
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;
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);
1407 }
1408 break;
1409
1410 case R_ARM_GNU_VTINHERIT:
1411 case R_ARM_GNU_VTENTRY:
1412 return bfd_reloc_ok;
1413
1414 case R_ARM_SBREL32:
1415 return bfd_reloc_notsupported;
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 }
1442
1443
1444 /* Relocate an ARM ELF section. */
1445 static boolean
1446 elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1447 contents, relocs, local_syms, local_sections)
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;
1460 const char *name;
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);
1480
1481 if (r_type == R_ARM_GNU_VTENTRY
1482 || r_type == R_ARM_GNU_VTINHERIT )
1483 continue;
1484
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
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. */
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 {
1536 if (!((*info->callbacks->undefined_symbol)
1537 (info, h->root.root.string, input_bfd,
1538 input_section, rel->r_offset)))
1539 return false;
1540 relocation = 0;
1541 }
1542 }
1543
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
1554 r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1555 input_section,
1556 contents, rel->r_offset,
1557 relocation, rel->r_addend,
1558 info, sec, name,
1559 (h ? ELF_ST_TYPE (h->type) :
1560 ELF_ST_TYPE (sym->st_info)));
1561
1562 if (r != bfd_reloc_ok)
1563 {
1564 const char * msg = (const char *) 0;
1565
1566 switch (r)
1567 {
1568 case bfd_reloc_overflow:
1569 if (!((*info->callbacks->reloc_overflow)
1570 (info, name, howto->name, (bfd_vma) 0,
1571 input_bfd, input_section, rel->r_offset)))
1572 return false;
1573 break;
1574
1575 case bfd_reloc_undefined:
1576 if (!((*info->callbacks->undefined_symbol)
1577 (info, name, input_bfd, input_section,
1578 rel->r_offset)))
1579 return false;
1580 break;
1581
1582 case bfd_reloc_outofrange:
1583 msg = _ ("internal error: out of range error");
1584 goto common_error;
1585
1586 case bfd_reloc_notsupported:
1587 msg = _ ("internal error: unsupported relocation error");
1588 goto common_error;
1589
1590 case bfd_reloc_dangerous:
1591 msg = _ ("internal error: dangerous error");
1592 goto common_error;
1593
1594 default:
1595 msg = _ ("internal error: unknown error");
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
1611 /* Function to keep ARM specific flags in the ELF header. */
1612 static boolean
1613 elf32_arm_set_private_flags (abfd, flags)
1614 bfd *abfd;
1615 flagword flags;
1616 {
1617 if (elf_flags_init (abfd)
1618 && elf_elfheader (abfd)->e_flags != flags)
1619 {
1620 if (flags & EF_INTERWORK)
1621 _bfd_error_handler (_ ("\
1622 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
1623 bfd_get_filename (abfd));
1624 else
1625 _bfd_error_handler (_ ("\
1626 Warning: Clearing the interwork flag of %s due to outside request"),
1627 bfd_get_filename (abfd));
1628 }
1629 else
1630 {
1631 elf_elfheader (abfd)->e_flags = flags;
1632 elf_flags_init (abfd) = true;
1633 }
1634
1635 return true;
1636 }
1637
1638 /* Copy backend specific data from one object module to another */
1639 static boolean
1640 elf32_arm_copy_private_bfd_data (ibfd, obfd)
1641 bfd *ibfd;
1642 bfd *obfd;
1643 {
1644 flagword in_flags;
1645 flagword out_flags;
1646
1647 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1648 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1649 return true;
1650
1651 in_flags = elf_elfheader (ibfd)->e_flags;
1652 out_flags = elf_elfheader (obfd)->e_flags;
1653
1654 if (elf_flags_init (obfd) && in_flags != out_flags)
1655 {
1656 /* Cannot mix PIC and non-PIC code. */
1657 if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1658 return false;
1659
1660 /* Cannot mix APCS26 and APCS32 code. */
1661 if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1662 return false;
1663
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
1669 then turn off the interworking bit. */
1670 if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1671 {
1672 if (out_flags & EF_INTERWORK)
1673 _bfd_error_handler (_ ("\
1674 Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
1675 bfd_get_filename (obfd), bfd_get_filename (ibfd));
1676
1677 in_flags &= ~EF_INTERWORK;
1678 }
1679 }
1680
1681 elf_elfheader (obfd)->e_flags = in_flags;
1682 elf_flags_init (obfd) = true;
1683
1684 return true;
1685 }
1686
1687 /* Merge backend specific data from an object file to the output
1688 object file when linking. */
1689 static boolean
1690 elf32_arm_merge_private_bfd_data (ibfd, obfd)
1691 bfd *ibfd;
1692 bfd *obfd;
1693 {
1694 flagword out_flags;
1695 flagword in_flags;
1696
1697 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1698 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1699 return true;
1700
1701 /* The input BFD must have had its flags initialised. */
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)); */
1706
1707 in_flags = elf_elfheader (ibfd)->e_flags;
1708 out_flags = elf_elfheader (obfd)->e_flags;
1709
1710 if (!elf_flags_init (obfd))
1711 {
1712 /* If the input is the default architecture then do not
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. */
1718 if (bfd_get_arch_info (ibfd)->the_default)
1719 return true;
1720
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. */
1736
1737 if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1738 _bfd_error_handler (_ ("\
1739 Error: %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);
1744
1745 if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1746 _bfd_error_handler (_ ("\
1747 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
1748 bfd_get_filename (ibfd),
1749 in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
1750 bfd_get_filename (obfd),
1751 out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
1752
1753 if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1754 _bfd_error_handler (_ ("\
1755 Error: %s is compiled as position %s code, whereas %s is not"),
1756 bfd_get_filename (ibfd),
1757 in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
1758 bfd_get_filename (obfd));
1759
1760 /* Interworking mismatch is only a warning. */
1761 if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1762 {
1763 _bfd_error_handler (_ ("\
1764 Warning: %s %s interworking, whereas %s %s"),
1765 bfd_get_filename (ibfd),
1766 in_flags & EF_INTERWORK ? _ ("supports") : _ ("does not support"),
1767 bfd_get_filename (obfd),
1768 out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
1769 return true;
1770 }
1771
1772 return false;
1773 }
1774
1775 /* Display the flags field */
1776 static boolean
1777 elf32_arm_print_private_bfd_data (abfd, ptr)
1778 bfd *abfd;
1779 PTR ptr;
1780 {
1781 FILE *file = (FILE *) ptr;
1782
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. */
1789
1790 /* xgettext:c-format */
1791 fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1792
1793 if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
1794 fprintf (file, _ (" [interworking enabled]"));
1795 else
1796 fprintf (file, _ (" [interworking not enabled]"));
1797
1798 if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
1799 fprintf (file, _ (" [APCS-26]"));
1800 else
1801 fprintf (file, _ (" [APCS-32]"));
1802
1803 if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
1804 fprintf (file, _ (" [floats passed in float registers]"));
1805 else
1806 fprintf (file, _ (" [floats passed in integer registers]"));
1807
1808 if (elf_elfheader (abfd)->e_flags & EF_PIC)
1809 fprintf (file, _ (" [position independent]"));
1810 else
1811 fprintf (file, _ (" [absolute position]"));
1812
1813 fputc ('\n', file);
1814
1815 return true;
1816 }
1817
1818 static int
1819 elf32_arm_get_symbol_type (elf_sym, type)
1820 Elf_Internal_Sym * elf_sym;
1821 int type;
1822 {
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;
1827 }
1828
1829 static asection *
1830 elf32_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 }
1870
1871 static boolean
1872 elf32_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 }
1881
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
1886 static boolean
1887 elf32_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 }
1939
1940
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
1945 boolean
1946 elf32_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
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
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
2039 #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
2040 #define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
2041 #define elf_backend_get_symbol_type elf32_arm_get_symbol_type
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
2047 #define elf_symbol_leading_char '_'
2048
2049 #include "elf32-target.h"
This page took 0.076552 seconds and 4 git commands to generate.