8e5acf68d1b5e6c4618e01c20ea21c3f25359e4a
[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 /* sign-extend a 24-bit number */
34 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
35
36 static reloc_howto_type *v850_elf_reloc_type_lookup
37 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
38 static void v850_elf_info_to_howto_rel
39 PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
40 static bfd_reloc_status_type v850_elf_reloc
41 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
42 static boolean v850_elf_is_local_label_name PARAMS ((bfd *, const char *));
43 static boolean v850_elf_relocate_section PARAMS((bfd *,
44 struct bfd_link_info *,
45 bfd *,
46 asection *,
47 bfd_byte *,
48 Elf_Internal_Rela *,
49 Elf_Internal_Sym *,
50 asection **));
51 /* Try to minimize the amount of space occupied by relocation tables
52 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
53 #define USE_REL
54
55 /* Note: It is REQUIRED that the 'type' value of each entry in this array
56 match the index of the entry in the array. */
57 static reloc_howto_type v850_elf_howto_table[] =
58 {
59 /* This reloc does nothing. */
60 HOWTO (R_V850_NONE, /* type */
61 0, /* rightshift */
62 2, /* size (0 = byte, 1 = short, 2 = long) */
63 32, /* bitsize */
64 false, /* pc_relative */
65 0, /* bitpos */
66 complain_overflow_bitfield, /* complain_on_overflow */
67 bfd_elf_generic_reloc, /* special_function */
68 "R_V850_NONE", /* name */
69 false, /* partial_inplace */
70 0, /* src_mask */
71 0, /* dst_mask */
72 false), /* pcrel_offset */
73
74 /* A PC relative 9 bit branch. */
75 HOWTO (R_V850_9_PCREL, /* type */
76 2, /* rightshift */
77 2, /* size (0 = byte, 1 = short, 2 = long) */
78 26, /* bitsize */
79 true, /* pc_relative */
80 0, /* bitpos */
81 complain_overflow_bitfield, /* complain_on_overflow */
82 v850_elf_reloc, /* special_function */
83 "R_V850_9_PCREL", /* name */
84 false, /* partial_inplace */
85 0x00ffffff, /* src_mask */
86 0x00ffffff, /* dst_mask */
87 true), /* pcrel_offset */
88
89 /* A PC relative 22 bit branch. */
90 HOWTO (R_V850_22_PCREL, /* type */
91 2, /* rightshift */
92 2, /* size (0 = byte, 1 = short, 2 = long) */
93 22, /* bitsize */
94 true, /* pc_relative */
95 7, /* bitpos */
96 complain_overflow_signed, /* complain_on_overflow */
97 v850_elf_reloc, /* special_function */
98 "R_V850_22_PCREL", /* name */
99 false, /* partial_inplace */
100 0x07ffff80, /* src_mask */
101 0x07ffff80, /* dst_mask */
102 true), /* pcrel_offset */
103
104 /* High 16 bits of symbol value. */
105 HOWTO (R_V850_HI16_S, /* type */
106 0, /* rightshift */
107 1, /* size (0 = byte, 1 = short, 2 = long) */
108 16, /* bitsize */
109 false, /* pc_relative */
110 0, /* bitpos */
111 complain_overflow_dont, /* complain_on_overflow */
112 v850_elf_reloc, /* special_function */
113 "R_V850_HI16_S", /* name */
114 true, /* partial_inplace */
115 0xffff, /* src_mask */
116 0xffff, /* dst_mask */
117 false), /* pcrel_offset */
118
119 /* High 16 bits of symbol value. */
120 HOWTO (R_V850_HI16, /* type */
121 0, /* rightshift */
122 1, /* size (0 = byte, 1 = short, 2 = long) */
123 16, /* bitsize */
124 false, /* pc_relative */
125 0, /* bitpos */
126 complain_overflow_dont, /* complain_on_overflow */
127 v850_elf_reloc, /* special_function */
128 "R_V850_HI16", /* name */
129 true, /* partial_inplace */
130 0xffff, /* src_mask */
131 0xffff, /* dst_mask */
132 false), /* pcrel_offset */
133
134 /* Low 16 bits of symbol value. */
135 HOWTO (R_V850_LO16, /* type */
136 0, /* rightshift */
137 1, /* size (0 = byte, 1 = short, 2 = long) */
138 16, /* bitsize */
139 false, /* pc_relative */
140 0, /* bitpos */
141 complain_overflow_dont, /* complain_on_overflow */
142 v850_elf_reloc, /* special_function */
143 "R_V850_LO16", /* name */
144 true, /* partial_inplace */
145 0xffff, /* src_mask */
146 0xffff, /* dst_mask */
147 false), /* pcrel_offset */
148
149 /* Simple 32bit reloc. */
150 HOWTO (R_V850_32, /* type */
151 0, /* rightshift */
152 2, /* size (0 = byte, 1 = short, 2 = long) */
153 32, /* bitsize */
154 false, /* pc_relative */
155 0, /* bitpos */
156 complain_overflow_dont, /* complain_on_overflow */
157 v850_elf_reloc, /* special_function */
158 "R_V850_32", /* name */
159 true, /* partial_inplace */
160 0xffffffff, /* src_mask */
161 0xffffffff, /* dst_mask */
162 false), /* pcrel_offset */
163
164 /* Simple 16bit reloc. */
165 HOWTO (R_V850_16, /* type */
166 0, /* rightshift */
167 1, /* size (0 = byte, 1 = short, 2 = long) */
168 16, /* bitsize */
169 false, /* pc_relative */
170 0, /* bitpos */
171 complain_overflow_dont, /* complain_on_overflow */
172 bfd_elf_generic_reloc, /* special_function */
173 "R_V850_16", /* name */
174 true, /* partial_inplace */
175 0xffff, /* src_mask */
176 0xffff, /* dst_mask */
177 false), /* pcrel_offset */
178
179 /* Simple 8bit reloc. */
180 HOWTO (R_V850_8, /* type */
181 0, /* rightshift */
182 0, /* size (0 = byte, 1 = short, 2 = long) */
183 8, /* bitsize */
184 false, /* pc_relative */
185 0, /* bitpos */
186 complain_overflow_dont, /* complain_on_overflow */
187 bfd_elf_generic_reloc, /* special_function */
188 "R_V850_8", /* name */
189 true, /* partial_inplace */
190 0xff, /* src_mask */
191 0xff, /* dst_mask */
192 false), /* pcrel_offset */
193
194 /* 16 bit offset from the short data area pointer. */
195 HOWTO (R_V850_SDA_16_16_OFFSET, /* type */
196 0, /* rightshift */
197 1, /* size (0 = byte, 1 = short, 2 = long) */
198 16, /* bitsize */
199 false, /* pc_relative */
200 0, /* bitpos */
201 complain_overflow_dont, /* complain_on_overflow */
202 v850_elf_reloc, /* special_function */
203 "R_V850_SDA_16_16_OFFSET", /* name */
204 false, /* partial_inplace */
205 0xffff, /* src_mask */
206 0xffff, /* dst_mask */
207 false), /* pcrel_offset */
208
209 /* 15 bit offset from the short data area pointer. */
210 HOWTO (R_V850_SDA_15_16_OFFSET, /* type */
211 1, /* rightshift */
212 1, /* size (0 = byte, 1 = short, 2 = long) */
213 16, /* bitsize */
214 false, /* pc_relative */
215 1, /* bitpos */
216 complain_overflow_dont, /* complain_on_overflow */
217 v850_elf_reloc, /* special_function */
218 "R_V850_SDA_15_16_OFFSET", /* name */
219 false, /* partial_inplace */
220 0xfffe, /* src_mask */
221 0xfffe, /* dst_mask */
222 false), /* pcrel_offset */
223
224 /* 16 bit offset from the zero data area pointer. */
225 HOWTO (R_V850_ZDA_16_16_OFFSET, /* type */
226 0, /* rightshift */
227 1, /* size (0 = byte, 1 = short, 2 = long) */
228 16, /* bitsize */
229 false, /* pc_relative */
230 0, /* bitpos */
231 complain_overflow_dont, /* complain_on_overflow */
232 v850_elf_reloc, /* special_function */
233 "R_V850_ZDA_16_16_OFFSET", /* name */
234 false, /* partial_inplace */
235 0xffff, /* src_mask */
236 0xffff, /* dst_mask */
237 false), /* pcrel_offset */
238
239 /* 15 bit offset from the zero data area pointer. */
240 HOWTO (R_V850_ZDA_15_16_OFFSET, /* type */
241 1, /* rightshift */
242 1, /* size (0 = byte, 1 = short, 2 = long) */
243 16, /* bitsize */
244 false, /* pc_relative */
245 1, /* bitpos */
246 complain_overflow_dont, /* complain_on_overflow */
247 v850_elf_reloc, /* special_function */
248 "R_V850_ZDA_15_16_OFFSET", /* name */
249 false, /* partial_inplace */
250 0xfffe, /* src_mask */
251 0xfffe, /* dst_mask */
252 false), /* pcrel_offset */
253
254 /* 6 bit offset from the tiny data area pointer. */
255 HOWTO (R_V850_TDA_6_8_OFFSET, /* type */
256 2, /* rightshift */
257 1, /* size (0 = byte, 1 = short, 2 = long) */
258 8, /* bitsize */
259 false, /* pc_relative */
260 1, /* bitpos */
261 complain_overflow_dont, /* complain_on_overflow */
262 v850_elf_reloc, /* special_function */
263 "R_V850_TDA_6_8_OFFSET", /* name */
264 false, /* partial_inplace */
265 0x7e, /* src_mask */
266 0x7e, /* dst_mask */
267 false), /* pcrel_offset */
268
269 /* 8 bit offset from the tiny data area pointer. */
270 HOWTO (R_V850_TDA_7_8_OFFSET, /* type */
271 1, /* rightshift */
272 1, /* size (0 = byte, 1 = short, 2 = long) */
273 8, /* bitsize */
274 false, /* pc_relative */
275 0, /* bitpos */
276 complain_overflow_dont, /* complain_on_overflow */
277 v850_elf_reloc, /* special_function */
278 "R_V850_TDA_7_8_OFFSET", /* name */
279 false, /* partial_inplace */
280 0x7f, /* src_mask */
281 0x7f, /* dst_mask */
282 false), /* pcrel_offset */
283
284 /* 7 bit offset from the tiny data area pointer. */
285 HOWTO (R_V850_TDA_7_7_OFFSET, /* type */
286 0, /* rightshift */
287 1, /* size (0 = byte, 1 = short, 2 = long) */
288 7, /* bitsize */
289 false, /* pc_relative */
290 0, /* bitpos */
291 complain_overflow_dont, /* complain_on_overflow */
292 v850_elf_reloc, /* special_function */
293 "R_V850_TDA_7_7_OFFSET", /* name */
294 false, /* partial_inplace */
295 0x7f, /* src_mask */
296 0x7f, /* dst_mask */
297 false), /* pcrel_offset */
298
299 /* 16 bit offset from the tiny data area pointer! */
300 HOWTO (R_V850_TDA_16_16_OFFSET, /* type */
301 0, /* rightshift */
302 1, /* size (0 = byte, 1 = short, 2 = long) */
303 16, /* bitsize */
304 false, /* pc_relative */
305 0, /* bitpos */
306 complain_overflow_dont, /* complain_on_overflow */
307 v850_elf_reloc, /* special_function */
308 "R_V850_TDA_16_16_OFFSET", /* name */
309 false, /* partial_inplace */
310 0xffff, /* src_mask */
311 0xfff, /* dst_mask */
312 false), /* pcrel_offset */
313
314 /* start-sanitize-v850e */
315
316 /* 5 bit offset from the tiny data area pointer. */
317 HOWTO (R_V850_TDA_4_5_OFFSET, /* type */
318 1, /* rightshift */
319 1, /* size (0 = byte, 1 = short, 2 = long) */
320 5, /* bitsize */
321 false, /* pc_relative */
322 0, /* bitpos */
323 complain_overflow_dont, /* complain_on_overflow */
324 v850_elf_reloc, /* special_function */
325 "R_V850_TDA_4_5_OFFSET", /* name */
326 false, /* partial_inplace */
327 0x0f, /* src_mask */
328 0x0f, /* dst_mask */
329 false), /* pcrel_offset */
330
331 /* 4 bit offset from the tiny data area pointer. */
332 HOWTO (R_V850_TDA_4_4_OFFSET, /* type */
333 0, /* rightshift */
334 1, /* size (0 = byte, 1 = short, 2 = long) */
335 4, /* bitsize */
336 false, /* pc_relative */
337 0, /* bitpos */
338 complain_overflow_dont, /* complain_on_overflow */
339 v850_elf_reloc, /* special_function */
340 "R_V850_TDA_4_4_OFFSET", /* name */
341 false, /* partial_inplace */
342 0x0f, /* src_mask */
343 0x0f, /* dst_mask */
344 false), /* pcrel_offset */
345
346 /* 16 bit offset from the short data area pointer. */
347 HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */
348 0, /* rightshift */
349 2, /* size (0 = byte, 1 = short, 2 = long) */
350 16, /* bitsize */
351 false, /* pc_relative */
352 0, /* bitpos */
353 complain_overflow_dont, /* complain_on_overflow */
354 v850_elf_reloc, /* special_function */
355 "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
356 false, /* partial_inplace */
357 0xfffe0020, /* src_mask */
358 0xfffe0020, /* dst_mask */
359 false), /* pcrel_offset */
360
361 /* 16 bit offset from the zero data area pointer. */
362 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
363 0, /* rightshift */
364 2, /* size (0 = byte, 1 = short, 2 = long) */
365 16, /* bitsize */
366 false, /* pc_relative */
367 0, /* bitpos */
368 complain_overflow_dont, /* complain_on_overflow */
369 v850_elf_reloc, /* special_function */
370 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
371 false, /* partial_inplace */
372 0xfffe0020, /* src_mask */
373 0xfffe0020, /* dst_mask */
374 false), /* pcrel_offset */
375
376 /* 6 bit offset from the call table base pointer. */
377 HOWTO (R_V850_CALLT_6_7_OFFSET, /* type */
378 0, /* rightshift */
379 1, /* size (0 = byte, 1 = short, 2 = long) */
380 7, /* bitsize */
381 false, /* pc_relative */
382 0, /* bitpos */
383 complain_overflow_dont, /* complain_on_overflow */
384 v850_elf_reloc, /* special_function */
385 "R_V850_CALLT_6_7_OFFSET", /* name */
386 false, /* partial_inplace */
387 0x3f, /* src_mask */
388 0x3f, /* dst_mask */
389 false), /* pcrel_offset */
390
391 /* 16 bit offset from the call table base pointer. */
392 HOWTO (R_V850_CALLT_16_16_OFFSET, /* type */
393 0, /* rightshift */
394 1, /* size (0 = byte, 1 = short, 2 = long) */
395 16, /* bitsize */
396 false, /* pc_relative */
397 0, /* bitpos */
398 complain_overflow_dont, /* complain_on_overflow */
399 v850_elf_reloc, /* special_function */
400 "R_V850_CALLT_16_16_OFFSET", /* name */
401 false, /* partial_inplace */
402 0xffff, /* src_mask */
403 0xffff, /* dst_mask */
404 false), /* pcrel_offset */
405
406 /* end-sanitize-v850e */
407 };
408
409 /* Map BFD reloc types to V850 ELF reloc types. */
410
411 struct v850_elf_reloc_map
412 {
413 unsigned char bfd_reloc_val;
414 unsigned char elf_reloc_val;
415 };
416
417 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
418 {
419 { BFD_RELOC_NONE, R_V850_NONE },
420 { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL },
421 { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL },
422 { BFD_RELOC_HI16_S, R_V850_HI16_S },
423 { BFD_RELOC_HI16, R_V850_HI16 },
424 { BFD_RELOC_LO16, R_V850_LO16 },
425 { BFD_RELOC_32, R_V850_32 },
426 { BFD_RELOC_16, R_V850_16 },
427 { BFD_RELOC_8, R_V850_8 },
428 { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
429 { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
430 { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
431 { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
432 { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET },
433 { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET },
434 { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET },
435 { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
436 /* start-sanitize-v850e */
437 { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET },
438 { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET },
439 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
440 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
441 { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET },
442 { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET },
443 /* end-sanitize-v850e */
444 };
445
446 \f
447 /* Map a bfd relocation into the appropriate howto structure */
448 static reloc_howto_type *
449 v850_elf_reloc_type_lookup (abfd, code)
450 bfd * abfd;
451 bfd_reloc_code_real_type code;
452 {
453 unsigned int i;
454
455 for (i = 0;
456 i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
457 i++)
458 {
459 if (v850_elf_reloc_map[i].bfd_reloc_val == code)
460 {
461 BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
462
463 return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
464 }
465 }
466
467 return NULL;
468 }
469
470 \f
471 /* Set the howto pointer for an V850 ELF reloc. */
472 static void
473 v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
474 bfd * abfd;
475 arelent * cache_ptr;
476 Elf32_Internal_Rel * dst;
477 {
478 unsigned int r_type;
479
480 r_type = ELF32_R_TYPE (dst->r_info);
481 BFD_ASSERT (r_type < (unsigned int) R_V850_max);
482 cache_ptr->howto = &v850_elf_howto_table[r_type];
483 }
484
485 \f
486 /* Look through the relocs for a section during the first phase, and
487 allocate space in the global offset table or procedure linkage
488 table. */
489
490 static boolean
491 v850_elf_check_relocs (abfd, info, sec, relocs)
492 bfd * abfd;
493 struct bfd_link_info * info;
494 asection * sec;
495 const Elf_Internal_Rela * relocs;
496 {
497 boolean ret = true;
498 bfd *dynobj;
499 Elf_Internal_Shdr *symtab_hdr;
500 struct elf_link_hash_entry **sym_hashes;
501 const Elf_Internal_Rela *rel;
502 const Elf_Internal_Rela *rel_end;
503 asection *sreloc;
504 enum v850_reloc_type r_type;
505 int other = 0;
506 const char *common = (const char *)0;
507
508 if (info->relocateable)
509 return true;
510
511 #ifdef DEBUG
512 fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
513 bfd_get_section_name (abfd, sec),
514 bfd_get_filename (abfd));
515 #endif
516
517 dynobj = elf_hash_table (info)->dynobj;
518 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
519 sym_hashes = elf_sym_hashes (abfd);
520 sreloc = NULL;
521
522 rel_end = relocs + sec->reloc_count;
523 for (rel = relocs; rel < rel_end; rel++)
524 {
525 unsigned long r_symndx;
526 struct elf_link_hash_entry *h;
527
528 r_symndx = ELF32_R_SYM (rel->r_info);
529 if (r_symndx < symtab_hdr->sh_info)
530 h = NULL;
531 else
532 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
533
534 r_type = (enum v850_reloc_type) ELF32_R_TYPE (rel->r_info);
535 switch (r_type)
536 {
537 default:
538 case R_V850_NONE:
539 case R_V850_9_PCREL:
540 case R_V850_22_PCREL:
541 case R_V850_HI16_S:
542 case R_V850_HI16:
543 case R_V850_LO16:
544 case R_V850_32:
545 case R_V850_16:
546 case R_V850_8:
547 /* start-sanitize-v850e */
548 case R_V850_CALLT_6_7_OFFSET:
549 case R_V850_CALLT_16_16_OFFSET:
550 /* end-sanitize-v850e */
551 break;
552
553 /* start-sanitize-v850e */
554 case R_V850_SDA_16_16_SPLIT_OFFSET:
555 /* end-sanitize-v850e */
556 case R_V850_SDA_16_16_OFFSET:
557 case R_V850_SDA_15_16_OFFSET:
558 other = V850_OTHER_SDA;
559 common = ".scommon";
560 goto small_data_common;
561
562 /* start-sanitize-v850e */
563 case R_V850_ZDA_16_16_SPLIT_OFFSET:
564 /* end-sanitize-v850e */
565 case R_V850_ZDA_16_16_OFFSET:
566 case R_V850_ZDA_15_16_OFFSET:
567 other = V850_OTHER_ZDA;
568 common = ".zcommon";
569 goto small_data_common;
570
571 /* start-sanitize-v850e */
572 case R_V850_TDA_4_5_OFFSET:
573 case R_V850_TDA_4_4_OFFSET:
574 /* end-sanitize-v850e */
575 case R_V850_TDA_6_8_OFFSET:
576 case R_V850_TDA_7_8_OFFSET:
577 case R_V850_TDA_7_7_OFFSET:
578 case R_V850_TDA_16_16_OFFSET:
579 other = V850_OTHER_TDA;
580 common = ".tcommon";
581 /* fall through */
582
583 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
584
585 small_data_common:
586 if (h)
587 {
588 h->other |= other; /* flag which type of relocation was used */
589 if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
590 && (h->other & V850_OTHER_ERROR) == 0)
591 {
592 const char * msg;
593 static char buff[100]; /* XXX */
594
595 switch (h->other & V850_OTHER_MASK)
596 {
597 default:
598 msg = "cannot occupy in multiple small data regions";
599 break;
600 case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
601 msg = "can only be in one of the small, zero, and tiny data regions";
602 break;
603 case V850_OTHER_SDA | V850_OTHER_ZDA:
604 msg = "cannot be in both small and zero data regions simultaneously";
605 break;
606 case V850_OTHER_SDA | V850_OTHER_TDA:
607 msg = "cannot be in both small and tiny data regions simultaneously";
608 break;
609 case V850_OTHER_ZDA | V850_OTHER_TDA:
610 msg = "cannot be in both zero and tiny data regions simultaneously";
611 break;
612 }
613
614 sprintf (buff, "Variable '%s' %s", h->root.root.string, msg );
615 info->callbacks->warning (info, buff, h->root.root.string,
616 abfd, h->root.u.def.section, 0);
617
618 bfd_set_error (bfd_error_bad_value);
619 h->other |= V850_OTHER_ERROR;
620 ret = false;
621 }
622 }
623
624 if (h && h->root.type == bfd_link_hash_common
625 && h->root.u.c.p
626 && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
627 {
628 asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
629 section->flags |= SEC_IS_COMMON;
630 }
631
632 #ifdef DEBUG
633 fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
634 v850_elf_howto_table[ (int)r_type ].name,
635 (h && h->root.root.string) ? h->root.root.string : "<unknown>",
636 (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
637 #endif
638 break;
639 }
640 }
641
642 return ret;
643 }
644
645 static bfd_reloc_status_type
646 v850_elf_store_addend_in_insn (abfd, r_type, addend, address, replace)
647 bfd * abfd;
648 int r_type;
649 long addend;
650 bfd_byte * address;
651 boolean replace;
652 {
653 unsigned long insn;
654
655 switch (r_type)
656 {
657 default:
658 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
659 return bfd_reloc_notsupported;
660
661 case R_V850_32:
662 if (! replace)
663 addend += bfd_get_32 (abfd, address);
664
665 bfd_put_32 (abfd, addend, address);
666 return bfd_reloc_ok;
667
668 case R_V850_22_PCREL:
669 if (addend > 0x1fffff || addend < -0x200000)
670 return bfd_reloc_overflow;
671
672 if ((addend % 2) != 0)
673 return bfd_reloc_dangerous;
674
675 insn = bfd_get_32 (abfd, address);
676 insn &= ~0xfffe003f;
677 insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
678 bfd_put_32 (abfd, insn, address);
679 return bfd_reloc_ok;
680
681 case R_V850_9_PCREL:
682 if (addend > 0xff || addend < -0x100)
683 return bfd_reloc_overflow;
684
685 if ((addend % 2) != 0)
686 return bfd_reloc_dangerous;
687
688 insn = bfd_get_16 (abfd, address);
689 insn &= ~ 0xf870;
690 insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
691 break;
692
693 case R_V850_HI16_S:
694 addend += bfd_get_16 (abfd, address);
695 addend = (addend >> 16) + ((addend & 0x8000) != 0);
696 insn = addend;
697 break;
698
699 case R_V850_HI16:
700 addend += bfd_get_16 (abfd, address);
701 addend = (addend >> 16);
702 insn = addend;
703 break;
704
705 case R_V850_LO16:
706 addend += (short) bfd_get_16 (abfd, address);
707 /* Do not complain if value has top bit set, as this has been anticipated. */
708 insn = addend;
709 break;
710
711 case R_V850_16:
712 replace = false;
713 /* drop through */
714
715 /* start-sanitize-v850e */
716 case R_V850_CALLT_16_16_OFFSET:
717 /* end-sanitize-v850e */
718 case R_V850_SDA_16_16_OFFSET:
719 case R_V850_ZDA_16_16_OFFSET:
720 case R_V850_TDA_16_16_OFFSET:
721 if (! replace)
722 addend += bfd_get_16 (abfd, address);
723
724 if (addend > 0x7fff || addend < -0x8000)
725 return bfd_reloc_overflow;
726
727 insn = addend;
728 break;
729
730 case R_V850_SDA_15_16_OFFSET:
731 case R_V850_ZDA_15_16_OFFSET:
732 insn = bfd_get_16 (abfd, address);
733
734 if (! replace)
735 addend += ((insn & 0xfffe) << 1);
736
737 if (addend > 0x7ffe || addend < -0x8000)
738 return bfd_reloc_overflow;
739
740 if (addend & 1)
741 return bfd_reloc_dangerous;
742
743 insn &= 1;
744 insn |= (addend >> 1) & ~1;
745 break;
746
747 case R_V850_TDA_6_8_OFFSET:
748 insn = bfd_get_16 (abfd, address);
749
750 if (! replace)
751 addend += ((insn & 0x7e) << 1);
752
753 if (addend > 0xfc || addend < 0)
754 return bfd_reloc_overflow;
755
756 if (addend & 3)
757 return bfd_reloc_dangerous;
758
759 insn &= 0xff81;
760 insn |= (addend >> 1);
761 break;
762
763 case R_V850_TDA_7_8_OFFSET:
764 insn = bfd_get_16 (abfd, address);
765
766 if (! replace)
767 addend += ((insn & 0x7f) << 1);
768
769 if (addend > 0xfe || addend < 0)
770 return bfd_reloc_overflow;
771
772 if (addend & 1)
773 return bfd_reloc_dangerous;
774
775 insn &= 0xff80;
776 insn |= (addend >> 1);
777 break;
778
779 case R_V850_TDA_7_7_OFFSET:
780 insn = bfd_get_16 (abfd, address);
781
782 if (! replace)
783 addend += insn & 0x7f;
784
785 if (addend > 0x7f || addend < 0)
786 return bfd_reloc_overflow;
787
788 insn &= 0xff80;
789 insn |= addend;
790 break;
791
792 /* start-sanitize-v850e */
793 case R_V850_TDA_4_5_OFFSET:
794 insn = bfd_get_16 (abfd, address);
795
796 if (! replace)
797 addend += ((insn & 0xf) << 1);
798
799 if (addend > 0x1e || addend < 0)
800 return bfd_reloc_overflow;
801
802 if (addend & 1)
803 return bfd_reloc_dangerous;
804
805 insn &= 0xfff0;
806 insn |= (addend >> 1);
807 break;
808
809 case R_V850_TDA_4_4_OFFSET:
810 insn = bfd_get_16 (abfd, address);
811
812 if (! replace)
813 addend += insn & 0xf;
814
815 if (addend > 0xf || addend < 0)
816 return bfd_reloc_overflow;
817
818 insn &= 0xfff0;
819 insn |= addend;
820 break;
821
822 case R_V850_ZDA_16_16_SPLIT_OFFSET:
823 case R_V850_SDA_16_16_SPLIT_OFFSET:
824 insn = bfd_get_32 (abfd, address);
825
826 if (! replace)
827 addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
828
829 if (addend > 0xffff || addend < 0)
830 return bfd_reloc_overflow;
831
832 insn &= 0x0001ffdf;
833 insn |= (addend & 1) << 5;
834 insn |= (addend & ~1) << 16;
835
836 bfd_put_32 (abfd, insn, address);
837 return bfd_reloc_ok;
838
839 case R_V850_CALLT_6_7_OFFSET:
840 insn = bfd_get_16 (abfd, address);
841
842 if (! replace)
843 addend += ((insn & 0x3f) << 1);
844
845 if (addend > 0x7e || addend < 0)
846 return bfd_reloc_overflow;
847
848 if (addend & 1)
849 return bfd_reloc_dangerous;
850
851 insn &= 0xff80;
852 insn |= (addend >> 1);
853 break;
854 /* end-sanitize-v850e */
855 }
856
857 bfd_put_16 (abfd, insn, address);
858 return bfd_reloc_ok;
859 }
860
861 \f
862 /* Insert the addend into the instruction. */
863 static bfd_reloc_status_type
864 v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
865 bfd * abfd;
866 arelent * reloc;
867 asymbol * symbol;
868 PTR data;
869 asection * isection;
870 bfd * obfd;
871 char ** err;
872 {
873 long relocation;
874 long insn;
875
876
877 /* If there is an output BFD,
878 and the symbol is not a section name (which is only defined at final link time),
879 and either we are not putting the addend into the instruction
880 or the addend is zero, so there is nothing to add into the instruction
881 then just fixup the address and return. */
882 if (obfd != (bfd *) NULL
883 && (symbol->flags & BSF_SECTION_SYM) == 0
884 && (! reloc->howto->partial_inplace
885 || reloc->addend == 0))
886 {
887 reloc->address += isection->output_offset;
888 return bfd_reloc_ok;
889 }
890 #if 0
891 else if (obfd != NULL)
892 {
893 return bfd_reloc_continue;
894 }
895 #endif
896
897 /* Catch relocs involving undefined symbols. */
898 if (bfd_is_und_section (symbol->section)
899 && (symbol->flags & BSF_WEAK) == 0
900 && obfd == NULL)
901 return bfd_reloc_undefined;
902
903 /* We handle final linking of some relocs ourselves. */
904
905 /* Is the address of the relocation really within the section? */
906 if (reloc->address > isection->_cooked_size)
907 return bfd_reloc_outofrange;
908
909 /* Work out which section the relocation is targetted at and the
910 initial relocation command value. */
911
912 /* Get symbol value. (Common symbols are special.) */
913 if (bfd_is_com_section (symbol->section))
914 relocation = 0;
915 else
916 relocation = symbol->value;
917
918 /* Convert input-section-relative symbol value to absolute + addend. */
919 relocation += symbol->section->output_section->vma;
920 relocation += symbol->section->output_offset;
921 relocation += reloc->addend;
922
923 if (reloc->howto->pc_relative == true)
924 {
925 /* Here the variable relocation holds the final address of the
926 symbol we are relocating against, plus any addend. */
927 relocation -= isection->output_section->vma + isection->output_offset;
928
929 /* Deal with pcrel_offset */
930 relocation -= reloc->address;
931 }
932
933 /* I've got no clue... */
934 reloc->addend = 0;
935
936 return v850_elf_store_addend_in_insn (abfd, reloc->howto->type, relocation,
937 (bfd_byte *) data + reloc->address, true);
938 }
939
940 \f
941 /*ARGSUSED*/
942 static boolean
943 v850_elf_is_local_label_name (abfd, name)
944 bfd * abfd;
945 const char * name;
946 {
947 return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
948 || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_'));
949 }
950
951 \f
952 /* Perform a relocation as part of a final link. */
953 static bfd_reloc_status_type
954 v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
955 input_section, contents, offset, value,
956 addend, info, sym_sec, is_local)
957 reloc_howto_type * howto;
958 bfd * input_bfd;
959 bfd * output_bfd;
960 asection * input_section;
961 bfd_byte * contents;
962 bfd_vma offset;
963 bfd_vma value;
964 bfd_vma addend;
965 struct bfd_link_info * info;
966 asection * sym_sec;
967 int is_local;
968 {
969 unsigned long insn;
970 unsigned long r_type = howto->type;
971 bfd_byte * hit_data = contents + offset;
972
973 switch (r_type)
974 {
975 case R_V850_9_PCREL:
976 value -= (input_section->output_section->vma
977 + input_section->output_offset);
978 value -= offset;
979
980 if ((long)value > 0xff || (long)value < -0x100)
981 return bfd_reloc_overflow;
982
983 if ((value % 2) != 0)
984 return bfd_reloc_dangerous;
985
986 insn = bfd_get_16 (input_bfd, hit_data);
987 insn &= 0x078f;
988 insn |= ((value & 0x1f0) << 7) | ((value & 0x0e) << 3);
989 bfd_put_16 (input_bfd, insn, hit_data);
990 return bfd_reloc_ok;
991
992 case R_V850_22_PCREL:
993 value -= (input_section->output_section->vma
994 + input_section->output_offset
995 + offset);
996
997 value = SEXT24 (value); /* Only the bottom 24 bits of the PC are valid */
998
999 if ((long)value > 0x1fffff || (long)value < -0x200000)
1000 return bfd_reloc_overflow;
1001
1002 if ((value % 2) != 0)
1003 return bfd_reloc_dangerous;
1004
1005 insn = bfd_get_32 (input_bfd, hit_data);
1006 insn &= 0x1ffc0;
1007 insn |= (((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
1008 bfd_put_32 (input_bfd, insn, hit_data);
1009 return bfd_reloc_ok;
1010
1011 case R_V850_HI16_S:
1012 value += (short)bfd_get_16 (input_bfd, hit_data);
1013 value = (value >> 16) + ((value & 0x8000) != 0);
1014
1015 if ((long)value > 0x7fff || (long)value < -0x8000)
1016 {
1017 /* This relocation cannot overflow. */
1018
1019 value = 0;
1020 }
1021
1022 bfd_put_16 (input_bfd, value, hit_data);
1023 return bfd_reloc_ok;
1024
1025 case R_V850_HI16:
1026 value += (short)bfd_get_16 (input_bfd, hit_data);
1027 value >>= 16;
1028
1029 bfd_put_16 (input_bfd, value, hit_data);
1030 return bfd_reloc_ok;
1031
1032 case R_V850_LO16:
1033 value += (short)bfd_get_16 (input_bfd, hit_data);
1034 value &= 0xffff;
1035
1036 bfd_put_16 (input_bfd, value, hit_data);
1037 return bfd_reloc_ok;
1038
1039 case R_V850_16:
1040 value += (short) bfd_get_16 (input_bfd, hit_data);
1041
1042 if ((long) value > 0x7fff || (long) value < -0x8000)
1043 return bfd_reloc_overflow;
1044
1045 bfd_put_16 (input_bfd, value, hit_data);
1046 return bfd_reloc_ok;
1047
1048 case R_V850_ZDA_16_16_OFFSET:
1049 if (sym_sec == NULL)
1050 return bfd_reloc_undefined;
1051
1052 value -= sym_sec->output_section->vma;
1053 value += (short) bfd_get_16 (input_bfd, hit_data);
1054
1055 if ((long) value > 0x7fff || (long) value < -0x8000)
1056 return bfd_reloc_overflow;
1057
1058 bfd_put_16 (input_bfd, value, hit_data);
1059 return bfd_reloc_ok;
1060
1061 case R_V850_ZDA_15_16_OFFSET:
1062 if (sym_sec == NULL)
1063 return bfd_reloc_undefined;
1064
1065 insn = bfd_get_16 (input_bfd, hit_data);
1066
1067 value -= sym_sec->output_section->vma;
1068 value += ((insn & 0xfffe) << 1);
1069
1070 if ((long) value > 0x7ffe || (long) value < -0x8000)
1071 return bfd_reloc_overflow;
1072
1073 value &= ~1;
1074 value |= (insn & 1);
1075
1076 bfd_put_16 (input_bfd, value, hit_data);
1077 return bfd_reloc_ok;
1078
1079 case R_V850_32:
1080 value += bfd_get_32 (input_bfd, hit_data);
1081 bfd_put_32 (input_bfd, value, hit_data);
1082 return bfd_reloc_ok;
1083
1084 case R_V850_8:
1085 value += (char)bfd_get_8 (input_bfd, hit_data);
1086
1087 if ((long)value > 0x7f || (long)value < -0x80)
1088 return bfd_reloc_overflow;
1089
1090 bfd_put_8 (input_bfd, value, hit_data);
1091 return bfd_reloc_ok;
1092
1093 case R_V850_SDA_16_16_OFFSET:
1094 if (sym_sec == NULL)
1095 return bfd_reloc_undefined;
1096
1097 {
1098 unsigned long gp;
1099 struct bfd_link_hash_entry * h;
1100
1101 /* Get the value of __gp. */
1102 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1103 if (h == (struct bfd_link_hash_entry *) NULL
1104 || h->type != bfd_link_hash_defined)
1105 return bfd_reloc_other;
1106
1107 gp = (h->u.def.value
1108 + h->u.def.section->output_section->vma
1109 + h->u.def.section->output_offset);
1110
1111 value -= sym_sec->output_section->vma;
1112 value -= (gp - sym_sec->output_section->vma);
1113 value += (short) bfd_get_16 (input_bfd, hit_data);
1114
1115 if ((long)value > 0x7fff || (long)value < -0x8000)
1116 return bfd_reloc_overflow;
1117
1118 bfd_put_16 (input_bfd, value, hit_data);
1119 return bfd_reloc_ok;
1120 }
1121
1122 case R_V850_SDA_15_16_OFFSET:
1123 if (sym_sec == NULL)
1124 return bfd_reloc_undefined;
1125
1126 {
1127 unsigned long gp;
1128 struct bfd_link_hash_entry * h;
1129
1130 /* Get the value of __gp. */
1131 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1132 if (h == (struct bfd_link_hash_entry *) NULL
1133 || h->type != bfd_link_hash_defined)
1134 return bfd_reloc_other;
1135
1136 gp = (h->u.def.value
1137 + h->u.def.section->output_section->vma
1138 + h->u.def.section->output_offset);
1139
1140 value -= sym_sec->output_section->vma;
1141 value -= (gp - sym_sec->output_section->vma);
1142
1143 insn = bfd_get_16 (input_bfd, hit_data);
1144
1145 value += ((insn & 0xfffe) << 1);
1146
1147 if ((long)value > 0x7ffe || (long)value < -0x8000)
1148 return bfd_reloc_overflow;
1149
1150 value &= ~1;
1151 value |= (insn & 1);
1152
1153 bfd_put_16 (input_bfd, value, hit_data);
1154 return bfd_reloc_ok;
1155 }
1156
1157 case R_V850_TDA_6_8_OFFSET:
1158 {
1159 unsigned long ep;
1160 struct bfd_link_hash_entry * h;
1161
1162 insn = bfd_get_16 (input_bfd, hit_data);
1163
1164 /* Get the value of __ep. */
1165 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1166 if (h == (struct bfd_link_hash_entry *) NULL
1167 || h->type != bfd_link_hash_defined)
1168 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1169
1170 ep = (h->u.def.value
1171 + h->u.def.section->output_section->vma
1172 + h->u.def.section->output_offset);
1173
1174 value -= ep;
1175 value += ((insn & 0x7e) << 1);
1176
1177 if ((long) value > 0xfc || (long) value < 0)
1178 return bfd_reloc_overflow;
1179
1180 if ((value % 2) != 0)
1181 return bfd_reloc_dangerous;
1182
1183 insn &= 0xff81;
1184 insn |= (value >> 1);
1185
1186 bfd_put_16 (input_bfd, insn, hit_data);
1187 return bfd_reloc_ok;
1188 }
1189
1190 case R_V850_TDA_7_8_OFFSET:
1191 {
1192 unsigned long ep;
1193 struct bfd_link_hash_entry * h;
1194
1195 insn = bfd_get_16 (input_bfd, hit_data);
1196
1197 /* Get the value of __ep. */
1198 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1199 if (h == (struct bfd_link_hash_entry *) NULL
1200 || h->type != bfd_link_hash_defined)
1201 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1202
1203 ep = (h->u.def.value
1204 + h->u.def.section->output_section->vma
1205 + h->u.def.section->output_offset);
1206
1207 value -= ep;
1208 value += ((insn & 0x7f) << 1);
1209
1210 if ((long) value > 0xfe || (long) value < 0)
1211 return bfd_reloc_overflow;
1212
1213 insn &= 0xff80;
1214 insn |= (value >> 1);
1215
1216 bfd_put_16 (input_bfd, insn, hit_data);
1217 return bfd_reloc_ok;
1218 }
1219
1220 case R_V850_TDA_7_7_OFFSET:
1221 {
1222 unsigned long ep;
1223 struct bfd_link_hash_entry * h;
1224
1225 insn = bfd_get_16 (input_bfd, hit_data);
1226
1227 /* Get the value of __ep. */
1228 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1229 if (h == (struct bfd_link_hash_entry *) NULL
1230 || h->type != bfd_link_hash_defined)
1231 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1232
1233 ep = (h->u.def.value
1234 + h->u.def.section->output_section->vma
1235 + h->u.def.section->output_offset);
1236 value -= ep;
1237
1238 value += insn & 0x7f;
1239
1240 if ((long) value > 0x7f || (long) value < 0)
1241 return bfd_reloc_overflow;
1242
1243 insn &= 0xff80;
1244 insn |= value;
1245 bfd_put_16 (input_bfd, insn, hit_data);
1246 return bfd_reloc_ok;
1247 }
1248
1249 case R_V850_TDA_16_16_OFFSET:
1250 {
1251 unsigned long ep;
1252 struct bfd_link_hash_entry * h;
1253
1254 /* Get the value of __ep. */
1255 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1256 if (h == (struct bfd_link_hash_entry *) NULL
1257 || h->type != bfd_link_hash_defined)
1258 return bfd_reloc_other;
1259
1260 ep = (h->u.def.value
1261 + h->u.def.section->output_section->vma
1262 + h->u.def.section->output_offset);
1263 value -= ep;
1264
1265 value += (short) bfd_get_16 (input_bfd, hit_data);
1266
1267 if ((long)value > 0x7fff || (long)value < -0x8000)
1268 return bfd_reloc_overflow;
1269
1270 bfd_put_16 (input_bfd, value, hit_data);
1271 return bfd_reloc_ok;
1272 }
1273
1274 /* start-sanitize-v850e */
1275 case R_V850_TDA_4_5_OFFSET:
1276 {
1277 unsigned long ep;
1278 struct bfd_link_hash_entry * h;
1279
1280 /* Get the value of __ep. */
1281 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1282 if (h == (struct bfd_link_hash_entry *) NULL
1283 || h->type != bfd_link_hash_defined)
1284 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1285
1286 ep = (h->u.def.value
1287 + h->u.def.section->output_section->vma
1288 + h->u.def.section->output_offset);
1289 value -= ep;
1290
1291 insn = bfd_get_16 (input_bfd, hit_data);
1292
1293 value += ((insn & 0xf) << 1);
1294
1295 if ((long) value > 0x1e || (long) value < 0)
1296 return bfd_reloc_overflow;
1297
1298 insn &= 0xfff0;
1299 insn |= (value >> 1);
1300 bfd_put_16 (input_bfd, insn, hit_data);
1301 return bfd_reloc_ok;
1302 }
1303
1304 case R_V850_TDA_4_4_OFFSET:
1305 {
1306 unsigned long ep;
1307 struct bfd_link_hash_entry * h;
1308
1309 /* Get the value of __ep. */
1310 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1311 if (h == (struct bfd_link_hash_entry *) NULL
1312 || h->type != bfd_link_hash_defined)
1313 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
1314
1315 ep = (h->u.def.value
1316 + h->u.def.section->output_section->vma
1317 + h->u.def.section->output_offset);
1318 value -= ep;
1319
1320 insn = bfd_get_16 (input_bfd, hit_data);
1321
1322 value += insn & 0xf;
1323
1324 if ((long) value > 0xf || (long) value < 0)
1325 return bfd_reloc_overflow;
1326
1327 insn &= 0xfff0;
1328 insn |= value;
1329 bfd_put_16 (input_bfd, insn, hit_data);
1330 return bfd_reloc_ok;
1331 }
1332
1333 case R_V850_SDA_16_16_SPLIT_OFFSET:
1334 if (sym_sec == NULL)
1335 return bfd_reloc_undefined;
1336
1337 {
1338 unsigned long gp;
1339 struct bfd_link_hash_entry * h;
1340
1341 /* Get the value of __gp. */
1342 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1343 if (h == (struct bfd_link_hash_entry *) NULL
1344 || h->type != bfd_link_hash_defined)
1345 return bfd_reloc_other;
1346
1347 gp = (h->u.def.value
1348 + h->u.def.section->output_section->vma
1349 + h->u.def.section->output_offset);
1350
1351 value -= sym_sec->output_section->vma;
1352 value -= (gp - sym_sec->output_section->vma);
1353
1354 insn = bfd_get_32 (input_bfd, hit_data);
1355
1356 value += ((insn & 0xfffe0000) >> 16);
1357 value += ((insn & 0x20) >> 5);
1358
1359 if ((long)value > 0x7fff || (long)value < -0x8000)
1360 return bfd_reloc_overflow;
1361
1362 insn &= 0x0001ffdf;
1363 insn |= (value & 1) << 5;
1364 insn |= (value & ~1) << 16;
1365
1366 bfd_put_32 (input_bfd, insn, hit_data);
1367 return bfd_reloc_ok;
1368 }
1369
1370 case R_V850_ZDA_16_16_SPLIT_OFFSET:
1371 if (sym_sec == NULL)
1372 return bfd_reloc_undefined;
1373
1374 insn = bfd_get_32 (input_bfd, hit_data);
1375
1376 value -= sym_sec->output_section->vma;
1377 value += ((insn & 0xfffe0000) >> 16);
1378 value += ((insn & 0x20) >> 5);
1379
1380 if ((long)value > 0x7fff || (long)value < -0x8000)
1381 return bfd_reloc_overflow;
1382
1383 insn &= 0x0001ffdf;
1384 insn |= (value & 1) << 5;
1385 insn |= (value & ~1) << 16;
1386
1387 bfd_put_32 (input_bfd, insn, hit_data);
1388 return bfd_reloc_ok;
1389
1390 case R_V850_CALLT_6_7_OFFSET:
1391 {
1392 unsigned long ctbp;
1393 struct bfd_link_hash_entry * h;
1394
1395 /* Get the value of __ctbp. */
1396 h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1397 if (h == (struct bfd_link_hash_entry *) NULL
1398 || h->type != bfd_link_hash_defined)
1399 return (bfd_reloc_dangerous + 1); /* Actually this indicates that __ctbp could not be found. */
1400
1401 ctbp = (h->u.def.value
1402 + h->u.def.section->output_section->vma
1403 + h->u.def.section->output_offset);
1404 value -= ctbp;
1405
1406 insn = bfd_get_16 (input_bfd, hit_data);
1407
1408 value += ((insn & 0x3f) << 1);
1409
1410 if ((long) value > 0x7e || (long) value < 0)
1411 return bfd_reloc_overflow;
1412
1413 insn &= 0xff80;
1414 insn |= (value >> 1);
1415 bfd_put_16 (input_bfd, insn, hit_data);
1416 return bfd_reloc_ok;
1417 }
1418
1419 case R_V850_CALLT_16_16_OFFSET:
1420 if (sym_sec == NULL)
1421 return bfd_reloc_undefined;
1422
1423 {
1424 unsigned long ctbp;
1425 struct bfd_link_hash_entry * h;
1426
1427 /* Get the value of __ctbp. */
1428 h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1429 if (h == (struct bfd_link_hash_entry *) NULL
1430 || h->type != bfd_link_hash_defined)
1431 return (bfd_reloc_dangerous + 1);
1432
1433 ctbp = (h->u.def.value
1434 + h->u.def.section->output_section->vma
1435 + h->u.def.section->output_offset);
1436
1437 value -= sym_sec->output_section->vma;
1438 value -= (ctbp - sym_sec->output_section->vma);
1439 value += (short) bfd_get_16 (input_bfd, hit_data);
1440
1441 if ((long) value > 0xffff || (long) value < 0)
1442 return bfd_reloc_overflow;
1443
1444 bfd_put_16 (input_bfd, value, hit_data);
1445 return bfd_reloc_ok;
1446 }
1447
1448 /* end-sanitize-v850e */
1449
1450 case R_V850_NONE:
1451 return bfd_reloc_ok;
1452
1453 default:
1454 return bfd_reloc_notsupported;
1455 }
1456 }
1457
1458 \f
1459 /* Relocate an V850 ELF section. */
1460 static boolean
1461 v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1462 contents, relocs, local_syms, local_sections)
1463 bfd * output_bfd;
1464 struct bfd_link_info * info;
1465 bfd * input_bfd;
1466 asection * input_section;
1467 bfd_byte * contents;
1468 Elf_Internal_Rela * relocs;
1469 Elf_Internal_Sym * local_syms;
1470 asection ** local_sections;
1471 {
1472 Elf_Internal_Shdr * symtab_hdr;
1473 struct elf_link_hash_entry ** sym_hashes;
1474 Elf_Internal_Rela * rel;
1475 Elf_Internal_Rela * relend;
1476
1477 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1478 sym_hashes = elf_sym_hashes (input_bfd);
1479
1480 rel = relocs;
1481 relend = relocs + input_section->reloc_count;
1482 for (; rel < relend; rel++)
1483 {
1484 int r_type;
1485 reloc_howto_type * howto;
1486 unsigned long r_symndx;
1487 Elf_Internal_Sym * sym;
1488 asection * sec;
1489 struct elf_link_hash_entry * h;
1490 bfd_vma relocation;
1491 bfd_reloc_status_type r;
1492
1493 r_symndx = ELF32_R_SYM (rel->r_info);
1494 r_type = ELF32_R_TYPE (rel->r_info);
1495 howto = v850_elf_howto_table + r_type;
1496
1497 if (info->relocateable)
1498 {
1499 /* This is a relocateable link. We don't have to change
1500 anything, unless the reloc is against a section symbol,
1501 in which case we have to adjust according to where the
1502 section symbol winds up in the output section. */
1503 if (r_symndx < symtab_hdr->sh_info)
1504 {
1505 sym = local_syms + r_symndx;
1506 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1507 {
1508 sec = local_sections[r_symndx];
1509 #ifdef USE_REL
1510 /* The Elf_Internal_Rel structure does not have space for the
1511 modified addend value, so we store it in the instruction
1512 instead. */
1513
1514 if (sec->output_offset + sym->st_value != 0)
1515 {
1516 if (v850_elf_store_addend_in_insn (input_bfd, r_type,
1517 sec->output_offset +
1518 sym->st_value,
1519 contents + rel->r_offset,
1520 false)
1521 != bfd_reloc_ok)
1522 {
1523 info->callbacks->warning
1524 (info,
1525 "Unable to handle relocation during incremental link",
1526 NULL, input_bfd, input_section, rel->r_offset);
1527 }
1528 }
1529 #else
1530 rel->r_addend += sec->output_offset + sym->st_value;
1531 #endif
1532 }
1533 }
1534
1535 continue;
1536 }
1537
1538 /* This is a final link. */
1539 h = NULL;
1540 sym = NULL;
1541 sec = NULL;
1542 if (r_symndx < symtab_hdr->sh_info)
1543 {
1544 sym = local_syms + r_symndx;
1545 sec = local_sections[r_symndx];
1546 relocation = (sec->output_section->vma
1547 + sec->output_offset
1548 + sym->st_value);
1549 #if 0
1550 {
1551 char * name;
1552 name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1553 name = (name == NULL) ? "<none>" : name;
1554 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x rel %x\n", sec->name, name, sym->st_name,
1555 sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend, rel);
1556 }
1557 #endif
1558 }
1559 else
1560 {
1561 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1562
1563 while (h->root.type == bfd_link_hash_indirect
1564 || h->root.type == bfd_link_hash_warning)
1565 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1566
1567 if (h->root.type == bfd_link_hash_defined
1568 || h->root.type == bfd_link_hash_defweak)
1569 {
1570 sec = h->root.u.def.section;
1571 relocation = (h->root.u.def.value
1572 + sec->output_section->vma
1573 + sec->output_offset);
1574 #if 0
1575 fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1576 sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
1577 #endif
1578 }
1579 else if (h->root.type == bfd_link_hash_undefweak)
1580 {
1581 #if 0
1582 fprintf (stderr, "undefined: sec: %s, name: %s\n",
1583 sec->name, h->root.root.string);
1584 #endif
1585 relocation = 0;
1586 }
1587 else
1588 {
1589 if (! ((*info->callbacks->undefined_symbol)
1590 (info, h->root.root.string, input_bfd,
1591 input_section, rel->r_offset)))
1592 return false;
1593 #if 0
1594 fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
1595 #endif
1596 relocation = 0;
1597 }
1598 }
1599
1600 /* FIXME: We should use the addend, but the COFF relocations
1601 don't. */
1602 r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1603 input_section,
1604 contents, rel->r_offset,
1605 relocation, rel->r_addend,
1606 info, sec, h == NULL);
1607
1608 if (r != bfd_reloc_ok)
1609 {
1610 const char * name;
1611 const char * msg = (const char *)0;
1612
1613 if (h != NULL)
1614 name = h->root.root.string;
1615 else
1616 {
1617 name = (bfd_elf_string_from_elf_section
1618 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1619 if (name == NULL || *name == '\0')
1620 name = bfd_section_name (input_bfd, sec);
1621 }
1622
1623 switch (r)
1624 {
1625 case bfd_reloc_overflow:
1626 if (! ((*info->callbacks->reloc_overflow)
1627 (info, name, howto->name, (bfd_vma) 0,
1628 input_bfd, input_section, rel->r_offset)))
1629 return false;
1630 break;
1631
1632 case bfd_reloc_undefined:
1633 if (! ((*info->callbacks->undefined_symbol)
1634 (info, name, input_bfd, input_section,
1635 rel->r_offset)))
1636 return false;
1637 break;
1638
1639 case bfd_reloc_outofrange:
1640 msg = "internal error: out of range error";
1641 goto common_error;
1642
1643 case bfd_reloc_notsupported:
1644 msg = "internal error: unsupported relocation error";
1645 goto common_error;
1646
1647 case bfd_reloc_dangerous:
1648 msg = "internal error: dangerous relocation";
1649 goto common_error;
1650
1651 case bfd_reloc_other:
1652 msg = "could not locate special linker symbol __gp";
1653 goto common_error;
1654
1655 case bfd_reloc_continue:
1656 msg = "could not locate special linker symbol __ep";
1657 goto common_error;
1658
1659 case (bfd_reloc_dangerous + 1):
1660 msg = "could not locate special linker symbol __ctbp";
1661 goto common_error;
1662
1663 default:
1664 msg = "internal error: unknown error";
1665 /* fall through */
1666
1667 common_error:
1668 if (!((*info->callbacks->warning)
1669 (info, msg, name, input_bfd, input_section,
1670 rel->r_offset)))
1671 return false;
1672 break;
1673 }
1674 }
1675 }
1676
1677 return true;
1678 }
1679
1680 /* Set the right machine number. */
1681 static boolean
1682 v850_elf_object_p (abfd)
1683 bfd *abfd;
1684 {
1685 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1686 {
1687 default:
1688 case E_V850_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
1689 /* start-sanitize-v850e */
1690 case E_V850E_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
1691 case E_V850EQ_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850eq); break;
1692 /* end-sanitize-v850e */
1693 }
1694 }
1695
1696 /* Store the machine number in the flags field. */
1697 void
1698 v850_elf_final_write_processing (abfd, linker)
1699 bfd * abfd;
1700 boolean linker;
1701 {
1702 unsigned long val;
1703
1704 switch (bfd_get_mach (abfd))
1705 {
1706 default:
1707 case 0: val = E_V850_ARCH; break;
1708 /* start-sanitize-v850e */
1709 case bfd_mach_v850e: val = E_V850E_ARCH; break;
1710 case bfd_mach_v850eq: val = E_V850EQ_ARCH; break;
1711 /* end-sanitize-v850e */
1712 }
1713
1714 elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1715 elf_elfheader (abfd)->e_flags |= val;
1716 }
1717
1718 /* Function to keep V850 specific file flags. */
1719 boolean
1720 v850_elf_set_private_flags (abfd, flags)
1721 bfd * abfd;
1722 flagword flags;
1723 {
1724 BFD_ASSERT (!elf_flags_init (abfd)
1725 || elf_elfheader (abfd)->e_flags == flags);
1726
1727 elf_elfheader (abfd)->e_flags = flags;
1728 elf_flags_init (abfd) = true;
1729 return true;
1730 }
1731
1732 /* Copy backend specific data from one object module to another */
1733 boolean
1734 v850_elf_copy_private_bfd_data (ibfd, obfd)
1735 bfd * ibfd;
1736 bfd * obfd;
1737 {
1738 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1739 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1740 return true;
1741
1742 BFD_ASSERT (!elf_flags_init (obfd)
1743 || (elf_elfheader (obfd)->e_flags
1744 == elf_elfheader (ibfd)->e_flags));
1745
1746 elf_gp (obfd) = elf_gp (ibfd);
1747 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1748 elf_flags_init (obfd) = true;
1749 return true;
1750 }
1751
1752 /* Merge backend specific data from an object file to the output
1753 object file when linking. */
1754 boolean
1755 v850_elf_merge_private_bfd_data (ibfd, obfd)
1756 bfd * ibfd;
1757 bfd * obfd;
1758 {
1759 flagword old_flags;
1760 flagword new_flags;
1761
1762 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1763 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1764 return true;
1765
1766 new_flags = elf_elfheader (ibfd)->e_flags;
1767 old_flags = elf_elfheader (obfd)->e_flags;
1768
1769 if (! elf_flags_init (obfd))
1770 {
1771 elf_flags_init (obfd) = true;
1772 elf_elfheader (obfd)->e_flags = new_flags;
1773
1774 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1775 && bfd_get_arch_info (obfd)->the_default)
1776 {
1777 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1778 }
1779
1780 return true;
1781 }
1782
1783 /* Check flag compatibility. */
1784
1785 if (new_flags == old_flags)
1786 return true;
1787
1788 if ((new_flags & EF_V850_ARCH) != (old_flags & EF_V850_ARCH))
1789 {
1790 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1791 bfd_get_filename (ibfd));
1792 #if 0
1793 bfd_set_error (bfd_error_bad_value);
1794 return false;
1795 #else
1796 return true;
1797 #endif
1798 }
1799
1800 return true;
1801 }
1802 /* Display the flags field */
1803
1804 static boolean
1805 v850_elf_print_private_bfd_data (abfd, ptr)
1806 bfd * abfd;
1807 PTR ptr;
1808 {
1809 FILE * file = (FILE *) ptr;
1810
1811 BFD_ASSERT (abfd != NULL && ptr != NULL)
1812
1813 fprintf (file, "private flags = %x", elf_elfheader (abfd)->e_flags);
1814
1815 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1816 {
1817 default:
1818 case E_V850_ARCH: fprintf (file, ": v850 architecture"); break;
1819 /* start-sanitize-v850e */
1820 case E_V850E_ARCH: fprintf (file, ": v850e architecture"); break;
1821 case E_V850EQ_ARCH: fprintf (file, ": v850eq architecture"); break;
1822 /* end-sanitize-v850e */
1823 }
1824
1825 fputc ('\n', file);
1826
1827 return true;
1828 }
1829
1830 /* V850 ELF uses four common sections. One is the usual one, and the
1831 others are for (small) objects in one of the special data areas:
1832 small, tiny and zero. All the objects are kept together, and then
1833 referenced via the gp register, the ep register or the r0 register
1834 respectively, which yields smaller, faster assembler code. This
1835 approach is copied from elf32-mips.c. */
1836
1837 static asection v850_elf_scom_section;
1838 static asymbol v850_elf_scom_symbol;
1839 static asymbol * v850_elf_scom_symbol_ptr;
1840 static asection v850_elf_tcom_section;
1841 static asymbol v850_elf_tcom_symbol;
1842 static asymbol * v850_elf_tcom_symbol_ptr;
1843 static asection v850_elf_zcom_section;
1844 static asymbol v850_elf_zcom_symbol;
1845 static asymbol * v850_elf_zcom_symbol_ptr;
1846
1847
1848 /* Given a BFD section, try to locate the corresponding ELF section
1849 index. */
1850
1851 static boolean
1852 v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
1853 bfd * abfd;
1854 Elf32_Internal_Shdr * hdr;
1855 asection * sec;
1856 int * retval;
1857 {
1858 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
1859 {
1860 *retval = SHN_V850_SCOMMON;
1861 return true;
1862 }
1863 if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
1864 {
1865 *retval = SHN_V850_TCOMMON;
1866 return true;
1867 }
1868 if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
1869 {
1870 *retval = SHN_V850_ZCOMMON;
1871 return true;
1872 }
1873 return false;
1874 }
1875
1876 /* Handle the special V850 section numbers that a symbol may use. */
1877
1878 static void
1879 v850_elf_symbol_processing (abfd, asym)
1880 bfd * abfd;
1881 asymbol * asym;
1882 {
1883 elf_symbol_type * elfsym = (elf_symbol_type *) asym;
1884
1885 switch (elfsym->internal_elf_sym.st_shndx)
1886 {
1887 case SHN_V850_SCOMMON:
1888 if (v850_elf_scom_section.name == NULL)
1889 {
1890 /* Initialize the small common section. */
1891 v850_elf_scom_section.name = ".scommon";
1892 v850_elf_scom_section.flags = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
1893 v850_elf_scom_section.output_section = & v850_elf_scom_section;
1894 v850_elf_scom_section.symbol = & v850_elf_scom_symbol;
1895 v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
1896 v850_elf_scom_symbol.name = ".scommon";
1897 v850_elf_scom_symbol.flags = BSF_SECTION_SYM;
1898 v850_elf_scom_symbol.section = & v850_elf_scom_section;
1899 v850_elf_scom_symbol_ptr = & v850_elf_scom_symbol;
1900 }
1901 asym->section = & v850_elf_scom_section;
1902 asym->value = elfsym->internal_elf_sym.st_size;
1903 break;
1904
1905 case SHN_V850_TCOMMON:
1906 if (v850_elf_tcom_section.name == NULL)
1907 {
1908 /* Initialize the tcommon section. */
1909 v850_elf_tcom_section.name = ".tcommon";
1910 v850_elf_tcom_section.flags = SEC_IS_COMMON;
1911 v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
1912 v850_elf_tcom_section.symbol = & v850_elf_tcom_symbol;
1913 v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
1914 v850_elf_tcom_symbol.name = ".tcommon";
1915 v850_elf_tcom_symbol.flags = BSF_SECTION_SYM;
1916 v850_elf_tcom_symbol.section = & v850_elf_tcom_section;
1917 v850_elf_tcom_symbol_ptr = & v850_elf_tcom_symbol;
1918 }
1919 asym->section = & v850_elf_tcom_section;
1920 asym->value = elfsym->internal_elf_sym.st_size;
1921 break;
1922
1923 case SHN_V850_ZCOMMON:
1924 if (v850_elf_zcom_section.name == NULL)
1925 {
1926 /* Initialize the zcommon section. */
1927 v850_elf_zcom_section.name = ".zcommon";
1928 v850_elf_zcom_section.flags = SEC_IS_COMMON;
1929 v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
1930 v850_elf_zcom_section.symbol = & v850_elf_zcom_symbol;
1931 v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
1932 v850_elf_zcom_symbol.name = ".zcommon";
1933 v850_elf_zcom_symbol.flags = BSF_SECTION_SYM;
1934 v850_elf_zcom_symbol.section = & v850_elf_zcom_section;
1935 v850_elf_zcom_symbol_ptr = & v850_elf_zcom_symbol;
1936 }
1937 asym->section = & v850_elf_zcom_section;
1938 asym->value = elfsym->internal_elf_sym.st_size;
1939 break;
1940 }
1941 }
1942
1943 /* Hook called by the linker routine which adds symbols from an object
1944 file. We must handle the special MIPS section numbers here. */
1945
1946 /*ARGSUSED*/
1947 static boolean
1948 v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1949 bfd * abfd;
1950 struct bfd_link_info * info;
1951 const Elf_Internal_Sym * sym;
1952 const char ** namep;
1953 flagword * flagsp;
1954 asection ** secp;
1955 bfd_vma * valp;
1956 {
1957 switch (sym->st_shndx)
1958 {
1959 case SHN_V850_SCOMMON:
1960 *secp = bfd_make_section_old_way (abfd, ".scommon");
1961 (*secp)->flags |= SEC_IS_COMMON;
1962 *valp = sym->st_size;
1963 break;
1964
1965 case SHN_V850_TCOMMON:
1966 *secp = bfd_make_section_old_way (abfd, ".tcommon");
1967 (*secp)->flags |= SEC_IS_COMMON;
1968 *valp = sym->st_size;
1969 break;
1970
1971 case SHN_V850_ZCOMMON:
1972 *secp = bfd_make_section_old_way (abfd, ".zcommon");
1973 (*secp)->flags |= SEC_IS_COMMON;
1974 *valp = sym->st_size;
1975 break;
1976 }
1977
1978 return true;
1979 }
1980
1981 /*ARGSIGNORED*/
1982 static boolean
1983 v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
1984 bfd * abfd;
1985 struct bfd_link_info * info;
1986 const char * name;
1987 Elf_Internal_Sym * sym;
1988 asection * input_sec;
1989 {
1990 /* If we see a common symbol, which implies a relocatable link, then
1991 if a symbol was in a special common section in an input file, mark
1992 it as a special common in the output file. */
1993
1994 if (sym->st_shndx == SHN_COMMON)
1995 {
1996 if (strcmp (input_sec->name, ".scommon") == 0)
1997 sym->st_shndx = SHN_V850_SCOMMON;
1998 else if (strcmp (input_sec->name, ".tcommon") == 0)
1999 sym->st_shndx = SHN_V850_TCOMMON;
2000 else if (strcmp (input_sec->name, ".zcommon") == 0)
2001 sym->st_shndx = SHN_V850_ZCOMMON;
2002 }
2003
2004 return true;
2005 }
2006
2007 static boolean
2008 v850_elf_section_from_shdr (abfd, hdr, name)
2009 bfd * abfd;
2010 Elf_Internal_Shdr * hdr;
2011 char * name;
2012 {
2013 /* There ought to be a place to keep ELF backend specific flags, but
2014 at the moment there isn't one. We just keep track of the
2015 sections by their name, instead. */
2016
2017 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
2018 return false;
2019
2020 switch (hdr->sh_type)
2021 {
2022 case SHT_V850_SCOMMON:
2023 case SHT_V850_TCOMMON:
2024 case SHT_V850_ZCOMMON:
2025 if (! bfd_set_section_flags (abfd, hdr->bfd_section,
2026 (bfd_get_section_flags (abfd,
2027 hdr->bfd_section)
2028 | SEC_IS_COMMON)))
2029 return false;
2030 }
2031
2032 return true;
2033 }
2034
2035 /* Set the correct type for a V850 ELF section. We do this by the
2036 section name, which is a hack, but ought to work. */
2037 static boolean
2038 v850_elf_fake_sections (abfd, hdr, sec)
2039 bfd * abfd;
2040 Elf32_Internal_Shdr * hdr;
2041 asection * sec;
2042 {
2043 register const char * name;
2044
2045 name = bfd_get_section_name (abfd, sec);
2046
2047 if (strcmp (name, ".scommon") == 0)
2048 {
2049 hdr->sh_type = SHT_V850_SCOMMON;
2050 }
2051 else if (strcmp (name, ".tcommon") == 0)
2052 {
2053 hdr->sh_type = SHT_V850_TCOMMON;
2054 }
2055 else if (strcmp (name, ".zcommon") == 0)
2056 hdr->sh_type = SHT_V850_ZCOMMON;
2057
2058 return true;
2059 }
2060
2061
2062 \f
2063 #define TARGET_LITTLE_SYM bfd_elf32_v850_vec
2064 #define TARGET_LITTLE_NAME "elf32-v850"
2065 #define ELF_ARCH bfd_arch_v850
2066 #define ELF_MACHINE_CODE EM_CYGNUS_V850
2067 #define ELF_MAXPAGESIZE 0x1000
2068
2069 #define elf_info_to_howto 0
2070 #define elf_info_to_howto_rel v850_elf_info_to_howto_rel
2071
2072 #define elf_backend_check_relocs v850_elf_check_relocs
2073 #define elf_backend_relocate_section v850_elf_relocate_section
2074 #define elf_backend_object_p v850_elf_object_p
2075 #define elf_backend_final_write_processing v850_elf_final_write_processing
2076 #define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
2077 #define elf_backend_symbol_processing v850_elf_symbol_processing
2078 #define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
2079 #define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
2080 #define elf_backend_section_from_shdr v850_elf_section_from_shdr
2081 #define elf_backend_fake_sections v850_elf_fake_sections
2082
2083 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
2084 #define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
2085 #define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
2086 #define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
2087 #define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
2088 #define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
2089
2090 #define elf_symbol_leading_char '_'
2091
2092 #include "elf32-target.h"
This page took 0.102966 seconds and 4 git commands to generate.