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