Fixed buglet displaying machine architecture.
[binutils-gdb.git] / bfd / elf32-v850.c
1 /* V850-specific support for 32-bit ELF
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
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.
10
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.
15
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. */
19
20
21
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. */
24
25
26 #include "bfd.h"
27 #include "sysdep.h"
28 #include "bfdlink.h"
29 #include "libbfd.h"
30 #include "elf-bfd.h"
31 #include "elf/v850.h"
32
33 static reloc_howto_type *v850_elf_reloc_type_lookup
34 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
35 static void v850_elf_info_to_howto_rel
36 PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
37 static bfd_reloc_status_type v850_elf_reloc
38 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
39 static boolean v850_elf_is_local_label_name PARAMS ((bfd *, const char *));
40 static boolean v850_elf_relocate_section PARAMS((bfd *,
41 struct bfd_link_info *,
42 bfd *,
43 asection *,
44 bfd_byte *,
45 Elf_Internal_Rela *,
46 Elf_Internal_Sym *,
47 asection **));
48 /* Try to minimize the amount of space occupied by relocation tables
49 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
50 #define USE_REL
51
52 /* Note: It is REQUIRED that the 'type' value of each entry in this array
53 match the index of the entry in the array. */
54 static reloc_howto_type v850_elf_howto_table[] =
55 {
56 /* This reloc does nothing. */
57 HOWTO (R_V850_NONE, /* type */
58 0, /* rightshift */
59 2, /* size (0 = byte, 1 = short, 2 = long) */
60 32, /* bitsize */
61 false, /* pc_relative */
62 0, /* bitpos */
63 complain_overflow_bitfield, /* complain_on_overflow */
64 bfd_elf_generic_reloc, /* special_function */
65 "R_V850_NONE", /* name */
66 false, /* partial_inplace */
67 0, /* src_mask */
68 0, /* dst_mask */
69 false), /* pcrel_offset */
70
71 /* A PC relative 9 bit branch. */
72 HOWTO (R_V850_9_PCREL, /* type */
73 2, /* rightshift */
74 2, /* size (0 = byte, 1 = short, 2 = long) */
75 26, /* bitsize */
76 true, /* pc_relative */
77 0, /* bitpos */
78 complain_overflow_bitfield, /* complain_on_overflow */
79 v850_elf_reloc, /* special_function */
80 "R_V850_9_PCREL", /* name */
81 false, /* partial_inplace */
82 0x00ffffff, /* src_mask */
83 0x00ffffff, /* dst_mask */
84 true), /* pcrel_offset */
85
86 /* A PC relative 22 bit branch. */
87 HOWTO (R_V850_22_PCREL, /* type */
88 2, /* rightshift */
89 2, /* size (0 = byte, 1 = short, 2 = long) */
90 22, /* bitsize */
91 true, /* pc_relative */
92 7, /* bitpos */
93 complain_overflow_signed, /* complain_on_overflow */
94 v850_elf_reloc, /* special_function */
95 "R_V850_22_PCREL", /* name */
96 false, /* partial_inplace */
97 0x07ffff80, /* src_mask */
98 0x07ffff80, /* dst_mask */
99 true), /* pcrel_offset */
100
101 /* High 16 bits of symbol value. */
102 HOWTO (R_V850_HI16_S, /* type */
103 0, /* rightshift */
104 1, /* size (0 = byte, 1 = short, 2 = long) */
105 16, /* bitsize */
106 false, /* pc_relative */
107 0, /* bitpos */
108 complain_overflow_dont, /* complain_on_overflow */
109 v850_elf_reloc, /* special_function */
110 "R_V850_HI16_S", /* name */
111 true, /* partial_inplace */
112 0xffff, /* src_mask */
113 0xffff, /* dst_mask */
114 false), /* pcrel_offset */
115
116 /* High 16 bits of symbol value. */
117 HOWTO (R_V850_HI16, /* type */
118 0, /* rightshift */
119 1, /* size (0 = byte, 1 = short, 2 = long) */
120 16, /* bitsize */
121 false, /* pc_relative */
122 0, /* bitpos */
123 complain_overflow_dont, /* complain_on_overflow */
124 v850_elf_reloc, /* special_function */
125 "R_V850_HI16", /* name */
126 true, /* partial_inplace */
127 0xffff, /* src_mask */
128 0xffff, /* dst_mask */
129 false), /* pcrel_offset */
130
131 /* Low 16 bits of symbol value. */
132 HOWTO (R_V850_LO16, /* type */
133 0, /* rightshift */
134 1, /* size (0 = byte, 1 = short, 2 = long) */
135 16, /* bitsize */
136 false, /* pc_relative */
137 0, /* bitpos */
138 complain_overflow_dont, /* complain_on_overflow */
139 v850_elf_reloc, /* special_function */
140 "R_V850_LO16", /* name */
141 true, /* partial_inplace */
142 0xffff, /* src_mask */
143 0xffff, /* dst_mask */
144 false), /* pcrel_offset */
145
146 /* Simple 32bit reloc. */
147 HOWTO (R_V850_32, /* type */
148 0, /* rightshift */
149 2, /* size (0 = byte, 1 = short, 2 = long) */
150 32, /* bitsize */
151 false, /* pc_relative */
152 0, /* bitpos */
153 complain_overflow_dont, /* complain_on_overflow */
154 bfd_elf_generic_reloc, /* special_function */
155 "R_V850_32", /* name */
156 true, /* partial_inplace */
157 0xffffffff, /* src_mask */
158 0xffffffff, /* dst_mask */
159 false), /* pcrel_offset */
160
161 /* Simple 16bit reloc. */
162 HOWTO (R_V850_16, /* type */
163 0, /* rightshift */
164 1, /* size (0 = byte, 1 = short, 2 = long) */
165 16, /* bitsize */
166 false, /* pc_relative */
167 0, /* bitpos */
168 complain_overflow_dont, /* complain_on_overflow */
169 bfd_elf_generic_reloc, /* special_function */
170 "R_V850_16", /* name */
171 true, /* partial_inplace */
172 0xffff, /* src_mask */
173 0xffff, /* dst_mask */
174 false), /* pcrel_offset */
175
176 /* Simple 8bit reloc. */
177 HOWTO (R_V850_8, /* type */
178 0, /* rightshift */
179 0, /* size (0 = byte, 1 = short, 2 = long) */
180 8, /* bitsize */
181 false, /* pc_relative */
182 0, /* bitpos */
183 complain_overflow_dont, /* complain_on_overflow */
184 bfd_elf_generic_reloc, /* special_function */
185 "R_V850_8", /* name */
186 true, /* partial_inplace */
187 0xff, /* src_mask */
188 0xff, /* dst_mask */
189 false), /* pcrel_offset */
190
191 /* 16 bit offset from the short data area pointer. */
192 HOWTO (R_V850_SDA_16_16_OFFSET, /* type */
193 0, /* rightshift */
194 1, /* size (0 = byte, 1 = short, 2 = long) */
195 16, /* bitsize */
196 false, /* pc_relative */
197 0, /* bitpos */
198 complain_overflow_dont, /* complain_on_overflow */
199 v850_elf_reloc, /* special_function */
200 "R_V850_SDA_16_16_OFFSET", /* name */
201 false, /* partial_inplace */
202 0xffff, /* src_mask */
203 0xffff, /* dst_mask */
204 false), /* pcrel_offset */
205
206 /* 15 bit offset from the short data area pointer. */
207 HOWTO (R_V850_SDA_15_16_OFFSET, /* type */
208 1, /* rightshift */
209 1, /* size (0 = byte, 1 = short, 2 = long) */
210 16, /* bitsize */
211 false, /* pc_relative */
212 1, /* bitpos */
213 complain_overflow_dont, /* complain_on_overflow */
214 v850_elf_reloc, /* special_function */
215 "R_V850_SDA_15_16_OFFSET", /* name */
216 false, /* partial_inplace */
217 0xfffe, /* src_mask */
218 0xfffe, /* dst_mask */
219 false), /* pcrel_offset */
220
221 /* 16 bit offset from the zero data area pointer. */
222 HOWTO (R_V850_ZDA_16_16_OFFSET, /* type */
223 0, /* rightshift */
224 1, /* size (0 = byte, 1 = short, 2 = long) */
225 16, /* bitsize */
226 false, /* pc_relative */
227 0, /* bitpos */
228 complain_overflow_dont, /* complain_on_overflow */
229 v850_elf_reloc, /* special_function */
230 "R_V850_ZDA_16_16_OFFSET", /* name */
231 false, /* partial_inplace */
232 0xffff, /* src_mask */
233 0xffff, /* dst_mask */
234 false), /* pcrel_offset */
235
236 /* 15 bit offset from the zero data area pointer. */
237 HOWTO (R_V850_ZDA_15_16_OFFSET, /* type */
238 1, /* rightshift */
239 1, /* size (0 = byte, 1 = short, 2 = long) */
240 16, /* bitsize */
241 false, /* pc_relative */
242 1, /* bitpos */
243 complain_overflow_dont, /* complain_on_overflow */
244 v850_elf_reloc, /* special_function */
245 "R_V850_ZDA_15_16_OFFSET", /* name */
246 false, /* partial_inplace */
247 0xfffe, /* src_mask */
248 0xfffe, /* dst_mask */
249 false), /* pcrel_offset */
250
251 /* 6 bit offset from the tiny data area pointer. */
252 HOWTO (R_V850_TDA_6_8_OFFSET, /* type */
253 2, /* rightshift */
254 1, /* size (0 = byte, 1 = short, 2 = long) */
255 8, /* bitsize */
256 false, /* pc_relative */
257 1, /* bitpos */
258 complain_overflow_dont, /* complain_on_overflow */
259 v850_elf_reloc, /* special_function */
260 "R_V850_TDA_6_8_OFFSET", /* name */
261 false, /* partial_inplace */
262 0x7e, /* src_mask */
263 0x7e, /* dst_mask */
264 false), /* pcrel_offset */
265
266 /* 8 bit offset from the tiny data area pointer. */
267 HOWTO (R_V850_TDA_7_8_OFFSET, /* type */
268 1, /* rightshift */
269 1, /* size (0 = byte, 1 = short, 2 = long) */
270 8, /* bitsize */
271 false, /* pc_relative */
272 0, /* bitpos */
273 complain_overflow_dont, /* complain_on_overflow */
274 v850_elf_reloc, /* special_function */
275 "R_V850_TDA_7_8_OFFSET", /* name */
276 false, /* partial_inplace */
277 0x7f, /* src_mask */
278 0x7f, /* dst_mask */
279 false), /* pcrel_offset */
280
281 /* 7 bit offset from the tiny data area pointer. */
282 HOWTO (R_V850_TDA_7_7_OFFSET, /* type */
283 0, /* rightshift */
284 1, /* size (0 = byte, 1 = short, 2 = long) */
285 7, /* bitsize */
286 false, /* pc_relative */
287 0, /* bitpos */
288 complain_overflow_dont, /* complain_on_overflow */
289 v850_elf_reloc, /* special_function */
290 "R_V850_TDA_7_7_OFFSET", /* name */
291 false, /* partial_inplace */
292 0x7f, /* src_mask */
293 0x7f, /* dst_mask */
294 false), /* pcrel_offset */
295
296 /* start-sanitize-v850e */
297
298 /* 5 bit offset from the tiny data area pointer. */
299 HOWTO (R_V850_TDA_4_5_OFFSET, /* type */
300 1, /* rightshift */
301 1, /* size (0 = byte, 1 = short, 2 = long) */
302 5, /* bitsize */
303 false, /* pc_relative */
304 0, /* bitpos */
305 complain_overflow_dont, /* complain_on_overflow */
306 v850_elf_reloc, /* special_function */
307 "R_V850_TDA_4_5_OFFSET", /* name */
308 false, /* partial_inplace */
309 0x0f, /* src_mask */
310 0x0f, /* dst_mask */
311 false), /* pcrel_offset */
312
313 /* 4 bit offset from the tiny data area pointer. */
314 HOWTO (R_V850_TDA_4_4_OFFSET, /* type */
315 0, /* rightshift */
316 1, /* size (0 = byte, 1 = short, 2 = long) */
317 4, /* bitsize */
318 false, /* pc_relative */
319 0, /* bitpos */
320 complain_overflow_dont, /* complain_on_overflow */
321 v850_elf_reloc, /* special_function */
322 "R_V850_TDA_4_4_OFFSET", /* name */
323 false, /* partial_inplace */
324 0x0f, /* src_mask */
325 0x0f, /* dst_mask */
326 false), /* pcrel_offset */
327
328 /* 16 bit offset from the short data area pointer. */
329 HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */
330 0, /* rightshift */
331 2, /* size (0 = byte, 1 = short, 2 = long) */
332 16, /* bitsize */
333 false, /* pc_relative */
334 0, /* bitpos */
335 complain_overflow_dont, /* complain_on_overflow */
336 v850_elf_reloc, /* special_function */
337 "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
338 false, /* partial_inplace */
339 0xfffe0020, /* src_mask */
340 0xfffe0020, /* dst_mask */
341 false), /* pcrel_offset */
342
343 /* 16 bit offset from the zero data area pointer. */
344 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
345 0, /* rightshift */
346 2, /* size (0 = byte, 1 = short, 2 = long) */
347 16, /* bitsize */
348 false, /* pc_relative */
349 0, /* bitpos */
350 complain_overflow_dont, /* complain_on_overflow */
351 v850_elf_reloc, /* special_function */
352 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
353 false, /* partial_inplace */
354 0xfffe0020, /* src_mask */
355 0xfffe0020, /* dst_mask */
356 false), /* pcrel_offset */
357
358 /* end-sanitize-v850e */
359 };
360
361 /* Map BFD reloc types to V850 ELF reloc types. */
362
363 struct v850_elf_reloc_map
364 {
365 unsigned char bfd_reloc_val;
366 unsigned char elf_reloc_val;
367 };
368
369 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
370 {
371 { BFD_RELOC_NONE, R_V850_NONE },
372 { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL },
373 { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL },
374 { BFD_RELOC_HI16_S, R_V850_HI16_S },
375 { BFD_RELOC_HI16, R_V850_HI16 },
376 { BFD_RELOC_LO16, R_V850_LO16 },
377 { BFD_RELOC_32, R_V850_32 },
378 { BFD_RELOC_16, R_V850_16 },
379 { BFD_RELOC_8, R_V850_8 },
380 { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
381 { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
382 { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
383 { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
384 { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET },
385 { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET },
386 { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET },
387 /* start-sanitize-v850e */
388 { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET },
389 { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET },
390 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
391 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
392 /* end-sanitize-v850e */
393 };
394
395 \f
396 /* Map a bfd relocation into the appropriate howto structure */
397 static reloc_howto_type *
398 v850_elf_reloc_type_lookup (abfd, code)
399 bfd *abfd;
400 bfd_reloc_code_real_type code;
401 {
402 unsigned int i;
403
404 for (i = 0;
405 i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
406 i++)
407 {
408 if (v850_elf_reloc_map[i].bfd_reloc_val == code)
409 {
410 BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
411
412 return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
413 }
414 }
415
416 return NULL;
417 }
418
419 \f
420 /* Set the howto pointer for an V850 ELF reloc. */
421 static void
422 v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
423 bfd *abfd;
424 arelent *cache_ptr;
425 Elf32_Internal_Rel *dst;
426 {
427 unsigned int r_type;
428
429 r_type = ELF32_R_TYPE (dst->r_info);
430 BFD_ASSERT (r_type < (unsigned int) R_V850_max);
431 cache_ptr->howto = &v850_elf_howto_table[r_type];
432 }
433
434 \f
435 /* Look through the relocs for a section during the first phase, and
436 allocate space in the global offset table or procedure linkage
437 table. */
438
439 static boolean
440 v850_elf_check_relocs (abfd, info, sec, relocs)
441 bfd *abfd;
442 struct bfd_link_info *info;
443 asection *sec;
444 const Elf_Internal_Rela *relocs;
445 {
446 boolean ret = true;
447 bfd *dynobj;
448 Elf_Internal_Shdr *symtab_hdr;
449 struct elf_link_hash_entry **sym_hashes;
450 const Elf_Internal_Rela *rel;
451 const Elf_Internal_Rela *rel_end;
452 asection *sreloc;
453 enum reloc_type r_type;
454 int other = 0;
455 const char *common = (const char *)0;
456
457 if (info->relocateable)
458 return true;
459
460 #ifdef DEBUG
461 fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
462 bfd_get_section_name (abfd, sec),
463 bfd_get_filename (abfd));
464 #endif
465
466 dynobj = elf_hash_table (info)->dynobj;
467 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
468 sym_hashes = elf_sym_hashes (abfd);
469 sreloc = NULL;
470
471 rel_end = relocs + sec->reloc_count;
472 for (rel = relocs; rel < rel_end; rel++)
473 {
474 unsigned long r_symndx;
475 struct elf_link_hash_entry *h;
476
477 r_symndx = ELF32_R_SYM (rel->r_info);
478 if (r_symndx < symtab_hdr->sh_info)
479 h = NULL;
480 else
481 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
482
483 r_type = (enum reloc_type) ELF32_R_TYPE (rel->r_info);
484 switch (r_type)
485 {
486 default:
487 case R_V850_NONE:
488 case R_V850_9_PCREL:
489 case R_V850_22_PCREL:
490 case R_V850_HI16_S:
491 case R_V850_HI16:
492 case R_V850_LO16:
493 case R_V850_32:
494 case R_V850_16:
495 case R_V850_8:
496 break;
497
498 /* start-sanitize-v850e */
499 case R_V850_SDA_16_16_SPLIT_OFFSET:
500 /* end-sanitize-v850e */
501 case R_V850_SDA_16_16_OFFSET:
502 case R_V850_SDA_15_16_OFFSET:
503 other = V850_OTHER_SDA;
504 common = ".scommon";
505 goto small_data_common;
506
507 /* start-sanitize-v850e */
508 case R_V850_ZDA_16_16_SPLIT_OFFSET:
509 /* end-sanitize-v850e */
510 case R_V850_ZDA_16_16_OFFSET:
511 case R_V850_ZDA_15_16_OFFSET:
512 other = V850_OTHER_ZDA;
513 common = ".zcommon";
514 goto small_data_common;
515
516 /* start-sanitize-v850e */
517 case R_V850_TDA_4_5_OFFSET:
518 case R_V850_TDA_4_4_OFFSET:
519 /* end-sanitize-v850e */
520 case R_V850_TDA_6_8_OFFSET:
521 case R_V850_TDA_7_8_OFFSET:
522 case R_V850_TDA_7_7_OFFSET:
523 other = V850_OTHER_TDA;
524 common = ".tcommon";
525 /* fall through */
526
527 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
528
529 small_data_common:
530 if (h)
531 {
532 h->other |= other; /* flag which type of relocation was used */
533 if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
534 && (h->other & V850_OTHER_ERROR) == 0)
535 {
536 const char *msg;
537
538 switch (h->other & V850_OTHER_MASK)
539 {
540 default:
541 msg = "Variable cannot occupy in multiple small data regions";
542 break;
543 case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
544 msg = "Variable can only be in one of the small, zero, and tiny data regions";
545 break;
546 case V850_OTHER_SDA | V850_OTHER_ZDA:
547 msg = "Variable cannot be in both small and zero data regions simultaneously";
548 break;
549 case V850_OTHER_SDA | V850_OTHER_TDA:
550 msg = "Variable cannot be in both small and tiny data regions simultaneously";
551 break;
552 case V850_OTHER_ZDA | V850_OTHER_TDA:
553 msg = "Variable cannot be in both zero and tiny data regions simultaneously";
554 break;
555 }
556
557 (*info->callbacks->warning) (info, msg, h->root.root.string,
558 abfd, h->root.u.def.section, 0);
559
560 bfd_set_error (bfd_error_bad_value);
561 h->other |= V850_OTHER_ERROR;
562 ret = false;
563 }
564 }
565
566 if (h && h->root.type == bfd_link_hash_common
567 && h->root.u.c.p
568 && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
569 {
570 asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
571 section->flags |= SEC_IS_COMMON;
572 }
573
574 #ifdef DEBUG
575 fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
576 v850_elf_howto_table[ (int)r_type ].name,
577 (h && h->root.root.string) ? h->root.root.string : "<unknown>",
578 (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
579 #endif
580 break;
581 }
582 }
583
584 return ret;
585 }
586
587 \f
588 /* Insert the addend into the instruction. */
589 static bfd_reloc_status_type
590 v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
591 bfd * abfd;
592 arelent * reloc;
593 asymbol * symbol;
594 PTR data;
595 asection * isection;
596 bfd * obfd;
597 char ** err;
598 {
599 /* If there is an output BFD,
600 and the symbol is not a section name (which is only defined at final link time),
601 and either we are not putting the addend into the instruction
602 or the addend is zero, so there is nothing to add into the instruction
603 then just fixup the address and return. */
604 if (obfd != (bfd *) NULL
605 && (symbol->flags & BSF_SECTION_SYM) == 0
606 && (! reloc->howto->partial_inplace
607 || reloc->addend == 0))
608 {
609 reloc->address += isection->output_offset;
610 return bfd_reloc_ok;
611 }
612 #if 0
613 else if (obfd != NULL)
614 {
615 return bfd_reloc_continue;
616 }
617 #endif
618
619 /* Catch relocs involving undefined symbols. */
620 if (bfd_is_und_section (symbol->section)
621 && (symbol->flags & BSF_WEAK) == 0
622 && obfd == NULL)
623 return bfd_reloc_undefined;
624
625 /* We handle final linking of some relocs ourselves. */
626 {
627 long relocation, insn;
628
629 /* Is the address of the relocation really within the section? */
630 if (reloc->address > isection->_cooked_size)
631 return bfd_reloc_outofrange;
632
633 /* Work out which section the relocation is targetted at and the
634 initial relocation command value. */
635
636 /* Get symbol value. (Common symbols are special.) */
637 if (bfd_is_com_section (symbol->section))
638 relocation = 0;
639 else
640 relocation = symbol->value;
641
642 /* Convert input-section-relative symbol value to absolute + addend. */
643 relocation += symbol->section->output_section->vma;
644 relocation += symbol->section->output_offset;
645 relocation += reloc->addend;
646
647 if (reloc->howto->pc_relative == true)
648 {
649 /* Here the variable relocation holds the final address of the
650 symbol we are relocating against, plus any addend. */
651 relocation -= isection->output_section->vma + isection->output_offset;
652
653 /* Deal with pcrel_offset */
654 relocation -= reloc->address;
655 }
656
657 /* I've got no clue... */
658 reloc->addend = 0;
659
660 switch (reloc->howto->type)
661 {
662 default:
663 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", reloc->howto->type ); */
664 return bfd_reloc_notsupported;
665
666 case R_V850_22_PCREL:
667 if (relocation > 0x1ffff || relocation < -0x200000)
668 return bfd_reloc_overflow;
669
670 if ((relocation % 2) != 0)
671 return bfd_reloc_dangerous;
672
673 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
674 insn &= ~0xfffe003f;
675 insn |= (((relocation & 0xfffe) << 16)
676 | ((relocation & 0x3f0000) >> 16));
677 bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
678 return bfd_reloc_ok;
679
680 case R_V850_9_PCREL:
681 if (relocation > 0xff || relocation < -0x100)
682 return bfd_reloc_overflow;
683
684 if ((relocation % 2) != 0)
685 return bfd_reloc_dangerous;
686
687 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
688 insn &= ~ 0xf870;
689 insn |= ((relocation & 0x1f0) << 7) | ((relocation & 0x0e) << 3);
690 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
691 return bfd_reloc_ok;
692
693 case R_V850_HI16_S:
694 relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
695 relocation = (relocation >> 16) + ((relocation & 0x8000) != 0);
696 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
697 return bfd_reloc_ok;
698
699 case R_V850_HI16:
700 relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
701 relocation = (relocation >> 16);
702 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
703 return bfd_reloc_ok;
704
705 case R_V850_16:
706 case R_V850_LO16:
707 relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
708
709 case R_V850_SDA_16_16_OFFSET:
710 case R_V850_ZDA_16_16_OFFSET:
711 if ((long)relocation > 0x7fff || (long)relocation < -0x8000)
712 return bfd_reloc_overflow;
713 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
714 return bfd_reloc_ok;
715
716 case R_V850_SDA_15_16_OFFSET:
717 case R_V850_ZDA_15_16_OFFSET:
718 if ((long)relocation > 0x7ffe || (long)relocation < -0x8000)
719 return bfd_reloc_overflow;
720
721 if (relocation & 1)
722 return bfd_reloc_dangerous;
723
724 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
725 insn &= 1;
726 insn |= (relocation >> 1) & ~1;
727
728 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
729 return bfd_reloc_ok;
730
731 case R_V850_TDA_6_8_OFFSET:
732 if ((long) relocation > 0xfc || (long) relocation < 0)
733 return bfd_reloc_overflow;
734
735 if (relocation & 3)
736 return bfd_reloc_dangerous;
737
738 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
739 insn &= 0xff81;
740 insn |= (relocation >> 1);
741
742 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
743 return bfd_reloc_ok;
744
745 case R_V850_TDA_7_8_OFFSET:
746 if ((long) relocation > 0xfe || (long) relocation < 0)
747 return bfd_reloc_overflow;
748
749 if (relocation & 1)
750 return bfd_reloc_dangerous;
751
752 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
753 insn &= 0xff80;
754 insn |= (relocation >> 1);
755
756 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
757 return bfd_reloc_ok;
758
759 case R_V850_TDA_7_7_OFFSET:
760 if ((long) relocation > 0x7f || (long) relocation < 0)
761 return bfd_reloc_overflow;
762
763 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
764 insn &= 0xff80;
765 insn |= relocation;
766
767 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
768 return bfd_reloc_ok;
769
770 /* start-sanitize-v850e */
771 case R_V850_TDA_4_5_OFFSET:
772 if ((long) relocation > 0x1e || (long) relocation < 0)
773 return bfd_reloc_overflow;
774
775 if (relocation & 1)
776 return bfd_reloc_dangerous;
777
778 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
779 insn &= 0xfff0;
780 insn |= (relocation >> 1);
781
782 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
783 return bfd_reloc_ok;
784
785 case R_V850_TDA_4_4_OFFSET:
786 if ((long) relocation > 0xf || (long) relocation < 0)
787 return bfd_reloc_overflow;
788
789 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
790 insn &= 0xfff0;
791 insn |= relocation;
792
793 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
794 return bfd_reloc_ok;
795
796 case R_V850_ZDA_16_16_SPLIT_OFFSET:
797 case R_V850_SDA_16_16_SPLIT_OFFSET:
798 if ((long) relocation > 0xffff || (long) relocation < 0)
799 return bfd_reloc_overflow;
800
801 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
802
803 insn &= 0x0001ffdf;
804 insn |= (relocation & 1) << 5;
805 insn |= (relocation & ~1) << 16;
806
807 bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
808 return bfd_reloc_ok;
809 /* end-sanitize-v850e */
810 }
811 }
812
813 return bfd_reloc_continue;
814 }
815
816 \f
817 /*ARGSUSED*/
818 static boolean
819 v850_elf_is_local_label_name (abfd, name)
820 bfd *abfd;
821 const char *name;
822 {
823 return ((name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
824 || (name[0] == '_' && name[1] == '.' && name[2] == 'L'
825 && name[3] == '_'));
826 }
827
828 \f
829 /* Perform a relocation as part of a final link. */
830 static bfd_reloc_status_type
831 v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
832 input_section, contents, offset, value,
833 addend, info, sym_sec, is_local)
834 reloc_howto_type * howto;
835 bfd * input_bfd;
836 bfd * output_bfd;
837 asection * input_section;
838 bfd_byte * contents;
839 bfd_vma offset;
840 bfd_vma value;
841 bfd_vma addend;
842 struct bfd_link_info * info;
843 asection * sym_sec;
844 int is_local;
845 {
846 unsigned long insn;
847 unsigned long r_type = howto->type;
848 bfd_byte * hit_data = contents + offset;
849
850 switch (r_type)
851 {
852 case R_V850_9_PCREL:
853 value -= (input_section->output_section->vma
854 + input_section->output_offset);
855 value -= offset;
856
857 if ((long)value > 0xff || (long)value < -0x100)
858 return bfd_reloc_overflow;
859
860 if ((value % 2) != 0)
861 return bfd_reloc_dangerous;
862
863 insn = bfd_get_16 (input_bfd, hit_data);
864 insn &= 0x078f;
865 insn |= ((value & 0x1f0) << 7) | ((value & 0x0e) << 3);
866 bfd_put_16 (input_bfd, insn, hit_data);
867 return bfd_reloc_ok;
868
869 case R_V850_22_PCREL:
870 value -= (input_section->output_section->vma
871 + input_section->output_offset);
872 value -= offset;
873
874 if ((long)value > 0x1ffff || (long)value < -0x200000)
875 return bfd_reloc_overflow;
876
877 if ((value % 2) != 0)
878 return bfd_reloc_dangerous;
879
880 insn = bfd_get_32 (input_bfd, hit_data);
881 insn &= 0x1ffc0;
882 insn |= (((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
883 bfd_put_32 (input_bfd, insn, hit_data);
884 return bfd_reloc_ok;
885
886 case R_V850_HI16_S:
887 value += (short)bfd_get_16 (input_bfd, hit_data);
888 value = (value >> 16) + ((value & 0x8000) != 0);
889
890 if ((long)value > 0x7fff || (long)value < -0x8000)
891 return bfd_reloc_overflow;
892
893 bfd_put_16 (input_bfd, value, hit_data);
894 return bfd_reloc_ok;
895
896 case R_V850_HI16:
897 value += (short)bfd_get_16 (input_bfd, hit_data);
898 value >>= 16;
899
900 if ((long)value > 0x7fff || (long)value < -0x8000)
901 return bfd_reloc_overflow;
902
903 bfd_put_16 (input_bfd, value, hit_data);
904 return bfd_reloc_ok;
905
906 case R_V850_LO16:
907 value += (short)bfd_get_16 (input_bfd, hit_data);
908 value &= 0xffff;
909
910 bfd_put_16 (input_bfd, value, hit_data);
911 return bfd_reloc_ok;
912
913 case R_V850_16:
914 value += (short) bfd_get_16 (input_bfd, hit_data);
915
916 if ((long) value > 0x7fff || (long) value < -0x8000)
917 return bfd_reloc_overflow;
918
919 bfd_put_16 (input_bfd, value, hit_data);
920 return bfd_reloc_ok;
921
922 case R_V850_ZDA_16_16_OFFSET:
923 value -= sym_sec->output_section->vma;
924 value += (short) bfd_get_16 (input_bfd, hit_data);
925
926 if ((long) value > 0x7fff || (long) value < -0x8000)
927 return bfd_reloc_overflow;
928
929 bfd_put_16 (input_bfd, value, hit_data);
930 return bfd_reloc_ok;
931
932 case R_V850_ZDA_15_16_OFFSET:
933 insn = bfd_get_16 (input_bfd, hit_data);
934
935 value -= sym_sec->output_section->vma;
936 value += ((insn & 0xfffe) << 1);
937
938 if ((long) value > 0x7ffe || (long) value < -0x8000)
939 return bfd_reloc_overflow;
940
941 value &= ~1;
942 value |= (insn & 1);
943
944 bfd_put_16 (input_bfd, value, hit_data);
945 return bfd_reloc_ok;
946
947 case R_V850_32:
948 value += bfd_get_32 (input_bfd, hit_data);
949 bfd_put_32 (input_bfd, value, hit_data);
950 return bfd_reloc_ok;
951
952 case R_V850_8:
953 value += (char)bfd_get_8 (input_bfd, hit_data);
954
955 if ((long)value > 0x7f || (long)value < -0x80)
956 return bfd_reloc_overflow;
957
958 bfd_put_8 (input_bfd, value, hit_data);
959 return bfd_reloc_ok;
960
961 case R_V850_SDA_16_16_OFFSET:
962 {
963 unsigned long gp;
964 struct bfd_link_hash_entry * h;
965
966 /* Get the value of __gp. */
967 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
968 if (h == (struct bfd_link_hash_entry *) NULL
969 || h->type != bfd_link_hash_defined)
970 return bfd_reloc_other;
971
972 gp = (h->u.def.value
973 + h->u.def.section->output_section->vma
974 + h->u.def.section->output_offset);
975
976 value -= sym_sec->output_section->vma;
977 value -= (gp - sym_sec->output_section->vma);
978 value += (short) bfd_get_16 (input_bfd, hit_data);
979
980 if ((long)value > 0x7fff || (long)value < -0x8000)
981 return bfd_reloc_overflow;
982
983 bfd_put_16 (input_bfd, value, hit_data);
984 return bfd_reloc_ok;
985 }
986
987 case R_V850_SDA_15_16_OFFSET:
988 {
989 unsigned long gp;
990 struct bfd_link_hash_entry * h;
991
992 /* Get the value of __gp. */
993 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
994 if (h == (struct bfd_link_hash_entry *) NULL
995 || h->type != bfd_link_hash_defined)
996 return bfd_reloc_other;
997
998 gp = (h->u.def.value
999 + h->u.def.section->output_section->vma
1000 + h->u.def.section->output_offset);
1001
1002 value -= sym_sec->output_section->vma;
1003 value -= (gp - sym_sec->output_section->vma);
1004
1005 insn = bfd_get_16 (input_bfd, hit_data);
1006
1007 value += ((insn & 0xfffe) << 1);
1008
1009 if ((long)value > 0x7ffe || (long)value < -0x8000)
1010 return bfd_reloc_overflow;
1011
1012 value &= ~1;
1013 value |= (insn & 1);
1014
1015 bfd_put_16 (input_bfd, value, hit_data);
1016 return bfd_reloc_ok;
1017 }
1018
1019 case R_V850_TDA_6_8_OFFSET:
1020 {
1021 unsigned long ep;
1022 struct bfd_link_hash_entry * h;
1023
1024 insn = bfd_get_16 (input_bfd, hit_data);
1025
1026 /* Get the value of __ep. */
1027 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1028 if (h == (struct bfd_link_hash_entry *) NULL
1029 || h->type != bfd_link_hash_defined)
1030 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1031
1032 ep = (h->u.def.value
1033 + h->u.def.section->output_section->vma
1034 + h->u.def.section->output_offset);
1035
1036 value -= ep;
1037 value += ((insn & 0x7e) << 2);
1038
1039 if ((long) value > 0xfc || (long) value < 0)
1040 return bfd_reloc_overflow;
1041
1042 if ((value % 2) != 0)
1043 return bfd_reloc_dangerous;
1044
1045 insn &= 0xff81;
1046 insn |= (value >> 1);
1047
1048 bfd_put_16 (input_bfd, insn, hit_data);
1049 return bfd_reloc_ok;
1050 }
1051
1052 case R_V850_TDA_7_8_OFFSET:
1053 {
1054 unsigned long ep;
1055 struct bfd_link_hash_entry * h;
1056
1057 insn = bfd_get_16 (input_bfd, hit_data);
1058
1059 /* Get the value of __ep. */
1060 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1061 if (h == (struct bfd_link_hash_entry *) NULL
1062 || h->type != bfd_link_hash_defined)
1063 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1064
1065 ep = (h->u.def.value
1066 + h->u.def.section->output_section->vma
1067 + h->u.def.section->output_offset);
1068
1069 value -= ep;
1070 value += ((insn & 0x7f) << 1);
1071
1072 if ((long) value > 0xfe || (long) value < 0)
1073 return bfd_reloc_overflow;
1074
1075 insn &= 0xff80;
1076 insn |= (value >> 1);
1077
1078 bfd_put_16 (input_bfd, insn, hit_data);
1079 return bfd_reloc_ok;
1080 }
1081
1082 case R_V850_TDA_7_7_OFFSET:
1083 {
1084 unsigned long ep;
1085 struct bfd_link_hash_entry * h;
1086
1087 insn = bfd_get_16 (input_bfd, hit_data);
1088
1089 /* Get the value of __ep. */
1090 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1091 if (h == (struct bfd_link_hash_entry *) NULL
1092 || h->type != bfd_link_hash_defined)
1093 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1094
1095 ep = (h->u.def.value
1096 + h->u.def.section->output_section->vma
1097 + h->u.def.section->output_offset);
1098 value -= ep;
1099
1100 value += insn & 0x7f;
1101
1102 if ((long) value > 0x7f || (long) value < 0)
1103 return bfd_reloc_overflow;
1104
1105 insn &= 0xff80;
1106 insn |= value;
1107 bfd_put_16 (input_bfd, insn, hit_data);
1108 return bfd_reloc_ok;
1109 }
1110
1111 /* start-sanitize-v850e */
1112 case R_V850_TDA_4_5_OFFSET:
1113 {
1114 unsigned long ep;
1115 struct bfd_link_hash_entry * h;
1116
1117 /* Get the value of __ep. */
1118 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1119 if (h == (struct bfd_link_hash_entry *) NULL
1120 || h->type != bfd_link_hash_defined)
1121 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1122
1123 ep = (h->u.def.value
1124 + h->u.def.section->output_section->vma
1125 + h->u.def.section->output_offset);
1126 value -= ep;
1127
1128 insn = bfd_get_16 (input_bfd, hit_data);
1129
1130 value += ((insn & 0xf) << 1);
1131
1132 if ((long) value > 0x1e || (long) value < 0)
1133 return bfd_reloc_overflow;
1134
1135 insn &= 0xfff0;
1136 insn |= (value >> 1);
1137 bfd_put_16 (input_bfd, insn, hit_data);
1138 return bfd_reloc_ok;
1139 }
1140
1141 case R_V850_TDA_4_4_OFFSET:
1142 {
1143 unsigned long ep;
1144 struct bfd_link_hash_entry * h;
1145
1146 /* Get the value of __ep. */
1147 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1148 if (h == (struct bfd_link_hash_entry *) NULL
1149 || h->type != bfd_link_hash_defined)
1150 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1151
1152 ep = (h->u.def.value
1153 + h->u.def.section->output_section->vma
1154 + h->u.def.section->output_offset);
1155 value -= ep;
1156
1157 insn = bfd_get_16 (input_bfd, hit_data);
1158
1159 value += insn & 0xf;
1160
1161 if ((long) value > 0xf || (long) value < 0)
1162 return bfd_reloc_overflow;
1163
1164 insn &= 0xfff0;
1165 insn |= value;
1166 bfd_put_16 (input_bfd, insn, hit_data);
1167 return bfd_reloc_ok;
1168 }
1169
1170 case R_V850_SDA_16_16_SPLIT_OFFSET:
1171 {
1172 unsigned long gp;
1173 struct bfd_link_hash_entry * h;
1174
1175 /* Get the value of __gp. */
1176 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1177 if (h == (struct bfd_link_hash_entry *) NULL
1178 || h->type != bfd_link_hash_defined)
1179 return bfd_reloc_other;
1180
1181 gp = (h->u.def.value
1182 + h->u.def.section->output_section->vma
1183 + h->u.def.section->output_offset);
1184
1185 value -= sym_sec->output_section->vma;
1186 value -= (gp - sym_sec->output_section->vma);
1187
1188 insn = bfd_get_32 (input_bfd, hit_data);
1189
1190 value += ((insn & 0xfffe0000) >> 16);
1191 value += ((insn & 0x20) >> 5);
1192
1193 if ((long)value > 0x7fff || (long)value < -0x8000)
1194 return bfd_reloc_overflow;
1195
1196 insn &= 0x0001ffdf;
1197 insn |= (value & 1) << 5;
1198 insn |= (value & ~1) << 16;
1199
1200 bfd_put_32 (input_bfd, insn, hit_data);
1201 return bfd_reloc_ok;
1202 }
1203
1204 case R_V850_ZDA_16_16_SPLIT_OFFSET:
1205 insn = bfd_get_32 (input_bfd, hit_data);
1206
1207 value -= sym_sec->output_section->vma;
1208 value += ((insn & 0xfffe0000) >> 16);
1209 value += ((insn & 0x20) >> 5);
1210
1211 if ((long)value > 0x7fff || (long)value < -0x8000)
1212 return bfd_reloc_overflow;
1213
1214 insn &= 0x0001ffdf;
1215 insn |= (value & 1) << 5;
1216 insn |= (value & ~1) << 16;
1217
1218 bfd_put_32 (input_bfd, insn, hit_data);
1219 return bfd_reloc_ok;
1220
1221 /* end-sanitize-v850e */
1222
1223
1224 case R_V850_NONE:
1225 return bfd_reloc_ok;
1226
1227 default:
1228 return bfd_reloc_notsupported;
1229 }
1230 }
1231
1232 \f
1233 /* Relocate an V850 ELF section. */
1234 static boolean
1235 v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1236 contents, relocs, local_syms, local_sections)
1237 bfd * output_bfd;
1238 struct bfd_link_info * info;
1239 bfd * input_bfd;
1240 asection * input_section;
1241 bfd_byte * contents;
1242 Elf_Internal_Rela * relocs;
1243 Elf_Internal_Sym * local_syms;
1244 asection ** local_sections;
1245 {
1246 Elf_Internal_Shdr * symtab_hdr;
1247 struct elf_link_hash_entry ** sym_hashes;
1248 Elf_Internal_Rela * rel;
1249 Elf_Internal_Rela * relend;
1250
1251 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1252 sym_hashes = elf_sym_hashes (input_bfd);
1253
1254 rel = relocs;
1255 relend = relocs + input_section->reloc_count;
1256 for (; rel < relend; rel++)
1257 {
1258 int r_type;
1259 reloc_howto_type * howto;
1260 unsigned long r_symndx;
1261 Elf_Internal_Sym * sym;
1262 asection * sec;
1263 struct elf_link_hash_entry * h;
1264 bfd_vma relocation;
1265 bfd_reloc_status_type r;
1266
1267 r_symndx = ELF32_R_SYM (rel->r_info);
1268 r_type = ELF32_R_TYPE (rel->r_info);
1269 howto = v850_elf_howto_table + r_type;
1270
1271 if (info->relocateable)
1272 {
1273 /* This is a relocateable link. We don't have to change
1274 anything, unless the reloc is against a section symbol,
1275 in which case we have to adjust according to where the
1276 section symbol winds up in the output section. */
1277 if (r_symndx < symtab_hdr->sh_info)
1278 {
1279 sym = local_syms + r_symndx;
1280 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1281 {
1282 sec = local_sections[r_symndx];
1283 rel->r_addend += sec->output_offset + sym->st_value;
1284 }
1285 }
1286
1287 continue;
1288 }
1289
1290 /* This is a final link. */
1291 h = NULL;
1292 sym = NULL;
1293 sec = NULL;
1294 if (r_symndx < symtab_hdr->sh_info)
1295 {
1296 sym = local_syms + r_symndx;
1297 sec = local_sections[r_symndx];
1298 relocation = (sec->output_section->vma
1299 + sec->output_offset
1300 + sym->st_value);
1301 #if 0
1302 {
1303 char * name;
1304 name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1305 name = (name == NULL) ? "<none>" : name;
1306 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x rel %x\n", sec->name, name, sym->st_name,
1307 sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend, rel);
1308 }
1309 #endif
1310 }
1311 else
1312 {
1313 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1314
1315 while (h->root.type == bfd_link_hash_indirect
1316 || h->root.type == bfd_link_hash_warning)
1317 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1318
1319 if (h->root.type == bfd_link_hash_defined
1320 || h->root.type == bfd_link_hash_defweak)
1321 {
1322 sec = h->root.u.def.section;
1323 relocation = (h->root.u.def.value
1324 + sec->output_section->vma
1325 + sec->output_offset);
1326 }
1327 else if (h->root.type == bfd_link_hash_undefweak)
1328 relocation = 0;
1329 else
1330 {
1331 if (! ((*info->callbacks->undefined_symbol)
1332 (info, h->root.root.string, input_bfd,
1333 input_section, rel->r_offset)))
1334 return false;
1335 relocation = 0;
1336 }
1337 }
1338
1339 /* FIXME: We should use the addend, but the COFF relocations
1340 don't. */
1341 r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1342 input_section,
1343 contents, rel->r_offset,
1344 relocation, rel->r_addend,
1345 info, sec, h == NULL);
1346
1347 if (r != bfd_reloc_ok)
1348 {
1349 const char * name;
1350 const char * msg = (const char *)0;
1351
1352 if (h != NULL)
1353 name = h->root.root.string;
1354 else
1355 {
1356 name = (bfd_elf_string_from_elf_section
1357 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1358 if (name == NULL || *name == '\0')
1359 name = bfd_section_name (input_bfd, sec);
1360 }
1361
1362 switch (r)
1363 {
1364 case bfd_reloc_overflow:
1365 if (! ((*info->callbacks->reloc_overflow)
1366 (info, name, howto->name, (bfd_vma) 0,
1367 input_bfd, input_section, rel->r_offset)))
1368 return false;
1369 break;
1370
1371 case bfd_reloc_undefined:
1372 fprintf (stderr, "undef2 %s\n", name );
1373 if (! ((*info->callbacks->undefined_symbol)
1374 (info, name, input_bfd, input_section,
1375 rel->r_offset)))
1376 return false;
1377 break;
1378
1379 case bfd_reloc_outofrange:
1380 msg = "internal error: out of range error";
1381 goto common_error;
1382
1383 case bfd_reloc_notsupported:
1384 msg = "internal error: unsupported relocation error";
1385 goto common_error;
1386
1387 case bfd_reloc_dangerous:
1388 msg = "internal error: dangerous relocation";
1389 goto common_error;
1390
1391 case bfd_reloc_other:
1392 msg = "could not locate special linker symbol __gp";
1393 goto common_error;
1394
1395 case bfd_reloc_continue:
1396 msg = "could not locate special linker symbol __ep";
1397 goto common_error;
1398
1399 default:
1400 msg = "internal error: unknown error";
1401 /* fall through */
1402
1403 common_error:
1404 if (!((*info->callbacks->warning)
1405 (info, msg, name, input_bfd, input_section,
1406 rel->r_offset)))
1407 return false;
1408 break;
1409 }
1410 }
1411 }
1412
1413 return true;
1414 }
1415
1416 /* Set the right machine number. */
1417 static boolean
1418 v850_elf_object_p (abfd)
1419 bfd *abfd;
1420 {
1421 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1422 {
1423 default:
1424 case E_V850_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
1425 /* start-sanitize-v850e */
1426 case E_V850E_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
1427 /* end-sanitize-v850e */
1428 /* start-sanitize-v850eq */
1429 case E_V850EQ_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850eq); break;
1430 /* start-sanitize-v850eq */
1431 }
1432 }
1433
1434 /* Store the machine number in the flags field. */
1435 void
1436 v850_elf_final_write_processing (abfd, linker)
1437 bfd * abfd;
1438 boolean linker;
1439 {
1440 unsigned long val;
1441
1442 switch (bfd_get_mach (abfd))
1443 {
1444 default:
1445 case 0: val = E_V850_ARCH; break;
1446 /* start-sanitize-v850e */
1447 case bfd_mach_v850e: val = E_V850E_ARCH; break;
1448 /* end-sanitize-v850e */
1449 /* start-sanitize-v850eq */
1450 case bfd_mach_v850eq: val = E_V850EQ_ARCH; break;
1451 /* end-sanitize-v850eq */
1452 }
1453
1454 elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1455 elf_elfheader (abfd)->e_flags |= val;
1456 }
1457
1458 /* Function to keep V850 specific file flags. */
1459 boolean
1460 v850_elf_set_private_flags (abfd, flags)
1461 bfd * abfd;
1462 flagword flags;
1463 {
1464 BFD_ASSERT (!elf_flags_init (abfd)
1465 || elf_elfheader (abfd)->e_flags == flags);
1466
1467 elf_elfheader (abfd)->e_flags = flags;
1468 elf_flags_init (abfd) = true;
1469 return true;
1470 }
1471
1472 /* Copy backend specific data from one object module to another */
1473 boolean
1474 v850_elf_copy_private_bfd_data (ibfd, obfd)
1475 bfd * ibfd;
1476 bfd * obfd;
1477 {
1478 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1479 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1480 return true;
1481
1482 BFD_ASSERT (!elf_flags_init (obfd)
1483 || (elf_elfheader (obfd)->e_flags
1484 == elf_elfheader (ibfd)->e_flags));
1485
1486 elf_gp (obfd) = elf_gp (ibfd);
1487 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1488 elf_flags_init (obfd) = true;
1489 return true;
1490 }
1491
1492 /* Merge backend specific data from an object file to the output
1493 object file when linking. */
1494 boolean
1495 v850_elf_merge_private_bfd_data (ibfd, obfd)
1496 bfd * ibfd;
1497 bfd * obfd;
1498 {
1499 flagword old_flags;
1500 flagword new_flags;
1501
1502 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1503 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1504 return true;
1505
1506 new_flags = elf_elfheader (ibfd)->e_flags;
1507 old_flags = elf_elfheader (obfd)->e_flags;
1508
1509 if (! elf_flags_init (obfd))
1510 {
1511 elf_flags_init (obfd) = true;
1512 elf_elfheader (obfd)->e_flags = new_flags;
1513
1514 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1515 && bfd_get_arch_info (obfd)->the_default)
1516 {
1517 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1518 }
1519
1520 return true;
1521 }
1522
1523 /* Check flag compatibility. */
1524
1525 if (new_flags == old_flags)
1526 return true;
1527
1528 if ((new_flags & EF_V850_ARCH) != (old_flags & EF_V850_ARCH))
1529 {
1530 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1531 bfd_get_filename (ibfd));
1532 bfd_set_error (bfd_error_bad_value);
1533 return false;
1534 }
1535
1536 return true;
1537 }
1538 /* Display the flags field */
1539
1540 static boolean
1541 v850_elf_print_private_bfd_data (abfd, ptr)
1542 bfd * abfd;
1543 PTR ptr;
1544 {
1545 FILE * file = (FILE *) ptr;
1546
1547 BFD_ASSERT (abfd != NULL && ptr != NULL)
1548
1549 fprintf (file, "private flags = %x", elf_elfheader (abfd)->e_flags);
1550
1551 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1552 {
1553 default:
1554 case E_V850_ARCH: fprintf (file, ": v850 architecture"); break;
1555 /* start-sanitize-v850e */
1556 case E_V850E_ARCH: fprintf (file, ": v850e architecture"); break;
1557 /* end-sanitize-v850e */
1558 /* start-sanitize-v850eq */
1559 case E_V850EQ_ARCH: fprintf (file, ": v850eq architecture"); break;
1560 /* end-sanitize-v850eq */
1561 }
1562
1563 fputc ('\n', file);
1564
1565 return true;
1566 }
1567 \f
1568 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
1569 #define TARGET_LITTLE_NAME "elf32-v850"
1570 #define ELF_ARCH bfd_arch_v850
1571 #define ELF_MACHINE_CODE EM_CYGNUS_V850
1572 #define ELF_MAXPAGESIZE 0x1000
1573
1574 #define elf_info_to_howto 0
1575 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
1576 #define elf_backend_check_relocs v850_elf_check_relocs
1577 #define elf_backend_relocate_section v850_elf_relocate_section
1578 #define elf_backend_object_p v850_elf_object_p
1579 #define elf_backend_final_write_processing v850_elf_final_write_processing
1580 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
1581 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
1582 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
1583 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
1584 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
1585 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
1586
1587 #define elf_symbol_leading_char '_'
1588
1589 #include "elf32-target.h"