1 /* V850-specific support for 32-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 Free Software Foundation, Inc.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
25 dependencies. As is the gas & simulator code for the v850. */
33 #include "libiberty.h"
35 /* Sign-extend a 17-bit number. */
36 #define SEXT17(x) ((((x) & 0x1ffff) ^ 0x10000) - 0x10000)
38 /* Sign-extend a 22-bit number. */
39 #define SEXT22(x) ((((x) & 0x3fffff) ^ 0x200000) - 0x200000)
41 static reloc_howto_type v850_elf_howto_table[];
43 /* Look through the relocs for a section during the first phase, and
44 allocate space in the global offset table or procedure linkage
48 v850_elf_check_relocs (bfd *abfd,
49 struct bfd_link_info *info,
51 const Elf_Internal_Rela *relocs)
53 bfd_boolean ret = TRUE;
54 Elf_Internal_Shdr *symtab_hdr;
55 struct elf_link_hash_entry **sym_hashes;
56 const Elf_Internal_Rela *rel;
57 const Elf_Internal_Rela *rel_end;
60 const char *common = NULL;
62 if (info->relocatable)
66 _bfd_error_handler ("v850_elf_check_relocs called for section %A in %B",
70 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
71 sym_hashes = elf_sym_hashes (abfd);
73 rel_end = relocs + sec->reloc_count;
74 for (rel = relocs; rel < rel_end; rel++)
76 unsigned long r_symndx;
77 struct elf_link_hash_entry *h;
79 r_symndx = ELF32_R_SYM (rel->r_info);
80 if (r_symndx < symtab_hdr->sh_info)
84 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
85 while (h->root.type == bfd_link_hash_indirect
86 || h->root.type == bfd_link_hash_warning)
87 h = (struct elf_link_hash_entry *) h->root.u.i.link;
90 r_type = ELF32_R_TYPE (rel->r_info);
96 /* This relocation describes the C++ object vtable hierarchy.
97 Reconstruct it for later use during GC. */
98 case R_V850_GNU_VTINHERIT:
99 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
103 /* This relocation describes which C++ vtable entries
104 are actually used. Record for later use during GC. */
105 case R_V850_GNU_VTENTRY:
106 BFD_ASSERT (h != NULL);
108 && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
112 case R_V850_SDA_16_16_SPLIT_OFFSET:
113 case R_V850_SDA_16_16_OFFSET:
114 case R_V850_SDA_15_16_OFFSET:
118 other = V850_OTHER_SDA;
120 goto small_data_common;
122 case R_V850_ZDA_16_16_SPLIT_OFFSET:
123 case R_V850_ZDA_16_16_OFFSET:
124 case R_V850_ZDA_15_16_OFFSET:
125 other = V850_OTHER_ZDA;
127 goto small_data_common;
129 case R_V850_TDA_4_4_OFFSET:
130 case R_V850_TDA_4_5_OFFSET:
131 case R_V850_TDA_7_7_OFFSET:
132 case R_V850_TDA_6_8_OFFSET:
133 case R_V850_TDA_7_8_OFFSET:
134 case R_V850_TDA_16_16_OFFSET:
135 other = V850_OTHER_TDA;
139 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
144 /* Flag which type of relocation was used. */
146 if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
147 && (h->other & V850_OTHER_ERROR) == 0)
150 static char buff[200]; /* XXX */
152 switch (h->other & V850_OTHER_MASK)
155 msg = _("Variable `%s' cannot occupy in multiple small data regions");
157 case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
158 msg = _("Variable `%s' can only be in one of the small, zero, and tiny data regions");
160 case V850_OTHER_SDA | V850_OTHER_ZDA:
161 msg = _("Variable `%s' cannot be in both small and zero data regions simultaneously");
163 case V850_OTHER_SDA | V850_OTHER_TDA:
164 msg = _("Variable `%s' cannot be in both small and tiny data regions simultaneously");
166 case V850_OTHER_ZDA | V850_OTHER_TDA:
167 msg = _("Variable `%s' cannot be in both zero and tiny data regions simultaneously");
171 sprintf (buff, msg, h->root.root.string);
172 info->callbacks->warning (info, buff, h->root.root.string,
173 abfd, h->root.u.def.section,
176 bfd_set_error (bfd_error_bad_value);
177 h->other |= V850_OTHER_ERROR;
182 if (h && h->root.type == bfd_link_hash_common
184 && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
188 section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
189 section->flags |= SEC_IS_COMMON;
193 fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
194 v850_elf_howto_table[ (int)r_type ].name,
195 (h && h->root.root.string) ? h->root.root.string : "<unknown>",
196 (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
205 /* In the old version, when an entry was checked out from the table,
206 it was deleted. This produced an error if the entry was needed
207 more than once, as the second attempted retry failed.
209 In the current version, the entry is not deleted, instead we set
210 the field 'found' to TRUE. If a second lookup matches the same
211 entry, then we know that the hi16s reloc has already been updated
212 and does not need to be updated a second time.
214 TODO - TOFIX: If it is possible that we need to restore 2 different
215 addresses from the same table entry, where the first generates an
216 overflow, whilst the second do not, then this code will fail. */
218 typedef struct hi16s_location
222 unsigned long counter;
224 struct hi16s_location * next;
228 static hi16s_location * previous_hi16s;
229 static hi16s_location * free_hi16s;
230 static unsigned long hi16s_counter;
233 remember_hi16s_reloc (bfd *abfd, bfd_vma addend, bfd_byte *address)
235 hi16s_location * entry = NULL;
236 bfd_size_type amt = sizeof (* free_hi16s);
238 /* Find a free structure. */
239 if (free_hi16s == NULL)
240 free_hi16s = bfd_zalloc (abfd, amt);
243 free_hi16s = free_hi16s->next;
245 entry->addend = addend;
246 entry->address = address;
247 entry->counter = hi16s_counter ++;
248 entry->found = FALSE;
249 entry->next = previous_hi16s;
250 previous_hi16s = entry;
252 /* Cope with wrap around of our counter. */
253 if (hi16s_counter == 0)
255 /* XXX: Assume that all counter entries differ only in their low 16 bits. */
256 for (entry = previous_hi16s; entry != NULL; entry = entry->next)
257 entry->counter &= 0xffff;
259 hi16s_counter = 0x10000;
264 find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
266 hi16s_location *match = NULL;
267 hi16s_location *entry;
270 /* Search the table. Record the most recent entry that matches. */
271 for (entry = previous_hi16s; entry; entry = entry->next)
273 if (entry->addend == addend
274 && (match == NULL || match->counter < entry->counter))
283 /* Extract the address. */
284 addr = match->address;
286 /* Remember if this entry has already been used before. */
288 * already_found = match->found;
290 /* Note that this entry has now been used. */
296 /* Calculate the final operand value for a R_V850_LO16 or
297 R_V850_LO16_SPLIT_OFFSET. *INSN is the current operand value and
298 ADDEND is the sum of the relocation symbol and offset. Store the
299 operand value in *INSN and return true on success.
301 The assembler has already done some of this: If the value stored in
302 the instruction has its 15th bit set, (counting from zero) then the
303 assembler will have added 1 to the value stored in the associated
304 HI16S reloc. So for example, these relocations:
306 movhi hi( fred ), r0, r1
307 movea lo( fred ), r1, r1
309 will store 0 in the value fields for the MOVHI and MOVEA instructions
310 and addend will be the address of fred, but for these instructions:
312 movhi hi( fred + 0x123456 ), r0, r1
313 movea lo( fred + 0x123456 ), r1, r1
315 the value stored in the MOVHI instruction will be 0x12 and the value
316 stored in the MOVEA instruction will be 0x3456. If however the
319 movhi hi( fred + 0x10ffff ), r0, r1
320 movea lo( fred + 0x10ffff ), r1, r1
322 then the value stored in the MOVHI instruction would be 0x11 (not
323 0x10) and the value stored in the MOVEA instruction would be 0xffff.
324 Thus (assuming for the moment that the addend is 0), at run time the
325 MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
326 adds 0xffffffff (sign extension!) producing 0x10ffff. Similarly if
327 the instructions were:
329 movhi hi( fred - 1 ), r0, r1
330 movea lo( fred - 1 ), r1, r1
332 then 0 is stored in the MOVHI instruction and -1 is stored in the
335 Overflow can occur if the addition of the value stored in the
336 instruction plus the addend sets the 15th bit when before it was clear.
337 This is because the 15th bit will be sign extended into the high part,
338 thus reducing its value by one, but since the 15th bit was originally
339 clear, the assembler will not have added 1 to the previous HI16S reloc
340 to compensate for this effect. For example:
342 movhi hi( fred + 0x123456 ), r0, r1
343 movea lo( fred + 0x123456 ), r1, r1
345 The value stored in HI16S reloc is 0x12, the value stored in the LO16
346 reloc is 0x3456. If we assume that the address of fred is 0x00007000
347 then the relocations become:
349 HI16S: 0x0012 + (0x00007000 >> 16) = 0x12
350 LO16: 0x3456 + (0x00007000 & 0xffff) = 0xa456
352 but when the instructions are executed, the MOVEA instruction's value
353 is signed extended, so the sum becomes:
358 0x0011a456 but 'fred + 0x123456' = 0x0012a456
360 Note that if the 15th bit was set in the value stored in the LO16
361 reloc, then we do not have to do anything:
363 movhi hi( fred + 0x10ffff ), r0, r1
364 movea lo( fred + 0x10ffff ), r1, r1
366 HI16S: 0x0011 + (0x00007000 >> 16) = 0x11
367 LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff
372 0x00116fff = fred + 0x10ffff = 0x7000 + 0x10ffff
374 Overflow can also occur if the computation carries into the 16th bit
375 and it also results in the 15th bit having the same value as the 15th
376 bit of the original value. What happens is that the HI16S reloc
377 will have already examined the 15th bit of the original value and
378 added 1 to the high part if the bit is set. This compensates for the
379 sign extension of 15th bit of the result of the computation. But now
380 there is a carry into the 16th bit, and this has not been allowed for.
382 So, for example if fred is at address 0xf000:
384 movhi hi( fred + 0xffff ), r0, r1 [bit 15 of the offset is set]
385 movea lo( fred + 0xffff ), r1, r1
387 HI16S: 0x0001 + (0x0000f000 >> 16) = 0x0001
388 LO16: 0xffff + (0x0000f000 & 0xffff) = 0xefff (carry into bit 16 is lost)
393 0x0000efff but 'fred + 0xffff' = 0x0001efff
395 Similarly, if the 15th bit remains clear, but overflow occurs into
396 the 16th bit then (assuming the address of fred is 0xf000):
398 movhi hi( fred + 0x7000 ), r0, r1 [bit 15 of the offset is clear]
399 movea lo( fred + 0x7000 ), r1, r1
401 HI16S: 0x0000 + (0x0000f000 >> 16) = 0x0000
402 LO16: 0x7000 + (0x0000f000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
407 0x00006fff but 'fred + 0x7000' = 0x00016fff
409 Note - there is no need to change anything if a carry occurs, and the
410 15th bit changes its value from being set to being clear, as the HI16S
411 reloc will have already added in 1 to the high part for us:
413 movhi hi( fred + 0xffff ), r0, r1 [bit 15 of the offset is set]
414 movea lo( fred + 0xffff ), r1, r1
416 HI16S: 0x0001 + (0x00007000 >> 16)
417 LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
420 + 0x00006fff (bit 15 not set, so the top half is zero)
422 0x00016fff which is right (assuming that fred is at 0x7000)
424 but if the 15th bit goes from being clear to being set, then we must
425 once again handle overflow:
427 movhi hi( fred + 0x7000 ), r0, r1 [bit 15 of the offset is clear]
428 movea lo( fred + 0x7000 ), r1, r1
430 HI16S: 0x0000 + (0x0000ffff >> 16)
431 LO16: 0x7000 + (0x0000ffff & 0xffff) = 0x6fff (carry into bit 16)
434 + 0x00006fff (bit 15 not set, so the top half is zero)
436 0x00006fff which is wrong (assuming that fred is at 0xffff). */
439 v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn,
440 unsigned long addend)
442 #define BIT15_SET(x) ((x) & 0x8000)
443 #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
445 if ((BIT15_SET (*insn + addend) && ! BIT15_SET (addend))
446 || (OVERFLOWS (addend, *insn)
447 && ((! BIT15_SET (*insn)) || (BIT15_SET (addend)))))
449 bfd_boolean already_updated;
450 bfd_byte *hi16s_address = find_remembered_hi16s_reloc
451 (addend, & already_updated);
453 /* Amend the matching HI16_S relocation. */
454 if (hi16s_address != NULL)
456 if (! already_updated)
458 unsigned long hi_insn = bfd_get_16 (abfd, hi16s_address);
460 bfd_put_16 (abfd, hi_insn, hi16s_address);
465 (*_bfd_error_handler) (_("FAILED to find previous HI16 reloc"));
472 /* Do not complain if value has top bit set, as this has been
474 *insn = (*insn + addend) & 0xffff;
478 /* FIXME: The code here probably ought to be removed and the code in reloc.c
479 allowed to do its stuff instead. At least for most of the relocs, anyway. */
481 static bfd_reloc_status_type
482 v850_elf_perform_relocation (bfd *abfd,
488 unsigned long result;
489 bfd_signed_vma saddend = (bfd_signed_vma) addend;
495 fprintf (stderr, "reloc number %d not recognised\n", r_type);
497 return bfd_reloc_notsupported;
503 bfd_put_32 (abfd, addend, address);
508 insn = bfd_get_32 (abfd, address);
509 insn &= ~((0x7f << 4) | (0x7fff80 << (16-7)));
510 insn |= ((addend & 0x7f) << 4) | ((addend & 0x7fff80) << (16-7));
511 bfd_put_32 (abfd, (bfd_vma) insn, address);
515 case R_V850_22_PCREL:
516 if (saddend > 0x1fffff || saddend < -0x200000)
517 return bfd_reloc_overflow;
519 if ((addend % 2) != 0)
520 return bfd_reloc_dangerous;
522 insn = bfd_get_32 (abfd, address);
524 insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
525 bfd_put_32 (abfd, (bfd_vma) insn, address);
529 case R_V850_17_PCREL:
530 if (saddend > 0xffff || saddend < -0x10000)
531 return bfd_reloc_overflow;
533 if ((addend % 2) != 0)
534 return bfd_reloc_dangerous;
536 insn = bfd_get_32 (abfd, address);
537 insn &= ~ 0xfffe0010;
538 insn |= ((addend & 0xfffe) << 16) | ((addend & 0x10000) >> (16-4));
542 case R_V850_16_PCREL:
543 if ((saddend < -0xffff) || (saddend > 0))
544 return bfd_reloc_overflow;
546 if ((addend % 2) != 0)
547 return bfd_reloc_dangerous;
549 insn = bfd_get_16 (abfd, address);
551 insn |= (-addend & 0xfffe);
556 if (saddend > 0xff || saddend < -0x100)
557 return bfd_reloc_overflow;
559 if ((addend % 2) != 0)
560 return bfd_reloc_dangerous;
562 insn = bfd_get_16 (abfd, address);
564 insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
569 addend += (bfd_get_16 (abfd, address) << 16);
570 addend = (addend >> 16);
576 /* Remember where this relocation took place. */
577 remember_hi16s_reloc (abfd, addend, address);
579 addend += (bfd_get_16 (abfd, address) << 16);
580 addend = (addend >> 16) + ((addend & 0x8000) != 0);
582 /* This relocation cannot overflow. */
591 insn = bfd_get_16 (abfd, address);
592 if (! v850_elf_perform_lo16_relocation (abfd, &insn, addend))
593 return bfd_reloc_overflow;
598 addend += (char) bfd_get_8 (abfd, address);
600 saddend = (bfd_signed_vma) addend;
602 if (saddend > 0x7f || saddend < -0x80)
603 return bfd_reloc_overflow;
605 bfd_put_8 (abfd, addend, address);
608 case R_V850_CALLT_16_16_OFFSET:
609 addend += bfd_get_16 (abfd, address);
611 saddend = (bfd_signed_vma) addend;
613 if (saddend > 0xffff || saddend < 0)
614 return bfd_reloc_overflow;
619 case R_V850_CALLT_15_16_OFFSET:
620 insn = bfd_get_16 (abfd, address);
622 addend += insn & 0xfffe;
624 saddend = (bfd_signed_vma) addend;
626 if (saddend > 0xffff || saddend < 0)
627 return bfd_reloc_overflow;
629 insn = (0xfffe & addend)
633 case R_V850_CALLT_6_7_OFFSET:
634 insn = bfd_get_16 (abfd, address);
635 addend += ((insn & 0x3f) << 1);
637 saddend = (bfd_signed_vma) addend;
639 if (saddend > 0x7e || saddend < 0)
640 return bfd_reloc_overflow;
643 return bfd_reloc_dangerous;
646 insn |= (addend >> 1);
651 case R_V850_SDA_16_16_OFFSET:
652 case R_V850_ZDA_16_16_OFFSET:
653 case R_V850_TDA_16_16_OFFSET:
654 addend += bfd_get_16 (abfd, address);
656 saddend = (bfd_signed_vma) addend;
658 if (saddend > 0x7fff || saddend < -0x8000)
659 return bfd_reloc_overflow;
665 case R_V850_SDA_15_16_OFFSET:
666 case R_V850_ZDA_15_16_OFFSET:
668 insn = bfd_get_16 (abfd, address);
669 addend += (insn & 0xfffe);
671 saddend = (bfd_signed_vma) addend;
673 if (saddend > 0x7ffe || saddend < -0x8000)
674 return bfd_reloc_overflow;
677 return bfd_reloc_dangerous;
679 insn = (addend &~ (bfd_vma) 1) | (insn & 1);
682 case R_V850_TDA_6_8_OFFSET:
683 insn = bfd_get_16 (abfd, address);
684 addend += ((insn & 0x7e) << 1);
686 saddend = (bfd_signed_vma) addend;
688 if (saddend > 0xfc || saddend < 0)
689 return bfd_reloc_overflow;
692 return bfd_reloc_dangerous;
695 insn |= (addend >> 1);
698 case R_V850_TDA_7_8_OFFSET:
699 insn = bfd_get_16 (abfd, address);
700 addend += ((insn & 0x7f) << 1);
702 saddend = (bfd_signed_vma) addend;
704 if (saddend > 0xfe || saddend < 0)
705 return bfd_reloc_overflow;
708 return bfd_reloc_dangerous;
711 insn |= (addend >> 1);
714 case R_V850_TDA_7_7_OFFSET:
715 insn = bfd_get_16 (abfd, address);
716 addend += insn & 0x7f;
718 saddend = (bfd_signed_vma) addend;
720 if (saddend > 0x7f || saddend < 0)
721 return bfd_reloc_overflow;
727 case R_V850_TDA_4_5_OFFSET:
728 insn = bfd_get_16 (abfd, address);
729 addend += ((insn & 0xf) << 1);
731 saddend = (bfd_signed_vma) addend;
733 if (saddend > 0x1e || saddend < 0)
734 return bfd_reloc_overflow;
737 return bfd_reloc_dangerous;
740 insn |= (addend >> 1);
743 case R_V850_TDA_4_4_OFFSET:
744 insn = bfd_get_16 (abfd, address);
745 addend += insn & 0xf;
747 saddend = (bfd_signed_vma) addend;
749 if (saddend > 0xf || saddend < 0)
750 return bfd_reloc_overflow;
760 insn = bfd_get_16 (abfd, address);
761 result = insn & 0xfffe;
762 if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
763 return bfd_reloc_overflow;
765 return bfd_reloc_overflow;
766 insn = (result & 0xfffe)
768 bfd_put_16 (abfd, insn, address);
772 case R_V850_LO16_SPLIT_OFFSET:
773 insn = bfd_get_32 (abfd, address);
774 result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5);
775 if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
776 return bfd_reloc_overflow;
777 insn = (((result << 16) & 0xfffe0000)
778 | ((result << 5) & 0x20)
779 | (insn & ~0xfffe0020));
780 bfd_put_32 (abfd, insn, address);
783 case R_V850_16_SPLIT_OFFSET:
784 case R_V850_SDA_16_16_SPLIT_OFFSET:
785 case R_V850_ZDA_16_16_SPLIT_OFFSET:
786 insn = bfd_get_32 (abfd, address);
787 addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
789 saddend = (bfd_signed_vma) addend;
791 if (saddend > 0x7fff || saddend < -0x8000)
792 return bfd_reloc_overflow;
795 insn |= (addend & 1) << 5;
796 insn |= (addend &~ (bfd_vma) 1) << 16;
798 bfd_put_32 (abfd, (bfd_vma) insn, address);
801 case R_V850_GNU_VTINHERIT:
802 case R_V850_GNU_VTENTRY:
807 bfd_put_16 (abfd, (bfd_vma) insn, address);
811 /* Insert the addend into the instruction. */
813 static bfd_reloc_status_type
814 v850_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
817 void * data ATTRIBUTE_UNUSED,
820 char **err ATTRIBUTE_UNUSED)
824 /* If there is an output BFD,
825 and the symbol is not a section name (which is only defined at final link time),
826 and either we are not putting the addend into the instruction
827 or the addend is zero, so there is nothing to add into the instruction
828 then just fixup the address and return. */
830 && (symbol->flags & BSF_SECTION_SYM) == 0
831 && (! reloc->howto->partial_inplace
832 || reloc->addend == 0))
834 reloc->address += isection->output_offset;
838 /* Catch relocs involving undefined symbols. */
839 if (bfd_is_und_section (symbol->section)
840 && (symbol->flags & BSF_WEAK) == 0
842 return bfd_reloc_undefined;
844 /* We handle final linking of some relocs ourselves. */
846 /* Is the address of the relocation really within the section? */
847 if (reloc->address > bfd_get_section_limit (abfd, isection))
848 return bfd_reloc_outofrange;
850 /* Work out which section the relocation is targeted at and the
851 initial relocation command value. */
853 if (reloc->howto->pc_relative)
856 /* Get symbol value. (Common symbols are special.) */
857 if (bfd_is_com_section (symbol->section))
860 relocation = symbol->value;
862 /* Convert input-section-relative symbol value to absolute + addend. */
863 relocation += symbol->section->output_section->vma;
864 relocation += symbol->section->output_offset;
865 relocation += reloc->addend;
867 reloc->addend = relocation;
871 /* This function is used for relocs which are only used
872 for relaxing, which the linker should otherwise ignore. */
874 static bfd_reloc_status_type
875 v850_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
876 arelent *reloc_entry,
877 asymbol *symbol ATTRIBUTE_UNUSED,
878 void * data ATTRIBUTE_UNUSED,
879 asection *input_section,
881 char **error_message ATTRIBUTE_UNUSED)
883 if (output_bfd != NULL)
884 reloc_entry->address += input_section->output_offset;
888 /* Note: It is REQUIRED that the 'type' value of each entry
889 in this array match the index of the entry in the array.
890 SeeAlso: RELOC_NUBMER in include/elf/v850.h. */
891 static reloc_howto_type v850_elf_howto_table[] =
893 /* This reloc does nothing. */
894 HOWTO (R_V850_NONE, /* Type. */
896 2, /* Size (0 = byte, 1 = short, 2 = long). */
898 FALSE, /* PC_relative. */
900 complain_overflow_bitfield, /* Complain_on_overflow. */
901 bfd_elf_generic_reloc, /* Special_function. */
902 "R_V850_NONE", /* Name. */
903 FALSE, /* Partial_inplace. */
906 FALSE), /* PCrel_offset. */
908 /* A PC relative 9 bit branch. */
909 HOWTO (R_V850_9_PCREL, /* Type. */
911 1, /* Size (0 = byte, 1 = short, 2 = long). */
913 TRUE, /* PC_relative. */
915 complain_overflow_bitfield, /* Complain_on_overflow. */
916 v850_elf_reloc, /* Special_function. */
917 "R_V850_9_PCREL", /* Name. */
918 FALSE, /* Partial_inplace. */
919 0x00ffffff, /* Src_mask. */
920 0x00ffffff, /* Dst_mask. */
921 TRUE), /* PCrel_offset. */
923 /* A PC relative 22 bit branch. */
924 HOWTO (R_V850_22_PCREL, /* Type. */
926 2, /* Size (0 = byte, 1 = short, 2 = long). */
928 TRUE, /* PC_relative. */
930 complain_overflow_signed, /* Complain_on_overflow. */
931 v850_elf_reloc, /* Special_function. */
932 "R_V850_22_PCREL", /* Name. */
933 FALSE, /* Partial_inplace. */
934 0x07ffff80, /* Src_mask. */
935 0x07ffff80, /* Dst_mask. */
936 TRUE), /* PCrel_offset. */
938 /* High 16 bits of symbol value. */
939 HOWTO (R_V850_HI16_S, /* Type. */
941 1, /* Size (0 = byte, 1 = short, 2 = long). */
943 FALSE, /* PC_relative. */
945 complain_overflow_dont, /* Complain_on_overflow. */
946 v850_elf_reloc, /* Special_function. */
947 "R_V850_HI16_S", /* Name. */
948 FALSE, /* Partial_inplace. */
949 0xffff, /* Src_mask. */
950 0xffff, /* Dst_mask. */
951 FALSE), /* PCrel_offset. */
953 /* High 16 bits of symbol value. */
954 HOWTO (R_V850_HI16, /* Type. */
956 1, /* Size (0 = byte, 1 = short, 2 = long). */
958 FALSE, /* PC_relative. */
960 complain_overflow_dont, /* Complain_on_overflow. */
961 v850_elf_reloc, /* Special_function. */
962 "R_V850_HI16", /* Name. */
963 FALSE, /* Partial_inplace. */
964 0xffff, /* Src_mask. */
965 0xffff, /* Dst_mask. */
966 FALSE), /* PCrel_offset. */
968 /* Low 16 bits of symbol value. */
969 HOWTO (R_V850_LO16, /* Type. */
971 1, /* Size (0 = byte, 1 = short, 2 = long). */
973 FALSE, /* PC_relative. */
975 complain_overflow_dont, /* Complain_on_overflow. */
976 v850_elf_reloc, /* Special_function. */
977 "R_V850_LO16", /* Name. */
978 FALSE, /* Partial_inplace. */
979 0xffff, /* Src_mask. */
980 0xffff, /* Dst_mask. */
981 FALSE), /* PCrel_offset. */
983 /* Simple 32bit reloc. */
984 HOWTO (R_V850_ABS32, /* Type. */
986 2, /* Size (0 = byte, 1 = short, 2 = long). */
988 FALSE, /* PC_relative. */
990 complain_overflow_dont, /* Complain_on_overflow. */
991 v850_elf_reloc, /* Special_function. */
992 "R_V850_ABS32", /* Name. */
993 FALSE, /* Partial_inplace. */
994 0xffffffff, /* Src_mask. */
995 0xffffffff, /* Dst_mask. */
996 FALSE), /* PCrel_offset. */
998 /* Simple 16bit reloc. */
999 HOWTO (R_V850_16, /* Type. */
1000 0, /* Rightshift. */
1001 1, /* Size (0 = byte, 1 = short, 2 = long). */
1003 FALSE, /* PC_relative. */
1005 complain_overflow_dont, /* Complain_on_overflow. */
1006 bfd_elf_generic_reloc, /* Special_function. */
1007 "R_V850_16", /* Name. */
1008 FALSE, /* Partial_inplace. */
1009 0xffff, /* Src_mask. */
1010 0xffff, /* Dst_mask. */
1011 FALSE), /* PCrel_offset. */
1013 /* Simple 8bit reloc. */
1014 HOWTO (R_V850_8, /* Type. */
1015 0, /* Rightshift. */
1016 0, /* Size (0 = byte, 1 = short, 2 = long). */
1018 FALSE, /* PC_relative. */
1020 complain_overflow_dont, /* Complain_on_overflow. */
1021 bfd_elf_generic_reloc, /* Special_function. */
1022 "R_V850_8", /* Name. */
1023 FALSE, /* Partial_inplace. */
1024 0xff, /* Src_mask. */
1025 0xff, /* Dst_mask. */
1026 FALSE), /* PCrel_offset. */
1028 /* 16 bit offset from the short data area pointer. */
1029 HOWTO (R_V850_SDA_16_16_OFFSET, /* Type. */
1030 0, /* Rightshift. */
1031 1, /* Size (0 = byte, 1 = short, 2 = long). */
1033 FALSE, /* PC_relative. */
1035 complain_overflow_dont, /* Complain_on_overflow. */
1036 v850_elf_reloc, /* Special_function. */
1037 "R_V850_SDA_16_16_OFFSET", /* Name. */
1038 FALSE, /* Partial_inplace. */
1039 0xffff, /* Src_mask. */
1040 0xffff, /* Dst_mask. */
1041 FALSE), /* PCrel_offset. */
1043 /* 15 bit offset from the short data area pointer. */
1044 HOWTO (R_V850_SDA_15_16_OFFSET, /* Type. */
1045 1, /* Rightshift. */
1046 1, /* Size (0 = byte, 1 = short, 2 = long). */
1048 FALSE, /* PC_relative. */
1050 complain_overflow_dont, /* Complain_on_overflow. */
1051 v850_elf_reloc, /* Special_function. */
1052 "R_V850_SDA_15_16_OFFSET", /* Name. */
1053 FALSE, /* Partial_inplace. */
1054 0xfffe, /* Src_mask. */
1055 0xfffe, /* Dst_mask. */
1056 FALSE), /* PCrel_offset. */
1058 /* 16 bit offset from the zero data area pointer. */
1059 HOWTO (R_V850_ZDA_16_16_OFFSET, /* Type. */
1060 0, /* Rightshift. */
1061 1, /* Size (0 = byte, 1 = short, 2 = long). */
1063 FALSE, /* PC_relative. */
1065 complain_overflow_dont, /* Complain_on_overflow. */
1066 v850_elf_reloc, /* Special_function. */
1067 "R_V850_ZDA_16_16_OFFSET", /* Name. */
1068 FALSE, /* Partial_inplace. */
1069 0xffff, /* Src_mask. */
1070 0xffff, /* Dst_mask. */
1071 FALSE), /* PCrel_offset. */
1073 /* 15 bit offset from the zero data area pointer. */
1074 HOWTO (R_V850_ZDA_15_16_OFFSET, /* Type. */
1075 1, /* Rightshift. */
1076 1, /* Size (0 = byte, 1 = short, 2 = long). */
1078 FALSE, /* PC_relative. */
1080 complain_overflow_dont, /* Complain_on_overflow. */
1081 v850_elf_reloc, /* Special_function. */
1082 "R_V850_ZDA_15_16_OFFSET", /* Name. */
1083 FALSE, /* Partial_inplace. */
1084 0xfffe, /* Src_mask. */
1085 0xfffe, /* Dst_mask. */
1086 FALSE), /* PCrel_offset. */
1088 /* 6 bit offset from the tiny data area pointer. */
1089 HOWTO (R_V850_TDA_6_8_OFFSET, /* Type. */
1090 2, /* Rightshift. */
1091 1, /* Size (0 = byte, 1 = short, 2 = long). */
1093 FALSE, /* PC_relative. */
1095 complain_overflow_dont, /* Complain_on_overflow. */
1096 v850_elf_reloc, /* Special_function. */
1097 "R_V850_TDA_6_8_OFFSET", /* Name. */
1098 FALSE, /* Partial_inplace. */
1099 0x7e, /* Src_mask. */
1100 0x7e, /* Dst_mask. */
1101 FALSE), /* PCrel_offset. */
1103 /* 8 bit offset from the tiny data area pointer. */
1104 HOWTO (R_V850_TDA_7_8_OFFSET, /* Type. */
1105 1, /* Rightshift. */
1106 1, /* Size (0 = byte, 1 = short, 2 = long). */
1108 FALSE, /* PC_relative. */
1110 complain_overflow_dont, /* Complain_on_overflow. */
1111 v850_elf_reloc, /* Special_function. */
1112 "R_V850_TDA_7_8_OFFSET", /* Name. */
1113 FALSE, /* Partial_inplace. */
1114 0x7f, /* Src_mask. */
1115 0x7f, /* Dst_mask. */
1116 FALSE), /* PCrel_offset. */
1118 /* 7 bit offset from the tiny data area pointer. */
1119 HOWTO (R_V850_TDA_7_7_OFFSET, /* Type. */
1120 0, /* Rightshift. */
1121 1, /* Size (0 = byte, 1 = short, 2 = long). */
1123 FALSE, /* PC_relative. */
1125 complain_overflow_dont, /* Complain_on_overflow. */
1126 v850_elf_reloc, /* Special_function. */
1127 "R_V850_TDA_7_7_OFFSET", /* Name. */
1128 FALSE, /* Partial_inplace. */
1129 0x7f, /* Src_mask. */
1130 0x7f, /* Dst_mask. */
1131 FALSE), /* PCrel_offset. */
1133 /* 16 bit offset from the tiny data area pointer! */
1134 HOWTO (R_V850_TDA_16_16_OFFSET, /* Type. */
1135 0, /* Rightshift. */
1136 1, /* Size (0 = byte, 1 = short, 2 = long). */
1138 FALSE, /* PC_relative. */
1140 complain_overflow_dont, /* Complain_on_overflow. */
1141 v850_elf_reloc, /* Special_function. */
1142 "R_V850_TDA_16_16_OFFSET", /* Name. */
1143 FALSE, /* Partial_inplace. */
1144 0xffff, /* Src_mask. */
1145 0xfff, /* Dst_mask. */
1146 FALSE), /* PCrel_offset. */
1148 /* 5 bit offset from the tiny data area pointer. */
1149 HOWTO (R_V850_TDA_4_5_OFFSET, /* Type. */
1150 1, /* Rightshift. */
1151 1, /* Size (0 = byte, 1 = short, 2 = long). */
1153 FALSE, /* PC_relative. */
1155 complain_overflow_dont, /* Complain_on_overflow. */
1156 v850_elf_reloc, /* Special_function. */
1157 "R_V850_TDA_4_5_OFFSET", /* Name. */
1158 FALSE, /* Partial_inplace. */
1159 0x0f, /* Src_mask. */
1160 0x0f, /* Dst_mask. */
1161 FALSE), /* PCrel_offset. */
1163 /* 4 bit offset from the tiny data area pointer. */
1164 HOWTO (R_V850_TDA_4_4_OFFSET, /* Type. */
1165 0, /* Rightshift. */
1166 1, /* Size (0 = byte, 1 = short, 2 = long). */
1168 FALSE, /* PC_relative. */
1170 complain_overflow_dont, /* Complain_on_overflow. */
1171 v850_elf_reloc, /* Special_function. */
1172 "R_V850_TDA_4_4_OFFSET", /* Name. */
1173 FALSE, /* Partial_inplace. */
1174 0x0f, /* Src_mask. */
1175 0x0f, /* Dst_mask. */
1176 FALSE), /* PCrel_offset. */
1178 /* 16 bit offset from the short data area pointer. */
1179 HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* Type. */
1180 0, /* Rightshift. */
1181 2, /* Size (0 = byte, 1 = short, 2 = long). */
1183 FALSE, /* PC_relative. */
1185 complain_overflow_dont, /* Complain_on_overflow. */
1186 v850_elf_reloc, /* Special_function. */
1187 "R_V850_SDA_16_16_SPLIT_OFFSET",/* Name. */
1188 FALSE, /* Partial_inplace. */
1189 0xfffe0020, /* Src_mask. */
1190 0xfffe0020, /* Dst_mask. */
1191 FALSE), /* PCrel_offset. */
1193 /* 16 bit offset from the zero data area pointer. */
1194 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* Type. */
1195 0, /* Rightshift. */
1196 2, /* Size (0 = byte, 1 = short, 2 = long). */
1198 FALSE, /* PC_relative. */
1200 complain_overflow_dont, /* Complain_on_overflow. */
1201 v850_elf_reloc, /* Special_function. */
1202 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* Name. */
1203 FALSE, /* Partial_inplace. */
1204 0xfffe0020, /* Src_mask. */
1205 0xfffe0020, /* Dst_mask. */
1206 FALSE), /* PCrel_offset. */
1208 /* 6 bit offset from the call table base pointer. */
1209 HOWTO (R_V850_CALLT_6_7_OFFSET, /* Type. */
1210 0, /* Rightshift. */
1211 1, /* Size (0 = byte, 1 = short, 2 = long). */
1213 FALSE, /* PC_relative. */
1215 complain_overflow_dont, /* Complain_on_overflow. */
1216 v850_elf_reloc, /* Special_function. */
1217 "R_V850_CALLT_6_7_OFFSET", /* Name. */
1218 FALSE, /* Partial_inplace. */
1219 0x3f, /* Src_mask. */
1220 0x3f, /* Dst_mask. */
1221 FALSE), /* PCrel_offset. */
1223 /* 16 bit offset from the call table base pointer. */
1224 HOWTO (R_V850_CALLT_16_16_OFFSET, /* Type. */
1225 0, /* Rightshift. */
1226 1, /* Size (0 = byte, 1 = short, 2 = long). */
1228 FALSE, /* PC_relative. */
1230 complain_overflow_dont, /* Complain_on_overflow. */
1231 v850_elf_reloc, /* Special_function. */
1232 "R_V850_CALLT_16_16_OFFSET", /* Name. */
1233 FALSE, /* Partial_inplace. */
1234 0xffff, /* Src_mask. */
1235 0xffff, /* Dst_mask. */
1236 FALSE), /* PCrel_offset. */
1239 /* GNU extension to record C++ vtable hierarchy */
1240 HOWTO (R_V850_GNU_VTINHERIT, /* Type. */
1241 0, /* Rightshift. */
1242 2, /* Size (0 = byte, 1 = short, 2 = long). */
1244 FALSE, /* PC_relative. */
1246 complain_overflow_dont, /* Complain_on_overflow. */
1247 NULL, /* Special_function. */
1248 "R_V850_GNU_VTINHERIT", /* Name. */
1249 FALSE, /* Partial_inplace. */
1252 FALSE), /* PCrel_offset. */
1254 /* GNU extension to record C++ vtable member usage. */
1255 HOWTO (R_V850_GNU_VTENTRY, /* Type. */
1256 0, /* Rightshift. */
1257 2, /* Size (0 = byte, 1 = short, 2 = long). */
1259 FALSE, /* PC_relative. */
1261 complain_overflow_dont, /* Complain_on_overflow. */
1262 _bfd_elf_rel_vtable_reloc_fn, /* Special_function. */
1263 "R_V850_GNU_VTENTRY", /* Name. */
1264 FALSE, /* Partial_inplace. */
1267 FALSE), /* PCrel_offset. */
1269 /* Indicates a .longcall pseudo-op. The compiler will generate a .longcall
1270 pseudo-op when it finds a function call which can be relaxed. */
1271 HOWTO (R_V850_LONGCALL, /* Type. */
1272 0, /* Rightshift. */
1273 2, /* Size (0 = byte, 1 = short, 2 = long). */
1275 TRUE, /* PC_relative. */
1277 complain_overflow_signed, /* Complain_on_overflow. */
1278 v850_elf_ignore_reloc, /* Special_function. */
1279 "R_V850_LONGCALL", /* Name. */
1280 FALSE, /* Partial_inplace. */
1283 TRUE), /* PCrel_offset. */
1285 /* Indicates a .longjump pseudo-op. The compiler will generate a
1286 .longjump pseudo-op when it finds a branch which can be relaxed. */
1287 HOWTO (R_V850_LONGJUMP, /* Type. */
1288 0, /* Rightshift. */
1289 2, /* Size (0 = byte, 1 = short, 2 = long). */
1291 TRUE, /* PC_relative. */
1293 complain_overflow_signed, /* Complain_on_overflow. */
1294 v850_elf_ignore_reloc, /* Special_function. */
1295 "R_V850_LONGJUMP", /* Name. */
1296 FALSE, /* Partial_inplace. */
1299 TRUE), /* PCrel_offset. */
1301 HOWTO (R_V850_ALIGN, /* Type. */
1302 0, /* Rightshift. */
1303 1, /* Size (0 = byte, 1 = short, 2 = long). */
1305 FALSE, /* PC_relative. */
1307 complain_overflow_unsigned, /* Complain_on_overflow. */
1308 v850_elf_ignore_reloc, /* Special_function. */
1309 "R_V850_ALIGN", /* Name. */
1310 FALSE, /* Partial_inplace. */
1313 TRUE), /* PCrel_offset. */
1315 /* Simple pc-relative 32bit reloc. */
1316 HOWTO (R_V850_REL32, /* Type. */
1317 0, /* Rightshift. */
1318 2, /* Size (0 = byte, 1 = short, 2 = long). */
1320 TRUE, /* PC_relative. */
1322 complain_overflow_dont, /* Complain_on_overflow. */
1323 v850_elf_reloc, /* Special_function. */
1324 "R_V850_REL32", /* Name. */
1325 FALSE, /* Partial_inplace. */
1326 0xffffffff, /* Src_mask. */
1327 0xffffffff, /* Dst_mask. */
1328 FALSE), /* PCrel_offset. */
1330 /* An ld.bu version of R_V850_LO16. */
1331 HOWTO (R_V850_LO16_SPLIT_OFFSET, /* Type. */
1332 0, /* Rightshift. */
1333 2, /* Size (0 = byte, 1 = short, 2 = long). */
1335 FALSE, /* PC_relative. */
1337 complain_overflow_dont, /* Complain_on_overflow. */
1338 v850_elf_reloc, /* Special_function. */
1339 "R_V850_LO16_SPLIT_OFFSET", /* Name. */
1340 FALSE, /* Partial_inplace. */
1341 0xfffe0020, /* Src_mask. */
1342 0xfffe0020, /* Dst_mask. */
1343 FALSE), /* PCrel_offset. */
1345 /* A unsigned PC relative 16 bit loop. */
1346 HOWTO (R_V850_16_PCREL, /* Type. */
1347 0, /* Rightshift. */
1348 1, /* Size (0 = byte, 1 = short, 2 = long). */
1350 TRUE, /* PC_relative. */
1352 complain_overflow_bitfield, /* Complain_on_overflow. */
1353 v850_elf_reloc, /* Special_function. */
1354 "R_V850_16_PCREL", /* Name. */
1355 FALSE, /* Partial_inplace. */
1356 0xfffe, /* Src_mask. */
1357 0xfffe, /* Dst_mask. */
1358 TRUE), /* PCrel_offset. */
1360 /* A PC relative 17 bit branch. */
1361 HOWTO (R_V850_17_PCREL, /* Type. */
1362 0, /* Rightshift. */
1363 2, /* Size (0 = byte, 1 = short, 2 = long). */
1365 TRUE, /* PC_relative. */
1367 complain_overflow_bitfield, /* Complain_on_overflow. */
1368 v850_elf_reloc, /* Special_function. */
1369 "R_V850_17_PCREL", /* Name. */
1370 FALSE, /* Partial_inplace. */
1371 0x0010fffe, /* Src_mask. */
1372 0x0010fffe, /* Dst_mask. */
1373 TRUE), /* PCrel_offset. */
1375 /* A 23bit offset ld/st. */
1376 HOWTO (R_V850_23, /* type. */
1377 0, /* rightshift. */
1378 2, /* size (0 = byte, 1 = short, 2 = long). */
1380 FALSE, /* pc_relative. */
1382 complain_overflow_dont, /* complain_on_overflow. */
1383 v850_elf_reloc, /* special_function. */
1384 "R_V850_23", /* name. */
1385 FALSE, /* partial_inplace. */
1386 0xffff07f0, /* src_mask. */
1387 0xffff07f0, /* dst_mask. */
1388 FALSE), /* pcrel_offset. */
1390 /* A PC relative 32 bit branch. */
1391 HOWTO (R_V850_32_PCREL, /* type. */
1392 1, /* rightshift. */
1393 2, /* size (0 = byte, 1 = short, 2 = long). */
1395 TRUE, /* pc_relative. */
1397 complain_overflow_signed, /* complain_on_overflow. */
1398 v850_elf_reloc, /* special_function. */
1399 "R_V850_32_PCREL", /* name. */
1400 FALSE, /* partial_inplace. */
1401 0xfffffffe, /* src_mask. */
1402 0xfffffffe, /* dst_mask. */
1403 TRUE), /* pcrel_offset. */
1405 /* A absolute 32 bit branch. */
1406 HOWTO (R_V850_32_ABS, /* type. */
1407 1, /* rightshift. */
1408 2, /* size (0 = byte, 1 = short, 2 = long). */
1410 TRUE, /* pc_relative. */
1412 complain_overflow_signed, /* complain_on_overflow. */
1413 v850_elf_reloc, /* special_function. */
1414 "R_V850_32_ABS", /* name. */
1415 FALSE, /* partial_inplace. */
1416 0xfffffffe, /* src_mask. */
1417 0xfffffffe, /* dst_mask. */
1418 FALSE), /* pcrel_offset. */
1420 /* High 16 bits of symbol value. */
1421 HOWTO (R_V850_HI16, /* Type. */
1422 0, /* Rightshift. */
1423 1, /* Size (0 = byte, 1 = short, 2 = long). */
1425 FALSE, /* PC_relative. */
1427 complain_overflow_dont, /* Complain_on_overflow. */
1428 v850_elf_reloc, /* Special_function. */
1429 "R_V850_HI16", /* Name. */
1430 FALSE, /* Partial_inplace. */
1431 0xffff, /* Src_mask. */
1432 0xffff, /* Dst_mask. */
1433 FALSE), /* PCrel_offset. */
1435 /* Low 16 bits of symbol value. */
1436 HOWTO (R_V850_16_S1, /* type. */
1437 1, /* rightshift. */
1438 1, /* size (0 = byte, 1 = short, 2 = long). */
1440 FALSE, /* pc_relative. */
1442 complain_overflow_dont, /* complain_on_overflow. */
1443 v850_elf_reloc, /* special_function. */
1444 "R_V850_16_S1", /* name. */
1445 FALSE, /* partial_inplace. */
1446 0xfffe, /* src_mask. */
1447 0xfffe, /* dst_mask. */
1448 FALSE), /* pcrel_offset. */
1450 /* Low 16 bits of symbol value. */
1451 HOWTO (R_V850_LO16_S1, /* type. */
1452 1, /* rightshift. */
1453 1, /* size (0 = byte, 1 = short, 2 = long). */
1455 FALSE, /* pc_relative. */
1457 complain_overflow_dont, /* complain_on_overflow. */
1458 v850_elf_reloc, /* special_function. */
1459 "R_V850_LO16_S1", /* name. */
1460 FALSE, /* partial_inplace. */
1461 0xfffe, /* src_mask. */
1462 0xfffe, /* dst_mask. */
1463 FALSE), /* pcrel_offset. */
1465 /* 16 bit offset from the call table base pointer. */
1466 HOWTO (R_V850_CALLT_15_16_OFFSET, /* type. */
1467 1, /* rightshift. */
1468 1, /* size (0 = byte, 1 = short, 2 = long). */
1470 FALSE, /* pc_relative. */
1472 complain_overflow_dont, /* complain_on_overflow. */
1473 v850_elf_reloc, /* special_function. */
1474 "R_V850_CALLT_15_16_OFFSET", /* name. */
1475 FALSE, /* partial_inplace. */
1476 0xfffe, /* src_mask. */
1477 0xfffe, /* dst_mask. */
1478 FALSE), /* pcrel_offset. */
1480 /* Like R_V850_32 PCREL, but referring to the GOT table entry for
1482 HOWTO (R_V850_32_GOTPCREL, /* type. */
1483 0, /* rightshift. */
1484 2, /* size (0 = byte, 1 = short, 2 = long). */
1486 TRUE, /* pc_relative. */
1488 complain_overflow_unsigned, /* complain_on_overflow. */
1489 v850_elf_reloc, /* special_function. */
1490 "R_V850_32_GOTPCREL", /* name. */
1491 FALSE, /* partial_inplace. */
1492 0xffffffff, /* src_mask. */
1493 0xffffffff, /* dst_mask. */
1494 TRUE), /* pcrel_offset. */
1496 /* Like R_V850_SDA_, but referring to the GOT table entry for
1498 HOWTO (R_V850_16_GOT, /* type. */
1499 0, /* rightshift. */
1500 2, /* size (0 = byte, 1 = short, 2 = long). */
1502 FALSE, /* pc_relative. */
1504 complain_overflow_unsigned, /* complain_on_overflow. */
1505 bfd_elf_generic_reloc, /* special_function. */
1506 "R_V850_16_GOT", /* name. */
1507 FALSE, /* partial_inplace. */
1508 0xffff, /* src_mask. */
1509 0xffff, /* dst_mask. */
1510 FALSE), /* pcrel_offset. */
1512 HOWTO (R_V850_32_GOT, /* type. */
1513 0, /* rightshift. */
1514 2, /* size (0 = byte, 1 = short, 2 = long). */
1516 FALSE, /* pc_relative. */
1518 complain_overflow_unsigned, /* complain_on_overflow. */
1519 bfd_elf_generic_reloc, /* special_function. */
1520 "R_V850_32_GOT", /* name. */
1521 FALSE, /* partial_inplace. */
1522 0xffffffff, /* src_mask. */
1523 0xffffffff, /* dst_mask. */
1524 FALSE), /* pcrel_offset. */
1526 /* Like R_V850_22_PCREL, but referring to the procedure linkage table
1527 entry for the symbol. */
1528 HOWTO (R_V850_22_PLT, /* type. */
1529 1, /* rightshift. */
1530 2, /* size (0 = byte, 1 = short, 2 = long). */
1532 TRUE, /* pc_relative. */
1534 complain_overflow_signed, /* complain_on_overflow. */
1535 bfd_elf_generic_reloc, /* special_function. */
1536 "R_V850_22_PLT", /* name. */
1537 FALSE, /* partial_inplace. */
1538 0x07ffff80, /* src_mask. */
1539 0x07ffff80, /* dst_mask. */
1540 TRUE), /* pcrel_offset. */
1542 HOWTO (R_V850_32_PLT, /* type. */
1543 1, /* rightshift. */
1544 2, /* size (0 = byte, 1 = short, 2 = long). */
1546 TRUE, /* pc_relative. */
1548 complain_overflow_signed, /* complain_on_overflow. */
1549 bfd_elf_generic_reloc, /* special_function. */
1550 "R_V850_32_PLT", /* name. */
1551 FALSE, /* partial_inplace. */
1552 0xffffffff, /* src_mask. */
1553 0xffffffff, /* dst_mask. */
1554 TRUE), /* pcrel_offset. */
1556 /* This is used only by the dynamic linker. The symbol should exist
1557 both in the object being run and in some shared library. The
1558 dynamic linker copies the data addressed by the symbol from the
1559 shared library into the object, because the object being
1560 run has to have the data at some particular address. */
1561 HOWTO (R_V850_COPY, /* type. */
1562 0, /* rightshift. */
1563 2, /* size (0 = byte, 1 = short, 2 = long). */
1565 FALSE, /* pc_relative. */
1567 complain_overflow_bitfield, /* complain_on_overflow. */
1568 bfd_elf_generic_reloc, /* special_function. */
1569 "R_V850_COPY", /* name. */
1570 FALSE, /* partial_inplace. */
1571 0xffffffff, /* src_mask. */
1572 0xffffffff, /* dst_mask. */
1573 FALSE), /* pcrel_offset. */
1575 /* Like R_M32R_24, but used when setting global offset table
1577 HOWTO (R_V850_GLOB_DAT, /* type. */
1578 0, /* rightshift. */
1579 2, /* size (0 = byte, 1 = short, 2 = long) */
1581 FALSE, /* pc_relative. */
1583 complain_overflow_bitfield, /* complain_on_overflow. */
1584 bfd_elf_generic_reloc, /* special_function. */
1585 "R_V850_GLOB_DAT", /* name. */
1586 FALSE, /* partial_inplace. */
1587 0xffffffff, /* src_mask. */
1588 0xffffffff, /* dst_mask. */
1589 FALSE), /* pcrel_offset. */
1591 /* Marks a procedure linkage table entry for a symbol. */
1592 HOWTO (R_V850_JMP_SLOT, /* type. */
1593 0, /* rightshift. */
1594 2, /* size (0 = byte, 1 = short, 2 = long) */
1596 FALSE, /* pc_relative. */
1598 complain_overflow_bitfield, /* complain_on_overflow. */
1599 bfd_elf_generic_reloc, /* special_function. */
1600 "R_V850_JMP_SLOT", /* name. */
1601 FALSE, /* partial_inplace. */
1602 0xffffffff, /* src_mask. */
1603 0xffffffff, /* dst_mask. */
1604 FALSE), /* pcrel_offset. */
1606 /* Used only by the dynamic linker. When the object is run, this
1607 longword is set to the load address of the object, plus the
1609 HOWTO (R_V850_RELATIVE, /* type. */
1610 0, /* rightshift. */
1611 2, /* size (0 = byte, 1 = short, 2 = long) */
1613 FALSE, /* pc_relative. */
1615 complain_overflow_bitfield, /* complain_on_overflow. */
1616 bfd_elf_generic_reloc, /* special_function. */
1617 "R_V850_RELATIVE", /* name. */
1618 FALSE, /* partial_inplace. */
1619 0xffffffff, /* src_mask. */
1620 0xffffffff, /* dst_mask. */
1621 FALSE), /* pcrel_offset. */
1623 HOWTO (R_V850_16_GOTOFF, /* type. */
1624 0, /* rightshift. */
1625 2, /* size (0 = byte, 1 = short, 2 = long) */
1627 FALSE, /* pc_relative. */
1629 complain_overflow_bitfield, /* complain_on_overflow. */
1630 bfd_elf_generic_reloc, /* special_function. */
1631 "R_V850_16_GOTOFF", /* name. */
1632 FALSE, /* partial_inplace. */
1633 0xffff, /* src_mask. */
1634 0xffff, /* dst_mask. */
1635 FALSE), /* pcrel_offset. */
1637 HOWTO (R_V850_32_GOTOFF, /* type. */
1638 0, /* rightshift. */
1639 2, /* size (0 = byte, 1 = short, 2 = long) */
1641 FALSE, /* pc_relative. */
1643 complain_overflow_bitfield, /* complain_on_overflow. */
1644 bfd_elf_generic_reloc, /* special_function. */
1645 "R_V850_32_GOTOFF", /* name. */
1646 FALSE, /* partial_inplace. */
1647 0xffffffff, /* src_mask. */
1648 0xffffffff, /* dst_mask. */
1649 FALSE), /* pcrel_offset. */
1651 HOWTO (R_V850_CODE, /* type. */
1652 0, /* rightshift. */
1653 1, /* size (0 = byte, 1 = short, 2 = long) */
1655 FALSE, /* pc_relative. */
1657 complain_overflow_unsigned, /* complain_on_overflow. */
1658 v850_elf_ignore_reloc, /* special_function. */
1659 "R_V850_CODE", /* name. */
1660 FALSE, /* partial_inplace. */
1663 TRUE), /* pcrel_offset. */
1665 HOWTO (R_V850_DATA, /* type. */
1666 0, /* rightshift. */
1667 1, /* size (0 = byte, 1 = short, 2 = long) */
1669 FALSE, /* pc_relative. */
1671 complain_overflow_unsigned, /* complain_on_overflow. */
1672 v850_elf_ignore_reloc, /* special_function. */
1673 "R_V850_DATA", /* name. */
1674 FALSE, /* partial_inplace. */
1677 TRUE), /* pcrel_offset. */
1681 /* Map BFD reloc types to V850 ELF reloc types. */
1683 struct v850_elf_reloc_map
1685 /* BFD_RELOC_V850_CALLT_16_16_OFFSET is 258, which will not fix in an
1687 bfd_reloc_code_real_type bfd_reloc_val;
1688 unsigned int elf_reloc_val;
1691 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
1693 { BFD_RELOC_NONE, R_V850_NONE },
1694 { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL },
1695 { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL },
1696 { BFD_RELOC_HI16_S, R_V850_HI16_S },
1697 { BFD_RELOC_HI16, R_V850_HI16 },
1698 { BFD_RELOC_LO16, R_V850_LO16 },
1699 { BFD_RELOC_32, R_V850_ABS32 },
1700 { BFD_RELOC_32_PCREL, R_V850_REL32 },
1701 { BFD_RELOC_16, R_V850_16 },
1702 { BFD_RELOC_8, R_V850_8 },
1703 { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
1704 { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
1705 { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
1706 { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
1707 { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET },
1708 { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET },
1709 { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET },
1710 { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
1711 { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET },
1712 { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET },
1713 { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_LO16_SPLIT_OFFSET },
1714 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
1715 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
1716 { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET },
1717 { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET },
1718 { BFD_RELOC_VTABLE_INHERIT, R_V850_GNU_VTINHERIT },
1719 { BFD_RELOC_VTABLE_ENTRY, R_V850_GNU_VTENTRY },
1720 { BFD_RELOC_V850_LONGCALL, R_V850_LONGCALL },
1721 { BFD_RELOC_V850_LONGJUMP, R_V850_LONGJUMP },
1722 { BFD_RELOC_V850_ALIGN, R_V850_ALIGN },
1723 { BFD_RELOC_V850_16_PCREL, R_V850_16_PCREL },
1724 { BFD_RELOC_V850_17_PCREL, R_V850_17_PCREL },
1725 { BFD_RELOC_V850_23, R_V850_23 },
1726 { BFD_RELOC_V850_32_PCREL, R_V850_32_PCREL },
1727 { BFD_RELOC_V850_32_ABS, R_V850_32_ABS },
1728 { BFD_RELOC_V850_16_SPLIT_OFFSET, R_V850_HI16 },
1729 { BFD_RELOC_V850_16_S1, R_V850_16_S1 },
1730 { BFD_RELOC_V850_LO16_S1, R_V850_LO16_S1 },
1731 { BFD_RELOC_V850_CALLT_15_16_OFFSET, R_V850_CALLT_15_16_OFFSET },
1732 { BFD_RELOC_V850_32_GOTPCREL, R_V850_32_GOTPCREL },
1733 { BFD_RELOC_V850_16_GOT, R_V850_16_GOT },
1734 { BFD_RELOC_V850_32_GOT, R_V850_32_GOT },
1735 { BFD_RELOC_V850_22_PLT_PCREL, R_V850_22_PLT },
1736 { BFD_RELOC_V850_32_PLT_PCREL, R_V850_32_PLT },
1737 { BFD_RELOC_V850_COPY, R_V850_COPY },
1738 { BFD_RELOC_V850_GLOB_DAT, R_V850_GLOB_DAT },
1739 { BFD_RELOC_V850_JMP_SLOT, R_V850_JMP_SLOT },
1740 { BFD_RELOC_V850_RELATIVE, R_V850_RELATIVE },
1741 { BFD_RELOC_V850_16_GOTOFF, R_V850_16_GOTOFF },
1742 { BFD_RELOC_V850_32_GOTOFF, R_V850_32_GOTOFF },
1743 { BFD_RELOC_V850_CODE, R_V850_CODE },
1744 { BFD_RELOC_V850_DATA, R_V850_DATA },
1747 #define V800_RELOC(name,sz,bit,shift,complain,pcrel,resolver) \
1748 HOWTO (name, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
1749 bfd_elf_ ## resolver ## _reloc, #name, FALSE, 0, ~0, FALSE)
1751 #define V800_EMPTY(name) EMPTY_HOWTO (name - R_V810_NONE)
1753 #define bfd_elf_v850_reloc v850_elf_reloc
1755 /* Note: It is REQUIRED that the 'type' value (R_V810_...) of each entry
1756 in this array match the index of the entry in the array minus 0x30.
1757 See: bfd_elf_v850_relocate_section(), v800_elf_reloc_type_lookup()
1758 and v800_elf_info_to_howto(). */
1760 static reloc_howto_type v800_elf_howto_table[] =
1762 V800_RELOC (R_V810_NONE, 0, 0, 0, dont, FALSE, generic), /* Type = 0x30 */
1763 V800_RELOC (R_V810_BYTE, 0, 8, 0, dont, FALSE, generic),
1764 V800_RELOC (R_V810_HWORD, 1, 16, 0, dont, FALSE, generic),
1765 V800_RELOC (R_V810_WORD, 2, 32, 0, dont, FALSE, generic),
1766 V800_RELOC (R_V810_WLO, 1, 16, 0, dont, FALSE, generic),
1767 V800_RELOC (R_V810_WHI, 1, 16, 0, dont, FALSE, generic),
1768 V800_RELOC (R_V810_WHI1, 1, 16, 0, dont, FALSE, generic),
1769 V800_RELOC (R_V810_GPBYTE, 0, 8, 0, dont, FALSE, v850),
1770 V800_RELOC (R_V810_GPHWORD, 1, 16, 0, dont, FALSE, v850),
1771 V800_RELOC (R_V810_GPWORD, 2, 32, 0, dont, FALSE, v850),
1772 V800_RELOC (R_V810_GPWLO, 1, 16, 0, dont, FALSE, v850),
1773 V800_RELOC (R_V810_GPWHI, 1, 16, 0, dont, FALSE, v850),
1774 V800_RELOC (R_V810_GPWHI1, 1, 16, 0, dont, FALSE, v850),
1775 V800_RELOC (R_V850_HWLO, 1, 16, 0, dont, FALSE, generic),
1776 V800_EMPTY (R_V810_reserved1),
1777 V800_RELOC (R_V850_EP7BIT, 0, 7, 0, unsigned, FALSE, v850),
1778 V800_RELOC (R_V850_EPHBYTE, 0, 8, 1, unsigned, FALSE, v850),
1779 V800_RELOC (R_V850_EPWBYTE, 0, 8, 2, unsigned, FALSE, v850),
1780 V800_RELOC (R_V850_REGHWLO, 1, 16, 0, dont, FALSE, v850),
1781 V800_EMPTY (R_V810_reserved2),
1782 V800_RELOC (R_V850_GPHWLO, 1, 16, 0, dont, FALSE, v850),
1783 V800_EMPTY (R_V810_reserved3),
1784 V800_RELOC (R_V850_PCR22, 2, 22, 0, signed, TRUE, generic),
1785 V800_RELOC (R_V850_BLO, 2, 24, 0, dont, FALSE, v850),
1786 V800_RELOC (R_V850_EP4BIT, 0, 4, 0, unsigned, FALSE, v850),
1787 V800_RELOC (R_V850_EP5BIT, 0, 5, 0, unsigned, FALSE, v850),
1788 V800_RELOC (R_V850_REGBLO, 2, 24, 0, dont, FALSE, v850),
1789 V800_RELOC (R_V850_GPBLO, 2, 24, 0, dont, FALSE, v850),
1790 V800_RELOC (R_V810_WLO_1, 1, 16, 0, dont, FALSE, v850),
1791 V800_RELOC (R_V810_GPWLO_1, 1, 16, 0, signed, FALSE, v850),
1792 V800_RELOC (R_V850_BLO_1, 2, 16, 0, signed, FALSE, v850),
1793 V800_RELOC (R_V850_HWLO_1, 1, 16, 0, signed, FALSE, v850),
1794 V800_EMPTY (R_V810_reserved4),
1795 V800_RELOC (R_V850_GPBLO_1, 2, 16, 1, signed, FALSE, v850),
1796 V800_RELOC (R_V850_GPHWLO_1, 1, 16, 1, signed, FALSE, v850),
1797 V800_EMPTY (R_V810_reserved5),
1798 V800_RELOC (R_V850_EPBLO, 2, 16, 1, signed, FALSE, v850),
1799 V800_RELOC (R_V850_EPHWLO, 1, 16, 1, signed, FALSE, v850),
1800 V800_EMPTY (R_V810_reserved6),
1801 V800_RELOC (R_V850_EPWLO_N, 1, 16, 1, signed, FALSE, v850),
1802 V800_RELOC (R_V850_PC32, 2, 32, 1, signed, TRUE, v850),
1803 V800_RELOC (R_V850_W23BIT, 2, 23, 1, signed, FALSE, v850),
1804 V800_RELOC (R_V850_GPW23BIT, 2, 23, 1, signed, FALSE, v850),
1805 V800_RELOC (R_V850_EPW23BIT, 2, 23, 1, signed, FALSE, v850),
1806 V800_RELOC (R_V850_B23BIT, 2, 23, 1, signed, FALSE, v850),
1807 V800_RELOC (R_V850_GPB23BIT, 2, 23, 1, signed, FALSE, v850),
1808 V800_RELOC (R_V850_EPB23BIT, 2, 23, 1, signed, FALSE, v850),
1809 V800_RELOC (R_V850_PC16U, 1, 16, 1, unsigned, TRUE, generic),
1810 V800_RELOC (R_V850_PC17, 2, 17, 1, signed, TRUE, generic),
1811 V800_RELOC (R_V850_DW8, 2, 8, 2, signed, FALSE, v850),
1812 V800_RELOC (R_V850_GPDW8, 2, 8, 2, signed, FALSE, v850),
1813 V800_RELOC (R_V850_EPDW8, 2, 8, 2, signed, FALSE, v850),
1814 V800_RELOC (R_V850_PC9, 1, 9, 3, signed, TRUE, v850),
1815 V800_RELOC (R_V810_REGBYTE, 0, 8, 0, dont, FALSE, v850),
1816 V800_RELOC (R_V810_REGHWORD, 1, 16, 0, dont, FALSE, v850),
1817 V800_RELOC (R_V810_REGWORD, 2, 32, 0, dont, FALSE, v850),
1818 V800_RELOC (R_V810_REGWLO, 1, 16, 0, dont, FALSE, v850),
1819 V800_RELOC (R_V810_REGWHI, 1, 16, 0, dont, FALSE, v850),
1820 V800_RELOC (R_V810_REGWHI1, 1, 16, 0, dont, FALSE, v850),
1821 V800_RELOC (R_V850_REGW23BIT, 2, 23, 1, signed, FALSE, v850),
1822 V800_RELOC (R_V850_REGB23BIT, 2, 23, 1, signed, FALSE, v850),
1823 V800_RELOC (R_V850_REGDW8, 2, 8, 2, signed, FALSE, v850),
1824 V800_RELOC (R_V810_EPBYTE, 0, 8, 0, dont, FALSE, v850),
1825 V800_RELOC (R_V810_EPHWORD, 1, 16, 0, dont, FALSE, v850),
1826 V800_RELOC (R_V810_EPWORD, 2, 32, 0, dont, FALSE, v850),
1827 V800_RELOC (R_V850_WLO23, 2, 32, 1, dont, FALSE, v850),
1828 V800_RELOC (R_V850_WORD_E, 2, 32, 1, dont, FALSE, v850),
1829 V800_RELOC (R_V850_REGWORD_E, 2, 32, 1, dont, FALSE, v850),
1830 V800_RELOC (R_V850_WORD, 2, 32, 0, dont, FALSE, v850),
1831 V800_RELOC (R_V850_GPWORD, 2, 32, 0, dont, FALSE, v850),
1832 V800_RELOC (R_V850_REGWORD, 2, 32, 0, dont, FALSE, v850),
1833 V800_RELOC (R_V850_EPWORD, 2, 32, 0, dont, FALSE, v850),
1834 V800_RELOC (R_V810_TPBYTE, 0, 8, 0, dont, FALSE, v850),
1835 V800_RELOC (R_V810_TPHWORD, 1, 16, 0, dont, FALSE, v850),
1836 V800_RELOC (R_V810_TPWORD, 2, 32, 0, dont, FALSE, v850),
1837 V800_RELOC (R_V810_TPWLO, 1, 16, 0, dont, FALSE, v850),
1838 V800_RELOC (R_V810_TPWHI, 1, 16, 0, dont, FALSE, v850),
1839 V800_RELOC (R_V810_TPWHI1, 1, 16, 0, dont, FALSE, v850),
1840 V800_RELOC (R_V850_TPHWLO, 1, 16, 1, dont, FALSE, v850),
1841 V800_RELOC (R_V850_TPBLO, 2, 24, 0, dont, FALSE, v850),
1842 V800_RELOC (R_V810_TPWLO_1, 1, 16, 0, signed, FALSE, v850),
1843 V800_RELOC (R_V850_TPBLO_1, 2, 16, 0, signed, FALSE, v850),
1844 V800_RELOC (R_V850_TPHWLO_1, 1, 16, 0, signed, FALSE, v850),
1845 V800_RELOC (R_V850_TP23BIT, 2, 23, 0, signed, FALSE, v850),
1846 V800_RELOC (R_V850_TPW23BIT, 2, 23, 0, signed, FALSE, v850),
1847 V800_RELOC (R_V850_TPDW8, 2, 8, 0, signed, FALSE, v850)
1850 /* Map a bfd relocation into the appropriate howto structure. */
1852 static reloc_howto_type *
1853 v850_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1854 bfd_reloc_code_real_type code)
1858 for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;)
1859 if (v850_elf_reloc_map[i].bfd_reloc_val == code)
1861 unsigned int elf_reloc_val = v850_elf_reloc_map[i].elf_reloc_val;
1863 BFD_ASSERT (v850_elf_howto_table[elf_reloc_val].type == elf_reloc_val);
1865 return v850_elf_howto_table + elf_reloc_val;
1871 static reloc_howto_type *
1872 v850_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1878 i < sizeof (v850_elf_howto_table) / sizeof (v850_elf_howto_table[0]);
1880 if (v850_elf_howto_table[i].name != NULL
1881 && strcasecmp (v850_elf_howto_table[i].name, r_name) == 0)
1882 return &v850_elf_howto_table[i];
1887 /* Set the howto pointer for an V850 ELF reloc. */
1890 v850_elf_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
1892 Elf_Internal_Rela *dst)
1894 unsigned int r_type;
1896 r_type = ELF32_R_TYPE (dst->r_info);
1897 BFD_ASSERT (r_type < (unsigned int) R_V850_max);
1898 cache_ptr->howto = &v850_elf_howto_table[r_type];
1901 /* Set the howto pointer for a V850 ELF reloc (type RELA). */
1904 v850_elf_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
1905 arelent * cache_ptr,
1906 Elf_Internal_Rela *dst)
1908 unsigned int r_type;
1910 r_type = ELF32_R_TYPE (dst->r_info);
1911 BFD_ASSERT (r_type < (unsigned int) R_V850_max);
1912 cache_ptr->howto = &v850_elf_howto_table[r_type];
1916 v850_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
1918 return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
1919 || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_'));
1922 /* We overload some of the bfd_reloc error codes for own purposes. */
1923 #define bfd_reloc_gp_not_found bfd_reloc_other
1924 #define bfd_reloc_ep_not_found bfd_reloc_continue
1925 #define bfd_reloc_ctbp_not_found (bfd_reloc_dangerous + 1)
1927 /* Perform a relocation as part of a final link. */
1929 static bfd_reloc_status_type
1930 v850_elf_final_link_relocate (reloc_howto_type *howto,
1932 bfd *output_bfd ATTRIBUTE_UNUSED,
1933 asection *input_section,
1938 struct bfd_link_info *info,
1940 int is_local ATTRIBUTE_UNUSED)
1942 unsigned int r_type = howto->type;
1943 bfd_byte *hit_data = contents + offset;
1945 /* Adjust the value according to the relocation. */
1949 case R_V850_9_PCREL:
1950 value -= (input_section->output_section->vma
1951 + input_section->output_offset);
1956 case R_V850_16_PCREL:
1957 value -= (input_section->output_section->vma
1958 + input_section->output_offset
1961 /* If the sign extension will corrupt the value then we have overflowed. */
1962 if ((value & 0xffff0000) != 0xffff0000)
1963 return bfd_reloc_overflow;
1968 case R_V850_17_PCREL:
1969 value -= (input_section->output_section->vma
1970 + input_section->output_offset
1973 /* If the sign extension will corrupt the value then we have overflowed. */
1974 if (((value & 0xffff0000) != 0x0) && ((value & 0xffff0000) != 0xffff0000))
1975 return bfd_reloc_overflow;
1977 value = SEXT17 (value);
1981 case R_V850_22_PCREL:
1982 value -= (input_section->output_section->vma
1983 + input_section->output_offset
1986 /* If the sign extension will corrupt the value then we have overflowed. */
1987 if (((value & 0xffe00000) != 0x0) && ((value & 0xffe00000) != 0xffe00000))
1988 return bfd_reloc_overflow;
1990 /* Only the bottom 22 bits of the PC are valid. */
1991 value = SEXT22 (value);
1995 case R_V850_32_PCREL:
1996 value -= (input_section->output_section->vma
1997 + input_section->output_offset
2006 case R_V850_LO16_S1:
2007 case R_V850_LO16_SPLIT_OFFSET:
2022 case R_V850_ZDA_15_16_OFFSET:
2023 case R_V850_ZDA_16_16_OFFSET:
2024 case R_V850_ZDA_16_16_SPLIT_OFFSET:
2025 if (sym_sec == NULL)
2026 return bfd_reloc_undefined;
2028 value -= sym_sec->output_section->vma;
2031 case R_V850_SDA_15_16_OFFSET:
2032 case R_V850_SDA_16_16_OFFSET:
2033 case R_V850_SDA_16_16_SPLIT_OFFSET:
2034 case R_V810_GPWLO_1:
2037 struct bfd_link_hash_entry * h;
2039 if (sym_sec == NULL)
2040 return bfd_reloc_undefined;
2042 /* Get the value of __gp. */
2043 h = bfd_link_hash_lookup (info->hash, "__gp", FALSE, FALSE, TRUE);
2045 || h->type != bfd_link_hash_defined)
2046 return bfd_reloc_gp_not_found;
2048 gp = (h->u.def.value
2049 + h->u.def.section->output_section->vma
2050 + h->u.def.section->output_offset);
2052 value -= sym_sec->output_section->vma;
2053 value -= (gp - sym_sec->output_section->vma);
2057 case R_V850_TDA_4_4_OFFSET:
2058 case R_V850_TDA_4_5_OFFSET:
2059 case R_V850_TDA_7_7_OFFSET:
2060 case R_V850_TDA_7_8_OFFSET:
2061 case R_V850_TDA_6_8_OFFSET:
2062 case R_V850_TDA_16_16_OFFSET:
2065 struct bfd_link_hash_entry * h;
2067 /* Get the value of __ep. */
2068 h = bfd_link_hash_lookup (info->hash, "__ep", FALSE, FALSE, TRUE);
2070 || h->type != bfd_link_hash_defined)
2071 return bfd_reloc_ep_not_found;
2073 ep = (h->u.def.value
2074 + h->u.def.section->output_section->vma
2075 + h->u.def.section->output_offset);
2081 case R_V850_CALLT_6_7_OFFSET:
2084 struct bfd_link_hash_entry * h;
2086 /* Get the value of __ctbp. */
2087 h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
2089 || h->type != bfd_link_hash_defined)
2090 return bfd_reloc_ctbp_not_found;
2092 ctbp = (h->u.def.value
2093 + h->u.def.section->output_section->vma
2094 + h->u.def.section->output_offset);
2099 case R_V850_CALLT_15_16_OFFSET:
2100 case R_V850_CALLT_16_16_OFFSET:
2103 struct bfd_link_hash_entry * h;
2105 if (sym_sec == NULL)
2106 return bfd_reloc_undefined;
2108 /* Get the value of __ctbp. */
2109 h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
2111 || h->type != bfd_link_hash_defined)
2112 return bfd_reloc_ctbp_not_found;
2114 ctbp = (h->u.def.value
2115 + h->u.def.section->output_section->vma
2116 + h->u.def.section->output_offset);
2118 value -= sym_sec->output_section->vma;
2119 value -= (ctbp - sym_sec->output_section->vma);
2125 case R_V850_GNU_VTINHERIT:
2126 case R_V850_GNU_VTENTRY:
2127 case R_V850_LONGCALL:
2128 case R_V850_LONGJUMP:
2130 return bfd_reloc_ok;
2134 fprintf (stderr, "reloc number %d not recognised\n", r_type);
2136 return bfd_reloc_notsupported;
2139 /* Perform the relocation. */
2140 return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data);
2143 /* Relocate an V850 ELF section. */
2146 v850_elf_relocate_section (bfd *output_bfd,
2147 struct bfd_link_info *info,
2149 asection *input_section,
2151 Elf_Internal_Rela *relocs,
2152 Elf_Internal_Sym *local_syms,
2153 asection **local_sections)
2155 Elf_Internal_Shdr *symtab_hdr;
2156 struct elf_link_hash_entry **sym_hashes;
2157 Elf_Internal_Rela *rel;
2158 Elf_Internal_Rela *relend;
2160 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
2161 sym_hashes = elf_sym_hashes (input_bfd);
2163 /* Reset the list of remembered HI16S relocs to empty. */
2164 free_hi16s = previous_hi16s;
2165 previous_hi16s = NULL;
2169 relend = relocs + input_section->reloc_count;
2170 for (; rel < relend; rel++)
2172 unsigned int r_type;
2173 reloc_howto_type *howto;
2174 unsigned long r_symndx;
2175 Elf_Internal_Sym *sym;
2177 struct elf_link_hash_entry *h;
2179 bfd_reloc_status_type r;
2181 r_symndx = ELF32_R_SYM (rel->r_info);
2182 r_type = ELF32_R_TYPE (rel->r_info);
2184 if (r_type == R_V850_GNU_VTENTRY
2185 || r_type == R_V850_GNU_VTINHERIT)
2188 if (bfd_get_arch (input_bfd) == bfd_arch_v850_rh850)
2189 howto = v800_elf_howto_table + (r_type - R_V810_NONE);
2191 howto = v850_elf_howto_table + r_type;
2193 BFD_ASSERT (r_type == howto->type);
2198 if (r_symndx < symtab_hdr->sh_info)
2200 sym = local_syms + r_symndx;
2201 sec = local_sections[r_symndx];
2202 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2206 bfd_boolean unresolved_reloc, warned;
2208 /* Note - this check is delayed until now as it is possible and
2209 valid to have a file without any symbols but with relocs that
2210 can be processed. */
2211 if (sym_hashes == NULL)
2213 info->callbacks->warning
2214 (info, "no hash table available",
2215 NULL, input_bfd, input_section, (bfd_vma) 0);
2220 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2221 r_symndx, symtab_hdr, sym_hashes,
2223 unresolved_reloc, warned);
2226 if (sec != NULL && discarded_section (sec))
2227 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
2228 rel, 1, relend, howto, 0, contents);
2230 if (info->relocatable)
2233 /* FIXME: We should use the addend, but the COFF relocations don't. */
2234 r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
2236 contents, rel->r_offset,
2237 relocation, rel->r_addend,
2238 info, sec, h == NULL);
2240 if (r != bfd_reloc_ok)
2243 const char * msg = NULL;
2246 name = h->root.root.string;
2249 name = (bfd_elf_string_from_elf_section
2250 (input_bfd, symtab_hdr->sh_link, sym->st_name));
2251 if (name == NULL || *name == '\0')
2252 name = bfd_section_name (input_bfd, sec);
2257 case bfd_reloc_overflow:
2258 if (! ((*info->callbacks->reloc_overflow)
2259 (info, (h ? &h->root : NULL), name, howto->name,
2260 (bfd_vma) 0, input_bfd, input_section,
2265 case bfd_reloc_undefined:
2266 if (! ((*info->callbacks->undefined_symbol)
2267 (info, name, input_bfd, input_section,
2268 rel->r_offset, TRUE)))
2272 case bfd_reloc_outofrange:
2273 msg = _("internal error: out of range error");
2276 case bfd_reloc_notsupported:
2277 msg = _("internal error: unsupported relocation error");
2280 case bfd_reloc_dangerous:
2281 msg = _("internal error: dangerous relocation");
2284 case bfd_reloc_gp_not_found:
2285 msg = _("could not locate special linker symbol __gp");
2288 case bfd_reloc_ep_not_found:
2289 msg = _("could not locate special linker symbol __ep");
2292 case bfd_reloc_ctbp_not_found:
2293 msg = _("could not locate special linker symbol __ctbp");
2297 msg = _("internal error: unknown error");
2301 if (!((*info->callbacks->warning)
2302 (info, msg, name, input_bfd, input_section,
2314 v850_elf_gc_mark_hook (asection *sec,
2315 struct bfd_link_info *info,
2316 Elf_Internal_Rela *rel,
2317 struct elf_link_hash_entry *h,
2318 Elf_Internal_Sym *sym)
2321 switch (ELF32_R_TYPE (rel->r_info))
2323 case R_V850_GNU_VTINHERIT:
2324 case R_V850_GNU_VTENTRY:
2328 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2331 /* Set the right machine number and architecture. */
2334 v850_elf_object_p (bfd *abfd)
2336 enum bfd_architecture arch;
2339 switch (elf_elfheader (abfd)->e_machine)
2342 arch = bfd_arch_v850_rh850;
2343 mach = bfd_mach_v850e2v3;
2346 case EM_CYGNUS_V850:
2348 arch = bfd_arch_v850;
2349 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
2352 case E_V850_ARCH: mach = bfd_mach_v850; break;
2353 case E_V850E_ARCH: mach = bfd_mach_v850e; break;
2354 case E_V850E1_ARCH: mach = bfd_mach_v850e1; break;
2355 case E_V850E2_ARCH: mach = bfd_mach_v850e2; break;
2356 case E_V850E2V3_ARCH: mach = bfd_mach_v850e2v3; break;
2364 return bfd_default_set_arch_mach (abfd, arch, mach);
2367 /* Store the machine number in the flags field. */
2370 v850_elf_final_write_processing (bfd *abfd,
2371 bfd_boolean linker ATTRIBUTE_UNUSED)
2375 switch (bfd_get_arch (abfd))
2377 case bfd_arch_v850_rh850:
2379 elf_elfheader (abfd)->e_flags |= val;
2383 switch (bfd_get_mach (abfd))
2386 case bfd_mach_v850: val = E_V850_ARCH; break;
2387 case bfd_mach_v850e: val = E_V850E_ARCH; break;
2388 case bfd_mach_v850e1: val = E_V850E1_ARCH; break;
2389 case bfd_mach_v850e2: val = E_V850E2_ARCH; break;
2390 case bfd_mach_v850e2v3: val = E_V850E2V3_ARCH; break;
2392 elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
2393 elf_elfheader (abfd)->e_flags |= val;
2400 /* Function to keep V850 specific file flags. */
2403 v850_elf_set_private_flags (bfd *abfd, flagword flags)
2405 BFD_ASSERT (!elf_flags_init (abfd)
2406 || elf_elfheader (abfd)->e_flags == flags);
2408 elf_elfheader (abfd)->e_flags = flags;
2409 elf_flags_init (abfd) = TRUE;
2413 /* Merge backend specific data from an object file
2414 to the output object file when linking. */
2417 v850_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
2422 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2423 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
2426 in_flags = elf_elfheader (ibfd)->e_flags;
2427 out_flags = elf_elfheader (obfd)->e_flags;
2429 if (! elf_flags_init (obfd))
2431 /* If the input is the default architecture then do not
2432 bother setting the flags for the output architecture,
2433 instead allow future merges to do this. If no future
2434 merges ever set these flags then they will retain their
2435 unitialised values, which surprise surprise, correspond
2436 to the default values. */
2437 if (bfd_get_arch_info (ibfd)->the_default)
2440 elf_flags_init (obfd) = TRUE;
2441 elf_elfheader (obfd)->e_flags = in_flags;
2443 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
2444 && bfd_get_arch_info (obfd)->the_default)
2445 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2450 /* Check flag compatibility. */
2451 if (in_flags == out_flags)
2454 if (bfd_get_arch (obfd) == bfd_arch_v850_rh850)
2456 if ((in_flags & EF_V800_850E3) != (out_flags & EF_V800_850E3))
2458 _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
2460 elf_elfheader (obfd)->e_flags |= EF_V800_850E3;
2463 if ((in_flags & EF_RH850_DATA_ALIGN8) != (out_flags & EF_RH850_DATA_ALIGN8))
2465 _bfd_error_handler (_("%B: Alignment mismatch with previous modules"),
2467 elf_elfheader (obfd)->e_flags |= EF_RH850_DATA_ALIGN8;
2473 if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
2474 && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
2476 /* Allow earlier architecture binaries to be linked with later binaries.
2477 Set the output binary to the later architecture, except for v850e1,
2478 which we set to v850e. */
2479 if ( (in_flags & EF_V850_ARCH) == E_V850E1_ARCH
2480 && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
2483 if ( (in_flags & EF_V850_ARCH) == E_V850_ARCH
2484 && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
2486 elf_elfheader (obfd)->e_flags =
2487 ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
2491 if (( (in_flags & EF_V850_ARCH) == E_V850_ARCH
2492 || (in_flags & EF_V850_ARCH) == E_V850E_ARCH)
2493 && (out_flags & EF_V850_ARCH) == E_V850E2_ARCH)
2495 elf_elfheader (obfd)->e_flags =
2496 ((out_flags & ~ EF_V850_ARCH) | E_V850E2_ARCH);
2500 if (( (in_flags & EF_V850_ARCH) == E_V850_ARCH
2501 || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
2502 || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH)
2503 && (out_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
2505 elf_elfheader (obfd)->e_flags =
2506 ((out_flags & ~ EF_V850_ARCH) | E_V850E2V3_ARCH);
2510 _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
2517 /* Display the flags field. */
2520 v850_elf_print_private_bfd_data (bfd *abfd, void * ptr)
2522 FILE * file = (FILE *) ptr;
2524 BFD_ASSERT (abfd != NULL && ptr != NULL);
2526 _bfd_elf_print_private_bfd_data (abfd, ptr);
2528 /* xgettext:c-format. */
2529 fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
2531 if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
2533 if ((elf_elfheader (abfd)->e_flags & EF_RH850_ABI) != EF_RH850_ABI)
2534 fprintf (file, _("unknown v850 architecture"));
2535 else if (elf_elfheader (abfd)->e_flags & EF_V800_850E3)
2536 fprintf (file, _("v850 E3 architecture"));
2538 fprintf (file, _("v850 architecture"));
2540 if (elf_elfheader (abfd)->e_flags & EF_RH850_DATA_ALIGN8)
2541 fprintf (file, _(", 8-byte data alignment"));
2545 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
2548 case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
2549 case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break;
2550 case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
2551 case E_V850E2_ARCH: fprintf (file, _("v850e2 architecture")); break;
2552 case E_V850E2V3_ARCH: fprintf (file, _("v850e2v3 architecture")); break;
2561 /* V850 ELF uses four common sections. One is the usual one, and the
2562 others are for (small) objects in one of the special data areas:
2563 small, tiny and zero. All the objects are kept together, and then
2564 referenced via the gp register, the ep register or the r0 register
2565 respectively, which yields smaller, faster assembler code. This
2566 approach is copied from elf32-mips.c. */
2568 static asection v850_elf_scom_section;
2569 static asymbol v850_elf_scom_symbol;
2570 static asymbol * v850_elf_scom_symbol_ptr;
2571 static asection v850_elf_tcom_section;
2572 static asymbol v850_elf_tcom_symbol;
2573 static asymbol * v850_elf_tcom_symbol_ptr;
2574 static asection v850_elf_zcom_section;
2575 static asymbol v850_elf_zcom_symbol;
2576 static asymbol * v850_elf_zcom_symbol_ptr;
2578 /* Given a BFD section, try to locate the
2579 corresponding ELF section index. */
2582 v850_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2586 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2587 *retval = SHN_V850_SCOMMON;
2588 else if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
2589 *retval = SHN_V850_TCOMMON;
2590 else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
2591 *retval = SHN_V850_ZCOMMON;
2598 /* Handle the special V850 section numbers that a symbol may use. */
2601 v850_elf_symbol_processing (bfd *abfd, asymbol *asym)
2603 elf_symbol_type * elfsym = (elf_symbol_type *) asym;
2606 indx = elfsym->internal_elf_sym.st_shndx;
2608 /* If the section index is an "ordinary" index, then it may
2609 refer to a v850 specific section created by the assembler.
2610 Check the section's type and change the index it matches.
2612 FIXME: Should we alter the st_shndx field as well ? */
2614 if (indx < elf_numsections (abfd))
2615 switch (elf_elfsections (abfd)[indx]->sh_type)
2617 case SHT_V850_SCOMMON:
2618 indx = SHN_V850_SCOMMON;
2621 case SHT_V850_TCOMMON:
2622 indx = SHN_V850_TCOMMON;
2625 case SHT_V850_ZCOMMON:
2626 indx = SHN_V850_ZCOMMON;
2635 case SHN_V850_SCOMMON:
2636 if (v850_elf_scom_section.name == NULL)
2638 /* Initialize the small common section. */
2639 v850_elf_scom_section.name = ".scommon";
2640 v850_elf_scom_section.flags = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
2641 v850_elf_scom_section.output_section = & v850_elf_scom_section;
2642 v850_elf_scom_section.symbol = & v850_elf_scom_symbol;
2643 v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
2644 v850_elf_scom_symbol.name = ".scommon";
2645 v850_elf_scom_symbol.flags = BSF_SECTION_SYM;
2646 v850_elf_scom_symbol.section = & v850_elf_scom_section;
2647 v850_elf_scom_symbol_ptr = & v850_elf_scom_symbol;
2649 asym->section = & v850_elf_scom_section;
2650 asym->value = elfsym->internal_elf_sym.st_size;
2653 case SHN_V850_TCOMMON:
2654 if (v850_elf_tcom_section.name == NULL)
2656 /* Initialize the tcommon section. */
2657 v850_elf_tcom_section.name = ".tcommon";
2658 v850_elf_tcom_section.flags = SEC_IS_COMMON;
2659 v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
2660 v850_elf_tcom_section.symbol = & v850_elf_tcom_symbol;
2661 v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
2662 v850_elf_tcom_symbol.name = ".tcommon";
2663 v850_elf_tcom_symbol.flags = BSF_SECTION_SYM;
2664 v850_elf_tcom_symbol.section = & v850_elf_tcom_section;
2665 v850_elf_tcom_symbol_ptr = & v850_elf_tcom_symbol;
2667 asym->section = & v850_elf_tcom_section;
2668 asym->value = elfsym->internal_elf_sym.st_size;
2671 case SHN_V850_ZCOMMON:
2672 if (v850_elf_zcom_section.name == NULL)
2674 /* Initialize the zcommon section. */
2675 v850_elf_zcom_section.name = ".zcommon";
2676 v850_elf_zcom_section.flags = SEC_IS_COMMON;
2677 v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
2678 v850_elf_zcom_section.symbol = & v850_elf_zcom_symbol;
2679 v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
2680 v850_elf_zcom_symbol.name = ".zcommon";
2681 v850_elf_zcom_symbol.flags = BSF_SECTION_SYM;
2682 v850_elf_zcom_symbol.section = & v850_elf_zcom_section;
2683 v850_elf_zcom_symbol_ptr = & v850_elf_zcom_symbol;
2685 asym->section = & v850_elf_zcom_section;
2686 asym->value = elfsym->internal_elf_sym.st_size;
2691 /* Hook called by the linker routine which adds symbols from an object
2692 file. We must handle the special v850 section numbers here. */
2695 v850_elf_add_symbol_hook (bfd *abfd,
2696 struct bfd_link_info *info ATTRIBUTE_UNUSED,
2697 Elf_Internal_Sym *sym,
2698 const char **namep ATTRIBUTE_UNUSED,
2699 flagword *flagsp ATTRIBUTE_UNUSED,
2703 unsigned int indx = sym->st_shndx;
2705 /* If the section index is an "ordinary" index, then it may
2706 refer to a v850 specific section created by the assembler.
2707 Check the section's type and change the index it matches.
2709 FIXME: Should we alter the st_shndx field as well ? */
2711 if (indx < elf_numsections (abfd))
2712 switch (elf_elfsections (abfd)[indx]->sh_type)
2714 case SHT_V850_SCOMMON:
2715 indx = SHN_V850_SCOMMON;
2718 case SHT_V850_TCOMMON:
2719 indx = SHN_V850_TCOMMON;
2722 case SHT_V850_ZCOMMON:
2723 indx = SHN_V850_ZCOMMON;
2732 case SHN_V850_SCOMMON:
2733 *secp = bfd_make_section_old_way (abfd, ".scommon");
2734 (*secp)->flags |= SEC_IS_COMMON;
2735 *valp = sym->st_size;
2738 case SHN_V850_TCOMMON:
2739 *secp = bfd_make_section_old_way (abfd, ".tcommon");
2740 (*secp)->flags |= SEC_IS_COMMON;
2741 *valp = sym->st_size;
2744 case SHN_V850_ZCOMMON:
2745 *secp = bfd_make_section_old_way (abfd, ".zcommon");
2746 (*secp)->flags |= SEC_IS_COMMON;
2747 *valp = sym->st_size;
2755 v850_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2756 const char *name ATTRIBUTE_UNUSED,
2757 Elf_Internal_Sym *sym,
2758 asection *input_sec,
2759 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2761 /* If we see a common symbol, which implies a relocatable link, then
2762 if a symbol was in a special common section in an input file, mark
2763 it as a special common in the output file. */
2765 if (sym->st_shndx == SHN_COMMON)
2767 if (strcmp (input_sec->name, ".scommon") == 0)
2768 sym->st_shndx = SHN_V850_SCOMMON;
2769 else if (strcmp (input_sec->name, ".tcommon") == 0)
2770 sym->st_shndx = SHN_V850_TCOMMON;
2771 else if (strcmp (input_sec->name, ".zcommon") == 0)
2772 sym->st_shndx = SHN_V850_ZCOMMON;
2775 /* The price we pay for using h->other unused bits as flags in the
2776 linker is cleaning up after ourselves. */
2778 sym->st_other &= ~(V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA
2779 | V850_OTHER_ERROR);
2785 v850_elf_section_from_shdr (bfd *abfd,
2786 Elf_Internal_Shdr *hdr,
2790 /* There ought to be a place to keep ELF backend specific flags, but
2791 at the moment there isn't one. We just keep track of the
2792 sections by their name, instead. */
2794 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
2797 switch (hdr->sh_type)
2799 case SHT_V850_SCOMMON:
2800 case SHT_V850_TCOMMON:
2801 case SHT_V850_ZCOMMON:
2802 if (! bfd_set_section_flags (abfd, hdr->bfd_section,
2803 (bfd_get_section_flags (abfd,
2812 /* Set the correct type for a V850 ELF section. We do this
2813 by the section name, which is a hack, but ought to work. */
2816 v850_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
2817 Elf_Internal_Shdr *hdr,
2822 name = bfd_get_section_name (abfd, sec);
2824 if (strcmp (name, ".scommon") == 0)
2825 hdr->sh_type = SHT_V850_SCOMMON;
2826 else if (strcmp (name, ".tcommon") == 0)
2827 hdr->sh_type = SHT_V850_TCOMMON;
2828 else if (strcmp (name, ".zcommon") == 0)
2829 hdr->sh_type = SHT_V850_ZCOMMON;
2834 /* Delete some bytes from a section while relaxing. */
2837 v850_elf_relax_delete_bytes (bfd *abfd,
2843 Elf_Internal_Shdr *symtab_hdr;
2844 Elf32_External_Sym *extsyms;
2845 Elf32_External_Sym *esym;
2846 Elf32_External_Sym *esymend;
2848 unsigned int sec_shndx;
2850 Elf_Internal_Rela *irel;
2851 Elf_Internal_Rela *irelend;
2852 struct elf_link_hash_entry *sym_hash;
2853 Elf_Internal_Shdr *shndx_hdr;
2854 Elf_External_Sym_Shndx *shndx;
2856 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2857 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
2859 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
2861 contents = elf_section_data (sec)->this_hdr.contents;
2863 /* The deletion must stop at the next ALIGN reloc for an alignment
2864 power larger than the number of bytes we are deleting. */
2866 /* Actually delete the bytes. */
2867 #if (DEBUG_RELAX & 2)
2868 fprintf (stderr, "relax_delete: contents: sec: %s %p .. %p %x\n",
2869 sec->name, addr, toaddr, count );
2871 memmove (contents + addr, contents + addr + count,
2872 toaddr - addr - count);
2873 memset (contents + toaddr-count, 0, count);
2875 /* Adjust all the relocs. */
2876 irel = elf_section_data (sec)->relocs;
2877 irelend = irel + sec->reloc_count;
2878 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
2879 shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
2881 for (; irel < irelend; irel++)
2883 bfd_vma raddr, paddr, symval;
2884 Elf_Internal_Sym isym;
2886 /* Get the new reloc address. */
2887 raddr = irel->r_offset;
2888 if ((raddr >= (addr + count) && raddr < toaddr))
2889 irel->r_offset -= count;
2891 if (raddr >= addr && raddr < addr + count)
2893 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2898 if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
2901 bfd_elf32_swap_symbol_in (abfd,
2902 extsyms + ELF32_R_SYM (irel->r_info),
2903 shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
2906 if (isym.st_shndx != sec_shndx)
2909 /* Get the value of the symbol referred to by the reloc. */
2910 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2912 symval = isym.st_value;
2913 #if (DEBUG_RELAX & 2)
2915 char * name = bfd_elf_string_from_elf_section
2916 (abfd, symtab_hdr->sh_link, isym.st_name);
2918 "relax_delete: local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
2919 sec->name, name, isym.st_name,
2920 sec->output_section->vma, sec->output_offset,
2921 isym.st_value, irel->r_addend);
2928 struct elf_link_hash_entry * h;
2930 /* An external symbol. */
2931 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2933 h = elf_sym_hashes (abfd) [indx];
2934 BFD_ASSERT (h != NULL);
2936 symval = h->root.u.def.value;
2937 #if (DEBUG_RELAX & 2)
2939 "relax_delete: defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
2940 sec->name, h->root.root.string, h->root.u.def.value,
2941 sec->output_section->vma, sec->output_offset, irel->r_addend);
2945 paddr = symval + irel->r_addend;
2947 if ( (symval >= addr + count && symval < toaddr)
2948 && (paddr < addr + count || paddr >= toaddr))
2949 irel->r_addend += count;
2950 else if ( (symval < addr + count || symval >= toaddr)
2951 && (paddr >= addr + count && paddr < toaddr))
2952 irel->r_addend -= count;
2955 /* Adjust the local symbols defined in this section. */
2957 esymend = esym + symtab_hdr->sh_info;
2959 for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
2961 Elf_Internal_Sym isym;
2963 bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
2965 if (isym.st_shndx == sec_shndx
2966 && isym.st_value >= addr + count
2967 && isym.st_value < toaddr)
2969 isym.st_value -= count;
2971 if (isym.st_value + isym.st_size >= toaddr)
2972 isym.st_size += count;
2974 bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
2976 else if (isym.st_shndx == sec_shndx
2977 && isym.st_value < addr + count)
2979 if (isym.st_value+isym.st_size >= addr + count
2980 && isym.st_value+isym.st_size < toaddr)
2981 isym.st_size -= count;
2983 if (isym.st_value >= addr
2984 && isym.st_value < addr + count)
2985 isym.st_value = addr;
2987 bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
2991 /* Now adjust the global symbols defined in this section. */
2992 esym = extsyms + symtab_hdr->sh_info;
2993 esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
2995 for (sym_index = 0; esym < esymend; esym ++, sym_index ++)
2997 Elf_Internal_Sym isym;
2999 bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
3000 sym_hash = elf_sym_hashes (abfd) [sym_index];
3002 if (isym.st_shndx == sec_shndx
3003 && ((sym_hash)->root.type == bfd_link_hash_defined
3004 || (sym_hash)->root.type == bfd_link_hash_defweak)
3005 && (sym_hash)->root.u.def.section == sec
3006 && (sym_hash)->root.u.def.value >= addr + count
3007 && (sym_hash)->root.u.def.value < toaddr)
3009 if ((sym_hash)->root.u.def.value + isym.st_size >= toaddr)
3011 isym.st_size += count;
3012 bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3015 (sym_hash)->root.u.def.value -= count;
3017 else if (isym.st_shndx == sec_shndx
3018 && ((sym_hash)->root.type == bfd_link_hash_defined
3019 || (sym_hash)->root.type == bfd_link_hash_defweak)
3020 && (sym_hash)->root.u.def.section == sec
3021 && (sym_hash)->root.u.def.value < addr + count)
3023 if ((sym_hash)->root.u.def.value+isym.st_size >= addr + count
3024 && (sym_hash)->root.u.def.value+isym.st_size < toaddr)
3025 isym.st_size -= count;
3027 if ((sym_hash)->root.u.def.value >= addr
3028 && (sym_hash)->root.u.def.value < addr + count)
3029 (sym_hash)->root.u.def.value = addr;
3031 bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3041 #define NOP_OPCODE (0x0000)
3042 #define MOVHI 0x0640 /* 4byte. */
3043 #define MOVHI_MASK 0x07e0
3044 #define MOVHI_R1(insn) ((insn) & 0x1f) /* 4byte. */
3045 #define MOVHI_R2(insn) ((insn) >> 11)
3046 #define MOVEA 0x0620 /* 2byte. */
3047 #define MOVEA_MASK 0x07e0
3048 #define MOVEA_R1(insn) ((insn) & 0x1f)
3049 #define MOVEA_R2(insn) ((insn) >> 11)
3050 #define JARL_4 0x00040780 /* 4byte. */
3051 #define JARL_4_MASK 0xFFFF07FF
3052 #define JARL_R2(insn) (int)(((insn) & (~JARL_4_MASK)) >> 11)
3053 #define ADD_I 0x0240 /* 2byte. */
3054 #define ADD_I_MASK 0x07e0
3055 #define ADD_I5(insn) ((((insn) & 0x001f) << 11) >> 11) /* 2byte. */
3056 #define ADD_R2(insn) ((insn) >> 11)
3057 #define JMP_R 0x0060 /* 2byte. */
3058 #define JMP_R_MASK 0xFFE0
3059 #define JMP_R1(insn) ((insn) & 0x1f)
3062 v850_elf_relax_section (bfd *abfd,
3064 struct bfd_link_info *link_info,
3067 Elf_Internal_Shdr *symtab_hdr;
3068 Elf_Internal_Rela *internal_relocs;
3069 Elf_Internal_Rela *irel;
3070 Elf_Internal_Rela *irelend;
3071 Elf_Internal_Rela *irelalign = NULL;
3072 Elf_Internal_Sym *isymbuf = NULL;
3073 bfd_byte *contents = NULL;
3076 int align_pad_size = 0;
3077 bfd_boolean result = TRUE;
3081 if (link_info->relocatable
3082 || (sec->flags & SEC_RELOC) == 0
3083 || sec->reloc_count == 0)
3086 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
3088 internal_relocs = (_bfd_elf_link_read_relocs
3089 (abfd, sec, NULL, NULL, link_info->keep_memory));
3090 if (internal_relocs == NULL)
3093 irelend = internal_relocs + sec->reloc_count;
3095 while (addr < sec->size)
3099 for (irel = internal_relocs; irel < irelend; irel ++)
3100 if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
3101 && irel->r_offset > addr
3102 && irel->r_offset < toaddr)
3103 toaddr = irel->r_offset;
3106 fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
3107 addr, toaddr, align_pad_size);
3112 bfd_vma alignmoveto;
3114 alignmoveto = BFD_ALIGN (addr - align_pad_size, 1 << irelalign->r_addend);
3115 alignto = BFD_ALIGN (addr, 1 << irelalign->r_addend);
3117 if (alignmoveto < alignto)
3121 align_pad_size = alignto - alignmoveto;
3123 fprintf (stderr, "relax move region 0x%x to 0x%x delete size 0x%x\n",
3124 alignmoveto, toaddr, align_pad_size);
3126 if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
3127 toaddr, align_pad_size))
3130 for (i = BFD_ALIGN (toaddr - align_pad_size, 1);
3131 (i + 1) < toaddr; i += 2)
3132 bfd_put_16 (abfd, NOP_OPCODE, contents + i);
3140 for (irel = internal_relocs; irel < irelend; irel++)
3147 Elf_Internal_Rela *hi_irelfn;
3148 Elf_Internal_Rela *lo_irelfn;
3149 Elf_Internal_Rela *irelcall;
3150 bfd_signed_vma foff;
3151 unsigned int r_type;
3153 if (! (irel->r_offset >= addr && irel->r_offset < toaddr
3154 && (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
3155 || ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)))
3159 fprintf (stderr, "relax check r_info 0x%x r_offset 0x%x r_addend 0x%x\n",
3165 /* Get the section contents. */
3166 if (contents == NULL)
3168 if (elf_section_data (sec)->this_hdr.contents != NULL)
3169 contents = elf_section_data (sec)->this_hdr.contents;
3172 if (! bfd_malloc_and_get_section (abfd, sec, &contents))
3177 /* Read this BFD's local symbols if we haven't done so already. */
3178 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
3180 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3181 if (isymbuf == NULL)
3182 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3183 symtab_hdr->sh_info, 0,
3185 if (isymbuf == NULL)
3189 laddr = irel->r_offset;
3191 if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
3193 /* Check code for -mlong-calls output. */
3194 if (laddr + 16 <= (bfd_vma) sec->size)
3196 insn[0] = bfd_get_16 (abfd, contents + laddr);
3197 insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
3198 insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
3199 insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
3200 insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
3202 if ((insn[0] & MOVHI_MASK) != MOVHI
3203 || MOVHI_R1 (insn[0]) != 0)
3207 && ((insn[1] & MOVEA_MASK) != MOVEA
3208 || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
3212 && (insn[2] & JARL_4_MASK) != JARL_4)
3216 && ((insn[3] & ADD_I_MASK) != ADD_I
3217 || ADD_I5 (insn[3]) != 4
3218 || JARL_R2 (insn[2]) != ADD_R2 (insn[3])))
3222 && ((insn[4] & JMP_R_MASK) != JMP_R
3223 || MOVEA_R2 (insn[1]) != JMP_R1 (insn[4])))
3228 ((*_bfd_error_handler)
3229 ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insns",
3230 bfd_get_filename (abfd), (unsigned long) irel->r_offset));
3237 ((*_bfd_error_handler)
3238 ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insn 0x%x",
3239 bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
3244 /* Get the reloc for the address from which the register is
3245 being loaded. This reloc will tell us which function is
3246 actually being called. */
3248 for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
3250 r_type = ELF32_R_TYPE (hi_irelfn->r_info);
3252 if (hi_irelfn->r_offset == laddr + 2
3253 && (r_type == (int) R_V850_HI16_S || r_type == (int) R_V810_WHI1))
3257 for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
3259 r_type = ELF32_R_TYPE (lo_irelfn->r_info);
3261 if (lo_irelfn->r_offset == laddr + 6
3262 && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
3266 for (irelcall = internal_relocs; irelcall < irelend; irelcall ++)
3268 r_type = ELF32_R_TYPE (irelcall->r_info);
3270 if (irelcall->r_offset == laddr + 8
3271 && (r_type == (int) R_V850_22_PCREL || r_type == (int) R_V850_PCR22))
3275 if ( hi_irelfn == irelend
3276 || lo_irelfn == irelend
3277 || irelcall == irelend)
3279 ((*_bfd_error_handler)
3280 ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc",
3281 bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
3286 if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
3288 Elf_Internal_Sym * isym;
3290 /* A local symbol. */
3291 isym = isymbuf + ELF32_R_SYM (irelcall->r_info);
3293 symval = isym->st_value;
3298 struct elf_link_hash_entry * h;
3300 /* An external symbol. */
3301 indx = ELF32_R_SYM (irelcall->r_info) - symtab_hdr->sh_info;
3302 h = elf_sym_hashes (abfd)[indx];
3303 BFD_ASSERT (h != NULL);
3305 if ( h->root.type != bfd_link_hash_defined
3306 && h->root.type != bfd_link_hash_defweak)
3307 /* This appears to be a reference to an undefined
3308 symbol. Just ignore it--it will be caught by the
3309 regular reloc processing. */
3312 symval = h->root.u.def.value;
3315 if (symval + irelcall->r_addend != irelcall->r_offset + 4)
3317 ((*_bfd_error_handler)
3318 ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc 0x%lx",
3319 bfd_get_filename (abfd), (unsigned long) irel->r_offset, irelcall->r_offset ));
3324 /* Get the value of the symbol referred to by the reloc. */
3325 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3327 Elf_Internal_Sym *isym;
3330 /* A local symbol. */
3331 isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
3333 if (isym->st_shndx == SHN_UNDEF)
3334 sym_sec = bfd_und_section_ptr;
3335 else if (isym->st_shndx == SHN_ABS)
3336 sym_sec = bfd_abs_section_ptr;
3337 else if (isym->st_shndx == SHN_COMMON)
3338 sym_sec = bfd_com_section_ptr;
3340 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3341 symval = (isym->st_value
3342 + sym_sec->output_section->vma
3343 + sym_sec->output_offset);
3348 struct elf_link_hash_entry *h;
3350 /* An external symbol. */
3351 indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
3352 h = elf_sym_hashes (abfd)[indx];
3353 BFD_ASSERT (h != NULL);
3355 if ( h->root.type != bfd_link_hash_defined
3356 && h->root.type != bfd_link_hash_defweak)
3357 /* This appears to be a reference to an undefined
3358 symbol. Just ignore it--it will be caught by the
3359 regular reloc processing. */
3362 symval = (h->root.u.def.value
3363 + h->root.u.def.section->output_section->vma
3364 + h->root.u.def.section->output_offset);
3367 addend = irel->r_addend;
3369 foff = (symval + addend
3371 + sec->output_section->vma
3372 + sec->output_offset
3375 fprintf (stderr, "relax longcall r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
3378 + sec->output_section->vma
3379 + sec->output_offset),
3380 symval, addend, foff);
3383 if (foff < -0x100000 || foff >= 0x100000)
3384 /* After all that work, we can't shorten this function call. */
3387 /* For simplicity of coding, we are going to modify the section
3388 contents, the section relocs, and the BFD symbol table. We
3389 must tell the rest of the code not to free up this
3390 information. It would be possible to instead create a table
3391 of changes which have to be made, as is done in coff-mips.c;
3392 that would be more work, but would require less memory when
3393 the linker is run. */
3394 elf_section_data (sec)->relocs = internal_relocs;
3395 elf_section_data (sec)->this_hdr.contents = contents;
3396 symtab_hdr->contents = (bfd_byte *) isymbuf;
3398 /* Replace the long call with a jarl. */
3399 if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3400 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_PCR22);
3402 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
3406 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3407 /* If this needs to be changed because of future relaxing,
3408 it will be handled here like other internal IND12W
3411 0x00000780 | (JARL_R2 (insn[2])<<11) | ((addend << 16) & 0xffff) | ((addend >> 16) & 0xf),
3412 contents + irel->r_offset);
3414 /* We can't fully resolve this yet, because the external
3415 symbol value may be changed by future relaxing.
3416 We let the final link phase handle it. */
3417 bfd_put_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
3418 contents + irel->r_offset);
3421 ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3423 ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3425 ELF32_R_INFO (ELF32_R_SYM (irelcall->r_info), R_V850_NONE);
3427 if (! v850_elf_relax_delete_bytes (abfd, sec,
3428 irel->r_offset + 4, toaddr, 12))
3431 align_pad_size += 12;
3433 else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
3435 /* Check code for -mlong-jumps output. */
3436 if (laddr + 10 <= (bfd_vma) sec->size)
3438 insn[0] = bfd_get_16 (abfd, contents + laddr);
3439 insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
3440 insn[2] = bfd_get_16 (abfd, contents + laddr + 8);
3442 if ((insn[0] & MOVHI_MASK) != MOVHI
3443 || MOVHI_R1 (insn[0]) != 0)
3447 && ((insn[1] & MOVEA_MASK) != MOVEA
3448 || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
3452 && ((insn[2] & JMP_R_MASK) != JMP_R
3453 || MOVEA_R2 (insn[1]) != JMP_R1 (insn[2])))
3458 ((*_bfd_error_handler)
3459 ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insns",
3460 bfd_get_filename (abfd), (unsigned long) irel->r_offset));
3467 ((*_bfd_error_handler)
3468 ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insn 0x%x",
3469 bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
3474 /* Get the reloc for the address from which the register is
3475 being loaded. This reloc will tell us which function is
3476 actually being called. */
3477 for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
3479 r_type = ELF32_R_TYPE (hi_irelfn->r_info);
3481 if (hi_irelfn->r_offset == laddr + 2
3482 && ((r_type == (int) R_V850_HI16_S) || r_type == (int) R_V810_WHI1))
3486 for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
3488 r_type = ELF32_R_TYPE (lo_irelfn->r_info);
3490 if (lo_irelfn->r_offset == laddr + 6
3491 && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
3495 if ( hi_irelfn == irelend
3496 || lo_irelfn == irelend)
3498 ((*_bfd_error_handler)
3499 ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized reloc",
3500 bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
3505 /* Get the value of the symbol referred to by the reloc. */
3506 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3508 Elf_Internal_Sym * isym;
3511 /* A local symbol. */
3512 isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
3514 if (isym->st_shndx == SHN_UNDEF)
3515 sym_sec = bfd_und_section_ptr;
3516 else if (isym->st_shndx == SHN_ABS)
3517 sym_sec = bfd_abs_section_ptr;
3518 else if (isym->st_shndx == SHN_COMMON)
3519 sym_sec = bfd_com_section_ptr;
3521 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3522 symval = (isym->st_value
3523 + sym_sec->output_section->vma
3524 + sym_sec->output_offset);
3527 char * name = bfd_elf_string_from_elf_section
3528 (abfd, symtab_hdr->sh_link, isym->st_name);
3530 fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
3531 sym_sec->name, name, isym->st_name,
3532 sym_sec->output_section->vma,
3533 sym_sec->output_offset,
3534 isym->st_value, irel->r_addend);
3541 struct elf_link_hash_entry * h;
3543 /* An external symbol. */
3544 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
3545 h = elf_sym_hashes (abfd)[indx];
3546 BFD_ASSERT (h != NULL);
3548 if ( h->root.type != bfd_link_hash_defined
3549 && h->root.type != bfd_link_hash_defweak)
3550 /* This appears to be a reference to an undefined
3551 symbol. Just ignore it--it will be caught by the
3552 regular reloc processing. */
3555 symval = (h->root.u.def.value
3556 + h->root.u.def.section->output_section->vma
3557 + h->root.u.def.section->output_offset);
3560 "relax longjump defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
3561 sec->name, h->root.root.string, h->root.u.def.value,
3562 sec->output_section->vma, sec->output_offset, irel->r_addend);
3566 addend = irel->r_addend;
3568 foff = (symval + addend
3570 + sec->output_section->vma
3571 + sec->output_offset
3574 fprintf (stderr, "relax longjump r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
3577 + sec->output_section->vma
3578 + sec->output_offset),
3579 symval, addend, foff);
3581 if (foff < -0x100000 || foff >= 0x100000)
3582 /* After all that work, we can't shorten this function call. */
3585 /* For simplicity of coding, we are going to modify the section
3586 contents, the section relocs, and the BFD symbol table. We
3587 must tell the rest of the code not to free up this
3588 information. It would be possible to instead create a table
3589 of changes which have to be made, as is done in coff-mips.c;
3590 that would be more work, but would require less memory when
3591 the linker is run. */
3592 elf_section_data (sec)->relocs = internal_relocs;
3593 elf_section_data (sec)->this_hdr.contents = contents;
3594 symtab_hdr->contents = (bfd_byte *) isymbuf;
3596 if (foff < -0x100 || foff >= 0x100)
3598 /* Replace the long jump with a jr. */
3600 if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3601 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PCR22);
3604 ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
3606 irel->r_addend = addend;
3609 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3610 /* If this needs to be changed because of future relaxing,
3611 it will be handled here like other internal IND12W
3614 0x00000780 | ((addend << 15) & 0xffff0000) | ((addend >> 17) & 0xf),
3615 contents + irel->r_offset);
3617 /* We can't fully resolve this yet, because the external
3618 symbol value may be changed by future relaxing.
3619 We let the final link phase handle it. */
3620 bfd_put_32 (abfd, 0x00000780, contents + irel->r_offset);
3623 ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3625 ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3626 if (!v850_elf_relax_delete_bytes (abfd, sec,
3627 irel->r_offset + 4, toaddr, 6))
3630 align_pad_size += 6;
3634 /* Replace the long jump with a br. */
3636 if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3637 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PC9);
3640 ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_9_PCREL);
3642 irel->r_addend = addend;
3645 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3646 /* If this needs to be changed because of future relaxing,
3647 it will be handled here like other internal IND12W
3650 0x0585 | ((addend << 10) & 0xf800) | ((addend << 3) & 0x0070),
3651 contents + irel->r_offset);
3653 /* We can't fully resolve this yet, because the external
3654 symbol value may be changed by future relaxing.
3655 We let the final link phase handle it. */
3656 bfd_put_16 (abfd, 0x0585, contents + irel->r_offset);
3659 ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3661 ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3662 if (!v850_elf_relax_delete_bytes (abfd, sec,
3663 irel->r_offset + 2, toaddr, 8))
3666 align_pad_size += 8;
3672 for (irel = internal_relocs; irel < irelend; irel++)
3674 if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
3675 && irel->r_offset == toaddr)
3677 irel->r_offset -= align_pad_size;
3679 if (irelalign == NULL || irelalign->r_addend > irel->r_addend)
3690 fprintf (stderr, "relax pad %d shorten %d -> %d\n",
3693 sec->size - align_pad_size);
3695 sec->size -= align_pad_size;
3699 if (internal_relocs != NULL
3700 && elf_section_data (sec)->relocs != internal_relocs)
3701 free (internal_relocs);
3703 if (contents != NULL
3704 && elf_section_data (sec)->this_hdr.contents != (unsigned char *) contents)
3708 && symtab_hdr->contents != (bfd_byte *) isymbuf)
3718 static const struct bfd_elf_special_section v850_elf_special_sections[] =
3720 { STRING_COMMA_LEN (".call_table_data"), 0, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE) },
3721 { STRING_COMMA_LEN (".call_table_text"), 0, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
3723 { STRING_COMMA_LEN (".rosdata"), -2, SHT_PROGBITS, (SHF_ALLOC
3724 + SHF_V850_GPREL) },
3725 { STRING_COMMA_LEN (".rozdata"), -2, SHT_PROGBITS, (SHF_ALLOC
3726 + SHF_V850_R0REL) },
3727 { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
3728 + SHF_V850_GPREL) },
3729 { STRING_COMMA_LEN (".scommon"), -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
3730 + SHF_V850_GPREL) },
3731 { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
3732 + SHF_V850_GPREL) },
3733 { STRING_COMMA_LEN (".tbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
3734 + SHF_V850_EPREL) },
3735 { STRING_COMMA_LEN (".tcommon"), -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
3736 + SHF_V850_R0REL) },
3737 { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
3738 + SHF_V850_EPREL) },
3739 { STRING_COMMA_LEN (".zbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
3740 + SHF_V850_R0REL) },
3741 { STRING_COMMA_LEN (".zcommon"), -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
3742 + SHF_V850_R0REL) },
3743 { STRING_COMMA_LEN (".zdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
3744 + SHF_V850_R0REL) },
3745 { NULL, 0, 0, 0, 0 }
3748 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
3749 #define TARGET_LITTLE_NAME "elf32-v850"
3750 #define ELF_ARCH bfd_arch_v850
3751 #define ELF_MACHINE_CODE EM_V850
3752 #define ELF_MACHINE_ALT1 EM_CYGNUS_V850
3753 #define ELF_MAXPAGESIZE 0x1000
3755 #define elf_info_to_howto v850_elf_info_to_howto_rela
3756 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
3758 #define elf_backend_check_relocs v850_elf_check_relocs
3759 #define elf_backend_relocate_section v850_elf_relocate_section
3760 #define elf_backend_object_p v850_elf_object_p
3761 #define elf_backend_final_write_processing v850_elf_final_write_processing
3762 #define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
3763 #define elf_backend_symbol_processing v850_elf_symbol_processing
3764 #define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
3765 #define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
3766 #define elf_backend_section_from_shdr v850_elf_section_from_shdr
3767 #define elf_backend_fake_sections v850_elf_fake_sections
3768 #define elf_backend_gc_mark_hook v850_elf_gc_mark_hook
3769 #define elf_backend_special_sections v850_elf_special_sections
3771 #define elf_backend_can_gc_sections 1
3772 #define elf_backend_rela_normal 1
3774 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
3775 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
3776 #define bfd_elf32_bfd_reloc_name_lookup v850_elf_reloc_name_lookup
3777 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
3778 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
3779 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
3780 #define bfd_elf32_bfd_relax_section v850_elf_relax_section
3782 #define elf_symbol_leading_char '_'
3785 #define elf32_bed elf32_v850_bed
3787 #include "elf32-target.h"
3789 /* Map BFD reloc types to V800 ELF reloc types. */
3791 static const struct v850_elf_reloc_map v800_elf_reloc_map[] =
3793 { BFD_RELOC_NONE, R_V810_NONE },
3794 { BFD_RELOC_8, R_V810_BYTE },
3795 { BFD_RELOC_16, R_V810_HWORD },
3796 { BFD_RELOC_32, R_V810_WORD },
3797 { BFD_RELOC_LO16, R_V810_WLO },
3798 { BFD_RELOC_HI16, R_V810_WHI },
3799 { BFD_RELOC_HI16_S, R_V810_WHI1 },
3800 { BFD_RELOC_V850_32_PCREL, R_V850_PC32 },
3801 { BFD_RELOC_V850_22_PCREL, R_V850_PCR22 },
3802 { BFD_RELOC_V850_17_PCREL, R_V850_PC17 },
3803 { BFD_RELOC_V850_16_PCREL, R_V850_PC16U },
3804 { BFD_RELOC_V850_9_PCREL, R_V850_PC9 },
3805 { BFD_RELOC_V850_LO16_S1, R_V810_WLO_1 }, /* Or R_V850_HWLO or R_V850_HWLO_1. */
3806 { BFD_RELOC_V850_23, R_V850_WLO23 },
3807 { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_BLO },
3808 { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V810_HWORD },
3809 { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V810_HWORD },
3810 { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V810_HWORD },
3811 { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V810_GPWLO_1 }
3814 /* Map a bfd relocation into the appropriate howto structure. */
3816 static reloc_howto_type *
3817 v800_elf_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
3821 BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
3823 for (i = ARRAY_SIZE (v800_elf_reloc_map); i --;)
3824 if (v800_elf_reloc_map[i].bfd_reloc_val == code)
3826 unsigned int elf_reloc_val = v800_elf_reloc_map[i].elf_reloc_val;
3827 unsigned int idx = elf_reloc_val - R_V810_NONE;
3829 BFD_ASSERT (v800_elf_howto_table[idx].type == elf_reloc_val);
3831 return v800_elf_howto_table + idx;
3835 fprintf (stderr, "failed to find v800 equiv of bfd reloc code %d\n", code);
3840 static reloc_howto_type *
3841 v800_elf_reloc_name_lookup (bfd * abfd, const char * r_name)
3845 BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
3847 for (i = ARRAY_SIZE (v800_elf_howto_table); i--;)
3848 if (v800_elf_howto_table[i].name != NULL
3849 && strcasecmp (v800_elf_howto_table[i].name, r_name) == 0)
3850 return v800_elf_howto_table + i;
3856 /* Set the howto pointer in CACHE_PTR for a V800 ELF reloc. */
3859 v800_elf_info_to_howto (bfd * abfd,
3860 arelent * cache_ptr,
3861 Elf_Internal_Rela * dst)
3863 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
3865 BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
3867 BFD_ASSERT (r_type < (unsigned int) R_V800_max);
3869 if (r_type == R_V800_NONE)
3870 r_type = R_V810_NONE;
3872 BFD_ASSERT (r_type >= (unsigned int) R_V810_NONE);
3873 r_type -= R_V810_NONE;
3874 BFD_ASSERT (r_type < ARRAY_SIZE (v800_elf_howto_table));
3876 cache_ptr->howto = v800_elf_howto_table + r_type;
3880 #undef TARGET_LITTLE_SYM
3881 #define TARGET_LITTLE_SYM bfd_elf32_v850_rh850_vec
3882 #undef TARGET_LITTLE_NAME
3883 #define TARGET_LITTLE_NAME "elf32-v850-rh850"
3885 #define ELF_ARCH bfd_arch_v850_rh850
3886 #undef ELF_MACHINE_CODE
3887 #define ELF_MACHINE_CODE EM_V800
3888 #undef ELF_MACHINE_ALT1
3891 #define elf32_bed elf32_v850_rh850_bed
3893 #undef elf_info_to_howto
3894 #define elf_info_to_howto v800_elf_info_to_howto
3895 #undef elf_info_to_howto_rel
3896 #define elf_info_to_howto_rel NULL
3897 #undef bfd_elf32_bfd_reloc_type_lookup
3898 #define bfd_elf32_bfd_reloc_type_lookup v800_elf_reloc_type_lookup
3899 #undef bfd_elf32_bfd_reloc_name_lookup
3900 #define bfd_elf32_bfd_reloc_name_lookup v800_elf_reloc_name_lookup
3902 #include "elf32-target.h"