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