1 /* BFD back-end for National Semiconductor's CRX ELF
2 Copyright (C) 2004-2016 Free Software Foundation, Inc.
3 Written by Tomer Levi, NSC, Israel.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
29 static reloc_howto_type *elf_crx_reloc_type_lookup
30 (bfd *, bfd_reloc_code_real_type);
31 static void elf_crx_info_to_howto
32 (bfd *, arelent *, Elf_Internal_Rela *);
33 static bfd_boolean elf32_crx_relax_delete_bytes
34 (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
35 static bfd_reloc_status_type crx_elf_final_link_relocate
36 (reloc_howto_type *, bfd *, bfd *, asection *,
37 bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
38 struct bfd_link_info *, asection *, int);
39 static bfd_boolean elf32_crx_relocate_section
40 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
41 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
42 static bfd_boolean elf32_crx_relax_section
43 (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
44 static bfd_byte * elf32_crx_get_relocated_section_contents
45 (bfd *, struct bfd_link_info *, struct bfd_link_order *,
46 bfd_byte *, bfd_boolean, asymbol **);
48 /* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
52 bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */
53 unsigned short crx_reloc_type; /* CRX relocation type. */
56 static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
58 {BFD_RELOC_NONE, R_CRX_NONE},
59 {BFD_RELOC_CRX_REL4, R_CRX_REL4},
60 {BFD_RELOC_CRX_REL8, R_CRX_REL8},
61 {BFD_RELOC_CRX_REL8_CMP, R_CRX_REL8_CMP},
62 {BFD_RELOC_CRX_REL16, R_CRX_REL16},
63 {BFD_RELOC_CRX_REL24, R_CRX_REL24},
64 {BFD_RELOC_CRX_REL32, R_CRX_REL32},
65 {BFD_RELOC_CRX_REGREL12, R_CRX_REGREL12},
66 {BFD_RELOC_CRX_REGREL22, R_CRX_REGREL22},
67 {BFD_RELOC_CRX_REGREL28, R_CRX_REGREL28},
68 {BFD_RELOC_CRX_REGREL32, R_CRX_REGREL32},
69 {BFD_RELOC_CRX_ABS16, R_CRX_ABS16},
70 {BFD_RELOC_CRX_ABS32, R_CRX_ABS32},
71 {BFD_RELOC_CRX_NUM8, R_CRX_NUM8},
72 {BFD_RELOC_CRX_NUM16, R_CRX_NUM16},
73 {BFD_RELOC_CRX_NUM32, R_CRX_NUM32},
74 {BFD_RELOC_CRX_IMM16, R_CRX_IMM16},
75 {BFD_RELOC_CRX_IMM32, R_CRX_IMM32},
76 {BFD_RELOC_CRX_SWITCH8, R_CRX_SWITCH8},
77 {BFD_RELOC_CRX_SWITCH16, R_CRX_SWITCH16},
78 {BFD_RELOC_CRX_SWITCH32, R_CRX_SWITCH32}
81 static reloc_howto_type crx_elf_howto_table[] =
83 HOWTO (R_CRX_NONE, /* type */
87 FALSE, /* pc_relative */
89 complain_overflow_dont,/* complain_on_overflow */
90 bfd_elf_generic_reloc, /* special_function */
91 "R_CRX_NONE", /* name */
92 FALSE, /* partial_inplace */
95 FALSE), /* pcrel_offset */
97 HOWTO (R_CRX_REL4, /* type */
101 TRUE, /* pc_relative */
103 complain_overflow_bitfield,/* complain_on_overflow */
104 bfd_elf_generic_reloc, /* special_function */
105 "R_CRX_REL4", /* name */
106 FALSE, /* partial_inplace */
109 FALSE), /* pcrel_offset */
111 HOWTO (R_CRX_REL8, /* type */
115 TRUE, /* pc_relative */
117 complain_overflow_bitfield,/* complain_on_overflow */
118 bfd_elf_generic_reloc, /* special_function */
119 "R_CRX_REL8", /* name */
120 FALSE, /* partial_inplace */
123 FALSE), /* pcrel_offset */
125 HOWTO (R_CRX_REL8_CMP, /* type */
129 TRUE, /* pc_relative */
131 complain_overflow_bitfield,/* complain_on_overflow */
132 bfd_elf_generic_reloc, /* special_function */
133 "R_CRX_REL8_CMP", /* name */
134 FALSE, /* partial_inplace */
137 FALSE), /* pcrel_offset */
139 HOWTO (R_CRX_REL16, /* type */
143 TRUE, /* pc_relative */
145 complain_overflow_bitfield,/* complain_on_overflow */
146 bfd_elf_generic_reloc, /* special_function */
147 "R_CRX_REL16", /* name */
148 FALSE, /* partial_inplace */
150 0xffff, /* dst_mask */
151 FALSE), /* pcrel_offset */
153 HOWTO (R_CRX_REL24, /* type */
157 TRUE, /* pc_relative */
159 complain_overflow_bitfield,/* complain_on_overflow */
160 bfd_elf_generic_reloc, /* special_function */
161 "R_CRX_REL24", /* name */
162 FALSE, /* partial_inplace */
164 0xffffff, /* dst_mask */
165 FALSE), /* pcrel_offset */
167 HOWTO (R_CRX_REL32, /* type */
171 TRUE, /* pc_relative */
173 complain_overflow_bitfield,/* complain_on_overflow */
174 bfd_elf_generic_reloc, /* special_function */
175 "R_CRX_REL32", /* name */
176 FALSE, /* partial_inplace */
178 0xffffffff, /* dst_mask */
179 FALSE), /* pcrel_offset */
181 HOWTO (R_CRX_REGREL12, /* type */
185 FALSE, /* pc_relative */
187 complain_overflow_bitfield,/* complain_on_overflow */
188 bfd_elf_generic_reloc, /* special_function */
189 "R_CRX_REGREL12", /* name */
190 FALSE, /* partial_inplace */
192 0xfff, /* dst_mask */
193 FALSE), /* pcrel_offset */
195 HOWTO (R_CRX_REGREL22, /* type */
199 FALSE, /* pc_relative */
201 complain_overflow_bitfield,/* complain_on_overflow */
202 bfd_elf_generic_reloc, /* special_function */
203 "R_CRX_REGREL22", /* name */
204 FALSE, /* partial_inplace */
206 0x3fffff, /* dst_mask */
207 FALSE), /* pcrel_offset */
209 HOWTO (R_CRX_REGREL28, /* type */
213 FALSE, /* pc_relative */
215 complain_overflow_bitfield,/* complain_on_overflow */
216 bfd_elf_generic_reloc, /* special_function */
217 "R_CRX_REGREL28", /* name */
218 FALSE, /* partial_inplace */
220 0xfffffff, /* dst_mask */
221 FALSE), /* pcrel_offset */
223 HOWTO (R_CRX_REGREL32, /* type */
227 FALSE, /* pc_relative */
229 complain_overflow_bitfield,/* complain_on_overflow */
230 bfd_elf_generic_reloc, /* special_function */
231 "R_CRX_REGREL32", /* name */
232 FALSE, /* partial_inplace */
234 0xffffffff, /* dst_mask */
235 FALSE), /* pcrel_offset */
237 HOWTO (R_CRX_ABS16, /* type */
241 FALSE, /* pc_relative */
243 complain_overflow_bitfield,/* complain_on_overflow */
244 bfd_elf_generic_reloc, /* special_function */
245 "R_CRX_ABS16", /* name */
246 FALSE, /* partial_inplace */
248 0xffff, /* dst_mask */
249 FALSE), /* pcrel_offset */
251 HOWTO (R_CRX_ABS32, /* type */
255 FALSE, /* pc_relative */
257 complain_overflow_bitfield,/* complain_on_overflow */
258 bfd_elf_generic_reloc, /* special_function */
259 "R_CRX_ABS32", /* name */
260 FALSE, /* partial_inplace */
262 0xffffffff, /* dst_mask */
263 FALSE), /* pcrel_offset */
265 HOWTO (R_CRX_NUM8, /* type */
269 FALSE, /* pc_relative */
271 complain_overflow_bitfield,/* complain_on_overflow */
272 bfd_elf_generic_reloc, /* special_function */
273 "R_CRX_NUM8", /* name */
274 FALSE, /* partial_inplace */
277 FALSE), /* pcrel_offset */
279 HOWTO (R_CRX_NUM16, /* type */
283 FALSE, /* pc_relative */
285 complain_overflow_bitfield,/* complain_on_overflow */
286 bfd_elf_generic_reloc, /* special_function */
287 "R_CRX_NUM16", /* name */
288 FALSE, /* partial_inplace */
290 0xffff, /* dst_mask */
291 FALSE), /* pcrel_offset */
293 HOWTO (R_CRX_NUM32, /* type */
297 FALSE, /* pc_relative */
299 complain_overflow_bitfield,/* complain_on_overflow */
300 bfd_elf_generic_reloc, /* special_function */
301 "R_CRX_NUM32", /* name */
302 FALSE, /* partial_inplace */
304 0xffffffff, /* dst_mask */
305 FALSE), /* pcrel_offset */
307 HOWTO (R_CRX_IMM16, /* type */
311 FALSE, /* pc_relative */
313 complain_overflow_bitfield,/* complain_on_overflow */
314 bfd_elf_generic_reloc, /* special_function */
315 "R_CRX_IMM16", /* name */
316 FALSE, /* partial_inplace */
318 0xffff, /* dst_mask */
319 FALSE), /* pcrel_offset */
321 HOWTO (R_CRX_IMM32, /* type */
325 FALSE, /* pc_relative */
327 complain_overflow_bitfield,/* complain_on_overflow */
328 bfd_elf_generic_reloc, /* special_function */
329 "R_CRX_IMM32", /* name */
330 FALSE, /* partial_inplace */
332 0xffffffff, /* dst_mask */
333 FALSE), /* pcrel_offset */
335 /* An 8 bit switch table entry. This is generated for an expression
336 such as ``.byte L1 - L2''. The offset holds the difference
337 between the reloc address and L2. */
338 HOWTO (R_CRX_SWITCH8, /* type */
340 0, /* size (0 = byte, 1 = short, 2 = long) */
342 FALSE, /* pc_relative */
344 complain_overflow_unsigned, /* complain_on_overflow */
345 bfd_elf_generic_reloc, /* special_function */
346 "R_CRX_SWITCH8", /* name */
347 FALSE, /* partial_inplace */
350 TRUE), /* pcrel_offset */
352 /* A 16 bit switch table entry. This is generated for an expression
353 such as ``.word L1 - L2''. The offset holds the difference
354 between the reloc address and L2. */
355 HOWTO (R_CRX_SWITCH16, /* type */
357 1, /* size (0 = byte, 1 = short, 2 = long) */
359 FALSE, /* pc_relative */
361 complain_overflow_unsigned, /* complain_on_overflow */
362 bfd_elf_generic_reloc, /* special_function */
363 "R_CRX_SWITCH16", /* name */
364 FALSE, /* partial_inplace */
366 0xffff, /* dst_mask */
367 TRUE), /* pcrel_offset */
369 /* A 32 bit switch table entry. This is generated for an expression
370 such as ``.long L1 - L2''. The offset holds the difference
371 between the reloc address and L2. */
372 HOWTO (R_CRX_SWITCH32, /* type */
374 2, /* size (0 = byte, 1 = short, 2 = long) */
376 FALSE, /* pc_relative */
378 complain_overflow_unsigned, /* complain_on_overflow */
379 bfd_elf_generic_reloc, /* special_function */
380 "R_CRX_SWITCH32", /* name */
381 FALSE, /* partial_inplace */
383 0xffffffff, /* dst_mask */
384 TRUE) /* pcrel_offset */
387 /* Retrieve a howto ptr using a BFD reloc_code. */
389 static reloc_howto_type *
390 elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
391 bfd_reloc_code_real_type code)
395 for (i = 0; i < R_CRX_MAX; i++)
396 if (code == crx_reloc_map[i].bfd_reloc_enum)
397 return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type];
399 printf ("This relocation Type is not supported -0x%x\n", code);
403 static reloc_howto_type *
404 elf_crx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
410 i < sizeof (crx_elf_howto_table) / sizeof (crx_elf_howto_table[0]);
412 if (crx_elf_howto_table[i].name != NULL
413 && strcasecmp (crx_elf_howto_table[i].name, r_name) == 0)
414 return &crx_elf_howto_table[i];
419 /* Retrieve a howto ptr using an internal relocation entry. */
422 elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
423 Elf_Internal_Rela *dst)
425 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
426 if (r_type >= R_CRX_MAX)
428 (*_bfd_error_handler) (_("%B: unrecognised CRX reloc number: %d"),
430 bfd_set_error (bfd_error_bad_value);
433 cache_ptr->howto = &crx_elf_howto_table[r_type];
436 /* Perform a relocation as part of a final link. */
438 static bfd_reloc_status_type
439 crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
440 bfd *output_bfd ATTRIBUTE_UNUSED,
441 asection *input_section, bfd_byte *contents,
442 bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
443 struct bfd_link_info *info ATTRIBUTE_UNUSED,
444 asection *sec ATTRIBUTE_UNUSED,
445 int is_local ATTRIBUTE_UNUSED)
447 unsigned short r_type = howto->type;
448 bfd_byte *hit_data = contents + offset;
449 bfd_vma reloc_bits, check;
465 /* 'hit_data' is relative to the start of the instruction, not the
466 relocation offset. Advance it to account for the exact offset. */
471 /* This relocation type is used only in 'Branch if Equal to 0'
472 instructions and requires special handling. */
483 /* We only care about the addend, where the difference between
484 expressions is kept. */
491 if (howto->pc_relative)
493 /* Subtract the address of the section containing the location. */
494 Rvalue -= (input_section->output_section->vma
495 + input_section->output_offset);
496 /* Subtract the position of the location within the section. */
500 /* Add in supplied addend. */
503 /* Complain if the bitfield overflows, whether it is considered
504 as signed or unsigned. */
505 check = Rvalue >> howto->rightshift;
507 /* Assumes two's complement. This expression avoids
508 overflow if howto->bitsize is the number of bits in
510 reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
512 if (((bfd_vma) check & ~reloc_bits) != 0
513 && (((bfd_vma) check & ~reloc_bits)
514 != (-(bfd_vma) 1 & ~reloc_bits)))
516 /* The above right shift is incorrect for a signed
517 value. See if turning on the upper bits fixes the
519 if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
521 check |= ((bfd_vma) - 1
523 >> howto->rightshift));
524 if (((bfd_vma) check & ~reloc_bits)
525 != (-(bfd_vma) 1 & ~reloc_bits))
526 return bfd_reloc_overflow;
529 return bfd_reloc_overflow;
532 /* Drop unwanted bits from the value we are relocating to. */
533 Rvalue >>= (bfd_vma) howto->rightshift;
535 /* Apply dst_mask to select only relocatable part of the insn. */
536 Rvalue &= howto->dst_mask;
541 if (r_type == R_CRX_REL4)
544 Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
547 bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
551 if (r_type == R_CRX_REGREL12)
552 Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
554 bfd_put_16 (input_bfd, Rvalue, hit_data);
558 if (r_type == R_CRX_REL24
559 || r_type == R_CRX_REGREL22
560 || r_type == R_CRX_REGREL28)
561 Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
562 bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
564 if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
565 /* Relocation on DATA is purely little-endian, that is, for a
566 multi-byte datum, the lowest address in memory contains the
567 little end of the datum, that is, the least significant byte.
568 Therefore we use BFD's byte Putting functions. */
569 bfd_put_32 (input_bfd, Rvalue, hit_data);
571 /* Relocation on INSTRUCTIONS is different : Instructions are
572 word-addressable, that is, each word itself is arranged according
573 to little-endian convention, whereas the words are arranged with
574 respect to one another in BIG ENDIAN fashion.
575 When there is an immediate value that spans a word boundary, it is
576 split in a big-endian way with respect to the words. */
578 bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
579 bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
584 return bfd_reloc_notsupported;
590 /* Delete some bytes from a section while relaxing. */
593 elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
594 asection *sec, bfd_vma addr, int count)
596 Elf_Internal_Shdr *symtab_hdr;
597 unsigned int sec_shndx;
599 Elf_Internal_Rela *irel, *irelend;
601 Elf_Internal_Sym *isym;
602 Elf_Internal_Sym *isymend;
603 struct elf_link_hash_entry **sym_hashes;
604 struct elf_link_hash_entry **end_hashes;
605 struct elf_link_hash_entry **start_hashes;
606 unsigned int symcount;
608 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
610 contents = elf_section_data (sec)->this_hdr.contents;
614 irel = elf_section_data (sec)->relocs;
615 irelend = irel + sec->reloc_count;
617 /* Actually delete the bytes. */
618 memmove (contents + addr, contents + addr + count,
619 (size_t) (toaddr - addr - count));
622 /* Adjust all the relocs. */
623 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
625 /* Get the new reloc address. */
626 if ((irel->r_offset > addr
627 && irel->r_offset < toaddr))
628 irel->r_offset -= count;
631 /* Adjust the local symbols defined in this section. */
632 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
633 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
634 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
636 if (isym->st_shndx == sec_shndx
637 && isym->st_value > addr
638 && isym->st_value < toaddr)
640 /* Adjust the addend of SWITCH relocations in this section,
641 which reference this local symbol. */
642 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
644 unsigned long r_symndx;
645 Elf_Internal_Sym *rsym;
646 bfd_vma addsym, subsym;
648 /* Skip if not a SWITCH relocation. */
649 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
650 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
651 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
654 r_symndx = ELF32_R_SYM (irel->r_info);
655 rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
657 /* Skip if not the local adjusted symbol. */
661 addsym = isym->st_value;
662 subsym = addsym - irel->r_addend;
664 /* Fix the addend only when -->> (addsym > addr >= subsym). */
666 irel->r_addend -= count;
671 isym->st_value -= count;
675 /* Now adjust the global symbols defined in this section. */
676 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
677 - symtab_hdr->sh_info);
678 sym_hashes = start_hashes = elf_sym_hashes (abfd);
679 end_hashes = sym_hashes + symcount;
681 for (; sym_hashes < end_hashes; sym_hashes++)
683 struct elf_link_hash_entry *sym_hash = *sym_hashes;
685 /* The '--wrap SYMBOL' option is causing a pain when the object file,
686 containing the definition of __wrap_SYMBOL, includes a direct
687 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
688 the same symbol (which is __wrap_SYMBOL), but still exist as two
689 different symbols in 'sym_hashes', we don't want to adjust
690 the global symbol __wrap_SYMBOL twice.
691 This check is only relevant when symbols are being wrapped. */
692 if (link_info->wrap_hash != NULL)
694 struct elf_link_hash_entry **cur_sym_hashes;
696 /* Loop only over the symbols whom been already checked. */
697 for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
700 /* If the current symbol is identical to 'sym_hash', that means
701 the symbol was already adjusted (or at least checked). */
702 if (*cur_sym_hashes == sym_hash)
705 /* Don't adjust the symbol again. */
706 if (cur_sym_hashes < sym_hashes)
710 if ((sym_hash->root.type == bfd_link_hash_defined
711 || sym_hash->root.type == bfd_link_hash_defweak)
712 && sym_hash->root.u.def.section == sec
713 && sym_hash->root.u.def.value > addr
714 && sym_hash->root.u.def.value < toaddr)
715 sym_hash->root.u.def.value -= count;
721 /* This is a version of bfd_generic_get_relocated_section_contents
722 which uses elf32_crx_relocate_section. */
725 elf32_crx_get_relocated_section_contents (bfd *output_bfd,
726 struct bfd_link_info *link_info,
727 struct bfd_link_order *link_order,
729 bfd_boolean relocatable,
732 Elf_Internal_Shdr *symtab_hdr;
733 asection *input_section = link_order->u.indirect.section;
734 bfd *input_bfd = input_section->owner;
735 asection **sections = NULL;
736 Elf_Internal_Rela *internal_relocs = NULL;
737 Elf_Internal_Sym *isymbuf = NULL;
739 /* We only need to handle the case of relaxing, or of having a
740 particular set of section contents, specially. */
742 || elf_section_data (input_section)->this_hdr.contents == NULL)
743 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
748 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
750 memcpy (data, elf_section_data (input_section)->this_hdr.contents,
751 (size_t) input_section->size);
753 if ((input_section->flags & SEC_RELOC) != 0
754 && input_section->reloc_count > 0)
756 Elf_Internal_Sym *isym;
757 Elf_Internal_Sym *isymend;
761 internal_relocs = (_bfd_elf_link_read_relocs
762 (input_bfd, input_section, NULL,
763 (Elf_Internal_Rela *) NULL, FALSE));
764 if (internal_relocs == NULL)
767 if (symtab_hdr->sh_info != 0)
769 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
771 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
772 symtab_hdr->sh_info, 0,
778 amt = symtab_hdr->sh_info;
779 amt *= sizeof (asection *);
780 sections = bfd_malloc (amt);
781 if (sections == NULL && amt != 0)
784 isymend = isymbuf + symtab_hdr->sh_info;
785 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
789 if (isym->st_shndx == SHN_UNDEF)
790 isec = bfd_und_section_ptr;
791 else if (isym->st_shndx == SHN_ABS)
792 isec = bfd_abs_section_ptr;
793 else if (isym->st_shndx == SHN_COMMON)
794 isec = bfd_com_section_ptr;
796 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
801 if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
802 input_section, data, internal_relocs,
806 if (sections != NULL)
809 && symtab_hdr->contents != (unsigned char *) isymbuf)
811 if (elf_section_data (input_section)->relocs != internal_relocs)
812 free (internal_relocs);
818 if (sections != NULL)
821 && symtab_hdr->contents != (unsigned char *) isymbuf)
823 if (internal_relocs != NULL
824 && elf_section_data (input_section)->relocs != internal_relocs)
825 free (internal_relocs);
829 /* Relocate a CRX ELF section. */
832 elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
833 bfd *input_bfd, asection *input_section,
834 bfd_byte *contents, Elf_Internal_Rela *relocs,
835 Elf_Internal_Sym *local_syms,
836 asection **local_sections)
838 Elf_Internal_Shdr *symtab_hdr;
839 struct elf_link_hash_entry **sym_hashes;
840 Elf_Internal_Rela *rel, *relend;
842 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
843 sym_hashes = elf_sym_hashes (input_bfd);
846 relend = relocs + input_section->reloc_count;
847 for (; rel < relend; rel++)
850 reloc_howto_type *howto;
851 unsigned long r_symndx;
852 Elf_Internal_Sym *sym;
854 struct elf_link_hash_entry *h;
856 bfd_reloc_status_type r;
858 r_symndx = ELF32_R_SYM (rel->r_info);
859 r_type = ELF32_R_TYPE (rel->r_info);
860 howto = crx_elf_howto_table + (r_type);
865 if (r_symndx < symtab_hdr->sh_info)
867 sym = local_syms + r_symndx;
868 sec = local_sections[r_symndx];
869 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
873 bfd_boolean unresolved_reloc, warned, ignored;
875 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
876 r_symndx, symtab_hdr, sym_hashes,
878 unresolved_reloc, warned, ignored);
881 if (sec != NULL && discarded_section (sec))
882 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
883 rel, 1, relend, howto, 0, contents);
885 if (bfd_link_relocatable (info))
888 r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
890 contents, rel->r_offset,
891 relocation, rel->r_addend,
892 info, sec, h == NULL);
894 if (r != bfd_reloc_ok)
897 const char *msg = (const char *) 0;
900 name = h->root.root.string;
903 name = (bfd_elf_string_from_elf_section
904 (input_bfd, symtab_hdr->sh_link, sym->st_name));
905 if (name == NULL || *name == '\0')
906 name = bfd_section_name (input_bfd, sec);
911 case bfd_reloc_overflow:
912 (*info->callbacks->reloc_overflow)
913 (info, (h ? &h->root : NULL), name, howto->name,
914 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
917 case bfd_reloc_undefined:
918 (*info->callbacks->undefined_symbol)
919 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
922 case bfd_reloc_outofrange:
923 msg = _("internal error: out of range error");
926 case bfd_reloc_notsupported:
927 msg = _("internal error: unsupported relocation error");
930 case bfd_reloc_dangerous:
931 msg = _("internal error: dangerous error");
935 msg = _("internal error: unknown error");
939 (*info->callbacks->warning) (info, msg, name, input_bfd,
940 input_section, rel->r_offset);
949 /* This function handles relaxing for the CRX.
951 There's quite a few relaxing opportunites available on the CRX:
953 * bal/bcond:32 -> bal/bcond:16 2 bytes
954 * bcond:16 -> bcond:8 2 bytes
955 * cmpbcond:24 -> cmpbcond:8 2 bytes
956 * arithmetic imm32 -> arithmetic imm16 2 bytes
958 Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
961 elf32_crx_relax_section (bfd *abfd, asection *sec,
962 struct bfd_link_info *link_info, bfd_boolean *again)
964 Elf_Internal_Shdr *symtab_hdr;
965 Elf_Internal_Rela *internal_relocs;
966 Elf_Internal_Rela *irel, *irelend;
967 bfd_byte *contents = NULL;
968 Elf_Internal_Sym *isymbuf = NULL;
970 /* Assume nothing changes. */
973 /* We don't have to do anything for a relocatable link, if
974 this section does not have relocs, or if this is not a
976 if (bfd_link_relocatable (link_info)
977 || (sec->flags & SEC_RELOC) == 0
978 || sec->reloc_count == 0
979 || (sec->flags & SEC_CODE) == 0)
982 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
984 /* Get a copy of the native relocations. */
985 internal_relocs = (_bfd_elf_link_read_relocs
986 (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
987 link_info->keep_memory));
988 if (internal_relocs == NULL)
991 /* Walk through them looking for relaxing opportunities. */
992 irelend = internal_relocs + sec->reloc_count;
993 for (irel = internal_relocs; irel < irelend; irel++)
997 /* If this isn't something that can be relaxed, then ignore
999 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32
1000 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
1001 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
1002 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
1005 /* Get the section contents if we haven't done so already. */
1006 if (contents == NULL)
1008 /* Get cached copy if it exists. */
1009 if (elf_section_data (sec)->this_hdr.contents != NULL)
1010 contents = elf_section_data (sec)->this_hdr.contents;
1011 /* Go get them off disk. */
1012 else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1016 /* Read this BFD's local symbols if we haven't done so already. */
1017 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1019 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1020 if (isymbuf == NULL)
1021 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1022 symtab_hdr->sh_info, 0,
1024 if (isymbuf == NULL)
1028 /* Get the value of the symbol referred to by the reloc. */
1029 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1031 /* A local symbol. */
1032 Elf_Internal_Sym *isym;
1035 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1036 if (isym->st_shndx == SHN_UNDEF)
1037 sym_sec = bfd_und_section_ptr;
1038 else if (isym->st_shndx == SHN_ABS)
1039 sym_sec = bfd_abs_section_ptr;
1040 else if (isym->st_shndx == SHN_COMMON)
1041 sym_sec = bfd_com_section_ptr;
1043 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1044 symval = (isym->st_value
1045 + sym_sec->output_section->vma
1046 + sym_sec->output_offset);
1051 struct elf_link_hash_entry *h;
1053 /* An external symbol. */
1054 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1055 h = elf_sym_hashes (abfd)[indx];
1056 BFD_ASSERT (h != NULL);
1058 if (h->root.type != bfd_link_hash_defined
1059 && h->root.type != bfd_link_hash_defweak)
1060 /* This appears to be a reference to an undefined
1061 symbol. Just ignore it--it will be caught by the
1062 regular reloc processing. */
1065 symval = (h->root.u.def.value
1066 + h->root.u.def.section->output_section->vma
1067 + h->root.u.def.section->output_offset);
1070 /* For simplicity of coding, we are going to modify the section
1071 contents, the section relocs, and the BFD symbol table. We
1072 must tell the rest of the code not to free up this
1073 information. It would be possible to instead create a table
1074 of changes which have to be made, as is done in coff-mips.c;
1075 that would be more work, but would require less memory when
1076 the linker is run. */
1078 /* Try to turn a 32bit pc-relative branch/call into
1079 a 16bit pc-relative branch/call. */
1080 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
1082 bfd_vma value = symval;
1084 /* Deal with pc-relative gunk. */
1085 value -= (sec->output_section->vma + sec->output_offset);
1086 value -= irel->r_offset;
1087 value += irel->r_addend;
1089 /* See if the value will fit in 16 bits, note the high value is
1090 0xfffe + 2 as the target will be two bytes closer if we are
1092 if ((long) value < 0x10000 && (long) value > -0x10002)
1094 unsigned short code;
1096 /* Get the opcode. */
1097 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1099 /* Verify it's a 'bal'/'bcond' and fix the opcode. */
1100 if ((code & 0xfff0) == 0x3170)
1101 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1102 else if ((code & 0xf0ff) == 0x707f)
1103 bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
1107 /* Note that we've changed the relocs, section contents, etc. */
1108 elf_section_data (sec)->relocs = internal_relocs;
1109 elf_section_data (sec)->this_hdr.contents = contents;
1110 symtab_hdr->contents = (unsigned char *) isymbuf;
1112 /* Fix the relocation's type. */
1113 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1116 /* Delete two bytes of data. */
1117 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1118 irel->r_offset + 2, 2))
1121 /* That will change things, so, we should relax again.
1122 Note that this is not required, and it may be slow. */
1127 /* Try to turn a 16bit pc-relative branch into an
1128 8bit pc-relative branch. */
1129 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
1131 bfd_vma value = symval;
1133 /* Deal with pc-relative gunk. */
1134 value -= (sec->output_section->vma + sec->output_offset);
1135 value -= irel->r_offset;
1136 value += irel->r_addend;
1138 /* See if the value will fit in 8 bits, note the high value is
1139 0xfc + 2 as the target will be two bytes closer if we are
1141 if ((long) value < 0xfe && (long) value > -0x100)
1143 unsigned short code;
1145 /* Get the opcode. */
1146 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1148 /* Verify it's a 'bcond' opcode. */
1149 if ((code & 0xf0ff) != 0x707e)
1152 /* Note that we've changed the relocs, section contents, etc. */
1153 elf_section_data (sec)->relocs = internal_relocs;
1154 elf_section_data (sec)->this_hdr.contents = contents;
1155 symtab_hdr->contents = (unsigned char *) isymbuf;
1157 /* Fix the relocation's type. */
1158 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1161 /* Delete two bytes of data. */
1162 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1163 irel->r_offset + 2, 2))
1166 /* That will change things, so, we should relax again.
1167 Note that this is not required, and it may be slow. */
1172 /* Try to turn a 24bit pc-relative cmp&branch into
1173 an 8bit pc-relative cmp&branch. */
1174 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
1176 bfd_vma value = symval;
1178 /* Deal with pc-relative gunk. */
1179 value -= (sec->output_section->vma + sec->output_offset);
1180 value -= irel->r_offset;
1181 value += irel->r_addend;
1183 /* See if the value will fit in 8 bits, note the high value is
1184 0x7e + 2 as the target will be two bytes closer if we are
1186 if ((long) value < 0x100 && (long) value > -0x100)
1188 unsigned short code;
1190 /* Get the opcode. */
1191 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1193 /* Verify it's a 'cmp&branch' opcode. */
1194 if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
1195 && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
1196 && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
1197 /* Or a Co-processor branch ('bcop'). */
1198 && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
1201 /* Note that we've changed the relocs, section contents, etc. */
1202 elf_section_data (sec)->relocs = internal_relocs;
1203 elf_section_data (sec)->this_hdr.contents = contents;
1204 symtab_hdr->contents = (unsigned char *) isymbuf;
1206 /* Fix the opcode. */
1207 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1209 /* Fix the relocation's type. */
1210 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1213 /* Delete two bytes of data. */
1214 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1215 irel->r_offset + 4, 2))
1218 /* That will change things, so, we should relax again.
1219 Note that this is not required, and it may be slow. */
1224 /* Try to turn a 32bit immediate address into
1225 a 16bit immediate address. */
1226 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
1228 bfd_vma value = symval;
1230 /* See if the value will fit in 16 bits. */
1231 if ((long) value < 0x7fff && (long) value > -0x8000)
1233 unsigned short code;
1235 /* Get the opcode. */
1236 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1238 /* Verify it's a 'arithmetic double'. */
1239 if ((code & 0xf0f0) != 0x20f0)
1242 /* Note that we've changed the relocs, section contents, etc. */
1243 elf_section_data (sec)->relocs = internal_relocs;
1244 elf_section_data (sec)->this_hdr.contents = contents;
1245 symtab_hdr->contents = (unsigned char *) isymbuf;
1247 /* Fix the opcode. */
1248 bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
1250 /* Fix the relocation's type. */
1251 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1254 /* Delete two bytes of data. */
1255 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1256 irel->r_offset + 2, 2))
1259 /* That will change things, so, we should relax again.
1260 Note that this is not required, and it may be slow. */
1267 && symtab_hdr->contents != (unsigned char *) isymbuf)
1269 if (! link_info->keep_memory)
1273 /* Cache the symbols for elf_link_input_bfd. */
1274 symtab_hdr->contents = (unsigned char *) isymbuf;
1278 if (contents != NULL
1279 && elf_section_data (sec)->this_hdr.contents != contents)
1281 if (! link_info->keep_memory)
1285 /* Cache the section contents for elf_link_input_bfd. */
1286 elf_section_data (sec)->this_hdr.contents = contents;
1290 if (internal_relocs != NULL
1291 && elf_section_data (sec)->relocs != internal_relocs)
1292 free (internal_relocs);
1298 && symtab_hdr->contents != (unsigned char *) isymbuf)
1300 if (contents != NULL
1301 && elf_section_data (sec)->this_hdr.contents != contents)
1303 if (internal_relocs != NULL
1304 && elf_section_data (sec)->relocs != internal_relocs)
1305 free (internal_relocs);
1310 /* Definitions for setting CRX target vector. */
1311 #define TARGET_LITTLE_SYM crx_elf32_vec
1312 #define TARGET_LITTLE_NAME "elf32-crx"
1313 #define ELF_ARCH bfd_arch_crx
1314 #define ELF_MACHINE_CODE EM_CRX
1315 #define ELF_MAXPAGESIZE 0x1
1316 #define elf_symbol_leading_char '_'
1318 #define bfd_elf32_bfd_reloc_type_lookup elf_crx_reloc_type_lookup
1319 #define bfd_elf32_bfd_reloc_name_lookup \
1320 elf_crx_reloc_name_lookup
1321 #define elf_info_to_howto elf_crx_info_to_howto
1322 #define elf_info_to_howto_rel 0
1323 #define elf_backend_relocate_section elf32_crx_relocate_section
1324 #define bfd_elf32_bfd_relax_section elf32_crx_relax_section
1325 #define bfd_elf32_bfd_get_relocated_section_contents \
1326 elf32_crx_get_relocated_section_contents
1327 #define elf_backend_can_gc_sections 1
1328 #define elf_backend_rela_normal 1
1330 #include "elf32-target.h"