* decode.c, sem.c: Regenerate.
[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 *));
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{
75172c0f
NC
653 static long last_hi16s_addend;
654 static bfd_byte * last_hi16s_address;
22a9f052 655 unsigned long insn;
5ddf2a9e 656
22a9f052 657 switch (r_type)
5ddf2a9e
NC
658 {
659 default:
22a9f052 660 /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
5ddf2a9e
NC
661 return bfd_reloc_notsupported;
662
22a9f052
NC
663 case R_V850_32:
664 if (! replace)
665 addend += bfd_get_32 (abfd, address);
666
667 bfd_put_32 (abfd, addend, address);
668 return bfd_reloc_ok;
669
5ddf2a9e 670 case R_V850_22_PCREL:
22a9f052 671 if (addend > 0x1fffff || addend < -0x200000)
5ddf2a9e
NC
672 return bfd_reloc_overflow;
673
22a9f052 674 if ((addend % 2) != 0)
5ddf2a9e
NC
675 return bfd_reloc_dangerous;
676
22a9f052 677 insn = bfd_get_32 (abfd, address);
5ddf2a9e 678 insn &= ~0xfffe003f;
22a9f052
NC
679 insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
680 bfd_put_32 (abfd, insn, address);
5ddf2a9e
NC
681 return bfd_reloc_ok;
682
683 case R_V850_9_PCREL:
22a9f052 684 if (addend > 0xff || addend < -0x100)
5ddf2a9e
NC
685 return bfd_reloc_overflow;
686
22a9f052 687 if ((addend % 2) != 0)
5ddf2a9e
NC
688 return bfd_reloc_dangerous;
689
22a9f052 690 insn = bfd_get_16 (abfd, address);
5ddf2a9e 691 insn &= ~ 0xf870;
22a9f052
NC
692 insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
693 break;
5ddf2a9e
NC
694
695 case R_V850_HI16_S:
75172c0f
NC
696 last_hi16s_addend = addend;
697 last_hi16s_address = address;
698
0a5875fc 699 addend += (bfd_get_16 (abfd, address) << 16);
22a9f052 700 addend = (addend >> 16) + ((addend & 0x8000) != 0);
75172c0f
NC
701 /* This relocation cannot overflow. */
702 if (addend > 0x7fff || addend < -0x8000)
703 addend = 0;
22a9f052
NC
704 insn = addend;
705 break;
5ddf2a9e
NC
706
707 case R_V850_HI16:
0a5875fc 708 addend += (bfd_get_16 (abfd, address) << 16);
22a9f052
NC
709 addend = (addend >> 16);
710 insn = addend;
711 break;
5ddf2a9e
NC
712
713 case R_V850_LO16:
75172c0f
NC
714 /* Calculate the sum of the value stored in the instruction and the
715 addend and check for overflow from the low 16 bits into the high
716 16 bits. This can occur if the computation sets the 16th bit when
717 before it was clear, since the 16th bit will be sign extended into
718 the high part, thus reducing its value by one, but since the 16th bit
719 was originally clear, the previous R_V850_HI16_S relocation will not
720 have added in an additional 1 to the high part to compensate for this
721 effect. Overflow can also occur if the compuation carries into the
722 17th bit and it also results in the 16th bit having the same value as
723 the 16th bit of the original value. What happens is that the
724 R_V850_HI16_S relocation will have already examined the 16th bit of
725 the original value and added 1 to the high part if the bit is set.
726 This compensates for the sign extension of 16th bit of the result of
727 the computation. But now there is a carry into the 17th bit, and this
728 has not been allowed for. Note - there is no need to change anything
729 if a carry occurs, and the 16th bit changes its value, (this can only
730 happen if the bit was set in the original value, but is clear in the
731 result of the computation), as the R_V850_HI16_S relocation will have
732 already added in 1 to the high part for us. Here are some examples:
733
734 original value = 0x12345
735 addend = 0x01234
736 -------
737 0x13579 => R_V850_HI16_S stores 0x0001
738 R_V850_LO16 stores 0x3579
739
740 This is OK.
741
742 original value = 0x12345
743 addend = 0x07000
744 -------
745 0x19345 => R_V850_HI16_S stores 0x0001
746 R_V850_LO16 stores 0x9345
747
748 but the 0x9345 value gets sign
749 extended, so the sum becomes:
750
751 0x00010000
752 0xffff9345
753 ----------
754 0x00009345 which is wrong.
755
756 This is the first example of overflow.
757
758 original value = 0x18888
759 addend = 0x08888
760 -------
761 0x21110 => R_V850_HI16_S stores 0x0002 (because 16th bit of the original value is set)
762 R_V850_LO16 stores 0x1110
763
764 and the sum is now:
765
766 0x00020000
767 0x00001110
768 ----------
769 0x00021110 which is OK.
770
771 original value = 0x1ffff
772 addend = 0x08888
773 -------
774 0x28887 => R_V850_HI16_S stores 0x0002
775 R_V850_LO16 stores 0x8887
776
777 and the sum is now:
778
779 0x00020000
780 0xffff8887
781 ----------
782 0x00018887 which is wrong.
783
784 This is the second example of overflow.
785 (The 16th bit remains set).
786
787 original value = 0x15555
788 addend = 0x0ffff
789 -------
790 0x25554 => R_V850_HI16_S stores 0x0001
791 R_V850_LO16 stores 0x5554
792
793 the sum is now:
794
795 0x00010000
796 0x00005554
797 ----------
798 0x00015554 which is wrong.
799
800 This is the other form of the second
801 example of overflow. (The 16th bit
802 remains clear)
803 */
804
805 {
806 long result;
807
808 insn = bfd_get_16 (abfd, address);
809 result = insn + addend;
810
811#define BIT16_SET(x) ((x) & 0x8000)
812#define OVERFLOWS(a,i) (((a) & 0xffff) + (i) > 0xffff)
813
814 if ((BIT16_SET (result) && ! BIT16_SET (addend))
815 || (OVERFLOWS (addend, insn)
816 && (BIT16_SET (result) == BIT16_SET (addend))))
817 {
818 /* Amend the preceding HI16_S relocation, allowing for
819 an intervening instruction, which does occasionally happen. */
820 if ( (addend == last_hi16s_addend)
821 && ( (address == last_hi16s_address + 4)
822 || (address == last_hi16s_address + 8)))
823 {
824 insn = bfd_get_16 (abfd, last_hi16s_address);
825 insn += 1;
826 bfd_put_16 (abfd, insn, last_hi16s_address);
827 }
828 else
829 {
830 fprintf (stderr, "FAILED to find previous HI16 reloc:\n");
831 fprintf (stderr, "addend = %x, last_hi16s_added = %x, address = %x, last_address = %x\n",
832 addend, last_hi16s_addend, address, last_hi16s_address);
833 fprintf (stderr, "addend = %x, result = %x, insn = %x\n",
834 addend, result, insn);
835 return bfd_reloc_overflow;
836 }
837 }
838
839 /* Do not complain if value has top bit set, as this has been anticipated. */
840 insn = result & 0xffff;
841 }
842 break;
843
844 case R_V850_8:
845 if (! replace)
846 addend += (char) bfd_get_8 (abfd, address);
847
848 if (addend > 0x7f || addend < -0x80)
849 return bfd_reloc_overflow;
850
851 bfd_put_8 (abfd, addend, address);
852 return bfd_reloc_ok;
def31039 853
22a9f052
NC
854/* start-sanitize-v850e */
855 case R_V850_CALLT_16_16_OFFSET:
75172c0f
NC
856 if (! replace)
857 addend += bfd_get_16 (abfd, address);
858
859 if (addend > 0xffff || addend < 0)
860 return bfd_reloc_overflow;
861
862 insn = addend;
863 break;
22a9f052 864/* end-sanitize-v850e */
75172c0f
NC
865
866 case R_V850_16:
867 replace = false;
868 /* drop through */
5ddf2a9e
NC
869 case R_V850_SDA_16_16_OFFSET:
870 case R_V850_ZDA_16_16_OFFSET:
5bb28764 871 case R_V850_TDA_16_16_OFFSET:
22a9f052
NC
872 if (! replace)
873 addend += bfd_get_16 (abfd, address);
874
875 if (addend > 0x7fff || addend < -0x8000)
5ddf2a9e 876 return bfd_reloc_overflow;
22a9f052
NC
877
878 insn = addend;
879 break;
5ddf2a9e
NC
880
881 case R_V850_SDA_15_16_OFFSET:
882 case R_V850_ZDA_15_16_OFFSET:
22a9f052
NC
883 insn = bfd_get_16 (abfd, address);
884
885 if (! replace)
75172c0f 886 addend += (insn & 0xfffe);
22a9f052
NC
887
888 if (addend > 0x7ffe || addend < -0x8000)
5ddf2a9e
NC
889 return bfd_reloc_overflow;
890
22a9f052 891 if (addend & 1)
5ddf2a9e
NC
892 return bfd_reloc_dangerous;
893
75172c0f 894 insn = (addend & ~1) | (insn & 1);
22a9f052 895 break;
5ddf2a9e
NC
896
897 case R_V850_TDA_6_8_OFFSET:
22a9f052
NC
898 insn = bfd_get_16 (abfd, address);
899
900 if (! replace)
901 addend += ((insn & 0x7e) << 1);
902
903 if (addend > 0xfc || addend < 0)
5ddf2a9e
NC
904 return bfd_reloc_overflow;
905
22a9f052 906 if (addend & 3)
5ddf2a9e
NC
907 return bfd_reloc_dangerous;
908
5ddf2a9e 909 insn &= 0xff81;
22a9f052
NC
910 insn |= (addend >> 1);
911 break;
5ddf2a9e
NC
912
913 case R_V850_TDA_7_8_OFFSET:
22a9f052
NC
914 insn = bfd_get_16 (abfd, address);
915
916 if (! replace)
917 addend += ((insn & 0x7f) << 1);
918
919 if (addend > 0xfe || addend < 0)
5ddf2a9e
NC
920 return bfd_reloc_overflow;
921
22a9f052 922 if (addend & 1)
5ddf2a9e
NC
923 return bfd_reloc_dangerous;
924
5ddf2a9e 925 insn &= 0xff80;
22a9f052
NC
926 insn |= (addend >> 1);
927 break;
5ddf2a9e
NC
928
929 case R_V850_TDA_7_7_OFFSET:
22a9f052
NC
930 insn = bfd_get_16 (abfd, address);
931
932 if (! replace)
933 addend += insn & 0x7f;
934
935 if (addend > 0x7f || addend < 0)
5ddf2a9e
NC
936 return bfd_reloc_overflow;
937
5ddf2a9e 938 insn &= 0xff80;
22a9f052
NC
939 insn |= addend;
940 break;
5ddf2a9e 941
def31039 942/* start-sanitize-v850e */
5ddf2a9e 943 case R_V850_TDA_4_5_OFFSET:
22a9f052
NC
944 insn = bfd_get_16 (abfd, address);
945
946 if (! replace)
947 addend += ((insn & 0xf) << 1);
948
949 if (addend > 0x1e || addend < 0)
5ddf2a9e
NC
950 return bfd_reloc_overflow;
951
22a9f052 952 if (addend & 1)
5ddf2a9e
NC
953 return bfd_reloc_dangerous;
954
5ddf2a9e 955 insn &= 0xfff0;
22a9f052
NC
956 insn |= (addend >> 1);
957 break;
5ddf2a9e
NC
958
959 case R_V850_TDA_4_4_OFFSET:
22a9f052
NC
960 insn = bfd_get_16 (abfd, address);
961
962 if (! replace)
963 addend += insn & 0xf;
964
965 if (addend > 0xf || addend < 0)
5ddf2a9e
NC
966 return bfd_reloc_overflow;
967
5ddf2a9e 968 insn &= 0xfff0;
22a9f052
NC
969 insn |= addend;
970 break;
5ddf2a9e
NC
971
972 case R_V850_ZDA_16_16_SPLIT_OFFSET:
973 case R_V850_SDA_16_16_SPLIT_OFFSET:
22a9f052
NC
974 insn = bfd_get_32 (abfd, address);
975
976 if (! replace)
977 addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
5ddf2a9e 978
75172c0f 979 if (addend > 0x7fff || addend < -0x8000)
22a9f052 980 return bfd_reloc_overflow;
5ddf2a9e
NC
981
982 insn &= 0x0001ffdf;
22a9f052
NC
983 insn |= (addend & 1) << 5;
984 insn |= (addend & ~1) << 16;
5ddf2a9e 985
22a9f052 986 bfd_put_32 (abfd, insn, address);
5ddf2a9e 987 return bfd_reloc_ok;
9420c20a
NC
988
989 case R_V850_CALLT_6_7_OFFSET:
22a9f052
NC
990 insn = bfd_get_16 (abfd, address);
991
992 if (! replace)
993 addend += ((insn & 0x3f) << 1);
994
995 if (addend > 0x7e || addend < 0)
9420c20a
NC
996 return bfd_reloc_overflow;
997
22a9f052 998 if (addend & 1)
9420c20a
NC
999 return bfd_reloc_dangerous;
1000
9420c20a 1001 insn &= 0xff80;
22a9f052
NC
1002 insn |= (addend >> 1);
1003 break;
1004/* end-sanitize-v850e */
1005 }
1006
1007 bfd_put_16 (abfd, insn, address);
1008 return bfd_reloc_ok;
1009}
1010
1011\f
1012/* Insert the addend into the instruction. */
1013static bfd_reloc_status_type
1014v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
1015 bfd * abfd;
1016 arelent * reloc;
1017 asymbol * symbol;
1018 PTR data;
1019 asection * isection;
1020 bfd * obfd;
1021 char ** err;
1022{
1023 long relocation;
1024 long insn;
1025
1026
1027 /* If there is an output BFD,
1028 and the symbol is not a section name (which is only defined at final link time),
1029 and either we are not putting the addend into the instruction
1030 or the addend is zero, so there is nothing to add into the instruction
1031 then just fixup the address and return. */
1032 if (obfd != (bfd *) NULL
1033 && (symbol->flags & BSF_SECTION_SYM) == 0
1034 && (! reloc->howto->partial_inplace
1035 || reloc->addend == 0))
1036 {
1037 reloc->address += isection->output_offset;
9420c20a 1038 return bfd_reloc_ok;
22a9f052
NC
1039 }
1040#if 0
1041 else if (obfd != NULL)
1042 {
1043 return bfd_reloc_continue;
1044 }
1045#endif
1046
1047 /* Catch relocs involving undefined symbols. */
1048 if (bfd_is_und_section (symbol->section)
1049 && (symbol->flags & BSF_WEAK) == 0
1050 && obfd == NULL)
1051 return bfd_reloc_undefined;
1052
1053 /* We handle final linking of some relocs ourselves. */
1054
1055 /* Is the address of the relocation really within the section? */
1056 if (reloc->address > isection->_cooked_size)
1057 return bfd_reloc_outofrange;
1058
1059 /* Work out which section the relocation is targetted at and the
1060 initial relocation command value. */
1061
1062 /* Get symbol value. (Common symbols are special.) */
1063 if (bfd_is_com_section (symbol->section))
1064 relocation = 0;
1065 else
1066 relocation = symbol->value;
1067
1068 /* Convert input-section-relative symbol value to absolute + addend. */
1069 relocation += symbol->section->output_section->vma;
1070 relocation += symbol->section->output_offset;
1071 relocation += reloc->addend;
1072
1073 if (reloc->howto->pc_relative == true)
1074 {
1075 /* Here the variable relocation holds the final address of the
1076 symbol we are relocating against, plus any addend. */
1077 relocation -= isection->output_section->vma + isection->output_offset;
9420c20a 1078
22a9f052
NC
1079 /* Deal with pcrel_offset */
1080 relocation -= reloc->address;
e73b6ae6
JL
1081 }
1082
22a9f052
NC
1083 /* I've got no clue... */
1084 reloc->addend = 0;
1085
1086 return v850_elf_store_addend_in_insn (abfd, reloc->howto->type, relocation,
1087 (bfd_byte *) data + reloc->address, true);
e73b6ae6
JL
1088}
1089
de224d6a 1090\f
1336da39
SG
1091/*ARGSUSED*/
1092static boolean
8988d935 1093v850_elf_is_local_label_name (abfd, name)
9420c20a
NC
1094 bfd * abfd;
1095 const char * name;
1336da39 1096{
22a9f052
NC
1097 return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
1098 || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_'));
1336da39
SG
1099}
1100
de224d6a 1101\f
725b96f5
JL
1102/* Perform a relocation as part of a final link. */
1103static bfd_reloc_status_type
de224d6a 1104v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
725b96f5
JL
1105 input_section, contents, offset, value,
1106 addend, info, sym_sec, is_local)
def31039
NC
1107 reloc_howto_type * howto;
1108 bfd * input_bfd;
1109 bfd * output_bfd;
1110 asection * input_section;
1111 bfd_byte * contents;
1112 bfd_vma offset;
1113 bfd_vma value;
1114 bfd_vma addend;
1115 struct bfd_link_info * info;
1116 asection * sym_sec;
1117 int is_local;
725b96f5 1118{
def31039
NC
1119 unsigned long r_type = howto->type;
1120 bfd_byte * hit_data = contents + offset;
725b96f5 1121
75172c0f 1122 /* Adjust the value according to the relocation. */
725b96f5
JL
1123 switch (r_type)
1124 {
1125 case R_V850_9_PCREL:
1126 value -= (input_section->output_section->vma
1127 + input_section->output_offset);
1128 value -= offset;
75172c0f 1129 break;
725b96f5
JL
1130
1131 case R_V850_22_PCREL:
1132 value -= (input_section->output_section->vma
22a9f052
NC
1133 + input_section->output_offset
1134 + offset);
1135
1136 value = SEXT24 (value); /* Only the bottom 24 bits of the PC are valid */
75172c0f 1137 break;
725b96f5
JL
1138
1139 case R_V850_HI16_S:
725b96f5 1140 case R_V850_HI16:
725b96f5 1141 case R_V850_LO16:
725b96f5 1142 case R_V850_16:
75172c0f
NC
1143 case R_V850_32:
1144 case R_V850_8:
1145 break;
725b96f5 1146
def31039 1147 case R_V850_ZDA_15_16_OFFSET:
75172c0f
NC
1148 case R_V850_ZDA_16_16_OFFSET:
1149/* start-sanitize-v850e */
1150 case R_V850_ZDA_16_16_SPLIT_OFFSET:
1151/* end-sanitize-v850e */
db1fa6ab
NC
1152 if (sym_sec == NULL)
1153 return bfd_reloc_undefined;
1154
def31039 1155 value -= sym_sec->output_section->vma;
75172c0f 1156 break;
725b96f5 1157
75172c0f 1158 case R_V850_SDA_15_16_OFFSET:
def31039 1159 case R_V850_SDA_16_16_OFFSET:
75172c0f
NC
1160/* start-sanitize-v850e */
1161 case R_V850_SDA_16_16_SPLIT_OFFSET:
1162/* end-sanitize-v850e */
725b96f5 1163 {
def31039
NC
1164 unsigned long gp;
1165 struct bfd_link_hash_entry * h;
725b96f5 1166
75172c0f
NC
1167 if (sym_sec == NULL)
1168 return bfd_reloc_undefined;
db1fa6ab 1169
def31039
NC
1170 /* Get the value of __gp. */
1171 h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1172 if (h == (struct bfd_link_hash_entry *) NULL
1173 || h->type != bfd_link_hash_defined)
1174 return bfd_reloc_other;
1175
1176 gp = (h->u.def.value
1177 + h->u.def.section->output_section->vma
1178 + h->u.def.section->output_offset);
75172c0f 1179
def31039
NC
1180 value -= sym_sec->output_section->vma;
1181 value -= (gp - sym_sec->output_section->vma);
5bb28764 1182 }
75172c0f 1183 break;
5bb28764 1184
def31039 1185/* start-sanitize-v850e */
75172c0f 1186 case R_V850_TDA_4_4_OFFSET:
def31039 1187 case R_V850_TDA_4_5_OFFSET:
75172c0f
NC
1188/* end-sanitize-v850e */
1189 case R_V850_TDA_16_16_OFFSET:
1190 case R_V850_TDA_7_7_OFFSET:
1191 case R_V850_TDA_7_8_OFFSET:
1192 case R_V850_TDA_6_8_OFFSET:
def31039
NC
1193 {
1194 unsigned long ep;
1195 struct bfd_link_hash_entry * h;
1196
1197 /* Get the value of __ep. */
1198 h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1199 if (h == (struct bfd_link_hash_entry *) NULL
1200 || h->type != bfd_link_hash_defined)
1201 return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
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);
c322f1b5 1206
def31039 1207 value -= ep;
def31039 1208 }
75172c0f 1209 break;
def31039 1210
75172c0f 1211/* start-sanitize-v850e */
9420c20a
NC
1212 case R_V850_CALLT_6_7_OFFSET:
1213 {
1214 unsigned long ctbp;
1215 struct bfd_link_hash_entry * h;
1216
1217 /* Get the value of __ctbp. */
1218 h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1219 if (h == (struct bfd_link_hash_entry *) NULL
1220 || h->type != bfd_link_hash_defined)
676d3f02 1221 return (bfd_reloc_dangerous + 1); /* Actually this indicates that __ctbp could not be found. */
9420c20a
NC
1222
1223 ctbp = (h->u.def.value
1224 + h->u.def.section->output_section->vma
1225 + h->u.def.section->output_offset);
1226 value -= ctbp;
9420c20a 1227 }
75172c0f 1228 break;
def31039 1229
9420c20a 1230 case R_V850_CALLT_16_16_OFFSET:
9420c20a
NC
1231 {
1232 unsigned long ctbp;
1233 struct bfd_link_hash_entry * h;
1234
75172c0f
NC
1235 if (sym_sec == NULL)
1236 return bfd_reloc_undefined;
1237
9420c20a
NC
1238 /* Get the value of __ctbp. */
1239 h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1240 if (h == (struct bfd_link_hash_entry *) NULL
1241 || h->type != bfd_link_hash_defined)
676d3f02 1242 return (bfd_reloc_dangerous + 1);
9420c20a
NC
1243
1244 ctbp = (h->u.def.value
1245 + h->u.def.section->output_section->vma
1246 + h->u.def.section->output_offset);
1247
1248 value -= sym_sec->output_section->vma;
1249 value -= (ctbp - sym_sec->output_section->vma);
9420c20a 1250 }
75172c0f 1251 break;
9420c20a 1252/* end-sanitize-v850e */
75172c0f 1253
725b96f5 1254 case R_V850_NONE:
8988d935
NC
1255 return bfd_reloc_ok;
1256
725b96f5 1257 default:
8988d935 1258 return bfd_reloc_notsupported;
725b96f5 1259 }
75172c0f
NC
1260
1261 /* Perform the relocation. */
1262 return v850_elf_store_addend_in_insn (input_bfd, r_type, value, hit_data, false);
725b96f5
JL
1263}
1264
de224d6a 1265\f
725b96f5 1266/* Relocate an V850 ELF section. */
725b96f5
JL
1267static boolean
1268v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
de224d6a 1269 contents, relocs, local_syms, local_sections)
def31039
NC
1270 bfd * output_bfd;
1271 struct bfd_link_info * info;
1272 bfd * input_bfd;
1273 asection * input_section;
1274 bfd_byte * contents;
1275 Elf_Internal_Rela * relocs;
1276 Elf_Internal_Sym * local_syms;
1277 asection ** local_sections;
725b96f5 1278{
def31039
NC
1279 Elf_Internal_Shdr * symtab_hdr;
1280 struct elf_link_hash_entry ** sym_hashes;
1281 Elf_Internal_Rela * rel;
1282 Elf_Internal_Rela * relend;
725b96f5 1283
def31039 1284 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
725b96f5
JL
1285 sym_hashes = elf_sym_hashes (input_bfd);
1286
def31039 1287 rel = relocs;
725b96f5
JL
1288 relend = relocs + input_section->reloc_count;
1289 for (; rel < relend; rel++)
1290 {
def31039
NC
1291 int r_type;
1292 reloc_howto_type * howto;
1293 unsigned long r_symndx;
1294 Elf_Internal_Sym * sym;
1295 asection * sec;
1296 struct elf_link_hash_entry * h;
1297 bfd_vma relocation;
1298 bfd_reloc_status_type r;
725b96f5 1299
8988d935 1300 r_symndx = ELF32_R_SYM (rel->r_info);
def31039
NC
1301 r_type = ELF32_R_TYPE (rel->r_info);
1302 howto = v850_elf_howto_table + r_type;
8988d935 1303
725b96f5
JL
1304 if (info->relocateable)
1305 {
1306 /* This is a relocateable link. We don't have to change
1307 anything, unless the reloc is against a section symbol,
1308 in which case we have to adjust according to where the
1309 section symbol winds up in the output section. */
1310 if (r_symndx < symtab_hdr->sh_info)
1311 {
1312 sym = local_syms + r_symndx;
1313 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1314 {
1315 sec = local_sections[r_symndx];
22a9f052
NC
1316#ifdef USE_REL
1317 /* The Elf_Internal_Rel structure does not have space for the
1318 modified addend value, so we store it in the instruction
1319 instead. */
1320
1321 if (sec->output_offset + sym->st_value != 0)
1322 {
1323 if (v850_elf_store_addend_in_insn (input_bfd, r_type,
1324 sec->output_offset +
1325 sym->st_value,
1326 contents + rel->r_offset,
1327 false)
1328 != bfd_reloc_ok)
1329 {
1330 info->callbacks->warning
1331 (info,
1332 "Unable to handle relocation during incremental link",
1333 NULL, input_bfd, input_section, rel->r_offset);
1334 }
1335 }
1336#else
725b96f5 1337 rel->r_addend += sec->output_offset + sym->st_value;
22a9f052 1338#endif
725b96f5
JL
1339 }
1340 }
1341
1342 continue;
1343 }
1344
725b96f5
JL
1345 /* This is a final link. */
1346 h = NULL;
1347 sym = NULL;
1348 sec = NULL;
1349 if (r_symndx < symtab_hdr->sh_info)
1350 {
1351 sym = local_syms + r_symndx;
1352 sec = local_sections[r_symndx];
1353 relocation = (sec->output_section->vma
1354 + sec->output_offset
1355 + sym->st_value);
def31039
NC
1356#if 0
1357 {
1358 char * name;
1359 name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1360 name = (name == NULL) ? "<none>" : name;
75172c0f
NC
1361fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
1362 sec->name, name, sym->st_name,
1363 sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend);
def31039
NC
1364 }
1365#endif
725b96f5
JL
1366 }
1367 else
1368 {
1369 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
def31039 1370
725b96f5
JL
1371 while (h->root.type == bfd_link_hash_indirect
1372 || h->root.type == bfd_link_hash_warning)
1373 h = (struct elf_link_hash_entry *) h->root.u.i.link;
def31039 1374
725b96f5
JL
1375 if (h->root.type == bfd_link_hash_defined
1376 || h->root.type == bfd_link_hash_defweak)
1377 {
1378 sec = h->root.u.def.section;
1379 relocation = (h->root.u.def.value
1380 + sec->output_section->vma
1381 + sec->output_offset);
676d3f02
NC
1382#if 0
1383fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1384 sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
1385#endif
725b96f5
JL
1386 }
1387 else if (h->root.type == bfd_link_hash_undefweak)
676d3f02
NC
1388 {
1389#if 0
1390fprintf (stderr, "undefined: sec: %s, name: %s\n",
1391 sec->name, h->root.root.string);
1392#endif
1393 relocation = 0;
1394 }
725b96f5
JL
1395 else
1396 {
1397 if (! ((*info->callbacks->undefined_symbol)
1398 (info, h->root.root.string, input_bfd,
1399 input_section, rel->r_offset)))
1400 return false;
676d3f02
NC
1401#if 0
1402fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
1403#endif
725b96f5
JL
1404 relocation = 0;
1405 }
1406 }
1407
1408 /* FIXME: We should use the addend, but the COFF relocations
1409 don't. */
de224d6a
MM
1410 r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1411 input_section,
1412 contents, rel->r_offset,
1413 relocation, rel->r_addend,
1414 info, sec, h == NULL);
725b96f5
JL
1415
1416 if (r != bfd_reloc_ok)
1417 {
def31039
NC
1418 const char * name;
1419 const char * msg = (const char *)0;
8988d935
NC
1420
1421 if (h != NULL)
1422 name = h->root.root.string;
1423 else
1424 {
1425 name = (bfd_elf_string_from_elf_section
1426 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1427 if (name == NULL || *name == '\0')
1428 name = bfd_section_name (input_bfd, sec);
1429 }
1430
725b96f5
JL
1431 switch (r)
1432 {
725b96f5 1433 case bfd_reloc_overflow:
8988d935
NC
1434 if (! ((*info->callbacks->reloc_overflow)
1435 (info, name, howto->name, (bfd_vma) 0,
1436 input_bfd, input_section, rel->r_offset)))
1437 return false;
1438 break;
1439
1440 case bfd_reloc_undefined:
1441 if (! ((*info->callbacks->undefined_symbol)
1442 (info, name, input_bfd, input_section,
1443 rel->r_offset)))
1444 return false;
1445 break;
1446
1447 case bfd_reloc_outofrange:
1448 msg = "internal error: out of range error";
1449 goto common_error;
1450
1451 case bfd_reloc_notsupported:
1452 msg = "internal error: unsupported relocation error";
1453 goto common_error;
1454
1455 case bfd_reloc_dangerous:
def31039
NC
1456 msg = "internal error: dangerous relocation";
1457 goto common_error;
1458
1459 case bfd_reloc_other:
1460 msg = "could not locate special linker symbol __gp";
1461 goto common_error;
1462
1463 case bfd_reloc_continue:
1464 msg = "could not locate special linker symbol __ep";
8988d935
NC
1465 goto common_error;
1466
676d3f02
NC
1467 case (bfd_reloc_dangerous + 1):
1468 msg = "could not locate special linker symbol __ctbp";
1469 goto common_error;
1470
8988d935
NC
1471 default:
1472 msg = "internal error: unknown error";
1473 /* fall through */
1474
1475 common_error:
1476 if (!((*info->callbacks->warning)
1477 (info, msg, name, input_bfd, input_section,
1478 rel->r_offset)))
1479 return false;
725b96f5
JL
1480 break;
1481 }
1482 }
1483 }
1484
1485 return true;
1486}
01b49cb3 1487
8988d935 1488/* Set the right machine number. */
8988d935
NC
1489static boolean
1490v850_elf_object_p (abfd)
1491 bfd *abfd;
1492{
8bef8c30 1493 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
8988d935
NC
1494 {
1495 default:
8bef8c30 1496 case E_V850_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
8988d935 1497/* start-sanitize-v850e */
8bef8c30 1498 case E_V850E_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
75172c0f 1499 case E_V850EA_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850ea); break;
15d82b26 1500/* end-sanitize-v850e */
8988d935
NC
1501 }
1502}
1503
8bef8c30
NC
1504/* Store the machine number in the flags field. */
1505void
1506v850_elf_final_write_processing (abfd, linker)
1507 bfd * abfd;
1508 boolean linker;
1509{
1510 unsigned long val;
1511
1512 switch (bfd_get_mach (abfd))
1513 {
1514 default:
1515 case 0: val = E_V850_ARCH; break;
8988d935 1516/* start-sanitize-v850e */
15d82b26 1517 case bfd_mach_v850e: val = E_V850E_ARCH; break;
75172c0f 1518 case bfd_mach_v850ea: val = E_V850EA_ARCH; break;
15d82b26 1519/* end-sanitize-v850e */
8bef8c30
NC
1520 }
1521
1522 elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1523 elf_elfheader (abfd)->e_flags |= val;
1524}
1525
1526/* Function to keep V850 specific file flags. */
1527boolean
1528v850_elf_set_private_flags (abfd, flags)
1529 bfd * abfd;
1530 flagword flags;
1531{
1532 BFD_ASSERT (!elf_flags_init (abfd)
1533 || elf_elfheader (abfd)->e_flags == flags);
1534
1535 elf_elfheader (abfd)->e_flags = flags;
1536 elf_flags_init (abfd) = true;
1537 return true;
1538}
1539
1540/* Copy backend specific data from one object module to another */
1541boolean
1542v850_elf_copy_private_bfd_data (ibfd, obfd)
1543 bfd * ibfd;
1544 bfd * obfd;
1545{
1546 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1547 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1548 return true;
1549
1550 BFD_ASSERT (!elf_flags_init (obfd)
1551 || (elf_elfheader (obfd)->e_flags
1552 == elf_elfheader (ibfd)->e_flags));
1553
1554 elf_gp (obfd) = elf_gp (ibfd);
1555 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1556 elf_flags_init (obfd) = true;
1557 return true;
1558}
1559
1560/* Merge backend specific data from an object file to the output
1561 object file when linking. */
1562boolean
1563v850_elf_merge_private_bfd_data (ibfd, obfd)
1564 bfd * ibfd;
1565 bfd * obfd;
1566{
8b6dcc1b
NC
1567 flagword out_flags;
1568 flagword in_flags;
8bef8c30
NC
1569
1570 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1571 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1572 return true;
1573
8b6dcc1b
NC
1574 in_flags = elf_elfheader (ibfd)->e_flags;
1575 out_flags = elf_elfheader (obfd)->e_flags;
8bef8c30
NC
1576
1577 if (! elf_flags_init (obfd))
1578 {
8b6dcc1b
NC
1579 /* If the input is the default architecture then do not
1580 bother setting the flags for the output architecture,
1581 instead allow future merges to do this. If no future
1582 merges ever set these flags then they will retain their
1583 unitialised values, which surprise surprise, correspond
1584 to the default values. */
1585 if (bfd_get_arch_info (ibfd)->the_default)
1586 return true;
1587
8bef8c30 1588 elf_flags_init (obfd) = true;
8b6dcc1b 1589 elf_elfheader (obfd)->e_flags = in_flags;
8bef8c30
NC
1590
1591 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1592 && bfd_get_arch_info (obfd)->the_default)
1593 {
1594 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1595 }
1596
1597 return true;
1598 }
1599
1600 /* Check flag compatibility. */
8b6dcc1b 1601 if (in_flags == out_flags)
8bef8c30
NC
1602 return true;
1603
8b6dcc1b
NC
1604 if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
1605 && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
1606 _bfd_error_handler ("%s: Architecture mismatch with previous modules",
1607 bfd_get_filename (ibfd));
8bef8c30
NC
1608
1609 return true;
1610}
1611/* Display the flags field */
1612
1613static boolean
1614v850_elf_print_private_bfd_data (abfd, ptr)
1615 bfd * abfd;
1616 PTR ptr;
1617{
1618 FILE * file = (FILE *) ptr;
1619
1620 BFD_ASSERT (abfd != NULL && ptr != NULL)
1621
1622 fprintf (file, "private flags = %x", elf_elfheader (abfd)->e_flags);
1623
1624 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1625 {
1626 default:
98ab32a5 1627 case E_V850_ARCH: fprintf (file, ": v850 architecture"); break;
8bef8c30 1628/* start-sanitize-v850e */
15d82b26 1629 case E_V850E_ARCH: fprintf (file, ": v850e architecture"); break;
75172c0f 1630 case E_V850EA_ARCH: fprintf (file, ": v850ea architecture"); break;
15d82b26 1631/* end-sanitize-v850e */
8bef8c30
NC
1632 }
1633
1634 fputc ('\n', file);
1635
1636 return true;
1637}
22a9f052
NC
1638
1639/* V850 ELF uses four common sections. One is the usual one, and the
1640 others are for (small) objects in one of the special data areas:
1641 small, tiny and zero. All the objects are kept together, and then
1642 referenced via the gp register, the ep register or the r0 register
1643 respectively, which yields smaller, faster assembler code. This
1644 approach is copied from elf32-mips.c. */
1645
1646static asection v850_elf_scom_section;
1647static asymbol v850_elf_scom_symbol;
1648static asymbol * v850_elf_scom_symbol_ptr;
1649static asection v850_elf_tcom_section;
1650static asymbol v850_elf_tcom_symbol;
1651static asymbol * v850_elf_tcom_symbol_ptr;
1652static asection v850_elf_zcom_section;
1653static asymbol v850_elf_zcom_symbol;
1654static asymbol * v850_elf_zcom_symbol_ptr;
1655
1656
1657/* Given a BFD section, try to locate the corresponding ELF section
1658 index. */
1659
1660static boolean
1661v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
1662 bfd * abfd;
1663 Elf32_Internal_Shdr * hdr;
1664 asection * sec;
1665 int * retval;
1666{
1667 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
1668 {
1669 *retval = SHN_V850_SCOMMON;
1670 return true;
1671 }
1672 if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
1673 {
1674 *retval = SHN_V850_TCOMMON;
1675 return true;
1676 }
1677 if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
1678 {
1679 *retval = SHN_V850_ZCOMMON;
1680 return true;
1681 }
1682 return false;
1683}
1684
1685/* Handle the special V850 section numbers that a symbol may use. */
1686
1687static void
1688v850_elf_symbol_processing (abfd, asym)
1689 bfd * abfd;
1690 asymbol * asym;
1691{
1692 elf_symbol_type * elfsym = (elf_symbol_type *) asym;
1693
1694 switch (elfsym->internal_elf_sym.st_shndx)
1695 {
1696 case SHN_V850_SCOMMON:
1697 if (v850_elf_scom_section.name == NULL)
1698 {
1699 /* Initialize the small common section. */
1700 v850_elf_scom_section.name = ".scommon";
1701 v850_elf_scom_section.flags = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
1702 v850_elf_scom_section.output_section = & v850_elf_scom_section;
1703 v850_elf_scom_section.symbol = & v850_elf_scom_symbol;
1704 v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
1705 v850_elf_scom_symbol.name = ".scommon";
1706 v850_elf_scom_symbol.flags = BSF_SECTION_SYM;
1707 v850_elf_scom_symbol.section = & v850_elf_scom_section;
1708 v850_elf_scom_symbol_ptr = & v850_elf_scom_symbol;
1709 }
1710 asym->section = & v850_elf_scom_section;
1711 asym->value = elfsym->internal_elf_sym.st_size;
1712 break;
1713
1714 case SHN_V850_TCOMMON:
1715 if (v850_elf_tcom_section.name == NULL)
1716 {
1717 /* Initialize the tcommon section. */
1718 v850_elf_tcom_section.name = ".tcommon";
1719 v850_elf_tcom_section.flags = SEC_IS_COMMON;
1720 v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
1721 v850_elf_tcom_section.symbol = & v850_elf_tcom_symbol;
1722 v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
1723 v850_elf_tcom_symbol.name = ".tcommon";
1724 v850_elf_tcom_symbol.flags = BSF_SECTION_SYM;
1725 v850_elf_tcom_symbol.section = & v850_elf_tcom_section;
1726 v850_elf_tcom_symbol_ptr = & v850_elf_tcom_symbol;
1727 }
1728 asym->section = & v850_elf_tcom_section;
1729 asym->value = elfsym->internal_elf_sym.st_size;
1730 break;
1731
1732 case SHN_V850_ZCOMMON:
1733 if (v850_elf_zcom_section.name == NULL)
1734 {
1735 /* Initialize the zcommon section. */
1736 v850_elf_zcom_section.name = ".zcommon";
1737 v850_elf_zcom_section.flags = SEC_IS_COMMON;
1738 v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
1739 v850_elf_zcom_section.symbol = & v850_elf_zcom_symbol;
1740 v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
1741 v850_elf_zcom_symbol.name = ".zcommon";
1742 v850_elf_zcom_symbol.flags = BSF_SECTION_SYM;
1743 v850_elf_zcom_symbol.section = & v850_elf_zcom_section;
1744 v850_elf_zcom_symbol_ptr = & v850_elf_zcom_symbol;
1745 }
1746 asym->section = & v850_elf_zcom_section;
1747 asym->value = elfsym->internal_elf_sym.st_size;
1748 break;
1749 }
1750}
1751
1752/* Hook called by the linker routine which adds symbols from an object
1753 file. We must handle the special MIPS section numbers here. */
1754
1755/*ARGSUSED*/
1756static boolean
1757v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1758 bfd * abfd;
1759 struct bfd_link_info * info;
1760 const Elf_Internal_Sym * sym;
1761 const char ** namep;
1762 flagword * flagsp;
1763 asection ** secp;
1764 bfd_vma * valp;
1765{
1766 switch (sym->st_shndx)
1767 {
1768 case SHN_V850_SCOMMON:
1769 *secp = bfd_make_section_old_way (abfd, ".scommon");
1770 (*secp)->flags |= SEC_IS_COMMON;
1771 *valp = sym->st_size;
1772 break;
1773
1774 case SHN_V850_TCOMMON:
1775 *secp = bfd_make_section_old_way (abfd, ".tcommon");
1776 (*secp)->flags |= SEC_IS_COMMON;
1777 *valp = sym->st_size;
1778 break;
1779
1780 case SHN_V850_ZCOMMON:
1781 *secp = bfd_make_section_old_way (abfd, ".zcommon");
1782 (*secp)->flags |= SEC_IS_COMMON;
1783 *valp = sym->st_size;
1784 break;
1785 }
1786
1787 return true;
1788}
1789
1790/*ARGSIGNORED*/
1791static boolean
1792v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
1793 bfd * abfd;
1794 struct bfd_link_info * info;
1795 const char * name;
1796 Elf_Internal_Sym * sym;
1797 asection * input_sec;
1798{
1799 /* If we see a common symbol, which implies a relocatable link, then
1800 if a symbol was in a special common section in an input file, mark
1801 it as a special common in the output file. */
1802
1803 if (sym->st_shndx == SHN_COMMON)
1804 {
1805 if (strcmp (input_sec->name, ".scommon") == 0)
1806 sym->st_shndx = SHN_V850_SCOMMON;
1807 else if (strcmp (input_sec->name, ".tcommon") == 0)
1808 sym->st_shndx = SHN_V850_TCOMMON;
1809 else if (strcmp (input_sec->name, ".zcommon") == 0)
1810 sym->st_shndx = SHN_V850_ZCOMMON;
1811 }
1812
1813 return true;
1814}
1815
1816static boolean
1817v850_elf_section_from_shdr (abfd, hdr, name)
1818 bfd * abfd;
1819 Elf_Internal_Shdr * hdr;
1820 char * name;
1821{
1822 /* There ought to be a place to keep ELF backend specific flags, but
1823 at the moment there isn't one. We just keep track of the
1824 sections by their name, instead. */
1825
1826 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1827 return false;
1828
1829 switch (hdr->sh_type)
1830 {
1831 case SHT_V850_SCOMMON:
1832 case SHT_V850_TCOMMON:
1833 case SHT_V850_ZCOMMON:
1834 if (! bfd_set_section_flags (abfd, hdr->bfd_section,
1835 (bfd_get_section_flags (abfd,
1836 hdr->bfd_section)
1837 | SEC_IS_COMMON)))
1838 return false;
1839 }
1840
1841 return true;
1842}
1843
1844/* Set the correct type for a V850 ELF section. We do this by the
1845 section name, which is a hack, but ought to work. */
1846static boolean
1847v850_elf_fake_sections (abfd, hdr, sec)
1848 bfd * abfd;
1849 Elf32_Internal_Shdr * hdr;
1850 asection * sec;
1851{
1852 register const char * name;
1853
1854 name = bfd_get_section_name (abfd, sec);
1855
1856 if (strcmp (name, ".scommon") == 0)
1857 {
1858 hdr->sh_type = SHT_V850_SCOMMON;
1859 }
1860 else if (strcmp (name, ".tcommon") == 0)
1861 {
1862 hdr->sh_type = SHT_V850_TCOMMON;
1863 }
1864 else if (strcmp (name, ".zcommon") == 0)
1865 hdr->sh_type = SHT_V850_ZCOMMON;
1866
1867 return true;
1868}
1869
1870
8bef8c30
NC
1871\f
1872#define TARGET_LITTLE_SYM bfd_elf32_v850_vec
1873#define TARGET_LITTLE_NAME "elf32-v850"
1874#define ELF_ARCH bfd_arch_v850
1875#define ELF_MACHINE_CODE EM_CYGNUS_V850
de224d6a
MM
1876#define ELF_MAXPAGESIZE 0x1000
1877
1878#define elf_info_to_howto 0
1879#define elf_info_to_howto_rel v850_elf_info_to_howto_rel
22a9f052 1880
de224d6a
MM
1881#define elf_backend_check_relocs v850_elf_check_relocs
1882#define elf_backend_relocate_section v850_elf_relocate_section
8988d935 1883#define elf_backend_object_p v850_elf_object_p
8bef8c30 1884#define elf_backend_final_write_processing v850_elf_final_write_processing
22a9f052
NC
1885#define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
1886#define elf_backend_symbol_processing v850_elf_symbol_processing
1887#define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
1888#define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
1889#define elf_backend_section_from_shdr v850_elf_section_from_shdr
1890#define elf_backend_fake_sections v850_elf_fake_sections
1891
8988d935 1892#define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
de224d6a 1893#define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
8bef8c30
NC
1894#define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
1895#define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
1896#define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
1897#define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
de224d6a
MM
1898
1899#define elf_symbol_leading_char '_'
1336da39 1900
01b49cb3 1901#include "elf32-target.h"
This page took 0.147516 seconds and 4 git commands to generate.