]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf32-v850.c
2013-01-24 Hafiz Abid Qadeer <abidh@codesourcery.com>
[thirdparty/binutils-gdb.git] / bfd / elf32-v850.c
CommitLineData
252b5132 1/* V850-specific support for 32-bit ELF
e460dd0d 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
dbaa2011
AM
3 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 Free Software Foundation, Inc.
252b5132 5
86aba9db 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
86aba9db
NC
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
cd123cb7 10 the Free Software Foundation; either version 3 of the License, or
86aba9db 11 (at your option) any later version.
252b5132 12
86aba9db
NC
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
252b5132 17
86aba9db
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
47b0e7ad
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
cd123cb7 23
252b5132 24/* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
86aba9db 25 dependencies. As is the gas & simulator code for the v850. */
252b5132 26
252b5132 27#include "sysdep.h"
3db64b00 28#include "bfd.h"
252b5132
RH
29#include "bfdlink.h"
30#include "libbfd.h"
31#include "elf-bfd.h"
32#include "elf/v850.h"
e12dd2ea 33#include "libiberty.h"
252b5132 34
1cd986c5
NC
35/* Sign-extend a 17-bit number. */
36#define SEXT17(x) ((((x) & 0x1ffff) ^ 0x10000) - 0x10000)
37
38/* Sign-extend a 22-bit number. */
39#define SEXT22(x) ((((x) & 0x3fffff) ^ 0x200000) - 0x200000)
435b1e90 40
e460dd0d
AM
41static reloc_howto_type v850_elf_howto_table[];
42
252b5132
RH
43/* Look through the relocs for a section during the first phase, and
44 allocate space in the global offset table or procedure linkage
45 table. */
46
b34976b6 47static bfd_boolean
47b0e7ad
NC
48v850_elf_check_relocs (bfd *abfd,
49 struct bfd_link_info *info,
50 asection *sec,
51 const Elf_Internal_Rela *relocs)
252b5132 52{
b34976b6 53 bfd_boolean ret = TRUE;
252b5132
RH
54 Elf_Internal_Shdr *symtab_hdr;
55 struct elf_link_hash_entry **sym_hashes;
56 const Elf_Internal_Rela *rel;
57 const Elf_Internal_Rela *rel_end;
de863c74 58 unsigned int r_type;
252b5132 59 int other = 0;
47b0e7ad 60 const char *common = NULL;
252b5132 61
1049f94e 62 if (info->relocatable)
b34976b6 63 return TRUE;
252b5132
RH
64
65#ifdef DEBUG
d003868e
AM
66 _bfd_error_handler ("v850_elf_check_relocs called for section %A in %B",
67 sec, abfd);
252b5132
RH
68#endif
69
252b5132
RH
70 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
71 sym_hashes = elf_sym_hashes (abfd);
252b5132
RH
72
73 rel_end = relocs + sec->reloc_count;
74 for (rel = relocs; rel < rel_end; rel++)
75 {
76 unsigned long r_symndx;
77 struct elf_link_hash_entry *h;
78
79 r_symndx = ELF32_R_SYM (rel->r_info);
80 if (r_symndx < symtab_hdr->sh_info)
81 h = NULL;
82 else
973a3492
L
83 {
84 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
85 while (h->root.type == bfd_link_hash_indirect
86 || h->root.type == bfd_link_hash_warning)
87 h = (struct elf_link_hash_entry *) h->root.u.i.link;
88 }
252b5132 89
de863c74 90 r_type = ELF32_R_TYPE (rel->r_info);
252b5132
RH
91 switch (r_type)
92 {
93 default:
252b5132
RH
94 break;
95
96 /* This relocation describes the C++ object vtable hierarchy.
97 Reconstruct it for later use during GC. */
98 case R_V850_GNU_VTINHERIT:
c152c796 99 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
b34976b6 100 return FALSE;
252b5132
RH
101 break;
102
e12dd2ea
NC
103 /* This relocation describes which C++ vtable entries
104 are actually used. Record for later use during GC. */
252b5132 105 case R_V850_GNU_VTENTRY:
d17e0c6e
JB
106 BFD_ASSERT (h != NULL);
107 if (h != NULL
108 && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
b34976b6 109 return FALSE;
252b5132
RH
110 break;
111
112 case R_V850_SDA_16_16_SPLIT_OFFSET:
113 case R_V850_SDA_16_16_OFFSET:
114 case R_V850_SDA_15_16_OFFSET:
de863c74
NC
115 case R_V810_GPWLO_1:
116 case R_V850_HWLO:
117 case R_V850_HWLO_1:
252b5132
RH
118 other = V850_OTHER_SDA;
119 common = ".scommon";
120 goto small_data_common;
435b1e90 121
252b5132
RH
122 case R_V850_ZDA_16_16_SPLIT_OFFSET:
123 case R_V850_ZDA_16_16_OFFSET:
124 case R_V850_ZDA_15_16_OFFSET:
125 other = V850_OTHER_ZDA;
126 common = ".zcommon";
127 goto small_data_common;
435b1e90 128
252b5132 129 case R_V850_TDA_4_4_OFFSET:
1cd986c5
NC
130 case R_V850_TDA_4_5_OFFSET:
131 case R_V850_TDA_7_7_OFFSET:
252b5132
RH
132 case R_V850_TDA_6_8_OFFSET:
133 case R_V850_TDA_7_8_OFFSET:
252b5132
RH
134 case R_V850_TDA_16_16_OFFSET:
135 other = V850_OTHER_TDA;
136 common = ".tcommon";
137 /* fall through */
138
139#define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
140
141 small_data_common:
142 if (h)
143 {
e12dd2ea
NC
144 /* Flag which type of relocation was used. */
145 h->other |= other;
252b5132
RH
146 if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
147 && (h->other & V850_OTHER_ERROR) == 0)
148 {
149 const char * msg;
150 static char buff[200]; /* XXX */
151
152 switch (h->other & V850_OTHER_MASK)
153 {
154 default:
155 msg = _("Variable `%s' cannot occupy in multiple small data regions");
156 break;
157 case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
158 msg = _("Variable `%s' can only be in one of the small, zero, and tiny data regions");
159 break;
160 case V850_OTHER_SDA | V850_OTHER_ZDA:
161 msg = _("Variable `%s' cannot be in both small and zero data regions simultaneously");
162 break;
163 case V850_OTHER_SDA | V850_OTHER_TDA:
164 msg = _("Variable `%s' cannot be in both small and tiny data regions simultaneously");
165 break;
166 case V850_OTHER_ZDA | V850_OTHER_TDA:
167 msg = _("Variable `%s' cannot be in both zero and tiny data regions simultaneously");
168 break;
169 }
170
171 sprintf (buff, msg, h->root.root.string);
172 info->callbacks->warning (info, buff, h->root.root.string,
dc810e39
AM
173 abfd, h->root.u.def.section,
174 (bfd_vma) 0);
252b5132
RH
175
176 bfd_set_error (bfd_error_bad_value);
177 h->other |= V850_OTHER_ERROR;
b34976b6 178 ret = FALSE;
252b5132
RH
179 }
180 }
181
182 if (h && h->root.type == bfd_link_hash_common
183 && h->root.u.c.p
184 && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
185 {
e12dd2ea
NC
186 asection * section;
187
188 section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
252b5132
RH
189 section->flags |= SEC_IS_COMMON;
190 }
191
192#ifdef DEBUG
193 fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
194 v850_elf_howto_table[ (int)r_type ].name,
195 (h && h->root.root.string) ? h->root.root.string : "<unknown>",
196 (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
197#endif
198 break;
199 }
200 }
201
202 return ret;
203}
204
e12dd2ea
NC
205/* In the old version, when an entry was checked out from the table,
206 it was deleted. This produced an error if the entry was needed
207 more than once, as the second attempted retry failed.
208
209 In the current version, the entry is not deleted, instead we set
b34976b6 210 the field 'found' to TRUE. If a second lookup matches the same
e12dd2ea
NC
211 entry, then we know that the hi16s reloc has already been updated
212 and does not need to be updated a second time.
213
214 TODO - TOFIX: If it is possible that we need to restore 2 different
215 addresses from the same table entry, where the first generates an
216 overflow, whilst the second do not, then this code will fail. */
252b5132
RH
217
218typedef struct hi16s_location
219{
47b0e7ad
NC
220 bfd_vma addend;
221 bfd_byte * address;
222 unsigned long counter;
223 bfd_boolean found;
224 struct hi16s_location * next;
252b5132
RH
225}
226hi16s_location;
227
47b0e7ad
NC
228static hi16s_location * previous_hi16s;
229static hi16s_location * free_hi16s;
230static unsigned long hi16s_counter;
252b5132
RH
231
232static void
47b0e7ad 233remember_hi16s_reloc (bfd *abfd, bfd_vma addend, bfd_byte *address)
252b5132
RH
234{
235 hi16s_location * entry = NULL;
dc810e39 236 bfd_size_type amt = sizeof (* free_hi16s);
435b1e90 237
252b5132
RH
238 /* Find a free structure. */
239 if (free_hi16s == NULL)
47b0e7ad 240 free_hi16s = bfd_zalloc (abfd, amt);
252b5132
RH
241
242 entry = free_hi16s;
243 free_hi16s = free_hi16s->next;
435b1e90 244
252b5132
RH
245 entry->addend = addend;
246 entry->address = address;
247 entry->counter = hi16s_counter ++;
b34976b6 248 entry->found = FALSE;
252b5132
RH
249 entry->next = previous_hi16s;
250 previous_hi16s = entry;
435b1e90 251
252b5132
RH
252 /* Cope with wrap around of our counter. */
253 if (hi16s_counter == 0)
254 {
47b0e7ad 255 /* XXX: Assume that all counter entries differ only in their low 16 bits. */
252b5132
RH
256 for (entry = previous_hi16s; entry != NULL; entry = entry->next)
257 entry->counter &= 0xffff;
258
259 hi16s_counter = 0x10000;
260 }
252b5132
RH
261}
262
263static bfd_byte *
47b0e7ad 264find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
252b5132 265{
b34976b6
AM
266 hi16s_location *match = NULL;
267 hi16s_location *entry;
b34976b6 268 bfd_byte *addr;
435b1e90 269
252b5132
RH
270 /* Search the table. Record the most recent entry that matches. */
271 for (entry = previous_hi16s; entry; entry = entry->next)
272 {
273 if (entry->addend == addend
274 && (match == NULL || match->counter < entry->counter))
275 {
252b5132
RH
276 match = entry;
277 }
252b5132
RH
278 }
279
280 if (match == NULL)
281 return NULL;
282
283 /* Extract the address. */
284 addr = match->address;
285
4cc11e76 286 /* Remember if this entry has already been used before. */
252b5132
RH
287 if (already_found)
288 * already_found = match->found;
289
290 /* Note that this entry has now been used. */
b34976b6 291 match->found = TRUE;
435b1e90 292
252b5132 293 return addr;
435b1e90 294}
252b5132 295
1e50d24d
RS
296/* Calculate the final operand value for a R_V850_LO16 or
297 R_V850_LO16_SPLIT_OFFSET. *INSN is the current operand value and
298 ADDEND is the sum of the relocation symbol and offset. Store the
299 operand value in *INSN and return true on success.
300
301 The assembler has already done some of this: If the value stored in
302 the instruction has its 15th bit set, (counting from zero) then the
303 assembler will have added 1 to the value stored in the associated
304 HI16S reloc. So for example, these relocations:
305
306 movhi hi( fred ), r0, r1
307 movea lo( fred ), r1, r1
308
309 will store 0 in the value fields for the MOVHI and MOVEA instructions
310 and addend will be the address of fred, but for these instructions:
311
1cd986c5
NC
312 movhi hi( fred + 0x123456 ), r0, r1
313 movea lo( fred + 0x123456 ), r1, r1
1e50d24d
RS
314
315 the value stored in the MOVHI instruction will be 0x12 and the value
316 stored in the MOVEA instruction will be 0x3456. If however the
317 instructions were:
318
1cd986c5
NC
319 movhi hi( fred + 0x10ffff ), r0, r1
320 movea lo( fred + 0x10ffff ), r1, r1
1e50d24d
RS
321
322 then the value stored in the MOVHI instruction would be 0x11 (not
323 0x10) and the value stored in the MOVEA instruction would be 0xffff.
324 Thus (assuming for the moment that the addend is 0), at run time the
325 MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
326 adds 0xffffffff (sign extension!) producing 0x10ffff. Similarly if
327 the instructions were:
328
1cd986c5
NC
329 movhi hi( fred - 1 ), r0, r1
330 movea lo( fred - 1 ), r1, r1
1e50d24d
RS
331
332 then 0 is stored in the MOVHI instruction and -1 is stored in the
333 MOVEA instruction.
334
335 Overflow can occur if the addition of the value stored in the
336 instruction plus the addend sets the 15th bit when before it was clear.
337 This is because the 15th bit will be sign extended into the high part,
338 thus reducing its value by one, but since the 15th bit was originally
339 clear, the assembler will not have added 1 to the previous HI16S reloc
340 to compensate for this effect. For example:
341
1cd986c5
NC
342 movhi hi( fred + 0x123456 ), r0, r1
343 movea lo( fred + 0x123456 ), r1, r1
1e50d24d
RS
344
345 The value stored in HI16S reloc is 0x12, the value stored in the LO16
346 reloc is 0x3456. If we assume that the address of fred is 0x00007000
347 then the relocations become:
348
349 HI16S: 0x0012 + (0x00007000 >> 16) = 0x12
350 LO16: 0x3456 + (0x00007000 & 0xffff) = 0xa456
351
352 but when the instructions are executed, the MOVEA instruction's value
353 is signed extended, so the sum becomes:
354
355 0x00120000
356 + 0xffffa456
357 ------------
358 0x0011a456 but 'fred + 0x123456' = 0x0012a456
359
360 Note that if the 15th bit was set in the value stored in the LO16
361 reloc, then we do not have to do anything:
362
1cd986c5
NC
363 movhi hi( fred + 0x10ffff ), r0, r1
364 movea lo( fred + 0x10ffff ), r1, r1
1e50d24d
RS
365
366 HI16S: 0x0011 + (0x00007000 >> 16) = 0x11
367 LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff
368
369 0x00110000
370 + 0x00006fff
371 ------------
372 0x00116fff = fred + 0x10ffff = 0x7000 + 0x10ffff
373
374 Overflow can also occur if the computation carries into the 16th bit
375 and it also results in the 15th bit having the same value as the 15th
376 bit of the original value. What happens is that the HI16S reloc
377 will have already examined the 15th bit of the original value and
378 added 1 to the high part if the bit is set. This compensates for the
379 sign extension of 15th bit of the result of the computation. But now
380 there is a carry into the 16th bit, and this has not been allowed for.
381
382 So, for example if fred is at address 0xf000:
383
1cd986c5
NC
384 movhi hi( fred + 0xffff ), r0, r1 [bit 15 of the offset is set]
385 movea lo( fred + 0xffff ), r1, r1
1e50d24d
RS
386
387 HI16S: 0x0001 + (0x0000f000 >> 16) = 0x0001
388 LO16: 0xffff + (0x0000f000 & 0xffff) = 0xefff (carry into bit 16 is lost)
389
390 0x00010000
391 + 0xffffefff
392 ------------
393 0x0000efff but 'fred + 0xffff' = 0x0001efff
394
395 Similarly, if the 15th bit remains clear, but overflow occurs into
396 the 16th bit then (assuming the address of fred is 0xf000):
397
1cd986c5
NC
398 movhi hi( fred + 0x7000 ), r0, r1 [bit 15 of the offset is clear]
399 movea lo( fred + 0x7000 ), r1, r1
1e50d24d
RS
400
401 HI16S: 0x0000 + (0x0000f000 >> 16) = 0x0000
402 LO16: 0x7000 + (0x0000f000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
403
404 0x00000000
405 + 0x00006fff
406 ------------
407 0x00006fff but 'fred + 0x7000' = 0x00016fff
408
409 Note - there is no need to change anything if a carry occurs, and the
410 15th bit changes its value from being set to being clear, as the HI16S
411 reloc will have already added in 1 to the high part for us:
412
1cd986c5
NC
413 movhi hi( fred + 0xffff ), r0, r1 [bit 15 of the offset is set]
414 movea lo( fred + 0xffff ), r1, r1
1e50d24d
RS
415
416 HI16S: 0x0001 + (0x00007000 >> 16)
417 LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
418
419 0x00010000
420 + 0x00006fff (bit 15 not set, so the top half is zero)
421 ------------
422 0x00016fff which is right (assuming that fred is at 0x7000)
423
424 but if the 15th bit goes from being clear to being set, then we must
425 once again handle overflow:
426
1cd986c5
NC
427 movhi hi( fred + 0x7000 ), r0, r1 [bit 15 of the offset is clear]
428 movea lo( fred + 0x7000 ), r1, r1
1e50d24d
RS
429
430 HI16S: 0x0000 + (0x0000ffff >> 16)
431 LO16: 0x7000 + (0x0000ffff & 0xffff) = 0x6fff (carry into bit 16)
432
433 0x00000000
434 + 0x00006fff (bit 15 not set, so the top half is zero)
435 ------------
436 0x00006fff which is wrong (assuming that fred is at 0xffff). */
437
438static bfd_boolean
439v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn,
440 unsigned long addend)
441{
442#define BIT15_SET(x) ((x) & 0x8000)
443#define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
47b0e7ad 444
1e50d24d
RS
445 if ((BIT15_SET (*insn + addend) && ! BIT15_SET (addend))
446 || (OVERFLOWS (addend, *insn)
447 && ((! BIT15_SET (*insn)) || (BIT15_SET (addend)))))
448 {
449 bfd_boolean already_updated;
450 bfd_byte *hi16s_address = find_remembered_hi16s_reloc
451 (addend, & already_updated);
452
453 /* Amend the matching HI16_S relocation. */
454 if (hi16s_address != NULL)
455 {
456 if (! already_updated)
457 {
458 unsigned long hi_insn = bfd_get_16 (abfd, hi16s_address);
459 hi_insn += 1;
460 bfd_put_16 (abfd, hi_insn, hi16s_address);
461 }
462 }
463 else
464 {
4a97a0e5 465 (*_bfd_error_handler) (_("FAILED to find previous HI16 reloc"));
1e50d24d
RS
466 return FALSE;
467 }
468 }
469#undef OVERFLOWS
470#undef BIT15_SET
471
472 /* Do not complain if value has top bit set, as this has been
473 anticipated. */
474 *insn = (*insn + addend) & 0xffff;
475 return TRUE;
476}
477
252b5132 478/* FIXME: The code here probably ought to be removed and the code in reloc.c
4cc11e76 479 allowed to do its stuff instead. At least for most of the relocs, anyway. */
e12dd2ea 480
252b5132 481static bfd_reloc_status_type
47b0e7ad
NC
482v850_elf_perform_relocation (bfd *abfd,
483 unsigned int r_type,
484 bfd_vma addend,
485 bfd_byte *address)
252b5132
RH
486{
487 unsigned long insn;
1e50d24d 488 unsigned long result;
252b5132 489 bfd_signed_vma saddend = (bfd_signed_vma) addend;
435b1e90 490
252b5132
RH
491 switch (r_type)
492 {
493 default:
de863c74
NC
494#ifdef DEBUG
495 fprintf (stderr, "reloc number %d not recognised\n", r_type);
496#endif
252b5132 497 return bfd_reloc_notsupported;
435b1e90 498
e30ddb24
NC
499 case R_V850_REL32:
500 case R_V850_ABS32:
de863c74
NC
501 case R_V810_WORD:
502 case R_V850_PC32:
252b5132
RH
503 bfd_put_32 (abfd, addend, address);
504 return bfd_reloc_ok;
435b1e90 505
de863c74 506 case R_V850_WLO23:
1cd986c5
NC
507 case R_V850_23:
508 insn = bfd_get_32 (abfd, address);
509 insn &= ~((0x7f << 4) | (0x7fff80 << (16-7)));
510 insn |= ((addend & 0x7f) << 4) | ((addend & 0x7fff80) << (16-7));
511 bfd_put_32 (abfd, (bfd_vma) insn, address);
512 return bfd_reloc_ok;
513
de863c74 514 case R_V850_PCR22:
252b5132
RH
515 case R_V850_22_PCREL:
516 if (saddend > 0x1fffff || saddend < -0x200000)
517 return bfd_reloc_overflow;
435b1e90 518
252b5132
RH
519 if ((addend % 2) != 0)
520 return bfd_reloc_dangerous;
435b1e90 521
252b5132
RH
522 insn = bfd_get_32 (abfd, address);
523 insn &= ~0xfffe003f;
524 insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
dc810e39 525 bfd_put_32 (abfd, (bfd_vma) insn, address);
252b5132 526 return bfd_reloc_ok;
435b1e90 527
de863c74 528 case R_V850_PC17:
1cd986c5
NC
529 case R_V850_17_PCREL:
530 if (saddend > 0xffff || saddend < -0x10000)
531 return bfd_reloc_overflow;
532
533 if ((addend % 2) != 0)
534 return bfd_reloc_dangerous;
535
536 insn = bfd_get_32 (abfd, address);
537 insn &= ~ 0xfffe0010;
538 insn |= ((addend & 0xfffe) << 16) | ((addend & 0x10000) >> (16-4));
539 break;
540
de863c74 541 case R_V850_PC16U:
1cd986c5
NC
542 case R_V850_16_PCREL:
543 if ((saddend < -0xffff) || (saddend > 0))
544 return bfd_reloc_overflow;
545
546 if ((addend % 2) != 0)
547 return bfd_reloc_dangerous;
548
549 insn = bfd_get_16 (abfd, address);
550 insn &= ~0xfffe;
551 insn |= (-addend & 0xfffe);
552 break;
553
de863c74 554 case R_V850_PC9:
252b5132
RH
555 case R_V850_9_PCREL:
556 if (saddend > 0xff || saddend < -0x100)
557 return bfd_reloc_overflow;
435b1e90 558
252b5132
RH
559 if ((addend % 2) != 0)
560 return bfd_reloc_dangerous;
435b1e90 561
252b5132
RH
562 insn = bfd_get_16 (abfd, address);
563 insn &= ~ 0xf870;
564 insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
565 break;
435b1e90 566
de863c74 567 case R_V810_WHI:
252b5132
RH
568 case R_V850_HI16:
569 addend += (bfd_get_16 (abfd, address) << 16);
570 addend = (addend >> 16);
571 insn = addend;
572 break;
435b1e90 573
de863c74 574 case R_V810_WHI1:
252b5132
RH
575 case R_V850_HI16_S:
576 /* Remember where this relocation took place. */
577 remember_hi16s_reloc (abfd, addend, address);
578
579 addend += (bfd_get_16 (abfd, address) << 16);
580 addend = (addend >> 16) + ((addend & 0x8000) != 0);
435b1e90
KH
581
582 /* This relocation cannot overflow. */
4d421096 583 if (addend > 0xffff)
252b5132 584 addend = 0;
435b1e90 585
252b5132
RH
586 insn = addend;
587 break;
435b1e90 588
de863c74 589 case R_V810_WLO:
252b5132 590 case R_V850_LO16:
1e50d24d
RS
591 insn = bfd_get_16 (abfd, address);
592 if (! v850_elf_perform_lo16_relocation (abfd, &insn, addend))
593 return bfd_reloc_overflow;
594 break;
252b5132 595
de863c74 596 case R_V810_BYTE:
252b5132
RH
597 case R_V850_8:
598 addend += (char) bfd_get_8 (abfd, address);
599
600 saddend = (bfd_signed_vma) addend;
435b1e90 601
252b5132
RH
602 if (saddend > 0x7f || saddend < -0x80)
603 return bfd_reloc_overflow;
604
605 bfd_put_8 (abfd, addend, address);
606 return bfd_reloc_ok;
607
608 case R_V850_CALLT_16_16_OFFSET:
609 addend += bfd_get_16 (abfd, address);
435b1e90 610
252b5132 611 saddend = (bfd_signed_vma) addend;
435b1e90 612
252b5132
RH
613 if (saddend > 0xffff || saddend < 0)
614 return bfd_reloc_overflow;
615
616 insn = addend;
617 break;
435b1e90 618
1cd986c5
NC
619 case R_V850_CALLT_15_16_OFFSET:
620 insn = bfd_get_16 (abfd, address);
621
5bb3703f 622 addend += insn & 0xfffe;
1cd986c5
NC
623
624 saddend = (bfd_signed_vma) addend;
625
626 if (saddend > 0xffff || saddend < 0)
627 return bfd_reloc_overflow;
628
629 insn = (0xfffe & addend)
630 | (insn & ~0xfffe);
631 break;
632
633 case R_V850_CALLT_6_7_OFFSET:
634 insn = bfd_get_16 (abfd, address);
635 addend += ((insn & 0x3f) << 1);
636
637 saddend = (bfd_signed_vma) addend;
638
639 if (saddend > 0x7e || saddend < 0)
640 return bfd_reloc_overflow;
641
642 if (addend & 1)
643 return bfd_reloc_dangerous;
644
645 insn &= 0xff80;
646 insn |= (addend >> 1);
647 break;
648
252b5132 649 case R_V850_16:
de863c74 650 case R_V810_HWORD:
252b5132
RH
651 case R_V850_SDA_16_16_OFFSET:
652 case R_V850_ZDA_16_16_OFFSET:
653 case R_V850_TDA_16_16_OFFSET:
654 addend += bfd_get_16 (abfd, address);
435b1e90 655
252b5132 656 saddend = (bfd_signed_vma) addend;
435b1e90 657
252b5132
RH
658 if (saddend > 0x7fff || saddend < -0x8000)
659 return bfd_reloc_overflow;
660
661 insn = addend;
662 break;
435b1e90 663
1cd986c5 664 case R_V850_16_S1:
252b5132
RH
665 case R_V850_SDA_15_16_OFFSET:
666 case R_V850_ZDA_15_16_OFFSET:
de863c74 667 case R_V810_GPWLO_1:
252b5132
RH
668 insn = bfd_get_16 (abfd, address);
669 addend += (insn & 0xfffe);
435b1e90 670
252b5132 671 saddend = (bfd_signed_vma) addend;
435b1e90 672
252b5132
RH
673 if (saddend > 0x7ffe || saddend < -0x8000)
674 return bfd_reloc_overflow;
435b1e90 675
252b5132
RH
676 if (addend & 1)
677 return bfd_reloc_dangerous;
435b1e90 678
dc810e39 679 insn = (addend &~ (bfd_vma) 1) | (insn & 1);
252b5132 680 break;
435b1e90 681
252b5132
RH
682 case R_V850_TDA_6_8_OFFSET:
683 insn = bfd_get_16 (abfd, address);
684 addend += ((insn & 0x7e) << 1);
435b1e90 685
252b5132 686 saddend = (bfd_signed_vma) addend;
435b1e90 687
252b5132
RH
688 if (saddend > 0xfc || saddend < 0)
689 return bfd_reloc_overflow;
435b1e90 690
252b5132
RH
691 if (addend & 3)
692 return bfd_reloc_dangerous;
435b1e90 693
252b5132
RH
694 insn &= 0xff81;
695 insn |= (addend >> 1);
696 break;
435b1e90 697
252b5132
RH
698 case R_V850_TDA_7_8_OFFSET:
699 insn = bfd_get_16 (abfd, address);
700 addend += ((insn & 0x7f) << 1);
435b1e90 701
252b5132 702 saddend = (bfd_signed_vma) addend;
435b1e90 703
252b5132
RH
704 if (saddend > 0xfe || saddend < 0)
705 return bfd_reloc_overflow;
435b1e90 706
252b5132
RH
707 if (addend & 1)
708 return bfd_reloc_dangerous;
435b1e90 709
252b5132
RH
710 insn &= 0xff80;
711 insn |= (addend >> 1);
712 break;
435b1e90 713
252b5132
RH
714 case R_V850_TDA_7_7_OFFSET:
715 insn = bfd_get_16 (abfd, address);
716 addend += insn & 0x7f;
435b1e90 717
252b5132 718 saddend = (bfd_signed_vma) addend;
435b1e90 719
252b5132
RH
720 if (saddend > 0x7f || saddend < 0)
721 return bfd_reloc_overflow;
435b1e90 722
252b5132
RH
723 insn &= 0xff80;
724 insn |= addend;
725 break;
435b1e90 726
252b5132
RH
727 case R_V850_TDA_4_5_OFFSET:
728 insn = bfd_get_16 (abfd, address);
729 addend += ((insn & 0xf) << 1);
435b1e90 730
252b5132 731 saddend = (bfd_signed_vma) addend;
435b1e90 732
252b5132
RH
733 if (saddend > 0x1e || saddend < 0)
734 return bfd_reloc_overflow;
435b1e90 735
252b5132
RH
736 if (addend & 1)
737 return bfd_reloc_dangerous;
435b1e90 738
252b5132
RH
739 insn &= 0xfff0;
740 insn |= (addend >> 1);
741 break;
435b1e90 742
252b5132
RH
743 case R_V850_TDA_4_4_OFFSET:
744 insn = bfd_get_16 (abfd, address);
745 addend += insn & 0xf;
435b1e90 746
252b5132 747 saddend = (bfd_signed_vma) addend;
435b1e90 748
252b5132
RH
749 if (saddend > 0xf || saddend < 0)
750 return bfd_reloc_overflow;
435b1e90 751
252b5132
RH
752 insn &= 0xfff0;
753 insn |= addend;
754 break;
435b1e90 755
de863c74
NC
756 case R_V810_WLO_1:
757 case R_V850_HWLO:
758 case R_V850_HWLO_1:
1cd986c5
NC
759 case R_V850_LO16_S1:
760 insn = bfd_get_16 (abfd, address);
761 result = insn & 0xfffe;
762 if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
763 return bfd_reloc_overflow;
764 if (result & 1)
765 return bfd_reloc_overflow;
766 insn = (result & 0xfffe)
767 | (insn & ~0xfffe);
768 bfd_put_16 (abfd, insn, address);
769 return bfd_reloc_ok;
770
de863c74 771 case R_V850_BLO:
1e50d24d
RS
772 case R_V850_LO16_SPLIT_OFFSET:
773 insn = bfd_get_32 (abfd, address);
774 result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5);
775 if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
776 return bfd_reloc_overflow;
777 insn = (((result << 16) & 0xfffe0000)
778 | ((result << 5) & 0x20)
779 | (insn & ~0xfffe0020));
780 bfd_put_32 (abfd, insn, address);
781 return bfd_reloc_ok;
782
1cd986c5 783 case R_V850_16_SPLIT_OFFSET:
252b5132 784 case R_V850_SDA_16_16_SPLIT_OFFSET:
1cd986c5 785 case R_V850_ZDA_16_16_SPLIT_OFFSET:
252b5132
RH
786 insn = bfd_get_32 (abfd, address);
787 addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
435b1e90 788
252b5132 789 saddend = (bfd_signed_vma) addend;
435b1e90 790
252b5132
RH
791 if (saddend > 0x7fff || saddend < -0x8000)
792 return bfd_reloc_overflow;
435b1e90 793
252b5132
RH
794 insn &= 0x0001ffdf;
795 insn |= (addend & 1) << 5;
dc810e39 796 insn |= (addend &~ (bfd_vma) 1) << 16;
435b1e90 797
dc810e39 798 bfd_put_32 (abfd, (bfd_vma) insn, address);
252b5132 799 return bfd_reloc_ok;
435b1e90 800
252b5132
RH
801 case R_V850_GNU_VTINHERIT:
802 case R_V850_GNU_VTENTRY:
803 return bfd_reloc_ok;
804
805 }
806
dc810e39 807 bfd_put_16 (abfd, (bfd_vma) insn, address);
252b5132
RH
808 return bfd_reloc_ok;
809}
252b5132
RH
810\f
811/* Insert the addend into the instruction. */
e12dd2ea 812
252b5132 813static bfd_reloc_status_type
47b0e7ad
NC
814v850_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
815 arelent *reloc,
816 asymbol *symbol,
817 void * data ATTRIBUTE_UNUSED,
818 asection *isection,
819 bfd *obfd,
820 char **err ATTRIBUTE_UNUSED)
252b5132
RH
821{
822 long relocation;
435b1e90 823
252b5132
RH
824 /* If there is an output BFD,
825 and the symbol is not a section name (which is only defined at final link time),
826 and either we are not putting the addend into the instruction
e12dd2ea 827 or the addend is zero, so there is nothing to add into the instruction
252b5132 828 then just fixup the address and return. */
47b0e7ad 829 if (obfd != NULL
252b5132
RH
830 && (symbol->flags & BSF_SECTION_SYM) == 0
831 && (! reloc->howto->partial_inplace
832 || reloc->addend == 0))
833 {
834 reloc->address += isection->output_offset;
835 return bfd_reloc_ok;
836 }
435b1e90 837
252b5132
RH
838 /* Catch relocs involving undefined symbols. */
839 if (bfd_is_und_section (symbol->section)
840 && (symbol->flags & BSF_WEAK) == 0
841 && obfd == NULL)
842 return bfd_reloc_undefined;
843
844 /* We handle final linking of some relocs ourselves. */
845
846 /* Is the address of the relocation really within the section? */
07515404 847 if (reloc->address > bfd_get_section_limit (abfd, isection))
252b5132 848 return bfd_reloc_outofrange;
435b1e90 849
4cc11e76 850 /* Work out which section the relocation is targeted at and the
252b5132 851 initial relocation command value. */
435b1e90 852
b34976b6 853 if (reloc->howto->pc_relative)
86aba9db
NC
854 return bfd_reloc_ok;
855
252b5132
RH
856 /* Get symbol value. (Common symbols are special.) */
857 if (bfd_is_com_section (symbol->section))
858 relocation = 0;
859 else
860 relocation = symbol->value;
435b1e90 861
252b5132
RH
862 /* Convert input-section-relative symbol value to absolute + addend. */
863 relocation += symbol->section->output_section->vma;
864 relocation += symbol->section->output_offset;
865 relocation += reloc->addend;
435b1e90 866
435b1e90 867 reloc->addend = relocation;
252b5132
RH
868 return bfd_reloc_ok;
869}
86aba9db
NC
870
871/* This function is used for relocs which are only used
872 for relaxing, which the linker should otherwise ignore. */
873
874static bfd_reloc_status_type
47b0e7ad
NC
875v850_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
876 arelent *reloc_entry,
877 asymbol *symbol ATTRIBUTE_UNUSED,
878 void * data ATTRIBUTE_UNUSED,
879 asection *input_section,
880 bfd *output_bfd,
881 char **error_message ATTRIBUTE_UNUSED)
86aba9db
NC
882{
883 if (output_bfd != NULL)
884 reloc_entry->address += input_section->output_offset;
885
886 return bfd_reloc_ok;
887}
47b0e7ad 888/* Note: It is REQUIRED that the 'type' value of each entry
1cd986c5 889 in this array match the index of the entry in the array.
de863c74 890 SeeAlso: RELOC_NUBMER in include/elf/v850.h. */
47b0e7ad
NC
891static reloc_howto_type v850_elf_howto_table[] =
892{
893 /* This reloc does nothing. */
894 HOWTO (R_V850_NONE, /* Type. */
895 0, /* Rightshift. */
896 2, /* Size (0 = byte, 1 = short, 2 = long). */
897 32, /* Bitsize. */
898 FALSE, /* PC_relative. */
899 0, /* Bitpos. */
900 complain_overflow_bitfield, /* Complain_on_overflow. */
901 bfd_elf_generic_reloc, /* Special_function. */
902 "R_V850_NONE", /* Name. */
903 FALSE, /* Partial_inplace. */
904 0, /* Src_mask. */
905 0, /* Dst_mask. */
906 FALSE), /* PCrel_offset. */
907
908 /* A PC relative 9 bit branch. */
909 HOWTO (R_V850_9_PCREL, /* Type. */
1cd986c5
NC
910 0, /* Rightshift. */
911 1, /* Size (0 = byte, 1 = short, 2 = long). */
912 9, /* Bitsize. */
47b0e7ad
NC
913 TRUE, /* PC_relative. */
914 0, /* Bitpos. */
915 complain_overflow_bitfield, /* Complain_on_overflow. */
916 v850_elf_reloc, /* Special_function. */
917 "R_V850_9_PCREL", /* Name. */
918 FALSE, /* Partial_inplace. */
919 0x00ffffff, /* Src_mask. */
920 0x00ffffff, /* Dst_mask. */
921 TRUE), /* PCrel_offset. */
922
923 /* A PC relative 22 bit branch. */
924 HOWTO (R_V850_22_PCREL, /* Type. */
1cd986c5 925 0, /* Rightshift. */
47b0e7ad
NC
926 2, /* Size (0 = byte, 1 = short, 2 = long). */
927 22, /* Bitsize. */
928 TRUE, /* PC_relative. */
1cd986c5 929 0, /* Bitpos. */
47b0e7ad
NC
930 complain_overflow_signed, /* Complain_on_overflow. */
931 v850_elf_reloc, /* Special_function. */
932 "R_V850_22_PCREL", /* Name. */
933 FALSE, /* Partial_inplace. */
934 0x07ffff80, /* Src_mask. */
935 0x07ffff80, /* Dst_mask. */
936 TRUE), /* PCrel_offset. */
937
938 /* High 16 bits of symbol value. */
939 HOWTO (R_V850_HI16_S, /* Type. */
940 0, /* Rightshift. */
941 1, /* Size (0 = byte, 1 = short, 2 = long). */
942 16, /* Bitsize. */
943 FALSE, /* PC_relative. */
944 0, /* Bitpos. */
945 complain_overflow_dont, /* Complain_on_overflow. */
946 v850_elf_reloc, /* Special_function. */
947 "R_V850_HI16_S", /* Name. */
948 FALSE, /* Partial_inplace. */
949 0xffff, /* Src_mask. */
950 0xffff, /* Dst_mask. */
951 FALSE), /* PCrel_offset. */
952
953 /* High 16 bits of symbol value. */
954 HOWTO (R_V850_HI16, /* Type. */
955 0, /* Rightshift. */
956 1, /* Size (0 = byte, 1 = short, 2 = long). */
957 16, /* Bitsize. */
958 FALSE, /* PC_relative. */
959 0, /* Bitpos. */
960 complain_overflow_dont, /* Complain_on_overflow. */
961 v850_elf_reloc, /* Special_function. */
962 "R_V850_HI16", /* Name. */
963 FALSE, /* Partial_inplace. */
964 0xffff, /* Src_mask. */
965 0xffff, /* Dst_mask. */
966 FALSE), /* PCrel_offset. */
967
968 /* Low 16 bits of symbol value. */
969 HOWTO (R_V850_LO16, /* Type. */
970 0, /* Rightshift. */
971 1, /* Size (0 = byte, 1 = short, 2 = long). */
972 16, /* Bitsize. */
973 FALSE, /* PC_relative. */
974 0, /* Bitpos. */
975 complain_overflow_dont, /* Complain_on_overflow. */
976 v850_elf_reloc, /* Special_function. */
977 "R_V850_LO16", /* Name. */
978 FALSE, /* Partial_inplace. */
979 0xffff, /* Src_mask. */
980 0xffff, /* Dst_mask. */
981 FALSE), /* PCrel_offset. */
982
983 /* Simple 32bit reloc. */
984 HOWTO (R_V850_ABS32, /* Type. */
985 0, /* Rightshift. */
986 2, /* Size (0 = byte, 1 = short, 2 = long). */
987 32, /* Bitsize. */
988 FALSE, /* PC_relative. */
989 0, /* Bitpos. */
990 complain_overflow_dont, /* Complain_on_overflow. */
991 v850_elf_reloc, /* Special_function. */
992 "R_V850_ABS32", /* Name. */
993 FALSE, /* Partial_inplace. */
994 0xffffffff, /* Src_mask. */
995 0xffffffff, /* Dst_mask. */
996 FALSE), /* PCrel_offset. */
997
998 /* Simple 16bit reloc. */
999 HOWTO (R_V850_16, /* Type. */
1000 0, /* Rightshift. */
1001 1, /* Size (0 = byte, 1 = short, 2 = long). */
1002 16, /* Bitsize. */
1003 FALSE, /* PC_relative. */
1004 0, /* Bitpos. */
1005 complain_overflow_dont, /* Complain_on_overflow. */
1006 bfd_elf_generic_reloc, /* Special_function. */
1007 "R_V850_16", /* Name. */
1008 FALSE, /* Partial_inplace. */
1009 0xffff, /* Src_mask. */
1010 0xffff, /* Dst_mask. */
1011 FALSE), /* PCrel_offset. */
1012
1013 /* Simple 8bit reloc. */
1014 HOWTO (R_V850_8, /* Type. */
1015 0, /* Rightshift. */
1016 0, /* Size (0 = byte, 1 = short, 2 = long). */
1017 8, /* Bitsize. */
1018 FALSE, /* PC_relative. */
1019 0, /* Bitpos. */
1020 complain_overflow_dont, /* Complain_on_overflow. */
1021 bfd_elf_generic_reloc, /* Special_function. */
1022 "R_V850_8", /* Name. */
1023 FALSE, /* Partial_inplace. */
1024 0xff, /* Src_mask. */
1025 0xff, /* Dst_mask. */
1026 FALSE), /* PCrel_offset. */
1027
1028 /* 16 bit offset from the short data area pointer. */
1029 HOWTO (R_V850_SDA_16_16_OFFSET, /* Type. */
1030 0, /* Rightshift. */
1031 1, /* Size (0 = byte, 1 = short, 2 = long). */
1032 16, /* Bitsize. */
1033 FALSE, /* PC_relative. */
1034 0, /* Bitpos. */
1035 complain_overflow_dont, /* Complain_on_overflow. */
1036 v850_elf_reloc, /* Special_function. */
1037 "R_V850_SDA_16_16_OFFSET", /* Name. */
1038 FALSE, /* Partial_inplace. */
1039 0xffff, /* Src_mask. */
1040 0xffff, /* Dst_mask. */
1041 FALSE), /* PCrel_offset. */
1042
1043 /* 15 bit offset from the short data area pointer. */
1044 HOWTO (R_V850_SDA_15_16_OFFSET, /* Type. */
1045 1, /* Rightshift. */
1046 1, /* Size (0 = byte, 1 = short, 2 = long). */
1047 16, /* Bitsize. */
1048 FALSE, /* PC_relative. */
1049 1, /* Bitpos. */
1050 complain_overflow_dont, /* Complain_on_overflow. */
1051 v850_elf_reloc, /* Special_function. */
1052 "R_V850_SDA_15_16_OFFSET", /* Name. */
1053 FALSE, /* Partial_inplace. */
1054 0xfffe, /* Src_mask. */
1055 0xfffe, /* Dst_mask. */
1056 FALSE), /* PCrel_offset. */
1057
1058 /* 16 bit offset from the zero data area pointer. */
1059 HOWTO (R_V850_ZDA_16_16_OFFSET, /* Type. */
1060 0, /* Rightshift. */
1061 1, /* Size (0 = byte, 1 = short, 2 = long). */
1062 16, /* Bitsize. */
1063 FALSE, /* PC_relative. */
1064 0, /* Bitpos. */
1065 complain_overflow_dont, /* Complain_on_overflow. */
1066 v850_elf_reloc, /* Special_function. */
1067 "R_V850_ZDA_16_16_OFFSET", /* Name. */
1068 FALSE, /* Partial_inplace. */
1069 0xffff, /* Src_mask. */
1070 0xffff, /* Dst_mask. */
1071 FALSE), /* PCrel_offset. */
1072
1073 /* 15 bit offset from the zero data area pointer. */
1074 HOWTO (R_V850_ZDA_15_16_OFFSET, /* Type. */
1075 1, /* Rightshift. */
1076 1, /* Size (0 = byte, 1 = short, 2 = long). */
1077 16, /* Bitsize. */
1078 FALSE, /* PC_relative. */
1079 1, /* Bitpos. */
1080 complain_overflow_dont, /* Complain_on_overflow. */
1081 v850_elf_reloc, /* Special_function. */
1082 "R_V850_ZDA_15_16_OFFSET", /* Name. */
1083 FALSE, /* Partial_inplace. */
1084 0xfffe, /* Src_mask. */
1085 0xfffe, /* Dst_mask. */
1086 FALSE), /* PCrel_offset. */
1087
1088 /* 6 bit offset from the tiny data area pointer. */
1089 HOWTO (R_V850_TDA_6_8_OFFSET, /* Type. */
1090 2, /* Rightshift. */
1091 1, /* Size (0 = byte, 1 = short, 2 = long). */
1092 8, /* Bitsize. */
1093 FALSE, /* PC_relative. */
1094 1, /* Bitpos. */
1095 complain_overflow_dont, /* Complain_on_overflow. */
1096 v850_elf_reloc, /* Special_function. */
1097 "R_V850_TDA_6_8_OFFSET", /* Name. */
1098 FALSE, /* Partial_inplace. */
1099 0x7e, /* Src_mask. */
1100 0x7e, /* Dst_mask. */
1101 FALSE), /* PCrel_offset. */
1102
1103 /* 8 bit offset from the tiny data area pointer. */
1104 HOWTO (R_V850_TDA_7_8_OFFSET, /* Type. */
1105 1, /* Rightshift. */
1106 1, /* Size (0 = byte, 1 = short, 2 = long). */
1107 8, /* Bitsize. */
1108 FALSE, /* PC_relative. */
1109 0, /* Bitpos. */
1110 complain_overflow_dont, /* Complain_on_overflow. */
1111 v850_elf_reloc, /* Special_function. */
1112 "R_V850_TDA_7_8_OFFSET", /* Name. */
1113 FALSE, /* Partial_inplace. */
1114 0x7f, /* Src_mask. */
1115 0x7f, /* Dst_mask. */
1116 FALSE), /* PCrel_offset. */
1117
1118 /* 7 bit offset from the tiny data area pointer. */
1119 HOWTO (R_V850_TDA_7_7_OFFSET, /* Type. */
1120 0, /* Rightshift. */
1121 1, /* Size (0 = byte, 1 = short, 2 = long). */
1122 7, /* Bitsize. */
1123 FALSE, /* PC_relative. */
1124 0, /* Bitpos. */
1125 complain_overflow_dont, /* Complain_on_overflow. */
1126 v850_elf_reloc, /* Special_function. */
1127 "R_V850_TDA_7_7_OFFSET", /* Name. */
1128 FALSE, /* Partial_inplace. */
1129 0x7f, /* Src_mask. */
1130 0x7f, /* Dst_mask. */
1131 FALSE), /* PCrel_offset. */
1132
1133 /* 16 bit offset from the tiny data area pointer! */
1134 HOWTO (R_V850_TDA_16_16_OFFSET, /* Type. */
1135 0, /* Rightshift. */
1136 1, /* Size (0 = byte, 1 = short, 2 = long). */
1137 16, /* Bitsize. */
1138 FALSE, /* PC_relative. */
1139 0, /* Bitpos. */
1140 complain_overflow_dont, /* Complain_on_overflow. */
1141 v850_elf_reloc, /* Special_function. */
1142 "R_V850_TDA_16_16_OFFSET", /* Name. */
1143 FALSE, /* Partial_inplace. */
1144 0xffff, /* Src_mask. */
1145 0xfff, /* Dst_mask. */
1146 FALSE), /* PCrel_offset. */
1147
1148 /* 5 bit offset from the tiny data area pointer. */
1149 HOWTO (R_V850_TDA_4_5_OFFSET, /* Type. */
1150 1, /* Rightshift. */
1151 1, /* Size (0 = byte, 1 = short, 2 = long). */
1152 5, /* Bitsize. */
1153 FALSE, /* PC_relative. */
1154 0, /* Bitpos. */
1155 complain_overflow_dont, /* Complain_on_overflow. */
1156 v850_elf_reloc, /* Special_function. */
1157 "R_V850_TDA_4_5_OFFSET", /* Name. */
1158 FALSE, /* Partial_inplace. */
1159 0x0f, /* Src_mask. */
1160 0x0f, /* Dst_mask. */
1161 FALSE), /* PCrel_offset. */
1162
1163 /* 4 bit offset from the tiny data area pointer. */
1164 HOWTO (R_V850_TDA_4_4_OFFSET, /* Type. */
1165 0, /* Rightshift. */
1166 1, /* Size (0 = byte, 1 = short, 2 = long). */
1167 4, /* Bitsize. */
1168 FALSE, /* PC_relative. */
1169 0, /* Bitpos. */
1170 complain_overflow_dont, /* Complain_on_overflow. */
1171 v850_elf_reloc, /* Special_function. */
1172 "R_V850_TDA_4_4_OFFSET", /* Name. */
1173 FALSE, /* Partial_inplace. */
1174 0x0f, /* Src_mask. */
1175 0x0f, /* Dst_mask. */
1176 FALSE), /* PCrel_offset. */
1177
1178 /* 16 bit offset from the short data area pointer. */
1179 HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* Type. */
1180 0, /* Rightshift. */
1181 2, /* Size (0 = byte, 1 = short, 2 = long). */
1182 16, /* Bitsize. */
1183 FALSE, /* PC_relative. */
1184 0, /* Bitpos. */
1185 complain_overflow_dont, /* Complain_on_overflow. */
1186 v850_elf_reloc, /* Special_function. */
1187 "R_V850_SDA_16_16_SPLIT_OFFSET",/* Name. */
1188 FALSE, /* Partial_inplace. */
1189 0xfffe0020, /* Src_mask. */
1190 0xfffe0020, /* Dst_mask. */
1191 FALSE), /* PCrel_offset. */
1192
1193 /* 16 bit offset from the zero data area pointer. */
1194 HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* Type. */
1195 0, /* Rightshift. */
1196 2, /* Size (0 = byte, 1 = short, 2 = long). */
1197 16, /* Bitsize. */
1198 FALSE, /* PC_relative. */
1199 0, /* Bitpos. */
1200 complain_overflow_dont, /* Complain_on_overflow. */
1201 v850_elf_reloc, /* Special_function. */
1202 "R_V850_ZDA_16_16_SPLIT_OFFSET",/* Name. */
1203 FALSE, /* Partial_inplace. */
1204 0xfffe0020, /* Src_mask. */
1205 0xfffe0020, /* Dst_mask. */
1206 FALSE), /* PCrel_offset. */
1207
1208 /* 6 bit offset from the call table base pointer. */
1209 HOWTO (R_V850_CALLT_6_7_OFFSET, /* Type. */
1210 0, /* Rightshift. */
1211 1, /* Size (0 = byte, 1 = short, 2 = long). */
1212 7, /* Bitsize. */
1213 FALSE, /* PC_relative. */
1214 0, /* Bitpos. */
1215 complain_overflow_dont, /* Complain_on_overflow. */
1216 v850_elf_reloc, /* Special_function. */
1217 "R_V850_CALLT_6_7_OFFSET", /* Name. */
1218 FALSE, /* Partial_inplace. */
1219 0x3f, /* Src_mask. */
1220 0x3f, /* Dst_mask. */
1221 FALSE), /* PCrel_offset. */
1222
1223 /* 16 bit offset from the call table base pointer. */
1224 HOWTO (R_V850_CALLT_16_16_OFFSET, /* Type. */
1225 0, /* Rightshift. */
1226 1, /* Size (0 = byte, 1 = short, 2 = long). */
1227 16, /* Bitsize. */
1228 FALSE, /* PC_relative. */
1229 0, /* Bitpos. */
1230 complain_overflow_dont, /* Complain_on_overflow. */
1231 v850_elf_reloc, /* Special_function. */
1232 "R_V850_CALLT_16_16_OFFSET", /* Name. */
1233 FALSE, /* Partial_inplace. */
1234 0xffff, /* Src_mask. */
1235 0xffff, /* Dst_mask. */
1236 FALSE), /* PCrel_offset. */
1237
1cd986c5 1238
47b0e7ad
NC
1239 /* GNU extension to record C++ vtable hierarchy */
1240 HOWTO (R_V850_GNU_VTINHERIT, /* Type. */
1cd986c5
NC
1241 0, /* Rightshift. */
1242 2, /* Size (0 = byte, 1 = short, 2 = long). */
1243 0, /* Bitsize. */
1244 FALSE, /* PC_relative. */
1245 0, /* Bitpos. */
1246 complain_overflow_dont, /* Complain_on_overflow. */
1247 NULL, /* Special_function. */
1248 "R_V850_GNU_VTINHERIT", /* Name. */
1249 FALSE, /* Partial_inplace. */
1250 0, /* Src_mask. */
1251 0, /* Dst_mask. */
1252 FALSE), /* PCrel_offset. */
1253
1254 /* GNU extension to record C++ vtable member usage. */
47b0e7ad 1255 HOWTO (R_V850_GNU_VTENTRY, /* Type. */
1cd986c5
NC
1256 0, /* Rightshift. */
1257 2, /* Size (0 = byte, 1 = short, 2 = long). */
1258 0, /* Bitsize. */
1259 FALSE, /* PC_relative. */
1260 0, /* Bitpos. */
1261 complain_overflow_dont, /* Complain_on_overflow. */
1262 _bfd_elf_rel_vtable_reloc_fn, /* Special_function. */
1263 "R_V850_GNU_VTENTRY", /* Name. */
1264 FALSE, /* Partial_inplace. */
1265 0, /* Src_mask. */
1266 0, /* Dst_mask. */
1267 FALSE), /* PCrel_offset. */
47b0e7ad
NC
1268
1269 /* Indicates a .longcall pseudo-op. The compiler will generate a .longcall
1270 pseudo-op when it finds a function call which can be relaxed. */
1271 HOWTO (R_V850_LONGCALL, /* Type. */
1cd986c5
NC
1272 0, /* Rightshift. */
1273 2, /* Size (0 = byte, 1 = short, 2 = long). */
1274 32, /* Bitsize. */
1275 TRUE, /* PC_relative. */
1276 0, /* Bitpos. */
1277 complain_overflow_signed, /* Complain_on_overflow. */
1278 v850_elf_ignore_reloc, /* Special_function. */
1279 "R_V850_LONGCALL", /* Name. */
1280 FALSE, /* Partial_inplace. */
1281 0, /* Src_mask. */
1282 0, /* Dst_mask. */
1283 TRUE), /* PCrel_offset. */
47b0e7ad
NC
1284
1285 /* Indicates a .longjump pseudo-op. The compiler will generate a
1286 .longjump pseudo-op when it finds a branch which can be relaxed. */
1287 HOWTO (R_V850_LONGJUMP, /* Type. */
1cd986c5
NC
1288 0, /* Rightshift. */
1289 2, /* Size (0 = byte, 1 = short, 2 = long). */
1290 32, /* Bitsize. */
1291 TRUE, /* PC_relative. */
1292 0, /* Bitpos. */
1293 complain_overflow_signed, /* Complain_on_overflow. */
1294 v850_elf_ignore_reloc, /* Special_function. */
1295 "R_V850_LONGJUMP", /* Name. */
1296 FALSE, /* Partial_inplace. */
1297 0, /* Src_mask. */
1298 0, /* Dst_mask. */
1299 TRUE), /* PCrel_offset. */
47b0e7ad
NC
1300
1301 HOWTO (R_V850_ALIGN, /* Type. */
1cd986c5
NC
1302 0, /* Rightshift. */
1303 1, /* Size (0 = byte, 1 = short, 2 = long). */
1304 0, /* Bitsize. */
1305 FALSE, /* PC_relative. */
1306 0, /* Bitpos. */
1307 complain_overflow_unsigned, /* Complain_on_overflow. */
1308 v850_elf_ignore_reloc, /* Special_function. */
1309 "R_V850_ALIGN", /* Name. */
1310 FALSE, /* Partial_inplace. */
1311 0, /* Src_mask. */
1312 0, /* Dst_mask. */
1313 TRUE), /* PCrel_offset. */
1314
47b0e7ad
NC
1315 /* Simple pc-relative 32bit reloc. */
1316 HOWTO (R_V850_REL32, /* Type. */
1317 0, /* Rightshift. */
1318 2, /* Size (0 = byte, 1 = short, 2 = long). */
1319 32, /* Bitsize. */
1320 TRUE, /* PC_relative. */
1321 0, /* Bitpos. */
1322 complain_overflow_dont, /* Complain_on_overflow. */
1323 v850_elf_reloc, /* Special_function. */
1324 "R_V850_REL32", /* Name. */
1325 FALSE, /* Partial_inplace. */
1326 0xffffffff, /* Src_mask. */
1327 0xffffffff, /* Dst_mask. */
1328 FALSE), /* PCrel_offset. */
1329
1330 /* An ld.bu version of R_V850_LO16. */
1331 HOWTO (R_V850_LO16_SPLIT_OFFSET, /* Type. */
1332 0, /* Rightshift. */
1333 2, /* Size (0 = byte, 1 = short, 2 = long). */
1334 16, /* Bitsize. */
1335 FALSE, /* PC_relative. */
1336 0, /* Bitpos. */
1337 complain_overflow_dont, /* Complain_on_overflow. */
1338 v850_elf_reloc, /* Special_function. */
1339 "R_V850_LO16_SPLIT_OFFSET", /* Name. */
1340 FALSE, /* Partial_inplace. */
1341 0xfffe0020, /* Src_mask. */
1342 0xfffe0020, /* Dst_mask. */
1343 FALSE), /* PCrel_offset. */
1cd986c5
NC
1344
1345 /* A unsigned PC relative 16 bit loop. */
1346 HOWTO (R_V850_16_PCREL, /* Type. */
1347 0, /* Rightshift. */
1348 1, /* Size (0 = byte, 1 = short, 2 = long). */
1349 16, /* Bitsize. */
1350 TRUE, /* PC_relative. */
1351 0, /* Bitpos. */
1352 complain_overflow_bitfield, /* Complain_on_overflow. */
1353 v850_elf_reloc, /* Special_function. */
1354 "R_V850_16_PCREL", /* Name. */
1355 FALSE, /* Partial_inplace. */
1356 0xfffe, /* Src_mask. */
1357 0xfffe, /* Dst_mask. */
1358 TRUE), /* PCrel_offset. */
1359
1360 /* A PC relative 17 bit branch. */
1361 HOWTO (R_V850_17_PCREL, /* Type. */
1362 0, /* Rightshift. */
1363 2, /* Size (0 = byte, 1 = short, 2 = long). */
1364 17, /* Bitsize. */
1365 TRUE, /* PC_relative. */
1366 0, /* Bitpos. */
1367 complain_overflow_bitfield, /* Complain_on_overflow. */
1368 v850_elf_reloc, /* Special_function. */
1369 "R_V850_17_PCREL", /* Name. */
1370 FALSE, /* Partial_inplace. */
1371 0x0010fffe, /* Src_mask. */
1372 0x0010fffe, /* Dst_mask. */
1373 TRUE), /* PCrel_offset. */
1374
1375 /* A 23bit offset ld/st. */
1376 HOWTO (R_V850_23, /* type. */
1377 0, /* rightshift. */
1378 2, /* size (0 = byte, 1 = short, 2 = long). */
1379 23, /* bitsize. */
1380 FALSE, /* pc_relative. */
1381 0, /* bitpos. */
1382 complain_overflow_dont, /* complain_on_overflow. */
1383 v850_elf_reloc, /* special_function. */
1384 "R_V850_23", /* name. */
1385 FALSE, /* partial_inplace. */
1386 0xffff07f0, /* src_mask. */
1387 0xffff07f0, /* dst_mask. */
1388 FALSE), /* pcrel_offset. */
1389
1390 /* A PC relative 32 bit branch. */
1391 HOWTO (R_V850_32_PCREL, /* type. */
1392 1, /* rightshift. */
1393 2, /* size (0 = byte, 1 = short, 2 = long). */
1394 32, /* bitsize. */
1395 TRUE, /* pc_relative. */
1396 1, /* bitpos. */
1397 complain_overflow_signed, /* complain_on_overflow. */
1398 v850_elf_reloc, /* special_function. */
1399 "R_V850_32_PCREL", /* name. */
1400 FALSE, /* partial_inplace. */
1401 0xfffffffe, /* src_mask. */
1402 0xfffffffe, /* dst_mask. */
1403 TRUE), /* pcrel_offset. */
1404
1405 /* A absolute 32 bit branch. */
1406 HOWTO (R_V850_32_ABS, /* type. */
1407 1, /* rightshift. */
1408 2, /* size (0 = byte, 1 = short, 2 = long). */
1409 32, /* bitsize. */
1410 TRUE, /* pc_relative. */
1411 1, /* bitpos. */
1412 complain_overflow_signed, /* complain_on_overflow. */
1413 v850_elf_reloc, /* special_function. */
1414 "R_V850_32_ABS", /* name. */
1415 FALSE, /* partial_inplace. */
1416 0xfffffffe, /* src_mask. */
1417 0xfffffffe, /* dst_mask. */
1418 FALSE), /* pcrel_offset. */
1419
1420 /* High 16 bits of symbol value. */
1421 HOWTO (R_V850_HI16, /* Type. */
1422 0, /* Rightshift. */
1423 1, /* Size (0 = byte, 1 = short, 2 = long). */
1424 16, /* Bitsize. */
1425 FALSE, /* PC_relative. */
1426 0, /* Bitpos. */
1427 complain_overflow_dont, /* Complain_on_overflow. */
1428 v850_elf_reloc, /* Special_function. */
1429 "R_V850_HI16", /* Name. */
1430 FALSE, /* Partial_inplace. */
1431 0xffff, /* Src_mask. */
1432 0xffff, /* Dst_mask. */
1433 FALSE), /* PCrel_offset. */
1434
1435 /* Low 16 bits of symbol value. */
1436 HOWTO (R_V850_16_S1, /* type. */
1437 1, /* rightshift. */
1438 1, /* size (0 = byte, 1 = short, 2 = long). */
1439 16, /* bitsize. */
1440 FALSE, /* pc_relative. */
1441 1, /* bitpos. */
1442 complain_overflow_dont, /* complain_on_overflow. */
1443 v850_elf_reloc, /* special_function. */
1444 "R_V850_16_S1", /* name. */
1445 FALSE, /* partial_inplace. */
1446 0xfffe, /* src_mask. */
1447 0xfffe, /* dst_mask. */
1448 FALSE), /* pcrel_offset. */
1449
1450 /* Low 16 bits of symbol value. */
1451 HOWTO (R_V850_LO16_S1, /* type. */
1452 1, /* rightshift. */
1453 1, /* size (0 = byte, 1 = short, 2 = long). */
1454 16, /* bitsize. */
1455 FALSE, /* pc_relative. */
1456 1, /* bitpos. */
1457 complain_overflow_dont, /* complain_on_overflow. */
1458 v850_elf_reloc, /* special_function. */
1459 "R_V850_LO16_S1", /* name. */
1460 FALSE, /* partial_inplace. */
1461 0xfffe, /* src_mask. */
1462 0xfffe, /* dst_mask. */
1463 FALSE), /* pcrel_offset. */
1464
1465 /* 16 bit offset from the call table base pointer. */
1466 HOWTO (R_V850_CALLT_15_16_OFFSET, /* type. */
1467 1, /* rightshift. */
1468 1, /* size (0 = byte, 1 = short, 2 = long). */
1469 16, /* bitsize. */
1470 FALSE, /* pc_relative. */
1471 1, /* bitpos. */
1472 complain_overflow_dont, /* complain_on_overflow. */
1473 v850_elf_reloc, /* special_function. */
1474 "R_V850_CALLT_15_16_OFFSET", /* name. */
1475 FALSE, /* partial_inplace. */
1476 0xfffe, /* src_mask. */
1477 0xfffe, /* dst_mask. */
1478 FALSE), /* pcrel_offset. */
1479
1480 /* Like R_V850_32 PCREL, but referring to the GOT table entry for
1481 the symbol. */
1482 HOWTO (R_V850_32_GOTPCREL, /* type. */
1483 0, /* rightshift. */
1484 2, /* size (0 = byte, 1 = short, 2 = long). */
1485 32, /* bitsize. */
1486 TRUE, /* pc_relative. */
1487 0, /* bitpos. */
1488 complain_overflow_unsigned, /* complain_on_overflow. */
1489 v850_elf_reloc, /* special_function. */
1490 "R_V850_32_GOTPCREL", /* name. */
1491 FALSE, /* partial_inplace. */
1492 0xffffffff, /* src_mask. */
1493 0xffffffff, /* dst_mask. */
1494 TRUE), /* pcrel_offset. */
1495
1496 /* Like R_V850_SDA_, but referring to the GOT table entry for
1497 the symbol. */
1498 HOWTO (R_V850_16_GOT, /* type. */
1499 0, /* rightshift. */
1500 2, /* size (0 = byte, 1 = short, 2 = long). */
1501 16, /* bitsize. */
1502 FALSE, /* pc_relative. */
1503 0, /* bitpos. */
1504 complain_overflow_unsigned, /* complain_on_overflow. */
1505 bfd_elf_generic_reloc, /* special_function. */
1506 "R_V850_16_GOT", /* name. */
1507 FALSE, /* partial_inplace. */
1508 0xffff, /* src_mask. */
1509 0xffff, /* dst_mask. */
1510 FALSE), /* pcrel_offset. */
1511
1512 HOWTO (R_V850_32_GOT, /* type. */
1513 0, /* rightshift. */
1514 2, /* size (0 = byte, 1 = short, 2 = long). */
1515 32, /* bitsize. */
1516 FALSE, /* pc_relative. */
1517 0, /* bitpos. */
1518 complain_overflow_unsigned, /* complain_on_overflow. */
1519 bfd_elf_generic_reloc, /* special_function. */
1520 "R_V850_32_GOT", /* name. */
1521 FALSE, /* partial_inplace. */
1522 0xffffffff, /* src_mask. */
1523 0xffffffff, /* dst_mask. */
1524 FALSE), /* pcrel_offset. */
1525
1526 /* Like R_V850_22_PCREL, but referring to the procedure linkage table
1527 entry for the symbol. */
1528 HOWTO (R_V850_22_PLT, /* type. */
1529 1, /* rightshift. */
1530 2, /* size (0 = byte, 1 = short, 2 = long). */
1531 22, /* bitsize. */
1532 TRUE, /* pc_relative. */
1533 7, /* bitpos. */
1534 complain_overflow_signed, /* complain_on_overflow. */
1535 bfd_elf_generic_reloc, /* special_function. */
1536 "R_V850_22_PLT", /* name. */
1537 FALSE, /* partial_inplace. */
1538 0x07ffff80, /* src_mask. */
1539 0x07ffff80, /* dst_mask. */
1540 TRUE), /* pcrel_offset. */
1541
1542 HOWTO (R_V850_32_PLT, /* type. */
1543 1, /* rightshift. */
1544 2, /* size (0 = byte, 1 = short, 2 = long). */
1545 32, /* bitsize. */
1546 TRUE, /* pc_relative. */
1547 1, /* bitpos. */
1548 complain_overflow_signed, /* complain_on_overflow. */
1549 bfd_elf_generic_reloc, /* special_function. */
1550 "R_V850_32_PLT", /* name. */
1551 FALSE, /* partial_inplace. */
1552 0xffffffff, /* src_mask. */
1553 0xffffffff, /* dst_mask. */
1554 TRUE), /* pcrel_offset. */
1555
1556 /* This is used only by the dynamic linker. The symbol should exist
1557 both in the object being run and in some shared library. The
1558 dynamic linker copies the data addressed by the symbol from the
1559 shared library into the object, because the object being
1560 run has to have the data at some particular address. */
1561 HOWTO (R_V850_COPY, /* type. */
1562 0, /* rightshift. */
1563 2, /* size (0 = byte, 1 = short, 2 = long). */
1564 32, /* bitsize. */
1565 FALSE, /* pc_relative. */
1566 0, /* bitpos. */
1567 complain_overflow_bitfield, /* complain_on_overflow. */
1568 bfd_elf_generic_reloc, /* special_function. */
1569 "R_V850_COPY", /* name. */
1570 FALSE, /* partial_inplace. */
1571 0xffffffff, /* src_mask. */
1572 0xffffffff, /* dst_mask. */
1573 FALSE), /* pcrel_offset. */
1574
1575 /* Like R_M32R_24, but used when setting global offset table
1576 entries. */
1577 HOWTO (R_V850_GLOB_DAT, /* type. */
1578 0, /* rightshift. */
1579 2, /* size (0 = byte, 1 = short, 2 = long) */
1580 32, /* bitsize. */
1581 FALSE, /* pc_relative. */
1582 0, /* bitpos. */
1583 complain_overflow_bitfield, /* complain_on_overflow. */
1584 bfd_elf_generic_reloc, /* special_function. */
1585 "R_V850_GLOB_DAT", /* name. */
1586 FALSE, /* partial_inplace. */
1587 0xffffffff, /* src_mask. */
1588 0xffffffff, /* dst_mask. */
1589 FALSE), /* pcrel_offset. */
1590
1591 /* Marks a procedure linkage table entry for a symbol. */
1592 HOWTO (R_V850_JMP_SLOT, /* type. */
1593 0, /* rightshift. */
1594 2, /* size (0 = byte, 1 = short, 2 = long) */
1595 32, /* bitsize. */
1596 FALSE, /* pc_relative. */
1597 0, /* bitpos. */
1598 complain_overflow_bitfield, /* complain_on_overflow. */
1599 bfd_elf_generic_reloc, /* special_function. */
1600 "R_V850_JMP_SLOT", /* name. */
1601 FALSE, /* partial_inplace. */
1602 0xffffffff, /* src_mask. */
1603 0xffffffff, /* dst_mask. */
1604 FALSE), /* pcrel_offset. */
1605
1606 /* Used only by the dynamic linker. When the object is run, this
1607 longword is set to the load address of the object, plus the
1608 addend. */
1609 HOWTO (R_V850_RELATIVE, /* type. */
1610 0, /* rightshift. */
1611 2, /* size (0 = byte, 1 = short, 2 = long) */
1612 32, /* bitsize. */
1613 FALSE, /* pc_relative. */
1614 0, /* bitpos. */
1615 complain_overflow_bitfield, /* complain_on_overflow. */
1616 bfd_elf_generic_reloc, /* special_function. */
1617 "R_V850_RELATIVE", /* name. */
1618 FALSE, /* partial_inplace. */
1619 0xffffffff, /* src_mask. */
1620 0xffffffff, /* dst_mask. */
1621 FALSE), /* pcrel_offset. */
1622
1623 HOWTO (R_V850_16_GOTOFF, /* type. */
1624 0, /* rightshift. */
1625 2, /* size (0 = byte, 1 = short, 2 = long) */
1626 16, /* bitsize. */
1627 FALSE, /* pc_relative. */
1628 0, /* bitpos. */
1629 complain_overflow_bitfield, /* complain_on_overflow. */
1630 bfd_elf_generic_reloc, /* special_function. */
1631 "R_V850_16_GOTOFF", /* name. */
1632 FALSE, /* partial_inplace. */
1633 0xffff, /* src_mask. */
1634 0xffff, /* dst_mask. */
1635 FALSE), /* pcrel_offset. */
1636
1637 HOWTO (R_V850_32_GOTOFF, /* type. */
1638 0, /* rightshift. */
1639 2, /* size (0 = byte, 1 = short, 2 = long) */
1640 32, /* bitsize. */
1641 FALSE, /* pc_relative. */
1642 0, /* bitpos. */
1643 complain_overflow_bitfield, /* complain_on_overflow. */
1644 bfd_elf_generic_reloc, /* special_function. */
1645 "R_V850_32_GOTOFF", /* name. */
1646 FALSE, /* partial_inplace. */
1647 0xffffffff, /* src_mask. */
1648 0xffffffff, /* dst_mask. */
1649 FALSE), /* pcrel_offset. */
1650
1651 HOWTO (R_V850_CODE, /* type. */
1652 0, /* rightshift. */
1653 1, /* size (0 = byte, 1 = short, 2 = long) */
1654 0, /* bitsize. */
1655 FALSE, /* pc_relative. */
1656 0, /* bitpos. */
1657 complain_overflow_unsigned, /* complain_on_overflow. */
1658 v850_elf_ignore_reloc, /* special_function. */
1659 "R_V850_CODE", /* name. */
1660 FALSE, /* partial_inplace. */
1661 0, /* src_mask. */
1662 0, /* dst_mask. */
1663 TRUE), /* pcrel_offset. */
1664
1665 HOWTO (R_V850_DATA, /* type. */
1666 0, /* rightshift. */
1667 1, /* size (0 = byte, 1 = short, 2 = long) */
1668 0, /* bitsize. */
1669 FALSE, /* pc_relative. */
1670 0, /* bitpos. */
1671 complain_overflow_unsigned, /* complain_on_overflow. */
1672 v850_elf_ignore_reloc, /* special_function. */
1673 "R_V850_DATA", /* name. */
1674 FALSE, /* partial_inplace. */
1675 0, /* src_mask. */
1676 0, /* dst_mask. */
1677 TRUE), /* pcrel_offset. */
1678
47b0e7ad
NC
1679};
1680
1681/* Map BFD reloc types to V850 ELF reloc types. */
1682
1683struct v850_elf_reloc_map
1684{
1685 /* BFD_RELOC_V850_CALLT_16_16_OFFSET is 258, which will not fix in an
1686 unsigned char. */
1687 bfd_reloc_code_real_type bfd_reloc_val;
1688 unsigned int elf_reloc_val;
1689};
1690
1691static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
1692{
1cd986c5
NC
1693 { BFD_RELOC_NONE, R_V850_NONE },
1694 { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL },
1695 { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL },
1696 { BFD_RELOC_HI16_S, R_V850_HI16_S },
1697 { BFD_RELOC_HI16, R_V850_HI16 },
1698 { BFD_RELOC_LO16, R_V850_LO16 },
1699 { BFD_RELOC_32, R_V850_ABS32 },
1700 { BFD_RELOC_32_PCREL, R_V850_REL32 },
1701 { BFD_RELOC_16, R_V850_16 },
1702 { BFD_RELOC_8, R_V850_8 },
47b0e7ad
NC
1703 { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
1704 { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
1705 { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
1706 { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
1707 { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET },
1708 { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET },
1709 { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET },
1710 { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
1711 { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET },
1712 { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET },
1713 { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_LO16_SPLIT_OFFSET },
1714 { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
1715 { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
1716 { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET },
1717 { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET },
1718 { BFD_RELOC_VTABLE_INHERIT, R_V850_GNU_VTINHERIT },
1719 { BFD_RELOC_VTABLE_ENTRY, R_V850_GNU_VTENTRY },
1720 { BFD_RELOC_V850_LONGCALL, R_V850_LONGCALL },
1721 { BFD_RELOC_V850_LONGJUMP, R_V850_LONGJUMP },
1722 { BFD_RELOC_V850_ALIGN, R_V850_ALIGN },
1cd986c5
NC
1723 { BFD_RELOC_V850_16_PCREL, R_V850_16_PCREL },
1724 { BFD_RELOC_V850_17_PCREL, R_V850_17_PCREL },
1725 { BFD_RELOC_V850_23, R_V850_23 },
1726 { BFD_RELOC_V850_32_PCREL, R_V850_32_PCREL },
1727 { BFD_RELOC_V850_32_ABS, R_V850_32_ABS },
1728 { BFD_RELOC_V850_16_SPLIT_OFFSET, R_V850_HI16 },
1729 { BFD_RELOC_V850_16_S1, R_V850_16_S1 },
1730 { BFD_RELOC_V850_LO16_S1, R_V850_LO16_S1 },
1731 { BFD_RELOC_V850_CALLT_15_16_OFFSET, R_V850_CALLT_15_16_OFFSET },
1732 { BFD_RELOC_V850_32_GOTPCREL, R_V850_32_GOTPCREL },
1733 { BFD_RELOC_V850_16_GOT, R_V850_16_GOT },
1734 { BFD_RELOC_V850_32_GOT, R_V850_32_GOT },
1735 { BFD_RELOC_V850_22_PLT_PCREL, R_V850_22_PLT },
1736 { BFD_RELOC_V850_32_PLT_PCREL, R_V850_32_PLT },
1737 { BFD_RELOC_V850_COPY, R_V850_COPY },
1738 { BFD_RELOC_V850_GLOB_DAT, R_V850_GLOB_DAT },
1739 { BFD_RELOC_V850_JMP_SLOT, R_V850_JMP_SLOT },
1740 { BFD_RELOC_V850_RELATIVE, R_V850_RELATIVE },
1741 { BFD_RELOC_V850_16_GOTOFF, R_V850_16_GOTOFF },
1742 { BFD_RELOC_V850_32_GOTOFF, R_V850_32_GOTOFF },
1743 { BFD_RELOC_V850_CODE, R_V850_CODE },
1744 { BFD_RELOC_V850_DATA, R_V850_DATA },
47b0e7ad 1745};
de863c74
NC
1746
1747#define V800_RELOC(name,sz,bit,shift,complain,pcrel,resolver) \
1748 HOWTO (name, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
1749 bfd_elf_ ## resolver ## _reloc, #name, FALSE, 0, ~0, FALSE)
1750
1751#define V800_EMPTY(name) EMPTY_HOWTO (name - R_V810_NONE)
1752
1753#define bfd_elf_v850_reloc v850_elf_reloc
1754
1755/* Note: It is REQUIRED that the 'type' value (R_V810_...) of each entry
1756 in this array match the index of the entry in the array minus 0x30.
1757 See: bfd_elf_v850_relocate_section(), v800_elf_reloc_type_lookup()
1758 and v800_elf_info_to_howto(). */
1759
1760static reloc_howto_type v800_elf_howto_table[] =
1761{
1762 V800_RELOC (R_V810_NONE, 0, 0, 0, dont, FALSE, generic), /* Type = 0x30 */
1763 V800_RELOC (R_V810_BYTE, 0, 8, 0, dont, FALSE, generic),
1764 V800_RELOC (R_V810_HWORD, 1, 16, 0, dont, FALSE, generic),
1765 V800_RELOC (R_V810_WORD, 2, 32, 0, dont, FALSE, generic),
1766 V800_RELOC (R_V810_WLO, 1, 16, 0, dont, FALSE, generic),
1767 V800_RELOC (R_V810_WHI, 1, 16, 0, dont, FALSE, generic),
1768 V800_RELOC (R_V810_WHI1, 1, 16, 0, dont, FALSE, generic),
1769 V800_RELOC (R_V810_GPBYTE, 0, 8, 0, dont, FALSE, v850),
1770 V800_RELOC (R_V810_GPHWORD, 1, 16, 0, dont, FALSE, v850),
1771 V800_RELOC (R_V810_GPWORD, 2, 32, 0, dont, FALSE, v850),
1772 V800_RELOC (R_V810_GPWLO, 1, 16, 0, dont, FALSE, v850),
1773 V800_RELOC (R_V810_GPWHI, 1, 16, 0, dont, FALSE, v850),
1774 V800_RELOC (R_V810_GPWHI1, 1, 16, 0, dont, FALSE, v850),
1775 V800_RELOC (R_V850_HWLO, 1, 16, 0, dont, FALSE, generic),
1776 V800_EMPTY (R_V810_reserved1),
1777 V800_RELOC (R_V850_EP7BIT, 0, 7, 0, unsigned, FALSE, v850),
1778 V800_RELOC (R_V850_EPHBYTE, 0, 8, 1, unsigned, FALSE, v850),
1779 V800_RELOC (R_V850_EPWBYTE, 0, 8, 2, unsigned, FALSE, v850),
1780 V800_RELOC (R_V850_REGHWLO, 1, 16, 0, dont, FALSE, v850),
1781 V800_EMPTY (R_V810_reserved2),
1782 V800_RELOC (R_V850_GPHWLO, 1, 16, 0, dont, FALSE, v850),
1783 V800_EMPTY (R_V810_reserved3),
1784 V800_RELOC (R_V850_PCR22, 2, 22, 0, signed, TRUE, generic),
1785 V800_RELOC (R_V850_BLO, 2, 24, 0, dont, FALSE, v850),
1786 V800_RELOC (R_V850_EP4BIT, 0, 4, 0, unsigned, FALSE, v850),
1787 V800_RELOC (R_V850_EP5BIT, 0, 5, 0, unsigned, FALSE, v850),
1788 V800_RELOC (R_V850_REGBLO, 2, 24, 0, dont, FALSE, v850),
1789 V800_RELOC (R_V850_GPBLO, 2, 24, 0, dont, FALSE, v850),
1790 V800_RELOC (R_V810_WLO_1, 1, 16, 0, dont, FALSE, v850),
1791 V800_RELOC (R_V810_GPWLO_1, 1, 16, 0, signed, FALSE, v850),
1792 V800_RELOC (R_V850_BLO_1, 2, 16, 0, signed, FALSE, v850),
1793 V800_RELOC (R_V850_HWLO_1, 1, 16, 0, signed, FALSE, v850),
1794 V800_EMPTY (R_V810_reserved4),
1795 V800_RELOC (R_V850_GPBLO_1, 2, 16, 1, signed, FALSE, v850),
1796 V800_RELOC (R_V850_GPHWLO_1, 1, 16, 1, signed, FALSE, v850),
1797 V800_EMPTY (R_V810_reserved5),
1798 V800_RELOC (R_V850_EPBLO, 2, 16, 1, signed, FALSE, v850),
1799 V800_RELOC (R_V850_EPHWLO, 1, 16, 1, signed, FALSE, v850),
1800 V800_EMPTY (R_V810_reserved6),
1801 V800_RELOC (R_V850_EPWLO_N, 1, 16, 1, signed, FALSE, v850),
1802 V800_RELOC (R_V850_PC32, 2, 32, 1, signed, TRUE, v850),
1803 V800_RELOC (R_V850_W23BIT, 2, 23, 1, signed, FALSE, v850),
1804 V800_RELOC (R_V850_GPW23BIT, 2, 23, 1, signed, FALSE, v850),
1805 V800_RELOC (R_V850_EPW23BIT, 2, 23, 1, signed, FALSE, v850),
1806 V800_RELOC (R_V850_B23BIT, 2, 23, 1, signed, FALSE, v850),
1807 V800_RELOC (R_V850_GPB23BIT, 2, 23, 1, signed, FALSE, v850),
1808 V800_RELOC (R_V850_EPB23BIT, 2, 23, 1, signed, FALSE, v850),
1809 V800_RELOC (R_V850_PC16U, 1, 16, 1, unsigned, TRUE, generic),
1810 V800_RELOC (R_V850_PC17, 2, 17, 1, signed, TRUE, generic),
1811 V800_RELOC (R_V850_DW8, 2, 8, 2, signed, FALSE, v850),
1812 V800_RELOC (R_V850_GPDW8, 2, 8, 2, signed, FALSE, v850),
1813 V800_RELOC (R_V850_EPDW8, 2, 8, 2, signed, FALSE, v850),
1814 V800_RELOC (R_V850_PC9, 1, 9, 3, signed, TRUE, v850),
1815 V800_RELOC (R_V810_REGBYTE, 0, 8, 0, dont, FALSE, v850),
1816 V800_RELOC (R_V810_REGHWORD, 1, 16, 0, dont, FALSE, v850),
1817 V800_RELOC (R_V810_REGWORD, 2, 32, 0, dont, FALSE, v850),
1818 V800_RELOC (R_V810_REGWLO, 1, 16, 0, dont, FALSE, v850),
1819 V800_RELOC (R_V810_REGWHI, 1, 16, 0, dont, FALSE, v850),
1820 V800_RELOC (R_V810_REGWHI1, 1, 16, 0, dont, FALSE, v850),
1821 V800_RELOC (R_V850_REGW23BIT, 2, 23, 1, signed, FALSE, v850),
1822 V800_RELOC (R_V850_REGB23BIT, 2, 23, 1, signed, FALSE, v850),
1823 V800_RELOC (R_V850_REGDW8, 2, 8, 2, signed, FALSE, v850),
1824 V800_RELOC (R_V810_EPBYTE, 0, 8, 0, dont, FALSE, v850),
1825 V800_RELOC (R_V810_EPHWORD, 1, 16, 0, dont, FALSE, v850),
1826 V800_RELOC (R_V810_EPWORD, 2, 32, 0, dont, FALSE, v850),
1827 V800_RELOC (R_V850_WLO23, 2, 32, 1, dont, FALSE, v850),
1828 V800_RELOC (R_V850_WORD_E, 2, 32, 1, dont, FALSE, v850),
1829 V800_RELOC (R_V850_REGWORD_E, 2, 32, 1, dont, FALSE, v850),
1830 V800_RELOC (R_V850_WORD, 2, 32, 0, dont, FALSE, v850),
1831 V800_RELOC (R_V850_GPWORD, 2, 32, 0, dont, FALSE, v850),
1832 V800_RELOC (R_V850_REGWORD, 2, 32, 0, dont, FALSE, v850),
1833 V800_RELOC (R_V850_EPWORD, 2, 32, 0, dont, FALSE, v850),
1834 V800_RELOC (R_V810_TPBYTE, 0, 8, 0, dont, FALSE, v850),
1835 V800_RELOC (R_V810_TPHWORD, 1, 16, 0, dont, FALSE, v850),
1836 V800_RELOC (R_V810_TPWORD, 2, 32, 0, dont, FALSE, v850),
1837 V800_RELOC (R_V810_TPWLO, 1, 16, 0, dont, FALSE, v850),
1838 V800_RELOC (R_V810_TPWHI, 1, 16, 0, dont, FALSE, v850),
1839 V800_RELOC (R_V810_TPWHI1, 1, 16, 0, dont, FALSE, v850),
1840 V800_RELOC (R_V850_TPHWLO, 1, 16, 1, dont, FALSE, v850),
1841 V800_RELOC (R_V850_TPBLO, 2, 24, 0, dont, FALSE, v850),
1842 V800_RELOC (R_V810_TPWLO_1, 1, 16, 0, signed, FALSE, v850),
1843 V800_RELOC (R_V850_TPBLO_1, 2, 16, 0, signed, FALSE, v850),
1844 V800_RELOC (R_V850_TPHWLO_1, 1, 16, 0, signed, FALSE, v850),
1845 V800_RELOC (R_V850_TP23BIT, 2, 23, 0, signed, FALSE, v850),
1846 V800_RELOC (R_V850_TPW23BIT, 2, 23, 0, signed, FALSE, v850),
1847 V800_RELOC (R_V850_TPDW8, 2, 8, 0, signed, FALSE, v850)
1848};
47b0e7ad
NC
1849\f
1850/* Map a bfd relocation into the appropriate howto structure. */
1851
1852static reloc_howto_type *
1853v850_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1854 bfd_reloc_code_real_type code)
1855{
1856 unsigned int i;
1857
1858 for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;)
1859 if (v850_elf_reloc_map[i].bfd_reloc_val == code)
1860 {
1861 unsigned int elf_reloc_val = v850_elf_reloc_map[i].elf_reloc_val;
1862
1863 BFD_ASSERT (v850_elf_howto_table[elf_reloc_val].type == elf_reloc_val);
1864
1865 return v850_elf_howto_table + elf_reloc_val;
1866 }
1867
1868 return NULL;
1869}
157090f7
AM
1870
1871static reloc_howto_type *
1872v850_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1873 const char *r_name)
1874{
1875 unsigned int i;
1876
1877 for (i = 0;
1878 i < sizeof (v850_elf_howto_table) / sizeof (v850_elf_howto_table[0]);
1879 i++)
1880 if (v850_elf_howto_table[i].name != NULL
1881 && strcasecmp (v850_elf_howto_table[i].name, r_name) == 0)
1882 return &v850_elf_howto_table[i];
1883
1884 return NULL;
1885}
47b0e7ad
NC
1886\f
1887/* Set the howto pointer for an V850 ELF reloc. */
1888
1889static void
1890v850_elf_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
1891 arelent *cache_ptr,
1892 Elf_Internal_Rela *dst)
1893{
1894 unsigned int r_type;
1895
1896 r_type = ELF32_R_TYPE (dst->r_info);
1897 BFD_ASSERT (r_type < (unsigned int) R_V850_max);
1898 cache_ptr->howto = &v850_elf_howto_table[r_type];
1899}
1900
1901/* Set the howto pointer for a V850 ELF reloc (type RELA). */
1902
1903static void
1904v850_elf_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
1905 arelent * cache_ptr,
1906 Elf_Internal_Rela *dst)
1907{
1908 unsigned int r_type;
1909
1910 r_type = ELF32_R_TYPE (dst->r_info);
1911 BFD_ASSERT (r_type < (unsigned int) R_V850_max);
1912 cache_ptr->howto = &v850_elf_howto_table[r_type];
1913}
252b5132 1914\f
b34976b6 1915static bfd_boolean
47b0e7ad 1916v850_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
252b5132
RH
1917{
1918 return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
1919 || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_'));
1920}
252b5132 1921\f
5cec6941
NC
1922/* We overload some of the bfd_reloc error codes for own purposes. */
1923#define bfd_reloc_gp_not_found bfd_reloc_other
1924#define bfd_reloc_ep_not_found bfd_reloc_continue
1925#define bfd_reloc_ctbp_not_found (bfd_reloc_dangerous + 1)
1926
252b5132 1927/* Perform a relocation as part of a final link. */
e12dd2ea 1928
252b5132 1929static bfd_reloc_status_type
47b0e7ad
NC
1930v850_elf_final_link_relocate (reloc_howto_type *howto,
1931 bfd *input_bfd,
1932 bfd *output_bfd ATTRIBUTE_UNUSED,
1933 asection *input_section,
1934 bfd_byte *contents,
1935 bfd_vma offset,
1936 bfd_vma value,
1937 bfd_vma addend,
1938 struct bfd_link_info *info,
1939 asection *sym_sec,
1940 int is_local ATTRIBUTE_UNUSED)
252b5132 1941{
b34976b6
AM
1942 unsigned int r_type = howto->type;
1943 bfd_byte *hit_data = contents + offset;
252b5132
RH
1944
1945 /* Adjust the value according to the relocation. */
1946 switch (r_type)
1947 {
de863c74 1948 case R_V850_PC9:
252b5132
RH
1949 case R_V850_9_PCREL:
1950 value -= (input_section->output_section->vma
1951 + input_section->output_offset);
1952 value -= offset;
1953 break;
435b1e90 1954
de863c74 1955 case R_V850_PC16U:
1cd986c5
NC
1956 case R_V850_16_PCREL:
1957 value -= (input_section->output_section->vma
1958 + input_section->output_offset
1959 + offset);
1960
1961 /* If the sign extension will corrupt the value then we have overflowed. */
1962 if ((value & 0xffff0000) != 0xffff0000)
1963 return bfd_reloc_overflow;
1964
1965 break;
1966
de863c74 1967 case R_V850_PC17:
1cd986c5
NC
1968 case R_V850_17_PCREL:
1969 value -= (input_section->output_section->vma
1970 + input_section->output_offset
1971 + offset);
1972
1973 /* If the sign extension will corrupt the value then we have overflowed. */
1974 if (((value & 0xffff0000) != 0x0) && ((value & 0xffff0000) != 0xffff0000))
1975 return bfd_reloc_overflow;
1976
1977 value = SEXT17 (value);
1978 break;
1979
de863c74 1980 case R_V850_PCR22:
252b5132
RH
1981 case R_V850_22_PCREL:
1982 value -= (input_section->output_section->vma
1983 + input_section->output_offset
1984 + offset);
1985
232fb1a3 1986 /* If the sign extension will corrupt the value then we have overflowed. */
1cd986c5 1987 if (((value & 0xffe00000) != 0x0) && ((value & 0xffe00000) != 0xffe00000))
232fb1a3 1988 return bfd_reloc_overflow;
435b1e90 1989
1cd986c5
NC
1990 /* Only the bottom 22 bits of the PC are valid. */
1991 value = SEXT22 (value);
252b5132 1992 break;
435b1e90 1993
de863c74 1994 case R_V850_PC32:
1cd986c5 1995 case R_V850_32_PCREL:
e30ddb24
NC
1996 value -= (input_section->output_section->vma
1997 + input_section->output_offset
1998 + offset);
1999 break;
2000
1cd986c5
NC
2001 case R_V850_32_ABS:
2002 case R_V850_23:
252b5132
RH
2003 case R_V850_HI16_S:
2004 case R_V850_HI16:
2005 case R_V850_LO16:
1cd986c5 2006 case R_V850_LO16_S1:
1e50d24d 2007 case R_V850_LO16_SPLIT_OFFSET:
252b5132 2008 case R_V850_16:
e30ddb24 2009 case R_V850_ABS32:
252b5132 2010 case R_V850_8:
de863c74
NC
2011 case R_V810_BYTE:
2012 case R_V810_HWORD:
2013 case R_V810_WORD:
2014 case R_V810_WLO:
2015 case R_V810_WHI:
2016 case R_V810_WHI1:
2017 case R_V810_WLO_1:
2018 case R_V850_WLO23:
2019 case R_V850_BLO:
252b5132
RH
2020 break;
2021
435b1e90 2022 case R_V850_ZDA_15_16_OFFSET:
252b5132
RH
2023 case R_V850_ZDA_16_16_OFFSET:
2024 case R_V850_ZDA_16_16_SPLIT_OFFSET:
2025 if (sym_sec == NULL)
2026 return bfd_reloc_undefined;
435b1e90 2027
252b5132
RH
2028 value -= sym_sec->output_section->vma;
2029 break;
2030
2031 case R_V850_SDA_15_16_OFFSET:
2032 case R_V850_SDA_16_16_OFFSET:
2033 case R_V850_SDA_16_16_SPLIT_OFFSET:
de863c74 2034 case R_V810_GPWLO_1:
252b5132
RH
2035 {
2036 unsigned long gp;
2037 struct bfd_link_hash_entry * h;
2038
2039 if (sym_sec == NULL)
2040 return bfd_reloc_undefined;
435b1e90 2041
252b5132 2042 /* Get the value of __gp. */
b34976b6 2043 h = bfd_link_hash_lookup (info->hash, "__gp", FALSE, FALSE, TRUE);
47b0e7ad 2044 if (h == NULL
252b5132 2045 || h->type != bfd_link_hash_defined)
5cec6941 2046 return bfd_reloc_gp_not_found;
252b5132
RH
2047
2048 gp = (h->u.def.value
2049 + h->u.def.section->output_section->vma
2050 + h->u.def.section->output_offset);
2051
2052 value -= sym_sec->output_section->vma;
2053 value -= (gp - sym_sec->output_section->vma);
2054 }
2055 break;
2056
2057 case R_V850_TDA_4_4_OFFSET:
2058 case R_V850_TDA_4_5_OFFSET:
252b5132
RH
2059 case R_V850_TDA_7_7_OFFSET:
2060 case R_V850_TDA_7_8_OFFSET:
2061 case R_V850_TDA_6_8_OFFSET:
1cd986c5 2062 case R_V850_TDA_16_16_OFFSET:
252b5132
RH
2063 {
2064 unsigned long ep;
2065 struct bfd_link_hash_entry * h;
435b1e90 2066
252b5132 2067 /* Get the value of __ep. */
b34976b6 2068 h = bfd_link_hash_lookup (info->hash, "__ep", FALSE, FALSE, TRUE);
47b0e7ad 2069 if (h == NULL
252b5132 2070 || h->type != bfd_link_hash_defined)
5cec6941 2071 return bfd_reloc_ep_not_found;
252b5132
RH
2072
2073 ep = (h->u.def.value
2074 + h->u.def.section->output_section->vma
2075 + h->u.def.section->output_offset);
2076
2077 value -= ep;
2078 }
2079 break;
435b1e90 2080
252b5132
RH
2081 case R_V850_CALLT_6_7_OFFSET:
2082 {
2083 unsigned long ctbp;
2084 struct bfd_link_hash_entry * h;
435b1e90 2085
252b5132 2086 /* Get the value of __ctbp. */
b34976b6 2087 h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
47b0e7ad 2088 if (h == NULL
252b5132 2089 || h->type != bfd_link_hash_defined)
5cec6941 2090 return bfd_reloc_ctbp_not_found;
252b5132
RH
2091
2092 ctbp = (h->u.def.value
2093 + h->u.def.section->output_section->vma
2094 + h->u.def.section->output_offset);
2095 value -= ctbp;
2096 }
2097 break;
435b1e90 2098
1cd986c5 2099 case R_V850_CALLT_15_16_OFFSET:
252b5132
RH
2100 case R_V850_CALLT_16_16_OFFSET:
2101 {
2102 unsigned long ctbp;
2103 struct bfd_link_hash_entry * h;
2104
2105 if (sym_sec == NULL)
2106 return bfd_reloc_undefined;
435b1e90 2107
252b5132 2108 /* Get the value of __ctbp. */
b34976b6 2109 h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
47b0e7ad 2110 if (h == NULL
252b5132 2111 || h->type != bfd_link_hash_defined)
5cec6941 2112 return bfd_reloc_ctbp_not_found;
252b5132
RH
2113
2114 ctbp = (h->u.def.value
2115 + h->u.def.section->output_section->vma
2116 + h->u.def.section->output_offset);
2117
2118 value -= sym_sec->output_section->vma;
2119 value -= (ctbp - sym_sec->output_section->vma);
2120 }
2121 break;
435b1e90 2122
252b5132 2123 case R_V850_NONE:
de863c74 2124 case R_V810_NONE:
252b5132
RH
2125 case R_V850_GNU_VTINHERIT:
2126 case R_V850_GNU_VTENTRY:
86aba9db
NC
2127 case R_V850_LONGCALL:
2128 case R_V850_LONGJUMP:
2129 case R_V850_ALIGN:
252b5132
RH
2130 return bfd_reloc_ok;
2131
2132 default:
de863c74
NC
2133#ifdef DEBUG
2134 fprintf (stderr, "reloc number %d not recognised\n", r_type);
2135#endif
252b5132
RH
2136 return bfd_reloc_notsupported;
2137 }
2138
2139 /* Perform the relocation. */
435b1e90 2140 return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data);
252b5132 2141}
252b5132
RH
2142\f
2143/* Relocate an V850 ELF section. */
e12dd2ea 2144
b34976b6 2145static bfd_boolean
47b0e7ad
NC
2146v850_elf_relocate_section (bfd *output_bfd,
2147 struct bfd_link_info *info,
2148 bfd *input_bfd,
2149 asection *input_section,
2150 bfd_byte *contents,
2151 Elf_Internal_Rela *relocs,
2152 Elf_Internal_Sym *local_syms,
2153 asection **local_sections)
252b5132 2154{
b34976b6
AM
2155 Elf_Internal_Shdr *symtab_hdr;
2156 struct elf_link_hash_entry **sym_hashes;
2157 Elf_Internal_Rela *rel;
2158 Elf_Internal_Rela *relend;
252b5132
RH
2159
2160 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
2161 sym_hashes = elf_sym_hashes (input_bfd);
2162
252b5132
RH
2163 /* Reset the list of remembered HI16S relocs to empty. */
2164 free_hi16s = previous_hi16s;
2165 previous_hi16s = NULL;
2166 hi16s_counter = 0;
435b1e90 2167
252b5132
RH
2168 rel = relocs;
2169 relend = relocs + input_section->reloc_count;
2170 for (; rel < relend; rel++)
2171 {
de863c74 2172 unsigned int r_type;
b34976b6
AM
2173 reloc_howto_type *howto;
2174 unsigned long r_symndx;
2175 Elf_Internal_Sym *sym;
2176 asection *sec;
2177 struct elf_link_hash_entry *h;
2178 bfd_vma relocation;
2179 bfd_reloc_status_type r;
252b5132
RH
2180
2181 r_symndx = ELF32_R_SYM (rel->r_info);
2182 r_type = ELF32_R_TYPE (rel->r_info);
2183
2184 if (r_type == R_V850_GNU_VTENTRY
2185 || r_type == R_V850_GNU_VTINHERIT)
2186 continue;
2187
de863c74
NC
2188 if (bfd_get_arch (input_bfd) == bfd_arch_v850_rh850)
2189 howto = v800_elf_howto_table + (r_type - R_V810_NONE);
2190 else
2191 howto = v850_elf_howto_table + r_type;
2192
2193 BFD_ASSERT (r_type == howto->type);
2194
252b5132
RH
2195 h = NULL;
2196 sym = NULL;
2197 sec = NULL;
2198 if (r_symndx < symtab_hdr->sh_info)
2199 {
2200 sym = local_syms + r_symndx;
2201 sec = local_sections[r_symndx];
8517fae7 2202 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
252b5132
RH
2203 }
2204 else
2205 {
59c2e50f 2206 bfd_boolean unresolved_reloc, warned;
435b1e90 2207
47b0e7ad
NC
2208 /* Note - this check is delayed until now as it is possible and
2209 valid to have a file without any symbols but with relocs that
2210 can be processed. */
641bd093
NC
2211 if (sym_hashes == NULL)
2212 {
2213 info->callbacks->warning
2214 (info, "no hash table available",
2215 NULL, input_bfd, input_section, (bfd_vma) 0);
2216
2217 return FALSE;
2218 }
2219
b2a8e766
AM
2220 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2221 r_symndx, symtab_hdr, sym_hashes,
2222 h, sec, relocation,
2223 unresolved_reloc, warned);
252b5132
RH
2224 }
2225
dbaa2011 2226 if (sec != NULL && discarded_section (sec))
e4067dbb 2227 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 2228 rel, 1, relend, howto, 0, contents);
ab96bf03
AM
2229
2230 if (info->relocatable)
2231 continue;
2232
e12dd2ea 2233 /* FIXME: We should use the addend, but the COFF relocations don't. */
252b5132
RH
2234 r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
2235 input_section,
2236 contents, rel->r_offset,
2237 relocation, rel->r_addend,
2238 info, sec, h == NULL);
2239
2240 if (r != bfd_reloc_ok)
2241 {
2242 const char * name;
47b0e7ad 2243 const char * msg = NULL;
252b5132
RH
2244
2245 if (h != NULL)
2246 name = h->root.root.string;
2247 else
2248 {
2249 name = (bfd_elf_string_from_elf_section
2250 (input_bfd, symtab_hdr->sh_link, sym->st_name));
2251 if (name == NULL || *name == '\0')
2252 name = bfd_section_name (input_bfd, sec);
2253 }
2254
ceaf50a2 2255 switch ((int) r)
252b5132
RH
2256 {
2257 case bfd_reloc_overflow:
2258 if (! ((*info->callbacks->reloc_overflow)
dfeffb9f
L
2259 (info, (h ? &h->root : NULL), name, howto->name,
2260 (bfd_vma) 0, input_bfd, input_section,
2261 rel->r_offset)))
b34976b6 2262 return FALSE;
252b5132
RH
2263 break;
2264
2265 case bfd_reloc_undefined:
2266 if (! ((*info->callbacks->undefined_symbol)
2267 (info, name, input_bfd, input_section,
b34976b6
AM
2268 rel->r_offset, TRUE)))
2269 return FALSE;
252b5132
RH
2270 break;
2271
2272 case bfd_reloc_outofrange:
2273 msg = _("internal error: out of range error");
2274 goto common_error;
2275
2276 case bfd_reloc_notsupported:
2277 msg = _("internal error: unsupported relocation error");
2278 goto common_error;
2279
2280 case bfd_reloc_dangerous:
2281 msg = _("internal error: dangerous relocation");
2282 goto common_error;
2283
5cec6941 2284 case bfd_reloc_gp_not_found:
252b5132
RH
2285 msg = _("could not locate special linker symbol __gp");
2286 goto common_error;
2287
5cec6941 2288 case bfd_reloc_ep_not_found:
252b5132
RH
2289 msg = _("could not locate special linker symbol __ep");
2290 goto common_error;
2291
5cec6941 2292 case bfd_reloc_ctbp_not_found:
252b5132
RH
2293 msg = _("could not locate special linker symbol __ctbp");
2294 goto common_error;
435b1e90 2295
252b5132
RH
2296 default:
2297 msg = _("internal error: unknown error");
2298 /* fall through */
2299
2300 common_error:
2301 if (!((*info->callbacks->warning)
2302 (info, msg, name, input_bfd, input_section,
2303 rel->r_offset)))
b34976b6 2304 return FALSE;
252b5132
RH
2305 break;
2306 }
2307 }
2308 }
2309
b34976b6 2310 return TRUE;
252b5132
RH
2311}
2312
252b5132 2313static asection *
47b0e7ad 2314v850_elf_gc_mark_hook (asection *sec,
07adf181 2315 struct bfd_link_info *info,
47b0e7ad
NC
2316 Elf_Internal_Rela *rel,
2317 struct elf_link_hash_entry *h,
2318 Elf_Internal_Sym *sym)
252b5132
RH
2319{
2320 if (h != NULL)
07adf181 2321 switch (ELF32_R_TYPE (rel->r_info))
252b5132
RH
2322 {
2323 case R_V850_GNU_VTINHERIT:
2324 case R_V850_GNU_VTENTRY:
07adf181
AM
2325 return NULL;
2326 }
9ad5cbcf 2327
07adf181 2328 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
252b5132 2329}
e12dd2ea 2330
de863c74 2331/* Set the right machine number and architecture. */
e12dd2ea 2332
b34976b6 2333static bfd_boolean
47b0e7ad 2334v850_elf_object_p (bfd *abfd)
252b5132 2335{
de863c74
NC
2336 enum bfd_architecture arch;
2337 unsigned long mach;
2338
2339 switch (elf_elfheader (abfd)->e_machine)
252b5132 2340 {
de863c74
NC
2341 case EM_V800:
2342 arch = bfd_arch_v850_rh850;
2343 mach = bfd_mach_v850e2v3;
8ad30312 2344 break;
de863c74
NC
2345
2346 case EM_CYGNUS_V850:
2347 case EM_V850:
2348 arch = bfd_arch_v850;
2349 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
2350 {
2351 default:
2352 case E_V850_ARCH: mach = bfd_mach_v850; break;
2353 case E_V850E_ARCH: mach = bfd_mach_v850e; break;
2354 case E_V850E1_ARCH: mach = bfd_mach_v850e1; break;
2355 case E_V850E2_ARCH: mach = bfd_mach_v850e2; break;
2356 case E_V850E2V3_ARCH: mach = bfd_mach_v850e2v3; break;
2357 }
1cd986c5 2358 break;
de863c74
NC
2359
2360 default:
2361 return FALSE;
252b5132 2362 }
de863c74
NC
2363
2364 return bfd_default_set_arch_mach (abfd, arch, mach);
252b5132
RH
2365}
2366
2367/* Store the machine number in the flags field. */
e12dd2ea 2368
252b5132 2369static void
47b0e7ad
NC
2370v850_elf_final_write_processing (bfd *abfd,
2371 bfd_boolean linker ATTRIBUTE_UNUSED)
252b5132
RH
2372{
2373 unsigned long val;
2374
de863c74 2375 switch (bfd_get_arch (abfd))
252b5132 2376 {
de863c74
NC
2377 case bfd_arch_v850_rh850:
2378 val = EF_RH850_ABI;
2379 elf_elfheader (abfd)->e_flags |= val;
2380 break;
2381
2382 case bfd_arch_v850:
2383 switch (bfd_get_mach (abfd))
2384 {
2385 default:
2386 case bfd_mach_v850: val = E_V850_ARCH; break;
2387 case bfd_mach_v850e: val = E_V850E_ARCH; break;
2388 case bfd_mach_v850e1: val = E_V850E1_ARCH; break;
2389 case bfd_mach_v850e2: val = E_V850E2_ARCH; break;
2390 case bfd_mach_v850e2v3: val = E_V850E2V3_ARCH; break;
2391 }
2392 elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
2393 elf_elfheader (abfd)->e_flags |= val;
2394 break;
b34976b6 2395 default:
de863c74 2396 break;
252b5132 2397 }
252b5132
RH
2398}
2399
435b1e90 2400/* Function to keep V850 specific file flags. */
e12dd2ea 2401
b34976b6 2402static bfd_boolean
47b0e7ad 2403v850_elf_set_private_flags (bfd *abfd, flagword flags)
252b5132
RH
2404{
2405 BFD_ASSERT (!elf_flags_init (abfd)
2406 || elf_elfheader (abfd)->e_flags == flags);
2407
2408 elf_elfheader (abfd)->e_flags = flags;
b34976b6
AM
2409 elf_flags_init (abfd) = TRUE;
2410 return TRUE;
252b5132
RH
2411}
2412
e12dd2ea
NC
2413/* Merge backend specific data from an object file
2414 to the output object file when linking. */
47b0e7ad 2415
b34976b6 2416static bfd_boolean
47b0e7ad 2417v850_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
252b5132
RH
2418{
2419 flagword out_flags;
2420 flagword in_flags;
2421
2422 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2423 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
b34976b6 2424 return TRUE;
252b5132
RH
2425
2426 in_flags = elf_elfheader (ibfd)->e_flags;
2427 out_flags = elf_elfheader (obfd)->e_flags;
2428
2429 if (! elf_flags_init (obfd))
2430 {
2431 /* If the input is the default architecture then do not
2432 bother setting the flags for the output architecture,
2433 instead allow future merges to do this. If no future
2434 merges ever set these flags then they will retain their
2435 unitialised values, which surprise surprise, correspond
2436 to the default values. */
2437 if (bfd_get_arch_info (ibfd)->the_default)
b34976b6 2438 return TRUE;
435b1e90 2439
b34976b6 2440 elf_flags_init (obfd) = TRUE;
252b5132
RH
2441 elf_elfheader (obfd)->e_flags = in_flags;
2442
2443 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
2444 && bfd_get_arch_info (obfd)->the_default)
e12dd2ea 2445 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
252b5132 2446
b34976b6 2447 return TRUE;
252b5132
RH
2448 }
2449
2450 /* Check flag compatibility. */
2451 if (in_flags == out_flags)
b34976b6 2452 return TRUE;
252b5132 2453
de863c74
NC
2454 if (bfd_get_arch (obfd) == bfd_arch_v850_rh850)
2455 {
2456 if ((in_flags & EF_V800_850E3) != (out_flags & EF_V800_850E3))
2457 {
2458 _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
2459 ibfd);
2460 elf_elfheader (obfd)->e_flags |= EF_V800_850E3;
2461 }
2462
2463 if ((in_flags & EF_RH850_DATA_ALIGN8) != (out_flags & EF_RH850_DATA_ALIGN8))
2464 {
2465 _bfd_error_handler (_("%B: Alignment mismatch with previous modules"),
2466 ibfd);
2467 elf_elfheader (obfd)->e_flags |= EF_RH850_DATA_ALIGN8;
2468 }
2469
2470 return TRUE;
2471 }
2472
252b5132
RH
2473 if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
2474 && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
8ad30312 2475 {
de863c74
NC
2476 /* Allow earlier architecture binaries to be linked with later binaries.
2477 Set the output binary to the later architecture, except for v850e1,
2478 which we set to v850e. */
2479 if ( (in_flags & EF_V850_ARCH) == E_V850E1_ARCH
1cd986c5
NC
2480 && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
2481 return TRUE;
8ad30312 2482
de863c74 2483 if ( (in_flags & EF_V850_ARCH) == E_V850_ARCH
1cd986c5 2484 && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
8ad30312
NC
2485 {
2486 elf_elfheader (obfd)->e_flags =
2487 ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
2488 return TRUE;
2489 }
2490
de863c74 2491 if (( (in_flags & EF_V850_ARCH) == E_V850_ARCH
1cd986c5
NC
2492 || (in_flags & EF_V850_ARCH) == E_V850E_ARCH)
2493 && (out_flags & EF_V850_ARCH) == E_V850E2_ARCH)
2494 {
2495 elf_elfheader (obfd)->e_flags =
2496 ((out_flags & ~ EF_V850_ARCH) | E_V850E2_ARCH);
2497 return TRUE;
2498 }
2499
de863c74 2500 if (( (in_flags & EF_V850_ARCH) == E_V850_ARCH
1cd986c5
NC
2501 || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
2502 || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH)
2503 && (out_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
2504 {
2505 elf_elfheader (obfd)->e_flags =
2506 ((out_flags & ~ EF_V850_ARCH) | E_V850E2V3_ARCH);
2507 return TRUE;
2508 }
2509
d003868e
AM
2510 _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
2511 ibfd);
8ad30312 2512 }
252b5132 2513
b34976b6 2514 return TRUE;
252b5132 2515}
e12dd2ea
NC
2516
2517/* Display the flags field. */
252b5132 2518
b34976b6 2519static bfd_boolean
47b0e7ad 2520v850_elf_print_private_bfd_data (bfd *abfd, void * ptr)
252b5132
RH
2521{
2522 FILE * file = (FILE *) ptr;
435b1e90 2523
252b5132 2524 BFD_ASSERT (abfd != NULL && ptr != NULL);
435b1e90 2525
252b5132 2526 _bfd_elf_print_private_bfd_data (abfd, ptr);
435b1e90 2527
1cd986c5 2528 /* xgettext:c-format. */
252b5132 2529 fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
435b1e90 2530
de863c74 2531 if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
252b5132 2532 {
de863c74 2533 if ((elf_elfheader (abfd)->e_flags & EF_RH850_ABI) != EF_RH850_ABI)
68ffbac6 2534 fprintf (file, _("unknown v850 architecture"));
de863c74
NC
2535 else if (elf_elfheader (abfd)->e_flags & EF_V800_850E3)
2536 fprintf (file, _("v850 E3 architecture"));
2537 else
2538 fprintf (file, _("v850 architecture"));
2539
2540 if (elf_elfheader (abfd)->e_flags & EF_RH850_DATA_ALIGN8)
2541 fprintf (file, _(", 8-byte data alignment"));
2542 }
2543 else
2544 {
2545 switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
2546 {
2547 default:
2548 case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
2549 case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break;
2550 case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
2551 case E_V850E2_ARCH: fprintf (file, _("v850e2 architecture")); break;
2552 case E_V850E2V3_ARCH: fprintf (file, _("v850e2v3 architecture")); break;
2553 }
252b5132 2554 }
435b1e90 2555
252b5132 2556 fputc ('\n', file);
435b1e90 2557
b34976b6 2558 return TRUE;
252b5132
RH
2559}
2560
2561/* V850 ELF uses four common sections. One is the usual one, and the
2562 others are for (small) objects in one of the special data areas:
2563 small, tiny and zero. All the objects are kept together, and then
2564 referenced via the gp register, the ep register or the r0 register
2565 respectively, which yields smaller, faster assembler code. This
2566 approach is copied from elf32-mips.c. */
2567
2568static asection v850_elf_scom_section;
2569static asymbol v850_elf_scom_symbol;
2570static asymbol * v850_elf_scom_symbol_ptr;
2571static asection v850_elf_tcom_section;
2572static asymbol v850_elf_tcom_symbol;
2573static asymbol * v850_elf_tcom_symbol_ptr;
2574static asection v850_elf_zcom_section;
2575static asymbol v850_elf_zcom_symbol;
2576static asymbol * v850_elf_zcom_symbol_ptr;
2577
e12dd2ea
NC
2578/* Given a BFD section, try to locate the
2579 corresponding ELF section index. */
252b5132 2580
b34976b6 2581static bfd_boolean
47b0e7ad
NC
2582v850_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2583 asection *sec,
2584 int *retval)
252b5132
RH
2585{
2586 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2587 *retval = SHN_V850_SCOMMON;
2588 else if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
2589 *retval = SHN_V850_TCOMMON;
2590 else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
2591 *retval = SHN_V850_ZCOMMON;
2592 else
b34976b6 2593 return FALSE;
435b1e90 2594
b34976b6 2595 return TRUE;
252b5132
RH
2596}
2597
2598/* Handle the special V850 section numbers that a symbol may use. */
2599
2600static void
47b0e7ad 2601v850_elf_symbol_processing (bfd *abfd, asymbol *asym)
252b5132
RH
2602{
2603 elf_symbol_type * elfsym = (elf_symbol_type *) asym;
9ad5cbcf 2604 unsigned int indx;
435b1e90 2605
9ad5cbcf 2606 indx = elfsym->internal_elf_sym.st_shndx;
252b5132
RH
2607
2608 /* If the section index is an "ordinary" index, then it may
2609 refer to a v850 specific section created by the assembler.
2610 Check the section's type and change the index it matches.
435b1e90 2611
252b5132 2612 FIXME: Should we alter the st_shndx field as well ? */
435b1e90 2613
9ad5cbcf 2614 if (indx < elf_numsections (abfd))
1cd986c5 2615 switch (elf_elfsections (abfd)[indx]->sh_type)
252b5132
RH
2616 {
2617 case SHT_V850_SCOMMON:
9ad5cbcf 2618 indx = SHN_V850_SCOMMON;
252b5132 2619 break;
435b1e90 2620
252b5132 2621 case SHT_V850_TCOMMON:
9ad5cbcf 2622 indx = SHN_V850_TCOMMON;
252b5132 2623 break;
435b1e90 2624
252b5132 2625 case SHT_V850_ZCOMMON:
9ad5cbcf 2626 indx = SHN_V850_ZCOMMON;
252b5132 2627 break;
435b1e90 2628
252b5132
RH
2629 default:
2630 break;
2631 }
435b1e90 2632
9ad5cbcf 2633 switch (indx)
252b5132
RH
2634 {
2635 case SHN_V850_SCOMMON:
2636 if (v850_elf_scom_section.name == NULL)
2637 {
2638 /* Initialize the small common section. */
2639 v850_elf_scom_section.name = ".scommon";
2640 v850_elf_scom_section.flags = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
2641 v850_elf_scom_section.output_section = & v850_elf_scom_section;
2642 v850_elf_scom_section.symbol = & v850_elf_scom_symbol;
2643 v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
2644 v850_elf_scom_symbol.name = ".scommon";
2645 v850_elf_scom_symbol.flags = BSF_SECTION_SYM;
2646 v850_elf_scom_symbol.section = & v850_elf_scom_section;
2647 v850_elf_scom_symbol_ptr = & v850_elf_scom_symbol;
2648 }
2649 asym->section = & v850_elf_scom_section;
2650 asym->value = elfsym->internal_elf_sym.st_size;
2651 break;
435b1e90 2652
252b5132
RH
2653 case SHN_V850_TCOMMON:
2654 if (v850_elf_tcom_section.name == NULL)
2655 {
2656 /* Initialize the tcommon section. */
2657 v850_elf_tcom_section.name = ".tcommon";
2658 v850_elf_tcom_section.flags = SEC_IS_COMMON;
2659 v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
2660 v850_elf_tcom_section.symbol = & v850_elf_tcom_symbol;
2661 v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
2662 v850_elf_tcom_symbol.name = ".tcommon";
2663 v850_elf_tcom_symbol.flags = BSF_SECTION_SYM;
2664 v850_elf_tcom_symbol.section = & v850_elf_tcom_section;
2665 v850_elf_tcom_symbol_ptr = & v850_elf_tcom_symbol;
2666 }
2667 asym->section = & v850_elf_tcom_section;
2668 asym->value = elfsym->internal_elf_sym.st_size;
2669 break;
2670
2671 case SHN_V850_ZCOMMON:
2672 if (v850_elf_zcom_section.name == NULL)
2673 {
2674 /* Initialize the zcommon section. */
2675 v850_elf_zcom_section.name = ".zcommon";
2676 v850_elf_zcom_section.flags = SEC_IS_COMMON;
2677 v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
2678 v850_elf_zcom_section.symbol = & v850_elf_zcom_symbol;
2679 v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
2680 v850_elf_zcom_symbol.name = ".zcommon";
2681 v850_elf_zcom_symbol.flags = BSF_SECTION_SYM;
2682 v850_elf_zcom_symbol.section = & v850_elf_zcom_section;
2683 v850_elf_zcom_symbol_ptr = & v850_elf_zcom_symbol;
2684 }
2685 asym->section = & v850_elf_zcom_section;
2686 asym->value = elfsym->internal_elf_sym.st_size;
2687 break;
2688 }
2689}
2690
2691/* Hook called by the linker routine which adds symbols from an object
2692 file. We must handle the special v850 section numbers here. */
2693
b34976b6 2694static bfd_boolean
47b0e7ad
NC
2695v850_elf_add_symbol_hook (bfd *abfd,
2696 struct bfd_link_info *info ATTRIBUTE_UNUSED,
2697 Elf_Internal_Sym *sym,
2698 const char **namep ATTRIBUTE_UNUSED,
2699 flagword *flagsp ATTRIBUTE_UNUSED,
2700 asection **secp,
2701 bfd_vma *valp)
252b5132 2702{
9ad5cbcf 2703 unsigned int indx = sym->st_shndx;
435b1e90 2704
252b5132
RH
2705 /* If the section index is an "ordinary" index, then it may
2706 refer to a v850 specific section created by the assembler.
2707 Check the section's type and change the index it matches.
435b1e90 2708
252b5132 2709 FIXME: Should we alter the st_shndx field as well ? */
435b1e90 2710
9ad5cbcf 2711 if (indx < elf_numsections (abfd))
1cd986c5 2712 switch (elf_elfsections (abfd)[indx]->sh_type)
252b5132
RH
2713 {
2714 case SHT_V850_SCOMMON:
9ad5cbcf 2715 indx = SHN_V850_SCOMMON;
252b5132 2716 break;
435b1e90 2717
252b5132 2718 case SHT_V850_TCOMMON:
9ad5cbcf 2719 indx = SHN_V850_TCOMMON;
252b5132 2720 break;
435b1e90 2721
252b5132 2722 case SHT_V850_ZCOMMON:
9ad5cbcf 2723 indx = SHN_V850_ZCOMMON;
252b5132 2724 break;
435b1e90 2725
252b5132
RH
2726 default:
2727 break;
2728 }
435b1e90 2729
9ad5cbcf 2730 switch (indx)
252b5132
RH
2731 {
2732 case SHN_V850_SCOMMON:
2733 *secp = bfd_make_section_old_way (abfd, ".scommon");
2734 (*secp)->flags |= SEC_IS_COMMON;
2735 *valp = sym->st_size;
2736 break;
435b1e90 2737
252b5132
RH
2738 case SHN_V850_TCOMMON:
2739 *secp = bfd_make_section_old_way (abfd, ".tcommon");
2740 (*secp)->flags |= SEC_IS_COMMON;
2741 *valp = sym->st_size;
2742 break;
435b1e90 2743
252b5132
RH
2744 case SHN_V850_ZCOMMON:
2745 *secp = bfd_make_section_old_way (abfd, ".zcommon");
2746 (*secp)->flags |= SEC_IS_COMMON;
2747 *valp = sym->st_size;
2748 break;
2749 }
2750
b34976b6 2751 return TRUE;
252b5132
RH
2752}
2753
6e0b88f1 2754static int
47b0e7ad
NC
2755v850_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2756 const char *name ATTRIBUTE_UNUSED,
2757 Elf_Internal_Sym *sym,
2758 asection *input_sec,
3dd2d30b 2759 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
252b5132
RH
2760{
2761 /* If we see a common symbol, which implies a relocatable link, then
2762 if a symbol was in a special common section in an input file, mark
2763 it as a special common in the output file. */
435b1e90 2764
252b5132
RH
2765 if (sym->st_shndx == SHN_COMMON)
2766 {
2767 if (strcmp (input_sec->name, ".scommon") == 0)
2768 sym->st_shndx = SHN_V850_SCOMMON;
2769 else if (strcmp (input_sec->name, ".tcommon") == 0)
2770 sym->st_shndx = SHN_V850_TCOMMON;
2771 else if (strcmp (input_sec->name, ".zcommon") == 0)
2772 sym->st_shndx = SHN_V850_ZCOMMON;
2773 }
2774
d4c87fc1
AM
2775 /* The price we pay for using h->other unused bits as flags in the
2776 linker is cleaning up after ourselves. */
3dd2d30b
AM
2777
2778 sym->st_other &= ~(V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA
2779 | V850_OTHER_ERROR);
d4c87fc1 2780
6e0b88f1 2781 return 1;
252b5132
RH
2782}
2783
b34976b6 2784static bfd_boolean
6dc132d9
L
2785v850_elf_section_from_shdr (bfd *abfd,
2786 Elf_Internal_Shdr *hdr,
2787 const char *name,
2788 int shindex)
252b5132
RH
2789{
2790 /* There ought to be a place to keep ELF backend specific flags, but
2791 at the moment there isn't one. We just keep track of the
2792 sections by their name, instead. */
2793
6dc132d9 2794 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
b34976b6 2795 return FALSE;
252b5132
RH
2796
2797 switch (hdr->sh_type)
2798 {
2799 case SHT_V850_SCOMMON:
2800 case SHT_V850_TCOMMON:
2801 case SHT_V850_ZCOMMON:
2802 if (! bfd_set_section_flags (abfd, hdr->bfd_section,
2803 (bfd_get_section_flags (abfd,
2804 hdr->bfd_section)
2805 | SEC_IS_COMMON)))
b34976b6 2806 return FALSE;
252b5132
RH
2807 }
2808
b34976b6 2809 return TRUE;
252b5132
RH
2810}
2811
e12dd2ea
NC
2812/* Set the correct type for a V850 ELF section. We do this
2813 by the section name, which is a hack, but ought to work. */
2814
b34976b6 2815static bfd_boolean
47b0e7ad
NC
2816v850_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
2817 Elf_Internal_Shdr *hdr,
2818 asection *sec)
252b5132 2819{
47b0e7ad 2820 const char * name;
252b5132
RH
2821
2822 name = bfd_get_section_name (abfd, sec);
2823
2824 if (strcmp (name, ".scommon") == 0)
47b0e7ad 2825 hdr->sh_type = SHT_V850_SCOMMON;
252b5132 2826 else if (strcmp (name, ".tcommon") == 0)
47b0e7ad 2827 hdr->sh_type = SHT_V850_TCOMMON;
252b5132
RH
2828 else if (strcmp (name, ".zcommon") == 0)
2829 hdr->sh_type = SHT_V850_ZCOMMON;
435b1e90 2830
b34976b6 2831 return TRUE;
252b5132 2832}
86aba9db
NC
2833
2834/* Delete some bytes from a section while relaxing. */
2835
b34976b6 2836static bfd_boolean
47b0e7ad
NC
2837v850_elf_relax_delete_bytes (bfd *abfd,
2838 asection *sec,
2839 bfd_vma addr,
2840 bfd_vma toaddr,
2841 int count)
86aba9db 2842{
b34976b6
AM
2843 Elf_Internal_Shdr *symtab_hdr;
2844 Elf32_External_Sym *extsyms;
2845 Elf32_External_Sym *esym;
2846 Elf32_External_Sym *esymend;
91d6fa6a 2847 int sym_index;
b34976b6
AM
2848 unsigned int sec_shndx;
2849 bfd_byte *contents;
2850 Elf_Internal_Rela *irel;
2851 Elf_Internal_Rela *irelend;
2852 struct elf_link_hash_entry *sym_hash;
2853 Elf_Internal_Shdr *shndx_hdr;
2854 Elf_External_Sym_Shndx *shndx;
86aba9db
NC
2855
2856 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2857 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
2858
2859 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
2860
2861 contents = elf_section_data (sec)->this_hdr.contents;
2862
2863 /* The deletion must stop at the next ALIGN reloc for an alignment
2864 power larger than the number of bytes we are deleting. */
2865
2866 /* Actually delete the bytes. */
2867#if (DEBUG_RELAX & 2)
2868 fprintf (stderr, "relax_delete: contents: sec: %s %p .. %p %x\n",
2869 sec->name, addr, toaddr, count );
2870#endif
2871 memmove (contents + addr, contents + addr + count,
2872 toaddr - addr - count);
2873 memset (contents + toaddr-count, 0, count);
2874
2875 /* Adjust all the relocs. */
2876 irel = elf_section_data (sec)->relocs;
2877 irelend = irel + sec->reloc_count;
2878 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
2879 shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
2880
2881 for (; irel < irelend; irel++)
2882 {
2883 bfd_vma raddr, paddr, symval;
2884 Elf_Internal_Sym isym;
2885
2886 /* Get the new reloc address. */
2887 raddr = irel->r_offset;
2888 if ((raddr >= (addr + count) && raddr < toaddr))
b34976b6 2889 irel->r_offset -= count;
86aba9db
NC
2890
2891 if (raddr >= addr && raddr < addr + count)
2892 {
2893 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2894 (int) R_V850_NONE);
2895 continue;
2896 }
b34976b6 2897
86aba9db
NC
2898 if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
2899 continue;
2900
2901 bfd_elf32_swap_symbol_in (abfd,
2902 extsyms + ELF32_R_SYM (irel->r_info),
2903 shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
2904 & isym);
b34976b6 2905
86aba9db
NC
2906 if (isym.st_shndx != sec_shndx)
2907 continue;
2908
2909 /* Get the value of the symbol referred to by the reloc. */
2910 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2911 {
2912 symval = isym.st_value;
2913#if (DEBUG_RELAX & 2)
2914 {
2915 char * name = bfd_elf_string_from_elf_section
2916 (abfd, symtab_hdr->sh_link, isym.st_name);
2917 fprintf (stderr,
2918 "relax_delete: local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
2919 sec->name, name, isym.st_name,
2920 sec->output_section->vma, sec->output_offset,
2921 isym.st_value, irel->r_addend);
2922 }
2923#endif
2924 }
2925 else
2926 {
2927 unsigned long indx;
2928 struct elf_link_hash_entry * h;
2929
2930 /* An external symbol. */
2931 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2932
2933 h = elf_sym_hashes (abfd) [indx];
2934 BFD_ASSERT (h != NULL);
2935
2936 symval = h->root.u.def.value;
2937#if (DEBUG_RELAX & 2)
2938 fprintf (stderr,
2939 "relax_delete: defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
2940 sec->name, h->root.root.string, h->root.u.def.value,
2941 sec->output_section->vma, sec->output_offset, irel->r_addend);
2942#endif
2943 }
b34976b6 2944
86aba9db 2945 paddr = symval + irel->r_addend;
b34976b6 2946
86aba9db
NC
2947 if ( (symval >= addr + count && symval < toaddr)
2948 && (paddr < addr + count || paddr >= toaddr))
2949 irel->r_addend += count;
2950 else if ( (symval < addr + count || symval >= toaddr)
2951 && (paddr >= addr + count && paddr < toaddr))
2952 irel->r_addend -= count;
2953 }
2954
2955 /* Adjust the local symbols defined in this section. */
2956 esym = extsyms;
2957 esymend = esym + symtab_hdr->sh_info;
2958
2959 for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
2960 {
2961 Elf_Internal_Sym isym;
2962
2963 bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
2964
2965 if (isym.st_shndx == sec_shndx
2966 && isym.st_value >= addr + count
2967 && isym.st_value < toaddr)
2968 {
2969 isym.st_value -= count;
2970
2971 if (isym.st_value + isym.st_size >= toaddr)
b34976b6
AM
2972 isym.st_size += count;
2973
63a23799 2974 bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
86aba9db
NC
2975 }
2976 else if (isym.st_shndx == sec_shndx
2977 && isym.st_value < addr + count)
2978 {
2979 if (isym.st_value+isym.st_size >= addr + count
2980 && isym.st_value+isym.st_size < toaddr)
2981 isym.st_size -= count;
2982
2983 if (isym.st_value >= addr
2984 && isym.st_value < addr + count)
2985 isym.st_value = addr;
2986
63a23799 2987 bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
86aba9db
NC
2988 }
2989 }
2990
2991 /* Now adjust the global symbols defined in this section. */
2992 esym = extsyms + symtab_hdr->sh_info;
2993 esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
2994
91d6fa6a 2995 for (sym_index = 0; esym < esymend; esym ++, sym_index ++)
86aba9db
NC
2996 {
2997 Elf_Internal_Sym isym;
2998
2999 bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
91d6fa6a 3000 sym_hash = elf_sym_hashes (abfd) [sym_index];
86aba9db
NC
3001
3002 if (isym.st_shndx == sec_shndx
3003 && ((sym_hash)->root.type == bfd_link_hash_defined
3004 || (sym_hash)->root.type == bfd_link_hash_defweak)
3005 && (sym_hash)->root.u.def.section == sec
3006 && (sym_hash)->root.u.def.value >= addr + count
3007 && (sym_hash)->root.u.def.value < toaddr)
3008 {
3009 if ((sym_hash)->root.u.def.value + isym.st_size >= toaddr)
3010 {
3011 isym.st_size += count;
63a23799 3012 bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
86aba9db
NC
3013 }
3014
3015 (sym_hash)->root.u.def.value -= count;
3016 }
3017 else if (isym.st_shndx == sec_shndx
3018 && ((sym_hash)->root.type == bfd_link_hash_defined
3019 || (sym_hash)->root.type == bfd_link_hash_defweak)
3020 && (sym_hash)->root.u.def.section == sec
3021 && (sym_hash)->root.u.def.value < addr + count)
3022 {
3023 if ((sym_hash)->root.u.def.value+isym.st_size >= addr + count
3024 && (sym_hash)->root.u.def.value+isym.st_size < toaddr)
3025 isym.st_size -= count;
3026
3027 if ((sym_hash)->root.u.def.value >= addr
3028 && (sym_hash)->root.u.def.value < addr + count)
3029 (sym_hash)->root.u.def.value = addr;
3030
63a23799 3031 bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
86aba9db
NC
3032 }
3033
3034 if (shndx)
3035 ++ shndx;
3036 }
3037
b34976b6 3038 return TRUE;
86aba9db
NC
3039}
3040
3041#define NOP_OPCODE (0x0000)
1cd986c5 3042#define MOVHI 0x0640 /* 4byte. */
86aba9db 3043#define MOVHI_MASK 0x07e0
1cd986c5 3044#define MOVHI_R1(insn) ((insn) & 0x1f) /* 4byte. */
86aba9db 3045#define MOVHI_R2(insn) ((insn) >> 11)
1cd986c5 3046#define MOVEA 0x0620 /* 2byte. */
86aba9db
NC
3047#define MOVEA_MASK 0x07e0
3048#define MOVEA_R1(insn) ((insn) & 0x1f)
3049#define MOVEA_R2(insn) ((insn) >> 11)
1cd986c5 3050#define JARL_4 0x00040780 /* 4byte. */
86aba9db
NC
3051#define JARL_4_MASK 0xFFFF07FF
3052#define JARL_R2(insn) (int)(((insn) & (~JARL_4_MASK)) >> 11)
1cd986c5 3053#define ADD_I 0x0240 /* 2byte. */
86aba9db 3054#define ADD_I_MASK 0x07e0
1cd986c5 3055#define ADD_I5(insn) ((((insn) & 0x001f) << 11) >> 11) /* 2byte. */
86aba9db 3056#define ADD_R2(insn) ((insn) >> 11)
1cd986c5 3057#define JMP_R 0x0060 /* 2byte. */
86aba9db
NC
3058#define JMP_R_MASK 0xFFE0
3059#define JMP_R1(insn) ((insn) & 0x1f)
3060
b34976b6 3061static bfd_boolean
47b0e7ad
NC
3062v850_elf_relax_section (bfd *abfd,
3063 asection *sec,
3064 struct bfd_link_info *link_info,
3065 bfd_boolean *again)
86aba9db 3066{
b34976b6
AM
3067 Elf_Internal_Shdr *symtab_hdr;
3068 Elf_Internal_Rela *internal_relocs;
3069 Elf_Internal_Rela *irel;
3070 Elf_Internal_Rela *irelend;
3071 Elf_Internal_Rela *irelalign = NULL;
3072 Elf_Internal_Sym *isymbuf = NULL;
3073 bfd_byte *contents = NULL;
3074 bfd_vma addr = 0;
3075 bfd_vma toaddr;
3076 int align_pad_size = 0;
3077 bfd_boolean result = TRUE;
3078
3079 *again = FALSE;
86aba9db 3080
1049f94e 3081 if (link_info->relocatable
86aba9db
NC
3082 || (sec->flags & SEC_RELOC) == 0
3083 || sec->reloc_count == 0)
b34976b6 3084 return TRUE;
86aba9db 3085
86aba9db
NC
3086 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
3087
45d6a902 3088 internal_relocs = (_bfd_elf_link_read_relocs
47b0e7ad 3089 (abfd, sec, NULL, NULL, link_info->keep_memory));
86aba9db
NC
3090 if (internal_relocs == NULL)
3091 goto error_return;
86aba9db
NC
3092
3093 irelend = internal_relocs + sec->reloc_count;
b34976b6 3094
eea6121a 3095 while (addr < sec->size)
86aba9db 3096 {
eea6121a 3097 toaddr = sec->size;
86aba9db
NC
3098
3099 for (irel = internal_relocs; irel < irelend; irel ++)
3100 if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
3101 && irel->r_offset > addr
3102 && irel->r_offset < toaddr)
3103 toaddr = irel->r_offset;
b34976b6 3104
86aba9db
NC
3105#ifdef DEBUG_RELAX
3106 fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
3107 addr, toaddr, align_pad_size);
3108#endif
3109 if (irelalign)
3110 {
3111 bfd_vma alignto;
3112 bfd_vma alignmoveto;
3113
3114 alignmoveto = BFD_ALIGN (addr - align_pad_size, 1 << irelalign->r_addend);
3115 alignto = BFD_ALIGN (addr, 1 << irelalign->r_addend);
3116
3117 if (alignmoveto < alignto)
3118 {
3119 unsigned int i;
3120
3121 align_pad_size = alignto - alignmoveto;
3122#ifdef DEBUG_RELAX
3123 fprintf (stderr, "relax move region 0x%x to 0x%x delete size 0x%x\n",
3124 alignmoveto, toaddr, align_pad_size);
3125#endif
3126 if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
3127 toaddr, align_pad_size))
b34976b6 3128 goto error_return;
86aba9db
NC
3129
3130 for (i = BFD_ALIGN (toaddr - align_pad_size, 1);
3131 (i + 1) < toaddr; i += 2)
3132 bfd_put_16 (abfd, NOP_OPCODE, contents + i);
3133
3134 addr = alignmoveto;
3135 }
3136 else
3137 align_pad_size = 0;
3138 }
3139
3140 for (irel = internal_relocs; irel < irelend; irel++)
3141 {
b34976b6
AM
3142 bfd_vma laddr;
3143 bfd_vma addend;
3144 bfd_vma symval;
3145 int insn[5];
3146 int no_match = -1;
3147 Elf_Internal_Rela *hi_irelfn;
3148 Elf_Internal_Rela *lo_irelfn;
3149 Elf_Internal_Rela *irelcall;
3150 bfd_signed_vma foff;
de863c74 3151 unsigned int r_type;
86aba9db
NC
3152
3153 if (! (irel->r_offset >= addr && irel->r_offset < toaddr
3154 && (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
3155 || ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)))
3156 continue;
3157
3158#ifdef DEBUG_RELAX
3159 fprintf (stderr, "relax check r_info 0x%x r_offset 0x%x r_addend 0x%x\n",
3160 irel->r_info,
3161 irel->r_offset,
3162 irel->r_addend );
3163#endif
3164
3165 /* Get the section contents. */
3166 if (contents == NULL)
3167 {
3168 if (elf_section_data (sec)->this_hdr.contents != NULL)
3169 contents = elf_section_data (sec)->this_hdr.contents;
3170 else
3171 {
47b0e7ad 3172 if (! bfd_malloc_and_get_section (abfd, sec, &contents))
86aba9db
NC
3173 goto error_return;
3174 }
3175 }
3176
5cec6941
NC
3177 /* Read this BFD's local symbols if we haven't done so already. */
3178 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
86aba9db 3179 {
5cec6941
NC
3180 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3181 if (isymbuf == NULL)
3182 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3183 symtab_hdr->sh_info, 0,
3184 NULL, NULL, NULL);
3185 if (isymbuf == NULL)
3186 goto error_return;
86aba9db
NC
3187 }
3188
3189 laddr = irel->r_offset;
3190
3191 if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
3192 {
3193 /* Check code for -mlong-calls output. */
eea6121a 3194 if (laddr + 16 <= (bfd_vma) sec->size)
86aba9db
NC
3195 {
3196 insn[0] = bfd_get_16 (abfd, contents + laddr);
3197 insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
3198 insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
3199 insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
3200 insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
b34976b6 3201
86aba9db
NC
3202 if ((insn[0] & MOVHI_MASK) != MOVHI
3203 || MOVHI_R1 (insn[0]) != 0)
3204 no_match = 0;
3205
3206 if (no_match < 0
3207 && ((insn[1] & MOVEA_MASK) != MOVEA
3208 || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
3209 no_match = 1;
3210
3211 if (no_match < 0
3212 && (insn[2] & JARL_4_MASK) != JARL_4)
3213 no_match = 2;
3214
3215 if (no_match < 0
3216 && ((insn[3] & ADD_I_MASK) != ADD_I
3217 || ADD_I5 (insn[3]) != 4
3218 || JARL_R2 (insn[2]) != ADD_R2 (insn[3])))
3219 no_match = 3;
3220
3221 if (no_match < 0
3222 && ((insn[4] & JMP_R_MASK) != JMP_R
3223 || MOVEA_R2 (insn[1]) != JMP_R1 (insn[4])))
3224 no_match = 4;
3225 }
3226 else
3227 {
3228 ((*_bfd_error_handler)
3229 ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insns",
3230 bfd_get_filename (abfd), (unsigned long) irel->r_offset));
3231
3232 continue;
3233 }
3234
3235 if (no_match >= 0)
3236 {
3237 ((*_bfd_error_handler)
3238 ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insn 0x%x",
3239 bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
3240
3241 continue;
b34976b6 3242 }
86aba9db
NC
3243
3244 /* Get the reloc for the address from which the register is
3245 being loaded. This reloc will tell us which function is
3246 actually being called. */
68ffbac6 3247
86aba9db 3248 for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
de863c74
NC
3249 {
3250 r_type = ELF32_R_TYPE (hi_irelfn->r_info);
3251
3252 if (hi_irelfn->r_offset == laddr + 2
3253 && (r_type == (int) R_V850_HI16_S || r_type == (int) R_V810_WHI1))
3254 break;
3255 }
86aba9db
NC
3256
3257 for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
de863c74
NC
3258 {
3259 r_type = ELF32_R_TYPE (lo_irelfn->r_info);
3260
3261 if (lo_irelfn->r_offset == laddr + 6
3262 && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
3263 break;
3264 }
86aba9db
NC
3265
3266 for (irelcall = internal_relocs; irelcall < irelend; irelcall ++)
de863c74
NC
3267 {
3268 r_type = ELF32_R_TYPE (irelcall->r_info);
3269
3270 if (irelcall->r_offset == laddr + 8
3271 && (r_type == (int) R_V850_22_PCREL || r_type == (int) R_V850_PCR22))
3272 break;
3273 }
86aba9db
NC
3274
3275 if ( hi_irelfn == irelend
3276 || lo_irelfn == irelend
3277 || irelcall == irelend)
3278 {
3279 ((*_bfd_error_handler)
3280 ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc",
3281 bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
3282
3283 continue;
3284 }
b34976b6 3285
86aba9db
NC
3286 if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
3287 {
5cec6941 3288 Elf_Internal_Sym * isym;
86aba9db
NC
3289
3290 /* A local symbol. */
5cec6941 3291 isym = isymbuf + ELF32_R_SYM (irelcall->r_info);
86aba9db 3292
5cec6941 3293 symval = isym->st_value;
86aba9db
NC
3294 }
3295 else
3296 {
3297 unsigned long indx;
3298 struct elf_link_hash_entry * h;
3299
3300 /* An external symbol. */
3301 indx = ELF32_R_SYM (irelcall->r_info) - symtab_hdr->sh_info;
3302 h = elf_sym_hashes (abfd)[indx];
3303 BFD_ASSERT (h != NULL);
3304
3305 if ( h->root.type != bfd_link_hash_defined
3306 && h->root.type != bfd_link_hash_defweak)
3307 /* This appears to be a reference to an undefined
3308 symbol. Just ignore it--it will be caught by the
3309 regular reloc processing. */
3310 continue;
3311
3312 symval = h->root.u.def.value;
3313 }
3314
3315 if (symval + irelcall->r_addend != irelcall->r_offset + 4)
3316 {
3317 ((*_bfd_error_handler)
3318 ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc 0x%lx",
3319 bfd_get_filename (abfd), (unsigned long) irel->r_offset, irelcall->r_offset ));
3320
3321 continue;
3322 }
3323
3324 /* Get the value of the symbol referred to by the reloc. */
3325 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3326 {
b34976b6
AM
3327 Elf_Internal_Sym *isym;
3328 asection *sym_sec;
86aba9db
NC
3329
3330 /* A local symbol. */
5cec6941 3331 isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
b34976b6 3332
5cec6941 3333 if (isym->st_shndx == SHN_UNDEF)
86aba9db 3334 sym_sec = bfd_und_section_ptr;
5cec6941 3335 else if (isym->st_shndx == SHN_ABS)
86aba9db 3336 sym_sec = bfd_abs_section_ptr;
5cec6941 3337 else if (isym->st_shndx == SHN_COMMON)
86aba9db
NC
3338 sym_sec = bfd_com_section_ptr;
3339 else
5cec6941
NC
3340 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3341 symval = (isym->st_value
86aba9db
NC
3342 + sym_sec->output_section->vma
3343 + sym_sec->output_offset);
3344 }
3345 else
3346 {
3347 unsigned long indx;
b34976b6 3348 struct elf_link_hash_entry *h;
86aba9db
NC
3349
3350 /* An external symbol. */
5cec6941 3351 indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
86aba9db
NC
3352 h = elf_sym_hashes (abfd)[indx];
3353 BFD_ASSERT (h != NULL);
3354
3355 if ( h->root.type != bfd_link_hash_defined
3356 && h->root.type != bfd_link_hash_defweak)
3357 /* This appears to be a reference to an undefined
3358 symbol. Just ignore it--it will be caught by the
3359 regular reloc processing. */
3360 continue;
3361
3362 symval = (h->root.u.def.value
3363 + h->root.u.def.section->output_section->vma
3364 + h->root.u.def.section->output_offset);
3365 }
3366
3367 addend = irel->r_addend;
3368
3369 foff = (symval + addend
3370 - (irel->r_offset
3371 + sec->output_section->vma
3372 + sec->output_offset
3373 + 4));
3374#ifdef DEBUG_RELAX
3375 fprintf (stderr, "relax longcall r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
3376 irel->r_offset,
3377 (irel->r_offset
3378 + sec->output_section->vma
3379 + sec->output_offset),
3380 symval, addend, foff);
3381#endif
3382
3383 if (foff < -0x100000 || foff >= 0x100000)
3384 /* After all that work, we can't shorten this function call. */
3385 continue;
3386
3387 /* For simplicity of coding, we are going to modify the section
3388 contents, the section relocs, and the BFD symbol table. We
3389 must tell the rest of the code not to free up this
3390 information. It would be possible to instead create a table
3391 of changes which have to be made, as is done in coff-mips.c;
3392 that would be more work, but would require less memory when
3393 the linker is run. */
3394 elf_section_data (sec)->relocs = internal_relocs;
86aba9db 3395 elf_section_data (sec)->this_hdr.contents = contents;
5cec6941 3396 symtab_hdr->contents = (bfd_byte *) isymbuf;
b34976b6 3397
86aba9db 3398 /* Replace the long call with a jarl. */
de863c74
NC
3399 if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3400 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_PCR22);
3401 else
3402 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
86aba9db
NC
3403
3404 addend = 0;
3405
3406 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3407 /* If this needs to be changed because of future relaxing,
3408 it will be handled here like other internal IND12W
3409 relocs. */
3410 bfd_put_32 (abfd,
3411 0x00000780 | (JARL_R2 (insn[2])<<11) | ((addend << 16) & 0xffff) | ((addend >> 16) & 0xf),
3412 contents + irel->r_offset);
3413 else
3414 /* We can't fully resolve this yet, because the external
3415 symbol value may be changed by future relaxing.
3416 We let the final link phase handle it. */
3417 bfd_put_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
3418 contents + irel->r_offset);
3419
b34976b6 3420 hi_irelfn->r_info =
86aba9db
NC
3421 ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3422 lo_irelfn->r_info =
3423 ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3424 irelcall->r_info =
3425 ELF32_R_INFO (ELF32_R_SYM (irelcall->r_info), R_V850_NONE);
3426
3427 if (! v850_elf_relax_delete_bytes (abfd, sec,
3428 irel->r_offset + 4, toaddr, 12))
3429 goto error_return;
3430
3431 align_pad_size += 12;
3432 }
3433 else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
3434 {
3435 /* Check code for -mlong-jumps output. */
eea6121a 3436 if (laddr + 10 <= (bfd_vma) sec->size)
86aba9db
NC
3437 {
3438 insn[0] = bfd_get_16 (abfd, contents + laddr);
3439 insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
3440 insn[2] = bfd_get_16 (abfd, contents + laddr + 8);
3441
3442 if ((insn[0] & MOVHI_MASK) != MOVHI
3443 || MOVHI_R1 (insn[0]) != 0)
3444 no_match = 0;
3445
3446 if (no_match < 0
3447 && ((insn[1] & MOVEA_MASK) != MOVEA
3448 || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
3449 no_match = 1;
3450
3451 if (no_match < 0
3452 && ((insn[2] & JMP_R_MASK) != JMP_R
3453 || MOVEA_R2 (insn[1]) != JMP_R1 (insn[2])))
3454 no_match = 4;
3455 }
3456 else
3457 {
3458 ((*_bfd_error_handler)
3459 ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insns",
3460 bfd_get_filename (abfd), (unsigned long) irel->r_offset));
3461
3462 continue;
3463 }
3464
3465 if (no_match >= 0)
3466 {
3467 ((*_bfd_error_handler)
3468 ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insn 0x%x",
3469 bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
3470
3471 continue;
3472 }
3473
3474 /* Get the reloc for the address from which the register is
3475 being loaded. This reloc will tell us which function is
3476 actually being called. */
3477 for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
de863c74
NC
3478 {
3479 r_type = ELF32_R_TYPE (hi_irelfn->r_info);
3480
3481 if (hi_irelfn->r_offset == laddr + 2
3482 && ((r_type == (int) R_V850_HI16_S) || r_type == (int) R_V810_WHI1))
3483 break;
3484 }
86aba9db
NC
3485
3486 for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
de863c74
NC
3487 {
3488 r_type = ELF32_R_TYPE (lo_irelfn->r_info);
3489
3490 if (lo_irelfn->r_offset == laddr + 6
3491 && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
3492 break;
3493 }
86aba9db
NC
3494
3495 if ( hi_irelfn == irelend
3496 || lo_irelfn == irelend)
3497 {
3498 ((*_bfd_error_handler)
3499 ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized reloc",
3500 bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
3501
3502 continue;
3503 }
b34976b6 3504
86aba9db
NC
3505 /* Get the value of the symbol referred to by the reloc. */
3506 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3507 {
5cec6941
NC
3508 Elf_Internal_Sym * isym;
3509 asection * sym_sec;
86aba9db
NC
3510
3511 /* A local symbol. */
5cec6941
NC
3512 isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
3513
3514 if (isym->st_shndx == SHN_UNDEF)
86aba9db 3515 sym_sec = bfd_und_section_ptr;
5cec6941 3516 else if (isym->st_shndx == SHN_ABS)
86aba9db 3517 sym_sec = bfd_abs_section_ptr;
5cec6941 3518 else if (isym->st_shndx == SHN_COMMON)
86aba9db
NC
3519 sym_sec = bfd_com_section_ptr;
3520 else
5cec6941
NC
3521 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3522 symval = (isym->st_value
86aba9db
NC
3523 + sym_sec->output_section->vma
3524 + sym_sec->output_offset);
3525#ifdef DEBUG_RELAX
3526 {
3527 char * name = bfd_elf_string_from_elf_section
5cec6941 3528 (abfd, symtab_hdr->sh_link, isym->st_name);
86aba9db
NC
3529
3530 fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
5cec6941
NC
3531 sym_sec->name, name, isym->st_name,
3532 sym_sec->output_section->vma,
3533 sym_sec->output_offset,
3534 isym->st_value, irel->r_addend);
86aba9db
NC
3535 }
3536#endif
3537 }
3538 else
3539 {
3540 unsigned long indx;
3541 struct elf_link_hash_entry * h;
3542
3543 /* An external symbol. */
3544 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
3545 h = elf_sym_hashes (abfd)[indx];
3546 BFD_ASSERT (h != NULL);
3547
3548 if ( h->root.type != bfd_link_hash_defined
3549 && h->root.type != bfd_link_hash_defweak)
3550 /* This appears to be a reference to an undefined
3551 symbol. Just ignore it--it will be caught by the
3552 regular reloc processing. */
3553 continue;
3554
3555 symval = (h->root.u.def.value
3556 + h->root.u.def.section->output_section->vma
3557 + h->root.u.def.section->output_offset);
3558#ifdef DEBUG_RELAX
3559 fprintf (stderr,
3560 "relax longjump defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
3561 sec->name, h->root.root.string, h->root.u.def.value,
3562 sec->output_section->vma, sec->output_offset, irel->r_addend);
3563#endif
3564 }
3565
3566 addend = irel->r_addend;
3567
3568 foff = (symval + addend
3569 - (irel->r_offset
3570 + sec->output_section->vma
3571 + sec->output_offset
3572 + 4));
3573#ifdef DEBUG_RELAX
3574 fprintf (stderr, "relax longjump r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
3575 irel->r_offset,
3576 (irel->r_offset
3577 + sec->output_section->vma
3578 + sec->output_offset),
3579 symval, addend, foff);
3580#endif
3581 if (foff < -0x100000 || foff >= 0x100000)
3582 /* After all that work, we can't shorten this function call. */
3583 continue;
3584
3585 /* For simplicity of coding, we are going to modify the section
3586 contents, the section relocs, and the BFD symbol table. We
3587 must tell the rest of the code not to free up this
3588 information. It would be possible to instead create a table
3589 of changes which have to be made, as is done in coff-mips.c;
3590 that would be more work, but would require less memory when
3591 the linker is run. */
3592 elf_section_data (sec)->relocs = internal_relocs;
86aba9db 3593 elf_section_data (sec)->this_hdr.contents = contents;
5cec6941 3594 symtab_hdr->contents = (bfd_byte *) isymbuf;
86aba9db
NC
3595
3596 if (foff < -0x100 || foff >= 0x100)
3597 {
3598 /* Replace the long jump with a jr. */
3599
de863c74
NC
3600 if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3601 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PCR22);
3602 else
3603 irel->r_info =
3604 ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
b34976b6 3605
86aba9db
NC
3606 irel->r_addend = addend;
3607 addend = 0;
3608
3609 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3610 /* If this needs to be changed because of future relaxing,
3611 it will be handled here like other internal IND12W
3612 relocs. */
3613 bfd_put_32 (abfd,
3614 0x00000780 | ((addend << 15) & 0xffff0000) | ((addend >> 17) & 0xf),
3615 contents + irel->r_offset);
3616 else
3617 /* We can't fully resolve this yet, because the external
3618 symbol value may be changed by future relaxing.
3619 We let the final link phase handle it. */
3620 bfd_put_32 (abfd, 0x00000780, contents + irel->r_offset);
3621
3622 hi_irelfn->r_info =
3623 ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3624 lo_irelfn->r_info =
3625 ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3626 if (!v850_elf_relax_delete_bytes (abfd, sec,
3627 irel->r_offset + 4, toaddr, 6))
3628 goto error_return;
3629
3630 align_pad_size += 6;
3631 }
3632 else
3633 {
3634 /* Replace the long jump with a br. */
3635
de863c74
NC
3636 if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3637 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PC9);
3638 else
3639 irel->r_info =
3640 ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_9_PCREL);
86aba9db
NC
3641
3642 irel->r_addend = addend;
3643 addend = 0;
3644
3645 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3646 /* If this needs to be changed because of future relaxing,
3647 it will be handled here like other internal IND12W
3648 relocs. */
3649 bfd_put_16 (abfd,
3650 0x0585 | ((addend << 10) & 0xf800) | ((addend << 3) & 0x0070),
3651 contents + irel->r_offset);
3652 else
3653 /* We can't fully resolve this yet, because the external
3654 symbol value may be changed by future relaxing.
3655 We let the final link phase handle it. */
3656 bfd_put_16 (abfd, 0x0585, contents + irel->r_offset);
3657
3658 hi_irelfn->r_info =
3659 ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3660 lo_irelfn->r_info =
3661 ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3662 if (!v850_elf_relax_delete_bytes (abfd, sec,
3663 irel->r_offset + 2, toaddr, 8))
3664 goto error_return;
3665
3666 align_pad_size += 8;
3667 }
3668 }
3669 }
3670
3671 irelalign = NULL;
3672 for (irel = internal_relocs; irel < irelend; irel++)
3673 {
3674 if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
3675 && irel->r_offset == toaddr)
3676 {
3677 irel->r_offset -= align_pad_size;
3678
3679 if (irelalign == NULL || irelalign->r_addend > irel->r_addend)
3680 irelalign = irel;
3681 }
3682 }
3683
3684 addr = toaddr;
3685 }
3686
3687 if (!irelalign)
3688 {
3689#ifdef DEBUG_RELAX
3690 fprintf (stderr, "relax pad %d shorten %d -> %d\n",
3691 align_pad_size,
eea6121a
AM
3692 sec->size,
3693 sec->size - align_pad_size);
86aba9db 3694#endif
eea6121a 3695 sec->size -= align_pad_size;
86aba9db
NC
3696 }
3697
5cec6941
NC
3698 finish:
3699 if (internal_relocs != NULL
3700 && elf_section_data (sec)->relocs != internal_relocs)
3701 free (internal_relocs);
86aba9db 3702
5cec6941
NC
3703 if (contents != NULL
3704 && elf_section_data (sec)->this_hdr.contents != (unsigned char *) contents)
3705 free (contents);
86aba9db 3706
5cec6941
NC
3707 if (isymbuf != NULL
3708 && symtab_hdr->contents != (bfd_byte *) isymbuf)
3709 free (isymbuf);
86aba9db 3710
5cec6941 3711 return result;
86aba9db 3712
5cec6941 3713 error_return:
b34976b6 3714 result = FALSE;
5cec6941 3715 goto finish;
86aba9db 3716}
2f89ff8d 3717
b35d266b 3718static const struct bfd_elf_special_section v850_elf_special_sections[] =
7f4d3958 3719{
0112cd26
NC
3720 { STRING_COMMA_LEN (".call_table_data"), 0, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE) },
3721 { STRING_COMMA_LEN (".call_table_text"), 0, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
3722 + SHF_EXECINSTR) },
3723 { STRING_COMMA_LEN (".rosdata"), -2, SHT_PROGBITS, (SHF_ALLOC
3724 + SHF_V850_GPREL) },
3725 { STRING_COMMA_LEN (".rozdata"), -2, SHT_PROGBITS, (SHF_ALLOC
3726 + SHF_V850_R0REL) },
3727 { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
3728 + SHF_V850_GPREL) },
3729 { STRING_COMMA_LEN (".scommon"), -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
3730 + SHF_V850_GPREL) },
3731 { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
3732 + SHF_V850_GPREL) },
3733 { STRING_COMMA_LEN (".tbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
3734 + SHF_V850_EPREL) },
3735 { STRING_COMMA_LEN (".tcommon"), -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
3736 + SHF_V850_R0REL) },
3737 { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
3738 + SHF_V850_EPREL) },
3739 { STRING_COMMA_LEN (".zbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
3740 + SHF_V850_R0REL) },
3741 { STRING_COMMA_LEN (".zcommon"), -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
3742 + SHF_V850_R0REL) },
3743 { STRING_COMMA_LEN (".zdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
3744 + SHF_V850_R0REL) },
3745 { NULL, 0, 0, 0, 0 }
7f4d3958 3746};
252b5132
RH
3747\f
3748#define TARGET_LITTLE_SYM bfd_elf32_v850_vec
3749#define TARGET_LITTLE_NAME "elf32-v850"
3750#define ELF_ARCH bfd_arch_v850
aa4f99bb
AO
3751#define ELF_MACHINE_CODE EM_V850
3752#define ELF_MACHINE_ALT1 EM_CYGNUS_V850
252b5132 3753#define ELF_MAXPAGESIZE 0x1000
435b1e90 3754
252b5132
RH
3755#define elf_info_to_howto v850_elf_info_to_howto_rela
3756#define elf_info_to_howto_rel v850_elf_info_to_howto_rel
3757
3758#define elf_backend_check_relocs v850_elf_check_relocs
3759#define elf_backend_relocate_section v850_elf_relocate_section
3760#define elf_backend_object_p v850_elf_object_p
3761#define elf_backend_final_write_processing v850_elf_final_write_processing
3762#define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
3763#define elf_backend_symbol_processing v850_elf_symbol_processing
3764#define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
3765#define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
3766#define elf_backend_section_from_shdr v850_elf_section_from_shdr
3767#define elf_backend_fake_sections v850_elf_fake_sections
3768#define elf_backend_gc_mark_hook v850_elf_gc_mark_hook
29ef7005 3769#define elf_backend_special_sections v850_elf_special_sections
252b5132
RH
3770
3771#define elf_backend_can_gc_sections 1
f0fe0e16 3772#define elf_backend_rela_normal 1
252b5132 3773
252b5132
RH
3774#define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
3775#define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
de863c74 3776#define bfd_elf32_bfd_reloc_name_lookup v850_elf_reloc_name_lookup
252b5132
RH
3777#define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
3778#define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
3779#define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
86aba9db 3780#define bfd_elf32_bfd_relax_section v850_elf_relax_section
252b5132
RH
3781
3782#define elf_symbol_leading_char '_'
3783
de863c74
NC
3784#undef elf32_bed
3785#define elf32_bed elf32_v850_bed
3786
3787#include "elf32-target.h"
3788
3789/* Map BFD reloc types to V800 ELF reloc types. */
3790
3791static const struct v850_elf_reloc_map v800_elf_reloc_map[] =
3792{
3793 { BFD_RELOC_NONE, R_V810_NONE },
3794 { BFD_RELOC_8, R_V810_BYTE },
3795 { BFD_RELOC_16, R_V810_HWORD },
3796 { BFD_RELOC_32, R_V810_WORD },
3797 { BFD_RELOC_LO16, R_V810_WLO },
3798 { BFD_RELOC_HI16, R_V810_WHI },
3799 { BFD_RELOC_HI16_S, R_V810_WHI1 },
3800 { BFD_RELOC_V850_32_PCREL, R_V850_PC32 },
3801 { BFD_RELOC_V850_22_PCREL, R_V850_PCR22 },
3802 { BFD_RELOC_V850_17_PCREL, R_V850_PC17 },
3803 { BFD_RELOC_V850_16_PCREL, R_V850_PC16U },
3804 { BFD_RELOC_V850_9_PCREL, R_V850_PC9 },
3805 { BFD_RELOC_V850_LO16_S1, R_V810_WLO_1 }, /* Or R_V850_HWLO or R_V850_HWLO_1. */
3806 { BFD_RELOC_V850_23, R_V850_WLO23 },
3807 { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_BLO },
3808 { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V810_HWORD },
3809 { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V810_HWORD },
3810 { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V810_HWORD },
3811 { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V810_GPWLO_1 }
3812};
3813
3814/* Map a bfd relocation into the appropriate howto structure. */
3815
3816static reloc_howto_type *
3817v800_elf_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
3818{
3819 unsigned int i;
3820
3821 BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
3822
3823 for (i = ARRAY_SIZE (v800_elf_reloc_map); i --;)
3824 if (v800_elf_reloc_map[i].bfd_reloc_val == code)
3825 {
3826 unsigned int elf_reloc_val = v800_elf_reloc_map[i].elf_reloc_val;
3827 unsigned int idx = elf_reloc_val - R_V810_NONE;
3828
3829 BFD_ASSERT (v800_elf_howto_table[idx].type == elf_reloc_val);
3830
3831 return v800_elf_howto_table + idx;
3832 }
3833
3834#ifdef DEBUG
3835 fprintf (stderr, "failed to find v800 equiv of bfd reloc code %d\n", code);
3836#endif
3837 return NULL;
3838}
3839
3840static reloc_howto_type *
3841v800_elf_reloc_name_lookup (bfd * abfd, const char * r_name)
3842{
3843 unsigned int i;
3844
3845 BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
3846
3847 for (i = ARRAY_SIZE (v800_elf_howto_table); i--;)
3848 if (v800_elf_howto_table[i].name != NULL
3849 && strcasecmp (v800_elf_howto_table[i].name, r_name) == 0)
3850 return v800_elf_howto_table + i;
3851
3852 return NULL;
3853}
3854
3855
3856/* Set the howto pointer in CACHE_PTR for a V800 ELF reloc. */
3857
3858static void
3859v800_elf_info_to_howto (bfd * abfd,
3860 arelent * cache_ptr,
3861 Elf_Internal_Rela * dst)
3862{
3863 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
3864
3865 BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
3866
3867 BFD_ASSERT (r_type < (unsigned int) R_V800_max);
3868
3869 if (r_type == R_V800_NONE)
3870 r_type = R_V810_NONE;
3871
3872 BFD_ASSERT (r_type >= (unsigned int) R_V810_NONE);
3873 r_type -= R_V810_NONE;
3874 BFD_ASSERT (r_type < ARRAY_SIZE (v800_elf_howto_table));
3875
68ffbac6 3876 cache_ptr->howto = v800_elf_howto_table + r_type;
de863c74
NC
3877}
3878\f
3879
3880#undef TARGET_LITTLE_SYM
3881#define TARGET_LITTLE_SYM bfd_elf32_v850_rh850_vec
3882#undef TARGET_LITTLE_NAME
3883#define TARGET_LITTLE_NAME "elf32-v850-rh850"
3884#undef ELF_ARCH
3885#define ELF_ARCH bfd_arch_v850_rh850
3886#undef ELF_MACHINE_CODE
3887#define ELF_MACHINE_CODE EM_V800
3888#undef ELF_MACHINE_ALT1
3889
3890#undef elf32_bed
3891#define elf32_bed elf32_v850_rh850_bed
3892
3893#undef elf_info_to_howto
3894#define elf_info_to_howto v800_elf_info_to_howto
3895#undef elf_info_to_howto_rel
3896#define elf_info_to_howto_rel NULL
3897#undef bfd_elf32_bfd_reloc_type_lookup
3898#define bfd_elf32_bfd_reloc_type_lookup v800_elf_reloc_type_lookup
3899#undef bfd_elf32_bfd_reloc_name_lookup
3900#define bfd_elf32_bfd_reloc_name_lookup v800_elf_reloc_name_lookup
3901
252b5132 3902#include "elf32-target.h"