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