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 static reloc_howto_type
*v850_elf_reloc_type_lookup
34 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type code
));
35 static void v850_elf_info_to_howto_rel
36 PARAMS ((bfd
*, arelent
*, Elf32_Internal_Rel
*));
37 static bfd_reloc_status_type v850_elf_reloc
38 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
39 static boolean v850_elf_is_local_label_name
PARAMS ((bfd
*, const char *));
40 static boolean v850_elf_relocate_section
PARAMS((bfd
*,
41 struct bfd_link_info
*,
48 /* Try to minimize the amount of space occupied by relocation tables
49 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
52 /* Note: It is REQUIRED that the 'type' value of each entry in this array
53 match the index of the entry in the array. */
54 static reloc_howto_type v850_elf_howto_table
[] =
56 /* This reloc does nothing. */
57 HOWTO (R_V850_NONE
, /* type */
59 2, /* size (0 = byte, 1 = short, 2 = long) */
61 false, /* pc_relative */
63 complain_overflow_bitfield
, /* complain_on_overflow */
64 bfd_elf_generic_reloc
, /* special_function */
65 "R_V850_NONE", /* name */
66 false, /* partial_inplace */
69 false), /* pcrel_offset */
71 /* A PC relative 9 bit branch. */
72 HOWTO (R_V850_9_PCREL
, /* type */
74 2, /* size (0 = byte, 1 = short, 2 = long) */
76 true, /* pc_relative */
78 complain_overflow_bitfield
, /* complain_on_overflow */
79 v850_elf_reloc
, /* special_function */
80 "R_V850_9_PCREL", /* name */
81 false, /* partial_inplace */
82 0x00ffffff, /* src_mask */
83 0x00ffffff, /* dst_mask */
84 true), /* pcrel_offset */
86 /* A PC relative 22 bit branch. */
87 HOWTO (R_V850_22_PCREL
, /* type */
89 2, /* size (0 = byte, 1 = short, 2 = long) */
91 true, /* pc_relative */
93 complain_overflow_signed
, /* complain_on_overflow */
94 v850_elf_reloc
, /* special_function */
95 "R_V850_22_PCREL", /* name */
96 false, /* partial_inplace */
97 0x07ffff80, /* src_mask */
98 0x07ffff80, /* dst_mask */
99 true), /* pcrel_offset */
101 /* High 16 bits of symbol value. */
102 HOWTO (R_V850_HI16_S
, /* type */
104 1, /* size (0 = byte, 1 = short, 2 = long) */
106 false, /* pc_relative */
108 complain_overflow_dont
, /* complain_on_overflow */
109 v850_elf_reloc
, /* special_function */
110 "R_V850_HI16_S", /* name */
111 true, /* partial_inplace */
112 0xffff, /* src_mask */
113 0xffff, /* dst_mask */
114 false), /* pcrel_offset */
116 /* High 16 bits of symbol value. */
117 HOWTO (R_V850_HI16
, /* type */
119 1, /* size (0 = byte, 1 = short, 2 = long) */
121 false, /* pc_relative */
123 complain_overflow_dont
, /* complain_on_overflow */
124 v850_elf_reloc
, /* special_function */
125 "R_V850_HI16", /* name */
126 true, /* partial_inplace */
127 0xffff, /* src_mask */
128 0xffff, /* dst_mask */
129 false), /* pcrel_offset */
131 /* Low 16 bits of symbol value. */
132 HOWTO (R_V850_LO16
, /* type */
134 1, /* size (0 = byte, 1 = short, 2 = long) */
136 false, /* pc_relative */
138 complain_overflow_dont
, /* complain_on_overflow */
139 v850_elf_reloc
, /* special_function */
140 "R_V850_LO16", /* name */
141 true, /* partial_inplace */
142 0xffff, /* src_mask */
143 0xffff, /* dst_mask */
144 false), /* pcrel_offset */
146 /* Simple 32bit reloc. */
147 HOWTO (R_V850_32
, /* type */
149 2, /* size (0 = byte, 1 = short, 2 = long) */
151 false, /* pc_relative */
153 complain_overflow_dont
, /* complain_on_overflow */
154 bfd_elf_generic_reloc
, /* special_function */
155 "R_V850_32", /* name */
156 true, /* partial_inplace */
157 0xffffffff, /* src_mask */
158 0xffffffff, /* dst_mask */
159 false), /* pcrel_offset */
161 /* Simple 16bit reloc. */
162 HOWTO (R_V850_16
, /* type */
164 1, /* size (0 = byte, 1 = short, 2 = long) */
166 false, /* pc_relative */
168 complain_overflow_dont
, /* complain_on_overflow */
169 bfd_elf_generic_reloc
, /* special_function */
170 "R_V850_16", /* name */
171 true, /* partial_inplace */
172 0xffff, /* src_mask */
173 0xffff, /* dst_mask */
174 false), /* pcrel_offset */
176 /* Simple 8bit reloc. */
177 HOWTO (R_V850_8
, /* type */
179 0, /* size (0 = byte, 1 = short, 2 = long) */
181 false, /* pc_relative */
183 complain_overflow_dont
, /* complain_on_overflow */
184 bfd_elf_generic_reloc
, /* special_function */
185 "R_V850_8", /* name */
186 true, /* partial_inplace */
189 false), /* pcrel_offset */
191 /* 16 bit offset from the short data area pointer. */
192 HOWTO (R_V850_SDA_16_16_OFFSET
, /* type */
194 1, /* size (0 = byte, 1 = short, 2 = long) */
196 false, /* pc_relative */
198 complain_overflow_dont
, /* complain_on_overflow */
199 v850_elf_reloc
, /* special_function */
200 "R_V850_SDA_16_16_OFFSET", /* name */
201 false, /* partial_inplace */
202 0xffff, /* src_mask */
203 0xffff, /* dst_mask */
204 false), /* pcrel_offset */
206 /* 15 bit offset from the short data area pointer. */
207 HOWTO (R_V850_SDA_15_16_OFFSET
, /* type */
209 1, /* size (0 = byte, 1 = short, 2 = long) */
211 false, /* pc_relative */
213 complain_overflow_dont
, /* complain_on_overflow */
214 v850_elf_reloc
, /* special_function */
215 "R_V850_SDA_15_16_OFFSET", /* name */
216 false, /* partial_inplace */
217 0xfffe, /* src_mask */
218 0xfffe, /* dst_mask */
219 false), /* pcrel_offset */
221 /* 16 bit offset from the zero data area pointer. */
222 HOWTO (R_V850_ZDA_16_16_OFFSET
, /* type */
224 1, /* size (0 = byte, 1 = short, 2 = long) */
226 false, /* pc_relative */
228 complain_overflow_dont
, /* complain_on_overflow */
229 v850_elf_reloc
, /* special_function */
230 "R_V850_ZDA_16_16_OFFSET", /* name */
231 false, /* partial_inplace */
232 0xffff, /* src_mask */
233 0xffff, /* dst_mask */
234 false), /* pcrel_offset */
236 /* 15 bit offset from the zero data area pointer. */
237 HOWTO (R_V850_ZDA_15_16_OFFSET
, /* type */
239 1, /* size (0 = byte, 1 = short, 2 = long) */
241 false, /* pc_relative */
243 complain_overflow_dont
, /* complain_on_overflow */
244 v850_elf_reloc
, /* special_function */
245 "R_V850_ZDA_15_16_OFFSET", /* name */
246 false, /* partial_inplace */
247 0xfffe, /* src_mask */
248 0xfffe, /* dst_mask */
249 false), /* pcrel_offset */
251 /* 6 bit offset from the tiny data area pointer. */
252 HOWTO (R_V850_TDA_6_8_OFFSET
, /* type */
254 1, /* size (0 = byte, 1 = short, 2 = long) */
256 false, /* pc_relative */
258 complain_overflow_dont
, /* complain_on_overflow */
259 v850_elf_reloc
, /* special_function */
260 "R_V850_TDA_6_8_OFFSET", /* name */
261 false, /* partial_inplace */
264 false), /* pcrel_offset */
266 /* 8 bit offset from the tiny data area pointer. */
267 HOWTO (R_V850_TDA_7_8_OFFSET
, /* type */
269 1, /* size (0 = byte, 1 = short, 2 = long) */
271 false, /* pc_relative */
273 complain_overflow_dont
, /* complain_on_overflow */
274 v850_elf_reloc
, /* special_function */
275 "R_V850_TDA_7_8_OFFSET", /* name */
276 false, /* partial_inplace */
279 false), /* pcrel_offset */
281 /* 7 bit offset from the tiny data area pointer. */
282 HOWTO (R_V850_TDA_7_7_OFFSET
, /* type */
284 1, /* size (0 = byte, 1 = short, 2 = long) */
286 false, /* pc_relative */
288 complain_overflow_dont
, /* complain_on_overflow */
289 v850_elf_reloc
, /* special_function */
290 "R_V850_TDA_7_7_OFFSET", /* name */
291 false, /* partial_inplace */
294 false), /* pcrel_offset */
296 /* 16 bit offset from the tiny data area pointer! */
297 HOWTO (R_V850_TDA_16_16_OFFSET
, /* type */
299 1, /* size (0 = byte, 1 = short, 2 = long) */
301 false, /* pc_relative */
303 complain_overflow_dont
, /* complain_on_overflow */
304 v850_elf_reloc
, /* special_function */
305 "R_V850_TDA_16_16_OFFSET", /* name */
306 false, /* partial_inplace */
307 0xffff, /* src_mask */
308 0xfff, /* dst_mask */
309 false), /* pcrel_offset */
311 /* start-sanitize-v850e */
313 /* 5 bit offset from the tiny data area pointer. */
314 HOWTO (R_V850_TDA_4_5_OFFSET
, /* type */
316 1, /* size (0 = byte, 1 = short, 2 = long) */
318 false, /* pc_relative */
320 complain_overflow_dont
, /* complain_on_overflow */
321 v850_elf_reloc
, /* special_function */
322 "R_V850_TDA_4_5_OFFSET", /* name */
323 false, /* partial_inplace */
326 false), /* pcrel_offset */
328 /* 4 bit offset from the tiny data area pointer. */
329 HOWTO (R_V850_TDA_4_4_OFFSET
, /* type */
331 1, /* size (0 = byte, 1 = short, 2 = long) */
333 false, /* pc_relative */
335 complain_overflow_dont
, /* complain_on_overflow */
336 v850_elf_reloc
, /* special_function */
337 "R_V850_TDA_4_4_OFFSET", /* name */
338 false, /* partial_inplace */
341 false), /* pcrel_offset */
343 /* 16 bit offset from the short data area pointer. */
344 HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET
, /* type */
346 2, /* size (0 = byte, 1 = short, 2 = long) */
348 false, /* pc_relative */
350 complain_overflow_dont
, /* complain_on_overflow */
351 v850_elf_reloc
, /* special_function */
352 "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
353 false, /* partial_inplace */
354 0xfffe0020, /* src_mask */
355 0xfffe0020, /* dst_mask */
356 false), /* pcrel_offset */
358 /* 16 bit offset from the zero data area pointer. */
359 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET
, /* type */
361 2, /* size (0 = byte, 1 = short, 2 = long) */
363 false, /* pc_relative */
365 complain_overflow_dont
, /* complain_on_overflow */
366 v850_elf_reloc
, /* special_function */
367 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
368 false, /* partial_inplace */
369 0xfffe0020, /* src_mask */
370 0xfffe0020, /* dst_mask */
371 false), /* pcrel_offset */
373 /* 6 bit offset from the call table base pointer. */
374 HOWTO (R_V850_CALLT_6_7_OFFSET
, /* type */
376 1, /* size (0 = byte, 1 = short, 2 = long) */
378 false, /* pc_relative */
380 complain_overflow_dont
, /* complain_on_overflow */
381 v850_elf_reloc
, /* special_function */
382 "R_V850_CALLT_6_7_OFFSET", /* name */
383 false, /* partial_inplace */
386 false), /* pcrel_offset */
388 /* 16 bit offset from the call table base pointer. */
389 HOWTO (R_V850_CALLT_16_16_OFFSET
, /* type */
391 1, /* size (0 = byte, 1 = short, 2 = long) */
393 false, /* pc_relative */
395 complain_overflow_dont
, /* complain_on_overflow */
396 v850_elf_reloc
, /* special_function */
397 "R_V850_CALLT_16_16_OFFSET", /* name */
398 false, /* partial_inplace */
399 0xffff, /* src_mask */
400 0xffff, /* dst_mask */
401 false), /* pcrel_offset */
403 /* end-sanitize-v850e */
406 /* Map BFD reloc types to V850 ELF reloc types. */
408 struct v850_elf_reloc_map
410 unsigned char bfd_reloc_val
;
411 unsigned char elf_reloc_val
;
414 static const struct v850_elf_reloc_map v850_elf_reloc_map
[] =
416 { BFD_RELOC_NONE
, R_V850_NONE
},
417 { BFD_RELOC_V850_9_PCREL
, R_V850_9_PCREL
},
418 { BFD_RELOC_V850_22_PCREL
, R_V850_22_PCREL
},
419 { BFD_RELOC_HI16_S
, R_V850_HI16_S
},
420 { BFD_RELOC_HI16
, R_V850_HI16
},
421 { BFD_RELOC_LO16
, R_V850_LO16
},
422 { BFD_RELOC_32
, R_V850_32
},
423 { BFD_RELOC_16
, R_V850_16
},
424 { BFD_RELOC_8
, R_V850_8
},
425 { BFD_RELOC_V850_SDA_16_16_OFFSET
, R_V850_SDA_16_16_OFFSET
},
426 { BFD_RELOC_V850_SDA_15_16_OFFSET
, R_V850_SDA_15_16_OFFSET
},
427 { BFD_RELOC_V850_ZDA_16_16_OFFSET
, R_V850_ZDA_16_16_OFFSET
},
428 { BFD_RELOC_V850_ZDA_15_16_OFFSET
, R_V850_ZDA_15_16_OFFSET
},
429 { BFD_RELOC_V850_TDA_6_8_OFFSET
, R_V850_TDA_6_8_OFFSET
},
430 { BFD_RELOC_V850_TDA_7_8_OFFSET
, R_V850_TDA_7_8_OFFSET
},
431 { BFD_RELOC_V850_TDA_7_7_OFFSET
, R_V850_TDA_7_7_OFFSET
},
432 { BFD_RELOC_V850_TDA_16_16_OFFSET
, R_V850_TDA_16_16_OFFSET
},
433 /* start-sanitize-v850e */
434 { BFD_RELOC_V850_TDA_4_5_OFFSET
, R_V850_TDA_4_5_OFFSET
},
435 { BFD_RELOC_V850_TDA_4_4_OFFSET
, R_V850_TDA_4_4_OFFSET
},
436 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET
, R_V850_SDA_16_16_SPLIT_OFFSET
},
437 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET
, R_V850_ZDA_16_16_SPLIT_OFFSET
},
438 { BFD_RELOC_V850_CALLT_6_7_OFFSET
, R_V850_CALLT_6_7_OFFSET
},
439 { BFD_RELOC_V850_CALLT_16_16_OFFSET
, R_V850_CALLT_16_16_OFFSET
},
440 /* end-sanitize-v850e */
444 /* Map a bfd relocation into the appropriate howto structure */
445 static reloc_howto_type
*
446 v850_elf_reloc_type_lookup (abfd
, code
)
448 bfd_reloc_code_real_type code
;
453 i
< sizeof (v850_elf_reloc_map
) / sizeof (struct v850_elf_reloc_map
);
456 if (v850_elf_reloc_map
[i
].bfd_reloc_val
== code
)
458 BFD_ASSERT (v850_elf_howto_table
[v850_elf_reloc_map
[i
].elf_reloc_val
].type
== v850_elf_reloc_map
[i
].elf_reloc_val
);
460 return & v850_elf_howto_table
[v850_elf_reloc_map
[i
].elf_reloc_val
];
468 /* Set the howto pointer for an V850 ELF reloc. */
470 v850_elf_info_to_howto_rel (abfd
, cache_ptr
, dst
)
473 Elf32_Internal_Rel
* dst
;
477 r_type
= ELF32_R_TYPE (dst
->r_info
);
478 BFD_ASSERT (r_type
< (unsigned int) R_V850_max
);
479 cache_ptr
->howto
= &v850_elf_howto_table
[r_type
];
483 /* Look through the relocs for a section during the first phase, and
484 allocate space in the global offset table or procedure linkage
488 v850_elf_check_relocs (abfd
, info
, sec
, relocs
)
490 struct bfd_link_info
* info
;
492 const Elf_Internal_Rela
* relocs
;
496 Elf_Internal_Shdr
*symtab_hdr
;
497 struct elf_link_hash_entry
**sym_hashes
;
498 const Elf_Internal_Rela
*rel
;
499 const Elf_Internal_Rela
*rel_end
;
501 enum reloc_type r_type
;
503 const char *common
= (const char *)0;
505 if (info
->relocateable
)
509 fprintf (stderr
, "v850_elf_check_relocs called for section %s in %s\n",
510 bfd_get_section_name (abfd
, sec
),
511 bfd_get_filename (abfd
));
514 dynobj
= elf_hash_table (info
)->dynobj
;
515 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
516 sym_hashes
= elf_sym_hashes (abfd
);
519 rel_end
= relocs
+ sec
->reloc_count
;
520 for (rel
= relocs
; rel
< rel_end
; rel
++)
522 unsigned long r_symndx
;
523 struct elf_link_hash_entry
*h
;
525 r_symndx
= ELF32_R_SYM (rel
->r_info
);
526 if (r_symndx
< symtab_hdr
->sh_info
)
529 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
531 r_type
= (enum reloc_type
) ELF32_R_TYPE (rel
->r_info
);
537 case R_V850_22_PCREL
:
544 /* start-sanitize-v850e */
545 case R_V850_CALLT_6_7_OFFSET
:
546 case R_V850_CALLT_16_16_OFFSET
:
547 /* end-sanitize-v850e */
550 /* start-sanitize-v850e */
551 case R_V850_SDA_16_16_SPLIT_OFFSET
:
552 /* end-sanitize-v850e */
553 case R_V850_SDA_16_16_OFFSET
:
554 case R_V850_SDA_15_16_OFFSET
:
555 other
= V850_OTHER_SDA
;
557 goto small_data_common
;
559 /* start-sanitize-v850e */
560 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
561 /* end-sanitize-v850e */
562 case R_V850_ZDA_16_16_OFFSET
:
563 case R_V850_ZDA_15_16_OFFSET
:
564 other
= V850_OTHER_ZDA
;
566 goto small_data_common
;
568 /* start-sanitize-v850e */
569 case R_V850_TDA_4_5_OFFSET
:
570 case R_V850_TDA_4_4_OFFSET
:
571 /* end-sanitize-v850e */
572 case R_V850_TDA_6_8_OFFSET
:
573 case R_V850_TDA_7_8_OFFSET
:
574 case R_V850_TDA_7_7_OFFSET
:
575 case R_V850_TDA_16_16_OFFSET
:
576 other
= V850_OTHER_TDA
;
580 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
585 h
->other
|= other
; /* flag which type of relocation was used */
586 if ((h
->other
& V850_OTHER_MASK
) != (other
& V850_OTHER_MASK
)
587 && (h
->other
& V850_OTHER_ERROR
) == 0)
591 switch (h
->other
& V850_OTHER_MASK
)
594 msg
= "Variable cannot occupy in multiple small data regions";
596 case V850_OTHER_SDA
| V850_OTHER_ZDA
| V850_OTHER_TDA
:
597 msg
= "Variable can only be in one of the small, zero, and tiny data regions";
599 case V850_OTHER_SDA
| V850_OTHER_ZDA
:
600 msg
= "Variable cannot be in both small and zero data regions simultaneously";
602 case V850_OTHER_SDA
| V850_OTHER_TDA
:
603 msg
= "Variable cannot be in both small and tiny data regions simultaneously";
605 case V850_OTHER_ZDA
| V850_OTHER_TDA
:
606 msg
= "Variable cannot be in both zero and tiny data regions simultaneously";
610 (*info
->callbacks
->warning
) (info
, msg
, h
->root
.root
.string
,
611 abfd
, h
->root
.u
.def
.section
, 0);
613 bfd_set_error (bfd_error_bad_value
);
614 h
->other
|= V850_OTHER_ERROR
;
619 if (h
&& h
->root
.type
== bfd_link_hash_common
621 && !strcmp (bfd_get_section_name (abfd
, h
->root
.u
.c
.p
->section
), "COMMON"))
623 asection
*section
= h
->root
.u
.c
.p
->section
= bfd_make_section_old_way (abfd
, common
);
624 section
->flags
|= SEC_IS_COMMON
;
628 fprintf (stderr
, "v850_elf_check_relocs, found %s relocation for %s%s\n",
629 v850_elf_howto_table
[ (int)r_type
].name
,
630 (h
&& h
->root
.root
.string
) ? h
->root
.root
.string
: "<unknown>",
631 (h
->root
.type
== bfd_link_hash_common
) ? ", symbol is common" : "");
641 /* Insert the addend into the instruction. */
642 static bfd_reloc_status_type
643 v850_elf_reloc (abfd
, reloc
, symbol
, data
, isection
, obfd
, err
)
656 /* If there is an output BFD,
657 and the symbol is not a section name (which is only defined at final link time),
658 and either we are not putting the addend into the instruction
659 or the addend is zero, so there is nothing to add into the instruction
660 then just fixup the address and return. */
661 if (obfd
!= (bfd
*) NULL
662 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
663 && (! reloc
->howto
->partial_inplace
664 || reloc
->addend
== 0))
666 reloc
->address
+= isection
->output_offset
;
670 else if (obfd
!= NULL
)
672 return bfd_reloc_continue
;
676 /* Catch relocs involving undefined symbols. */
677 if (bfd_is_und_section (symbol
->section
)
678 && (symbol
->flags
& BSF_WEAK
) == 0
680 return bfd_reloc_undefined
;
682 /* We handle final linking of some relocs ourselves. */
684 /* Is the address of the relocation really within the section? */
685 if (reloc
->address
> isection
->_cooked_size
)
686 return bfd_reloc_outofrange
;
688 /* Work out which section the relocation is targetted at and the
689 initial relocation command value. */
691 /* Get symbol value. (Common symbols are special.) */
692 if (bfd_is_com_section (symbol
->section
))
695 relocation
= symbol
->value
;
697 /* Convert input-section-relative symbol value to absolute + addend. */
698 relocation
+= symbol
->section
->output_section
->vma
;
699 relocation
+= symbol
->section
->output_offset
;
700 relocation
+= reloc
->addend
;
702 if (reloc
->howto
->pc_relative
== true)
704 /* Here the variable relocation holds the final address of the
705 symbol we are relocating against, plus any addend. */
706 relocation
-= isection
->output_section
->vma
+ isection
->output_offset
;
708 /* Deal with pcrel_offset */
709 relocation
-= reloc
->address
;
712 /* I've got no clue... */
715 switch (reloc
->howto
->type
)
718 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", reloc->howto->type ); */
719 return bfd_reloc_notsupported
;
721 case R_V850_22_PCREL
:
722 if (relocation
> 0x1ffff || relocation
< -0x200000)
723 return bfd_reloc_overflow
;
725 if ((relocation
% 2) != 0)
726 return bfd_reloc_dangerous
;
728 insn
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
730 insn
|= (((relocation
& 0xfffe) << 16)
731 | ((relocation
& 0x3f0000) >> 16));
732 bfd_put_32 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
736 if (relocation
> 0xff || relocation
< -0x100)
737 return bfd_reloc_overflow
;
739 if ((relocation
% 2) != 0)
740 return bfd_reloc_dangerous
;
742 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
744 insn
|= ((relocation
& 0x1f0) << 7) | ((relocation
& 0x0e) << 3);
745 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
749 relocation
+= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
750 relocation
= (relocation
>> 16) + ((relocation
& 0x8000) != 0);
751 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
755 relocation
+= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
756 relocation
= (relocation
>> 16);
757 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
761 relocation
+= (short)bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
762 /* Do not complain if value has top bit set, as this has been anticipated. */
763 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
767 relocation
+= (short)bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
770 case R_V850_SDA_16_16_OFFSET
:
771 case R_V850_ZDA_16_16_OFFSET
:
772 case R_V850_TDA_16_16_OFFSET
:
773 if ((long)relocation
> 0x7fff || (long)relocation
< -0x8000)
774 return bfd_reloc_overflow
;
775 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
778 case R_V850_SDA_15_16_OFFSET
:
779 case R_V850_ZDA_15_16_OFFSET
:
780 if ((long)relocation
> 0x7ffe || (long)relocation
< -0x8000)
781 return bfd_reloc_overflow
;
784 return bfd_reloc_dangerous
;
786 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
788 insn
|= (relocation
>> 1) & ~1;
790 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
793 case R_V850_TDA_6_8_OFFSET
:
794 if ((long) relocation
> 0xfc || (long) relocation
< 0)
795 return bfd_reloc_overflow
;
798 return bfd_reloc_dangerous
;
800 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
802 insn
|= (relocation
>> 1);
804 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
807 case R_V850_TDA_7_8_OFFSET
:
808 if ((long) relocation
> 0xfe || (long) relocation
< 0)
809 return bfd_reloc_overflow
;
812 return bfd_reloc_dangerous
;
814 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
816 insn
|= (relocation
>> 1);
818 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
821 case R_V850_TDA_7_7_OFFSET
:
822 if ((long) relocation
> 0x7f || (long) relocation
< 0)
823 return bfd_reloc_overflow
;
825 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
829 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
832 /* start-sanitize-v850e */
833 case R_V850_TDA_4_5_OFFSET
:
834 if ((long) relocation
> 0x1e || (long) relocation
< 0)
835 return bfd_reloc_overflow
;
838 return bfd_reloc_dangerous
;
840 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
842 insn
|= (relocation
>> 1);
844 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
847 case R_V850_TDA_4_4_OFFSET
:
848 if ((long) relocation
> 0xf || (long) relocation
< 0)
849 return bfd_reloc_overflow
;
851 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
855 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
858 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
859 case R_V850_SDA_16_16_SPLIT_OFFSET
:
860 if ((long) relocation
> 0xffff || (long) relocation
< 0)
861 return bfd_reloc_overflow
;
863 insn
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
866 insn
|= (relocation
& 1) << 5;
867 insn
|= (relocation
& ~1) << 16;
869 bfd_put_32 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
872 case R_V850_CALLT_6_7_OFFSET
:
873 if ((long) relocation
> 0x7e || (long) relocation
< 0)
874 return bfd_reloc_overflow
;
877 return bfd_reloc_dangerous
;
879 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
881 insn
|= (relocation
>> 1);
883 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
886 case R_V850_CALLT_16_16_OFFSET
:
887 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
890 /* end-sanitize-v850e */
893 return bfd_reloc_continue
;
899 v850_elf_is_local_label_name (abfd
, name
)
903 return ((name
[0] == '.' && (name
[1] == 'L' || name
[1] == '.'))
904 || (name
[0] == '_' && name
[1] == '.' && name
[2] == 'L'
909 /* Perform a relocation as part of a final link. */
910 static bfd_reloc_status_type
911 v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
912 input_section
, contents
, offset
, value
,
913 addend
, info
, sym_sec
, is_local
)
914 reloc_howto_type
* howto
;
917 asection
* input_section
;
922 struct bfd_link_info
* info
;
927 unsigned long r_type
= howto
->type
;
928 bfd_byte
* hit_data
= contents
+ offset
;
933 value
-= (input_section
->output_section
->vma
934 + input_section
->output_offset
);
937 if ((long)value
> 0xff || (long)value
< -0x100)
938 return bfd_reloc_overflow
;
940 if ((value
% 2) != 0)
941 return bfd_reloc_dangerous
;
943 insn
= bfd_get_16 (input_bfd
, hit_data
);
945 insn
|= ((value
& 0x1f0) << 7) | ((value
& 0x0e) << 3);
946 bfd_put_16 (input_bfd
, insn
, hit_data
);
949 case R_V850_22_PCREL
:
950 value
-= (input_section
->output_section
->vma
951 + input_section
->output_offset
);
954 if ((long)value
> 0x1ffff || (long)value
< -0x200000)
955 return bfd_reloc_overflow
;
957 if ((value
% 2) != 0)
958 return bfd_reloc_dangerous
;
960 insn
= bfd_get_32 (input_bfd
, hit_data
);
962 insn
|= (((value
& 0xfffe) << 16) | ((value
& 0x3f0000) >> 16));
963 bfd_put_32 (input_bfd
, insn
, hit_data
);
967 value
+= (short)bfd_get_16 (input_bfd
, hit_data
);
968 value
= (value
>> 16) + ((value
& 0x8000) != 0);
970 if ((long)value
> 0x7fff || (long)value
< -0x8000)
971 return bfd_reloc_overflow
;
973 bfd_put_16 (input_bfd
, value
, hit_data
);
977 value
+= (short)bfd_get_16 (input_bfd
, hit_data
);
980 if ((long)value
> 0x7fff || (long)value
< -0x8000)
981 return bfd_reloc_overflow
;
983 bfd_put_16 (input_bfd
, value
, hit_data
);
987 value
+= (short)bfd_get_16 (input_bfd
, hit_data
);
990 bfd_put_16 (input_bfd
, value
, hit_data
);
994 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
996 if ((long) value
> 0x7fff || (long) value
< -0x8000)
997 return bfd_reloc_overflow
;
999 bfd_put_16 (input_bfd
, value
, hit_data
);
1000 return bfd_reloc_ok
;
1002 case R_V850_ZDA_16_16_OFFSET
:
1003 if (sym_sec
== NULL
)
1004 return bfd_reloc_undefined
;
1006 value
-= sym_sec
->output_section
->vma
;
1007 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
1009 if ((long) value
> 0x7fff || (long) value
< -0x8000)
1010 return bfd_reloc_overflow
;
1012 bfd_put_16 (input_bfd
, value
, hit_data
);
1013 return bfd_reloc_ok
;
1015 case R_V850_ZDA_15_16_OFFSET
:
1016 if (sym_sec
== NULL
)
1017 return bfd_reloc_undefined
;
1019 insn
= bfd_get_16 (input_bfd
, hit_data
);
1021 value
-= sym_sec
->output_section
->vma
;
1022 value
+= ((insn
& 0xfffe) << 1);
1024 if ((long) value
> 0x7ffe || (long) value
< -0x8000)
1025 return bfd_reloc_overflow
;
1028 value
|= (insn
& 1);
1030 bfd_put_16 (input_bfd
, value
, hit_data
);
1031 return bfd_reloc_ok
;
1034 value
+= bfd_get_32 (input_bfd
, hit_data
);
1035 bfd_put_32 (input_bfd
, value
, hit_data
);
1036 return bfd_reloc_ok
;
1039 value
+= (char)bfd_get_8 (input_bfd
, hit_data
);
1041 if ((long)value
> 0x7f || (long)value
< -0x80)
1042 return bfd_reloc_overflow
;
1044 bfd_put_8 (input_bfd
, value
, hit_data
);
1045 return bfd_reloc_ok
;
1047 case R_V850_SDA_16_16_OFFSET
:
1048 if (sym_sec
== NULL
)
1049 return bfd_reloc_undefined
;
1053 struct bfd_link_hash_entry
* h
;
1055 /* Get the value of __gp. */
1056 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1057 if (h
== (struct bfd_link_hash_entry
*) NULL
1058 || h
->type
!= bfd_link_hash_defined
)
1059 return bfd_reloc_other
;
1061 gp
= (h
->u
.def
.value
1062 + h
->u
.def
.section
->output_section
->vma
1063 + h
->u
.def
.section
->output_offset
);
1065 value
-= sym_sec
->output_section
->vma
;
1066 value
-= (gp
- sym_sec
->output_section
->vma
);
1067 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
1069 if ((long)value
> 0x7fff || (long)value
< -0x8000)
1070 return bfd_reloc_overflow
;
1072 bfd_put_16 (input_bfd
, value
, hit_data
);
1073 return bfd_reloc_ok
;
1076 case R_V850_SDA_15_16_OFFSET
:
1077 if (sym_sec
== NULL
)
1078 return bfd_reloc_undefined
;
1082 struct bfd_link_hash_entry
* h
;
1084 /* Get the value of __gp. */
1085 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1086 if (h
== (struct bfd_link_hash_entry
*) NULL
1087 || h
->type
!= bfd_link_hash_defined
)
1088 return bfd_reloc_other
;
1090 gp
= (h
->u
.def
.value
1091 + h
->u
.def
.section
->output_section
->vma
1092 + h
->u
.def
.section
->output_offset
);
1094 value
-= sym_sec
->output_section
->vma
;
1095 value
-= (gp
- sym_sec
->output_section
->vma
);
1097 insn
= bfd_get_16 (input_bfd
, hit_data
);
1099 value
+= ((insn
& 0xfffe) << 1);
1101 if ((long)value
> 0x7ffe || (long)value
< -0x8000)
1102 return bfd_reloc_overflow
;
1105 value
|= (insn
& 1);
1107 bfd_put_16 (input_bfd
, value
, hit_data
);
1108 return bfd_reloc_ok
;
1111 case R_V850_TDA_6_8_OFFSET
:
1114 struct bfd_link_hash_entry
* h
;
1116 insn
= bfd_get_16 (input_bfd
, hit_data
);
1118 /* Get the value of __ep. */
1119 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1120 if (h
== (struct bfd_link_hash_entry
*) NULL
1121 || h
->type
!= bfd_link_hash_defined
)
1122 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1124 ep
= (h
->u
.def
.value
1125 + h
->u
.def
.section
->output_section
->vma
1126 + h
->u
.def
.section
->output_offset
);
1129 value
+= ((insn
& 0x7e) << 2);
1131 if ((long) value
> 0xfc || (long) value
< 0)
1132 return bfd_reloc_overflow
;
1134 if ((value
% 2) != 0)
1135 return bfd_reloc_dangerous
;
1138 insn
|= (value
>> 1);
1140 bfd_put_16 (input_bfd
, insn
, hit_data
);
1141 return bfd_reloc_ok
;
1144 case R_V850_TDA_7_8_OFFSET
:
1147 struct bfd_link_hash_entry
* h
;
1149 insn
= bfd_get_16 (input_bfd
, hit_data
);
1151 /* Get the value of __ep. */
1152 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1153 if (h
== (struct bfd_link_hash_entry
*) NULL
1154 || h
->type
!= bfd_link_hash_defined
)
1155 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1157 ep
= (h
->u
.def
.value
1158 + h
->u
.def
.section
->output_section
->vma
1159 + h
->u
.def
.section
->output_offset
);
1162 value
+= ((insn
& 0x7f) << 1);
1164 if ((long) value
> 0xfe || (long) value
< 0)
1165 return bfd_reloc_overflow
;
1168 insn
|= (value
>> 1);
1170 bfd_put_16 (input_bfd
, insn
, hit_data
);
1171 return bfd_reloc_ok
;
1174 case R_V850_TDA_7_7_OFFSET
:
1177 struct bfd_link_hash_entry
* h
;
1179 insn
= bfd_get_16 (input_bfd
, hit_data
);
1181 /* Get the value of __ep. */
1182 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1183 if (h
== (struct bfd_link_hash_entry
*) NULL
1184 || h
->type
!= bfd_link_hash_defined
)
1185 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1187 ep
= (h
->u
.def
.value
1188 + h
->u
.def
.section
->output_section
->vma
1189 + h
->u
.def
.section
->output_offset
);
1192 value
+= insn
& 0x7f;
1194 if ((long) value
> 0x7f || (long) value
< 0)
1195 return bfd_reloc_overflow
;
1199 bfd_put_16 (input_bfd
, insn
, hit_data
);
1200 return bfd_reloc_ok
;
1203 case R_V850_TDA_16_16_OFFSET
:
1206 struct bfd_link_hash_entry
* h
;
1208 /* Get the value of __ep. */
1209 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1210 if (h
== (struct bfd_link_hash_entry
*) NULL
1211 || h
->type
!= bfd_link_hash_defined
)
1212 return bfd_reloc_other
;
1214 ep
= (h
->u
.def
.value
1215 + h
->u
.def
.section
->output_section
->vma
1216 + h
->u
.def
.section
->output_offset
);
1219 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
1221 if ((long)value
> 0x7fff || (long)value
< -0x8000)
1222 return bfd_reloc_overflow
;
1224 bfd_put_16 (input_bfd
, value
, hit_data
);
1225 return bfd_reloc_ok
;
1228 /* start-sanitize-v850e */
1229 case R_V850_TDA_4_5_OFFSET
:
1232 struct bfd_link_hash_entry
* h
;
1234 /* Get the value of __ep. */
1235 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1236 if (h
== (struct bfd_link_hash_entry
*) NULL
1237 || h
->type
!= bfd_link_hash_defined
)
1238 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1240 ep
= (h
->u
.def
.value
1241 + h
->u
.def
.section
->output_section
->vma
1242 + h
->u
.def
.section
->output_offset
);
1245 insn
= bfd_get_16 (input_bfd
, hit_data
);
1247 value
+= ((insn
& 0xf) << 1);
1249 if ((long) value
> 0x1e || (long) value
< 0)
1250 return bfd_reloc_overflow
;
1253 insn
|= (value
>> 1);
1254 bfd_put_16 (input_bfd
, insn
, hit_data
);
1255 return bfd_reloc_ok
;
1258 case R_V850_TDA_4_4_OFFSET
:
1261 struct bfd_link_hash_entry
* h
;
1263 /* Get the value of __ep. */
1264 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1265 if (h
== (struct bfd_link_hash_entry
*) NULL
1266 || h
->type
!= bfd_link_hash_defined
)
1267 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1269 ep
= (h
->u
.def
.value
1270 + h
->u
.def
.section
->output_section
->vma
1271 + h
->u
.def
.section
->output_offset
);
1274 insn
= bfd_get_16 (input_bfd
, hit_data
);
1276 value
+= insn
& 0xf;
1278 if ((long) value
> 0xf || (long) value
< 0)
1279 return bfd_reloc_overflow
;
1283 bfd_put_16 (input_bfd
, insn
, hit_data
);
1284 return bfd_reloc_ok
;
1287 case R_V850_SDA_16_16_SPLIT_OFFSET
:
1288 if (sym_sec
== NULL
)
1289 return bfd_reloc_undefined
;
1293 struct bfd_link_hash_entry
* h
;
1295 /* Get the value of __gp. */
1296 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1297 if (h
== (struct bfd_link_hash_entry
*) NULL
1298 || h
->type
!= bfd_link_hash_defined
)
1299 return bfd_reloc_other
;
1301 gp
= (h
->u
.def
.value
1302 + h
->u
.def
.section
->output_section
->vma
1303 + h
->u
.def
.section
->output_offset
);
1305 value
-= sym_sec
->output_section
->vma
;
1306 value
-= (gp
- sym_sec
->output_section
->vma
);
1308 insn
= bfd_get_32 (input_bfd
, hit_data
);
1310 value
+= ((insn
& 0xfffe0000) >> 16);
1311 value
+= ((insn
& 0x20) >> 5);
1313 if ((long)value
> 0x7fff || (long)value
< -0x8000)
1314 return bfd_reloc_overflow
;
1317 insn
|= (value
& 1) << 5;
1318 insn
|= (value
& ~1) << 16;
1320 bfd_put_32 (input_bfd
, insn
, hit_data
);
1321 return bfd_reloc_ok
;
1324 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
1325 if (sym_sec
== NULL
)
1326 return bfd_reloc_undefined
;
1328 insn
= bfd_get_32 (input_bfd
, hit_data
);
1330 value
-= sym_sec
->output_section
->vma
;
1331 value
+= ((insn
& 0xfffe0000) >> 16);
1332 value
+= ((insn
& 0x20) >> 5);
1334 if ((long)value
> 0x7fff || (long)value
< -0x8000)
1335 return bfd_reloc_overflow
;
1338 insn
|= (value
& 1) << 5;
1339 insn
|= (value
& ~1) << 16;
1341 bfd_put_32 (input_bfd
, insn
, hit_data
);
1342 return bfd_reloc_ok
;
1344 case R_V850_CALLT_6_7_OFFSET
:
1347 struct bfd_link_hash_entry
* h
;
1349 /* Get the value of __ctbp. */
1350 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1351 if (h
== (struct bfd_link_hash_entry
*) NULL
1352 || h
->type
!= bfd_link_hash_defined
)
1353 return bfd_reloc_continue
; /* Actually this indicates that __ctbp could not be found. */
1355 ctbp
= (h
->u
.def
.value
1356 + h
->u
.def
.section
->output_section
->vma
1357 + h
->u
.def
.section
->output_offset
);
1360 insn
= bfd_get_16 (input_bfd
, hit_data
);
1362 value
+= ((insn
& 0x3f) << 1);
1364 if ((long) value
> 0x7e || (long) value
< 0)
1365 return bfd_reloc_overflow
;
1368 insn
|= (value
>> 1);
1369 bfd_put_16 (input_bfd
, insn
, hit_data
);
1370 return bfd_reloc_ok
;
1373 case R_V850_CALLT_16_16_OFFSET
:
1374 if (sym_sec
== NULL
)
1375 return bfd_reloc_undefined
;
1379 struct bfd_link_hash_entry
* h
;
1381 /* Get the value of __ctbp. */
1382 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1383 if (h
== (struct bfd_link_hash_entry
*) NULL
1384 || h
->type
!= bfd_link_hash_defined
)
1385 return bfd_reloc_other
;
1387 ctbp
= (h
->u
.def
.value
1388 + h
->u
.def
.section
->output_section
->vma
1389 + h
->u
.def
.section
->output_offset
);
1391 value
-= sym_sec
->output_section
->vma
;
1392 value
-= (ctbp
- sym_sec
->output_section
->vma
);
1393 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
1395 if ((long) value
> 0xffff || (long) value
< 0)
1396 return bfd_reloc_overflow
;
1398 bfd_put_16 (input_bfd
, value
, hit_data
);
1399 return bfd_reloc_ok
;
1402 /* end-sanitize-v850e */
1405 return bfd_reloc_ok
;
1408 return bfd_reloc_notsupported
;
1413 /* Relocate an V850 ELF section. */
1415 v850_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
1416 contents
, relocs
, local_syms
, local_sections
)
1418 struct bfd_link_info
* info
;
1420 asection
* input_section
;
1421 bfd_byte
* contents
;
1422 Elf_Internal_Rela
* relocs
;
1423 Elf_Internal_Sym
* local_syms
;
1424 asection
** local_sections
;
1426 Elf_Internal_Shdr
* symtab_hdr
;
1427 struct elf_link_hash_entry
** sym_hashes
;
1428 Elf_Internal_Rela
* rel
;
1429 Elf_Internal_Rela
* relend
;
1431 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
1432 sym_hashes
= elf_sym_hashes (input_bfd
);
1435 relend
= relocs
+ input_section
->reloc_count
;
1436 for (; rel
< relend
; rel
++)
1439 reloc_howto_type
* howto
;
1440 unsigned long r_symndx
;
1441 Elf_Internal_Sym
* sym
;
1443 struct elf_link_hash_entry
* h
;
1445 bfd_reloc_status_type r
;
1447 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1448 r_type
= ELF32_R_TYPE (rel
->r_info
);
1449 howto
= v850_elf_howto_table
+ r_type
;
1451 if (info
->relocateable
)
1453 /* This is a relocateable link. We don't have to change
1454 anything, unless the reloc is against a section symbol,
1455 in which case we have to adjust according to where the
1456 section symbol winds up in the output section. */
1457 if (r_symndx
< symtab_hdr
->sh_info
)
1459 sym
= local_syms
+ r_symndx
;
1460 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1462 sec
= local_sections
[r_symndx
];
1463 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1470 /* This is a final link. */
1474 if (r_symndx
< symtab_hdr
->sh_info
)
1476 sym
= local_syms
+ r_symndx
;
1477 sec
= local_sections
[r_symndx
];
1478 relocation
= (sec
->output_section
->vma
1479 + sec
->output_offset
1484 name
= bfd_elf_string_from_elf_section (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
1485 name
= (name
== NULL
) ? "<none>" : name
;
1486 fprintf (stderr
, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x rel %x\n", sec
->name
, name
, sym
->st_name
,
1487 sec
->output_section
->vma
, sec
->output_offset
, sym
->st_value
, rel
->r_addend
, rel
);
1493 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1495 while (h
->root
.type
== bfd_link_hash_indirect
1496 || h
->root
.type
== bfd_link_hash_warning
)
1497 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1499 if (h
->root
.type
== bfd_link_hash_defined
1500 || h
->root
.type
== bfd_link_hash_defweak
)
1502 sec
= h
->root
.u
.def
.section
;
1503 relocation
= (h
->root
.u
.def
.value
1504 + sec
->output_section
->vma
1505 + sec
->output_offset
);
1507 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1511 if (! ((*info
->callbacks
->undefined_symbol
)
1512 (info
, h
->root
.root
.string
, input_bfd
,
1513 input_section
, rel
->r_offset
)))
1519 /* FIXME: We should use the addend, but the COFF relocations
1521 r
= v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
1523 contents
, rel
->r_offset
,
1524 relocation
, rel
->r_addend
,
1525 info
, sec
, h
== NULL
);
1527 if (r
!= bfd_reloc_ok
)
1530 const char * msg
= (const char *)0;
1533 name
= h
->root
.root
.string
;
1536 name
= (bfd_elf_string_from_elf_section
1537 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1538 if (name
== NULL
|| *name
== '\0')
1539 name
= bfd_section_name (input_bfd
, sec
);
1544 case bfd_reloc_overflow
:
1545 if (! ((*info
->callbacks
->reloc_overflow
)
1546 (info
, name
, howto
->name
, (bfd_vma
) 0,
1547 input_bfd
, input_section
, rel
->r_offset
)))
1551 case bfd_reloc_undefined
:
1552 fprintf (stderr
, "undef2 %s\n", name
);
1553 if (! ((*info
->callbacks
->undefined_symbol
)
1554 (info
, name
, input_bfd
, input_section
,
1559 case bfd_reloc_outofrange
:
1560 msg
= "internal error: out of range error";
1563 case bfd_reloc_notsupported
:
1564 msg
= "internal error: unsupported relocation error";
1567 case bfd_reloc_dangerous
:
1568 msg
= "internal error: dangerous relocation";
1571 case bfd_reloc_other
:
1572 msg
= "could not locate special linker symbol __gp";
1575 case bfd_reloc_continue
:
1576 msg
= "could not locate special linker symbol __ep";
1580 msg
= "internal error: unknown error";
1584 if (!((*info
->callbacks
->warning
)
1585 (info
, msg
, name
, input_bfd
, input_section
,
1596 /* Set the right machine number. */
1598 v850_elf_object_p (abfd
)
1601 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1604 case E_V850_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, 0); break;
1605 /* start-sanitize-v850e */
1606 case E_V850E_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850e
); break;
1607 /* end-sanitize-v850e */
1608 /* start-sanitize-v850eq */
1609 case E_V850EQ_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850eq
); break;
1610 /* end-sanitize-v850eq */
1614 /* Store the machine number in the flags field. */
1616 v850_elf_final_write_processing (abfd
, linker
)
1622 switch (bfd_get_mach (abfd
))
1625 case 0: val
= E_V850_ARCH
; break;
1626 /* start-sanitize-v850e */
1627 case bfd_mach_v850e
: val
= E_V850E_ARCH
; break;
1628 /* end-sanitize-v850e */
1629 /* start-sanitize-v850eq */
1630 case bfd_mach_v850eq
: val
= E_V850EQ_ARCH
; break;
1631 /* end-sanitize-v850eq */
1634 elf_elfheader (abfd
)->e_flags
&=~ EF_V850_ARCH
;
1635 elf_elfheader (abfd
)->e_flags
|= val
;
1638 /* Function to keep V850 specific file flags. */
1640 v850_elf_set_private_flags (abfd
, flags
)
1644 BFD_ASSERT (!elf_flags_init (abfd
)
1645 || elf_elfheader (abfd
)->e_flags
== flags
);
1647 elf_elfheader (abfd
)->e_flags
= flags
;
1648 elf_flags_init (abfd
) = true;
1652 /* Copy backend specific data from one object module to another */
1654 v850_elf_copy_private_bfd_data (ibfd
, obfd
)
1658 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1659 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1662 BFD_ASSERT (!elf_flags_init (obfd
)
1663 || (elf_elfheader (obfd
)->e_flags
1664 == elf_elfheader (ibfd
)->e_flags
));
1666 elf_gp (obfd
) = elf_gp (ibfd
);
1667 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
1668 elf_flags_init (obfd
) = true;
1672 /* Merge backend specific data from an object file to the output
1673 object file when linking. */
1675 v850_elf_merge_private_bfd_data (ibfd
, obfd
)
1682 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1683 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1686 new_flags
= elf_elfheader (ibfd
)->e_flags
;
1687 old_flags
= elf_elfheader (obfd
)->e_flags
;
1689 if (! elf_flags_init (obfd
))
1691 elf_flags_init (obfd
) = true;
1692 elf_elfheader (obfd
)->e_flags
= new_flags
;
1694 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
1695 && bfd_get_arch_info (obfd
)->the_default
)
1697 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
1703 /* Check flag compatibility. */
1705 if (new_flags
== old_flags
)
1708 if ((new_flags
& EF_V850_ARCH
) != (old_flags
& EF_V850_ARCH
))
1710 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1711 bfd_get_filename (ibfd
));
1712 bfd_set_error (bfd_error_bad_value
);
1718 /* Display the flags field */
1721 v850_elf_print_private_bfd_data (abfd
, ptr
)
1725 FILE * file
= (FILE *) ptr
;
1727 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
)
1729 fprintf (file
, "private flags = %x", elf_elfheader (abfd
)->e_flags
);
1731 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1734 case E_V850_ARCH
: fprintf (file
, ": v850 architecture"); break;
1735 /* start-sanitize-v850e */
1736 case E_V850E_ARCH
: fprintf (file
, ": v850e architecture"); break;
1737 /* end-sanitize-v850e */
1738 /* start-sanitize-v850eq */
1739 case E_V850EQ_ARCH
: fprintf (file
, ": v850eq architecture"); break;
1740 /* end-sanitize-v850eq */
1748 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
1749 #define TARGET_LITTLE_NAME "elf32-v850"
1750 #define ELF_ARCH bfd_arch_v850
1751 #define ELF_MACHINE_CODE EM_CYGNUS_V850
1752 #define ELF_MAXPAGESIZE 0x1000
1754 #define elf_info_to_howto 0
1755 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
1756 #define elf_backend_check_relocs v850_elf_check_relocs
1757 #define elf_backend_relocate_section v850_elf_relocate_section
1758 #define elf_backend_object_p v850_elf_object_p
1759 #define elf_backend_final_write_processing v850_elf_final_write_processing
1760 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
1761 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
1762 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
1763 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
1764 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
1765 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
1767 #define elf_symbol_leading_char '_'
1769 #include "elf32-target.h"