1 /* V850-specific support for 32-bit ELF
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
23 dependencies. As is the gas & simulator code or the v850. */
33 /* sign-extend a 24-bit number */
34 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
36 static reloc_howto_type *v850_elf_reloc_type_lookup
37 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
38 static void v850_elf_info_to_howto_rel
39 PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
40 static bfd_reloc_status_type v850_elf_reloc
41 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
42 static boolean v850_elf_is_local_label_name PARAMS ((bfd *, const char *));
43 static boolean v850_elf_relocate_section PARAMS((bfd *,
44 struct bfd_link_info *,
51 /* Try to minimize the amount of space occupied by relocation tables
52 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
55 /* Note: It is REQUIRED that the 'type' value of each entry in this array
56 match the index of the entry in the array. */
57 static reloc_howto_type v850_elf_howto_table[] =
59 /* This reloc does nothing. */
60 HOWTO (R_V850_NONE, /* type */
62 2, /* size (0 = byte, 1 = short, 2 = long) */
64 false, /* pc_relative */
66 complain_overflow_bitfield, /* complain_on_overflow */
67 bfd_elf_generic_reloc, /* special_function */
68 "R_V850_NONE", /* name */
69 false, /* partial_inplace */
72 false), /* pcrel_offset */
74 /* A PC relative 9 bit branch. */
75 HOWTO (R_V850_9_PCREL, /* type */
77 2, /* size (0 = byte, 1 = short, 2 = long) */
79 true, /* pc_relative */
81 complain_overflow_bitfield, /* complain_on_overflow */
82 v850_elf_reloc, /* special_function */
83 "R_V850_9_PCREL", /* name */
84 false, /* partial_inplace */
85 0x00ffffff, /* src_mask */
86 0x00ffffff, /* dst_mask */
87 true), /* pcrel_offset */
89 /* A PC relative 22 bit branch. */
90 HOWTO (R_V850_22_PCREL, /* type */
92 2, /* size (0 = byte, 1 = short, 2 = long) */
94 true, /* pc_relative */
96 complain_overflow_signed, /* complain_on_overflow */
97 v850_elf_reloc, /* special_function */
98 "R_V850_22_PCREL", /* name */
99 false, /* partial_inplace */
100 0x07ffff80, /* src_mask */
101 0x07ffff80, /* dst_mask */
102 true), /* pcrel_offset */
104 /* High 16 bits of symbol value. */
105 HOWTO (R_V850_HI16_S, /* type */
107 1, /* size (0 = byte, 1 = short, 2 = long) */
109 false, /* pc_relative */
111 complain_overflow_dont, /* complain_on_overflow */
112 v850_elf_reloc, /* special_function */
113 "R_V850_HI16_S", /* name */
114 true, /* partial_inplace */
115 0xffff, /* src_mask */
116 0xffff, /* dst_mask */
117 false), /* pcrel_offset */
119 /* High 16 bits of symbol value. */
120 HOWTO (R_V850_HI16, /* type */
122 1, /* size (0 = byte, 1 = short, 2 = long) */
124 false, /* pc_relative */
126 complain_overflow_dont, /* complain_on_overflow */
127 v850_elf_reloc, /* special_function */
128 "R_V850_HI16", /* name */
129 true, /* partial_inplace */
130 0xffff, /* src_mask */
131 0xffff, /* dst_mask */
132 false), /* pcrel_offset */
134 /* Low 16 bits of symbol value. */
135 HOWTO (R_V850_LO16, /* type */
137 1, /* size (0 = byte, 1 = short, 2 = long) */
139 false, /* pc_relative */
141 complain_overflow_dont, /* complain_on_overflow */
142 v850_elf_reloc, /* special_function */
143 "R_V850_LO16", /* name */
144 true, /* partial_inplace */
145 0xffff, /* src_mask */
146 0xffff, /* dst_mask */
147 false), /* pcrel_offset */
149 /* Simple 32bit reloc. */
150 HOWTO (R_V850_32, /* type */
152 2, /* size (0 = byte, 1 = short, 2 = long) */
154 false, /* pc_relative */
156 complain_overflow_dont, /* complain_on_overflow */
157 v850_elf_reloc, /* special_function */
158 "R_V850_32", /* name */
159 true, /* partial_inplace */
160 0xffffffff, /* src_mask */
161 0xffffffff, /* dst_mask */
162 false), /* pcrel_offset */
164 /* Simple 16bit reloc. */
165 HOWTO (R_V850_16, /* type */
167 1, /* size (0 = byte, 1 = short, 2 = long) */
169 false, /* pc_relative */
171 complain_overflow_dont, /* complain_on_overflow */
172 bfd_elf_generic_reloc, /* special_function */
173 "R_V850_16", /* name */
174 true, /* partial_inplace */
175 0xffff, /* src_mask */
176 0xffff, /* dst_mask */
177 false), /* pcrel_offset */
179 /* Simple 8bit reloc. */
180 HOWTO (R_V850_8, /* type */
182 0, /* size (0 = byte, 1 = short, 2 = long) */
184 false, /* pc_relative */
186 complain_overflow_dont, /* complain_on_overflow */
187 bfd_elf_generic_reloc, /* special_function */
188 "R_V850_8", /* name */
189 true, /* partial_inplace */
192 false), /* pcrel_offset */
194 /* 16 bit offset from the short data area pointer. */
195 HOWTO (R_V850_SDA_16_16_OFFSET, /* type */
197 1, /* size (0 = byte, 1 = short, 2 = long) */
199 false, /* pc_relative */
201 complain_overflow_dont, /* complain_on_overflow */
202 v850_elf_reloc, /* special_function */
203 "R_V850_SDA_16_16_OFFSET", /* name */
204 false, /* partial_inplace */
205 0xffff, /* src_mask */
206 0xffff, /* dst_mask */
207 false), /* pcrel_offset */
209 /* 15 bit offset from the short data area pointer. */
210 HOWTO (R_V850_SDA_15_16_OFFSET, /* type */
212 1, /* size (0 = byte, 1 = short, 2 = long) */
214 false, /* pc_relative */
216 complain_overflow_dont, /* complain_on_overflow */
217 v850_elf_reloc, /* special_function */
218 "R_V850_SDA_15_16_OFFSET", /* name */
219 false, /* partial_inplace */
220 0xfffe, /* src_mask */
221 0xfffe, /* dst_mask */
222 false), /* pcrel_offset */
224 /* 16 bit offset from the zero data area pointer. */
225 HOWTO (R_V850_ZDA_16_16_OFFSET, /* type */
227 1, /* size (0 = byte, 1 = short, 2 = long) */
229 false, /* pc_relative */
231 complain_overflow_dont, /* complain_on_overflow */
232 v850_elf_reloc, /* special_function */
233 "R_V850_ZDA_16_16_OFFSET", /* name */
234 false, /* partial_inplace */
235 0xffff, /* src_mask */
236 0xffff, /* dst_mask */
237 false), /* pcrel_offset */
239 /* 15 bit offset from the zero data area pointer. */
240 HOWTO (R_V850_ZDA_15_16_OFFSET, /* type */
242 1, /* size (0 = byte, 1 = short, 2 = long) */
244 false, /* pc_relative */
246 complain_overflow_dont, /* complain_on_overflow */
247 v850_elf_reloc, /* special_function */
248 "R_V850_ZDA_15_16_OFFSET", /* name */
249 false, /* partial_inplace */
250 0xfffe, /* src_mask */
251 0xfffe, /* dst_mask */
252 false), /* pcrel_offset */
254 /* 6 bit offset from the tiny data area pointer. */
255 HOWTO (R_V850_TDA_6_8_OFFSET, /* type */
257 1, /* size (0 = byte, 1 = short, 2 = long) */
259 false, /* pc_relative */
261 complain_overflow_dont, /* complain_on_overflow */
262 v850_elf_reloc, /* special_function */
263 "R_V850_TDA_6_8_OFFSET", /* name */
264 false, /* partial_inplace */
267 false), /* pcrel_offset */
269 /* 8 bit offset from the tiny data area pointer. */
270 HOWTO (R_V850_TDA_7_8_OFFSET, /* type */
272 1, /* size (0 = byte, 1 = short, 2 = long) */
274 false, /* pc_relative */
276 complain_overflow_dont, /* complain_on_overflow */
277 v850_elf_reloc, /* special_function */
278 "R_V850_TDA_7_8_OFFSET", /* name */
279 false, /* partial_inplace */
282 false), /* pcrel_offset */
284 /* 7 bit offset from the tiny data area pointer. */
285 HOWTO (R_V850_TDA_7_7_OFFSET, /* type */
287 1, /* size (0 = byte, 1 = short, 2 = long) */
289 false, /* pc_relative */
291 complain_overflow_dont, /* complain_on_overflow */
292 v850_elf_reloc, /* special_function */
293 "R_V850_TDA_7_7_OFFSET", /* name */
294 false, /* partial_inplace */
297 false), /* pcrel_offset */
299 /* 16 bit offset from the tiny data area pointer! */
300 HOWTO (R_V850_TDA_16_16_OFFSET, /* type */
302 1, /* size (0 = byte, 1 = short, 2 = long) */
304 false, /* pc_relative */
306 complain_overflow_dont, /* complain_on_overflow */
307 v850_elf_reloc, /* special_function */
308 "R_V850_TDA_16_16_OFFSET", /* name */
309 false, /* partial_inplace */
310 0xffff, /* src_mask */
311 0xfff, /* dst_mask */
312 false), /* pcrel_offset */
314 /* start-sanitize-v850e */
316 /* 5 bit offset from the tiny data area pointer. */
317 HOWTO (R_V850_TDA_4_5_OFFSET, /* type */
319 1, /* size (0 = byte, 1 = short, 2 = long) */
321 false, /* pc_relative */
323 complain_overflow_dont, /* complain_on_overflow */
324 v850_elf_reloc, /* special_function */
325 "R_V850_TDA_4_5_OFFSET", /* name */
326 false, /* partial_inplace */
329 false), /* pcrel_offset */
331 /* 4 bit offset from the tiny data area pointer. */
332 HOWTO (R_V850_TDA_4_4_OFFSET, /* type */
334 1, /* size (0 = byte, 1 = short, 2 = long) */
336 false, /* pc_relative */
338 complain_overflow_dont, /* complain_on_overflow */
339 v850_elf_reloc, /* special_function */
340 "R_V850_TDA_4_4_OFFSET", /* name */
341 false, /* partial_inplace */
344 false), /* pcrel_offset */
346 /* 16 bit offset from the short data area pointer. */
347 HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */
349 2, /* size (0 = byte, 1 = short, 2 = long) */
351 false, /* pc_relative */
353 complain_overflow_dont, /* complain_on_overflow */
354 v850_elf_reloc, /* special_function */
355 "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
356 false, /* partial_inplace */
357 0xfffe0020, /* src_mask */
358 0xfffe0020, /* dst_mask */
359 false), /* pcrel_offset */
361 /* 16 bit offset from the zero data area pointer. */
362 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
364 2, /* size (0 = byte, 1 = short, 2 = long) */
366 false, /* pc_relative */
368 complain_overflow_dont, /* complain_on_overflow */
369 v850_elf_reloc, /* special_function */
370 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
371 false, /* partial_inplace */
372 0xfffe0020, /* src_mask */
373 0xfffe0020, /* dst_mask */
374 false), /* pcrel_offset */
376 /* 6 bit offset from the call table base pointer. */
377 HOWTO (R_V850_CALLT_6_7_OFFSET, /* type */
379 1, /* size (0 = byte, 1 = short, 2 = long) */
381 false, /* pc_relative */
383 complain_overflow_dont, /* complain_on_overflow */
384 v850_elf_reloc, /* special_function */
385 "R_V850_CALLT_6_7_OFFSET", /* name */
386 false, /* partial_inplace */
389 false), /* pcrel_offset */
391 /* 16 bit offset from the call table base pointer. */
392 HOWTO (R_V850_CALLT_16_16_OFFSET, /* type */
394 1, /* size (0 = byte, 1 = short, 2 = long) */
396 false, /* pc_relative */
398 complain_overflow_dont, /* complain_on_overflow */
399 v850_elf_reloc, /* special_function */
400 "R_V850_CALLT_16_16_OFFSET", /* name */
401 false, /* partial_inplace */
402 0xffff, /* src_mask */
403 0xffff, /* dst_mask */
404 false), /* pcrel_offset */
406 /* end-sanitize-v850e */
409 /* Map BFD reloc types to V850 ELF reloc types. */
411 struct v850_elf_reloc_map
413 unsigned char bfd_reloc_val;
414 unsigned char elf_reloc_val;
417 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
419 { BFD_RELOC_NONE, R_V850_NONE },
420 { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL },
421 { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL },
422 { BFD_RELOC_HI16_S, R_V850_HI16_S },
423 { BFD_RELOC_HI16, R_V850_HI16 },
424 { BFD_RELOC_LO16, R_V850_LO16 },
425 { BFD_RELOC_32, R_V850_32 },
426 { BFD_RELOC_16, R_V850_16 },
427 { BFD_RELOC_8, R_V850_8 },
428 { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
429 { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
430 { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
431 { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
432 { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET },
433 { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET },
434 { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET },
435 { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
436 /* start-sanitize-v850e */
437 { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET },
438 { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET },
439 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
440 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
441 { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET },
442 { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET },
443 /* end-sanitize-v850e */
447 /* Map a bfd relocation into the appropriate howto structure */
448 static reloc_howto_type *
449 v850_elf_reloc_type_lookup (abfd, code)
451 bfd_reloc_code_real_type code;
456 i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
459 if (v850_elf_reloc_map[i].bfd_reloc_val == code)
461 BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
463 return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
471 /* Set the howto pointer for an V850 ELF reloc. */
473 v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
476 Elf32_Internal_Rel * dst;
480 r_type = ELF32_R_TYPE (dst->r_info);
481 BFD_ASSERT (r_type < (unsigned int) R_V850_max);
482 cache_ptr->howto = &v850_elf_howto_table[r_type];
486 /* Look through the relocs for a section during the first phase, and
487 allocate space in the global offset table or procedure linkage
491 v850_elf_check_relocs (abfd, info, sec, relocs)
493 struct bfd_link_info * info;
495 const Elf_Internal_Rela * relocs;
499 Elf_Internal_Shdr *symtab_hdr;
500 struct elf_link_hash_entry **sym_hashes;
501 const Elf_Internal_Rela *rel;
502 const Elf_Internal_Rela *rel_end;
504 enum v850_reloc_type r_type;
506 const char *common = (const char *)0;
508 if (info->relocateable)
512 fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
513 bfd_get_section_name (abfd, sec),
514 bfd_get_filename (abfd));
517 dynobj = elf_hash_table (info)->dynobj;
518 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
519 sym_hashes = elf_sym_hashes (abfd);
522 rel_end = relocs + sec->reloc_count;
523 for (rel = relocs; rel < rel_end; rel++)
525 unsigned long r_symndx;
526 struct elf_link_hash_entry *h;
528 r_symndx = ELF32_R_SYM (rel->r_info);
529 if (r_symndx < symtab_hdr->sh_info)
532 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
534 r_type = (enum v850_reloc_type) ELF32_R_TYPE (rel->r_info);
540 case R_V850_22_PCREL:
547 /* start-sanitize-v850e */
548 case R_V850_CALLT_6_7_OFFSET:
549 case R_V850_CALLT_16_16_OFFSET:
550 /* end-sanitize-v850e */
553 /* start-sanitize-v850e */
554 case R_V850_SDA_16_16_SPLIT_OFFSET:
555 /* end-sanitize-v850e */
556 case R_V850_SDA_16_16_OFFSET:
557 case R_V850_SDA_15_16_OFFSET:
558 other = V850_OTHER_SDA;
560 goto small_data_common;
562 /* start-sanitize-v850e */
563 case R_V850_ZDA_16_16_SPLIT_OFFSET:
564 /* end-sanitize-v850e */
565 case R_V850_ZDA_16_16_OFFSET:
566 case R_V850_ZDA_15_16_OFFSET:
567 other = V850_OTHER_ZDA;
569 goto small_data_common;
571 /* start-sanitize-v850e */
572 case R_V850_TDA_4_5_OFFSET:
573 case R_V850_TDA_4_4_OFFSET:
574 /* end-sanitize-v850e */
575 case R_V850_TDA_6_8_OFFSET:
576 case R_V850_TDA_7_8_OFFSET:
577 case R_V850_TDA_7_7_OFFSET:
578 case R_V850_TDA_16_16_OFFSET:
579 other = V850_OTHER_TDA;
583 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
588 h->other |= other; /* flag which type of relocation was used */
589 if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
590 && (h->other & V850_OTHER_ERROR) == 0)
593 static char buff[100]; /* XXX */
595 switch (h->other & V850_OTHER_MASK)
598 msg = "cannot occupy in multiple small data regions";
600 case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
601 msg = "can only be in one of the small, zero, and tiny data regions";
603 case V850_OTHER_SDA | V850_OTHER_ZDA:
604 msg = "cannot be in both small and zero data regions simultaneously";
606 case V850_OTHER_SDA | V850_OTHER_TDA:
607 msg = "cannot be in both small and tiny data regions simultaneously";
609 case V850_OTHER_ZDA | V850_OTHER_TDA:
610 msg = "cannot be in both zero and tiny data regions simultaneously";
614 sprintf (buff, "Variable '%s' %s", h->root.root.string, msg );
615 info->callbacks->warning (info, buff, h->root.root.string,
616 abfd, h->root.u.def.section, 0);
618 bfd_set_error (bfd_error_bad_value);
619 h->other |= V850_OTHER_ERROR;
624 if (h && h->root.type == bfd_link_hash_common
626 && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
628 asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
629 section->flags |= SEC_IS_COMMON;
633 fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
634 v850_elf_howto_table[ (int)r_type ].name,
635 (h && h->root.root.string) ? h->root.root.string : "<unknown>",
636 (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
645 static bfd_reloc_status_type
646 v850_elf_store_addend_in_insn (abfd, r_type, addend, address, replace)
658 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
659 return bfd_reloc_notsupported;
663 addend += bfd_get_32 (abfd, address);
665 bfd_put_32 (abfd, addend, address);
668 case R_V850_22_PCREL:
669 if (addend > 0x1fffff || addend < -0x200000)
670 return bfd_reloc_overflow;
672 if ((addend % 2) != 0)
673 return bfd_reloc_dangerous;
675 insn = bfd_get_32 (abfd, address);
677 insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
678 bfd_put_32 (abfd, insn, address);
682 if (addend > 0xff || addend < -0x100)
683 return bfd_reloc_overflow;
685 if ((addend % 2) != 0)
686 return bfd_reloc_dangerous;
688 insn = bfd_get_16 (abfd, address);
690 insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
694 addend += (bfd_get_16 (abfd, address) << 16);
695 addend = (addend >> 16) + ((addend & 0x8000) != 0);
700 addend += (bfd_get_16 (abfd, address) << 16);
701 addend = (addend >> 16);
706 addend += (short) bfd_get_16 (abfd, address);
707 /* Do not complain if value has top bit set, as this has been anticipated. */
715 /* start-sanitize-v850e */
716 case R_V850_CALLT_16_16_OFFSET:
717 /* end-sanitize-v850e */
718 case R_V850_SDA_16_16_OFFSET:
719 case R_V850_ZDA_16_16_OFFSET:
720 case R_V850_TDA_16_16_OFFSET:
722 addend += bfd_get_16 (abfd, address);
724 if (addend > 0x7fff || addend < -0x8000)
725 return bfd_reloc_overflow;
730 case R_V850_SDA_15_16_OFFSET:
731 case R_V850_ZDA_15_16_OFFSET:
732 insn = bfd_get_16 (abfd, address);
735 addend += ((insn & 0xfffe) << 1);
737 if (addend > 0x7ffe || addend < -0x8000)
738 return bfd_reloc_overflow;
741 return bfd_reloc_dangerous;
744 insn |= (addend >> 1) & ~1;
747 case R_V850_TDA_6_8_OFFSET:
748 insn = bfd_get_16 (abfd, address);
751 addend += ((insn & 0x7e) << 1);
753 if (addend > 0xfc || addend < 0)
754 return bfd_reloc_overflow;
757 return bfd_reloc_dangerous;
760 insn |= (addend >> 1);
763 case R_V850_TDA_7_8_OFFSET:
764 insn = bfd_get_16 (abfd, address);
767 addend += ((insn & 0x7f) << 1);
769 if (addend > 0xfe || addend < 0)
770 return bfd_reloc_overflow;
773 return bfd_reloc_dangerous;
776 insn |= (addend >> 1);
779 case R_V850_TDA_7_7_OFFSET:
780 insn = bfd_get_16 (abfd, address);
783 addend += insn & 0x7f;
785 if (addend > 0x7f || addend < 0)
786 return bfd_reloc_overflow;
792 /* start-sanitize-v850e */
793 case R_V850_TDA_4_5_OFFSET:
794 insn = bfd_get_16 (abfd, address);
797 addend += ((insn & 0xf) << 1);
799 if (addend > 0x1e || addend < 0)
800 return bfd_reloc_overflow;
803 return bfd_reloc_dangerous;
806 insn |= (addend >> 1);
809 case R_V850_TDA_4_4_OFFSET:
810 insn = bfd_get_16 (abfd, address);
813 addend += insn & 0xf;
815 if (addend > 0xf || addend < 0)
816 return bfd_reloc_overflow;
822 case R_V850_ZDA_16_16_SPLIT_OFFSET:
823 case R_V850_SDA_16_16_SPLIT_OFFSET:
824 insn = bfd_get_32 (abfd, address);
827 addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
829 if (addend > 0xffff || addend < 0)
830 return bfd_reloc_overflow;
833 insn |= (addend & 1) << 5;
834 insn |= (addend & ~1) << 16;
836 bfd_put_32 (abfd, insn, address);
839 case R_V850_CALLT_6_7_OFFSET:
840 insn = bfd_get_16 (abfd, address);
843 addend += ((insn & 0x3f) << 1);
845 if (addend > 0x7e || addend < 0)
846 return bfd_reloc_overflow;
849 return bfd_reloc_dangerous;
852 insn |= (addend >> 1);
854 /* end-sanitize-v850e */
857 bfd_put_16 (abfd, insn, address);
862 /* Insert the addend into the instruction. */
863 static bfd_reloc_status_type
864 v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
877 /* If there is an output BFD,
878 and the symbol is not a section name (which is only defined at final link time),
879 and either we are not putting the addend into the instruction
880 or the addend is zero, so there is nothing to add into the instruction
881 then just fixup the address and return. */
882 if (obfd != (bfd *) NULL
883 && (symbol->flags & BSF_SECTION_SYM) == 0
884 && (! reloc->howto->partial_inplace
885 || reloc->addend == 0))
887 reloc->address += isection->output_offset;
891 else if (obfd != NULL)
893 return bfd_reloc_continue;
897 /* Catch relocs involving undefined symbols. */
898 if (bfd_is_und_section (symbol->section)
899 && (symbol->flags & BSF_WEAK) == 0
901 return bfd_reloc_undefined;
903 /* We handle final linking of some relocs ourselves. */
905 /* Is the address of the relocation really within the section? */
906 if (reloc->address > isection->_cooked_size)
907 return bfd_reloc_outofrange;
909 /* Work out which section the relocation is targetted at and the
910 initial relocation command value. */
912 /* Get symbol value. (Common symbols are special.) */
913 if (bfd_is_com_section (symbol->section))
916 relocation = symbol->value;
918 /* Convert input-section-relative symbol value to absolute + addend. */
919 relocation += symbol->section->output_section->vma;
920 relocation += symbol->section->output_offset;
921 relocation += reloc->addend;
923 if (reloc->howto->pc_relative == true)
925 /* Here the variable relocation holds the final address of the
926 symbol we are relocating against, plus any addend. */
927 relocation -= isection->output_section->vma + isection->output_offset;
929 /* Deal with pcrel_offset */
930 relocation -= reloc->address;
933 /* I've got no clue... */
936 return v850_elf_store_addend_in_insn (abfd, reloc->howto->type, relocation,
937 (bfd_byte *) data + reloc->address, true);
943 v850_elf_is_local_label_name (abfd, name)
947 return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
948 || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_'));
952 /* Perform a relocation as part of a final link. */
953 static bfd_reloc_status_type
954 v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
955 input_section, contents, offset, value,
956 addend, info, sym_sec, is_local)
957 reloc_howto_type * howto;
960 asection * input_section;
965 struct bfd_link_info * info;
970 unsigned long r_type = howto->type;
971 bfd_byte * hit_data = contents + offset;
976 value -= (input_section->output_section->vma
977 + input_section->output_offset);
980 if ((long)value > 0xff || (long)value < -0x100)
981 return bfd_reloc_overflow;
983 if ((value % 2) != 0)
984 return bfd_reloc_dangerous;
986 insn = bfd_get_16 (input_bfd, hit_data);
988 insn |= ((value & 0x1f0) << 7) | ((value & 0x0e) << 3);
989 bfd_put_16 (input_bfd, insn, hit_data);
992 case R_V850_22_PCREL:
993 value -= (input_section->output_section->vma
994 + input_section->output_offset
997 value = SEXT24 (value); /* Only the bottom 24 bits of the PC are valid */
999 if ((long)value > 0x1fffff || (long)value < -0x200000)
1000 return bfd_reloc_overflow;
1002 if ((value % 2) != 0)
1003 return bfd_reloc_dangerous;
1005 insn = bfd_get_32 (input_bfd, hit_data);
1007 insn |= (((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
1008 bfd_put_32 (input_bfd, insn, hit_data);
1009 return bfd_reloc_ok;
1012 value += (bfd_get_16 (input_bfd, hit_data) << 16);
1013 value = (value >> 16) + ((value & 0x8000) != 0);
1015 if ((long)value > 0x7fff || (long)value < -0x8000)
1017 /* This relocation cannot overflow. */
1022 bfd_put_16 (input_bfd, value, hit_data);
1023 return bfd_reloc_ok;
1026 value += (bfd_get_16 (input_bfd, hit_data) << 16);
1029 bfd_put_16 (input_bfd, value, hit_data);
1030 return bfd_reloc_ok;
1033 value += (short)bfd_get_16 (input_bfd, hit_data);
1036 bfd_put_16 (input_bfd, value, hit_data);
1037 return bfd_reloc_ok;
1040 value += (short) bfd_get_16 (input_bfd, hit_data);
1042 if ((long) value > 0x7fff || (long) value < -0x8000)
1043 return bfd_reloc_overflow;
1045 bfd_put_16 (input_bfd, value, hit_data);
1046 return bfd_reloc_ok;
1048 case R_V850_ZDA_16_16_OFFSET:
1049 if (sym_sec == NULL)
1050 return bfd_reloc_undefined;
1052 value -= sym_sec->output_section->vma;
1053 value += (short) bfd_get_16 (input_bfd, hit_data);
1055 if ((long) value > 0x7fff || (long) value < -0x8000)
1056 return bfd_reloc_overflow;
1058 bfd_put_16 (input_bfd, value, hit_data);
1059 return bfd_reloc_ok;
1061 case R_V850_ZDA_15_16_OFFSET:
1062 if (sym_sec == NULL)
1063 return bfd_reloc_undefined;
1065 insn = bfd_get_16 (input_bfd, hit_data);
1067 value -= sym_sec->output_section->vma;
1068 value += ((insn & 0xfffe) << 1);
1070 if ((long) value > 0x7ffe || (long) value < -0x8000)
1071 return bfd_reloc_overflow;
1074 value |= (insn & 1);
1076 bfd_put_16 (input_bfd, value, hit_data);
1077 return bfd_reloc_ok;
1080 value += bfd_get_32 (input_bfd, hit_data);
1081 bfd_put_32 (input_bfd, value, hit_data);
1082 return bfd_reloc_ok;
1085 value += (char)bfd_get_8 (input_bfd, hit_data);
1087 if ((long)value > 0x7f || (long)value < -0x80)
1088 return bfd_reloc_overflow;
1090 bfd_put_8 (input_bfd, value, hit_data);
1091 return bfd_reloc_ok;
1093 case R_V850_SDA_16_16_OFFSET:
1094 if (sym_sec == NULL)
1095 return bfd_reloc_undefined;
1099 struct bfd_link_hash_entry * h;
1101 /* Get the value of __gp. */
1102 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1103 if (h == (struct bfd_link_hash_entry *) NULL
1104 || h->type != bfd_link_hash_defined)
1105 return bfd_reloc_other;
1107 gp = (h->u.def.value
1108 + h->u.def.section->output_section->vma
1109 + h->u.def.section->output_offset);
1111 value -= sym_sec->output_section->vma;
1112 value -= (gp - sym_sec->output_section->vma);
1113 value += (short) bfd_get_16 (input_bfd, hit_data);
1115 if ((long)value > 0x7fff || (long)value < -0x8000)
1116 return bfd_reloc_overflow;
1118 bfd_put_16 (input_bfd, value, hit_data);
1119 return bfd_reloc_ok;
1122 case R_V850_SDA_15_16_OFFSET:
1123 if (sym_sec == NULL)
1124 return bfd_reloc_undefined;
1128 struct bfd_link_hash_entry * h;
1130 /* Get the value of __gp. */
1131 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1132 if (h == (struct bfd_link_hash_entry *) NULL
1133 || h->type != bfd_link_hash_defined)
1134 return bfd_reloc_other;
1136 gp = (h->u.def.value
1137 + h->u.def.section->output_section->vma
1138 + h->u.def.section->output_offset);
1140 value -= sym_sec->output_section->vma;
1141 value -= (gp - sym_sec->output_section->vma);
1143 insn = bfd_get_16 (input_bfd, hit_data);
1145 value += ((insn & 0xfffe) << 1);
1147 if ((long)value > 0x7ffe || (long)value < -0x8000)
1148 return bfd_reloc_overflow;
1151 value |= (insn & 1);
1153 bfd_put_16 (input_bfd, value, hit_data);
1154 return bfd_reloc_ok;
1157 case R_V850_TDA_6_8_OFFSET:
1160 struct bfd_link_hash_entry * h;
1162 insn = bfd_get_16 (input_bfd, hit_data);
1164 /* Get the value of __ep. */
1165 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1166 if (h == (struct bfd_link_hash_entry *) NULL
1167 || h->type != bfd_link_hash_defined)
1168 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1170 ep = (h->u.def.value
1171 + h->u.def.section->output_section->vma
1172 + h->u.def.section->output_offset);
1175 value += ((insn & 0x7e) << 1);
1177 if ((long) value > 0xfc || (long) value < 0)
1178 return bfd_reloc_overflow;
1180 if ((value % 2) != 0)
1181 return bfd_reloc_dangerous;
1184 insn |= (value >> 1);
1186 bfd_put_16 (input_bfd, insn, hit_data);
1187 return bfd_reloc_ok;
1190 case R_V850_TDA_7_8_OFFSET:
1193 struct bfd_link_hash_entry * h;
1195 insn = bfd_get_16 (input_bfd, hit_data);
1197 /* Get the value of __ep. */
1198 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1199 if (h == (struct bfd_link_hash_entry *) NULL
1200 || h->type != bfd_link_hash_defined)
1201 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1203 ep = (h->u.def.value
1204 + h->u.def.section->output_section->vma
1205 + h->u.def.section->output_offset);
1208 value += ((insn & 0x7f) << 1);
1210 if ((long) value > 0xfe || (long) value < 0)
1211 return bfd_reloc_overflow;
1214 insn |= (value >> 1);
1216 bfd_put_16 (input_bfd, insn, hit_data);
1217 return bfd_reloc_ok;
1220 case R_V850_TDA_7_7_OFFSET:
1223 struct bfd_link_hash_entry * h;
1225 insn = bfd_get_16 (input_bfd, hit_data);
1227 /* Get the value of __ep. */
1228 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1229 if (h == (struct bfd_link_hash_entry *) NULL
1230 || h->type != bfd_link_hash_defined)
1231 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1233 ep = (h->u.def.value
1234 + h->u.def.section->output_section->vma
1235 + h->u.def.section->output_offset);
1238 value += insn & 0x7f;
1240 if ((long) value > 0x7f || (long) value < 0)
1241 return bfd_reloc_overflow;
1245 bfd_put_16 (input_bfd, insn, hit_data);
1246 return bfd_reloc_ok;
1249 case R_V850_TDA_16_16_OFFSET:
1252 struct bfd_link_hash_entry * h;
1254 /* Get the value of __ep. */
1255 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1256 if (h == (struct bfd_link_hash_entry *) NULL
1257 || h->type != bfd_link_hash_defined)
1258 return bfd_reloc_other;
1260 ep = (h->u.def.value
1261 + h->u.def.section->output_section->vma
1262 + h->u.def.section->output_offset);
1265 value += (short) bfd_get_16 (input_bfd, hit_data);
1267 if ((long)value > 0x7fff || (long)value < -0x8000)
1268 return bfd_reloc_overflow;
1270 bfd_put_16 (input_bfd, value, hit_data);
1271 return bfd_reloc_ok;
1274 /* start-sanitize-v850e */
1275 case R_V850_TDA_4_5_OFFSET:
1278 struct bfd_link_hash_entry * h;
1280 /* Get the value of __ep. */
1281 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1282 if (h == (struct bfd_link_hash_entry *) NULL
1283 || h->type != bfd_link_hash_defined)
1284 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1286 ep = (h->u.def.value
1287 + h->u.def.section->output_section->vma
1288 + h->u.def.section->output_offset);
1291 insn = bfd_get_16 (input_bfd, hit_data);
1293 value += ((insn & 0xf) << 1);
1295 if ((long) value > 0x1e || (long) value < 0)
1296 return bfd_reloc_overflow;
1299 insn |= (value >> 1);
1300 bfd_put_16 (input_bfd, insn, hit_data);
1301 return bfd_reloc_ok;
1304 case R_V850_TDA_4_4_OFFSET:
1307 struct bfd_link_hash_entry * h;
1309 /* Get the value of __ep. */
1310 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1311 if (h == (struct bfd_link_hash_entry *) NULL
1312 || h->type != bfd_link_hash_defined)
1313 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1315 ep = (h->u.def.value
1316 + h->u.def.section->output_section->vma
1317 + h->u.def.section->output_offset);
1320 insn = bfd_get_16 (input_bfd, hit_data);
1322 value += insn & 0xf;
1324 if ((long) value > 0xf || (long) value < 0)
1325 return bfd_reloc_overflow;
1329 bfd_put_16 (input_bfd, insn, hit_data);
1330 return bfd_reloc_ok;
1333 case R_V850_SDA_16_16_SPLIT_OFFSET:
1334 if (sym_sec == NULL)
1335 return bfd_reloc_undefined;
1339 struct bfd_link_hash_entry * h;
1341 /* Get the value of __gp. */
1342 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1343 if (h == (struct bfd_link_hash_entry *) NULL
1344 || h->type != bfd_link_hash_defined)
1345 return bfd_reloc_other;
1347 gp = (h->u.def.value
1348 + h->u.def.section->output_section->vma
1349 + h->u.def.section->output_offset);
1351 value -= sym_sec->output_section->vma;
1352 value -= (gp - sym_sec->output_section->vma);
1354 insn = bfd_get_32 (input_bfd, hit_data);
1356 value += ((insn & 0xfffe0000) >> 16);
1357 value += ((insn & 0x20) >> 5);
1359 if ((long)value > 0x7fff || (long)value < -0x8000)
1360 return bfd_reloc_overflow;
1363 insn |= (value & 1) << 5;
1364 insn |= (value & ~1) << 16;
1366 bfd_put_32 (input_bfd, insn, hit_data);
1367 return bfd_reloc_ok;
1370 case R_V850_ZDA_16_16_SPLIT_OFFSET:
1371 if (sym_sec == NULL)
1372 return bfd_reloc_undefined;
1374 insn = bfd_get_32 (input_bfd, hit_data);
1376 value -= sym_sec->output_section->vma;
1377 value += ((insn & 0xfffe0000) >> 16);
1378 value += ((insn & 0x20) >> 5);
1380 if ((long)value > 0x7fff || (long)value < -0x8000)
1381 return bfd_reloc_overflow;
1384 insn |= (value & 1) << 5;
1385 insn |= (value & ~1) << 16;
1387 bfd_put_32 (input_bfd, insn, hit_data);
1388 return bfd_reloc_ok;
1390 case R_V850_CALLT_6_7_OFFSET:
1393 struct bfd_link_hash_entry * h;
1395 /* Get the value of __ctbp. */
1396 h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1397 if (h == (struct bfd_link_hash_entry *) NULL
1398 || h->type != bfd_link_hash_defined)
1399 return (bfd_reloc_dangerous + 1); /* Actually this indicates that __ctbp could not be found. */
1401 ctbp = (h->u.def.value
1402 + h->u.def.section->output_section->vma
1403 + h->u.def.section->output_offset);
1406 insn = bfd_get_16 (input_bfd, hit_data);
1408 value += ((insn & 0x3f) << 1);
1410 if ((long) value > 0x7e || (long) value < 0)
1411 return bfd_reloc_overflow;
1414 insn |= (value >> 1);
1415 bfd_put_16 (input_bfd, insn, hit_data);
1416 return bfd_reloc_ok;
1419 case R_V850_CALLT_16_16_OFFSET:
1420 if (sym_sec == NULL)
1421 return bfd_reloc_undefined;
1425 struct bfd_link_hash_entry * h;
1427 /* Get the value of __ctbp. */
1428 h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1429 if (h == (struct bfd_link_hash_entry *) NULL
1430 || h->type != bfd_link_hash_defined)
1431 return (bfd_reloc_dangerous + 1);
1433 ctbp = (h->u.def.value
1434 + h->u.def.section->output_section->vma
1435 + h->u.def.section->output_offset);
1437 value -= sym_sec->output_section->vma;
1438 value -= (ctbp - sym_sec->output_section->vma);
1439 value += (short) bfd_get_16 (input_bfd, hit_data);
1441 if ((long) value > 0xffff || (long) value < 0)
1442 return bfd_reloc_overflow;
1444 bfd_put_16 (input_bfd, value, hit_data);
1445 return bfd_reloc_ok;
1448 /* end-sanitize-v850e */
1451 return bfd_reloc_ok;
1454 return bfd_reloc_notsupported;
1459 /* Relocate an V850 ELF section. */
1461 v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1462 contents, relocs, local_syms, local_sections)
1464 struct bfd_link_info * info;
1466 asection * input_section;
1467 bfd_byte * contents;
1468 Elf_Internal_Rela * relocs;
1469 Elf_Internal_Sym * local_syms;
1470 asection ** local_sections;
1472 Elf_Internal_Shdr * symtab_hdr;
1473 struct elf_link_hash_entry ** sym_hashes;
1474 Elf_Internal_Rela * rel;
1475 Elf_Internal_Rela * relend;
1477 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1478 sym_hashes = elf_sym_hashes (input_bfd);
1481 relend = relocs + input_section->reloc_count;
1482 for (; rel < relend; rel++)
1485 reloc_howto_type * howto;
1486 unsigned long r_symndx;
1487 Elf_Internal_Sym * sym;
1489 struct elf_link_hash_entry * h;
1491 bfd_reloc_status_type r;
1493 r_symndx = ELF32_R_SYM (rel->r_info);
1494 r_type = ELF32_R_TYPE (rel->r_info);
1495 howto = v850_elf_howto_table + r_type;
1497 if (info->relocateable)
1499 /* This is a relocateable link. We don't have to change
1500 anything, unless the reloc is against a section symbol,
1501 in which case we have to adjust according to where the
1502 section symbol winds up in the output section. */
1503 if (r_symndx < symtab_hdr->sh_info)
1505 sym = local_syms + r_symndx;
1506 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1508 sec = local_sections[r_symndx];
1510 /* The Elf_Internal_Rel structure does not have space for the
1511 modified addend value, so we store it in the instruction
1514 if (sec->output_offset + sym->st_value != 0)
1516 if (v850_elf_store_addend_in_insn (input_bfd, r_type,
1517 sec->output_offset +
1519 contents + rel->r_offset,
1523 info->callbacks->warning
1525 "Unable to handle relocation during incremental link",
1526 NULL, input_bfd, input_section, rel->r_offset);
1530 rel->r_addend += sec->output_offset + sym->st_value;
1538 /* This is a final link. */
1542 if (r_symndx < symtab_hdr->sh_info)
1544 sym = local_syms + r_symndx;
1545 sec = local_sections[r_symndx];
1546 relocation = (sec->output_section->vma
1547 + sec->output_offset
1552 name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1553 name = (name == NULL) ? "<none>" : name;
1554 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x rel %x\n", sec->name, name, sym->st_name,
1555 sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend, rel);
1561 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1563 while (h->root.type == bfd_link_hash_indirect
1564 || h->root.type == bfd_link_hash_warning)
1565 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1567 if (h->root.type == bfd_link_hash_defined
1568 || h->root.type == bfd_link_hash_defweak)
1570 sec = h->root.u.def.section;
1571 relocation = (h->root.u.def.value
1572 + sec->output_section->vma
1573 + sec->output_offset);
1575 fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1576 sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
1579 else if (h->root.type == bfd_link_hash_undefweak)
1582 fprintf (stderr, "undefined: sec: %s, name: %s\n",
1583 sec->name, h->root.root.string);
1589 if (! ((*info->callbacks->undefined_symbol)
1590 (info, h->root.root.string, input_bfd,
1591 input_section, rel->r_offset)))
1594 fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
1600 /* FIXME: We should use the addend, but the COFF relocations
1602 r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1604 contents, rel->r_offset,
1605 relocation, rel->r_addend,
1606 info, sec, h == NULL);
1608 if (r != bfd_reloc_ok)
1611 const char * msg = (const char *)0;
1614 name = h->root.root.string;
1617 name = (bfd_elf_string_from_elf_section
1618 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1619 if (name == NULL || *name == '\0')
1620 name = bfd_section_name (input_bfd, sec);
1625 case bfd_reloc_overflow:
1626 if (! ((*info->callbacks->reloc_overflow)
1627 (info, name, howto->name, (bfd_vma) 0,
1628 input_bfd, input_section, rel->r_offset)))
1632 case bfd_reloc_undefined:
1633 if (! ((*info->callbacks->undefined_symbol)
1634 (info, name, input_bfd, input_section,
1639 case bfd_reloc_outofrange:
1640 msg = "internal error: out of range error";
1643 case bfd_reloc_notsupported:
1644 msg = "internal error: unsupported relocation error";
1647 case bfd_reloc_dangerous:
1648 msg = "internal error: dangerous relocation";
1651 case bfd_reloc_other:
1652 msg = "could not locate special linker symbol __gp";
1655 case bfd_reloc_continue:
1656 msg = "could not locate special linker symbol __ep";
1659 case (bfd_reloc_dangerous + 1):
1660 msg = "could not locate special linker symbol __ctbp";
1664 msg = "internal error: unknown error";
1668 if (!((*info->callbacks->warning)
1669 (info, msg, name, input_bfd, input_section,
1680 /* Set the right machine number. */
1682 v850_elf_object_p (abfd)
1685 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1688 case E_V850_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
1689 /* start-sanitize-v850e */
1690 case E_V850E_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
1691 case E_V850EQ_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850eq); break;
1692 /* end-sanitize-v850e */
1696 /* Store the machine number in the flags field. */
1698 v850_elf_final_write_processing (abfd, linker)
1704 switch (bfd_get_mach (abfd))
1707 case 0: val = E_V850_ARCH; break;
1708 /* start-sanitize-v850e */
1709 case bfd_mach_v850e: val = E_V850E_ARCH; break;
1710 case bfd_mach_v850eq: val = E_V850EQ_ARCH; break;
1711 /* end-sanitize-v850e */
1714 elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1715 elf_elfheader (abfd)->e_flags |= val;
1718 /* Function to keep V850 specific file flags. */
1720 v850_elf_set_private_flags (abfd, flags)
1724 BFD_ASSERT (!elf_flags_init (abfd)
1725 || elf_elfheader (abfd)->e_flags == flags);
1727 elf_elfheader (abfd)->e_flags = flags;
1728 elf_flags_init (abfd) = true;
1732 /* Copy backend specific data from one object module to another */
1734 v850_elf_copy_private_bfd_data (ibfd, obfd)
1738 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1739 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1742 BFD_ASSERT (!elf_flags_init (obfd)
1743 || (elf_elfheader (obfd)->e_flags
1744 == elf_elfheader (ibfd)->e_flags));
1746 elf_gp (obfd) = elf_gp (ibfd);
1747 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1748 elf_flags_init (obfd) = true;
1752 /* Merge backend specific data from an object file to the output
1753 object file when linking. */
1755 v850_elf_merge_private_bfd_data (ibfd, obfd)
1762 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1763 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1766 new_flags = elf_elfheader (ibfd)->e_flags;
1767 old_flags = elf_elfheader (obfd)->e_flags;
1769 if (! elf_flags_init (obfd))
1771 elf_flags_init (obfd) = true;
1772 elf_elfheader (obfd)->e_flags = new_flags;
1774 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1775 && bfd_get_arch_info (obfd)->the_default)
1777 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1783 /* Check flag compatibility. */
1785 if (new_flags == old_flags)
1788 if ((new_flags & EF_V850_ARCH) != (old_flags & EF_V850_ARCH))
1790 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1791 bfd_get_filename (ibfd));
1793 bfd_set_error (bfd_error_bad_value);
1802 /* Display the flags field */
1805 v850_elf_print_private_bfd_data (abfd, ptr)
1809 FILE * file = (FILE *) ptr;
1811 BFD_ASSERT (abfd != NULL && ptr != NULL)
1813 fprintf (file, "private flags = %x", elf_elfheader (abfd)->e_flags);
1815 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1818 case E_V850_ARCH: fprintf (file, ": v850 architecture"); break;
1819 /* start-sanitize-v850e */
1820 case E_V850E_ARCH: fprintf (file, ": v850e architecture"); break;
1821 case E_V850EQ_ARCH: fprintf (file, ": v850eq architecture"); break;
1822 /* end-sanitize-v850e */
1830 /* V850 ELF uses four common sections. One is the usual one, and the
1831 others are for (small) objects in one of the special data areas:
1832 small, tiny and zero. All the objects are kept together, and then
1833 referenced via the gp register, the ep register or the r0 register
1834 respectively, which yields smaller, faster assembler code. This
1835 approach is copied from elf32-mips.c. */
1837 static asection v850_elf_scom_section;
1838 static asymbol v850_elf_scom_symbol;
1839 static asymbol * v850_elf_scom_symbol_ptr;
1840 static asection v850_elf_tcom_section;
1841 static asymbol v850_elf_tcom_symbol;
1842 static asymbol * v850_elf_tcom_symbol_ptr;
1843 static asection v850_elf_zcom_section;
1844 static asymbol v850_elf_zcom_symbol;
1845 static asymbol * v850_elf_zcom_symbol_ptr;
1848 /* Given a BFD section, try to locate the corresponding ELF section
1852 v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
1854 Elf32_Internal_Shdr * hdr;
1858 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
1860 *retval = SHN_V850_SCOMMON;
1863 if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
1865 *retval = SHN_V850_TCOMMON;
1868 if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
1870 *retval = SHN_V850_ZCOMMON;
1876 /* Handle the special V850 section numbers that a symbol may use. */
1879 v850_elf_symbol_processing (abfd, asym)
1883 elf_symbol_type * elfsym = (elf_symbol_type *) asym;
1885 switch (elfsym->internal_elf_sym.st_shndx)
1887 case SHN_V850_SCOMMON:
1888 if (v850_elf_scom_section.name == NULL)
1890 /* Initialize the small common section. */
1891 v850_elf_scom_section.name = ".scommon";
1892 v850_elf_scom_section.flags = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
1893 v850_elf_scom_section.output_section = & v850_elf_scom_section;
1894 v850_elf_scom_section.symbol = & v850_elf_scom_symbol;
1895 v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
1896 v850_elf_scom_symbol.name = ".scommon";
1897 v850_elf_scom_symbol.flags = BSF_SECTION_SYM;
1898 v850_elf_scom_symbol.section = & v850_elf_scom_section;
1899 v850_elf_scom_symbol_ptr = & v850_elf_scom_symbol;
1901 asym->section = & v850_elf_scom_section;
1902 asym->value = elfsym->internal_elf_sym.st_size;
1905 case SHN_V850_TCOMMON:
1906 if (v850_elf_tcom_section.name == NULL)
1908 /* Initialize the tcommon section. */
1909 v850_elf_tcom_section.name = ".tcommon";
1910 v850_elf_tcom_section.flags = SEC_IS_COMMON;
1911 v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
1912 v850_elf_tcom_section.symbol = & v850_elf_tcom_symbol;
1913 v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
1914 v850_elf_tcom_symbol.name = ".tcommon";
1915 v850_elf_tcom_symbol.flags = BSF_SECTION_SYM;
1916 v850_elf_tcom_symbol.section = & v850_elf_tcom_section;
1917 v850_elf_tcom_symbol_ptr = & v850_elf_tcom_symbol;
1919 asym->section = & v850_elf_tcom_section;
1920 asym->value = elfsym->internal_elf_sym.st_size;
1923 case SHN_V850_ZCOMMON:
1924 if (v850_elf_zcom_section.name == NULL)
1926 /* Initialize the zcommon section. */
1927 v850_elf_zcom_section.name = ".zcommon";
1928 v850_elf_zcom_section.flags = SEC_IS_COMMON;
1929 v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
1930 v850_elf_zcom_section.symbol = & v850_elf_zcom_symbol;
1931 v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
1932 v850_elf_zcom_symbol.name = ".zcommon";
1933 v850_elf_zcom_symbol.flags = BSF_SECTION_SYM;
1934 v850_elf_zcom_symbol.section = & v850_elf_zcom_section;
1935 v850_elf_zcom_symbol_ptr = & v850_elf_zcom_symbol;
1937 asym->section = & v850_elf_zcom_section;
1938 asym->value = elfsym->internal_elf_sym.st_size;
1943 /* Hook called by the linker routine which adds symbols from an object
1944 file. We must handle the special MIPS section numbers here. */
1948 v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1950 struct bfd_link_info * info;
1951 const Elf_Internal_Sym * sym;
1952 const char ** namep;
1957 switch (sym->st_shndx)
1959 case SHN_V850_SCOMMON:
1960 *secp = bfd_make_section_old_way (abfd, ".scommon");
1961 (*secp)->flags |= SEC_IS_COMMON;
1962 *valp = sym->st_size;
1965 case SHN_V850_TCOMMON:
1966 *secp = bfd_make_section_old_way (abfd, ".tcommon");
1967 (*secp)->flags |= SEC_IS_COMMON;
1968 *valp = sym->st_size;
1971 case SHN_V850_ZCOMMON:
1972 *secp = bfd_make_section_old_way (abfd, ".zcommon");
1973 (*secp)->flags |= SEC_IS_COMMON;
1974 *valp = sym->st_size;
1983 v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
1985 struct bfd_link_info * info;
1987 Elf_Internal_Sym * sym;
1988 asection * input_sec;
1990 /* If we see a common symbol, which implies a relocatable link, then
1991 if a symbol was in a special common section in an input file, mark
1992 it as a special common in the output file. */
1994 if (sym->st_shndx == SHN_COMMON)
1996 if (strcmp (input_sec->name, ".scommon") == 0)
1997 sym->st_shndx = SHN_V850_SCOMMON;
1998 else if (strcmp (input_sec->name, ".tcommon") == 0)
1999 sym->st_shndx = SHN_V850_TCOMMON;
2000 else if (strcmp (input_sec->name, ".zcommon") == 0)
2001 sym->st_shndx = SHN_V850_ZCOMMON;
2008 v850_elf_section_from_shdr (abfd, hdr, name)
2010 Elf_Internal_Shdr * hdr;
2013 /* There ought to be a place to keep ELF backend specific flags, but
2014 at the moment there isn't one. We just keep track of the
2015 sections by their name, instead. */
2017 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
2020 switch (hdr->sh_type)
2022 case SHT_V850_SCOMMON:
2023 case SHT_V850_TCOMMON:
2024 case SHT_V850_ZCOMMON:
2025 if (! bfd_set_section_flags (abfd, hdr->bfd_section,
2026 (bfd_get_section_flags (abfd,
2035 /* Set the correct type for a V850 ELF section. We do this by the
2036 section name, which is a hack, but ought to work. */
2038 v850_elf_fake_sections (abfd, hdr, sec)
2040 Elf32_Internal_Shdr * hdr;
2043 register const char * name;
2045 name = bfd_get_section_name (abfd, sec);
2047 if (strcmp (name, ".scommon") == 0)
2049 hdr->sh_type = SHT_V850_SCOMMON;
2051 else if (strcmp (name, ".tcommon") == 0)
2053 hdr->sh_type = SHT_V850_TCOMMON;
2055 else if (strcmp (name, ".zcommon") == 0)
2056 hdr->sh_type = SHT_V850_ZCOMMON;
2063 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
2064 #define TARGET_LITTLE_NAME "elf32-v850"
2065 #define ELF_ARCH bfd_arch_v850
2066 #define ELF_MACHINE_CODE EM_CYGNUS_V850
2067 #define ELF_MAXPAGESIZE 0x1000
2069 #define elf_info_to_howto 0
2070 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
2072 #define elf_backend_check_relocs v850_elf_check_relocs
2073 #define elf_backend_relocate_section v850_elf_relocate_section
2074 #define elf_backend_object_p v850_elf_object_p
2075 #define elf_backend_final_write_processing v850_elf_final_write_processing
2076 #define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
2077 #define elf_backend_symbol_processing v850_elf_symbol_processing
2078 #define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
2079 #define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
2080 #define elf_backend_section_from_shdr v850_elf_section_from_shdr
2081 #define elf_backend_fake_sections v850_elf_fake_sections
2083 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
2084 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
2085 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
2086 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
2087 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
2088 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
2090 #define elf_symbol_leading_char '_'
2092 #include "elf32-target.h"