1 /* V850-specific support for 32-bit ELF
2 Copyright (C) 1996, 1997, 1998 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 void v850_elf_info_to_howto_rela
41 PARAMS ((bfd
*, arelent
*, Elf32_Internal_Rela
*));
42 static bfd_reloc_status_type v850_elf_reloc
43 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
44 static boolean v850_elf_is_local_label_name
PARAMS ((bfd
*, const char *));
45 static boolean v850_elf_relocate_section
PARAMS((bfd
*,
46 struct bfd_link_info
*,
54 /* Note: It is REQUIRED that the 'type' value of each entry in this array
55 match the index of the entry in the array. */
56 static reloc_howto_type v850_elf_howto_table
[] =
58 /* This reloc does nothing. */
59 HOWTO (R_V850_NONE
, /* type */
61 2, /* size (0 = byte, 1 = short, 2 = long) */
63 false, /* pc_relative */
65 complain_overflow_bitfield
, /* complain_on_overflow */
66 bfd_elf_generic_reloc
, /* special_function */
67 "R_V850_NONE", /* name */
68 false, /* partial_inplace */
71 false), /* pcrel_offset */
73 /* A PC relative 9 bit branch. */
74 HOWTO (R_V850_9_PCREL
, /* type */
76 2, /* size (0 = byte, 1 = short, 2 = long) */
78 true, /* pc_relative */
80 complain_overflow_bitfield
, /* complain_on_overflow */
81 v850_elf_reloc
, /* special_function */
82 "R_V850_9_PCREL", /* name */
83 false, /* partial_inplace */
84 0x00ffffff, /* src_mask */
85 0x00ffffff, /* dst_mask */
86 true), /* pcrel_offset */
88 /* A PC relative 22 bit branch. */
89 HOWTO (R_V850_22_PCREL
, /* type */
91 2, /* size (0 = byte, 1 = short, 2 = long) */
93 true, /* pc_relative */
95 complain_overflow_signed
, /* complain_on_overflow */
96 v850_elf_reloc
, /* special_function */
97 "R_V850_22_PCREL", /* name */
98 false, /* partial_inplace */
99 0x07ffff80, /* src_mask */
100 0x07ffff80, /* dst_mask */
101 true), /* pcrel_offset */
103 /* High 16 bits of symbol value. */
104 HOWTO (R_V850_HI16_S
, /* type */
106 1, /* size (0 = byte, 1 = short, 2 = long) */
108 false, /* pc_relative */
110 complain_overflow_dont
, /* complain_on_overflow */
111 v850_elf_reloc
, /* special_function */
112 "R_V850_HI16_S", /* name */
113 true, /* partial_inplace */
114 0xffff, /* src_mask */
115 0xffff, /* dst_mask */
116 false), /* pcrel_offset */
118 /* High 16 bits of symbol value. */
119 HOWTO (R_V850_HI16
, /* type */
121 1, /* size (0 = byte, 1 = short, 2 = long) */
123 false, /* pc_relative */
125 complain_overflow_dont
, /* complain_on_overflow */
126 v850_elf_reloc
, /* special_function */
127 "R_V850_HI16", /* name */
128 true, /* partial_inplace */
129 0xffff, /* src_mask */
130 0xffff, /* dst_mask */
131 false), /* pcrel_offset */
133 /* Low 16 bits of symbol value. */
134 HOWTO (R_V850_LO16
, /* type */
136 1, /* size (0 = byte, 1 = short, 2 = long) */
138 false, /* pc_relative */
140 complain_overflow_dont
, /* complain_on_overflow */
141 v850_elf_reloc
, /* special_function */
142 "R_V850_LO16", /* name */
143 true, /* partial_inplace */
144 0xffff, /* src_mask */
145 0xffff, /* dst_mask */
146 false), /* pcrel_offset */
148 /* Simple 32bit reloc. */
149 HOWTO (R_V850_32
, /* type */
151 2, /* size (0 = byte, 1 = short, 2 = long) */
153 false, /* pc_relative */
155 complain_overflow_dont
, /* complain_on_overflow */
156 v850_elf_reloc
, /* special_function */
157 "R_V850_32", /* name */
158 true, /* partial_inplace */
159 0xffffffff, /* src_mask */
160 0xffffffff, /* dst_mask */
161 false), /* pcrel_offset */
163 /* Simple 16bit reloc. */
164 HOWTO (R_V850_16
, /* type */
166 1, /* size (0 = byte, 1 = short, 2 = long) */
168 false, /* pc_relative */
170 complain_overflow_dont
, /* complain_on_overflow */
171 bfd_elf_generic_reloc
, /* special_function */
172 "R_V850_16", /* name */
173 true, /* partial_inplace */
174 0xffff, /* src_mask */
175 0xffff, /* dst_mask */
176 false), /* pcrel_offset */
178 /* Simple 8bit reloc. */
179 HOWTO (R_V850_8
, /* type */
181 0, /* size (0 = byte, 1 = short, 2 = long) */
183 false, /* pc_relative */
185 complain_overflow_dont
, /* complain_on_overflow */
186 bfd_elf_generic_reloc
, /* special_function */
187 "R_V850_8", /* name */
188 true, /* partial_inplace */
191 false), /* pcrel_offset */
193 /* 16 bit offset from the short data area pointer. */
194 HOWTO (R_V850_SDA_16_16_OFFSET
, /* type */
196 1, /* size (0 = byte, 1 = short, 2 = long) */
198 false, /* pc_relative */
200 complain_overflow_dont
, /* complain_on_overflow */
201 v850_elf_reloc
, /* special_function */
202 "R_V850_SDA_16_16_OFFSET", /* name */
203 false, /* partial_inplace */
204 0xffff, /* src_mask */
205 0xffff, /* dst_mask */
206 false), /* pcrel_offset */
208 /* 15 bit offset from the short data area pointer. */
209 HOWTO (R_V850_SDA_15_16_OFFSET
, /* type */
211 1, /* size (0 = byte, 1 = short, 2 = long) */
213 false, /* pc_relative */
215 complain_overflow_dont
, /* complain_on_overflow */
216 v850_elf_reloc
, /* special_function */
217 "R_V850_SDA_15_16_OFFSET", /* name */
218 false, /* partial_inplace */
219 0xfffe, /* src_mask */
220 0xfffe, /* dst_mask */
221 false), /* pcrel_offset */
223 /* 16 bit offset from the zero data area pointer. */
224 HOWTO (R_V850_ZDA_16_16_OFFSET
, /* type */
226 1, /* size (0 = byte, 1 = short, 2 = long) */
228 false, /* pc_relative */
230 complain_overflow_dont
, /* complain_on_overflow */
231 v850_elf_reloc
, /* special_function */
232 "R_V850_ZDA_16_16_OFFSET", /* name */
233 false, /* partial_inplace */
234 0xffff, /* src_mask */
235 0xffff, /* dst_mask */
236 false), /* pcrel_offset */
238 /* 15 bit offset from the zero data area pointer. */
239 HOWTO (R_V850_ZDA_15_16_OFFSET
, /* type */
241 1, /* size (0 = byte, 1 = short, 2 = long) */
243 false, /* pc_relative */
245 complain_overflow_dont
, /* complain_on_overflow */
246 v850_elf_reloc
, /* special_function */
247 "R_V850_ZDA_15_16_OFFSET", /* name */
248 false, /* partial_inplace */
249 0xfffe, /* src_mask */
250 0xfffe, /* dst_mask */
251 false), /* pcrel_offset */
253 /* 6 bit offset from the tiny data area pointer. */
254 HOWTO (R_V850_TDA_6_8_OFFSET
, /* type */
256 1, /* size (0 = byte, 1 = short, 2 = long) */
258 false, /* pc_relative */
260 complain_overflow_dont
, /* complain_on_overflow */
261 v850_elf_reloc
, /* special_function */
262 "R_V850_TDA_6_8_OFFSET", /* name */
263 false, /* partial_inplace */
266 false), /* pcrel_offset */
268 /* 8 bit offset from the tiny data area pointer. */
269 HOWTO (R_V850_TDA_7_8_OFFSET
, /* type */
271 1, /* size (0 = byte, 1 = short, 2 = long) */
273 false, /* pc_relative */
275 complain_overflow_dont
, /* complain_on_overflow */
276 v850_elf_reloc
, /* special_function */
277 "R_V850_TDA_7_8_OFFSET", /* name */
278 false, /* partial_inplace */
281 false), /* pcrel_offset */
283 /* 7 bit offset from the tiny data area pointer. */
284 HOWTO (R_V850_TDA_7_7_OFFSET
, /* type */
286 1, /* size (0 = byte, 1 = short, 2 = long) */
288 false, /* pc_relative */
290 complain_overflow_dont
, /* complain_on_overflow */
291 v850_elf_reloc
, /* special_function */
292 "R_V850_TDA_7_7_OFFSET", /* name */
293 false, /* partial_inplace */
296 false), /* pcrel_offset */
298 /* 16 bit offset from the tiny data area pointer! */
299 HOWTO (R_V850_TDA_16_16_OFFSET
, /* type */
301 1, /* size (0 = byte, 1 = short, 2 = long) */
303 false, /* pc_relative */
305 complain_overflow_dont
, /* complain_on_overflow */
306 v850_elf_reloc
, /* special_function */
307 "R_V850_TDA_16_16_OFFSET", /* name */
308 false, /* partial_inplace */
309 0xffff, /* src_mask */
310 0xfff, /* dst_mask */
311 false), /* pcrel_offset */
313 /* start-sanitize-v850e */
315 /* 5 bit offset from the tiny data area pointer. */
316 HOWTO (R_V850_TDA_4_5_OFFSET
, /* type */
318 1, /* size (0 = byte, 1 = short, 2 = long) */
320 false, /* pc_relative */
322 complain_overflow_dont
, /* complain_on_overflow */
323 v850_elf_reloc
, /* special_function */
324 "R_V850_TDA_4_5_OFFSET", /* name */
325 false, /* partial_inplace */
328 false), /* pcrel_offset */
330 /* 4 bit offset from the tiny data area pointer. */
331 HOWTO (R_V850_TDA_4_4_OFFSET
, /* type */
333 1, /* size (0 = byte, 1 = short, 2 = long) */
335 false, /* pc_relative */
337 complain_overflow_dont
, /* complain_on_overflow */
338 v850_elf_reloc
, /* special_function */
339 "R_V850_TDA_4_4_OFFSET", /* name */
340 false, /* partial_inplace */
343 false), /* pcrel_offset */
345 /* 16 bit offset from the short data area pointer. */
346 HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET
, /* type */
348 2, /* size (0 = byte, 1 = short, 2 = long) */
350 false, /* pc_relative */
352 complain_overflow_dont
, /* complain_on_overflow */
353 v850_elf_reloc
, /* special_function */
354 "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
355 false, /* partial_inplace */
356 0xfffe0020, /* src_mask */
357 0xfffe0020, /* dst_mask */
358 false), /* pcrel_offset */
360 /* 16 bit offset from the zero data area pointer. */
361 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET
, /* type */
363 2, /* size (0 = byte, 1 = short, 2 = long) */
365 false, /* pc_relative */
367 complain_overflow_dont
, /* complain_on_overflow */
368 v850_elf_reloc
, /* special_function */
369 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
370 false, /* partial_inplace */
371 0xfffe0020, /* src_mask */
372 0xfffe0020, /* dst_mask */
373 false), /* pcrel_offset */
375 /* 6 bit offset from the call table base pointer. */
376 HOWTO (R_V850_CALLT_6_7_OFFSET
, /* type */
378 1, /* size (0 = byte, 1 = short, 2 = long) */
380 false, /* pc_relative */
382 complain_overflow_dont
, /* complain_on_overflow */
383 v850_elf_reloc
, /* special_function */
384 "R_V850_CALLT_6_7_OFFSET", /* name */
385 false, /* partial_inplace */
388 false), /* pcrel_offset */
390 /* 16 bit offset from the call table base pointer. */
391 HOWTO (R_V850_CALLT_16_16_OFFSET
, /* type */
393 1, /* size (0 = byte, 1 = short, 2 = long) */
395 false, /* pc_relative */
397 complain_overflow_dont
, /* complain_on_overflow */
398 v850_elf_reloc
, /* special_function */
399 "R_V850_CALLT_16_16_OFFSET", /* name */
400 false, /* partial_inplace */
401 0xffff, /* src_mask */
402 0xffff, /* dst_mask */
403 false), /* pcrel_offset */
405 /* end-sanitize-v850e */
408 /* Map BFD reloc types to V850 ELF reloc types. */
410 struct v850_elf_reloc_map
412 unsigned char bfd_reloc_val
;
413 unsigned char elf_reloc_val
;
416 static const struct v850_elf_reloc_map v850_elf_reloc_map
[] =
418 { BFD_RELOC_NONE
, R_V850_NONE
},
419 { BFD_RELOC_V850_9_PCREL
, R_V850_9_PCREL
},
420 { BFD_RELOC_V850_22_PCREL
, R_V850_22_PCREL
},
421 { BFD_RELOC_HI16_S
, R_V850_HI16_S
},
422 { BFD_RELOC_HI16
, R_V850_HI16
},
423 { BFD_RELOC_LO16
, R_V850_LO16
},
424 { BFD_RELOC_32
, R_V850_32
},
425 { BFD_RELOC_16
, R_V850_16
},
426 { BFD_RELOC_8
, R_V850_8
},
427 { BFD_RELOC_V850_SDA_16_16_OFFSET
, R_V850_SDA_16_16_OFFSET
},
428 { BFD_RELOC_V850_SDA_15_16_OFFSET
, R_V850_SDA_15_16_OFFSET
},
429 { BFD_RELOC_V850_ZDA_16_16_OFFSET
, R_V850_ZDA_16_16_OFFSET
},
430 { BFD_RELOC_V850_ZDA_15_16_OFFSET
, R_V850_ZDA_15_16_OFFSET
},
431 { BFD_RELOC_V850_TDA_6_8_OFFSET
, R_V850_TDA_6_8_OFFSET
},
432 { BFD_RELOC_V850_TDA_7_8_OFFSET
, R_V850_TDA_7_8_OFFSET
},
433 { BFD_RELOC_V850_TDA_7_7_OFFSET
, R_V850_TDA_7_7_OFFSET
},
434 { BFD_RELOC_V850_TDA_16_16_OFFSET
, R_V850_TDA_16_16_OFFSET
},
435 /* start-sanitize-v850e */
436 { BFD_RELOC_V850_TDA_4_5_OFFSET
, R_V850_TDA_4_5_OFFSET
},
437 { BFD_RELOC_V850_TDA_4_4_OFFSET
, R_V850_TDA_4_4_OFFSET
},
438 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET
, R_V850_SDA_16_16_SPLIT_OFFSET
},
439 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET
, R_V850_ZDA_16_16_SPLIT_OFFSET
},
440 { BFD_RELOC_V850_CALLT_6_7_OFFSET
, R_V850_CALLT_6_7_OFFSET
},
441 { BFD_RELOC_V850_CALLT_16_16_OFFSET
, R_V850_CALLT_16_16_OFFSET
},
442 /* end-sanitize-v850e */
446 /* Map a bfd relocation into the appropriate howto structure */
447 static reloc_howto_type
*
448 v850_elf_reloc_type_lookup (abfd
, code
)
450 bfd_reloc_code_real_type code
;
455 i
< sizeof (v850_elf_reloc_map
) / sizeof (struct v850_elf_reloc_map
);
458 if (v850_elf_reloc_map
[i
].bfd_reloc_val
== code
)
460 BFD_ASSERT (v850_elf_howto_table
[v850_elf_reloc_map
[i
].elf_reloc_val
].type
== v850_elf_reloc_map
[i
].elf_reloc_val
);
462 return & v850_elf_howto_table
[v850_elf_reloc_map
[i
].elf_reloc_val
];
470 /* Set the howto pointer for an V850 ELF reloc. */
472 v850_elf_info_to_howto_rel (abfd
, cache_ptr
, dst
)
475 Elf32_Internal_Rel
* dst
;
479 r_type
= ELF32_R_TYPE (dst
->r_info
);
480 BFD_ASSERT (r_type
< (unsigned int) R_V850_max
);
481 cache_ptr
->howto
= &v850_elf_howto_table
[r_type
];
484 /* Set the howto pointer for a V850 ELF reloc (type RELA). */
486 v850_elf_info_to_howto_rela (abfd
, cache_ptr
, dst
)
489 Elf32_Internal_Rela
*dst
;
493 r_type
= ELF32_R_TYPE (dst
->r_info
);
494 BFD_ASSERT (r_type
< (unsigned int) R_V850_max
);
495 cache_ptr
->howto
= &v850_elf_howto_table
[r_type
];
499 /* Look through the relocs for a section during the first phase, and
500 allocate space in the global offset table or procedure linkage
504 v850_elf_check_relocs (abfd
, info
, sec
, relocs
)
506 struct bfd_link_info
* info
;
508 const Elf_Internal_Rela
* relocs
;
512 Elf_Internal_Shdr
*symtab_hdr
;
513 struct elf_link_hash_entry
**sym_hashes
;
514 const Elf_Internal_Rela
*rel
;
515 const Elf_Internal_Rela
*rel_end
;
517 enum v850_reloc_type r_type
;
519 const char *common
= (const char *)0;
521 if (info
->relocateable
)
525 fprintf (stderr
, "v850_elf_check_relocs called for section %s in %s\n",
526 bfd_get_section_name (abfd
, sec
),
527 bfd_get_filename (abfd
));
530 dynobj
= elf_hash_table (info
)->dynobj
;
531 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
532 sym_hashes
= elf_sym_hashes (abfd
);
535 rel_end
= relocs
+ sec
->reloc_count
;
536 for (rel
= relocs
; rel
< rel_end
; rel
++)
538 unsigned long r_symndx
;
539 struct elf_link_hash_entry
*h
;
541 r_symndx
= ELF32_R_SYM (rel
->r_info
);
542 if (r_symndx
< symtab_hdr
->sh_info
)
545 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
547 r_type
= (enum v850_reloc_type
) ELF32_R_TYPE (rel
->r_info
);
553 case R_V850_22_PCREL
:
560 /* start-sanitize-v850e */
561 case R_V850_CALLT_6_7_OFFSET
:
562 case R_V850_CALLT_16_16_OFFSET
:
563 /* end-sanitize-v850e */
566 /* start-sanitize-v850e */
567 case R_V850_SDA_16_16_SPLIT_OFFSET
:
568 /* end-sanitize-v850e */
569 case R_V850_SDA_16_16_OFFSET
:
570 case R_V850_SDA_15_16_OFFSET
:
571 other
= V850_OTHER_SDA
;
573 goto small_data_common
;
575 /* start-sanitize-v850e */
576 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
577 /* end-sanitize-v850e */
578 case R_V850_ZDA_16_16_OFFSET
:
579 case R_V850_ZDA_15_16_OFFSET
:
580 other
= V850_OTHER_ZDA
;
582 goto small_data_common
;
584 /* start-sanitize-v850e */
585 case R_V850_TDA_4_5_OFFSET
:
586 case R_V850_TDA_4_4_OFFSET
:
587 /* end-sanitize-v850e */
588 case R_V850_TDA_6_8_OFFSET
:
589 case R_V850_TDA_7_8_OFFSET
:
590 case R_V850_TDA_7_7_OFFSET
:
591 case R_V850_TDA_16_16_OFFSET
:
592 other
= V850_OTHER_TDA
;
596 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
601 h
->other
|= other
; /* flag which type of relocation was used */
602 if ((h
->other
& V850_OTHER_MASK
) != (other
& V850_OTHER_MASK
)
603 && (h
->other
& V850_OTHER_ERROR
) == 0)
606 static char buff
[200]; /* XXX */
608 switch (h
->other
& V850_OTHER_MASK
)
611 msg
= _("Variable `%s' cannot occupy in multiple small data regions");
613 case V850_OTHER_SDA
| V850_OTHER_ZDA
| V850_OTHER_TDA
:
614 msg
= _("Variable `%s' can only be in one of the small, zero, and tiny data regions");
616 case V850_OTHER_SDA
| V850_OTHER_ZDA
:
617 msg
= _("Variable `%s' cannot be in both small and zero data regions simultaneously");
619 case V850_OTHER_SDA
| V850_OTHER_TDA
:
620 msg
= _("Variable `%s' cannot be in both small and tiny data regions simultaneously");
622 case V850_OTHER_ZDA
| V850_OTHER_TDA
:
623 msg
= _("Variable `%s' cannot be in both zero and tiny data regions simultaneously");
627 sprintf (buff
, msg
, h
->root
.root
.string
);
628 info
->callbacks
->warning (info
, buff
, h
->root
.root
.string
,
629 abfd
, h
->root
.u
.def
.section
, 0);
631 bfd_set_error (bfd_error_bad_value
);
632 h
->other
|= V850_OTHER_ERROR
;
637 if (h
&& h
->root
.type
== bfd_link_hash_common
639 && !strcmp (bfd_get_section_name (abfd
, h
->root
.u
.c
.p
->section
), "COMMON"))
641 asection
*section
= h
->root
.u
.c
.p
->section
= bfd_make_section_old_way (abfd
, common
);
642 section
->flags
|= SEC_IS_COMMON
;
646 fprintf (stderr
, "v850_elf_check_relocs, found %s relocation for %s%s\n",
647 v850_elf_howto_table
[ (int)r_type
].name
,
648 (h
&& h
->root
.root
.string
) ? h
->root
.root
.string
: "<unknown>",
649 (h
->root
.type
== bfd_link_hash_common
) ? ", symbol is common" : "");
662 unsigned long counter
;
666 static hi16s_location previous_hi16s
[ 10 ]; /* XXX is this enough ? */
667 static unsigned long hi16s_counter
;
670 remember_hi16s_reloc (addend
, address
)
674 hi16s_location
* oldest
= NULL
;
677 /* Find a free slot. */
678 for (i
= sizeof (previous_hi16s
) / sizeof (previous_hi16s
[0]); i
--;)
680 hi16s_location
* entry
= previous_hi16s
+ i
;
682 if (entry
->addend
== 0 && entry
->address
== 0)
684 /* Use this entry. */
689 /* Remember the least recently added entry. */
690 if (oldest
== NULL
|| oldest
->counter
> entry
->counter
)
694 oldest
->addend
= addend
;
695 oldest
->address
= address
;
696 oldest
->counter
= hi16s_counter
++;
698 /* Cope with wrap around of our counter. */
699 if (hi16s_counter
== 0)
701 /* XXX - Assume that all counter entries differ only in their low 16 bits. */
702 for (i
= sizeof (previous_hi16s
) / sizeof (previous_hi16s
[0]); i
--;)
704 hi16s_location
* entry
= previous_hi16s
+ i
;
706 entry
->counter
&= 0xffff;
709 hi16s_counter
= 0x10000;
716 find_remembered_hi16s_reloc (addend
)
719 hi16s_location
* match
= NULL
;
722 /* Search the table. Record the most recent entry that matches. */
723 for (i
= sizeof (previous_hi16s
) / sizeof (previous_hi16s
[0]); i
--;)
725 hi16s_location
* entry
= previous_hi16s
+ i
;
727 if (entry
->addend
== addend
)
729 if (match
== NULL
|| match
->counter
< entry
->counter
)
738 /* Empty the table entry. */
741 addr
= match
->address
;
742 match
->address
= NULL
;
750 static bfd_reloc_status_type
751 v850_elf_perform_relocation (abfd
, r_type
, addend
, address
)
762 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
763 return bfd_reloc_notsupported
;
766 addend
+= bfd_get_32 (abfd
, address
);
767 bfd_put_32 (abfd
, addend
, address
);
770 case R_V850_22_PCREL
:
771 if (addend
> 0x1fffff || addend
< -0x200000)
772 return bfd_reloc_overflow
;
774 if ((addend
% 2) != 0)
775 return bfd_reloc_dangerous
;
777 insn
= bfd_get_32 (abfd
, address
);
779 insn
|= (((addend
& 0xfffe) << 16) | ((addend
& 0x3f0000) >> 16));
780 bfd_put_32 (abfd
, insn
, address
);
784 if (addend
> 0xff || addend
< -0x100)
785 return bfd_reloc_overflow
;
787 if ((addend
% 2) != 0)
788 return bfd_reloc_dangerous
;
790 insn
= bfd_get_16 (abfd
, address
);
792 insn
|= ((addend
& 0x1f0) << 7) | ((addend
& 0x0e) << 3);
796 addend
+= (bfd_get_16 (abfd
, address
) << 16);
797 addend
= (addend
>> 16);
802 /* Remember where this relocation took place. */
803 remember_hi16s_reloc (addend
, address
);
805 addend
+= (bfd_get_16 (abfd
, address
) << 16);
806 addend
= (addend
>> 16) + ((addend
& 0x8000) != 0);
808 /* This relocation cannot overflow. */
809 if (addend
> 0x7fff || addend
< -0x8000)
816 /* Calculate the sum of the value stored in the instruction and the
817 addend and check for overflow from the low 16 bits into the high
818 16 bits. The assembler has already done some of this: If the
819 value stored in the instruction has its 15th bit set, (counting
820 from zero) then the assembler will have added 1 to the value
821 stored in the associated HI16S reloc. So for example, these
824 movhi hi( fred ), r0, r1
825 movea lo( fred ), r1, r1
827 will store 0 in the value fields for the MOVHI and MOVEA instructions
828 and addend will be the address of fred, but for these instructions:
830 movhi hi( fred + 0x123456), r0, r1
831 movea lo( fred + 0x123456), r1, r1
833 the value stored in the MOVHI instruction will be 0x12 and the value
834 stored in the MOVEA instruction will be 0x3456. If however the
837 movhi hi( fred + 0x10ffff), r0, r1
838 movea lo( fred + 0x10ffff), r1, r1
840 then the value stored in the MOVHI instruction would be 0x11 (not
841 0x10) and the value stored in the MOVEA instruction would be 0xffff.
842 Thus (assuming for the moment that the addend is 0), at run time the
843 MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
844 adds 0xffffffff (sign extension!) producing 0x10ffff. Similarly if
845 the instructions were:
847 movhi hi( fred - 1), r0, r1
848 movea lo( fred - 1), r1, r1
850 then 0 is stored in the MOVHI instruction and -1 is stored in the
853 Overflow can occur if the addition of the value stored in the
854 instruction plus the addend sets the 15th bit when before it was clear.
855 This is because the 15th bit will be sign extended into the high part,
856 thus reducing its value by one, but since the 15th bit was originally
857 clear, the assembler will not have added 1 to the previous HI16S reloc
858 to compensate for this effect. For example:
860 movhi hi( fred + 0x123456), r0, r1
861 movea lo( fred + 0x123456), r1, r1
863 The value stored in HI16S reloc is 0x12, the value stored in the LO16
864 reloc is 0x3456. If we assume that the address of fred is 0x00007000
865 then the relocations become:
867 HI16S: 0x0012 + (0x00007000 >> 16) = 0x12
868 LO16: 0x3456 + (0x00007000 & 0xffff) = 0xa456
870 but when the instructions are executed, the MOVEA instruction's value
871 is signed extended, so the sum becomes:
876 0x0011a456 but 'fred + 0x123456' = 0x0012a456
878 Note that if the 15th bit was set in the value stored in the LO16
879 reloc, then we do not have to do anything:
881 movhi hi( fred + 0x10ffff), r0, r1
882 movea lo( fred + 0x10ffff), r1, r1
884 HI16S: 0x0011 + (0x00007000 >> 16) = 0x11
885 LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff
890 0x00116fff = fred + 0x10ffff = 0x7000 + 0x10ffff
893 Overflow can also occur if the computation carries into the 16th bit
894 and it also results in the 15th bit having the same value as the 15th
895 bit of the original value. What happens is that the HI16S reloc
896 will have already examined the 15th bit of the original value and
897 added 1 to the high part if the bit is set. This compensates for the
898 sign extension of 15th bit of the result of the computation. But now
899 there is a carry into the 16th bit, and this has not been allowed for.
901 So, for example if fred is at address 0xf000:
903 movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is set]
904 movea lo( fred + 0xffff), r1, r1
906 HI16S: 0x0001 + (0x0000f000 >> 16) = 0x0001
907 LO16: 0xffff + (0x0000f000 & 0xffff) = 0xefff (carry into bit 16 is lost)
912 0x0000efff but 'fred + 0xffff' = 0x0001efff
914 Similarly, if the 15th bit remains clear, but overflow occurs into
915 the 16th bit then (assuming the address of fred is 0xf000):
917 movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is clear]
918 movea lo( fred + 0x7000), r1, r1
920 HI16S: 0x0000 + (0x0000f000 >> 16) = 0x0000
921 LO16: 0x7000 + (0x0000f000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
926 0x00006fff but 'fred + 0x7000' = 0x00016fff
928 Note - there is no need to change anything if a carry occurs, and the
929 15th bit changes its value from being set to being clear, as the HI16S
930 reloc will have already added in 1 to the high part for us:
932 movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is set]
933 movea lo( fred + 0xffff), r1, r1
935 HI16S: 0x0001 + (0x00007000 >> 16)
936 LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
939 + 0x00006fff (bit 15 not set, so the top half is zero)
941 0x00016fff which is right (assuming that fred is at 0x7000)
943 but if the 15th bit goes from being clear to being set, then we must
944 once again handle overflow:
946 movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is clear]
947 movea lo( fred + 0x7000), r1, r1
949 HI16S: 0x0000 + (0x0000ffff >> 16)
950 LO16: 0x7000 + (0x0000ffff & 0xffff) = 0x6fff (carry into bit 16)
953 + 0x00006fff (bit 15 not set, so the top half is zero)
955 0x00006fff which is wrong (assuming that fred is at 0xffff)
961 insn
= bfd_get_16 (abfd
, address
);
962 result
= insn
+ addend
;
964 #define BIT15_SET(x) ((x) & 0x8000)
965 #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
967 if ((BIT15_SET (result
) && ! BIT15_SET (addend
))
968 || (OVERFLOWS (addend
, insn
)
969 && ((! BIT15_SET (insn
)) || (BIT15_SET (addend
)))))
971 bfd_byte
* hi16s_address
= find_remembered_hi16s_reloc (addend
);
973 /* Amend the matching HI16_S relocation. */
974 if (hi16s_address
!= NULL
)
976 insn
= bfd_get_16 (abfd
, hi16s_address
);
978 bfd_put_16 (abfd
, insn
, hi16s_address
);
982 fprintf (stderr
, _("FAILED to find previous HI16 reloc\n"));
983 return bfd_reloc_overflow
;
987 /* Do not complain if value has top bit set, as this has been anticipated. */
988 insn
= result
& 0xffff;
993 addend
+= (char) bfd_get_8 (abfd
, address
);
995 if (addend
> 0x7f || addend
< -0x80)
996 return bfd_reloc_overflow
;
998 bfd_put_8 (abfd
, addend
, address
);
1001 /* start-sanitize-v850e */
1002 case R_V850_CALLT_16_16_OFFSET
:
1003 addend
+= bfd_get_16 (abfd
, address
);
1005 if (addend
> 0xffff || addend
< 0)
1006 return bfd_reloc_overflow
;
1010 /* end-sanitize-v850e */
1015 case R_V850_SDA_16_16_OFFSET
:
1016 case R_V850_ZDA_16_16_OFFSET
:
1017 case R_V850_TDA_16_16_OFFSET
:
1018 addend
+= bfd_get_16 (abfd
, address
);
1020 if (addend
> 0x7fff || addend
< -0x8000)
1021 return bfd_reloc_overflow
;
1026 case R_V850_SDA_15_16_OFFSET
:
1027 case R_V850_ZDA_15_16_OFFSET
:
1028 insn
= bfd_get_16 (abfd
, address
);
1029 addend
+= (insn
& 0xfffe);
1031 if (addend
> 0x7ffe || addend
< -0x8000)
1032 return bfd_reloc_overflow
;
1035 return bfd_reloc_dangerous
;
1037 insn
= (addend
& ~1) | (insn
& 1);
1040 case R_V850_TDA_6_8_OFFSET
:
1041 insn
= bfd_get_16 (abfd
, address
);
1042 addend
+= ((insn
& 0x7e) << 1);
1044 if (addend
> 0xfc || addend
< 0)
1045 return bfd_reloc_overflow
;
1048 return bfd_reloc_dangerous
;
1051 insn
|= (addend
>> 1);
1054 case R_V850_TDA_7_8_OFFSET
:
1055 insn
= bfd_get_16 (abfd
, address
);
1056 addend
+= ((insn
& 0x7f) << 1);
1058 if (addend
> 0xfe || addend
< 0)
1059 return bfd_reloc_overflow
;
1062 return bfd_reloc_dangerous
;
1065 insn
|= (addend
>> 1);
1068 case R_V850_TDA_7_7_OFFSET
:
1069 insn
= bfd_get_16 (abfd
, address
);
1070 addend
+= insn
& 0x7f;
1072 if (addend
> 0x7f || addend
< 0)
1073 return bfd_reloc_overflow
;
1079 /* start-sanitize-v850e */
1080 case R_V850_TDA_4_5_OFFSET
:
1081 insn
= bfd_get_16 (abfd
, address
);
1082 addend
+= ((insn
& 0xf) << 1);
1084 if (addend
> 0x1e || addend
< 0)
1085 return bfd_reloc_overflow
;
1088 return bfd_reloc_dangerous
;
1091 insn
|= (addend
>> 1);
1094 case R_V850_TDA_4_4_OFFSET
:
1095 insn
= bfd_get_16 (abfd
, address
);
1096 addend
+= insn
& 0xf;
1098 if (addend
> 0xf || addend
< 0)
1099 return bfd_reloc_overflow
;
1105 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
1106 case R_V850_SDA_16_16_SPLIT_OFFSET
:
1107 insn
= bfd_get_32 (abfd
, address
);
1108 addend
+= ((insn
& 0xfffe0000) >> 16) + ((insn
& 0x20) >> 5);
1110 if (addend
> 0x7fff || addend
< -0x8000)
1111 return bfd_reloc_overflow
;
1114 insn
|= (addend
& 1) << 5;
1115 insn
|= (addend
& ~1) << 16;
1117 bfd_put_32 (abfd
, insn
, address
);
1118 return bfd_reloc_ok
;
1120 case R_V850_CALLT_6_7_OFFSET
:
1121 insn
= bfd_get_16 (abfd
, address
);
1122 addend
+= ((insn
& 0x3f) << 1);
1124 if (addend
> 0x7e || addend
< 0)
1125 return bfd_reloc_overflow
;
1128 return bfd_reloc_dangerous
;
1131 insn
|= (addend
>> 1);
1133 /* end-sanitize-v850e */
1136 bfd_put_16 (abfd
, insn
, address
);
1137 return bfd_reloc_ok
;
1141 /* Insert the addend into the instruction. */
1142 static bfd_reloc_status_type
1143 v850_elf_reloc (abfd
, reloc
, symbol
, data
, isection
, obfd
, err
)
1148 asection
* isection
;
1154 /* If there is an output BFD,
1155 and the symbol is not a section name (which is only defined at final link time),
1156 and either we are not putting the addend into the instruction
1157 or the addend is zero, so there is nothing to add into the instruction
1158 then just fixup the address and return. */
1159 if (obfd
!= (bfd
*) NULL
1160 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1161 && (! reloc
->howto
->partial_inplace
1162 || reloc
->addend
== 0))
1164 reloc
->address
+= isection
->output_offset
;
1165 return bfd_reloc_ok
;
1168 else if (obfd
!= NULL
)
1170 return bfd_reloc_continue
;
1174 /* Catch relocs involving undefined symbols. */
1175 if (bfd_is_und_section (symbol
->section
)
1176 && (symbol
->flags
& BSF_WEAK
) == 0
1178 return bfd_reloc_undefined
;
1180 /* We handle final linking of some relocs ourselves. */
1182 /* Is the address of the relocation really within the section? */
1183 if (reloc
->address
> isection
->_cooked_size
)
1184 return bfd_reloc_outofrange
;
1186 /* Work out which section the relocation is targetted at and the
1187 initial relocation command value. */
1189 /* Get symbol value. (Common symbols are special.) */
1190 if (bfd_is_com_section (symbol
->section
))
1193 relocation
= symbol
->value
;
1195 /* Convert input-section-relative symbol value to absolute + addend. */
1196 relocation
+= symbol
->section
->output_section
->vma
;
1197 relocation
+= symbol
->section
->output_offset
;
1198 relocation
+= reloc
->addend
;
1200 if (reloc
->howto
->pc_relative
== true)
1202 /* Here the variable relocation holds the final address of the
1203 symbol we are relocating against, plus any addend. */
1204 relocation
-= isection
->output_section
->vma
+ isection
->output_offset
;
1206 /* Deal with pcrel_offset */
1207 relocation
-= reloc
->address
;
1210 reloc
->addend
= relocation
;
1211 return bfd_reloc_ok
;
1217 v850_elf_is_local_label_name (abfd
, name
)
1221 return ( (name
[0] == '.' && (name
[1] == 'L' || name
[1] == '.'))
1222 || (name
[0] == '_' && name
[1] == '.' && name
[2] == 'L' && name
[3] == '_'));
1226 /* Perform a relocation as part of a final link. */
1227 static bfd_reloc_status_type
1228 v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
1229 input_section
, contents
, offset
, value
,
1230 addend
, info
, sym_sec
, is_local
)
1231 reloc_howto_type
* howto
;
1234 asection
* input_section
;
1235 bfd_byte
* contents
;
1239 struct bfd_link_info
* info
;
1243 unsigned long r_type
= howto
->type
;
1244 bfd_byte
* hit_data
= contents
+ offset
;
1246 /* Adjust the value according to the relocation. */
1249 case R_V850_9_PCREL
:
1250 value
-= (input_section
->output_section
->vma
1251 + input_section
->output_offset
);
1255 case R_V850_22_PCREL
:
1256 value
-= (input_section
->output_section
->vma
1257 + input_section
->output_offset
1260 value
= SEXT24 (value
); /* Only the bottom 24 bits of the PC are valid */
1271 case R_V850_ZDA_15_16_OFFSET
:
1272 case R_V850_ZDA_16_16_OFFSET
:
1273 /* start-sanitize-v850e */
1274 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
1275 /* end-sanitize-v850e */
1276 if (sym_sec
== NULL
)
1277 return bfd_reloc_undefined
;
1279 value
-= sym_sec
->output_section
->vma
;
1282 case R_V850_SDA_15_16_OFFSET
:
1283 case R_V850_SDA_16_16_OFFSET
:
1284 /* start-sanitize-v850e */
1285 case R_V850_SDA_16_16_SPLIT_OFFSET
:
1286 /* end-sanitize-v850e */
1289 struct bfd_link_hash_entry
* h
;
1291 if (sym_sec
== NULL
)
1292 return bfd_reloc_undefined
;
1294 /* Get the value of __gp. */
1295 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1296 if (h
== (struct bfd_link_hash_entry
*) NULL
1297 || h
->type
!= bfd_link_hash_defined
)
1298 return bfd_reloc_other
;
1300 gp
= (h
->u
.def
.value
1301 + h
->u
.def
.section
->output_section
->vma
1302 + h
->u
.def
.section
->output_offset
);
1304 value
-= sym_sec
->output_section
->vma
;
1305 value
-= (gp
- sym_sec
->output_section
->vma
);
1309 /* start-sanitize-v850e */
1310 case R_V850_TDA_4_4_OFFSET
:
1311 case R_V850_TDA_4_5_OFFSET
:
1312 /* end-sanitize-v850e */
1313 case R_V850_TDA_16_16_OFFSET
:
1314 case R_V850_TDA_7_7_OFFSET
:
1315 case R_V850_TDA_7_8_OFFSET
:
1316 case R_V850_TDA_6_8_OFFSET
:
1319 struct bfd_link_hash_entry
* h
;
1321 /* Get the value of __ep. */
1322 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1323 if (h
== (struct bfd_link_hash_entry
*) NULL
1324 || h
->type
!= bfd_link_hash_defined
)
1325 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1327 ep
= (h
->u
.def
.value
1328 + h
->u
.def
.section
->output_section
->vma
1329 + h
->u
.def
.section
->output_offset
);
1335 /* start-sanitize-v850e */
1336 case R_V850_CALLT_6_7_OFFSET
:
1339 struct bfd_link_hash_entry
* h
;
1341 /* Get the value of __ctbp. */
1342 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1343 if (h
== (struct bfd_link_hash_entry
*) NULL
1344 || h
->type
!= bfd_link_hash_defined
)
1345 return (bfd_reloc_dangerous
+ 1); /* Actually this indicates that __ctbp could not be found. */
1347 ctbp
= (h
->u
.def
.value
1348 + h
->u
.def
.section
->output_section
->vma
1349 + h
->u
.def
.section
->output_offset
);
1354 case R_V850_CALLT_16_16_OFFSET
:
1357 struct bfd_link_hash_entry
* h
;
1359 if (sym_sec
== NULL
)
1360 return bfd_reloc_undefined
;
1362 /* Get the value of __ctbp. */
1363 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1364 if (h
== (struct bfd_link_hash_entry
*) NULL
1365 || h
->type
!= bfd_link_hash_defined
)
1366 return (bfd_reloc_dangerous
+ 1);
1368 ctbp
= (h
->u
.def
.value
1369 + h
->u
.def
.section
->output_section
->vma
1370 + h
->u
.def
.section
->output_offset
);
1372 value
-= sym_sec
->output_section
->vma
;
1373 value
-= (ctbp
- sym_sec
->output_section
->vma
);
1376 /* end-sanitize-v850e */
1379 return bfd_reloc_ok
;
1382 return bfd_reloc_notsupported
;
1385 /* Perform the relocation. */
1386 return v850_elf_perform_relocation (input_bfd
, r_type
, value
+ addend
, hit_data
);
1391 /* Relocate an V850 ELF section. */
1393 v850_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
1394 contents
, relocs
, local_syms
, local_sections
)
1396 struct bfd_link_info
* info
;
1398 asection
* input_section
;
1399 bfd_byte
* contents
;
1400 Elf_Internal_Rela
* relocs
;
1401 Elf_Internal_Sym
* local_syms
;
1402 asection
** local_sections
;
1404 Elf_Internal_Shdr
* symtab_hdr
;
1405 struct elf_link_hash_entry
** sym_hashes
;
1406 Elf_Internal_Rela
* rel
;
1407 Elf_Internal_Rela
* relend
;
1409 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
1410 sym_hashes
= elf_sym_hashes (input_bfd
);
1413 relend
= relocs
+ input_section
->reloc_count
;
1414 for (; rel
< relend
; rel
++)
1417 reloc_howto_type
* howto
;
1418 unsigned long r_symndx
;
1419 Elf_Internal_Sym
* sym
;
1421 struct elf_link_hash_entry
* h
;
1423 bfd_reloc_status_type r
;
1425 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1426 r_type
= ELF32_R_TYPE (rel
->r_info
);
1427 howto
= v850_elf_howto_table
+ r_type
;
1429 if (info
->relocateable
)
1431 /* This is a relocateable link. We don't have to change
1432 anything, unless the reloc is against a section symbol,
1433 in which case we have to adjust according to where the
1434 section symbol winds up in the output section. */
1435 if (r_symndx
< symtab_hdr
->sh_info
)
1437 sym
= local_syms
+ r_symndx
;
1438 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1440 sec
= local_sections
[r_symndx
];
1441 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1448 /* This is a final link. */
1452 if (r_symndx
< symtab_hdr
->sh_info
)
1454 sym
= local_syms
+ r_symndx
;
1455 sec
= local_sections
[r_symndx
];
1456 relocation
= (sec
->output_section
->vma
1457 + sec
->output_offset
1462 name
= bfd_elf_string_from_elf_section (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
1463 name
= (name
== NULL
) ? "<none>" : name
;
1464 fprintf (stderr
, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
1465 sec
->name
, name
, sym
->st_name
,
1466 sec
->output_section
->vma
, sec
->output_offset
, sym
->st_value
, rel
->r_addend
);
1472 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1474 while (h
->root
.type
== bfd_link_hash_indirect
1475 || h
->root
.type
== bfd_link_hash_warning
)
1476 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1478 if (h
->root
.type
== bfd_link_hash_defined
1479 || h
->root
.type
== bfd_link_hash_defweak
)
1481 sec
= h
->root
.u
.def
.section
;
1482 relocation
= (h
->root
.u
.def
.value
1483 + sec
->output_section
->vma
1484 + sec
->output_offset
);
1486 fprintf (stderr
, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1487 sec
->name
, h
->root
.root
.string
, h
->root
.u
.def
.value
, sec
->output_section
->vma
, sec
->output_offset
, relocation
);
1490 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1493 fprintf (stderr
, "undefined: sec: %s, name: %s\n",
1494 sec
->name
, h
->root
.root
.string
);
1500 if (! ((*info
->callbacks
->undefined_symbol
)
1501 (info
, h
->root
.root
.string
, input_bfd
,
1502 input_section
, rel
->r_offset
)))
1505 fprintf (stderr
, "unknown: name: %s\n", h
->root
.root
.string
);
1511 /* FIXME: We should use the addend, but the COFF relocations
1513 r
= v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
1515 contents
, rel
->r_offset
,
1516 relocation
, rel
->r_addend
,
1517 info
, sec
, h
== NULL
);
1519 if (r
!= bfd_reloc_ok
)
1522 const char * msg
= (const char *)0;
1525 name
= h
->root
.root
.string
;
1528 name
= (bfd_elf_string_from_elf_section
1529 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1530 if (name
== NULL
|| *name
== '\0')
1531 name
= bfd_section_name (input_bfd
, sec
);
1536 case bfd_reloc_overflow
:
1537 if (! ((*info
->callbacks
->reloc_overflow
)
1538 (info
, name
, howto
->name
, (bfd_vma
) 0,
1539 input_bfd
, input_section
, rel
->r_offset
)))
1543 case bfd_reloc_undefined
:
1544 if (! ((*info
->callbacks
->undefined_symbol
)
1545 (info
, name
, input_bfd
, input_section
,
1550 case bfd_reloc_outofrange
:
1551 msg
= _("internal error: out of range error");
1554 case bfd_reloc_notsupported
:
1555 msg
= _("internal error: unsupported relocation error");
1558 case bfd_reloc_dangerous
:
1559 msg
= _("internal error: dangerous relocation");
1562 case bfd_reloc_other
:
1563 msg
= _("could not locate special linker symbol __gp");
1566 case bfd_reloc_continue
:
1567 msg
= _("could not locate special linker symbol __ep");
1570 case (bfd_reloc_dangerous
+ 1):
1571 msg
= _("could not locate special linker symbol __ctbp");
1575 msg
= _("internal error: unknown error");
1579 if (!((*info
->callbacks
->warning
)
1580 (info
, msg
, name
, input_bfd
, input_section
,
1591 /* Set the right machine number. */
1593 v850_elf_object_p (abfd
)
1596 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1599 case E_V850_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, 0); break;
1600 /* start-sanitize-v850e */
1601 case E_V850E_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850e
); break;
1602 case E_V850EA_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850ea
); break;
1603 /* end-sanitize-v850e */
1608 /* Store the machine number in the flags field. */
1610 v850_elf_final_write_processing (abfd
, linker
)
1616 switch (bfd_get_mach (abfd
))
1619 case 0: val
= E_V850_ARCH
; break;
1620 /* start-sanitize-v850e */
1621 case bfd_mach_v850e
: val
= E_V850E_ARCH
; break;
1622 case bfd_mach_v850ea
: val
= E_V850EA_ARCH
; break;
1623 /* end-sanitize-v850e */
1626 elf_elfheader (abfd
)->e_flags
&=~ EF_V850_ARCH
;
1627 elf_elfheader (abfd
)->e_flags
|= val
;
1630 /* Function to keep V850 specific file flags. */
1632 v850_elf_set_private_flags (abfd
, flags
)
1636 BFD_ASSERT (!elf_flags_init (abfd
)
1637 || elf_elfheader (abfd
)->e_flags
== flags
);
1639 elf_elfheader (abfd
)->e_flags
= flags
;
1640 elf_flags_init (abfd
) = true;
1644 /* Copy backend specific data from one object module to another */
1646 v850_elf_copy_private_bfd_data (ibfd
, obfd
)
1650 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1651 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1654 BFD_ASSERT (!elf_flags_init (obfd
)
1655 || (elf_elfheader (obfd
)->e_flags
1656 == elf_elfheader (ibfd
)->e_flags
));
1658 elf_gp (obfd
) = elf_gp (ibfd
);
1659 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
1660 elf_flags_init (obfd
) = true;
1664 /* Merge backend specific data from an object file to the output
1665 object file when linking. */
1667 v850_elf_merge_private_bfd_data (ibfd
, obfd
)
1674 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1675 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1678 in_flags
= elf_elfheader (ibfd
)->e_flags
;
1679 out_flags
= elf_elfheader (obfd
)->e_flags
;
1681 if (! elf_flags_init (obfd
))
1683 /* If the input is the default architecture then do not
1684 bother setting the flags for the output architecture,
1685 instead allow future merges to do this. If no future
1686 merges ever set these flags then they will retain their
1687 unitialised values, which surprise surprise, correspond
1688 to the default values. */
1689 if (bfd_get_arch_info (ibfd
)->the_default
)
1692 elf_flags_init (obfd
) = true;
1693 elf_elfheader (obfd
)->e_flags
= in_flags
;
1695 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
1696 && bfd_get_arch_info (obfd
)->the_default
)
1698 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
1704 /* Check flag compatibility. */
1705 if (in_flags
== out_flags
)
1708 if ((in_flags
& EF_V850_ARCH
) != (out_flags
& EF_V850_ARCH
)
1709 && (in_flags
& EF_V850_ARCH
) != E_V850_ARCH
)
1710 _bfd_error_handler (_("%s: Architecture mismatch with previous modules"),
1711 bfd_get_filename (ibfd
));
1715 /* Display the flags field */
1718 v850_elf_print_private_bfd_data (abfd
, ptr
)
1722 FILE * file
= (FILE *) ptr
;
1724 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
1726 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
1728 /* xgettext:c-format */
1729 fprintf (file
, _("private flags = %lx: "), 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 case E_V850EA_ARCH
: fprintf (file
, _("v850ea architecture")); break;
1738 /* end-sanitize-v850e */
1746 /* V850 ELF uses four common sections. One is the usual one, and the
1747 others are for (small) objects in one of the special data areas:
1748 small, tiny and zero. All the objects are kept together, and then
1749 referenced via the gp register, the ep register or the r0 register
1750 respectively, which yields smaller, faster assembler code. This
1751 approach is copied from elf32-mips.c. */
1753 static asection v850_elf_scom_section
;
1754 static asymbol v850_elf_scom_symbol
;
1755 static asymbol
* v850_elf_scom_symbol_ptr
;
1756 static asection v850_elf_tcom_section
;
1757 static asymbol v850_elf_tcom_symbol
;
1758 static asymbol
* v850_elf_tcom_symbol_ptr
;
1759 static asection v850_elf_zcom_section
;
1760 static asymbol v850_elf_zcom_symbol
;
1761 static asymbol
* v850_elf_zcom_symbol_ptr
;
1764 /* Given a BFD section, try to locate the corresponding ELF section
1768 v850_elf_section_from_bfd_section (abfd
, hdr
, sec
, retval
)
1770 Elf32_Internal_Shdr
* hdr
;
1774 if (strcmp (bfd_get_section_name (abfd
, sec
), ".scommon") == 0)
1776 *retval
= SHN_V850_SCOMMON
;
1779 if (strcmp (bfd_get_section_name (abfd
, sec
), ".tcommon") == 0)
1781 *retval
= SHN_V850_TCOMMON
;
1784 if (strcmp (bfd_get_section_name (abfd
, sec
), ".zcommon") == 0)
1786 *retval
= SHN_V850_ZCOMMON
;
1792 /* Handle the special V850 section numbers that a symbol may use. */
1795 v850_elf_symbol_processing (abfd
, asym
)
1799 elf_symbol_type
* elfsym
= (elf_symbol_type
*) asym
;
1801 switch (elfsym
->internal_elf_sym
.st_shndx
)
1803 case SHN_V850_SCOMMON
:
1804 if (v850_elf_scom_section
.name
== NULL
)
1806 /* Initialize the small common section. */
1807 v850_elf_scom_section
.name
= ".scommon";
1808 v850_elf_scom_section
.flags
= SEC_IS_COMMON
| SEC_ALLOC
| SEC_DATA
;
1809 v850_elf_scom_section
.output_section
= & v850_elf_scom_section
;
1810 v850_elf_scom_section
.symbol
= & v850_elf_scom_symbol
;
1811 v850_elf_scom_section
.symbol_ptr_ptr
= & v850_elf_scom_symbol_ptr
;
1812 v850_elf_scom_symbol
.name
= ".scommon";
1813 v850_elf_scom_symbol
.flags
= BSF_SECTION_SYM
;
1814 v850_elf_scom_symbol
.section
= & v850_elf_scom_section
;
1815 v850_elf_scom_symbol_ptr
= & v850_elf_scom_symbol
;
1817 asym
->section
= & v850_elf_scom_section
;
1818 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1821 case SHN_V850_TCOMMON
:
1822 if (v850_elf_tcom_section
.name
== NULL
)
1824 /* Initialize the tcommon section. */
1825 v850_elf_tcom_section
.name
= ".tcommon";
1826 v850_elf_tcom_section
.flags
= SEC_IS_COMMON
;
1827 v850_elf_tcom_section
.output_section
= & v850_elf_tcom_section
;
1828 v850_elf_tcom_section
.symbol
= & v850_elf_tcom_symbol
;
1829 v850_elf_tcom_section
.symbol_ptr_ptr
= & v850_elf_tcom_symbol_ptr
;
1830 v850_elf_tcom_symbol
.name
= ".tcommon";
1831 v850_elf_tcom_symbol
.flags
= BSF_SECTION_SYM
;
1832 v850_elf_tcom_symbol
.section
= & v850_elf_tcom_section
;
1833 v850_elf_tcom_symbol_ptr
= & v850_elf_tcom_symbol
;
1835 asym
->section
= & v850_elf_tcom_section
;
1836 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1839 case SHN_V850_ZCOMMON
:
1840 if (v850_elf_zcom_section
.name
== NULL
)
1842 /* Initialize the zcommon section. */
1843 v850_elf_zcom_section
.name
= ".zcommon";
1844 v850_elf_zcom_section
.flags
= SEC_IS_COMMON
;
1845 v850_elf_zcom_section
.output_section
= & v850_elf_zcom_section
;
1846 v850_elf_zcom_section
.symbol
= & v850_elf_zcom_symbol
;
1847 v850_elf_zcom_section
.symbol_ptr_ptr
= & v850_elf_zcom_symbol_ptr
;
1848 v850_elf_zcom_symbol
.name
= ".zcommon";
1849 v850_elf_zcom_symbol
.flags
= BSF_SECTION_SYM
;
1850 v850_elf_zcom_symbol
.section
= & v850_elf_zcom_section
;
1851 v850_elf_zcom_symbol_ptr
= & v850_elf_zcom_symbol
;
1853 asym
->section
= & v850_elf_zcom_section
;
1854 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1859 /* Hook called by the linker routine which adds symbols from an object
1860 file. We must handle the special MIPS section numbers here. */
1864 v850_elf_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1866 struct bfd_link_info
* info
;
1867 const Elf_Internal_Sym
* sym
;
1868 const char ** namep
;
1873 switch (sym
->st_shndx
)
1875 case SHN_V850_SCOMMON
:
1876 *secp
= bfd_make_section_old_way (abfd
, ".scommon");
1877 (*secp
)->flags
|= SEC_IS_COMMON
;
1878 *valp
= sym
->st_size
;
1881 case SHN_V850_TCOMMON
:
1882 *secp
= bfd_make_section_old_way (abfd
, ".tcommon");
1883 (*secp
)->flags
|= SEC_IS_COMMON
;
1884 *valp
= sym
->st_size
;
1887 case SHN_V850_ZCOMMON
:
1888 *secp
= bfd_make_section_old_way (abfd
, ".zcommon");
1889 (*secp
)->flags
|= SEC_IS_COMMON
;
1890 *valp
= sym
->st_size
;
1899 v850_elf_link_output_symbol_hook (abfd
, info
, name
, sym
, input_sec
)
1901 struct bfd_link_info
* info
;
1903 Elf_Internal_Sym
* sym
;
1904 asection
* input_sec
;
1906 /* If we see a common symbol, which implies a relocatable link, then
1907 if a symbol was in a special common section in an input file, mark
1908 it as a special common in the output file. */
1910 if (sym
->st_shndx
== SHN_COMMON
)
1912 if (strcmp (input_sec
->name
, ".scommon") == 0)
1913 sym
->st_shndx
= SHN_V850_SCOMMON
;
1914 else if (strcmp (input_sec
->name
, ".tcommon") == 0)
1915 sym
->st_shndx
= SHN_V850_TCOMMON
;
1916 else if (strcmp (input_sec
->name
, ".zcommon") == 0)
1917 sym
->st_shndx
= SHN_V850_ZCOMMON
;
1924 v850_elf_section_from_shdr (abfd
, hdr
, name
)
1926 Elf_Internal_Shdr
* hdr
;
1929 /* There ought to be a place to keep ELF backend specific flags, but
1930 at the moment there isn't one. We just keep track of the
1931 sections by their name, instead. */
1933 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1936 switch (hdr
->sh_type
)
1938 case SHT_V850_SCOMMON
:
1939 case SHT_V850_TCOMMON
:
1940 case SHT_V850_ZCOMMON
:
1941 if (! bfd_set_section_flags (abfd
, hdr
->bfd_section
,
1942 (bfd_get_section_flags (abfd
,
1951 /* Set the correct type for a V850 ELF section. We do this by the
1952 section name, which is a hack, but ought to work. */
1954 v850_elf_fake_sections (abfd
, hdr
, sec
)
1956 Elf32_Internal_Shdr
* hdr
;
1959 register const char * name
;
1961 name
= bfd_get_section_name (abfd
, sec
);
1963 if (strcmp (name
, ".scommon") == 0)
1965 hdr
->sh_type
= SHT_V850_SCOMMON
;
1967 else if (strcmp (name
, ".tcommon") == 0)
1969 hdr
->sh_type
= SHT_V850_TCOMMON
;
1971 else if (strcmp (name
, ".zcommon") == 0)
1972 hdr
->sh_type
= SHT_V850_ZCOMMON
;
1979 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
1980 #define TARGET_LITTLE_NAME "elf32-v850"
1981 #define ELF_ARCH bfd_arch_v850
1982 #define ELF_MACHINE_CODE EM_CYGNUS_V850
1983 #define ELF_MAXPAGESIZE 0x1000
1985 #define elf_info_to_howto v850_elf_info_to_howto_rela
1986 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
1988 #define elf_backend_check_relocs v850_elf_check_relocs
1989 #define elf_backend_relocate_section v850_elf_relocate_section
1990 #define elf_backend_object_p v850_elf_object_p
1991 #define elf_backend_final_write_processing v850_elf_final_write_processing
1992 #define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
1993 #define elf_backend_symbol_processing v850_elf_symbol_processing
1994 #define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
1995 #define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
1996 #define elf_backend_section_from_shdr v850_elf_section_from_shdr
1997 #define elf_backend_fake_sections v850_elf_fake_sections
1999 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
2000 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
2001 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
2002 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
2003 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
2004 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
2006 #define elf_symbol_leading_char '_'
2008 #include "elf32-target.h"