d3339fb6fbff62fdab9918aa60acbad234f4346c
[deliverable/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 /* 16 bit offset from the tiny data area pointer! */
297 HOWTO (R_V850_TDA_16_16_OFFSET, /* type */
298 0, /* rightshift */
299 1, /* size (0 = byte, 1 = short, 2 = long) */
300 16, /* bitsize */
301 false, /* pc_relative */
302 0, /* bitpos */
303 complain_overflow_dont, /* complain_on_overflow */
304 v850_elf_reloc, /* special_function */
305 "R_V850_TDA_16_16_OFFSET", /* name */
306 false, /* partial_inplace */
307 0xffff, /* src_mask */
308 0xfff, /* dst_mask */
309 false), /* pcrel_offset */
310
311 /* start-sanitize-v850e */
312
313 /* 5 bit offset from the tiny data area pointer. */
314 HOWTO (R_V850_TDA_4_5_OFFSET, /* type */
315 1, /* rightshift */
316 1, /* size (0 = byte, 1 = short, 2 = long) */
317 5, /* 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_5_OFFSET", /* name */
323 false, /* partial_inplace */
324 0x0f, /* src_mask */
325 0x0f, /* dst_mask */
326 false), /* pcrel_offset */
327
328 /* 4 bit offset from the tiny data area pointer. */
329 HOWTO (R_V850_TDA_4_4_OFFSET, /* type */
330 0, /* rightshift */
331 1, /* size (0 = byte, 1 = short, 2 = long) */
332 4, /* bitsize */
333 false, /* pc_relative */
334 0, /* bitpos */
335 complain_overflow_dont, /* complain_on_overflow */
336 v850_elf_reloc, /* special_function */
337 "R_V850_TDA_4_4_OFFSET", /* name */
338 false, /* partial_inplace */
339 0x0f, /* src_mask */
340 0x0f, /* dst_mask */
341 false), /* pcrel_offset */
342
343 /* 16 bit offset from the short data area pointer. */
344 HOWTO (R_V850_SDA_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_SDA_16_16_SPLIT_OFFSET",/* name */
353 false, /* partial_inplace */
354 0xfffe0020, /* src_mask */
355 0xfffe0020, /* dst_mask */
356 false), /* pcrel_offset */
357
358 /* 16 bit offset from the zero data area pointer. */
359 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
360 0, /* rightshift */
361 2, /* size (0 = byte, 1 = short, 2 = long) */
362 16, /* bitsize */
363 false, /* pc_relative */
364 0, /* bitpos */
365 complain_overflow_dont, /* complain_on_overflow */
366 v850_elf_reloc, /* special_function */
367 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
368 false, /* partial_inplace */
369 0xfffe0020, /* src_mask */
370 0xfffe0020, /* dst_mask */
371 false), /* pcrel_offset */
372
373 /* end-sanitize-v850e */
374 };
375
376 /* Map BFD reloc types to V850 ELF reloc types. */
377
378 struct v850_elf_reloc_map
379 {
380 unsigned char bfd_reloc_val;
381 unsigned char elf_reloc_val;
382 };
383
384 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
385 {
386 { BFD_RELOC_NONE, R_V850_NONE },
387 { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL },
388 { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL },
389 { BFD_RELOC_HI16_S, R_V850_HI16_S },
390 { BFD_RELOC_HI16, R_V850_HI16 },
391 { BFD_RELOC_LO16, R_V850_LO16 },
392 { BFD_RELOC_32, R_V850_32 },
393 { BFD_RELOC_16, R_V850_16 },
394 { BFD_RELOC_8, R_V850_8 },
395 { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
396 { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
397 { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
398 { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
399 { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET },
400 { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET },
401 { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET },
402 { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
403 /* start-sanitize-v850e */
404 { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET },
405 { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET },
406 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
407 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
408 /* end-sanitize-v850e */
409 };
410
411 \f
412 /* Map a bfd relocation into the appropriate howto structure */
413 static reloc_howto_type *
414 v850_elf_reloc_type_lookup (abfd, code)
415 bfd *abfd;
416 bfd_reloc_code_real_type code;
417 {
418 unsigned int i;
419
420 for (i = 0;
421 i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
422 i++)
423 {
424 if (v850_elf_reloc_map[i].bfd_reloc_val == code)
425 {
426 BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
427
428 return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
429 }
430 }
431
432 return NULL;
433 }
434
435 \f
436 /* Set the howto pointer for an V850 ELF reloc. */
437 static void
438 v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
439 bfd *abfd;
440 arelent *cache_ptr;
441 Elf32_Internal_Rel *dst;
442 {
443 unsigned int r_type;
444
445 r_type = ELF32_R_TYPE (dst->r_info);
446 BFD_ASSERT (r_type < (unsigned int) R_V850_max);
447 cache_ptr->howto = &v850_elf_howto_table[r_type];
448 }
449
450 \f
451 /* Look through the relocs for a section during the first phase, and
452 allocate space in the global offset table or procedure linkage
453 table. */
454
455 static boolean
456 v850_elf_check_relocs (abfd, info, sec, relocs)
457 bfd *abfd;
458 struct bfd_link_info *info;
459 asection *sec;
460 const Elf_Internal_Rela *relocs;
461 {
462 boolean ret = true;
463 bfd *dynobj;
464 Elf_Internal_Shdr *symtab_hdr;
465 struct elf_link_hash_entry **sym_hashes;
466 const Elf_Internal_Rela *rel;
467 const Elf_Internal_Rela *rel_end;
468 asection *sreloc;
469 enum reloc_type r_type;
470 int other = 0;
471 const char *common = (const char *)0;
472
473 if (info->relocateable)
474 return true;
475
476 #ifdef DEBUG
477 fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
478 bfd_get_section_name (abfd, sec),
479 bfd_get_filename (abfd));
480 #endif
481
482 dynobj = elf_hash_table (info)->dynobj;
483 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
484 sym_hashes = elf_sym_hashes (abfd);
485 sreloc = NULL;
486
487 rel_end = relocs + sec->reloc_count;
488 for (rel = relocs; rel < rel_end; rel++)
489 {
490 unsigned long r_symndx;
491 struct elf_link_hash_entry *h;
492
493 r_symndx = ELF32_R_SYM (rel->r_info);
494 if (r_symndx < symtab_hdr->sh_info)
495 h = NULL;
496 else
497 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
498
499 r_type = (enum reloc_type) ELF32_R_TYPE (rel->r_info);
500 switch (r_type)
501 {
502 default:
503 case R_V850_NONE:
504 case R_V850_9_PCREL:
505 case R_V850_22_PCREL:
506 case R_V850_HI16_S:
507 case R_V850_HI16:
508 case R_V850_LO16:
509 case R_V850_32:
510 case R_V850_16:
511 case R_V850_8:
512 break;
513
514 /* start-sanitize-v850e */
515 case R_V850_SDA_16_16_SPLIT_OFFSET:
516 /* end-sanitize-v850e */
517 case R_V850_SDA_16_16_OFFSET:
518 case R_V850_SDA_15_16_OFFSET:
519 other = V850_OTHER_SDA;
520 common = ".scommon";
521 goto small_data_common;
522
523 /* start-sanitize-v850e */
524 case R_V850_ZDA_16_16_SPLIT_OFFSET:
525 /* end-sanitize-v850e */
526 case R_V850_ZDA_16_16_OFFSET:
527 case R_V850_ZDA_15_16_OFFSET:
528 other = V850_OTHER_ZDA;
529 common = ".zcommon";
530 goto small_data_common;
531
532 /* start-sanitize-v850e */
533 case R_V850_TDA_4_5_OFFSET:
534 case R_V850_TDA_4_4_OFFSET:
535 /* end-sanitize-v850e */
536 case R_V850_TDA_6_8_OFFSET:
537 case R_V850_TDA_7_8_OFFSET:
538 case R_V850_TDA_7_7_OFFSET:
539 case R_V850_TDA_16_16_OFFSET:
540 other = V850_OTHER_TDA;
541 common = ".tcommon";
542 /* fall through */
543
544 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
545
546 small_data_common:
547 if (h)
548 {
549 h->other |= other; /* flag which type of relocation was used */
550 if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
551 && (h->other & V850_OTHER_ERROR) == 0)
552 {
553 const char *msg;
554
555 switch (h->other & V850_OTHER_MASK)
556 {
557 default:
558 msg = "Variable cannot occupy in multiple small data regions";
559 break;
560 case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
561 msg = "Variable can only be in one of the small, zero, and tiny data regions";
562 break;
563 case V850_OTHER_SDA | V850_OTHER_ZDA:
564 msg = "Variable cannot be in both small and zero data regions simultaneously";
565 break;
566 case V850_OTHER_SDA | V850_OTHER_TDA:
567 msg = "Variable cannot be in both small and tiny data regions simultaneously";
568 break;
569 case V850_OTHER_ZDA | V850_OTHER_TDA:
570 msg = "Variable cannot be in both zero and tiny data regions simultaneously";
571 break;
572 }
573
574 (*info->callbacks->warning) (info, msg, h->root.root.string,
575 abfd, h->root.u.def.section, 0);
576
577 bfd_set_error (bfd_error_bad_value);
578 h->other |= V850_OTHER_ERROR;
579 ret = false;
580 }
581 }
582
583 if (h && h->root.type == bfd_link_hash_common
584 && h->root.u.c.p
585 && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
586 {
587 asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
588 section->flags |= SEC_IS_COMMON;
589 }
590
591 #ifdef DEBUG
592 fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
593 v850_elf_howto_table[ (int)r_type ].name,
594 (h && h->root.root.string) ? h->root.root.string : "<unknown>",
595 (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
596 #endif
597 break;
598 }
599 }
600
601 return ret;
602 }
603
604 \f
605 /* Insert the addend into the instruction. */
606 static bfd_reloc_status_type
607 v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
608 bfd * abfd;
609 arelent * reloc;
610 asymbol * symbol;
611 PTR data;
612 asection * isection;
613 bfd * obfd;
614 char ** err;
615 {
616 long relocation;
617 long insn;
618
619
620 /* If there is an output BFD,
621 and the symbol is not a section name (which is only defined at final link time),
622 and either we are not putting the addend into the instruction
623 or the addend is zero, so there is nothing to add into the instruction
624 then just fixup the address and return. */
625 if (obfd != (bfd *) NULL
626 && (symbol->flags & BSF_SECTION_SYM) == 0
627 && (! reloc->howto->partial_inplace
628 || reloc->addend == 0))
629 {
630 reloc->address += isection->output_offset;
631 return bfd_reloc_ok;
632 }
633 #if 0
634 else if (obfd != NULL)
635 {
636 return bfd_reloc_continue;
637 }
638 #endif
639
640 /* Catch relocs involving undefined symbols. */
641 if (bfd_is_und_section (symbol->section)
642 && (symbol->flags & BSF_WEAK) == 0
643 && obfd == NULL)
644 return bfd_reloc_undefined;
645
646 /* We handle final linking of some relocs ourselves. */
647
648 /* Is the address of the relocation really within the section? */
649 if (reloc->address > isection->_cooked_size)
650 return bfd_reloc_outofrange;
651
652 /* Work out which section the relocation is targetted at and the
653 initial relocation command value. */
654
655 /* Get symbol value. (Common symbols are special.) */
656 if (bfd_is_com_section (symbol->section))
657 relocation = 0;
658 else
659 relocation = symbol->value;
660
661 /* Convert input-section-relative symbol value to absolute + addend. */
662 relocation += symbol->section->output_section->vma;
663 relocation += symbol->section->output_offset;
664 relocation += reloc->addend;
665
666 if (reloc->howto->pc_relative == true)
667 {
668 /* Here the variable relocation holds the final address of the
669 symbol we are relocating against, plus any addend. */
670 relocation -= isection->output_section->vma + isection->output_offset;
671
672 /* Deal with pcrel_offset */
673 relocation -= reloc->address;
674 }
675
676 /* I've got no clue... */
677 reloc->addend = 0;
678
679 switch (reloc->howto->type)
680 {
681 default:
682 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", reloc->howto->type ); */
683 return bfd_reloc_notsupported;
684
685 case R_V850_22_PCREL:
686 if (relocation > 0x1ffff || relocation < -0x200000)
687 return bfd_reloc_overflow;
688
689 if ((relocation % 2) != 0)
690 return bfd_reloc_dangerous;
691
692 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
693 insn &= ~0xfffe003f;
694 insn |= (((relocation & 0xfffe) << 16)
695 | ((relocation & 0x3f0000) >> 16));
696 bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
697 return bfd_reloc_ok;
698
699 case R_V850_9_PCREL:
700 if (relocation > 0xff || relocation < -0x100)
701 return bfd_reloc_overflow;
702
703 if ((relocation % 2) != 0)
704 return bfd_reloc_dangerous;
705
706 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
707 insn &= ~ 0xf870;
708 insn |= ((relocation & 0x1f0) << 7) | ((relocation & 0x0e) << 3);
709 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
710 return bfd_reloc_ok;
711
712 case R_V850_HI16_S:
713 relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
714 relocation = (relocation >> 16) + ((relocation & 0x8000) != 0);
715 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
716 return bfd_reloc_ok;
717
718 case R_V850_HI16:
719 relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
720 relocation = (relocation >> 16);
721 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
722 return bfd_reloc_ok;
723
724 case R_V850_LO16:
725 relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
726 /* Do not complain if value has top bit set, as this has been anticipated. */
727 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
728 return bfd_reloc_ok;
729
730 case R_V850_16:
731 relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
732 /* drop through */
733
734 case R_V850_SDA_16_16_OFFSET:
735 case R_V850_ZDA_16_16_OFFSET:
736 case R_V850_TDA_16_16_OFFSET:
737 if ((long)relocation > 0x7fff || (long)relocation < -0x8000)
738 return bfd_reloc_overflow;
739 bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
740 return bfd_reloc_ok;
741
742 case R_V850_SDA_15_16_OFFSET:
743 case R_V850_ZDA_15_16_OFFSET:
744 if ((long)relocation > 0x7ffe || (long)relocation < -0x8000)
745 return bfd_reloc_overflow;
746
747 if (relocation & 1)
748 return bfd_reloc_dangerous;
749
750 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
751 insn &= 1;
752 insn |= (relocation >> 1) & ~1;
753
754 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
755 return bfd_reloc_ok;
756
757 case R_V850_TDA_6_8_OFFSET:
758 if ((long) relocation > 0xfc || (long) relocation < 0)
759 return bfd_reloc_overflow;
760
761 if (relocation & 3)
762 return bfd_reloc_dangerous;
763
764 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
765 insn &= 0xff81;
766 insn |= (relocation >> 1);
767
768 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
769 return bfd_reloc_ok;
770
771 case R_V850_TDA_7_8_OFFSET:
772 if ((long) relocation > 0xfe || (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 &= 0xff80;
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_7_7_OFFSET:
786 if ((long) relocation > 0x7f || (long) relocation < 0)
787 return bfd_reloc_overflow;
788
789 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
790 insn &= 0xff80;
791 insn |= relocation;
792
793 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
794 return bfd_reloc_ok;
795
796 /* start-sanitize-v850e */
797 case R_V850_TDA_4_5_OFFSET:
798 if ((long) relocation > 0x1e || (long) relocation < 0)
799 return bfd_reloc_overflow;
800
801 if (relocation & 1)
802 return bfd_reloc_dangerous;
803
804 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
805 insn &= 0xfff0;
806 insn |= (relocation >> 1);
807
808 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
809 return bfd_reloc_ok;
810
811 case R_V850_TDA_4_4_OFFSET:
812 if ((long) relocation > 0xf || (long) relocation < 0)
813 return bfd_reloc_overflow;
814
815 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
816 insn &= 0xfff0;
817 insn |= relocation;
818
819 bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
820 return bfd_reloc_ok;
821
822 case R_V850_ZDA_16_16_SPLIT_OFFSET:
823 case R_V850_SDA_16_16_SPLIT_OFFSET:
824 if ((long) relocation > 0xffff || (long) relocation < 0)
825 return bfd_reloc_overflow;
826
827 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
828
829 insn &= 0x0001ffdf;
830 insn |= (relocation & 1) << 5;
831 insn |= (relocation & ~1) << 16;
832
833 bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
834 return bfd_reloc_ok;
835 /* end-sanitize-v850e */
836 }
837
838 return bfd_reloc_continue;
839 }
840
841 \f
842 /*ARGSUSED*/
843 static boolean
844 v850_elf_is_local_label_name (abfd, name)
845 bfd *abfd;
846 const char *name;
847 {
848 return ((name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
849 || (name[0] == '_' && name[1] == '.' && name[2] == 'L'
850 && name[3] == '_'));
851 }
852
853 \f
854 /* Perform a relocation as part of a final link. */
855 static bfd_reloc_status_type
856 v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
857 input_section, contents, offset, value,
858 addend, info, sym_sec, is_local)
859 reloc_howto_type * howto;
860 bfd * input_bfd;
861 bfd * output_bfd;
862 asection * input_section;
863 bfd_byte * contents;
864 bfd_vma offset;
865 bfd_vma value;
866 bfd_vma addend;
867 struct bfd_link_info * info;
868 asection * sym_sec;
869 int is_local;
870 {
871 unsigned long insn;
872 unsigned long r_type = howto->type;
873 bfd_byte * hit_data = contents + offset;
874
875 switch (r_type)
876 {
877 case R_V850_9_PCREL:
878 value -= (input_section->output_section->vma
879 + input_section->output_offset);
880 value -= offset;
881
882 if ((long)value > 0xff || (long)value < -0x100)
883 return bfd_reloc_overflow;
884
885 if ((value % 2) != 0)
886 return bfd_reloc_dangerous;
887
888 insn = bfd_get_16 (input_bfd, hit_data);
889 insn &= 0x078f;
890 insn |= ((value & 0x1f0) << 7) | ((value & 0x0e) << 3);
891 bfd_put_16 (input_bfd, insn, hit_data);
892 return bfd_reloc_ok;
893
894 case R_V850_22_PCREL:
895 value -= (input_section->output_section->vma
896 + input_section->output_offset);
897 value -= offset;
898
899 if ((long)value > 0x1ffff || (long)value < -0x200000)
900 return bfd_reloc_overflow;
901
902 if ((value % 2) != 0)
903 return bfd_reloc_dangerous;
904
905 insn = bfd_get_32 (input_bfd, hit_data);
906 insn &= 0x1ffc0;
907 insn |= (((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
908 bfd_put_32 (input_bfd, insn, hit_data);
909 return bfd_reloc_ok;
910
911 case R_V850_HI16_S:
912 value += (short)bfd_get_16 (input_bfd, hit_data);
913 value = (value >> 16) + ((value & 0x8000) != 0);
914
915 if ((long)value > 0x7fff || (long)value < -0x8000)
916 return bfd_reloc_overflow;
917
918 bfd_put_16 (input_bfd, value, hit_data);
919 return bfd_reloc_ok;
920
921 case R_V850_HI16:
922 value += (short)bfd_get_16 (input_bfd, hit_data);
923 value >>= 16;
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_LO16:
932 value += (short)bfd_get_16 (input_bfd, hit_data);
933 value &= 0xffff;
934
935 bfd_put_16 (input_bfd, value, hit_data);
936 return bfd_reloc_ok;
937
938 case R_V850_16:
939 value += (short) bfd_get_16 (input_bfd, hit_data);
940
941 if ((long) value > 0x7fff || (long) value < -0x8000)
942 return bfd_reloc_overflow;
943
944 bfd_put_16 (input_bfd, value, hit_data);
945 return bfd_reloc_ok;
946
947 case R_V850_ZDA_16_16_OFFSET:
948 if (sym_sec == NULL)
949 return bfd_reloc_undefined;
950
951 value -= sym_sec->output_section->vma;
952 value += (short) bfd_get_16 (input_bfd, hit_data);
953
954 if ((long) value > 0x7fff || (long) value < -0x8000)
955 return bfd_reloc_overflow;
956
957 bfd_put_16 (input_bfd, value, hit_data);
958 return bfd_reloc_ok;
959
960 case R_V850_ZDA_15_16_OFFSET:
961 if (sym_sec == NULL)
962 return bfd_reloc_undefined;
963
964 insn = bfd_get_16 (input_bfd, hit_data);
965
966 value -= sym_sec->output_section->vma;
967 value += ((insn & 0xfffe) << 1);
968
969 if ((long) value > 0x7ffe || (long) value < -0x8000)
970 return bfd_reloc_overflow;
971
972 value &= ~1;
973 value |= (insn & 1);
974
975 bfd_put_16 (input_bfd, value, hit_data);
976 return bfd_reloc_ok;
977
978 case R_V850_32:
979 value += bfd_get_32 (input_bfd, hit_data);
980 bfd_put_32 (input_bfd, value, hit_data);
981 return bfd_reloc_ok;
982
983 case R_V850_8:
984 value += (char)bfd_get_8 (input_bfd, hit_data);
985
986 if ((long)value > 0x7f || (long)value < -0x80)
987 return bfd_reloc_overflow;
988
989 bfd_put_8 (input_bfd, value, hit_data);
990 return bfd_reloc_ok;
991
992 case R_V850_SDA_16_16_OFFSET:
993 if (sym_sec == NULL)
994 return bfd_reloc_undefined;
995
996 {
997 unsigned long gp;
998 struct bfd_link_hash_entry * h;
999
1000 /* Get the value of __gp. */
1001 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1002 if (h == (struct bfd_link_hash_entry *) NULL
1003 || h->type != bfd_link_hash_defined)
1004 return bfd_reloc_other;
1005
1006 gp = (h->u.def.value
1007 + h->u.def.section->output_section->vma
1008 + h->u.def.section->output_offset);
1009
1010 value -= sym_sec->output_section->vma;
1011 value -= (gp - sym_sec->output_section->vma);
1012 value += (short) bfd_get_16 (input_bfd, hit_data);
1013
1014 if ((long)value > 0x7fff || (long)value < -0x8000)
1015 return bfd_reloc_overflow;
1016
1017 bfd_put_16 (input_bfd, value, hit_data);
1018 return bfd_reloc_ok;
1019 }
1020
1021 case R_V850_SDA_15_16_OFFSET:
1022 if (sym_sec == NULL)
1023 return bfd_reloc_undefined;
1024
1025 {
1026 unsigned long gp;
1027 struct bfd_link_hash_entry * h;
1028
1029 /* Get the value of __gp. */
1030 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1031 if (h == (struct bfd_link_hash_entry *) NULL
1032 || h->type != bfd_link_hash_defined)
1033 return bfd_reloc_other;
1034
1035 gp = (h->u.def.value
1036 + h->u.def.section->output_section->vma
1037 + h->u.def.section->output_offset);
1038
1039 value -= sym_sec->output_section->vma;
1040 value -= (gp - sym_sec->output_section->vma);
1041
1042 insn = bfd_get_16 (input_bfd, hit_data);
1043
1044 value += ((insn & 0xfffe) << 1);
1045
1046 if ((long)value > 0x7ffe || (long)value < -0x8000)
1047 return bfd_reloc_overflow;
1048
1049 value &= ~1;
1050 value |= (insn & 1);
1051
1052 bfd_put_16 (input_bfd, value, hit_data);
1053 return bfd_reloc_ok;
1054 }
1055
1056 case R_V850_TDA_6_8_OFFSET:
1057 {
1058 unsigned long ep;
1059 struct bfd_link_hash_entry * h;
1060
1061 insn = bfd_get_16 (input_bfd, hit_data);
1062
1063 /* Get the value of __ep. */
1064 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1065 if (h == (struct bfd_link_hash_entry *) NULL
1066 || h->type != bfd_link_hash_defined)
1067 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1068
1069 ep = (h->u.def.value
1070 + h->u.def.section->output_section->vma
1071 + h->u.def.section->output_offset);
1072
1073 value -= ep;
1074 value += ((insn & 0x7e) << 2);
1075
1076 if ((long) value > 0xfc || (long) value < 0)
1077 return bfd_reloc_overflow;
1078
1079 if ((value % 2) != 0)
1080 return bfd_reloc_dangerous;
1081
1082 insn &= 0xff81;
1083 insn |= (value >> 1);
1084
1085 bfd_put_16 (input_bfd, insn, hit_data);
1086 return bfd_reloc_ok;
1087 }
1088
1089 case R_V850_TDA_7_8_OFFSET:
1090 {
1091 unsigned long ep;
1092 struct bfd_link_hash_entry * h;
1093
1094 insn = bfd_get_16 (input_bfd, hit_data);
1095
1096 /* Get the value of __ep. */
1097 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1098 if (h == (struct bfd_link_hash_entry *) NULL
1099 || h->type != bfd_link_hash_defined)
1100 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1101
1102 ep = (h->u.def.value
1103 + h->u.def.section->output_section->vma
1104 + h->u.def.section->output_offset);
1105
1106 value -= ep;
1107 value += ((insn & 0x7f) << 1);
1108
1109 if ((long) value > 0xfe || (long) value < 0)
1110 return bfd_reloc_overflow;
1111
1112 insn &= 0xff80;
1113 insn |= (value >> 1);
1114
1115 bfd_put_16 (input_bfd, insn, hit_data);
1116 return bfd_reloc_ok;
1117 }
1118
1119 case R_V850_TDA_7_7_OFFSET:
1120 {
1121 unsigned long ep;
1122 struct bfd_link_hash_entry * h;
1123
1124 insn = bfd_get_16 (input_bfd, hit_data);
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 value += insn & 0x7f;
1138
1139 if ((long) value > 0x7f || (long) value < 0)
1140 return bfd_reloc_overflow;
1141
1142 insn &= 0xff80;
1143 insn |= value;
1144 bfd_put_16 (input_bfd, insn, hit_data);
1145 return bfd_reloc_ok;
1146 }
1147
1148 case R_V850_TDA_16_16_OFFSET:
1149 {
1150 unsigned long ep;
1151 struct bfd_link_hash_entry * h;
1152
1153 /* Get the value of __ep. */
1154 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1155 if (h == (struct bfd_link_hash_entry *) NULL
1156 || h->type != bfd_link_hash_defined)
1157 return bfd_reloc_other;
1158
1159 ep = (h->u.def.value
1160 + h->u.def.section->output_section->vma
1161 + h->u.def.section->output_offset);
1162 value -= ep;
1163
1164 value += (short) bfd_get_16 (input_bfd, hit_data);
1165
1166 if ((long)value > 0x7fff || (long)value < -0x8000)
1167 return bfd_reloc_overflow;
1168
1169 bfd_put_16 (input_bfd, value, hit_data);
1170 return bfd_reloc_ok;
1171 }
1172
1173 /* start-sanitize-v850e */
1174 case R_V850_TDA_4_5_OFFSET:
1175 {
1176 unsigned long ep;
1177 struct bfd_link_hash_entry * h;
1178
1179 /* Get the value of __ep. */
1180 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1181 if (h == (struct bfd_link_hash_entry *) NULL
1182 || h->type != bfd_link_hash_defined)
1183 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1184
1185 ep = (h->u.def.value
1186 + h->u.def.section->output_section->vma
1187 + h->u.def.section->output_offset);
1188 value -= ep;
1189
1190 insn = bfd_get_16 (input_bfd, hit_data);
1191
1192 value += ((insn & 0xf) << 1);
1193
1194 if ((long) value > 0x1e || (long) value < 0)
1195 return bfd_reloc_overflow;
1196
1197 insn &= 0xfff0;
1198 insn |= (value >> 1);
1199 bfd_put_16 (input_bfd, insn, hit_data);
1200 return bfd_reloc_ok;
1201 }
1202
1203 case R_V850_TDA_4_4_OFFSET:
1204 {
1205 unsigned long ep;
1206 struct bfd_link_hash_entry * h;
1207
1208 /* Get the value of __ep. */
1209 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1210 if (h == (struct bfd_link_hash_entry *) NULL
1211 || h->type != bfd_link_hash_defined)
1212 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1213
1214 ep = (h->u.def.value
1215 + h->u.def.section->output_section->vma
1216 + h->u.def.section->output_offset);
1217 value -= ep;
1218
1219 insn = bfd_get_16 (input_bfd, hit_data);
1220
1221 value += insn & 0xf;
1222
1223 if ((long) value > 0xf || (long) value < 0)
1224 return bfd_reloc_overflow;
1225
1226 insn &= 0xfff0;
1227 insn |= value;
1228 bfd_put_16 (input_bfd, insn, hit_data);
1229 return bfd_reloc_ok;
1230 }
1231
1232 case R_V850_SDA_16_16_SPLIT_OFFSET:
1233 if (sym_sec == NULL)
1234 return bfd_reloc_undefined;
1235
1236 {
1237 unsigned long gp;
1238 struct bfd_link_hash_entry * h;
1239
1240 /* Get the value of __gp. */
1241 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1242 if (h == (struct bfd_link_hash_entry *) NULL
1243 || h->type != bfd_link_hash_defined)
1244 return bfd_reloc_other;
1245
1246 gp = (h->u.def.value
1247 + h->u.def.section->output_section->vma
1248 + h->u.def.section->output_offset);
1249
1250 value -= sym_sec->output_section->vma;
1251 value -= (gp - sym_sec->output_section->vma);
1252
1253 insn = bfd_get_32 (input_bfd, hit_data);
1254
1255 value += ((insn & 0xfffe0000) >> 16);
1256 value += ((insn & 0x20) >> 5);
1257
1258 if ((long)value > 0x7fff || (long)value < -0x8000)
1259 return bfd_reloc_overflow;
1260
1261 insn &= 0x0001ffdf;
1262 insn |= (value & 1) << 5;
1263 insn |= (value & ~1) << 16;
1264
1265 bfd_put_32 (input_bfd, insn, hit_data);
1266 return bfd_reloc_ok;
1267 }
1268
1269 case R_V850_ZDA_16_16_SPLIT_OFFSET:
1270 if (sym_sec == NULL)
1271 return bfd_reloc_undefined;
1272
1273 insn = bfd_get_32 (input_bfd, hit_data);
1274
1275 value -= sym_sec->output_section->vma;
1276 value += ((insn & 0xfffe0000) >> 16);
1277 value += ((insn & 0x20) >> 5);
1278
1279 if ((long)value > 0x7fff || (long)value < -0x8000)
1280 return bfd_reloc_overflow;
1281
1282 insn &= 0x0001ffdf;
1283 insn |= (value & 1) << 5;
1284 insn |= (value & ~1) << 16;
1285
1286 bfd_put_32 (input_bfd, insn, hit_data);
1287 return bfd_reloc_ok;
1288
1289 /* end-sanitize-v850e */
1290
1291
1292 case R_V850_NONE:
1293 return bfd_reloc_ok;
1294
1295 default:
1296 return bfd_reloc_notsupported;
1297 }
1298 }
1299
1300 \f
1301 /* Relocate an V850 ELF section. */
1302 static boolean
1303 v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1304 contents, relocs, local_syms, local_sections)
1305 bfd * output_bfd;
1306 struct bfd_link_info * info;
1307 bfd * input_bfd;
1308 asection * input_section;
1309 bfd_byte * contents;
1310 Elf_Internal_Rela * relocs;
1311 Elf_Internal_Sym * local_syms;
1312 asection ** local_sections;
1313 {
1314 Elf_Internal_Shdr * symtab_hdr;
1315 struct elf_link_hash_entry ** sym_hashes;
1316 Elf_Internal_Rela * rel;
1317 Elf_Internal_Rela * relend;
1318
1319 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1320 sym_hashes = elf_sym_hashes (input_bfd);
1321
1322 rel = relocs;
1323 relend = relocs + input_section->reloc_count;
1324 for (; rel < relend; rel++)
1325 {
1326 int r_type;
1327 reloc_howto_type * howto;
1328 unsigned long r_symndx;
1329 Elf_Internal_Sym * sym;
1330 asection * sec;
1331 struct elf_link_hash_entry * h;
1332 bfd_vma relocation;
1333 bfd_reloc_status_type r;
1334
1335 r_symndx = ELF32_R_SYM (rel->r_info);
1336 r_type = ELF32_R_TYPE (rel->r_info);
1337 howto = v850_elf_howto_table + r_type;
1338
1339 if (info->relocateable)
1340 {
1341 /* This is a relocateable link. We don't have to change
1342 anything, unless the reloc is against a section symbol,
1343 in which case we have to adjust according to where the
1344 section symbol winds up in the output section. */
1345 if (r_symndx < symtab_hdr->sh_info)
1346 {
1347 sym = local_syms + r_symndx;
1348 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1349 {
1350 sec = local_sections[r_symndx];
1351 rel->r_addend += sec->output_offset + sym->st_value;
1352 }
1353 }
1354
1355 continue;
1356 }
1357
1358 /* This is a final link. */
1359 h = NULL;
1360 sym = NULL;
1361 sec = NULL;
1362 if (r_symndx < symtab_hdr->sh_info)
1363 {
1364 sym = local_syms + r_symndx;
1365 sec = local_sections[r_symndx];
1366 relocation = (sec->output_section->vma
1367 + sec->output_offset
1368 + sym->st_value);
1369 #if 0
1370 {
1371 char * name;
1372 name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1373 name = (name == NULL) ? "<none>" : name;
1374 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x rel %x\n", sec->name, name, sym->st_name,
1375 sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend, rel);
1376 }
1377 #endif
1378 }
1379 else
1380 {
1381 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1382
1383 while (h->root.type == bfd_link_hash_indirect
1384 || h->root.type == bfd_link_hash_warning)
1385 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1386
1387 if (h->root.type == bfd_link_hash_defined
1388 || h->root.type == bfd_link_hash_defweak)
1389 {
1390 sec = h->root.u.def.section;
1391 relocation = (h->root.u.def.value
1392 + sec->output_section->vma
1393 + sec->output_offset);
1394 }
1395 else if (h->root.type == bfd_link_hash_undefweak)
1396 relocation = 0;
1397 else
1398 {
1399 if (! ((*info->callbacks->undefined_symbol)
1400 (info, h->root.root.string, input_bfd,
1401 input_section, rel->r_offset)))
1402 return false;
1403 relocation = 0;
1404 }
1405 }
1406
1407 /* FIXME: We should use the addend, but the COFF relocations
1408 don't. */
1409 r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1410 input_section,
1411 contents, rel->r_offset,
1412 relocation, rel->r_addend,
1413 info, sec, h == NULL);
1414
1415 if (r != bfd_reloc_ok)
1416 {
1417 const char * name;
1418 const char * msg = (const char *)0;
1419
1420 if (h != NULL)
1421 name = h->root.root.string;
1422 else
1423 {
1424 name = (bfd_elf_string_from_elf_section
1425 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1426 if (name == NULL || *name == '\0')
1427 name = bfd_section_name (input_bfd, sec);
1428 }
1429
1430 switch (r)
1431 {
1432 case bfd_reloc_overflow:
1433 if (! ((*info->callbacks->reloc_overflow)
1434 (info, name, howto->name, (bfd_vma) 0,
1435 input_bfd, input_section, rel->r_offset)))
1436 return false;
1437 break;
1438
1439 case bfd_reloc_undefined:
1440 fprintf (stderr, "undef2 %s\n", name );
1441 if (! ((*info->callbacks->undefined_symbol)
1442 (info, name, input_bfd, input_section,
1443 rel->r_offset)))
1444 return false;
1445 break;
1446
1447 case bfd_reloc_outofrange:
1448 msg = "internal error: out of range error";
1449 goto common_error;
1450
1451 case bfd_reloc_notsupported:
1452 msg = "internal error: unsupported relocation error";
1453 goto common_error;
1454
1455 case bfd_reloc_dangerous:
1456 msg = "internal error: dangerous relocation";
1457 goto common_error;
1458
1459 case bfd_reloc_other:
1460 msg = "could not locate special linker symbol __gp";
1461 goto common_error;
1462
1463 case bfd_reloc_continue:
1464 msg = "could not locate special linker symbol __ep";
1465 goto common_error;
1466
1467 default:
1468 msg = "internal error: unknown error";
1469 /* fall through */
1470
1471 common_error:
1472 if (!((*info->callbacks->warning)
1473 (info, msg, name, input_bfd, input_section,
1474 rel->r_offset)))
1475 return false;
1476 break;
1477 }
1478 }
1479 }
1480
1481 return true;
1482 }
1483
1484 /* Set the right machine number. */
1485 static boolean
1486 v850_elf_object_p (abfd)
1487 bfd *abfd;
1488 {
1489 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1490 {
1491 default:
1492 case E_V850_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
1493 /* start-sanitize-v850e */
1494 case E_V850E_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
1495 /* end-sanitize-v850e */
1496 /* start-sanitize-v850eq */
1497 case E_V850EQ_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850eq); break;
1498 /* end-sanitize-v850eq */
1499 }
1500 }
1501
1502 /* Store the machine number in the flags field. */
1503 void
1504 v850_elf_final_write_processing (abfd, linker)
1505 bfd * abfd;
1506 boolean linker;
1507 {
1508 unsigned long val;
1509
1510 switch (bfd_get_mach (abfd))
1511 {
1512 default:
1513 case 0: val = E_V850_ARCH; break;
1514 /* start-sanitize-v850e */
1515 case bfd_mach_v850e: val = E_V850E_ARCH; break;
1516 /* end-sanitize-v850e */
1517 /* start-sanitize-v850eq */
1518 case bfd_mach_v850eq: val = E_V850EQ_ARCH; break;
1519 /* end-sanitize-v850eq */
1520 }
1521
1522 elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1523 elf_elfheader (abfd)->e_flags |= val;
1524 }
1525
1526 /* Function to keep V850 specific file flags. */
1527 boolean
1528 v850_elf_set_private_flags (abfd, flags)
1529 bfd * abfd;
1530 flagword flags;
1531 {
1532 BFD_ASSERT (!elf_flags_init (abfd)
1533 || elf_elfheader (abfd)->e_flags == flags);
1534
1535 elf_elfheader (abfd)->e_flags = flags;
1536 elf_flags_init (abfd) = true;
1537 return true;
1538 }
1539
1540 /* Copy backend specific data from one object module to another */
1541 boolean
1542 v850_elf_copy_private_bfd_data (ibfd, obfd)
1543 bfd * ibfd;
1544 bfd * obfd;
1545 {
1546 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1547 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1548 return true;
1549
1550 BFD_ASSERT (!elf_flags_init (obfd)
1551 || (elf_elfheader (obfd)->e_flags
1552 == elf_elfheader (ibfd)->e_flags));
1553
1554 elf_gp (obfd) = elf_gp (ibfd);
1555 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1556 elf_flags_init (obfd) = true;
1557 return true;
1558 }
1559
1560 /* Merge backend specific data from an object file to the output
1561 object file when linking. */
1562 boolean
1563 v850_elf_merge_private_bfd_data (ibfd, obfd)
1564 bfd * ibfd;
1565 bfd * obfd;
1566 {
1567 flagword old_flags;
1568 flagword new_flags;
1569
1570 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1571 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1572 return true;
1573
1574 new_flags = elf_elfheader (ibfd)->e_flags;
1575 old_flags = elf_elfheader (obfd)->e_flags;
1576
1577 if (! elf_flags_init (obfd))
1578 {
1579 elf_flags_init (obfd) = true;
1580 elf_elfheader (obfd)->e_flags = new_flags;
1581
1582 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1583 && bfd_get_arch_info (obfd)->the_default)
1584 {
1585 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1586 }
1587
1588 return true;
1589 }
1590
1591 /* Check flag compatibility. */
1592
1593 if (new_flags == old_flags)
1594 return true;
1595
1596 if ((new_flags & EF_V850_ARCH) != (old_flags & EF_V850_ARCH))
1597 {
1598 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1599 bfd_get_filename (ibfd));
1600 bfd_set_error (bfd_error_bad_value);
1601 return false;
1602 }
1603
1604 return true;
1605 }
1606 /* Display the flags field */
1607
1608 static boolean
1609 v850_elf_print_private_bfd_data (abfd, ptr)
1610 bfd * abfd;
1611 PTR ptr;
1612 {
1613 FILE * file = (FILE *) ptr;
1614
1615 BFD_ASSERT (abfd != NULL && ptr != NULL)
1616
1617 fprintf (file, "private flags = %x", elf_elfheader (abfd)->e_flags);
1618
1619 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1620 {
1621 default:
1622 case E_V850_ARCH: fprintf (file, ": v850 architecture"); break;
1623 /* start-sanitize-v850e */
1624 case E_V850E_ARCH: fprintf (file, ": v850e architecture"); break;
1625 /* end-sanitize-v850e */
1626 /* start-sanitize-v850eq */
1627 case E_V850EQ_ARCH: fprintf (file, ": v850eq architecture"); break;
1628 /* end-sanitize-v850eq */
1629 }
1630
1631 fputc ('\n', file);
1632
1633 return true;
1634 }
1635 \f
1636 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
1637 #define TARGET_LITTLE_NAME "elf32-v850"
1638 #define ELF_ARCH bfd_arch_v850
1639 #define ELF_MACHINE_CODE EM_CYGNUS_V850
1640 #define ELF_MAXPAGESIZE 0x1000
1641
1642 #define elf_info_to_howto 0
1643 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
1644 #define elf_backend_check_relocs v850_elf_check_relocs
1645 #define elf_backend_relocate_section v850_elf_relocate_section
1646 #define elf_backend_object_p v850_elf_object_p
1647 #define elf_backend_final_write_processing v850_elf_final_write_processing
1648 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
1649 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
1650 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
1651 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
1652 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
1653 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
1654
1655 #define elf_symbol_leading_char '_'
1656
1657 #include "elf32-target.h"
This page took 0.10191 seconds and 4 git commands to generate.