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)
590 static char buff
[100]; /* XXX */
592 switch (h
->other
& V850_OTHER_MASK
)
595 msg
= "cannot occupy in multiple small data regions";
597 case V850_OTHER_SDA
| V850_OTHER_ZDA
| V850_OTHER_TDA
:
598 msg
= "can only be in one of the small, zero, and tiny data regions";
600 case V850_OTHER_SDA
| V850_OTHER_ZDA
:
601 msg
= "cannot be in both small and zero data regions simultaneously";
603 case V850_OTHER_SDA
| V850_OTHER_TDA
:
604 msg
= "cannot be in both small and tiny data regions simultaneously";
606 case V850_OTHER_ZDA
| V850_OTHER_TDA
:
607 msg
= "cannot be in both zero and tiny data regions simultaneously";
611 sprintf (buff
, "Variable '%s' %s", h
->root
.root
.string
, msg
);
612 info
->callbacks
->warning (info
, buff
, h
->root
.root
.string
,
613 abfd
, h
->root
.u
.def
.section
, 0);
615 bfd_set_error (bfd_error_bad_value
);
616 h
->other
|= V850_OTHER_ERROR
;
621 if (h
&& h
->root
.type
== bfd_link_hash_common
623 && !strcmp (bfd_get_section_name (abfd
, h
->root
.u
.c
.p
->section
), "COMMON"))
625 asection
*section
= h
->root
.u
.c
.p
->section
= bfd_make_section_old_way (abfd
, common
);
626 section
->flags
|= SEC_IS_COMMON
;
630 fprintf (stderr
, "v850_elf_check_relocs, found %s relocation for %s%s\n",
631 v850_elf_howto_table
[ (int)r_type
].name
,
632 (h
&& h
->root
.root
.string
) ? h
->root
.root
.string
: "<unknown>",
633 (h
->root
.type
== bfd_link_hash_common
) ? ", symbol is common" : "");
643 /* Insert the addend into the instruction. */
644 static bfd_reloc_status_type
645 v850_elf_reloc (abfd
, reloc
, symbol
, data
, isection
, obfd
, err
)
658 /* If there is an output BFD,
659 and the symbol is not a section name (which is only defined at final link time),
660 and either we are not putting the addend into the instruction
661 or the addend is zero, so there is nothing to add into the instruction
662 then just fixup the address and return. */
663 if (obfd
!= (bfd
*) NULL
664 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
665 && (! reloc
->howto
->partial_inplace
666 || reloc
->addend
== 0))
668 reloc
->address
+= isection
->output_offset
;
672 else if (obfd
!= NULL
)
674 return bfd_reloc_continue
;
678 /* Catch relocs involving undefined symbols. */
679 if (bfd_is_und_section (symbol
->section
)
680 && (symbol
->flags
& BSF_WEAK
) == 0
682 return bfd_reloc_undefined
;
684 /* We handle final linking of some relocs ourselves. */
686 /* Is the address of the relocation really within the section? */
687 if (reloc
->address
> isection
->_cooked_size
)
688 return bfd_reloc_outofrange
;
690 /* Work out which section the relocation is targetted at and the
691 initial relocation command value. */
693 /* Get symbol value. (Common symbols are special.) */
694 if (bfd_is_com_section (symbol
->section
))
697 relocation
= symbol
->value
;
699 /* Convert input-section-relative symbol value to absolute + addend. */
700 relocation
+= symbol
->section
->output_section
->vma
;
701 relocation
+= symbol
->section
->output_offset
;
702 relocation
+= reloc
->addend
;
704 if (reloc
->howto
->pc_relative
== true)
706 /* Here the variable relocation holds the final address of the
707 symbol we are relocating against, plus any addend. */
708 relocation
-= isection
->output_section
->vma
+ isection
->output_offset
;
710 /* Deal with pcrel_offset */
711 relocation
-= reloc
->address
;
714 /* I've got no clue... */
717 switch (reloc
->howto
->type
)
720 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", reloc->howto->type ); */
721 return bfd_reloc_notsupported
;
723 case R_V850_22_PCREL
:
724 if (relocation
> 0x1ffff || relocation
< -0x200000)
725 return bfd_reloc_overflow
;
727 if ((relocation
% 2) != 0)
728 return bfd_reloc_dangerous
;
730 insn
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
732 insn
|= (((relocation
& 0xfffe) << 16)
733 | ((relocation
& 0x3f0000) >> 16));
734 bfd_put_32 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
738 if (relocation
> 0xff || relocation
< -0x100)
739 return bfd_reloc_overflow
;
741 if ((relocation
% 2) != 0)
742 return bfd_reloc_dangerous
;
744 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
746 insn
|= ((relocation
& 0x1f0) << 7) | ((relocation
& 0x0e) << 3);
747 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
751 relocation
+= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
752 relocation
= (relocation
>> 16) + ((relocation
& 0x8000) != 0);
753 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
757 relocation
+= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
758 relocation
= (relocation
>> 16);
759 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
763 relocation
+= (short)bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
764 /* Do not complain if value has top bit set, as this has been anticipated. */
765 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
769 relocation
+= (short)bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
772 case R_V850_SDA_16_16_OFFSET
:
773 case R_V850_ZDA_16_16_OFFSET
:
774 case R_V850_TDA_16_16_OFFSET
:
775 if ((long)relocation
> 0x7fff || (long)relocation
< -0x8000)
776 return bfd_reloc_overflow
;
777 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
780 case R_V850_SDA_15_16_OFFSET
:
781 case R_V850_ZDA_15_16_OFFSET
:
782 if ((long)relocation
> 0x7ffe || (long)relocation
< -0x8000)
783 return bfd_reloc_overflow
;
786 return bfd_reloc_dangerous
;
788 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
790 insn
|= (relocation
>> 1) & ~1;
792 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
795 case R_V850_TDA_6_8_OFFSET
:
796 if ((long) relocation
> 0xfc || (long) relocation
< 0)
797 return bfd_reloc_overflow
;
800 return bfd_reloc_dangerous
;
802 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
804 insn
|= (relocation
>> 1);
806 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
809 case R_V850_TDA_7_8_OFFSET
:
810 if ((long) relocation
> 0xfe || (long) relocation
< 0)
811 return bfd_reloc_overflow
;
814 return bfd_reloc_dangerous
;
816 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
818 insn
|= (relocation
>> 1);
820 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
823 case R_V850_TDA_7_7_OFFSET
:
824 if ((long) relocation
> 0x7f || (long) relocation
< 0)
825 return bfd_reloc_overflow
;
827 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
831 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
834 /* start-sanitize-v850e */
835 case R_V850_TDA_4_5_OFFSET
:
836 if ((long) relocation
> 0x1e || (long) relocation
< 0)
837 return bfd_reloc_overflow
;
840 return bfd_reloc_dangerous
;
842 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
844 insn
|= (relocation
>> 1);
846 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
849 case R_V850_TDA_4_4_OFFSET
:
850 if ((long) relocation
> 0xf || (long) relocation
< 0)
851 return bfd_reloc_overflow
;
853 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
857 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
860 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
861 case R_V850_SDA_16_16_SPLIT_OFFSET
:
862 if ((long) relocation
> 0xffff || (long) relocation
< 0)
863 return bfd_reloc_overflow
;
865 insn
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
868 insn
|= (relocation
& 1) << 5;
869 insn
|= (relocation
& ~1) << 16;
871 bfd_put_32 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
874 case R_V850_CALLT_6_7_OFFSET
:
875 if ((long) relocation
> 0x7e || (long) relocation
< 0)
876 return bfd_reloc_overflow
;
879 return bfd_reloc_dangerous
;
881 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc
->address
);
883 insn
|= (relocation
>> 1);
885 bfd_put_16 (abfd
, insn
, (bfd_byte
*)data
+ reloc
->address
);
888 case R_V850_CALLT_16_16_OFFSET
:
889 bfd_put_16 (abfd
, relocation
, (bfd_byte
*)data
+ reloc
->address
);
892 /* end-sanitize-v850e */
895 return bfd_reloc_continue
;
901 v850_elf_is_local_label_name (abfd
, name
)
905 return ((name
[0] == '.' && (name
[1] == 'L' || name
[1] == '.'))
906 || (name
[0] == '_' && name
[1] == '.' && name
[2] == 'L'
911 /* Perform a relocation as part of a final link. */
912 static bfd_reloc_status_type
913 v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
914 input_section
, contents
, offset
, value
,
915 addend
, info
, sym_sec
, is_local
)
916 reloc_howto_type
* howto
;
919 asection
* input_section
;
924 struct bfd_link_info
* info
;
929 unsigned long r_type
= howto
->type
;
930 bfd_byte
* hit_data
= contents
+ offset
;
935 value
-= (input_section
->output_section
->vma
936 + input_section
->output_offset
);
939 if ((long)value
> 0xff || (long)value
< -0x100)
940 return bfd_reloc_overflow
;
942 if ((value
% 2) != 0)
943 return bfd_reloc_dangerous
;
945 insn
= bfd_get_16 (input_bfd
, hit_data
);
947 insn
|= ((value
& 0x1f0) << 7) | ((value
& 0x0e) << 3);
948 bfd_put_16 (input_bfd
, insn
, hit_data
);
951 case R_V850_22_PCREL
:
952 value
-= (input_section
->output_section
->vma
953 + input_section
->output_offset
);
956 if ((long)value
> 0x1ffff || (long)value
< -0x200000)
957 return bfd_reloc_overflow
;
959 if ((value
% 2) != 0)
960 return bfd_reloc_dangerous
;
962 insn
= bfd_get_32 (input_bfd
, hit_data
);
964 insn
|= (((value
& 0xfffe) << 16) | ((value
& 0x3f0000) >> 16));
965 bfd_put_32 (input_bfd
, insn
, hit_data
);
969 value
+= (short)bfd_get_16 (input_bfd
, hit_data
);
970 value
= (value
>> 16) + ((value
& 0x8000) != 0);
972 if ((long)value
> 0x7fff || (long)value
< -0x8000)
973 return bfd_reloc_overflow
;
975 bfd_put_16 (input_bfd
, value
, hit_data
);
979 value
+= (short)bfd_get_16 (input_bfd
, hit_data
);
982 if ((long)value
> 0x7fff || (long)value
< -0x8000)
983 return bfd_reloc_overflow
;
985 bfd_put_16 (input_bfd
, value
, hit_data
);
989 value
+= (short)bfd_get_16 (input_bfd
, hit_data
);
992 bfd_put_16 (input_bfd
, value
, hit_data
);
996 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
998 if ((long) value
> 0x7fff || (long) value
< -0x8000)
999 return bfd_reloc_overflow
;
1001 bfd_put_16 (input_bfd
, value
, hit_data
);
1002 return bfd_reloc_ok
;
1004 case R_V850_ZDA_16_16_OFFSET
:
1005 if (sym_sec
== NULL
)
1006 return bfd_reloc_undefined
;
1008 value
-= sym_sec
->output_section
->vma
;
1009 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
1011 if ((long) value
> 0x7fff || (long) value
< -0x8000)
1012 return bfd_reloc_overflow
;
1014 bfd_put_16 (input_bfd
, value
, hit_data
);
1015 return bfd_reloc_ok
;
1017 case R_V850_ZDA_15_16_OFFSET
:
1018 if (sym_sec
== NULL
)
1019 return bfd_reloc_undefined
;
1021 insn
= bfd_get_16 (input_bfd
, hit_data
);
1023 value
-= sym_sec
->output_section
->vma
;
1024 value
+= ((insn
& 0xfffe) << 1);
1026 if ((long) value
> 0x7ffe || (long) value
< -0x8000)
1027 return bfd_reloc_overflow
;
1030 value
|= (insn
& 1);
1032 bfd_put_16 (input_bfd
, value
, hit_data
);
1033 return bfd_reloc_ok
;
1036 value
+= bfd_get_32 (input_bfd
, hit_data
);
1037 bfd_put_32 (input_bfd
, value
, hit_data
);
1038 return bfd_reloc_ok
;
1041 value
+= (char)bfd_get_8 (input_bfd
, hit_data
);
1043 if ((long)value
> 0x7f || (long)value
< -0x80)
1044 return bfd_reloc_overflow
;
1046 bfd_put_8 (input_bfd
, value
, hit_data
);
1047 return bfd_reloc_ok
;
1049 case R_V850_SDA_16_16_OFFSET
:
1050 if (sym_sec
== NULL
)
1051 return bfd_reloc_undefined
;
1055 struct bfd_link_hash_entry
* h
;
1057 /* Get the value of __gp. */
1058 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1059 if (h
== (struct bfd_link_hash_entry
*) NULL
1060 || h
->type
!= bfd_link_hash_defined
)
1061 return bfd_reloc_other
;
1063 gp
= (h
->u
.def
.value
1064 + h
->u
.def
.section
->output_section
->vma
1065 + h
->u
.def
.section
->output_offset
);
1067 value
-= sym_sec
->output_section
->vma
;
1068 value
-= (gp
- sym_sec
->output_section
->vma
);
1069 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
1071 if ((long)value
> 0x7fff || (long)value
< -0x8000)
1072 return bfd_reloc_overflow
;
1074 bfd_put_16 (input_bfd
, value
, hit_data
);
1075 return bfd_reloc_ok
;
1078 case R_V850_SDA_15_16_OFFSET
:
1079 if (sym_sec
== NULL
)
1080 return bfd_reloc_undefined
;
1084 struct bfd_link_hash_entry
* h
;
1086 /* Get the value of __gp. */
1087 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1088 if (h
== (struct bfd_link_hash_entry
*) NULL
1089 || h
->type
!= bfd_link_hash_defined
)
1090 return bfd_reloc_other
;
1092 gp
= (h
->u
.def
.value
1093 + h
->u
.def
.section
->output_section
->vma
1094 + h
->u
.def
.section
->output_offset
);
1096 value
-= sym_sec
->output_section
->vma
;
1097 value
-= (gp
- sym_sec
->output_section
->vma
);
1099 insn
= bfd_get_16 (input_bfd
, hit_data
);
1101 value
+= ((insn
& 0xfffe) << 1);
1103 if ((long)value
> 0x7ffe || (long)value
< -0x8000)
1104 return bfd_reloc_overflow
;
1107 value
|= (insn
& 1);
1109 bfd_put_16 (input_bfd
, value
, hit_data
);
1110 return bfd_reloc_ok
;
1113 case R_V850_TDA_6_8_OFFSET
:
1116 struct bfd_link_hash_entry
* h
;
1118 insn
= bfd_get_16 (input_bfd
, hit_data
);
1120 /* Get the value of __ep. */
1121 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1122 if (h
== (struct bfd_link_hash_entry
*) NULL
1123 || h
->type
!= bfd_link_hash_defined
)
1124 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1126 ep
= (h
->u
.def
.value
1127 + h
->u
.def
.section
->output_section
->vma
1128 + h
->u
.def
.section
->output_offset
);
1131 value
+= ((insn
& 0x7e) << 2);
1133 if ((long) value
> 0xfc || (long) value
< 0)
1134 return bfd_reloc_overflow
;
1136 if ((value
% 2) != 0)
1137 return bfd_reloc_dangerous
;
1140 insn
|= (value
>> 1);
1142 bfd_put_16 (input_bfd
, insn
, hit_data
);
1143 return bfd_reloc_ok
;
1146 case R_V850_TDA_7_8_OFFSET
:
1149 struct bfd_link_hash_entry
* h
;
1151 insn
= bfd_get_16 (input_bfd
, hit_data
);
1153 /* Get the value of __ep. */
1154 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1155 if (h
== (struct bfd_link_hash_entry
*) NULL
1156 || h
->type
!= bfd_link_hash_defined
)
1157 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1159 ep
= (h
->u
.def
.value
1160 + h
->u
.def
.section
->output_section
->vma
1161 + h
->u
.def
.section
->output_offset
);
1164 value
+= ((insn
& 0x7f) << 1);
1166 if ((long) value
> 0xfe || (long) value
< 0)
1167 return bfd_reloc_overflow
;
1170 insn
|= (value
>> 1);
1172 bfd_put_16 (input_bfd
, insn
, hit_data
);
1173 return bfd_reloc_ok
;
1176 case R_V850_TDA_7_7_OFFSET
:
1179 struct bfd_link_hash_entry
* h
;
1181 insn
= bfd_get_16 (input_bfd
, hit_data
);
1183 /* Get the value of __ep. */
1184 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1185 if (h
== (struct bfd_link_hash_entry
*) NULL
1186 || h
->type
!= bfd_link_hash_defined
)
1187 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1189 ep
= (h
->u
.def
.value
1190 + h
->u
.def
.section
->output_section
->vma
1191 + h
->u
.def
.section
->output_offset
);
1194 value
+= insn
& 0x7f;
1196 if ((long) value
> 0x7f || (long) value
< 0)
1197 return bfd_reloc_overflow
;
1201 bfd_put_16 (input_bfd
, insn
, hit_data
);
1202 return bfd_reloc_ok
;
1205 case R_V850_TDA_16_16_OFFSET
:
1208 struct bfd_link_hash_entry
* h
;
1210 /* Get the value of __ep. */
1211 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1212 if (h
== (struct bfd_link_hash_entry
*) NULL
1213 || h
->type
!= bfd_link_hash_defined
)
1214 return bfd_reloc_other
;
1216 ep
= (h
->u
.def
.value
1217 + h
->u
.def
.section
->output_section
->vma
1218 + h
->u
.def
.section
->output_offset
);
1221 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
1223 if ((long)value
> 0x7fff || (long)value
< -0x8000)
1224 return bfd_reloc_overflow
;
1226 bfd_put_16 (input_bfd
, value
, hit_data
);
1227 return bfd_reloc_ok
;
1230 /* start-sanitize-v850e */
1231 case R_V850_TDA_4_5_OFFSET
:
1234 struct bfd_link_hash_entry
* h
;
1236 /* Get the value of __ep. */
1237 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1238 if (h
== (struct bfd_link_hash_entry
*) NULL
1239 || h
->type
!= bfd_link_hash_defined
)
1240 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1242 ep
= (h
->u
.def
.value
1243 + h
->u
.def
.section
->output_section
->vma
1244 + h
->u
.def
.section
->output_offset
);
1247 insn
= bfd_get_16 (input_bfd
, hit_data
);
1249 value
+= ((insn
& 0xf) << 1);
1251 if ((long) value
> 0x1e || (long) value
< 0)
1252 return bfd_reloc_overflow
;
1255 insn
|= (value
>> 1);
1256 bfd_put_16 (input_bfd
, insn
, hit_data
);
1257 return bfd_reloc_ok
;
1260 case R_V850_TDA_4_4_OFFSET
:
1263 struct bfd_link_hash_entry
* h
;
1265 /* Get the value of __ep. */
1266 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1267 if (h
== (struct bfd_link_hash_entry
*) NULL
1268 || h
->type
!= bfd_link_hash_defined
)
1269 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1271 ep
= (h
->u
.def
.value
1272 + h
->u
.def
.section
->output_section
->vma
1273 + h
->u
.def
.section
->output_offset
);
1276 insn
= bfd_get_16 (input_bfd
, hit_data
);
1278 value
+= insn
& 0xf;
1280 if ((long) value
> 0xf || (long) value
< 0)
1281 return bfd_reloc_overflow
;
1285 bfd_put_16 (input_bfd
, insn
, hit_data
);
1286 return bfd_reloc_ok
;
1289 case R_V850_SDA_16_16_SPLIT_OFFSET
:
1290 if (sym_sec
== NULL
)
1291 return bfd_reloc_undefined
;
1295 struct bfd_link_hash_entry
* h
;
1297 /* Get the value of __gp. */
1298 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1299 if (h
== (struct bfd_link_hash_entry
*) NULL
1300 || h
->type
!= bfd_link_hash_defined
)
1301 return bfd_reloc_other
;
1303 gp
= (h
->u
.def
.value
1304 + h
->u
.def
.section
->output_section
->vma
1305 + h
->u
.def
.section
->output_offset
);
1307 value
-= sym_sec
->output_section
->vma
;
1308 value
-= (gp
- sym_sec
->output_section
->vma
);
1310 insn
= bfd_get_32 (input_bfd
, hit_data
);
1312 value
+= ((insn
& 0xfffe0000) >> 16);
1313 value
+= ((insn
& 0x20) >> 5);
1315 if ((long)value
> 0x7fff || (long)value
< -0x8000)
1316 return bfd_reloc_overflow
;
1319 insn
|= (value
& 1) << 5;
1320 insn
|= (value
& ~1) << 16;
1322 bfd_put_32 (input_bfd
, insn
, hit_data
);
1323 return bfd_reloc_ok
;
1326 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
1327 if (sym_sec
== NULL
)
1328 return bfd_reloc_undefined
;
1330 insn
= bfd_get_32 (input_bfd
, hit_data
);
1332 value
-= sym_sec
->output_section
->vma
;
1333 value
+= ((insn
& 0xfffe0000) >> 16);
1334 value
+= ((insn
& 0x20) >> 5);
1336 if ((long)value
> 0x7fff || (long)value
< -0x8000)
1337 return bfd_reloc_overflow
;
1340 insn
|= (value
& 1) << 5;
1341 insn
|= (value
& ~1) << 16;
1343 bfd_put_32 (input_bfd
, insn
, hit_data
);
1344 return bfd_reloc_ok
;
1346 case R_V850_CALLT_6_7_OFFSET
:
1349 struct bfd_link_hash_entry
* h
;
1351 /* Get the value of __ctbp. */
1352 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1353 if (h
== (struct bfd_link_hash_entry
*) NULL
1354 || h
->type
!= bfd_link_hash_defined
)
1355 return bfd_reloc_continue
; /* Actually this indicates that __ctbp could not be found. */
1357 ctbp
= (h
->u
.def
.value
1358 + h
->u
.def
.section
->output_section
->vma
1359 + h
->u
.def
.section
->output_offset
);
1362 insn
= bfd_get_16 (input_bfd
, hit_data
);
1364 value
+= ((insn
& 0x3f) << 1);
1366 if ((long) value
> 0x7e || (long) value
< 0)
1367 return bfd_reloc_overflow
;
1370 insn
|= (value
>> 1);
1371 bfd_put_16 (input_bfd
, insn
, hit_data
);
1372 return bfd_reloc_ok
;
1375 case R_V850_CALLT_16_16_OFFSET
:
1376 if (sym_sec
== NULL
)
1377 return bfd_reloc_undefined
;
1381 struct bfd_link_hash_entry
* h
;
1383 /* Get the value of __ctbp. */
1384 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1385 if (h
== (struct bfd_link_hash_entry
*) NULL
1386 || h
->type
!= bfd_link_hash_defined
)
1387 return bfd_reloc_other
;
1389 ctbp
= (h
->u
.def
.value
1390 + h
->u
.def
.section
->output_section
->vma
1391 + h
->u
.def
.section
->output_offset
);
1393 value
-= sym_sec
->output_section
->vma
;
1394 value
-= (ctbp
- sym_sec
->output_section
->vma
);
1395 value
+= (short) bfd_get_16 (input_bfd
, hit_data
);
1397 if ((long) value
> 0xffff || (long) value
< 0)
1398 return bfd_reloc_overflow
;
1400 bfd_put_16 (input_bfd
, value
, hit_data
);
1401 return bfd_reloc_ok
;
1404 /* end-sanitize-v850e */
1407 return bfd_reloc_ok
;
1410 return bfd_reloc_notsupported
;
1415 /* Relocate an V850 ELF section. */
1417 v850_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
1418 contents
, relocs
, local_syms
, local_sections
)
1420 struct bfd_link_info
* info
;
1422 asection
* input_section
;
1423 bfd_byte
* contents
;
1424 Elf_Internal_Rela
* relocs
;
1425 Elf_Internal_Sym
* local_syms
;
1426 asection
** local_sections
;
1428 Elf_Internal_Shdr
* symtab_hdr
;
1429 struct elf_link_hash_entry
** sym_hashes
;
1430 Elf_Internal_Rela
* rel
;
1431 Elf_Internal_Rela
* relend
;
1433 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
1434 sym_hashes
= elf_sym_hashes (input_bfd
);
1437 relend
= relocs
+ input_section
->reloc_count
;
1438 for (; rel
< relend
; rel
++)
1441 reloc_howto_type
* howto
;
1442 unsigned long r_symndx
;
1443 Elf_Internal_Sym
* sym
;
1445 struct elf_link_hash_entry
* h
;
1447 bfd_reloc_status_type r
;
1449 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1450 r_type
= ELF32_R_TYPE (rel
->r_info
);
1451 howto
= v850_elf_howto_table
+ r_type
;
1453 if (info
->relocateable
)
1455 /* This is a relocateable link. We don't have to change
1456 anything, unless the reloc is against a section symbol,
1457 in which case we have to adjust according to where the
1458 section symbol winds up in the output section. */
1459 if (r_symndx
< symtab_hdr
->sh_info
)
1461 sym
= local_syms
+ r_symndx
;
1462 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1464 sec
= local_sections
[r_symndx
];
1465 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1472 /* This is a final link. */
1476 if (r_symndx
< symtab_hdr
->sh_info
)
1478 sym
= local_syms
+ r_symndx
;
1479 sec
= local_sections
[r_symndx
];
1480 relocation
= (sec
->output_section
->vma
1481 + sec
->output_offset
1486 name
= bfd_elf_string_from_elf_section (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
1487 name
= (name
== NULL
) ? "<none>" : name
;
1488 fprintf (stderr
, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x rel %x\n", sec
->name
, name
, sym
->st_name
,
1489 sec
->output_section
->vma
, sec
->output_offset
, sym
->st_value
, rel
->r_addend
, rel
);
1495 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1497 while (h
->root
.type
== bfd_link_hash_indirect
1498 || h
->root
.type
== bfd_link_hash_warning
)
1499 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1501 if (h
->root
.type
== bfd_link_hash_defined
1502 || h
->root
.type
== bfd_link_hash_defweak
)
1504 sec
= h
->root
.u
.def
.section
;
1505 relocation
= (h
->root
.u
.def
.value
1506 + sec
->output_section
->vma
1507 + sec
->output_offset
);
1509 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1513 if (! ((*info
->callbacks
->undefined_symbol
)
1514 (info
, h
->root
.root
.string
, input_bfd
,
1515 input_section
, rel
->r_offset
)))
1521 /* FIXME: We should use the addend, but the COFF relocations
1523 r
= v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
1525 contents
, rel
->r_offset
,
1526 relocation
, rel
->r_addend
,
1527 info
, sec
, h
== NULL
);
1529 if (r
!= bfd_reloc_ok
)
1532 const char * msg
= (const char *)0;
1535 name
= h
->root
.root
.string
;
1538 name
= (bfd_elf_string_from_elf_section
1539 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1540 if (name
== NULL
|| *name
== '\0')
1541 name
= bfd_section_name (input_bfd
, sec
);
1546 case bfd_reloc_overflow
:
1547 if (! ((*info
->callbacks
->reloc_overflow
)
1548 (info
, name
, howto
->name
, (bfd_vma
) 0,
1549 input_bfd
, input_section
, rel
->r_offset
)))
1553 case bfd_reloc_undefined
:
1554 fprintf (stderr
, "undef2 %s\n", name
);
1555 if (! ((*info
->callbacks
->undefined_symbol
)
1556 (info
, name
, input_bfd
, input_section
,
1561 case bfd_reloc_outofrange
:
1562 msg
= "internal error: out of range error";
1565 case bfd_reloc_notsupported
:
1566 msg
= "internal error: unsupported relocation error";
1569 case bfd_reloc_dangerous
:
1570 msg
= "internal error: dangerous relocation";
1573 case bfd_reloc_other
:
1574 msg
= "could not locate special linker symbol __gp";
1577 case bfd_reloc_continue
:
1578 msg
= "could not locate special linker symbol __ep";
1582 msg
= "internal error: unknown error";
1586 if (!((*info
->callbacks
->warning
)
1587 (info
, msg
, name
, input_bfd
, input_section
,
1598 /* Set the right machine number. */
1600 v850_elf_object_p (abfd
)
1603 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1606 case E_V850_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, 0); break;
1607 /* start-sanitize-v850e */
1608 case E_V850E_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850e
); break;
1609 case E_V850EQ_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850eq
); break;
1610 /* end-sanitize-v850e */
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 case bfd_mach_v850eq
: val
= E_V850EQ_ARCH
; break;
1629 /* end-sanitize-v850e */
1632 elf_elfheader (abfd
)->e_flags
&=~ EF_V850_ARCH
;
1633 elf_elfheader (abfd
)->e_flags
|= val
;
1636 /* Function to keep V850 specific file flags. */
1638 v850_elf_set_private_flags (abfd
, flags
)
1642 BFD_ASSERT (!elf_flags_init (abfd
)
1643 || elf_elfheader (abfd
)->e_flags
== flags
);
1645 elf_elfheader (abfd
)->e_flags
= flags
;
1646 elf_flags_init (abfd
) = true;
1650 /* Copy backend specific data from one object module to another */
1652 v850_elf_copy_private_bfd_data (ibfd
, obfd
)
1656 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1657 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1660 BFD_ASSERT (!elf_flags_init (obfd
)
1661 || (elf_elfheader (obfd
)->e_flags
1662 == elf_elfheader (ibfd
)->e_flags
));
1664 elf_gp (obfd
) = elf_gp (ibfd
);
1665 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
1666 elf_flags_init (obfd
) = true;
1670 /* Merge backend specific data from an object file to the output
1671 object file when linking. */
1673 v850_elf_merge_private_bfd_data (ibfd
, obfd
)
1680 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1681 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1684 new_flags
= elf_elfheader (ibfd
)->e_flags
;
1685 old_flags
= elf_elfheader (obfd
)->e_flags
;
1687 if (! elf_flags_init (obfd
))
1689 elf_flags_init (obfd
) = true;
1690 elf_elfheader (obfd
)->e_flags
= new_flags
;
1692 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
1693 && bfd_get_arch_info (obfd
)->the_default
)
1695 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
1701 /* Check flag compatibility. */
1703 if (new_flags
== old_flags
)
1706 if ((new_flags
& EF_V850_ARCH
) != (old_flags
& EF_V850_ARCH
))
1708 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1709 bfd_get_filename (ibfd
));
1711 bfd_set_error (bfd_error_bad_value
);
1720 /* Display the flags field */
1723 v850_elf_print_private_bfd_data (abfd
, ptr
)
1727 FILE * file
= (FILE *) ptr
;
1729 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
)
1731 fprintf (file
, "private flags = %x", elf_elfheader (abfd
)->e_flags
);
1733 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1736 case E_V850_ARCH
: fprintf (file
, ": v850 architecture"); break;
1737 /* start-sanitize-v850e */
1738 case E_V850E_ARCH
: fprintf (file
, ": v850e architecture"); break;
1739 case E_V850EQ_ARCH
: fprintf (file
, ": v850eq architecture"); break;
1740 /* end-sanitize-v850e */
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"