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