Do not complain if an R_V850_LO16 reloc has bit 15 set.
[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 long relocation;
600 long insn;
601
602
603 /* If there is an output BFD,
604 and the symbol is not a section name (which is only defined at final link time),
605 and either we are not putting the addend into the instruction
606 or the addend is zero, so there is nothing to add into the instruction
607 then just fixup the address and return. */
608 if (obfd != (bfd *) NULL
609 && (symbol->flags & BSF_SECTION_SYM) == 0
610 && (! reloc->howto->partial_inplace
611 || reloc->addend == 0))
612 {
613 reloc->address += isection->output_offset;
614 return bfd_reloc_ok;
615 }
616 #if 0
617 else if (obfd != NULL)
618 {
619 return bfd_reloc_continue;
620 }
621 #endif
622
623 /* Catch relocs involving undefined symbols. */
624 if (bfd_is_und_section (symbol->section)
625 && (symbol->flags & BSF_WEAK) == 0
626 && obfd == NULL)
627 return bfd_reloc_undefined;
628
629 /* We handle final linking of some relocs ourselves. */
630
631 /* Is the address of the relocation really within the section? */
632 if (reloc->address > isection->_cooked_size)
633 return bfd_reloc_outofrange;
634
635 /* Work out which section the relocation is targetted at and the
636 initial relocation command value. */
637
638 /* Get symbol value. (Common symbols are special.) */
639 if (bfd_is_com_section (symbol->section))
640 relocation = 0;
641 else
642 relocation = symbol->value;
643
644 /* Convert input-section-relative symbol value to absolute + addend. */
645 relocation += symbol->section->output_section->vma;
646 relocation += symbol->section->output_offset;
647 relocation += reloc->addend;
648
649 if (reloc->howto->pc_relative == true)
650 {
651 /* Here the variable relocation holds the final address of the
652 symbol we are relocating against, plus any addend. */
653 relocation -= isection->output_section->vma + isection->output_offset;
654
655 /* Deal with pcrel_offset */
656 relocation -= reloc->address;
657 }
658
659 /* I've got no clue... */
660 reloc->addend = 0;
661
662 switch (reloc->howto->type)
663 {
664 default:
665 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", reloc->howto->type ); */
666 return bfd_reloc_notsupported;
667
668 case R_V850_22_PCREL:
669 if (relocation > 0x1ffff || relocation < -0x200000)
670 return bfd_reloc_overflow;
671
672 if ((relocation % 2) != 0)
673 return bfd_reloc_dangerous;
674
675 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
676 insn &= ~0xfffe003f;
677 insn |= (((relocation & 0xfffe) << 16)
678 | ((relocation & 0x3f0000) >> 16));
679 bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
680 return bfd_reloc_ok;
681
682 case R_V850_9_PCREL:
683 if (relocation > 0xff || relocation < -0x100)
684 return bfd_reloc_overflow;
685
686 if ((relocation % 2) != 0)
687 return bfd_reloc_dangerous;
688
689 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
690 insn &= ~ 0xf870;
691 insn |= ((relocation & 0x1f0) << 7) | ((relocation & 0x0e) << 3);
692 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
693 return bfd_reloc_ok;
694
695 case R_V850_HI16_S:
696 relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
697 relocation = (relocation >> 16) + ((relocation & 0x8000) != 0);
698 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
699 return bfd_reloc_ok;
700
701 case R_V850_HI16:
702 relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
703 relocation = (relocation >> 16);
704 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
705 return bfd_reloc_ok;
706
707 case R_V850_LO16:
708 relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
709 /* Do not complain if value has top bit set, as this has been anticipated. */
710 if ((unsigned long)relocation > 0xffff)
711 return bfd_reloc_overflow;
712 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
713 return bfd_reloc_ok;
714
715 case R_V850_16:
716 relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
717 /* drop through */
718
719 case R_V850_SDA_16_16_OFFSET:
720 case R_V850_ZDA_16_16_OFFSET:
721 if ((long)relocation > 0x7fff || (long)relocation < -0x8000)
722 return bfd_reloc_overflow;
723 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
724 return bfd_reloc_ok;
725
726 case R_V850_SDA_15_16_OFFSET:
727 case R_V850_ZDA_15_16_OFFSET:
728 if ((long)relocation > 0x7ffe || (long)relocation < -0x8000)
729 return bfd_reloc_overflow;
730
731 if (relocation & 1)
732 return bfd_reloc_dangerous;
733
734 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
735 insn &= 1;
736 insn |= (relocation >> 1) & ~1;
737
738 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
739 return bfd_reloc_ok;
740
741 case R_V850_TDA_6_8_OFFSET:
742 if ((long) relocation > 0xfc || (long) relocation < 0)
743 return bfd_reloc_overflow;
744
745 if (relocation & 3)
746 return bfd_reloc_dangerous;
747
748 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
749 insn &= 0xff81;
750 insn |= (relocation >> 1);
751
752 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
753 return bfd_reloc_ok;
754
755 case R_V850_TDA_7_8_OFFSET:
756 if ((long) relocation > 0xfe || (long) relocation < 0)
757 return bfd_reloc_overflow;
758
759 if (relocation & 1)
760 return bfd_reloc_dangerous;
761
762 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
763 insn &= 0xff80;
764 insn |= (relocation >> 1);
765
766 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
767 return bfd_reloc_ok;
768
769 case R_V850_TDA_7_7_OFFSET:
770 if ((long) relocation > 0x7f || (long) relocation < 0)
771 return bfd_reloc_overflow;
772
773 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
774 insn &= 0xff80;
775 insn |= relocation;
776
777 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
778 return bfd_reloc_ok;
779
780 /* start-sanitize-v850e */
781 case R_V850_TDA_4_5_OFFSET:
782 if ((long) relocation > 0x1e || (long) relocation < 0)
783 return bfd_reloc_overflow;
784
785 if (relocation & 1)
786 return bfd_reloc_dangerous;
787
788 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
789 insn &= 0xfff0;
790 insn |= (relocation >> 1);
791
792 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
793 return bfd_reloc_ok;
794
795 case R_V850_TDA_4_4_OFFSET:
796 if ((long) relocation > 0xf || (long) relocation < 0)
797 return bfd_reloc_overflow;
798
799 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
800 insn &= 0xfff0;
801 insn |= relocation;
802
803 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
804 return bfd_reloc_ok;
805
806 case R_V850_ZDA_16_16_SPLIT_OFFSET:
807 case R_V850_SDA_16_16_SPLIT_OFFSET:
808 if ((long) relocation > 0xffff || (long) relocation < 0)
809 return bfd_reloc_overflow;
810
811 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
812
813 insn &= 0x0001ffdf;
814 insn |= (relocation & 1) << 5;
815 insn |= (relocation & ~1) << 16;
816
817 bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
818 return bfd_reloc_ok;
819 /* end-sanitize-v850e */
820 }
821
822 return bfd_reloc_continue;
823 }
824
825 \f
826 /*ARGSUSED*/
827 static boolean
828 v850_elf_is_local_label_name (abfd, name)
829 bfd *abfd;
830 const char *name;
831 {
832 return ((name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
833 || (name[0] == '_' && name[1] == '.' && name[2] == 'L'
834 && name[3] == '_'));
835 }
836
837 \f
838 /* Perform a relocation as part of a final link. */
839 static bfd_reloc_status_type
840 v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
841 input_section, contents, offset, value,
842 addend, info, sym_sec, is_local)
843 reloc_howto_type * howto;
844 bfd * input_bfd;
845 bfd * output_bfd;
846 asection * input_section;
847 bfd_byte * contents;
848 bfd_vma offset;
849 bfd_vma value;
850 bfd_vma addend;
851 struct bfd_link_info * info;
852 asection * sym_sec;
853 int is_local;
854 {
855 unsigned long insn;
856 unsigned long r_type = howto->type;
857 bfd_byte * hit_data = contents + offset;
858
859 switch (r_type)
860 {
861 case R_V850_9_PCREL:
862 value -= (input_section->output_section->vma
863 + input_section->output_offset);
864 value -= offset;
865
866 if ((long)value > 0xff || (long)value < -0x100)
867 return bfd_reloc_overflow;
868
869 if ((value % 2) != 0)
870 return bfd_reloc_dangerous;
871
872 insn = bfd_get_16 (input_bfd, hit_data);
873 insn &= 0x078f;
874 insn |= ((value & 0x1f0) << 7) | ((value & 0x0e) << 3);
875 bfd_put_16 (input_bfd, insn, hit_data);
876 return bfd_reloc_ok;
877
878 case R_V850_22_PCREL:
879 value -= (input_section->output_section->vma
880 + input_section->output_offset);
881 value -= offset;
882
883 if ((long)value > 0x1ffff || (long)value < -0x200000)
884 return bfd_reloc_overflow;
885
886 if ((value % 2) != 0)
887 return bfd_reloc_dangerous;
888
889 insn = bfd_get_32 (input_bfd, hit_data);
890 insn &= 0x1ffc0;
891 insn |= (((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
892 bfd_put_32 (input_bfd, insn, hit_data);
893 return bfd_reloc_ok;
894
895 case R_V850_HI16_S:
896 value += (short)bfd_get_16 (input_bfd, hit_data);
897 value = (value >> 16) + ((value & 0x8000) != 0);
898
899 if ((long)value > 0x7fff || (long)value < -0x8000)
900 return bfd_reloc_overflow;
901
902 bfd_put_16 (input_bfd, value, hit_data);
903 return bfd_reloc_ok;
904
905 case R_V850_HI16:
906 value += (short)bfd_get_16 (input_bfd, hit_data);
907 value >>= 16;
908
909 if ((long)value > 0x7fff || (long)value < -0x8000)
910 return bfd_reloc_overflow;
911
912 bfd_put_16 (input_bfd, value, hit_data);
913 return bfd_reloc_ok;
914
915 case R_V850_LO16:
916 value += (short)bfd_get_16 (input_bfd, hit_data);
917 value &= 0xffff;
918
919 bfd_put_16 (input_bfd, value, hit_data);
920 return bfd_reloc_ok;
921
922 case R_V850_16:
923 value += (short) bfd_get_16 (input_bfd, hit_data);
924
925 if ((long) value > 0x7fff || (long) value < -0x8000)
926 return bfd_reloc_overflow;
927
928 bfd_put_16 (input_bfd, value, hit_data);
929 return bfd_reloc_ok;
930
931 case R_V850_ZDA_16_16_OFFSET:
932 value -= sym_sec->output_section->vma;
933 value += (short) bfd_get_16 (input_bfd, hit_data);
934
935 if ((long) value > 0x7fff || (long) value < -0x8000)
936 return bfd_reloc_overflow;
937
938 bfd_put_16 (input_bfd, value, hit_data);
939 return bfd_reloc_ok;
940
941 case R_V850_ZDA_15_16_OFFSET:
942 insn = bfd_get_16 (input_bfd, hit_data);
943
944 value -= sym_sec->output_section->vma;
945 value += ((insn & 0xfffe) << 1);
946
947 if ((long) value > 0x7ffe || (long) value < -0x8000)
948 return bfd_reloc_overflow;
949
950 value &= ~1;
951 value |= (insn & 1);
952
953 bfd_put_16 (input_bfd, value, hit_data);
954 return bfd_reloc_ok;
955
956 case R_V850_32:
957 value += bfd_get_32 (input_bfd, hit_data);
958 bfd_put_32 (input_bfd, value, hit_data);
959 return bfd_reloc_ok;
960
961 case R_V850_8:
962 value += (char)bfd_get_8 (input_bfd, hit_data);
963
964 if ((long)value > 0x7f || (long)value < -0x80)
965 return bfd_reloc_overflow;
966
967 bfd_put_8 (input_bfd, value, hit_data);
968 return bfd_reloc_ok;
969
970 case R_V850_SDA_16_16_OFFSET:
971 {
972 unsigned long gp;
973 struct bfd_link_hash_entry * h;
974
975 /* Get the value of __gp. */
976 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
977 if (h == (struct bfd_link_hash_entry *) NULL
978 || h->type != bfd_link_hash_defined)
979 return bfd_reloc_other;
980
981 gp = (h->u.def.value
982 + h->u.def.section->output_section->vma
983 + h->u.def.section->output_offset);
984
985 value -= sym_sec->output_section->vma;
986 value -= (gp - sym_sec->output_section->vma);
987 value += (short) bfd_get_16 (input_bfd, hit_data);
988
989 if ((long)value > 0x7fff || (long)value < -0x8000)
990 return bfd_reloc_overflow;
991
992 bfd_put_16 (input_bfd, value, hit_data);
993 return bfd_reloc_ok;
994 }
995
996 case R_V850_SDA_15_16_OFFSET:
997 {
998 unsigned long gp;
999 struct bfd_link_hash_entry * h;
1000
1001 /* Get the value of __gp. */
1002 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1003 if (h == (struct bfd_link_hash_entry *) NULL
1004 || h->type != bfd_link_hash_defined)
1005 return bfd_reloc_other;
1006
1007 gp = (h->u.def.value
1008 + h->u.def.section->output_section->vma
1009 + h->u.def.section->output_offset);
1010
1011 value -= sym_sec->output_section->vma;
1012 value -= (gp - sym_sec->output_section->vma);
1013
1014 insn = bfd_get_16 (input_bfd, hit_data);
1015
1016 value += ((insn & 0xfffe) << 1);
1017
1018 if ((long)value > 0x7ffe || (long)value < -0x8000)
1019 return bfd_reloc_overflow;
1020
1021 value &= ~1;
1022 value |= (insn & 1);
1023
1024 bfd_put_16 (input_bfd, value, hit_data);
1025 return bfd_reloc_ok;
1026 }
1027
1028 case R_V850_TDA_6_8_OFFSET:
1029 {
1030 unsigned long ep;
1031 struct bfd_link_hash_entry * h;
1032
1033 insn = bfd_get_16 (input_bfd, hit_data);
1034
1035 /* Get the value of __ep. */
1036 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1037 if (h == (struct bfd_link_hash_entry *) NULL
1038 || h->type != bfd_link_hash_defined)
1039 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1040
1041 ep = (h->u.def.value
1042 + h->u.def.section->output_section->vma
1043 + h->u.def.section->output_offset);
1044
1045 value -= ep;
1046 value += ((insn & 0x7e) << 2);
1047
1048 if ((long) value > 0xfc || (long) value < 0)
1049 return bfd_reloc_overflow;
1050
1051 if ((value % 2) != 0)
1052 return bfd_reloc_dangerous;
1053
1054 insn &= 0xff81;
1055 insn |= (value >> 1);
1056
1057 bfd_put_16 (input_bfd, insn, hit_data);
1058 return bfd_reloc_ok;
1059 }
1060
1061 case R_V850_TDA_7_8_OFFSET:
1062 {
1063 unsigned long ep;
1064 struct bfd_link_hash_entry * h;
1065
1066 insn = bfd_get_16 (input_bfd, hit_data);
1067
1068 /* Get the value of __ep. */
1069 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1070 if (h == (struct bfd_link_hash_entry *) NULL
1071 || h->type != bfd_link_hash_defined)
1072 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1073
1074 ep = (h->u.def.value
1075 + h->u.def.section->output_section->vma
1076 + h->u.def.section->output_offset);
1077
1078 value -= ep;
1079 value += ((insn & 0x7f) << 1);
1080
1081 if ((long) value > 0xfe || (long) value < 0)
1082 return bfd_reloc_overflow;
1083
1084 insn &= 0xff80;
1085 insn |= (value >> 1);
1086
1087 bfd_put_16 (input_bfd, insn, hit_data);
1088 return bfd_reloc_ok;
1089 }
1090
1091 case R_V850_TDA_7_7_OFFSET:
1092 {
1093 unsigned long ep;
1094 struct bfd_link_hash_entry * h;
1095
1096 insn = bfd_get_16 (input_bfd, hit_data);
1097
1098 /* Get the value of __ep. */
1099 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1100 if (h == (struct bfd_link_hash_entry *) NULL
1101 || h->type != bfd_link_hash_defined)
1102 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1103
1104 ep = (h->u.def.value
1105 + h->u.def.section->output_section->vma
1106 + h->u.def.section->output_offset);
1107 value -= ep;
1108
1109 value += insn & 0x7f;
1110
1111 if ((long) value > 0x7f || (long) value < 0)
1112 return bfd_reloc_overflow;
1113
1114 insn &= 0xff80;
1115 insn |= value;
1116 bfd_put_16 (input_bfd, insn, hit_data);
1117 return bfd_reloc_ok;
1118 }
1119
1120 /* start-sanitize-v850e */
1121 case R_V850_TDA_4_5_OFFSET:
1122 {
1123 unsigned long ep;
1124 struct bfd_link_hash_entry * h;
1125
1126 /* Get the value of __ep. */
1127 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1128 if (h == (struct bfd_link_hash_entry *) NULL
1129 || h->type != bfd_link_hash_defined)
1130 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1131
1132 ep = (h->u.def.value
1133 + h->u.def.section->output_section->vma
1134 + h->u.def.section->output_offset);
1135 value -= ep;
1136
1137 insn = bfd_get_16 (input_bfd, hit_data);
1138
1139 value += ((insn & 0xf) << 1);
1140
1141 if ((long) value > 0x1e || (long) value < 0)
1142 return bfd_reloc_overflow;
1143
1144 insn &= 0xfff0;
1145 insn |= (value >> 1);
1146 bfd_put_16 (input_bfd, insn, hit_data);
1147 return bfd_reloc_ok;
1148 }
1149
1150 case R_V850_TDA_4_4_OFFSET:
1151 {
1152 unsigned long ep;
1153 struct bfd_link_hash_entry * h;
1154
1155 /* Get the value of __ep. */
1156 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1157 if (h == (struct bfd_link_hash_entry *) NULL
1158 || h->type != bfd_link_hash_defined)
1159 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1160
1161 ep = (h->u.def.value
1162 + h->u.def.section->output_section->vma
1163 + h->u.def.section->output_offset);
1164 value -= ep;
1165
1166 insn = bfd_get_16 (input_bfd, hit_data);
1167
1168 value += insn & 0xf;
1169
1170 if ((long) value > 0xf || (long) value < 0)
1171 return bfd_reloc_overflow;
1172
1173 insn &= 0xfff0;
1174 insn |= value;
1175 bfd_put_16 (input_bfd, insn, hit_data);
1176 return bfd_reloc_ok;
1177 }
1178
1179 case R_V850_SDA_16_16_SPLIT_OFFSET:
1180 {
1181 unsigned long gp;
1182 struct bfd_link_hash_entry * h;
1183
1184 /* Get the value of __gp. */
1185 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1186 if (h == (struct bfd_link_hash_entry *) NULL
1187 || h->type != bfd_link_hash_defined)
1188 return bfd_reloc_other;
1189
1190 gp = (h->u.def.value
1191 + h->u.def.section->output_section->vma
1192 + h->u.def.section->output_offset);
1193
1194 value -= sym_sec->output_section->vma;
1195 value -= (gp - sym_sec->output_section->vma);
1196
1197 insn = bfd_get_32 (input_bfd, hit_data);
1198
1199 value += ((insn & 0xfffe0000) >> 16);
1200 value += ((insn & 0x20) >> 5);
1201
1202 if ((long)value > 0x7fff || (long)value < -0x8000)
1203 return bfd_reloc_overflow;
1204
1205 insn &= 0x0001ffdf;
1206 insn |= (value & 1) << 5;
1207 insn |= (value & ~1) << 16;
1208
1209 bfd_put_32 (input_bfd, insn, hit_data);
1210 return bfd_reloc_ok;
1211 }
1212
1213 case R_V850_ZDA_16_16_SPLIT_OFFSET:
1214 insn = bfd_get_32 (input_bfd, hit_data);
1215
1216 value -= sym_sec->output_section->vma;
1217 value += ((insn & 0xfffe0000) >> 16);
1218 value += ((insn & 0x20) >> 5);
1219
1220 if ((long)value > 0x7fff || (long)value < -0x8000)
1221 return bfd_reloc_overflow;
1222
1223 insn &= 0x0001ffdf;
1224 insn |= (value & 1) << 5;
1225 insn |= (value & ~1) << 16;
1226
1227 bfd_put_32 (input_bfd, insn, hit_data);
1228 return bfd_reloc_ok;
1229
1230 /* end-sanitize-v850e */
1231
1232
1233 case R_V850_NONE:
1234 return bfd_reloc_ok;
1235
1236 default:
1237 return bfd_reloc_notsupported;
1238 }
1239 }
1240
1241 \f
1242 /* Relocate an V850 ELF section. */
1243 static boolean
1244 v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1245 contents, relocs, local_syms, local_sections)
1246 bfd * output_bfd;
1247 struct bfd_link_info * info;
1248 bfd * input_bfd;
1249 asection * input_section;
1250 bfd_byte * contents;
1251 Elf_Internal_Rela * relocs;
1252 Elf_Internal_Sym * local_syms;
1253 asection ** local_sections;
1254 {
1255 Elf_Internal_Shdr * symtab_hdr;
1256 struct elf_link_hash_entry ** sym_hashes;
1257 Elf_Internal_Rela * rel;
1258 Elf_Internal_Rela * relend;
1259
1260 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1261 sym_hashes = elf_sym_hashes (input_bfd);
1262
1263 rel = relocs;
1264 relend = relocs + input_section->reloc_count;
1265 for (; rel < relend; rel++)
1266 {
1267 int r_type;
1268 reloc_howto_type * howto;
1269 unsigned long r_symndx;
1270 Elf_Internal_Sym * sym;
1271 asection * sec;
1272 struct elf_link_hash_entry * h;
1273 bfd_vma relocation;
1274 bfd_reloc_status_type r;
1275
1276 r_symndx = ELF32_R_SYM (rel->r_info);
1277 r_type = ELF32_R_TYPE (rel->r_info);
1278 howto = v850_elf_howto_table + r_type;
1279
1280 if (info->relocateable)
1281 {
1282 /* This is a relocateable link. We don't have to change
1283 anything, unless the reloc is against a section symbol,
1284 in which case we have to adjust according to where the
1285 section symbol winds up in the output section. */
1286 if (r_symndx < symtab_hdr->sh_info)
1287 {
1288 sym = local_syms + r_symndx;
1289 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1290 {
1291 sec = local_sections[r_symndx];
1292 rel->r_addend += sec->output_offset + sym->st_value;
1293 }
1294 }
1295
1296 continue;
1297 }
1298
1299 /* This is a final link. */
1300 h = NULL;
1301 sym = NULL;
1302 sec = NULL;
1303 if (r_symndx < symtab_hdr->sh_info)
1304 {
1305 sym = local_syms + r_symndx;
1306 sec = local_sections[r_symndx];
1307 relocation = (sec->output_section->vma
1308 + sec->output_offset
1309 + sym->st_value);
1310 #if 0
1311 {
1312 char * name;
1313 name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1314 name = (name == NULL) ? "<none>" : name;
1315 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x rel %x\n", sec->name, name, sym->st_name,
1316 sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend, rel);
1317 }
1318 #endif
1319 }
1320 else
1321 {
1322 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1323
1324 while (h->root.type == bfd_link_hash_indirect
1325 || h->root.type == bfd_link_hash_warning)
1326 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1327
1328 if (h->root.type == bfd_link_hash_defined
1329 || h->root.type == bfd_link_hash_defweak)
1330 {
1331 sec = h->root.u.def.section;
1332 relocation = (h->root.u.def.value
1333 + sec->output_section->vma
1334 + sec->output_offset);
1335 }
1336 else if (h->root.type == bfd_link_hash_undefweak)
1337 relocation = 0;
1338 else
1339 {
1340 if (! ((*info->callbacks->undefined_symbol)
1341 (info, h->root.root.string, input_bfd,
1342 input_section, rel->r_offset)))
1343 return false;
1344 relocation = 0;
1345 }
1346 }
1347
1348 /* FIXME: We should use the addend, but the COFF relocations
1349 don't. */
1350 r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1351 input_section,
1352 contents, rel->r_offset,
1353 relocation, rel->r_addend,
1354 info, sec, h == NULL);
1355
1356 if (r != bfd_reloc_ok)
1357 {
1358 const char * name;
1359 const char * msg = (const char *)0;
1360
1361 if (h != NULL)
1362 name = h->root.root.string;
1363 else
1364 {
1365 name = (bfd_elf_string_from_elf_section
1366 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1367 if (name == NULL || *name == '\0')
1368 name = bfd_section_name (input_bfd, sec);
1369 }
1370
1371 switch (r)
1372 {
1373 case bfd_reloc_overflow:
1374 if (! ((*info->callbacks->reloc_overflow)
1375 (info, name, howto->name, (bfd_vma) 0,
1376 input_bfd, input_section, rel->r_offset)))
1377 return false;
1378 break;
1379
1380 case bfd_reloc_undefined:
1381 fprintf (stderr, "undef2 %s\n", name );
1382 if (! ((*info->callbacks->undefined_symbol)
1383 (info, name, input_bfd, input_section,
1384 rel->r_offset)))
1385 return false;
1386 break;
1387
1388 case bfd_reloc_outofrange:
1389 msg = "internal error: out of range error";
1390 goto common_error;
1391
1392 case bfd_reloc_notsupported:
1393 msg = "internal error: unsupported relocation error";
1394 goto common_error;
1395
1396 case bfd_reloc_dangerous:
1397 msg = "internal error: dangerous relocation";
1398 goto common_error;
1399
1400 case bfd_reloc_other:
1401 msg = "could not locate special linker symbol __gp";
1402 goto common_error;
1403
1404 case bfd_reloc_continue:
1405 msg = "could not locate special linker symbol __ep";
1406 goto common_error;
1407
1408 default:
1409 msg = "internal error: unknown error";
1410 /* fall through */
1411
1412 common_error:
1413 if (!((*info->callbacks->warning)
1414 (info, msg, name, input_bfd, input_section,
1415 rel->r_offset)))
1416 return false;
1417 break;
1418 }
1419 }
1420 }
1421
1422 return true;
1423 }
1424
1425 /* Set the right machine number. */
1426 static boolean
1427 v850_elf_object_p (abfd)
1428 bfd *abfd;
1429 {
1430 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1431 {
1432 default:
1433 case E_V850_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
1434 /* start-sanitize-v850e */
1435 case E_V850E_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
1436 /* end-sanitize-v850e */
1437 /* start-sanitize-v850eq */
1438 case E_V850EQ_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850eq); break;
1439 /* start-sanitize-v850eq */
1440 }
1441 }
1442
1443 /* Store the machine number in the flags field. */
1444 void
1445 v850_elf_final_write_processing (abfd, linker)
1446 bfd * abfd;
1447 boolean linker;
1448 {
1449 unsigned long val;
1450
1451 switch (bfd_get_mach (abfd))
1452 {
1453 default:
1454 case 0: val = E_V850_ARCH; break;
1455 /* start-sanitize-v850e */
1456 case bfd_mach_v850e: val = E_V850E_ARCH; break;
1457 /* end-sanitize-v850e */
1458 /* start-sanitize-v850eq */
1459 case bfd_mach_v850eq: val = E_V850EQ_ARCH; break;
1460 /* end-sanitize-v850eq */
1461 }
1462
1463 elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1464 elf_elfheader (abfd)->e_flags |= val;
1465 }
1466
1467 /* Function to keep V850 specific file flags. */
1468 boolean
1469 v850_elf_set_private_flags (abfd, flags)
1470 bfd * abfd;
1471 flagword flags;
1472 {
1473 BFD_ASSERT (!elf_flags_init (abfd)
1474 || elf_elfheader (abfd)->e_flags == flags);
1475
1476 elf_elfheader (abfd)->e_flags = flags;
1477 elf_flags_init (abfd) = true;
1478 return true;
1479 }
1480
1481 /* Copy backend specific data from one object module to another */
1482 boolean
1483 v850_elf_copy_private_bfd_data (ibfd, obfd)
1484 bfd * ibfd;
1485 bfd * obfd;
1486 {
1487 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1488 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1489 return true;
1490
1491 BFD_ASSERT (!elf_flags_init (obfd)
1492 || (elf_elfheader (obfd)->e_flags
1493 == elf_elfheader (ibfd)->e_flags));
1494
1495 elf_gp (obfd) = elf_gp (ibfd);
1496 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1497 elf_flags_init (obfd) = true;
1498 return true;
1499 }
1500
1501 /* Merge backend specific data from an object file to the output
1502 object file when linking. */
1503 boolean
1504 v850_elf_merge_private_bfd_data (ibfd, obfd)
1505 bfd * ibfd;
1506 bfd * obfd;
1507 {
1508 flagword old_flags;
1509 flagword new_flags;
1510
1511 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1512 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1513 return true;
1514
1515 new_flags = elf_elfheader (ibfd)->e_flags;
1516 old_flags = elf_elfheader (obfd)->e_flags;
1517
1518 if (! elf_flags_init (obfd))
1519 {
1520 elf_flags_init (obfd) = true;
1521 elf_elfheader (obfd)->e_flags = new_flags;
1522
1523 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1524 && bfd_get_arch_info (obfd)->the_default)
1525 {
1526 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1527 }
1528
1529 return true;
1530 }
1531
1532 /* Check flag compatibility. */
1533
1534 if (new_flags == old_flags)
1535 return true;
1536
1537 if ((new_flags & EF_V850_ARCH) != (old_flags & EF_V850_ARCH))
1538 {
1539 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1540 bfd_get_filename (ibfd));
1541 bfd_set_error (bfd_error_bad_value);
1542 return false;
1543 }
1544
1545 return true;
1546 }
1547 /* Display the flags field */
1548
1549 static boolean
1550 v850_elf_print_private_bfd_data (abfd, ptr)
1551 bfd * abfd;
1552 PTR ptr;
1553 {
1554 FILE * file = (FILE *) ptr;
1555
1556 BFD_ASSERT (abfd != NULL && ptr != NULL)
1557
1558 fprintf (file, "private flags = %x", elf_elfheader (abfd)->e_flags);
1559
1560 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1561 {
1562 default:
1563 case E_V850_ARCH: fprintf (file, ": v850 architecture"); break;
1564 /* start-sanitize-v850e */
1565 case E_V850E_ARCH: fprintf (file, ": v850e architecture"); break;
1566 /* end-sanitize-v850e */
1567 /* start-sanitize-v850eq */
1568 case E_V850EQ_ARCH: fprintf (file, ": v850eq architecture"); break;
1569 /* end-sanitize-v850eq */
1570 }
1571
1572 fputc ('\n', file);
1573
1574 return true;
1575 }
1576 \f
1577 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
1578 #define TARGET_LITTLE_NAME "elf32-v850"
1579 #define ELF_ARCH bfd_arch_v850
1580 #define ELF_MACHINE_CODE EM_CYGNUS_V850
1581 #define ELF_MAXPAGESIZE 0x1000
1582
1583 #define elf_info_to_howto 0
1584 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
1585 #define elf_backend_check_relocs v850_elf_check_relocs
1586 #define elf_backend_relocate_section v850_elf_relocate_section
1587 #define elf_backend_object_p v850_elf_object_p
1588 #define elf_backend_final_write_processing v850_elf_final_write_processing
1589 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
1590 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
1591 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
1592 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
1593 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
1594 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
1595
1596 #define elf_symbol_leading_char '_'
1597
1598 #include "elf32-target.h"