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