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. This can occur if the computation sets the 16th bit when
717 before it was clear, since the 16th bit will be sign extended into
718 the high part, thus reducing its value by one, but since the 16th bit
719 was originally clear, the previous R_V850_HI16_S relocation will not
720 have added in an additional 1 to the high part to compensate for this
721 effect. Overflow can also occur if the compuation carries into the
722 17th bit and it also results in the 16th bit having the same value as
723 the 16th bit of the original value. What happens is that the
724 R_V850_HI16_S relocation will have already examined the 16th bit of
725 the original value and added 1 to the high part if the bit is set.
726 This compensates for the sign extension of 16th bit of the result of
727 the computation. But now there is a carry into the 17th bit, and this
728 has not been allowed for. Note - there is no need to change anything
729 if a carry occurs, and the 16th bit changes its value, (this can only
730 happen if the bit was set in the original value, but is clear in the
731 result of the computation), as the R_V850_HI16_S relocation will have
732 already added in 1 to the high part for us. Here are some examples:
734 original value = 0x12345
737 0x13579 => R_V850_HI16_S stores 0x0001
738 R_V850_LO16 stores 0x3579
742 original value = 0x12345
745 0x19345 => R_V850_HI16_S stores 0x0001
746 R_V850_LO16 stores 0x9345
748 but the 0x9345 value gets sign
749 extended, so the sum becomes:
754 0x00009345 which is wrong.
756 This is the first example of overflow.
758 original value = 0x18888
761 0x21110 => R_V850_HI16_S stores 0x0002 (because 16th bit of the original value is set)
762 R_V850_LO16 stores 0x1110
769 0x00021110 which is OK.
771 original value = 0x1ffff
774 0x28887 => R_V850_HI16_S stores 0x0002
775 R_V850_LO16 stores 0x8887
782 0x00018887 which is wrong.
784 This is the second example of overflow.
785 (The 16th bit remains set).
787 original value = 0x15555
790 0x25554 => R_V850_HI16_S stores 0x0001
791 R_V850_LO16 stores 0x5554
798 0x00015554 which is wrong.
800 This is the other form of the second
801 example of overflow. (The 16th bit
808 insn
= bfd_get_16 (abfd
, address
);
809 result
= insn
+ addend
;
811 #define BIT16_SET(x) ((x) & 0x8000)
812 #define OVERFLOWS(a,i) (((a) & 0xffff) + (i) > 0xffff)
814 if ((BIT16_SET (result
) && ! BIT16_SET (addend
))
815 || (OVERFLOWS (addend
, insn
)
816 && (BIT16_SET (result
) == BIT16_SET (addend
))))
818 /* Amend the preceding HI16_S relocation, allowing for
819 an intervening instruction, which does occasionally happen. */
820 if ( (addend
== last_hi16s_addend
)
821 && ( (address
== last_hi16s_address
+ 4)
822 || (address
== last_hi16s_address
+ 8)))
824 insn
= bfd_get_16 (abfd
, last_hi16s_address
);
826 bfd_put_16 (abfd
, insn
, last_hi16s_address
);
830 fprintf (stderr
, "FAILED to find previous HI16 reloc:\n");
831 fprintf (stderr
, "addend = %x, last_hi16s_added = %x, address = %x, last_address = %x\n",
832 addend
, last_hi16s_addend
, address
, last_hi16s_address
);
833 fprintf (stderr
, "addend = %x, result = %x, insn = %x\n",
834 addend
, result
, insn
);
835 return bfd_reloc_overflow
;
839 /* Do not complain if value has top bit set, as this has been anticipated. */
840 insn
= result
& 0xffff;
846 addend
+= (char) bfd_get_8 (abfd
, address
);
848 if (addend
> 0x7f || addend
< -0x80)
849 return bfd_reloc_overflow
;
851 bfd_put_8 (abfd
, addend
, address
);
854 /* start-sanitize-v850e */
855 case R_V850_CALLT_16_16_OFFSET
:
857 addend
+= bfd_get_16 (abfd
, address
);
859 if (addend
> 0xffff || addend
< 0)
860 return bfd_reloc_overflow
;
864 /* end-sanitize-v850e */
869 case R_V850_SDA_16_16_OFFSET
:
870 case R_V850_ZDA_16_16_OFFSET
:
871 case R_V850_TDA_16_16_OFFSET
:
873 addend
+= bfd_get_16 (abfd
, address
);
875 if (addend
> 0x7fff || addend
< -0x8000)
876 return bfd_reloc_overflow
;
881 case R_V850_SDA_15_16_OFFSET
:
882 case R_V850_ZDA_15_16_OFFSET
:
883 insn
= bfd_get_16 (abfd
, address
);
886 addend
+= (insn
& 0xfffe);
888 if (addend
> 0x7ffe || addend
< -0x8000)
889 return bfd_reloc_overflow
;
892 return bfd_reloc_dangerous
;
894 insn
= (addend
& ~1) | (insn
& 1);
897 case R_V850_TDA_6_8_OFFSET
:
898 insn
= bfd_get_16 (abfd
, address
);
901 addend
+= ((insn
& 0x7e) << 1);
903 if (addend
> 0xfc || addend
< 0)
904 return bfd_reloc_overflow
;
907 return bfd_reloc_dangerous
;
910 insn
|= (addend
>> 1);
913 case R_V850_TDA_7_8_OFFSET
:
914 insn
= bfd_get_16 (abfd
, address
);
917 addend
+= ((insn
& 0x7f) << 1);
919 if (addend
> 0xfe || addend
< 0)
920 return bfd_reloc_overflow
;
923 return bfd_reloc_dangerous
;
926 insn
|= (addend
>> 1);
929 case R_V850_TDA_7_7_OFFSET
:
930 insn
= bfd_get_16 (abfd
, address
);
933 addend
+= insn
& 0x7f;
935 if (addend
> 0x7f || addend
< 0)
936 return bfd_reloc_overflow
;
942 /* start-sanitize-v850e */
943 case R_V850_TDA_4_5_OFFSET
:
944 insn
= bfd_get_16 (abfd
, address
);
947 addend
+= ((insn
& 0xf) << 1);
949 if (addend
> 0x1e || addend
< 0)
950 return bfd_reloc_overflow
;
953 return bfd_reloc_dangerous
;
956 insn
|= (addend
>> 1);
959 case R_V850_TDA_4_4_OFFSET
:
960 insn
= bfd_get_16 (abfd
, address
);
963 addend
+= insn
& 0xf;
965 if (addend
> 0xf || addend
< 0)
966 return bfd_reloc_overflow
;
972 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
973 case R_V850_SDA_16_16_SPLIT_OFFSET
:
974 insn
= bfd_get_32 (abfd
, address
);
977 addend
+= ((insn
& 0xfffe0000) >> 16) + ((insn
& 0x20) >> 5);
979 if (addend
> 0x7fff || addend
< -0x8000)
980 return bfd_reloc_overflow
;
983 insn
|= (addend
& 1) << 5;
984 insn
|= (addend
& ~1) << 16;
986 bfd_put_32 (abfd
, insn
, address
);
989 case R_V850_CALLT_6_7_OFFSET
:
990 insn
= bfd_get_16 (abfd
, address
);
993 addend
+= ((insn
& 0x3f) << 1);
995 if (addend
> 0x7e || addend
< 0)
996 return bfd_reloc_overflow
;
999 return bfd_reloc_dangerous
;
1002 insn
|= (addend
>> 1);
1004 /* end-sanitize-v850e */
1007 bfd_put_16 (abfd
, insn
, address
);
1008 return bfd_reloc_ok
;
1012 /* Insert the addend into the instruction. */
1013 static bfd_reloc_status_type
1014 v850_elf_reloc (abfd
, reloc
, symbol
, data
, isection
, obfd
, err
)
1019 asection
* isection
;
1027 /* If there is an output BFD,
1028 and the symbol is not a section name (which is only defined at final link time),
1029 and either we are not putting the addend into the instruction
1030 or the addend is zero, so there is nothing to add into the instruction
1031 then just fixup the address and return. */
1032 if (obfd
!= (bfd
*) NULL
1033 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1034 && (! reloc
->howto
->partial_inplace
1035 || reloc
->addend
== 0))
1037 reloc
->address
+= isection
->output_offset
;
1038 return bfd_reloc_ok
;
1041 else if (obfd
!= NULL
)
1043 return bfd_reloc_continue
;
1047 /* Catch relocs involving undefined symbols. */
1048 if (bfd_is_und_section (symbol
->section
)
1049 && (symbol
->flags
& BSF_WEAK
) == 0
1051 return bfd_reloc_undefined
;
1053 /* We handle final linking of some relocs ourselves. */
1055 /* Is the address of the relocation really within the section? */
1056 if (reloc
->address
> isection
->_cooked_size
)
1057 return bfd_reloc_outofrange
;
1059 /* Work out which section the relocation is targetted at and the
1060 initial relocation command value. */
1062 /* Get symbol value. (Common symbols are special.) */
1063 if (bfd_is_com_section (symbol
->section
))
1066 relocation
= symbol
->value
;
1068 /* Convert input-section-relative symbol value to absolute + addend. */
1069 relocation
+= symbol
->section
->output_section
->vma
;
1070 relocation
+= symbol
->section
->output_offset
;
1071 relocation
+= reloc
->addend
;
1073 if (reloc
->howto
->pc_relative
== true)
1075 /* Here the variable relocation holds the final address of the
1076 symbol we are relocating against, plus any addend. */
1077 relocation
-= isection
->output_section
->vma
+ isection
->output_offset
;
1079 /* Deal with pcrel_offset */
1080 relocation
-= reloc
->address
;
1083 /* I've got no clue... */
1086 return v850_elf_store_addend_in_insn (abfd
, reloc
->howto
->type
, relocation
,
1087 (bfd_byte
*) data
+ reloc
->address
, true);
1093 v850_elf_is_local_label_name (abfd
, name
)
1097 return ( (name
[0] == '.' && (name
[1] == 'L' || name
[1] == '.'))
1098 || (name
[0] == '_' && name
[1] == '.' && name
[2] == 'L' && name
[3] == '_'));
1102 /* Perform a relocation as part of a final link. */
1103 static bfd_reloc_status_type
1104 v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
1105 input_section
, contents
, offset
, value
,
1106 addend
, info
, sym_sec
, is_local
)
1107 reloc_howto_type
* howto
;
1110 asection
* input_section
;
1111 bfd_byte
* contents
;
1115 struct bfd_link_info
* info
;
1119 unsigned long r_type
= howto
->type
;
1120 bfd_byte
* hit_data
= contents
+ offset
;
1122 /* Adjust the value according to the relocation. */
1125 case R_V850_9_PCREL
:
1126 value
-= (input_section
->output_section
->vma
1127 + input_section
->output_offset
);
1131 case R_V850_22_PCREL
:
1132 value
-= (input_section
->output_section
->vma
1133 + input_section
->output_offset
1136 value
= SEXT24 (value
); /* Only the bottom 24 bits of the PC are valid */
1147 case R_V850_ZDA_15_16_OFFSET
:
1148 case R_V850_ZDA_16_16_OFFSET
:
1149 /* start-sanitize-v850e */
1150 case R_V850_ZDA_16_16_SPLIT_OFFSET
:
1151 /* end-sanitize-v850e */
1152 if (sym_sec
== NULL
)
1153 return bfd_reloc_undefined
;
1155 value
-= sym_sec
->output_section
->vma
;
1158 case R_V850_SDA_15_16_OFFSET
:
1159 case R_V850_SDA_16_16_OFFSET
:
1160 /* start-sanitize-v850e */
1161 case R_V850_SDA_16_16_SPLIT_OFFSET
:
1162 /* end-sanitize-v850e */
1165 struct bfd_link_hash_entry
* h
;
1167 if (sym_sec
== NULL
)
1168 return bfd_reloc_undefined
;
1170 /* Get the value of __gp. */
1171 h
= bfd_link_hash_lookup (info
->hash
, "__gp", false, false, true);
1172 if (h
== (struct bfd_link_hash_entry
*) NULL
1173 || h
->type
!= bfd_link_hash_defined
)
1174 return bfd_reloc_other
;
1176 gp
= (h
->u
.def
.value
1177 + h
->u
.def
.section
->output_section
->vma
1178 + h
->u
.def
.section
->output_offset
);
1180 value
-= sym_sec
->output_section
->vma
;
1181 value
-= (gp
- sym_sec
->output_section
->vma
);
1185 /* start-sanitize-v850e */
1186 case R_V850_TDA_4_4_OFFSET
:
1187 case R_V850_TDA_4_5_OFFSET
:
1188 /* end-sanitize-v850e */
1189 case R_V850_TDA_16_16_OFFSET
:
1190 case R_V850_TDA_7_7_OFFSET
:
1191 case R_V850_TDA_7_8_OFFSET
:
1192 case R_V850_TDA_6_8_OFFSET
:
1195 struct bfd_link_hash_entry
* h
;
1197 /* Get the value of __ep. */
1198 h
= bfd_link_hash_lookup (info
->hash
, "__ep", false, false, true);
1199 if (h
== (struct bfd_link_hash_entry
*) NULL
1200 || h
->type
!= bfd_link_hash_defined
)
1201 return bfd_reloc_continue
; /* Actually this indicates that __ep could not be found. */
1203 ep
= (h
->u
.def
.value
1204 + h
->u
.def
.section
->output_section
->vma
1205 + h
->u
.def
.section
->output_offset
);
1211 /* start-sanitize-v850e */
1212 case R_V850_CALLT_6_7_OFFSET
:
1215 struct bfd_link_hash_entry
* h
;
1217 /* Get the value of __ctbp. */
1218 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1219 if (h
== (struct bfd_link_hash_entry
*) NULL
1220 || h
->type
!= bfd_link_hash_defined
)
1221 return (bfd_reloc_dangerous
+ 1); /* Actually this indicates that __ctbp could not be found. */
1223 ctbp
= (h
->u
.def
.value
1224 + h
->u
.def
.section
->output_section
->vma
1225 + h
->u
.def
.section
->output_offset
);
1230 case R_V850_CALLT_16_16_OFFSET
:
1233 struct bfd_link_hash_entry
* h
;
1235 if (sym_sec
== NULL
)
1236 return bfd_reloc_undefined
;
1238 /* Get the value of __ctbp. */
1239 h
= bfd_link_hash_lookup (info
->hash
, "__ctbp", false, false, true);
1240 if (h
== (struct bfd_link_hash_entry
*) NULL
1241 || h
->type
!= bfd_link_hash_defined
)
1242 return (bfd_reloc_dangerous
+ 1);
1244 ctbp
= (h
->u
.def
.value
1245 + h
->u
.def
.section
->output_section
->vma
1246 + h
->u
.def
.section
->output_offset
);
1248 value
-= sym_sec
->output_section
->vma
;
1249 value
-= (ctbp
- sym_sec
->output_section
->vma
);
1252 /* end-sanitize-v850e */
1255 return bfd_reloc_ok
;
1258 return bfd_reloc_notsupported
;
1261 /* Perform the relocation. */
1262 return v850_elf_store_addend_in_insn (input_bfd
, r_type
, value
, hit_data
, false);
1266 /* Relocate an V850 ELF section. */
1268 v850_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
1269 contents
, relocs
, local_syms
, local_sections
)
1271 struct bfd_link_info
* info
;
1273 asection
* input_section
;
1274 bfd_byte
* contents
;
1275 Elf_Internal_Rela
* relocs
;
1276 Elf_Internal_Sym
* local_syms
;
1277 asection
** local_sections
;
1279 Elf_Internal_Shdr
* symtab_hdr
;
1280 struct elf_link_hash_entry
** sym_hashes
;
1281 Elf_Internal_Rela
* rel
;
1282 Elf_Internal_Rela
* relend
;
1284 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
1285 sym_hashes
= elf_sym_hashes (input_bfd
);
1288 relend
= relocs
+ input_section
->reloc_count
;
1289 for (; rel
< relend
; rel
++)
1292 reloc_howto_type
* howto
;
1293 unsigned long r_symndx
;
1294 Elf_Internal_Sym
* sym
;
1296 struct elf_link_hash_entry
* h
;
1298 bfd_reloc_status_type r
;
1300 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1301 r_type
= ELF32_R_TYPE (rel
->r_info
);
1302 howto
= v850_elf_howto_table
+ r_type
;
1304 if (info
->relocateable
)
1306 /* This is a relocateable link. We don't have to change
1307 anything, unless the reloc is against a section symbol,
1308 in which case we have to adjust according to where the
1309 section symbol winds up in the output section. */
1310 if (r_symndx
< symtab_hdr
->sh_info
)
1312 sym
= local_syms
+ r_symndx
;
1313 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1315 sec
= local_sections
[r_symndx
];
1317 /* The Elf_Internal_Rel structure does not have space for the
1318 modified addend value, so we store it in the instruction
1321 if (sec
->output_offset
+ sym
->st_value
!= 0)
1323 if (v850_elf_store_addend_in_insn (input_bfd
, r_type
,
1324 sec
->output_offset
+
1326 contents
+ rel
->r_offset
,
1330 info
->callbacks
->warning
1332 "Unable to handle relocation during incremental link",
1333 NULL
, input_bfd
, input_section
, rel
->r_offset
);
1337 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1345 /* This is a final link. */
1349 if (r_symndx
< symtab_hdr
->sh_info
)
1351 sym
= local_syms
+ r_symndx
;
1352 sec
= local_sections
[r_symndx
];
1353 relocation
= (sec
->output_section
->vma
1354 + sec
->output_offset
1359 name
= bfd_elf_string_from_elf_section (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
1360 name
= (name
== NULL
) ? "<none>" : name
;
1361 fprintf (stderr
, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
1362 sec
->name
, name
, sym
->st_name
,
1363 sec
->output_section
->vma
, sec
->output_offset
, sym
->st_value
, rel
->r_addend
);
1369 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1371 while (h
->root
.type
== bfd_link_hash_indirect
1372 || h
->root
.type
== bfd_link_hash_warning
)
1373 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1375 if (h
->root
.type
== bfd_link_hash_defined
1376 || h
->root
.type
== bfd_link_hash_defweak
)
1378 sec
= h
->root
.u
.def
.section
;
1379 relocation
= (h
->root
.u
.def
.value
1380 + sec
->output_section
->vma
1381 + sec
->output_offset
);
1383 fprintf (stderr
, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1384 sec
->name
, h
->root
.root
.string
, h
->root
.u
.def
.value
, sec
->output_section
->vma
, sec
->output_offset
, relocation
);
1387 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1390 fprintf (stderr
, "undefined: sec: %s, name: %s\n",
1391 sec
->name
, h
->root
.root
.string
);
1397 if (! ((*info
->callbacks
->undefined_symbol
)
1398 (info
, h
->root
.root
.string
, input_bfd
,
1399 input_section
, rel
->r_offset
)))
1402 fprintf (stderr
, "unknown: name: %s\n", h
->root
.root
.string
);
1408 /* FIXME: We should use the addend, but the COFF relocations
1410 r
= v850_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
1412 contents
, rel
->r_offset
,
1413 relocation
, rel
->r_addend
,
1414 info
, sec
, h
== NULL
);
1416 if (r
!= bfd_reloc_ok
)
1419 const char * msg
= (const char *)0;
1422 name
= h
->root
.root
.string
;
1425 name
= (bfd_elf_string_from_elf_section
1426 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1427 if (name
== NULL
|| *name
== '\0')
1428 name
= bfd_section_name (input_bfd
, sec
);
1433 case bfd_reloc_overflow
:
1434 if (! ((*info
->callbacks
->reloc_overflow
)
1435 (info
, name
, howto
->name
, (bfd_vma
) 0,
1436 input_bfd
, input_section
, rel
->r_offset
)))
1440 case bfd_reloc_undefined
:
1441 if (! ((*info
->callbacks
->undefined_symbol
)
1442 (info
, name
, input_bfd
, input_section
,
1447 case bfd_reloc_outofrange
:
1448 msg
= "internal error: out of range error";
1451 case bfd_reloc_notsupported
:
1452 msg
= "internal error: unsupported relocation error";
1455 case bfd_reloc_dangerous
:
1456 msg
= "internal error: dangerous relocation";
1459 case bfd_reloc_other
:
1460 msg
= "could not locate special linker symbol __gp";
1463 case bfd_reloc_continue
:
1464 msg
= "could not locate special linker symbol __ep";
1467 case (bfd_reloc_dangerous
+ 1):
1468 msg
= "could not locate special linker symbol __ctbp";
1472 msg
= "internal error: unknown error";
1476 if (!((*info
->callbacks
->warning
)
1477 (info
, msg
, name
, input_bfd
, input_section
,
1488 /* Set the right machine number. */
1490 v850_elf_object_p (abfd
)
1493 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1496 case E_V850_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, 0); break;
1497 /* start-sanitize-v850e */
1498 case E_V850E_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850e
); break;
1499 case E_V850EA_ARCH
: (void) bfd_default_set_arch_mach (abfd
, bfd_arch_v850
, bfd_mach_v850ea
); break;
1500 /* end-sanitize-v850e */
1504 /* Store the machine number in the flags field. */
1506 v850_elf_final_write_processing (abfd
, linker
)
1512 switch (bfd_get_mach (abfd
))
1515 case 0: val
= E_V850_ARCH
; break;
1516 /* start-sanitize-v850e */
1517 case bfd_mach_v850e
: val
= E_V850E_ARCH
; break;
1518 case bfd_mach_v850ea
: val
= E_V850EA_ARCH
; break;
1519 /* end-sanitize-v850e */
1522 elf_elfheader (abfd
)->e_flags
&=~ EF_V850_ARCH
;
1523 elf_elfheader (abfd
)->e_flags
|= val
;
1526 /* Function to keep V850 specific file flags. */
1528 v850_elf_set_private_flags (abfd
, flags
)
1532 BFD_ASSERT (!elf_flags_init (abfd
)
1533 || elf_elfheader (abfd
)->e_flags
== flags
);
1535 elf_elfheader (abfd
)->e_flags
= flags
;
1536 elf_flags_init (abfd
) = true;
1540 /* Copy backend specific data from one object module to another */
1542 v850_elf_copy_private_bfd_data (ibfd
, obfd
)
1546 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1547 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1550 BFD_ASSERT (!elf_flags_init (obfd
)
1551 || (elf_elfheader (obfd
)->e_flags
1552 == elf_elfheader (ibfd
)->e_flags
));
1554 elf_gp (obfd
) = elf_gp (ibfd
);
1555 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
1556 elf_flags_init (obfd
) = true;
1560 /* Merge backend specific data from an object file to the output
1561 object file when linking. */
1563 v850_elf_merge_private_bfd_data (ibfd
, obfd
)
1570 if ( bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
1571 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
1574 in_flags
= elf_elfheader (ibfd
)->e_flags
;
1575 out_flags
= elf_elfheader (obfd
)->e_flags
;
1577 if (! elf_flags_init (obfd
))
1579 /* If the input is the default architecture then do not
1580 bother setting the flags for the output architecture,
1581 instead allow future merges to do this. If no future
1582 merges ever set these flags then they will retain their
1583 unitialised values, which surprise surprise, correspond
1584 to the default values. */
1585 if (bfd_get_arch_info (ibfd
)->the_default
)
1588 elf_flags_init (obfd
) = true;
1589 elf_elfheader (obfd
)->e_flags
= in_flags
;
1591 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
1592 && bfd_get_arch_info (obfd
)->the_default
)
1594 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
1600 /* Check flag compatibility. */
1601 if (in_flags
== out_flags
)
1604 if ((in_flags
& EF_V850_ARCH
) != (out_flags
& EF_V850_ARCH
)
1605 && (in_flags
& EF_V850_ARCH
) != E_V850_ARCH
)
1606 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1607 bfd_get_filename (ibfd
));
1611 /* Display the flags field */
1614 v850_elf_print_private_bfd_data (abfd
, ptr
)
1618 FILE * file
= (FILE *) ptr
;
1620 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
)
1622 fprintf (file
, "private flags = %x", elf_elfheader (abfd
)->e_flags
);
1624 switch (elf_elfheader (abfd
)->e_flags
& EF_V850_ARCH
)
1627 case E_V850_ARCH
: fprintf (file
, ": v850 architecture"); break;
1628 /* start-sanitize-v850e */
1629 case E_V850E_ARCH
: fprintf (file
, ": v850e architecture"); break;
1630 case E_V850EA_ARCH
: fprintf (file
, ": v850ea architecture"); break;
1631 /* end-sanitize-v850e */
1639 /* V850 ELF uses four common sections. One is the usual one, and the
1640 others are for (small) objects in one of the special data areas:
1641 small, tiny and zero. All the objects are kept together, and then
1642 referenced via the gp register, the ep register or the r0 register
1643 respectively, which yields smaller, faster assembler code. This
1644 approach is copied from elf32-mips.c. */
1646 static asection v850_elf_scom_section
;
1647 static asymbol v850_elf_scom_symbol
;
1648 static asymbol
* v850_elf_scom_symbol_ptr
;
1649 static asection v850_elf_tcom_section
;
1650 static asymbol v850_elf_tcom_symbol
;
1651 static asymbol
* v850_elf_tcom_symbol_ptr
;
1652 static asection v850_elf_zcom_section
;
1653 static asymbol v850_elf_zcom_symbol
;
1654 static asymbol
* v850_elf_zcom_symbol_ptr
;
1657 /* Given a BFD section, try to locate the corresponding ELF section
1661 v850_elf_section_from_bfd_section (abfd
, hdr
, sec
, retval
)
1663 Elf32_Internal_Shdr
* hdr
;
1667 if (strcmp (bfd_get_section_name (abfd
, sec
), ".scommon") == 0)
1669 *retval
= SHN_V850_SCOMMON
;
1672 if (strcmp (bfd_get_section_name (abfd
, sec
), ".tcommon") == 0)
1674 *retval
= SHN_V850_TCOMMON
;
1677 if (strcmp (bfd_get_section_name (abfd
, sec
), ".zcommon") == 0)
1679 *retval
= SHN_V850_ZCOMMON
;
1685 /* Handle the special V850 section numbers that a symbol may use. */
1688 v850_elf_symbol_processing (abfd
, asym
)
1692 elf_symbol_type
* elfsym
= (elf_symbol_type
*) asym
;
1694 switch (elfsym
->internal_elf_sym
.st_shndx
)
1696 case SHN_V850_SCOMMON
:
1697 if (v850_elf_scom_section
.name
== NULL
)
1699 /* Initialize the small common section. */
1700 v850_elf_scom_section
.name
= ".scommon";
1701 v850_elf_scom_section
.flags
= SEC_IS_COMMON
| SEC_ALLOC
| SEC_DATA
;
1702 v850_elf_scom_section
.output_section
= & v850_elf_scom_section
;
1703 v850_elf_scom_section
.symbol
= & v850_elf_scom_symbol
;
1704 v850_elf_scom_section
.symbol_ptr_ptr
= & v850_elf_scom_symbol_ptr
;
1705 v850_elf_scom_symbol
.name
= ".scommon";
1706 v850_elf_scom_symbol
.flags
= BSF_SECTION_SYM
;
1707 v850_elf_scom_symbol
.section
= & v850_elf_scom_section
;
1708 v850_elf_scom_symbol_ptr
= & v850_elf_scom_symbol
;
1710 asym
->section
= & v850_elf_scom_section
;
1711 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1714 case SHN_V850_TCOMMON
:
1715 if (v850_elf_tcom_section
.name
== NULL
)
1717 /* Initialize the tcommon section. */
1718 v850_elf_tcom_section
.name
= ".tcommon";
1719 v850_elf_tcom_section
.flags
= SEC_IS_COMMON
;
1720 v850_elf_tcom_section
.output_section
= & v850_elf_tcom_section
;
1721 v850_elf_tcom_section
.symbol
= & v850_elf_tcom_symbol
;
1722 v850_elf_tcom_section
.symbol_ptr_ptr
= & v850_elf_tcom_symbol_ptr
;
1723 v850_elf_tcom_symbol
.name
= ".tcommon";
1724 v850_elf_tcom_symbol
.flags
= BSF_SECTION_SYM
;
1725 v850_elf_tcom_symbol
.section
= & v850_elf_tcom_section
;
1726 v850_elf_tcom_symbol_ptr
= & v850_elf_tcom_symbol
;
1728 asym
->section
= & v850_elf_tcom_section
;
1729 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1732 case SHN_V850_ZCOMMON
:
1733 if (v850_elf_zcom_section
.name
== NULL
)
1735 /* Initialize the zcommon section. */
1736 v850_elf_zcom_section
.name
= ".zcommon";
1737 v850_elf_zcom_section
.flags
= SEC_IS_COMMON
;
1738 v850_elf_zcom_section
.output_section
= & v850_elf_zcom_section
;
1739 v850_elf_zcom_section
.symbol
= & v850_elf_zcom_symbol
;
1740 v850_elf_zcom_section
.symbol_ptr_ptr
= & v850_elf_zcom_symbol_ptr
;
1741 v850_elf_zcom_symbol
.name
= ".zcommon";
1742 v850_elf_zcom_symbol
.flags
= BSF_SECTION_SYM
;
1743 v850_elf_zcom_symbol
.section
= & v850_elf_zcom_section
;
1744 v850_elf_zcom_symbol_ptr
= & v850_elf_zcom_symbol
;
1746 asym
->section
= & v850_elf_zcom_section
;
1747 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
1752 /* Hook called by the linker routine which adds symbols from an object
1753 file. We must handle the special MIPS section numbers here. */
1757 v850_elf_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
1759 struct bfd_link_info
* info
;
1760 const Elf_Internal_Sym
* sym
;
1761 const char ** namep
;
1766 switch (sym
->st_shndx
)
1768 case SHN_V850_SCOMMON
:
1769 *secp
= bfd_make_section_old_way (abfd
, ".scommon");
1770 (*secp
)->flags
|= SEC_IS_COMMON
;
1771 *valp
= sym
->st_size
;
1774 case SHN_V850_TCOMMON
:
1775 *secp
= bfd_make_section_old_way (abfd
, ".tcommon");
1776 (*secp
)->flags
|= SEC_IS_COMMON
;
1777 *valp
= sym
->st_size
;
1780 case SHN_V850_ZCOMMON
:
1781 *secp
= bfd_make_section_old_way (abfd
, ".zcommon");
1782 (*secp
)->flags
|= SEC_IS_COMMON
;
1783 *valp
= sym
->st_size
;
1792 v850_elf_link_output_symbol_hook (abfd
, info
, name
, sym
, input_sec
)
1794 struct bfd_link_info
* info
;
1796 Elf_Internal_Sym
* sym
;
1797 asection
* input_sec
;
1799 /* If we see a common symbol, which implies a relocatable link, then
1800 if a symbol was in a special common section in an input file, mark
1801 it as a special common in the output file. */
1803 if (sym
->st_shndx
== SHN_COMMON
)
1805 if (strcmp (input_sec
->name
, ".scommon") == 0)
1806 sym
->st_shndx
= SHN_V850_SCOMMON
;
1807 else if (strcmp (input_sec
->name
, ".tcommon") == 0)
1808 sym
->st_shndx
= SHN_V850_TCOMMON
;
1809 else if (strcmp (input_sec
->name
, ".zcommon") == 0)
1810 sym
->st_shndx
= SHN_V850_ZCOMMON
;
1817 v850_elf_section_from_shdr (abfd
, hdr
, name
)
1819 Elf_Internal_Shdr
* hdr
;
1822 /* There ought to be a place to keep ELF backend specific flags, but
1823 at the moment there isn't one. We just keep track of the
1824 sections by their name, instead. */
1826 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
1829 switch (hdr
->sh_type
)
1831 case SHT_V850_SCOMMON
:
1832 case SHT_V850_TCOMMON
:
1833 case SHT_V850_ZCOMMON
:
1834 if (! bfd_set_section_flags (abfd
, hdr
->bfd_section
,
1835 (bfd_get_section_flags (abfd
,
1844 /* Set the correct type for a V850 ELF section. We do this by the
1845 section name, which is a hack, but ought to work. */
1847 v850_elf_fake_sections (abfd
, hdr
, sec
)
1849 Elf32_Internal_Shdr
* hdr
;
1852 register const char * name
;
1854 name
= bfd_get_section_name (abfd
, sec
);
1856 if (strcmp (name
, ".scommon") == 0)
1858 hdr
->sh_type
= SHT_V850_SCOMMON
;
1860 else if (strcmp (name
, ".tcommon") == 0)
1862 hdr
->sh_type
= SHT_V850_TCOMMON
;
1864 else if (strcmp (name
, ".zcommon") == 0)
1865 hdr
->sh_type
= SHT_V850_ZCOMMON
;
1872 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
1873 #define TARGET_LITTLE_NAME "elf32-v850"
1874 #define ELF_ARCH bfd_arch_v850
1875 #define ELF_MACHINE_CODE EM_CYGNUS_V850
1876 #define ELF_MAXPAGESIZE 0x1000
1878 #define elf_info_to_howto 0
1879 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
1881 #define elf_backend_check_relocs v850_elf_check_relocs
1882 #define elf_backend_relocate_section v850_elf_relocate_section
1883 #define elf_backend_object_p v850_elf_object_p
1884 #define elf_backend_final_write_processing v850_elf_final_write_processing
1885 #define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
1886 #define elf_backend_symbol_processing v850_elf_symbol_processing
1887 #define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
1888 #define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
1889 #define elf_backend_section_from_shdr v850_elf_section_from_shdr
1890 #define elf_backend_fake_sections v850_elf_fake_sections
1892 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
1893 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
1894 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
1895 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
1896 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
1897 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
1899 #define elf_symbol_leading_char '_'
1901 #include "elf32-target.h"