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 bfd_reloc_status_type v850_elf_reloc
41 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
42 static boolean v850_elf_is_local_label_name
PARAMS ((bfd
*, const char *));
43 static boolean v850_elf_relocate_section
PARAMS((bfd
*,
44 struct bfd_link_info
*,
51 /* Try to minimize the amount of space occupied by relocation tables
52 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
55 /* Note: It is REQUIRED that the 'type' value of each entry in this array
56 match the index of the entry in the array. */
57 static reloc_howto_type v850_elf_howto_table
[] =
59 /* This reloc does nothing. */
60 HOWTO (R_V850_NONE
, /* type */
62 2, /* size (0 = byte, 1 = short, 2 = long) */
64 false, /* pc_relative */
66 complain_overflow_bitfield
, /* complain_on_overflow */
67 bfd_elf_generic_reloc
, /* special_function */
68 "R_V850_NONE", /* name */
69 false, /* partial_inplace */
72 false), /* pcrel_offset */
74 /* A PC relative 9 bit branch. */
75 HOWTO (R_V850_9_PCREL
, /* type */
77 2, /* size (0 = byte, 1 = short, 2 = long) */
79 true, /* pc_relative */
81 complain_overflow_bitfield
, /* complain_on_overflow */
82 v850_elf_reloc
, /* special_function */
83 "R_V850_9_PCREL", /* name */
84 false, /* partial_inplace */
85 0x00ffffff, /* src_mask */
86 0x00ffffff, /* dst_mask */
87 true), /* pcrel_offset */
89 /* A PC relative 22 bit branch. */
90 HOWTO (R_V850_22_PCREL
, /* type */
92 2, /* size (0 = byte, 1 = short, 2 = long) */
94 true, /* pc_relative */
96 complain_overflow_signed
, /* complain_on_overflow */
97 v850_elf_reloc
, /* special_function */
98 "R_V850_22_PCREL", /* name */
99 false, /* partial_inplace */
100 0x07ffff80, /* src_mask */
101 0x07ffff80, /* dst_mask */
102 true), /* pcrel_offset */
104 /* High 16 bits of symbol value. */
105 HOWTO (R_V850_HI16_S
, /* type */
107 1, /* size (0 = byte, 1 = short, 2 = long) */
109 false, /* pc_relative */
111 complain_overflow_dont
, /* complain_on_overflow */
112 v850_elf_reloc
, /* special_function */
113 "R_V850_HI16_S", /* name */
114 true, /* partial_inplace */
115 0xffff, /* src_mask */
116 0xffff, /* dst_mask */
117 false), /* pcrel_offset */
119 /* High 16 bits of symbol value. */
120 HOWTO (R_V850_HI16
, /* type */
122 1, /* size (0 = byte, 1 = short, 2 = long) */
124 false, /* pc_relative */
126 complain_overflow_dont
, /* complain_on_overflow */
127 v850_elf_reloc
, /* special_function */
128 "R_V850_HI16", /* name */
129 true, /* partial_inplace */
130 0xffff, /* src_mask */
131 0xffff, /* dst_mask */
132 false), /* pcrel_offset */
134 /* Low 16 bits of symbol value. */
135 HOWTO (R_V850_LO16
, /* type */
137 1, /* size (0 = byte, 1 = short, 2 = long) */
139 false, /* pc_relative */
141 complain_overflow_dont
, /* complain_on_overflow */
142 v850_elf_reloc
, /* special_function */
143 "R_V850_LO16", /* name */
144 true, /* partial_inplace */
145 0xffff, /* src_mask */
146 0xffff, /* dst_mask */
147 false), /* pcrel_offset */
149 /* Simple 32bit reloc. */
150 HOWTO (R_V850_32
, /* type */
152 2, /* size (0 = byte, 1 = short, 2 = long) */
154 false, /* pc_relative */
156 complain_overflow_dont
, /* complain_on_overflow */
157 v850_elf_reloc
, /* special_function */
158 "R_V850_32", /* name */
159 true, /* partial_inplace */
160 0xffffffff, /* src_mask */
161 0xffffffff, /* dst_mask */
162 false), /* pcrel_offset */
164 /* Simple 16bit reloc. */
165 HOWTO (R_V850_16
, /* type */
167 1, /* size (0 = byte, 1 = short, 2 = long) */
169 false, /* pc_relative */
171 complain_overflow_dont
, /* complain_on_overflow */
172 bfd_elf_generic_reloc
, /* special_function */
173 "R_V850_16", /* name */
174 true, /* partial_inplace */
175 0xffff, /* src_mask */
176 0xffff, /* dst_mask */
177 false), /* pcrel_offset */
179 /* Simple 8bit reloc. */
180 HOWTO (R_V850_8
, /* type */
182 0, /* size (0 = byte, 1 = short, 2 = long) */
184 false, /* pc_relative */
186 complain_overflow_dont
, /* complain_on_overflow */
187 bfd_elf_generic_reloc
, /* special_function */
188 "R_V850_8", /* name */
189 true, /* partial_inplace */
192 false), /* pcrel_offset */
194 /* 16 bit offset from the short data area pointer. */
195 HOWTO (R_V850_SDA_16_16_OFFSET
, /* type */
197 1, /* size (0 = byte, 1 = short, 2 = long) */
199 false, /* pc_relative */
201 complain_overflow_dont
, /* complain_on_overflow */
202 v850_elf_reloc
, /* special_function */
203 "R_V850_SDA_16_16_OFFSET", /* name */
204 false, /* partial_inplace */
205 0xffff, /* src_mask */
206 0xffff, /* dst_mask */
207 false), /* pcrel_offset */
209 /* 15 bit offset from the short data area pointer. */
210 HOWTO (R_V850_SDA_15_16_OFFSET
, /* type */
212 1, /* size (0 = byte, 1 = short, 2 = long) */
214 false, /* pc_relative */
216 complain_overflow_dont
, /* complain_on_overflow */
217 v850_elf_reloc
, /* special_function */
218 "R_V850_SDA_15_16_OFFSET", /* name */
219 false, /* partial_inplace */
220 0xfffe, /* src_mask */
221 0xfffe, /* dst_mask */
222 false), /* pcrel_offset */
224 /* 16 bit offset from the zero data area pointer. */
225 HOWTO (R_V850_ZDA_16_16_OFFSET
, /* type */
227 1, /* size (0 = byte, 1 = short, 2 = long) */
229 false, /* pc_relative */
231 complain_overflow_dont
, /* complain_on_overflow */
232 v850_elf_reloc
, /* special_function */
233 "R_V850_ZDA_16_16_OFFSET", /* name */
234 false, /* partial_inplace */
235 0xffff, /* src_mask */
236 0xffff, /* dst_mask */
237 false), /* pcrel_offset */
239 /* 15 bit offset from the zero data area pointer. */
240 HOWTO (R_V850_ZDA_15_16_OFFSET
, /* type */
242 1, /* size (0 = byte, 1 = short, 2 = long) */
244 false, /* pc_relative */
246 complain_overflow_dont
, /* complain_on_overflow */
247 v850_elf_reloc
, /* special_function */
248 "R_V850_ZDA_15_16_OFFSET", /* name */
249 false, /* partial_inplace */
250 0xfffe, /* src_mask */
251 0xfffe, /* dst_mask */
252 false), /* pcrel_offset */
254 /* 6 bit offset from the tiny data area pointer. */
255 HOWTO (R_V850_TDA_6_8_OFFSET
, /* type */
257 1, /* size (0 = byte, 1 = short, 2 = long) */
259 false, /* pc_relative */
261 complain_overflow_dont
, /* complain_on_overflow */
262 v850_elf_reloc
, /* special_function */
263 "R_V850_TDA_6_8_OFFSET", /* name */
264 false, /* partial_inplace */
267 false), /* pcrel_offset */
269 /* 8 bit offset from the tiny data area pointer. */
270 HOWTO (R_V850_TDA_7_8_OFFSET
, /* type */
272 1, /* size (0 = byte, 1 = short, 2 = long) */
274 false, /* pc_relative */
276 complain_overflow_dont
, /* complain_on_overflow */
277 v850_elf_reloc
, /* special_function */
278 "R_V850_TDA_7_8_OFFSET", /* name */
279 false, /* partial_inplace */
282 false), /* pcrel_offset */
284 /* 7 bit offset from the tiny data area pointer. */
285 HOWTO (R_V850_TDA_7_7_OFFSET
, /* type */
287 1, /* size (0 = byte, 1 = short, 2 = long) */
289 false, /* pc_relative */
291 complain_overflow_dont
, /* complain_on_overflow */
292 v850_elf_reloc
, /* special_function */
293 "R_V850_TDA_7_7_OFFSET", /* name */
294 false, /* partial_inplace */
297 false), /* pcrel_offset */
299 /* 16 bit offset from the tiny data area pointer! */
300 HOWTO (R_V850_TDA_16_16_OFFSET
, /* type */
302 1, /* size (0 = byte, 1 = short, 2 = long) */
304 false, /* pc_relative */
306 complain_overflow_dont
, /* complain_on_overflow */
307 v850_elf_reloc
, /* special_function */
308 "R_V850_TDA_16_16_OFFSET", /* name */
309 false, /* partial_inplace */
310 0xffff, /* src_mask */
311 0xfff, /* dst_mask */
312 false), /* pcrel_offset */
314 /* start-sanitize-v850e */
316 /* 5 bit offset from the tiny data area pointer. */
317 HOWTO (R_V850_TDA_4_5_OFFSET
, /* type */
319 1, /* size (0 = byte, 1 = short, 2 = long) */
321 false, /* pc_relative */
323 complain_overflow_dont
, /* complain_on_overflow */
324 v850_elf_reloc
, /* special_function */
325 "R_V850_TDA_4_5_OFFSET", /* name */
326 false, /* partial_inplace */
329 false), /* pcrel_offset */
331 /* 4 bit offset from the tiny data area pointer. */
332 HOWTO (R_V850_TDA_4_4_OFFSET
, /* type */
334 1, /* size (0 = byte, 1 = short, 2 = long) */
336 false, /* pc_relative */
338 complain_overflow_dont
, /* complain_on_overflow */
339 v850_elf_reloc
, /* special_function */
340 "R_V850_TDA_4_4_OFFSET", /* name */
341 false, /* partial_inplace */
344 false), /* pcrel_offset */
346 /* 16 bit offset from the short data area pointer. */
347 HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET
, /* type */
349 2, /* size (0 = byte, 1 = short, 2 = long) */
351 false, /* pc_relative */
353 complain_overflow_dont
, /* complain_on_overflow */
354 v850_elf_reloc
, /* special_function */
355 "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
356 false, /* partial_inplace */
357 0xfffe0020, /* src_mask */
358 0xfffe0020, /* dst_mask */
359 false), /* pcrel_offset */
361 /* 16 bit offset from the zero data area pointer. */
362 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET
, /* type */
364 2, /* size (0 = byte, 1 = short, 2 = long) */
366 false, /* pc_relative */
368 complain_overflow_dont
, /* complain_on_overflow */
369 v850_elf_reloc
, /* special_function */
370 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
371 false, /* partial_inplace */
372 0xfffe0020, /* src_mask */
373 0xfffe0020, /* dst_mask */
374 false), /* pcrel_offset */
376 /* 6 bit offset from the call table base pointer. */
377 HOWTO (R_V850_CALLT_6_7_OFFSET
, /* type */
379 1, /* size (0 = byte, 1 = short, 2 = long) */
381 false, /* pc_relative */
383 complain_overflow_dont
, /* complain_on_overflow */
384 v850_elf_reloc
, /* special_function */
385 "R_V850_CALLT_6_7_OFFSET", /* name */
386 false, /* partial_inplace */
389 false), /* pcrel_offset */
391 /* 16 bit offset from the call table base pointer. */
392 HOWTO (R_V850_CALLT_16_16_OFFSET
, /* type */
394 1, /* size (0 = byte, 1 = short, 2 = long) */
396 false, /* pc_relative */
398 complain_overflow_dont
, /* complain_on_overflow */
399 v850_elf_reloc
, /* special_function */
400 "R_V850_CALLT_16_16_OFFSET", /* name */
401 false, /* partial_inplace */
402 0xffff, /* src_mask */
403 0xffff, /* dst_mask */
404 false), /* pcrel_offset */
406 /* end-sanitize-v850e */
409 /* Map BFD reloc types to V850 ELF reloc types. */
411 struct v850_elf_reloc_map
413 unsigned char bfd_reloc_val
;
414 unsigned char elf_reloc_val
;
417 static const struct v850_elf_reloc_map v850_elf_reloc_map
[] =
419 { BFD_RELOC_NONE
, R_V850_NONE
},
420 { BFD_RELOC_V850_9_PCREL
, R_V850_9_PCREL
},
421 { BFD_RELOC_V850_22_PCREL
, R_V850_22_PCREL
},
422 { BFD_RELOC_HI16_S
, R_V850_HI16_S
},
423 { BFD_RELOC_HI16
, R_V850_HI16
},
424 { BFD_RELOC_LO16
, R_V850_LO16
},
425 { BFD_RELOC_32
, R_V850_32
},
426 { BFD_RELOC_16
, R_V850_16
},
427 { BFD_RELOC_8
, R_V850_8
},
428 { BFD_RELOC_V850_SDA_16_16_OFFSET
, R_V850_SDA_16_16_OFFSET
},
429 { BFD_RELOC_V850_SDA_15_16_OFFSET
, R_V850_SDA_15_16_OFFSET
},
430 { BFD_RELOC_V850_ZDA_16_16_OFFSET
, R_V850_ZDA_16_16_OFFSET
},
431 { BFD_RELOC_V850_ZDA_15_16_OFFSET
, R_V850_ZDA_15_16_OFFSET
},
432 { BFD_RELOC_V850_TDA_6_8_OFFSET
, R_V850_TDA_6_8_OFFSET
},
433 { BFD_RELOC_V850_TDA_7_8_OFFSET
, R_V850_TDA_7_8_OFFSET
},
434 { BFD_RELOC_V850_TDA_7_7_OFFSET
, R_V850_TDA_7_7_OFFSET
},
435 { BFD_RELOC_V850_TDA_16_16_OFFSET
, R_V850_TDA_16_16_OFFSET
},
436 /* start-sanitize-v850e */
437 { BFD_RELOC_V850_TDA_4_5_OFFSET
, R_V850_TDA_4_5_OFFSET
},
438 { BFD_RELOC_V850_TDA_4_4_OFFSET
, R_V850_TDA_4_4_OFFSET
},
439 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET
, R_V850_SDA_16_16_SPLIT_OFFSET
},
440 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET
, R_V850_ZDA_16_16_SPLIT_OFFSET
},
441 { BFD_RELOC_V850_CALLT_6_7_OFFSET
, R_V850_CALLT_6_7_OFFSET
},
442 { BFD_RELOC_V850_CALLT_16_16_OFFSET
, R_V850_CALLT_16_16_OFFSET
},
443 /* end-sanitize-v850e */
447 /* Map a bfd relocation into the appropriate howto structure */
448 static reloc_howto_type
*
449 v850_elf_reloc_type_lookup (abfd
, code
)
451 bfd_reloc_code_real_type code
;
456 i
< sizeof (v850_elf_reloc_map
) / sizeof (struct v850_elf_reloc_map
);
459 if (v850_elf_reloc_map
[i
].bfd_reloc_val
== code
)
461 BFD_ASSERT (v850_elf_howto_table
[v850_elf_reloc_map
[i
].elf_reloc_val
].type
== v850_elf_reloc_map
[i
].elf_reloc_val
);
463 return & v850_elf_howto_table
[v850_elf_reloc_map
[i
].elf_reloc_val
];
471 /* Set the howto pointer for an V850 ELF reloc. */
473 v850_elf_info_to_howto_rel (abfd
, cache_ptr
, dst
)
476 Elf32_Internal_Rel
* dst
;
480 r_type
= ELF32_R_TYPE (dst
->r_info
);
481 BFD_ASSERT (r_type
< (unsigned int) R_V850_max
);
482 cache_ptr
->howto
= &v850_elf_howto_table
[r_type
];
486 /* Look through the relocs for a section during the first phase, and
487 allocate space in the global offset table or procedure linkage
491 v850_elf_check_relocs (abfd
, info
, sec
, relocs
)
493 struct bfd_link_info
* info
;
495 const Elf_Internal_Rela
* relocs
;
499 Elf_Internal_Shdr
*symtab_hdr
;
500 struct elf_link_hash_entry
**sym_hashes
;
501 const Elf_Internal_Rela
*rel
;
502 const Elf_Internal_Rela
*rel_end
;
504 enum v850_reloc_type r_type
;
506 const char *common
= (const char *)0;
508 if (info
->relocateable
)
512 fprintf (stderr
, "v850_elf_check_relocs called for section %s in %s\n",
513 bfd_get_section_name (abfd
, sec
),
514 bfd_get_filename (abfd
));
517 dynobj
= elf_hash_table (info
)->dynobj
;
518 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
519 sym_hashes
= elf_sym_hashes (abfd
);
522 rel_end
= relocs
+ sec
->reloc_count
;
523 for (rel
= relocs
; rel
< rel_end
; rel
++)
525 unsigned long r_symndx
;
526 struct elf_link_hash_entry
*h
;
528 r_symndx
= ELF32_R_SYM (rel
->r_info
);
529 if (r_symndx
< symtab_hdr
->sh_info
)
532 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
534 r_type
= (enum v850_reloc_type
) ELF32_R_TYPE (rel
->r_info
);
540 case R_V850_22_PCREL
:
547 /* start-sanitize-v850e */
548 case R_V850_CALLT_6_7_OFFSET
:
549 case R_V850_CALLT_16_16_OFFSET
:
550 /* end-sanitize-v850e */
553 /* start-sanitize-v850e */
554 case R_V850_SDA_16_16_SPLIT_OFFSET
:
555 /* end-sanitize-v850e */
556 case R_V850_SDA_16_16_OFFSET
:
557 case R_V850_SDA_15_16_OFFSET
:
558 other
= V850_OTHER_SDA
;
560 goto small_data_common
;
562 /* start-sanitize-v850e */
563 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
564 /* end-sanitize-v850e */
565 case R_V850_ZDA_16_16_OFFSET
:
566 case R_V850_ZDA_15_16_OFFSET
:
567 other
= V850_OTHER_ZDA
;
569 goto small_data_common
;
571 /* start-sanitize-v850e */
572 case R_V850_TDA_4_5_OFFSET
:
573 case R_V850_TDA_4_4_OFFSET
:
574 /* end-sanitize-v850e */
575 case R_V850_TDA_6_8_OFFSET
:
576 case R_V850_TDA_7_8_OFFSET
:
577 case R_V850_TDA_7_7_OFFSET
:
578 case R_V850_TDA_16_16_OFFSET
:
579 other
= V850_OTHER_TDA
;
583 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
588 h
->other
|= other
; /* flag which type of relocation was used */
589 if ((h
->other
& V850_OTHER_MASK
) != (other
& V850_OTHER_MASK
)
590 && (h
->other
& V850_OTHER_ERROR
) == 0)
593 static char buff
[100]; /* XXX */
595 switch (h
->other
& V850_OTHER_MASK
)
598 msg
= "cannot occupy in multiple small data regions";
600 case V850_OTHER_SDA
| V850_OTHER_ZDA
| V850_OTHER_TDA
:
601 msg
= "can only be in one of the small, zero, and tiny data regions";
603 case V850_OTHER_SDA
| V850_OTHER_ZDA
:
604 msg
= "cannot be in both small and zero data regions simultaneously";
606 case V850_OTHER_SDA
| V850_OTHER_TDA
:
607 msg
= "cannot be in both small and tiny data regions simultaneously";
609 case V850_OTHER_ZDA
| V850_OTHER_TDA
:
610 msg
= "cannot be in both zero and tiny data regions simultaneously";
614 sprintf (buff
, "Variable '%s' %s", h
->root
.root
.string
, msg
);
615 info
->callbacks
->warning (info
, buff
, h
->root
.root
.string
,
616 abfd
, h
->root
.u
.def
.section
, 0);
618 bfd_set_error (bfd_error_bad_value
);
619 h
->other
|= V850_OTHER_ERROR
;
624 if (h
&& h
->root
.type
== bfd_link_hash_common
626 && !strcmp (bfd_get_section_name (abfd
, h
->root
.u
.c
.p
->section
), "COMMON"))
628 asection
*section
= h
->root
.u
.c
.p
->section
= bfd_make_section_old_way (abfd
, common
);
629 section
->flags
|= SEC_IS_COMMON
;
633 fprintf (stderr
, "v850_elf_check_relocs, found %s relocation for %s%s\n",
634 v850_elf_howto_table
[ (int)r_type
].name
,
635 (h
&& h
->root
.root
.string
) ? h
->root
.root
.string
: "<unknown>",
636 (h
->root
.type
== bfd_link_hash_common
) ? ", symbol is common" : "");
645 static bfd_reloc_status_type
646 v850_elf_store_addend_in_insn (abfd
, r_type
, addend
, address
, replace
)
653 static long last_hi16s_addend
;
654 static bfd_byte
* last_hi16s_address
;
660 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
661 return bfd_reloc_notsupported
;
665 addend
+= bfd_get_32 (abfd
, address
);
667 bfd_put_32 (abfd
, addend
, address
);
670 case R_V850_22_PCREL
:
671 if (addend
> 0x1fffff || addend
< -0x200000)
672 return bfd_reloc_overflow
;
674 if ((addend
% 2) != 0)
675 return bfd_reloc_dangerous
;
677 insn
= bfd_get_32 (abfd
, address
);
679 insn
|= (((addend
& 0xfffe) << 16) | ((addend
& 0x3f0000) >> 16));
680 bfd_put_32 (abfd
, insn
, address
);
684 if (addend
> 0xff || addend
< -0x100)
685 return bfd_reloc_overflow
;
687 if ((addend
% 2) != 0)
688 return bfd_reloc_dangerous
;
690 insn
= bfd_get_16 (abfd
, address
);
692 insn
|= ((addend
& 0x1f0) << 7) | ((addend
& 0x0e) << 3);
696 last_hi16s_addend
= addend
;
697 last_hi16s_address
= address
;
699 addend
+= (bfd_get_16 (abfd
, address
) << 16);
700 addend
= (addend
>> 16) + ((addend
& 0x8000) != 0);
701 /* This relocation cannot overflow. */
702 if (addend
> 0x7fff || addend
< -0x8000)
708 addend
+= (bfd_get_16 (abfd
, address
) << 16);
709 addend
= (addend
>> 16);
714 /* Calculate the sum of the value stored in the instruction and the
715 addend and check for overflow from the low 16 bits into the high
716 16 bits. The assembler has already done some of this: If the
717 value stored in the instruction has its 15th bit set, then the
718 assembler will have added 1 to the value stored in the associated
719 HI16S reloc. So for example, these relocations:
721 movhi hi( fred ), r0, r1
722 movea lo( fred ), r1, r1
724 will store 0 in the value fields for the MOVHI and MOVEA instructions
725 and addend will be the address of fred, but for these instructions:
727 movhi hi( fred + 0x123456), r0, r1
728 movea lo( fred + 0x123456), r1, r1
730 the value stored in the MOVHI instruction will be 0x12 and the value
731 stored in the MOVEA instruction will be 0x3456. If however the
734 movhi hi( fred + 0x10ffff), r0, r1
735 movea lo( fred + 0x10ffff), r1, r1
737 then the value stored in the MOVHI instruction would be 0x11 (not
738 0x10) and the value stored in the MOVEA instruction would be 0xffff.
739 Thus (assuming for the moment that the addend is 0), at run time the
740 MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
741 adds 0xffffffff (sign extension!) producing 0x10ffff. Similarly if
742 the instructions were:
744 movhi hi( fred - 1), r0, r1
745 movea lo( fred - 1), r1, r1
747 then 0 is stored in the MOVHI instruction and -1 is stored in the
750 Overflow can occur if the addition of the value stored in the
751 instruction plus the addend sets the 15th bit (counting from 0) when
752 before it was clear. This is because the 15th bit will be sign
753 extended into the high part, thus reducing its value by one, but
754 since the 15th bit was originally clear, the previous HI16S
755 relocation will not have added in an additional 1 to the high part
756 to compensate for this effect. For example:
758 movhi hi( fred + 0x123456), r0, r1
759 movea lo( fred + 0x123456), r1, r1
761 The value stored in HI16S reloc is 0x12, the value stored in the LO16
762 reloc is 0x3456. If we assume that the address of fred is 0x00007000
763 then the relocations become:
765 HI16S: 0x0012 + (0x00007000 >> 16) = 0x12
766 LO16: 0x3456 + (0x00007000 & 0xffff) = 0xa456
768 but when the instructions are executed, the MOVEA instruction's value
769 is signed extended, so the sum becomes:
774 0x0011a456 but 'fred + 0x123456' = 0x0012a456
776 Note that if the 15th bit was set in the value stored in the LO16
777 reloc, then we do not have to do anything:
779 movhi hi( fred + 0x10ffff), r0, r1
780 movea lo( fred + 0x10ffff), r1, r1
782 HI16S: 0x0011 + (0x00007000 >> 16) = 0x11
783 LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff
788 0x00116fff = fred + 0x10ffff = 0x7000 + 0x10ffff
791 Overflow can also occur if the computation carries into the 16th bit
792 and it also results in the 15th bit having the same value as the 15th
793 bit of the original value. What happens is that the HI16S reloc
794 will have already examined the 15th bit of the original value and
795 added 1 to the high part if the bit is set. This compensates for the
796 sign extension of 15th bit of the result of the computation. But now
797 there is a carry into the 16th bit, and this has not been allowed for.
799 So, for example if fred is at address 0xf000:
801 movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is 1]
802 movea lo( fred + 0xffff), r1, r1
804 HI16S: 0x0001 + (0x0000f000 >> 16) = 0x0001
805 LO16: 0xffff + (0x0000f000 & 0xffff) = 0xefff (carry into bit 16)
810 0x0000efff but 'fred + 0xffff' = 0x0001efff
812 Similarly, if the 15th bit remains clear, but overflow occurs into
813 the 16th bit then (assuming the address of fred is 0xf000):
815 movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is 0]
816 movea lo( fred + 0x7000), r1, r1
818 HI16S: 0x0000 + (0x0000f000 >> 16) = 0x0000
819 LO16: 0x7000 + (0x0000f000 & 0xffff) = 0x6fff (carry into bit 16)
824 0x00006fff but 'fred + 0x7000' = 0x00016fff
826 Note - there is no need to change anything if a carry occurs, and the
827 15th bit changes its value from being set to being clear, as the HI16S
828 reloc will have already added in 1 to the high part for us:
830 movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is 1]
831 movea lo( fred + 0xffff), r1, r1
833 HI16S: 0x0001 + (0x00007000 >> 16)
834 LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff (carry into bit 16)
837 + 0x00006fff (bit 15 not set, so the top half is zero)
839 0x00016fff which is right (assuming that fred is at 0x7000)
841 but if the 15th bit goes from being clear to being set, then we must
842 once again handle overflow:
844 movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is 0]
845 movea lo( fred + 0x7000), r1, r1
847 HI16S: 0x0000 + (0x0000ffff >> 16)
848 LO16: 0x7000 + (0x0000ffff & 0xffff) = 0x6fff (carry into bit 16)
851 + 0x00006fff (bit 15 not set, so the top half is zero)
853 0x00006fff which is wrong (assuming that fred is at 0xffff)
859 insn
= bfd_get_16 (abfd
, address
);
860 result
= insn
+ addend
;
862 #define BIT15_SET(x) ((x) & 0x8000)
863 #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
865 if ((BIT15_SET (result
) && ! BIT15_SET (addend
))
866 || (OVERFLOWS (addend
, insn
)
867 && ((! BIT15_SET (insn
)) || (BIT15_SET (addend
)))))
869 /* Amend the preceding HI16_S relocation, allowing for
870 an intervening instruction, which does occasionally happen. */
871 if ( (addend
== last_hi16s_addend
)
872 && ( (address
== last_hi16s_address
+ 4)
873 || (address
== last_hi16s_address
+ 8)))
875 insn
= bfd_get_16 (abfd
, last_hi16s_address
);
877 bfd_put_16 (abfd
, insn
, last_hi16s_address
);
881 fprintf (stderr
, "FAILED to find previous HI16 reloc:\n");
882 fprintf (stderr
, "addend = %x, last_hi16s_added = %x, address = %x, last_address = %x\n",
883 addend
, last_hi16s_addend
, address
, last_hi16s_address
);
884 fprintf (stderr
, "addend = %x, result = %x, insn = %x\n",
885 addend
, result
, insn
);
886 return bfd_reloc_overflow
;
890 /* Do not complain if value has top bit set, as this has been anticipated. */
891 insn
= result
& 0xffff;
897 addend
+= (char) bfd_get_8 (abfd
, address
);
899 if (addend
> 0x7f || addend
< -0x80)
900 return bfd_reloc_overflow
;
902 bfd_put_8 (abfd
, addend
, address
);
905 /* start-sanitize-v850e */
906 case R_V850_CALLT_16_16_OFFSET
:
908 addend
+= bfd_get_16 (abfd
, address
);
910 if (addend
> 0xffff || addend
< 0)
911 return bfd_reloc_overflow
;
915 /* end-sanitize-v850e */
920 case R_V850_SDA_16_16_OFFSET
:
921 case R_V850_ZDA_16_16_OFFSET
:
922 case R_V850_TDA_16_16_OFFSET
:
924 addend
+= bfd_get_16 (abfd
, address
);
926 if (addend
> 0x7fff || addend
< -0x8000)
927 return bfd_reloc_overflow
;
932 case R_V850_SDA_15_16_OFFSET
:
933 case R_V850_ZDA_15_16_OFFSET
:
934 insn
= bfd_get_16 (abfd
, address
);
937 addend
+= (insn
& 0xfffe);
939 if (addend
> 0x7ffe || addend
< -0x8000)
940 return bfd_reloc_overflow
;
943 return bfd_reloc_dangerous
;
945 insn
= (addend
& ~1) | (insn
& 1);
948 case R_V850_TDA_6_8_OFFSET
:
949 insn
= bfd_get_16 (abfd
, address
);
952 addend
+= ((insn
& 0x7e) << 1);
954 if (addend
> 0xfc || addend
< 0)
955 return bfd_reloc_overflow
;
958 return bfd_reloc_dangerous
;
961 insn
|= (addend
>> 1);
964 case R_V850_TDA_7_8_OFFSET
:
965 insn
= bfd_get_16 (abfd
, address
);
968 addend
+= ((insn
& 0x7f) << 1);
970 if (addend
> 0xfe || addend
< 0)
971 return bfd_reloc_overflow
;
974 return bfd_reloc_dangerous
;
977 insn
|= (addend
>> 1);
980 case R_V850_TDA_7_7_OFFSET
:
981 insn
= bfd_get_16 (abfd
, address
);
984 addend
+= insn
& 0x7f;
986 if (addend
> 0x7f || addend
< 0)
987 return bfd_reloc_overflow
;
993 /* start-sanitize-v850e */
994 case R_V850_TDA_4_5_OFFSET
:
995 insn
= bfd_get_16 (abfd
, address
);
998 addend
+= ((insn
& 0xf) << 1);
1000 if (addend
> 0x1e || addend
< 0)
1001 return bfd_reloc_overflow
;
1004 return bfd_reloc_dangerous
;
1007 insn
|= (addend
>> 1);
1010 case R_V850_TDA_4_4_OFFSET
:
1011 insn
= bfd_get_16 (abfd
, address
);
1014 addend
+= insn
& 0xf;
1016 if (addend
> 0xf || addend
< 0)
1017 return bfd_reloc_overflow
;
1023 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
1024 case R_V850_SDA_16_16_SPLIT_OFFSET
:
1025 insn
= bfd_get_32 (abfd
, address
);
1028 addend
+= ((insn
& 0xfffe0000) >> 16) + ((insn
& 0x20) >> 5);
1030 if (addend
> 0x7fff || addend
< -0x8000)
1031 return bfd_reloc_overflow
;
1034 insn
|= (addend
& 1) << 5;
1035 insn
|= (addend
& ~1) << 16;
1037 bfd_put_32 (abfd
, insn
, address
);
1038 return bfd_reloc_ok
;
1040 case R_V850_CALLT_6_7_OFFSET
:
1041 insn
= bfd_get_16 (abfd
, address
);
1044 addend
+= ((insn
& 0x3f) << 1);
1046 if (addend
> 0x7e || addend
< 0)
1047 return bfd_reloc_overflow
;
1050 return bfd_reloc_dangerous
;
1053 insn
|= (addend
>> 1);
1055 /* end-sanitize-v850e */
1058 bfd_put_16 (abfd
, insn
, address
);
1059 return bfd_reloc_ok
;
1063 /* Insert the addend into the instruction. */
1064 static bfd_reloc_status_type
1065 v850_elf_reloc (abfd
, reloc
, symbol
, data
, isection
, obfd
, err
)
1070 asection
* isection
;
1078 /* If there is an output BFD,
1079 and the symbol is not a section name (which is only defined at final link time),
1080 and either we are not putting the addend into the instruction
1081 or the addend is zero, so there is nothing to add into the instruction
1082 then just fixup the address and return. */
1083 if (obfd
!= (bfd
*) NULL
1084 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1085 && (! reloc
->howto
->partial_inplace
1086 || reloc
->addend
== 0))
1088 reloc
->address
+= isection
->output_offset
;
1089 return bfd_reloc_ok
;
1092 else if (obfd
!= NULL
)
1094 return bfd_reloc_continue
;
1098 /* Catch relocs involving undefined symbols. */
1099 if (bfd_is_und_section (symbol
->section
)
1100 && (symbol
->flags
& BSF_WEAK
) == 0
1102 return bfd_reloc_undefined
;
1104 /* We handle final linking of some relocs ourselves. */
1106 /* Is the address of the relocation really within the section? */
1107 if (reloc
->address
> isection
->_cooked_size
)
1108 return bfd_reloc_outofrange
;
1110 /* Work out which section the relocation is targetted at and the
1111 initial relocation command value. */
1113 /* Get symbol value. (Common symbols are special.) */
1114 if (bfd_is_com_section (symbol
->section
))
1117 relocation
= symbol
->value
;
1119 /* Convert input-section-relative symbol value to absolute + addend. */
1120 relocation
+= symbol
->section
->output_section
->vma
;
1121 relocation
+= symbol
->section
->output_offset
;
1122 relocation
+= reloc
->addend
;
1124 if (reloc
->howto
->pc_relative
== true)
1126 /* Here the variable relocation holds the final address of the
1127 symbol we are relocating against, plus any addend. */
1128 relocation
-= isection
->output_section
->vma
+ isection
->output_offset
;
1130 /* Deal with pcrel_offset */
1131 relocation
-= reloc
->address
;
1134 /* I've got no clue... */
1137 return v850_elf_store_addend_in_insn (abfd
, reloc
->howto
->type
, relocation
,
1138 (bfd_byte
*) data
+ reloc
->address
, true);
1144 v850_elf_is_local_label_name (abfd
, name
)
1148 return ( (name
[0] == '.' && (name
[1] == 'L' || name
[1] == '.'))
1149 || (name
[0] == '_' && name
[1] == '.' && name
[2] == 'L' && name
[3] == '_'));
1153 /* Perform a relocation as part of a final link. */
1154 static bfd_reloc_status_type
1155 v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
1156 input_section
, contents
, offset
, value
,
1157 addend
, info
, sym_sec
, is_local
)
1158 reloc_howto_type
* howto
;
1161 asection
* input_section
;
1162 bfd_byte
* contents
;
1166 struct bfd_link_info
* info
;
1170 unsigned long r_type
= howto
->type
;
1171 bfd_byte
* hit_data
= contents
+ offset
;
1173 /* Adjust the value according to the relocation. */
1176 case R_V850_9_PCREL
:
1177 value
-= (input_section
->output_section
->vma
1178 + input_section
->output_offset
);
1182 case R_V850_22_PCREL
:
1183 value
-= (input_section
->output_section
->vma
1184 + input_section
->output_offset
1187 value
= SEXT24 (value
); /* Only the bottom 24 bits of the PC are valid */
1198 case R_V850_ZDA_15_16_OFFSET
:
1199 case R_V850_ZDA_16_16_OFFSET
:
1200 /* start-sanitize-v850e */
1201 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
1202 /* end-sanitize-v850e */
1203 if (sym_sec
== NULL
)
1204 return bfd_reloc_undefined
;
1206 value
-= sym_sec
->output_section
->vma
;
1209 case R_V850_SDA_15_16_OFFSET
:
1210 case R_V850_SDA_16_16_OFFSET
:
1211 /* start-sanitize-v850e */
1212 case R_V850_SDA_16_16_SPLIT_OFFSET
:
1213 /* end-sanitize-v850e */
1216 struct bfd_link_hash_entry
* h
;
1218 if (sym_sec
== NULL
)
1219 return bfd_reloc_undefined
;
1221 /* Get the value of __gp. */
1222 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1223 if (h
== (struct bfd_link_hash_entry
*) NULL
1224 || h
->type
!= bfd_link_hash_defined
)
1225 return bfd_reloc_other
;
1227 gp
= (h
->u
.def
.value
1228 + h
->u
.def
.section
->output_section
->vma
1229 + h
->u
.def
.section
->output_offset
);
1231 value
-= sym_sec
->output_section
->vma
;
1232 value
-= (gp
- sym_sec
->output_section
->vma
);
1236 /* start-sanitize-v850e */
1237 case R_V850_TDA_4_4_OFFSET
:
1238 case R_V850_TDA_4_5_OFFSET
:
1239 /* end-sanitize-v850e */
1240 case R_V850_TDA_16_16_OFFSET
:
1241 case R_V850_TDA_7_7_OFFSET
:
1242 case R_V850_TDA_7_8_OFFSET
:
1243 case R_V850_TDA_6_8_OFFSET
:
1246 struct bfd_link_hash_entry
* h
;
1248 /* Get the value of __ep. */
1249 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1250 if (h
== (struct bfd_link_hash_entry
*) NULL
1251 || h
->type
!= bfd_link_hash_defined
)
1252 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1254 ep
= (h
->u
.def
.value
1255 + h
->u
.def
.section
->output_section
->vma
1256 + h
->u
.def
.section
->output_offset
);
1262 /* start-sanitize-v850e */
1263 case R_V850_CALLT_6_7_OFFSET
:
1266 struct bfd_link_hash_entry
* h
;
1268 /* Get the value of __ctbp. */
1269 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1270 if (h
== (struct bfd_link_hash_entry
*) NULL
1271 || h
->type
!= bfd_link_hash_defined
)
1272 return (bfd_reloc_dangerous
+ 1); /* Actually this indicates that __ctbp could not be found. */
1274 ctbp
= (h
->u
.def
.value
1275 + h
->u
.def
.section
->output_section
->vma
1276 + h
->u
.def
.section
->output_offset
);
1281 case R_V850_CALLT_16_16_OFFSET
:
1284 struct bfd_link_hash_entry
* h
;
1286 if (sym_sec
== NULL
)
1287 return bfd_reloc_undefined
;
1289 /* Get the value of __ctbp. */
1290 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1291 if (h
== (struct bfd_link_hash_entry
*) NULL
1292 || h
->type
!= bfd_link_hash_defined
)
1293 return (bfd_reloc_dangerous
+ 1);
1295 ctbp
= (h
->u
.def
.value
1296 + h
->u
.def
.section
->output_section
->vma
1297 + h
->u
.def
.section
->output_offset
);
1299 value
-= sym_sec
->output_section
->vma
;
1300 value
-= (ctbp
- sym_sec
->output_section
->vma
);
1303 /* end-sanitize-v850e */
1306 return bfd_reloc_ok
;
1309 return bfd_reloc_notsupported
;
1312 /* Perform the relocation. */
1313 return v850_elf_store_addend_in_insn (input_bfd
, r_type
, value
, hit_data
, false);
1317 /* Relocate an V850 ELF section. */
1319 v850_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
1320 contents
, relocs
, local_syms
, local_sections
)
1322 struct bfd_link_info
* info
;
1324 asection
* input_section
;
1325 bfd_byte
* contents
;
1326 Elf_Internal_Rela
* relocs
;
1327 Elf_Internal_Sym
* local_syms
;
1328 asection
** local_sections
;
1330 Elf_Internal_Shdr
* symtab_hdr
;
1331 struct elf_link_hash_entry
** sym_hashes
;
1332 Elf_Internal_Rela
* rel
;
1333 Elf_Internal_Rela
* relend
;
1335 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
1336 sym_hashes
= elf_sym_hashes (input_bfd
);
1339 relend
= relocs
+ input_section
->reloc_count
;
1340 for (; rel
< relend
; rel
++)
1343 reloc_howto_type
* howto
;
1344 unsigned long r_symndx
;
1345 Elf_Internal_Sym
* sym
;
1347 struct elf_link_hash_entry
* h
;
1349 bfd_reloc_status_type r
;
1351 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1352 r_type
= ELF32_R_TYPE (rel
->r_info
);
1353 howto
= v850_elf_howto_table
+ r_type
;
1355 if (info
->relocateable
)
1357 /* This is a relocateable link. We don't have to change
1358 anything, unless the reloc is against a section symbol,
1359 in which case we have to adjust according to where the
1360 section symbol winds up in the output section. */
1361 if (r_symndx
< symtab_hdr
->sh_info
)
1363 sym
= local_syms
+ r_symndx
;
1364 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1366 sec
= local_sections
[r_symndx
];
1368 /* The Elf_Internal_Rel structure does not have space for the
1369 modified addend value, so we store it in the instruction
1372 if (sec
->output_offset
+ sym
->st_value
!= 0)
1374 if (v850_elf_store_addend_in_insn (input_bfd
, r_type
,
1375 sec
->output_offset
+
1377 contents
+ rel
->r_offset
,
1381 info
->callbacks
->warning
1383 "Unable to handle relocation during incremental link",
1384 NULL
, input_bfd
, input_section
, rel
->r_offset
);
1388 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1396 /* This is a final link. */
1400 if (r_symndx
< symtab_hdr
->sh_info
)
1402 sym
= local_syms
+ r_symndx
;
1403 sec
= local_sections
[r_symndx
];
1404 relocation
= (sec
->output_section
->vma
1405 + sec
->output_offset
1410 name
= bfd_elf_string_from_elf_section (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
1411 name
= (name
== NULL
) ? "<none>" : name
;
1412 fprintf (stderr
, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
1413 sec
->name
, name
, sym
->st_name
,
1414 sec
->output_section
->vma
, sec
->output_offset
, sym
->st_value
, rel
->r_addend
);
1420 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1422 while (h
->root
.type
== bfd_link_hash_indirect
1423 || h
->root
.type
== bfd_link_hash_warning
)
1424 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1426 if (h
->root
.type
== bfd_link_hash_defined
1427 || h
->root
.type
== bfd_link_hash_defweak
)
1429 sec
= h
->root
.u
.def
.section
;
1430 relocation
= (h
->root
.u
.def
.value
1431 + sec
->output_section
->vma
1432 + sec
->output_offset
);
1434 fprintf (stderr
, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1435 sec
->name
, h
->root
.root
.string
, h
->root
.u
.def
.value
, sec
->output_section
->vma
, sec
->output_offset
, relocation
);
1438 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1441 fprintf (stderr
, "undefined: sec: %s, name: %s\n",
1442 sec
->name
, h
->root
.root
.string
);
1448 if (! ((*info
->callbacks
->undefined_symbol
)
1449 (info
, h
->root
.root
.string
, input_bfd
,
1450 input_section
, rel
->r_offset
)))
1453 fprintf (stderr
, "unknown: name: %s\n", h
->root
.root
.string
);
1459 /* FIXME: We should use the addend, but the COFF relocations
1461 r
= v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
1463 contents
, rel
->r_offset
,
1464 relocation
, rel
->r_addend
,
1465 info
, sec
, h
== NULL
);
1467 if (r
!= bfd_reloc_ok
)
1470 const char * msg
= (const char *)0;
1473 name
= h
->root
.root
.string
;
1476 name
= (bfd_elf_string_from_elf_section
1477 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1478 if (name
== NULL
|| *name
== '\0')
1479 name
= bfd_section_name (input_bfd
, sec
);
1484 case bfd_reloc_overflow
:
1485 if (! ((*info
->callbacks
->reloc_overflow
)
1486 (info
, name
, howto
->name
, (bfd_vma
) 0,
1487 input_bfd
, input_section
, rel
->r_offset
)))
1491 case bfd_reloc_undefined
:
1492 if (! ((*info
->callbacks
->undefined_symbol
)
1493 (info
, name
, input_bfd
, input_section
,
1498 case bfd_reloc_outofrange
:
1499 msg
= "internal error: out of range error";
1502 case bfd_reloc_notsupported
:
1503 msg
= "internal error: unsupported relocation error";
1506 case bfd_reloc_dangerous
:
1507 msg
= "internal error: dangerous relocation";
1510 case bfd_reloc_other
:
1511 msg
= "could not locate special linker symbol __gp";
1514 case bfd_reloc_continue
:
1515 msg
= "could not locate special linker symbol __ep";
1518 case (bfd_reloc_dangerous
+ 1):
1519 msg
= "could not locate special linker symbol __ctbp";
1523 msg
= "internal error: unknown error";
1527 if (!((*info
->callbacks
->warning
)
1528 (info
, msg
, name
, input_bfd
, input_section
,
1539 /* Set the right machine number. */
1541 v850_elf_object_p (abfd
)
1544 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1547 case E_V850_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, 0); break;
1548 /* start-sanitize-v850e */
1549 case E_V850E_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850e
); break;
1550 case E_V850EA_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850ea
); break;
1551 /* end-sanitize-v850e */
1555 /* Store the machine number in the flags field. */
1557 v850_elf_final_write_processing (abfd
, linker
)
1563 switch (bfd_get_mach (abfd
))
1566 case 0: val
= E_V850_ARCH
; break;
1567 /* start-sanitize-v850e */
1568 case bfd_mach_v850e
: val
= E_V850E_ARCH
; break;
1569 case bfd_mach_v850ea
: val
= E_V850EA_ARCH
; break;
1570 /* end-sanitize-v850e */
1573 elf_elfheader (abfd
)->e_flags
&=~ EF_V850_ARCH
;
1574 elf_elfheader (abfd
)->e_flags
|= val
;
1577 /* Function to keep V850 specific file flags. */
1579 v850_elf_set_private_flags (abfd
, flags
)
1583 BFD_ASSERT (!elf_flags_init (abfd
)
1584 || elf_elfheader (abfd
)->e_flags
== flags
);
1586 elf_elfheader (abfd
)->e_flags
= flags
;
1587 elf_flags_init (abfd
) = true;
1591 /* Copy backend specific data from one object module to another */
1593 v850_elf_copy_private_bfd_data (ibfd
, obfd
)
1597 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1598 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1601 BFD_ASSERT (!elf_flags_init (obfd
)
1602 || (elf_elfheader (obfd
)->e_flags
1603 == elf_elfheader (ibfd
)->e_flags
));
1605 elf_gp (obfd
) = elf_gp (ibfd
);
1606 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
1607 elf_flags_init (obfd
) = true;
1611 /* Merge backend specific data from an object file to the output
1612 object file when linking. */
1614 v850_elf_merge_private_bfd_data (ibfd
, obfd
)
1621 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1622 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1625 in_flags
= elf_elfheader (ibfd
)->e_flags
;
1626 out_flags
= elf_elfheader (obfd
)->e_flags
;
1628 if (! elf_flags_init (obfd
))
1630 /* If the input is the default architecture then do not
1631 bother setting the flags for the output architecture,
1632 instead allow future merges to do this. If no future
1633 merges ever set these flags then they will retain their
1634 unitialised values, which surprise surprise, correspond
1635 to the default values. */
1636 if (bfd_get_arch_info (ibfd
)->the_default
)
1639 elf_flags_init (obfd
) = true;
1640 elf_elfheader (obfd
)->e_flags
= in_flags
;
1642 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
1643 && bfd_get_arch_info (obfd
)->the_default
)
1645 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
1651 /* Check flag compatibility. */
1652 if (in_flags
== out_flags
)
1655 if ((in_flags
& EF_V850_ARCH
) != (out_flags
& EF_V850_ARCH
)
1656 && (in_flags
& EF_V850_ARCH
) != E_V850_ARCH
)
1657 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1658 bfd_get_filename (ibfd
));
1662 /* Display the flags field */
1665 v850_elf_print_private_bfd_data (abfd
, ptr
)
1669 FILE * file
= (FILE *) ptr
;
1671 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
)
1673 fprintf (file
, "private flags = %x", elf_elfheader (abfd
)->e_flags
);
1675 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1678 case E_V850_ARCH
: fprintf (file
, ": v850 architecture"); break;
1679 /* start-sanitize-v850e */
1680 case E_V850E_ARCH
: fprintf (file
, ": v850e architecture"); break;
1681 case E_V850EA_ARCH
: fprintf (file
, ": v850ea architecture"); break;
1682 /* end-sanitize-v850e */
1690 /* V850 ELF uses four common sections. One is the usual one, and the
1691 others are for (small) objects in one of the special data areas:
1692 small, tiny and zero. All the objects are kept together, and then
1693 referenced via the gp register, the ep register or the r0 register
1694 respectively, which yields smaller, faster assembler code. This
1695 approach is copied from elf32-mips.c. */
1697 static asection v850_elf_scom_section
;
1698 static asymbol v850_elf_scom_symbol
;
1699 static asymbol
* v850_elf_scom_symbol_ptr
;
1700 static asection v850_elf_tcom_section
;
1701 static asymbol v850_elf_tcom_symbol
;
1702 static asymbol
* v850_elf_tcom_symbol_ptr
;
1703 static asection v850_elf_zcom_section
;
1704 static asymbol v850_elf_zcom_symbol
;
1705 static asymbol
* v850_elf_zcom_symbol_ptr
;
1708 /* Given a BFD section, try to locate the corresponding ELF section
1712 v850_elf_section_from_bfd_section (abfd
, hdr
, sec
, retval
)
1714 Elf32_Internal_Shdr
* hdr
;
1718 if (strcmp (bfd_get_section_name (abfd
, sec
), ".scommon") == 0)
1720 *retval
= SHN_V850_SCOMMON
;
1723 if (strcmp (bfd_get_section_name (abfd
, sec
), ".tcommon") == 0)
1725 *retval
= SHN_V850_TCOMMON
;
1728 if (strcmp (bfd_get_section_name (abfd
, sec
), ".zcommon") == 0)
1730 *retval
= SHN_V850_ZCOMMON
;
1736 /* Handle the special V850 section numbers that a symbol may use. */
1739 v850_elf_symbol_processing (abfd
, asym
)
1743 elf_symbol_type
* elfsym
= (elf_symbol_type
*) asym
;
1745 switch (elfsym
->internal_elf_sym
.st_shndx
)
1747 case SHN_V850_SCOMMON
:
1748 if (v850_elf_scom_section
.name
== NULL
)
1750 /* Initialize the small common section. */
1751 v850_elf_scom_section
.name
= ".scommon";
1752 v850_elf_scom_section
.flags
= SEC_IS_COMMON
| SEC_ALLOC
| SEC_DATA
;
1753 v850_elf_scom_section
.output_section
= & v850_elf_scom_section
;
1754 v850_elf_scom_section
.symbol
= & v850_elf_scom_symbol
;
1755 v850_elf_scom_section
.symbol_ptr_ptr
= & v850_elf_scom_symbol_ptr
;
1756 v850_elf_scom_symbol
.name
= ".scommon";
1757 v850_elf_scom_symbol
.flags
= BSF_SECTION_SYM
;
1758 v850_elf_scom_symbol
.section
= & v850_elf_scom_section
;
1759 v850_elf_scom_symbol_ptr
= & v850_elf_scom_symbol
;
1761 asym
->section
= & v850_elf_scom_section
;
1762 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1765 case SHN_V850_TCOMMON
:
1766 if (v850_elf_tcom_section
.name
== NULL
)
1768 /* Initialize the tcommon section. */
1769 v850_elf_tcom_section
.name
= ".tcommon";
1770 v850_elf_tcom_section
.flags
= SEC_IS_COMMON
;
1771 v850_elf_tcom_section
.output_section
= & v850_elf_tcom_section
;
1772 v850_elf_tcom_section
.symbol
= & v850_elf_tcom_symbol
;
1773 v850_elf_tcom_section
.symbol_ptr_ptr
= & v850_elf_tcom_symbol_ptr
;
1774 v850_elf_tcom_symbol
.name
= ".tcommon";
1775 v850_elf_tcom_symbol
.flags
= BSF_SECTION_SYM
;
1776 v850_elf_tcom_symbol
.section
= & v850_elf_tcom_section
;
1777 v850_elf_tcom_symbol_ptr
= & v850_elf_tcom_symbol
;
1779 asym
->section
= & v850_elf_tcom_section
;
1780 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1783 case SHN_V850_ZCOMMON
:
1784 if (v850_elf_zcom_section
.name
== NULL
)
1786 /* Initialize the zcommon section. */
1787 v850_elf_zcom_section
.name
= ".zcommon";
1788 v850_elf_zcom_section
.flags
= SEC_IS_COMMON
;
1789 v850_elf_zcom_section
.output_section
= & v850_elf_zcom_section
;
1790 v850_elf_zcom_section
.symbol
= & v850_elf_zcom_symbol
;
1791 v850_elf_zcom_section
.symbol_ptr_ptr
= & v850_elf_zcom_symbol_ptr
;
1792 v850_elf_zcom_symbol
.name
= ".zcommon";
1793 v850_elf_zcom_symbol
.flags
= BSF_SECTION_SYM
;
1794 v850_elf_zcom_symbol
.section
= & v850_elf_zcom_section
;
1795 v850_elf_zcom_symbol_ptr
= & v850_elf_zcom_symbol
;
1797 asym
->section
= & v850_elf_zcom_section
;
1798 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1803 /* Hook called by the linker routine which adds symbols from an object
1804 file. We must handle the special MIPS section numbers here. */
1808 v850_elf_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1810 struct bfd_link_info
* info
;
1811 const Elf_Internal_Sym
* sym
;
1812 const char ** namep
;
1817 switch (sym
->st_shndx
)
1819 case SHN_V850_SCOMMON
:
1820 *secp
= bfd_make_section_old_way (abfd
, ".scommon");
1821 (*secp
)->flags
|= SEC_IS_COMMON
;
1822 *valp
= sym
->st_size
;
1825 case SHN_V850_TCOMMON
:
1826 *secp
= bfd_make_section_old_way (abfd
, ".tcommon");
1827 (*secp
)->flags
|= SEC_IS_COMMON
;
1828 *valp
= sym
->st_size
;
1831 case SHN_V850_ZCOMMON
:
1832 *secp
= bfd_make_section_old_way (abfd
, ".zcommon");
1833 (*secp
)->flags
|= SEC_IS_COMMON
;
1834 *valp
= sym
->st_size
;
1843 v850_elf_link_output_symbol_hook (abfd
, info
, name
, sym
, input_sec
)
1845 struct bfd_link_info
* info
;
1847 Elf_Internal_Sym
* sym
;
1848 asection
* input_sec
;
1850 /* If we see a common symbol, which implies a relocatable link, then
1851 if a symbol was in a special common section in an input file, mark
1852 it as a special common in the output file. */
1854 if (sym
->st_shndx
== SHN_COMMON
)
1856 if (strcmp (input_sec
->name
, ".scommon") == 0)
1857 sym
->st_shndx
= SHN_V850_SCOMMON
;
1858 else if (strcmp (input_sec
->name
, ".tcommon") == 0)
1859 sym
->st_shndx
= SHN_V850_TCOMMON
;
1860 else if (strcmp (input_sec
->name
, ".zcommon") == 0)
1861 sym
->st_shndx
= SHN_V850_ZCOMMON
;
1868 v850_elf_section_from_shdr (abfd
, hdr
, name
)
1870 Elf_Internal_Shdr
* hdr
;
1873 /* There ought to be a place to keep ELF backend specific flags, but
1874 at the moment there isn't one. We just keep track of the
1875 sections by their name, instead. */
1877 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1880 switch (hdr
->sh_type
)
1882 case SHT_V850_SCOMMON
:
1883 case SHT_V850_TCOMMON
:
1884 case SHT_V850_ZCOMMON
:
1885 if (! bfd_set_section_flags (abfd
, hdr
->bfd_section
,
1886 (bfd_get_section_flags (abfd
,
1895 /* Set the correct type for a V850 ELF section. We do this by the
1896 section name, which is a hack, but ought to work. */
1898 v850_elf_fake_sections (abfd
, hdr
, sec
)
1900 Elf32_Internal_Shdr
* hdr
;
1903 register const char * name
;
1905 name
= bfd_get_section_name (abfd
, sec
);
1907 if (strcmp (name
, ".scommon") == 0)
1909 hdr
->sh_type
= SHT_V850_SCOMMON
;
1911 else if (strcmp (name
, ".tcommon") == 0)
1913 hdr
->sh_type
= SHT_V850_TCOMMON
;
1915 else if (strcmp (name
, ".zcommon") == 0)
1916 hdr
->sh_type
= SHT_V850_ZCOMMON
;
1923 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
1924 #define TARGET_LITTLE_NAME "elf32-v850"
1925 #define ELF_ARCH bfd_arch_v850
1926 #define ELF_MACHINE_CODE EM_CYGNUS_V850
1927 #define ELF_MAXPAGESIZE 0x1000
1929 #define elf_info_to_howto 0
1930 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
1932 #define elf_backend_check_relocs v850_elf_check_relocs
1933 #define elf_backend_relocate_section v850_elf_relocate_section
1934 #define elf_backend_object_p v850_elf_object_p
1935 #define elf_backend_final_write_processing v850_elf_final_write_processing
1936 #define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
1937 #define elf_backend_symbol_processing v850_elf_symbol_processing
1938 #define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
1939 #define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
1940 #define elf_backend_section_from_shdr v850_elf_section_from_shdr
1941 #define elf_backend_fake_sections v850_elf_fake_sections
1943 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
1944 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
1945 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
1946 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
1947 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
1948 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
1950 #define elf_symbol_leading_char '_'
1952 #include "elf32-target.h"