* MAINTAINERS: Added myself.
[deliverable/binutils-gdb.git] / bfd / elf32-i860.c
CommitLineData
0e5136c6 1/* Intel i860 specific support for 32-bit ELF.
9d751335
JE
2 Copyright 1993, 2000 Free Software Foundation, Inc.
3
0e5136c6 4 Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
252b5132
RH
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
25#include "elf-bfd.h"
0e5136c6
JE
26#include "elf/i860.h"
27
28
29/* Prototypes. */
30static reloc_howto_type *lookup_howto
31 PARAMS ((unsigned int));
32
33static reloc_howto_type *elf32_i860_reloc_type_lookup
34 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
35
36static void elf32_i860_info_to_howto_rela
37 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
38
fdeafce7
JE
39static bfd_reloc_status_type elf32_i860_relocate_splitn
40 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
41
fdeafce7 42static bfd_reloc_status_type elf32_i860_relocate_pc16
d670a150 43 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
fdeafce7
JE
44
45static bfd_reloc_status_type elf32_i860_relocate_highadj
46 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
47
48static boolean elf32_i860_relocate_section
49 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
50 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
51
52static bfd_reloc_status_type i860_final_link_relocate
53 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
54 Elf_Internal_Rela *, bfd_vma));
55
de24da47
JE
56static boolean elf32_i860_is_local_label_name
57 PARAMS ((bfd *, const char *));
58
fdeafce7 59
0e5136c6
JE
60
61/* This howto table is preliminary. */
62static reloc_howto_type elf32_i860_howto_table [] =
63{
64 /* This relocation does nothing. */
65 HOWTO (R_860_NONE, /* type */
66 0, /* rightshift */
67 2, /* size (0 = byte, 1 = short, 2 = long) */
68 32, /* bitsize */
69 false, /* pc_relative */
70 0, /* bitpos */
71 complain_overflow_bitfield, /* complain_on_overflow */
72 bfd_elf_generic_reloc, /* special_function */
73 "R_860_NONE", /* name */
74 false, /* partial_inplace */
75 0, /* src_mask */
76 0, /* dst_mask */
77 false), /* pcrel_offset */
78
79 /* A 32-bit absolute relocation. */
80 HOWTO (R_860_32, /* type */
81 0, /* rightshift */
82 2, /* size (0 = byte, 1 = short, 2 = long) */
83 32, /* bitsize */
84 false, /* pc_relative */
85 0, /* bitpos */
86 complain_overflow_bitfield, /* complain_on_overflow */
87 bfd_elf_generic_reloc, /* special_function */
88 "R_860_32", /* name */
89 false, /* partial_inplace */
90 0xffffffff, /* src_mask */
91 0xffffffff, /* dst_mask */
92 false), /* pcrel_offset */
93
94 HOWTO (R_860_COPY, /* type */
95 0, /* rightshift */
96 2, /* size (0 = byte, 1 = short, 2 = long) */
97 32, /* bitsize */
98 false, /* pc_relative */
99 0, /* bitpos */
100 complain_overflow_bitfield, /* complain_on_overflow */
101 bfd_elf_generic_reloc, /* special_function */
102 "R_860_COPY", /* name */
103 true, /* partial_inplace */
104 0xffffffff, /* src_mask */
105 0xffffffff, /* dst_mask */
106 false), /* pcrel_offset */
107
108 HOWTO (R_860_GLOB_DAT, /* type */
109 0, /* rightshift */
110 2, /* size (0 = byte, 1 = short, 2 = long) */
111 32, /* bitsize */
112 false, /* pc_relative */
113 0, /* bitpos */
114 complain_overflow_bitfield, /* complain_on_overflow */
115 bfd_elf_generic_reloc, /* special_function */
116 "R_860_GLOB_DAT", /* name */
117 true, /* partial_inplace */
118 0xffffffff, /* src_mask */
119 0xffffffff, /* dst_mask */
120 false), /* pcrel_offset */
121
122 HOWTO (R_860_JUMP_SLOT, /* type */
123 0, /* rightshift */
124 2, /* size (0 = byte, 1 = short, 2 = long) */
125 32, /* bitsize */
126 false, /* pc_relative */
127 0, /* bitpos */
128 complain_overflow_bitfield, /* complain_on_overflow */
129 bfd_elf_generic_reloc, /* special_function */
130 "R_860_JUMP_SLOT", /* name */
131 true, /* partial_inplace */
132 0xffffffff, /* src_mask */
133 0xffffffff, /* dst_mask */
134 false), /* pcrel_offset */
135
136 HOWTO (R_860_RELATIVE, /* type */
137 0, /* rightshift */
138 2, /* size (0 = byte, 1 = short, 2 = long) */
139 32, /* bitsize */
140 false, /* pc_relative */
141 0, /* bitpos */
142 complain_overflow_bitfield, /* complain_on_overflow */
143 bfd_elf_generic_reloc, /* special_function */
144 "R_860_RELATIVE", /* name */
145 true, /* partial_inplace */
146 0xffffffff, /* src_mask */
147 0xffffffff, /* dst_mask */
148 false), /* pcrel_offset */
149
150 /* A 26-bit PC-relative relocation. */
151 HOWTO (R_860_PC26, /* type */
fdeafce7 152 2, /* rightshift */
0e5136c6
JE
153 2, /* size (0 = byte, 1 = short, 2 = long) */
154 26, /* bitsize */
155 true, /* pc_relative */
156 0, /* bitpos */
157 complain_overflow_bitfield, /* complain_on_overflow */
158 bfd_elf_generic_reloc, /* special_function */
159 "R_860_PC26", /* name */
160 false, /* partial_inplace */
161 0x3ffffff, /* src_mask */
162 0x3ffffff, /* dst_mask */
163 true), /* pcrel_offset */
164
165 HOWTO (R_860_PLT26, /* type */
166 0, /* rightshift */
167 2, /* size (0 = byte, 1 = short, 2 = long) */
168 26, /* bitsize */
169 true, /* pc_relative */
170 0, /* bitpos */
171 complain_overflow_bitfield, /* complain_on_overflow */
172 bfd_elf_generic_reloc, /* special_function */
173 "R_860_PLT26", /* name */
174 true, /* partial_inplace */
175 0xffffffff, /* src_mask */
176 0xffffffff, /* dst_mask */
177 true), /* pcrel_offset */
178
179 /* A 16-bit PC-relative relocation. */
180 HOWTO (R_860_PC16, /* type */
fdeafce7 181 2, /* rightshift */
0e5136c6
JE
182 2, /* size (0 = byte, 1 = short, 2 = long) */
183 16, /* bitsize */
184 true, /* pc_relative */
185 0, /* bitpos */
186 complain_overflow_bitfield, /* complain_on_overflow */
187 bfd_elf_generic_reloc, /* special_function */
188 "R_860_PC16", /* name */
189 false, /* partial_inplace */
305d537e
JE
190 0x1f07ff, /* src_mask */
191 0x1f07ff, /* dst_mask */
0e5136c6
JE
192 true), /* pcrel_offset */
193
194 HOWTO (R_860_LOW0, /* type */
195 0, /* rightshift */
196 2, /* size (0 = byte, 1 = short, 2 = long) */
197 16, /* bitsize */
198 false, /* pc_relative */
199 0, /* bitpos */
200 complain_overflow_dont, /* complain_on_overflow */
201 bfd_elf_generic_reloc, /* special_function */
202 "R_860_LOW0", /* name */
203 false, /* partial_inplace */
204 0xffff, /* src_mask */
205 0xffff, /* dst_mask */
206 false), /* pcrel_offset */
207
208 HOWTO (R_860_SPLIT0, /* type */
209 0, /* rightshift */
210 2, /* size (0 = byte, 1 = short, 2 = long) */
211 16, /* bitsize */
212 false, /* pc_relative */
213 0, /* bitpos */
214 complain_overflow_dont, /* complain_on_overflow */
215 bfd_elf_generic_reloc, /* special_function */
216 "R_860_SPLIT0", /* name */
217 false, /* partial_inplace */
218 0x1f07ff, /* src_mask */
219 0x1f07ff, /* dst_mask */
220 false), /* pcrel_offset */
221
222 HOWTO (R_860_LOW1, /* type */
223 0, /* rightshift */
224 2, /* size (0 = byte, 1 = short, 2 = long) */
225 16, /* bitsize */
226 false, /* pc_relative */
227 0, /* bitpos */
228 complain_overflow_dont, /* complain_on_overflow */
229 bfd_elf_generic_reloc, /* special_function */
230 "R_860_LOW1", /* name */
231 false, /* partial_inplace */
232 0xfffe, /* src_mask */
233 0xfffe, /* dst_mask */
234 false), /* pcrel_offset */
235
236 HOWTO (R_860_SPLIT1, /* type */
237 0, /* rightshift */
238 2, /* size (0 = byte, 1 = short, 2 = long) */
239 16, /* bitsize */
240 false, /* pc_relative */
241 0, /* bitpos */
242 complain_overflow_dont, /* complain_on_overflow */
243 bfd_elf_generic_reloc, /* special_function */
244 "R_860_SPLIT1", /* name */
245 false, /* partial_inplace */
305d537e
JE
246 0x1f07fe, /* src_mask */
247 0x1f07fe, /* dst_mask */
0e5136c6
JE
248 false), /* pcrel_offset */
249
250 HOWTO (R_860_LOW2, /* type */
251 0, /* rightshift */
252 2, /* size (0 = byte, 1 = short, 2 = long) */
253 16, /* bitsize */
254 false, /* pc_relative */
255 0, /* bitpos */
256 complain_overflow_dont, /* complain_on_overflow */
257 bfd_elf_generic_reloc, /* special_function */
258 "R_860_LOW2", /* name */
259 false, /* partial_inplace */
260 0xfffc, /* src_mask */
261 0xfffc, /* dst_mask */
262 false), /* pcrel_offset */
263
264 HOWTO (R_860_SPLIT2, /* type */
265 0, /* rightshift */
266 2, /* size (0 = byte, 1 = short, 2 = long) */
267 16, /* bitsize */
268 false, /* pc_relative */
269 0, /* bitpos */
270 complain_overflow_dont, /* complain_on_overflow */
271 bfd_elf_generic_reloc, /* special_function */
272 "R_860_SPLIT2", /* name */
273 false, /* partial_inplace */
305d537e
JE
274 0x1f07fc, /* src_mask */
275 0x1f07fc, /* dst_mask */
0e5136c6
JE
276 false), /* pcrel_offset */
277
278 HOWTO (R_860_LOW3, /* type */
279 0, /* rightshift */
280 2, /* size (0 = byte, 1 = short, 2 = long) */
281 16, /* bitsize */
282 false, /* pc_relative */
283 0, /* bitpos */
284 complain_overflow_dont, /* complain_on_overflow */
285 bfd_elf_generic_reloc, /* special_function */
286 "R_860_LOW3", /* name */
287 false, /* partial_inplace */
288 0xfff8, /* src_mask */
289 0xfff8, /* dst_mask */
290 false), /* pcrel_offset */
291
292 HOWTO (R_860_LOGOT0, /* type */
293 0, /* rightshift */
294 2, /* size (0 = byte, 1 = short, 2 = long) */
295 16, /* bitsize */
296 false, /* pc_relative */
297 0, /* bitpos */
298 complain_overflow_dont, /* complain_on_overflow */
299 bfd_elf_generic_reloc, /* special_function */
300 "R_860_LOGOT0", /* name */
301 false, /* partial_inplace */
302 0, /* src_mask */
303 0xffff, /* dst_mask */
304 true), /* pcrel_offset */
305
306 HOWTO (R_860_SPGOT0, /* type */
307 0, /* rightshift */
308 2, /* size (0 = byte, 1 = short, 2 = long) */
309 16, /* bitsize */
310 false, /* pc_relative */
311 0, /* bitpos */
312 complain_overflow_dont, /* complain_on_overflow */
313 bfd_elf_generic_reloc, /* special_function */
314 "R_860_SPGOT0", /* name */
315 false, /* partial_inplace */
316 0, /* src_mask */
317 0xffff, /* dst_mask */
318 true), /* pcrel_offset */
319
320 HOWTO (R_860_LOGOT1, /* type */
321 0, /* rightshift */
322 2, /* size (0 = byte, 1 = short, 2 = long) */
323 16, /* bitsize */
324 false, /* pc_relative */
325 0, /* bitpos */
326 complain_overflow_dont, /* complain_on_overflow */
327 bfd_elf_generic_reloc, /* special_function */
328 "R_860_LOGOT1", /* name */
329 false, /* partial_inplace */
330 0, /* src_mask */
331 0xffff, /* dst_mask */
332 true), /* pcrel_offset */
333
334 HOWTO (R_860_SPGOT1, /* type */
335 0, /* rightshift */
336 2, /* size (0 = byte, 1 = short, 2 = long) */
337 16, /* bitsize */
338 false, /* pc_relative */
339 0, /* bitpos */
340 complain_overflow_dont, /* complain_on_overflow */
341 bfd_elf_generic_reloc, /* special_function */
342 "R_860_SPGOT1", /* name */
343 false, /* partial_inplace */
344 0, /* src_mask */
345 0xffff, /* dst_mask */
346 true), /* pcrel_offset */
347
348 HOWTO (R_860_LOGOTOFF0, /* type */
349 0, /* rightshift */
350 2, /* size (0 = byte, 1 = short, 2 = long) */
351 32, /* bitsize */
352 false, /* pc_relative */
353 0, /* bitpos */
354 complain_overflow_dont, /* complain_on_overflow */
355 bfd_elf_generic_reloc, /* special_function */
356 "R_860_LOGOTOFF0", /* name */
357 true, /* partial_inplace */
358 0xffffffff, /* src_mask */
359 0xffffffff, /* dst_mask */
360 false), /* pcrel_offset */
361
362 HOWTO (R_860_SPGOTOFF0, /* type */
363 0, /* rightshift */
364 2, /* size (0 = byte, 1 = short, 2 = long) */
365 32, /* bitsize */
366 false, /* pc_relative */
367 0, /* bitpos */
368 complain_overflow_dont, /* complain_on_overflow */
369 bfd_elf_generic_reloc, /* special_function */
370 "R_860_SPGOTOFF0", /* name */
371 true, /* partial_inplace */
372 0xffffffff, /* src_mask */
373 0xffffffff, /* dst_mask */
374 false), /* pcrel_offset */
375
376 HOWTO (R_860_LOGOTOFF1, /* type */
377 0, /* rightshift */
378 2, /* size (0 = byte, 1 = short, 2 = long) */
379 32, /* bitsize */
380 false, /* pc_relative */
381 0, /* bitpos */
382 complain_overflow_dont, /* complain_on_overflow */
383 bfd_elf_generic_reloc, /* special_function */
384 "R_860_LOGOTOFF1", /* name */
385 true, /* partial_inplace */
386 0xffffffff, /* src_mask */
387 0xffffffff, /* dst_mask */
388 false), /* pcrel_offset */
389
390 HOWTO (R_860_SPGOTOFF1, /* type */
391 0, /* rightshift */
392 2, /* size (0 = byte, 1 = short, 2 = long) */
393 32, /* bitsize */
394 false, /* pc_relative */
395 0, /* bitpos */
396 complain_overflow_dont, /* complain_on_overflow */
397 bfd_elf_generic_reloc, /* special_function */
398 "R_860_SPGOTOFF1", /* name */
399 true, /* partial_inplace */
400 0xffffffff, /* src_mask */
401 0xffffffff, /* dst_mask */
402 false), /* pcrel_offset */
403
404 HOWTO (R_860_LOGOTOFF2, /* type */
405 0, /* rightshift */
406 2, /* size (0 = byte, 1 = short, 2 = long) */
407 32, /* bitsize */
408 false, /* pc_relative */
409 0, /* bitpos */
410 complain_overflow_dont, /* complain_on_overflow */
411 bfd_elf_generic_reloc, /* special_function */
412 "R_860_LOGOTOFF2", /* name */
413 true, /* partial_inplace */
414 0xffffffff, /* src_mask */
415 0xffffffff, /* dst_mask */
416 false), /* pcrel_offset */
417
418 HOWTO (R_860_LOGOTOFF3, /* type */
419 0, /* rightshift */
420 2, /* size (0 = byte, 1 = short, 2 = long) */
421 32, /* bitsize */
422 false, /* pc_relative */
423 0, /* bitpos */
424 complain_overflow_dont, /* complain_on_overflow */
425 bfd_elf_generic_reloc, /* special_function */
426 "R_860_LOGOTOFF3", /* name */
427 true, /* partial_inplace */
428 0xffffffff, /* src_mask */
429 0xffffffff, /* dst_mask */
430 false), /* pcrel_offset */
431
432 HOWTO (R_860_LOPC, /* type */
433 0, /* rightshift */
434 2, /* size (0 = byte, 1 = short, 2 = long) */
435 16, /* bitsize */
436 true, /* pc_relative */
437 0, /* bitpos */
438 complain_overflow_bitfield, /* complain_on_overflow */
439 bfd_elf_generic_reloc, /* special_function */
440 "R_860_LOPC", /* name */
441 false, /* partial_inplace */
442 0xffff, /* src_mask */
443 0xffff, /* dst_mask */
444 true), /* pcrel_offset */
445
446 HOWTO (R_860_HIGHADJ, /* type */
447 0, /* rightshift */
448 2, /* size (0 = byte, 1 = short, 2 = long) */
449 16, /* bitsize */
450 false, /* pc_relative */
451 0, /* bitpos */
452 complain_overflow_dont, /* complain_on_overflow */
453 bfd_elf_generic_reloc, /* special_function */
454 "R_860_HIGHADJ", /* name */
455 false, /* partial_inplace */
456 0xffff, /* src_mask */
457 0xffff, /* dst_mask */
458 false), /* pcrel_offset */
459
460 HOWTO (R_860_HAGOT, /* type */
461 0, /* rightshift */
462 2, /* size (0 = byte, 1 = short, 2 = long) */
463 16, /* bitsize */
464 false, /* pc_relative */
465 0, /* bitpos */
466 complain_overflow_dont, /* complain_on_overflow */
467 bfd_elf_generic_reloc, /* special_function */
468 "R_860_HAGOT", /* name */
469 false, /* partial_inplace */
470 0, /* src_mask */
471 0xffff, /* dst_mask */
472 true), /* pcrel_offset */
473
474 HOWTO (R_860_HAGOTOFF, /* type */
475 0, /* rightshift */
476 2, /* size (0 = byte, 1 = short, 2 = long) */
477 32, /* bitsize */
478 false, /* pc_relative */
479 0, /* bitpos */
480 complain_overflow_dont, /* complain_on_overflow */
481 bfd_elf_generic_reloc, /* special_function */
482 "R_860_HAGOTOFF", /* name */
483 true, /* partial_inplace */
484 0xffffffff, /* src_mask */
485 0xffffffff, /* dst_mask */
486 false), /* pcrel_offset */
487
488 HOWTO (R_860_HAPC, /* type */
489 0, /* rightshift */
490 2, /* size (0 = byte, 1 = short, 2 = long) */
491 16, /* bitsize */
492 true, /* pc_relative */
493 0, /* bitpos */
494 complain_overflow_bitfield, /* complain_on_overflow */
495 bfd_elf_generic_reloc, /* special_function */
496 "R_860_HAPC", /* name */
497 false, /* partial_inplace */
498 0xffff, /* src_mask */
499 0xffff, /* dst_mask */
500 true), /* pcrel_offset */
501
502 HOWTO (R_860_HIGH, /* type */
fdeafce7 503 16, /* rightshift */
0e5136c6
JE
504 2, /* size (0 = byte, 1 = short, 2 = long) */
505 16, /* bitsize */
506 false, /* pc_relative */
507 0, /* bitpos */
508 complain_overflow_dont, /* complain_on_overflow */
509 bfd_elf_generic_reloc, /* special_function */
510 "R_860_HIGH", /* name */
511 false, /* partial_inplace */
512 0xffff, /* src_mask */
513 0xffff, /* dst_mask */
514 false), /* pcrel_offset */
515
516 HOWTO (R_860_HIGOT, /* type */
517 0, /* rightshift */
518 2, /* size (0 = byte, 1 = short, 2 = long) */
519 16, /* bitsize */
520 false, /* pc_relative */
521 0, /* bitpos */
522 complain_overflow_dont, /* complain_on_overflow */
523 bfd_elf_generic_reloc, /* special_function */
524 "R_860_HIGOT", /* name */
525 false, /* partial_inplace */
526 0, /* src_mask */
527 0xffff, /* dst_mask */
528 true), /* pcrel_offset */
529
530 HOWTO (R_860_HIGOTOFF, /* type */
531 0, /* rightshift */
532 2, /* size (0 = byte, 1 = short, 2 = long) */
533 32, /* bitsize */
534 false, /* pc_relative */
535 0, /* bitpos */
536 complain_overflow_dont, /* complain_on_overflow */
537 bfd_elf_generic_reloc, /* special_function */
538 "R_860_HIGOTOFF", /* name */
539 true, /* partial_inplace */
540 0xffffffff, /* src_mask */
541 0xffffffff, /* dst_mask */
542 false), /* pcrel_offset */
543};
544
545\f
546static unsigned char elf_code_to_howto_index[R_860_max + 1];
547
548static reloc_howto_type *
549lookup_howto (rtype)
550 unsigned int rtype;
551{
552 static int initialized = 0;
553 int i;
554 int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
555 / sizeof (elf32_i860_howto_table[0]));
556
557 if (! initialized)
558 {
559 initialized = 1;
560 memset (elf_code_to_howto_index, 0xff,
561 sizeof (elf_code_to_howto_index));
562 for (i = 0; i < howto_tbl_size; i++)
563 elf_code_to_howto_index[elf32_i860_howto_table[i].type] = i;
564 }
565
566 BFD_ASSERT (rtype <= R_860_max);
567 i = elf_code_to_howto_index[rtype];
568 if (i >= howto_tbl_size)
569 return 0;
570 return elf32_i860_howto_table + i;
571}
572
573
574/* Given a BFD reloc, return the matching HOWTO structure. */
575static reloc_howto_type *
576elf32_i860_reloc_type_lookup (abfd, code)
577 bfd * abfd ATTRIBUTE_UNUSED;
578 bfd_reloc_code_real_type code;
579{
580 unsigned int rtype;
581
582 switch (code)
583 {
584 case BFD_RELOC_NONE:
585 rtype = R_860_NONE;
586 break;
587 case BFD_RELOC_32:
588 rtype = R_860_32;
589 break;
590 case BFD_RELOC_860_COPY:
591 rtype = R_860_COPY;
592 break;
593 case BFD_RELOC_860_GLOB_DAT:
594 rtype = R_860_GLOB_DAT;
595 break;
596 case BFD_RELOC_860_JUMP_SLOT:
597 rtype = R_860_JUMP_SLOT;
598 break;
599 case BFD_RELOC_860_RELATIVE:
600 rtype = R_860_RELATIVE;
601 break;
602 case BFD_RELOC_860_PC26:
603 rtype = R_860_PC26;
604 break;
605 case BFD_RELOC_860_PLT26:
606 rtype = R_860_PLT26;
607 break;
608 case BFD_RELOC_860_PC16:
609 rtype = R_860_PC16;
610 break;
611 case BFD_RELOC_860_LOW0:
612 rtype = R_860_LOW0;
613 break;
614 case BFD_RELOC_860_SPLIT0:
615 rtype = R_860_SPLIT0;
616 break;
617 case BFD_RELOC_860_LOW1:
618 rtype = R_860_LOW1;
619 break;
620 case BFD_RELOC_860_SPLIT1:
621 rtype = R_860_SPLIT1;
622 break;
623 case BFD_RELOC_860_LOW2:
624 rtype = R_860_LOW2;
625 break;
626 case BFD_RELOC_860_SPLIT2:
627 rtype = R_860_SPLIT2;
628 break;
629 case BFD_RELOC_860_LOW3:
630 rtype = R_860_LOW3;
631 break;
632 case BFD_RELOC_860_LOGOT0:
633 rtype = R_860_LOGOT0;
634 break;
635 case BFD_RELOC_860_SPGOT0:
636 rtype = R_860_SPGOT0;
637 break;
638 case BFD_RELOC_860_LOGOT1:
639 rtype = R_860_LOGOT1;
640 break;
641 case BFD_RELOC_860_SPGOT1:
642 rtype = R_860_SPGOT1;
643 break;
644 case BFD_RELOC_860_LOGOTOFF0:
645 rtype = R_860_LOGOTOFF0;
646 break;
647 case BFD_RELOC_860_SPGOTOFF0:
648 rtype = R_860_SPGOTOFF0;
649 break;
650 case BFD_RELOC_860_LOGOTOFF1:
651 rtype = R_860_LOGOTOFF1;
652 break;
653 case BFD_RELOC_860_SPGOTOFF1:
654 rtype = R_860_SPGOTOFF1;
655 break;
656 case BFD_RELOC_860_LOGOTOFF2:
657 rtype = R_860_LOGOTOFF2;
658 break;
659 case BFD_RELOC_860_LOGOTOFF3:
660 rtype = R_860_LOGOTOFF3;
661 break;
662 case BFD_RELOC_860_LOPC:
663 rtype = R_860_LOPC;
664 break;
665 case BFD_RELOC_860_HIGHADJ:
666 rtype = R_860_HIGHADJ;
667 break;
668 case BFD_RELOC_860_HAGOT:
669 rtype = R_860_HAGOT;
670 break;
671 case BFD_RELOC_860_HAGOTOFF:
672 rtype = R_860_HAGOTOFF;
673 break;
674 case BFD_RELOC_860_HAPC:
675 rtype = R_860_HAPC;
676 break;
677 case BFD_RELOC_860_HIGH:
678 rtype = R_860_HIGH;
679 break;
680 case BFD_RELOC_860_HIGOT:
681 rtype = R_860_HIGOT;
682 break;
683 case BFD_RELOC_860_HIGOTOFF:
684 rtype = R_860_HIGOTOFF;
685 break;
686 default:
687 rtype = 0;
688 break;
689 }
690 return lookup_howto (rtype);
691}
692
693
694/* Given a ELF reloc, return the matching HOWTO structure. */
695static void
696elf32_i860_info_to_howto_rela (abfd, bfd_reloc, elf_reloc)
697 bfd *abfd ATTRIBUTE_UNUSED;
698 arelent *bfd_reloc;
699 Elf64_Internal_Rela *elf_reloc;
700{
701 bfd_reloc->howto = lookup_howto (ELF32_R_TYPE (elf_reloc->r_info));
702}
703
252b5132 704
fdeafce7
JE
705\f
706/* Specialized relocation handler for R_860_SPLITn. These relocations
707 involves a 16-bit field that is split into two contiguous parts. */
708static bfd_reloc_status_type
709elf32_i860_relocate_splitn (input_bfd, rello, contents, value)
710 bfd *input_bfd;
711 Elf_Internal_Rela *rello;
712 bfd_byte *contents;
713 bfd_vma value;
714{
ded0649c 715 bfd_vma insn;
fdeafce7
JE
716 reloc_howto_type *howto;
717 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
718 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
719
fdeafce7 720 /* Relocate. */
ded0649c 721 value += rello->r_addend;
fdeafce7 722
ded0649c 723 /* Separate the fields and insert. */
fdeafce7
JE
724 value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
725 insn = (insn & ~howto->dst_mask) | value;
726
727 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
728 return bfd_reloc_ok;
729}
730
731
fdeafce7
JE
732/* Specialized relocation handler for R_860_PC16. This relocation
733 involves a 16-bit, PC-relative field that is split into two contiguous
734 parts. */
735static bfd_reloc_status_type
d670a150 736elf32_i860_relocate_pc16 (input_bfd, input_section, rello, contents, value)
fdeafce7 737 bfd *input_bfd;
d670a150 738 asection *input_section;
fdeafce7
JE
739 Elf_Internal_Rela *rello;
740 bfd_byte *contents;
741 bfd_vma value;
742{
ded0649c 743 bfd_vma insn;
d670a150
JE
744 reloc_howto_type *howto;
745 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
746 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
747
748 /* Adjust for PC-relative relocation. */
749 value -= (input_section->output_section->vma
750 + input_section->output_offset);
751 value -= rello->r_offset;
752
d670a150 753 /* Relocate. */
ded0649c 754 value += rello->r_addend;
d670a150 755
ded0649c 756 /* Separate the fields and insert. */
d670a150
JE
757 value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
758 insn = (insn & ~howto->dst_mask) | value;
759
760 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
761 return bfd_reloc_ok;
762
fdeafce7 763}
fdeafce7
JE
764
765
766/* Specialized relocation handler for R_860_HIGHADJ. */
767static bfd_reloc_status_type
768elf32_i860_relocate_highadj (input_bfd, rel, contents, value)
769 bfd *input_bfd;
770 Elf_Internal_Rela *rel;
771 bfd_byte *contents;
772 bfd_vma value;
773{
774 bfd_vma insn;
775
776 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
777
778 value += ((rel->r_addend & 0x8000) << 1);
779 value += rel->r_addend;
780 value = ((value >> 16) & 0xffff);
fdeafce7
JE
781
782 insn = (insn & 0xffff0000) | value;
783
784 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
785 return bfd_reloc_ok;
786}
787
788
789/* Perform a single relocation. By default we use the standard BFD
790 routines. However, we handle some specially. */
791static bfd_reloc_status_type
792i860_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
793 reloc_howto_type * howto;
794 bfd * input_bfd;
795 asection * input_section;
796 bfd_byte * contents;
797 Elf_Internal_Rela * rel;
798 bfd_vma relocation;
799{
800 return _bfd_final_link_relocate (howto, input_bfd, input_section,
801 contents, rel->r_offset, relocation,
802 rel->r_addend);
803}
804
805
806/* Relocate an i860 ELF section.
252b5132 807
fdeafce7
JE
808 This is boiler-plate code copied from fr30.
809 There is some attempt to make this function usable for many architectures,
810 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
811 if only to serve as a learning tool.
812
813 The RELOCATE_SECTION function is called by the new ELF backend linker
814 to handle the relocations for a section.
815
816 The relocs are always passed as Rela structures; if the section
817 actually uses Rel structures, the r_addend field will always be
818 zero.
819
820 This function is responsible for adjusting the section contents as
821 necessary, and (if using Rela relocs and generating a relocateable
822 output file) adjusting the reloc addend as necessary.
823
824 This function does not have to worry about setting the reloc
825 address or the reloc symbol index.
826
827 LOCAL_SYMS is a pointer to the swapped in local symbols.
828
829 LOCAL_SECTIONS is an array giving the section in the input file
830 corresponding to the st_shndx field of each local symbol.
831
832 The global hash table entry for the global symbols can be found
833 via elf_sym_hashes (input_bfd).
834
835 When generating relocateable output, this function must handle
836 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
837 going to be the section symbol corresponding to the output
838 section, which means that the addend must be adjusted
839 accordingly. */
840static boolean
841elf32_i860_relocate_section (output_bfd, info, input_bfd, input_section,
842 contents, relocs, local_syms, local_sections)
843 bfd * output_bfd ATTRIBUTE_UNUSED;
844 struct bfd_link_info * info;
845 bfd * input_bfd;
846 asection * input_section;
847 bfd_byte * contents;
848 Elf_Internal_Rela * relocs;
849 Elf_Internal_Sym * local_syms;
850 asection ** local_sections;
851{
852 Elf_Internal_Shdr * symtab_hdr;
853 struct elf_link_hash_entry ** sym_hashes;
854 Elf_Internal_Rela * rel;
855 Elf_Internal_Rela * relend;
856
857 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
858 sym_hashes = elf_sym_hashes (input_bfd);
859 relend = relocs + input_section->reloc_count;
860
861 for (rel = relocs; rel < relend; rel ++)
862 {
863 reloc_howto_type * howto;
864 unsigned long r_symndx;
865 Elf_Internal_Sym * sym;
866 asection * sec;
867 struct elf_link_hash_entry * h;
868 bfd_vma relocation;
869 bfd_reloc_status_type r;
870 const char * name = NULL;
871 int r_type;
872
873 r_type = ELF32_R_TYPE (rel->r_info);
874
875#if 0
876 if ( r_type == R_860_GNU_VTINHERIT
877 || r_type == R_860_GNU_VTENTRY)
878 continue;
879#endif
880
881 r_symndx = ELF32_R_SYM (rel->r_info);
882
883 if (info->relocateable)
884 {
885 /* This is a relocateable link. We don't have to change
886 anything, unless the reloc is against a section symbol,
887 in which case we have to adjust according to where the
888 section symbol winds up in the output section. */
889 if (r_symndx < symtab_hdr->sh_info)
890 {
891 sym = local_syms + r_symndx;
892
893 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
894 {
895 sec = local_sections [r_symndx];
896 rel->r_addend += sec->output_offset + sym->st_value;
897 }
898 }
899
900 continue;
901 }
902
903 /* This is a final link. */
904 howto = lookup_howto (ELF32_R_TYPE (rel->r_info));
905 h = NULL;
906 sym = NULL;
907 sec = NULL;
908
909 if (r_symndx < symtab_hdr->sh_info)
910 {
911 sym = local_syms + r_symndx;
912 sec = local_sections [r_symndx];
913 relocation = (sec->output_section->vma
914 + sec->output_offset
915 + sym->st_value);
916
917 name = bfd_elf_string_from_elf_section
918 (input_bfd, symtab_hdr->sh_link, sym->st_name);
919 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
920 }
921 else
922 {
923 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
924
925 while (h->root.type == bfd_link_hash_indirect
926 || h->root.type == bfd_link_hash_warning)
927 h = (struct elf_link_hash_entry *) h->root.u.i.link;
928
929 name = h->root.root.string;
930
931 if (h->root.type == bfd_link_hash_defined
932 || h->root.type == bfd_link_hash_defweak)
933 {
934 sec = h->root.u.def.section;
935 relocation = (h->root.u.def.value
936 + sec->output_section->vma
937 + sec->output_offset);
938 }
939 else if (h->root.type == bfd_link_hash_undefweak)
940 {
941 relocation = 0;
942 }
943 else
944 {
945 if (! ((*info->callbacks->undefined_symbol)
946 (info, h->root.root.string, input_bfd,
947 input_section, rel->r_offset, true)))
948 return false;
949 relocation = 0;
950 }
951 }
952
953 switch (r_type)
954 {
955 default:
956 r = i860_final_link_relocate (howto, input_bfd, input_section,
957 contents, rel, relocation);
958 break;
959
960 case R_860_HIGHADJ:
961 r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
962 relocation);
963 break;
964
fdeafce7 965 case R_860_PC16:
d670a150
JE
966 r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
967 contents, relocation);
fdeafce7 968 break;
fdeafce7
JE
969
970 case R_860_SPLIT0:
971 case R_860_SPLIT1:
972 case R_860_SPLIT2:
973 r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
974 relocation);
975 break;
976
977 /* We do not yet handle GOT/PLT/Dynamic relocations. */
978 case R_860_COPY:
979 case R_860_GLOB_DAT:
980 case R_860_JUMP_SLOT:
981 case R_860_RELATIVE:
982 case R_860_PLT26:
983 case R_860_LOGOT0:
984 case R_860_SPGOT0:
985 case R_860_LOGOT1:
986 case R_860_SPGOT1:
987 case R_860_LOGOTOFF0:
988 case R_860_SPGOTOFF0:
989 case R_860_LOGOTOFF1:
990 case R_860_SPGOTOFF1:
991 case R_860_LOGOTOFF2:
992 case R_860_LOGOTOFF3:
993 case R_860_LOPC:
994 case R_860_HAGOT:
995 case R_860_HAGOTOFF:
996 case R_860_HAPC:
997 case R_860_HIGOT:
998 case R_860_HIGOTOFF:
999 r = bfd_reloc_notsupported;
1000 break;
1001 }
1002
1003 if (r != bfd_reloc_ok)
1004 {
1005 const char * msg = (const char *) NULL;
1006
1007 switch (r)
1008 {
1009 case bfd_reloc_overflow:
1010 r = info->callbacks->reloc_overflow
1011 (info, name, howto->name, (bfd_vma) 0,
1012 input_bfd, input_section, rel->r_offset);
1013 break;
1014
1015 case bfd_reloc_undefined:
1016 r = info->callbacks->undefined_symbol
1017 (info, name, input_bfd, input_section, rel->r_offset, true);
1018 break;
1019
1020 case bfd_reloc_outofrange:
1021 msg = _("internal error: out of range error");
1022 break;
1023
1024 case bfd_reloc_notsupported:
1025 msg = _("internal error: unsupported relocation error");
1026 break;
1027
1028 case bfd_reloc_dangerous:
1029 msg = _("internal error: dangerous relocation");
1030 break;
1031
1032 default:
1033 msg = _("internal error: unknown error");
1034 break;
1035 }
1036
1037 if (msg)
1038 r = info->callbacks->warning
1039 (info, msg, name, input_bfd, input_section, rel->r_offset);
1040
1041 if (! r)
1042 return false;
1043 }
1044 }
1045
1046 return true;
1047}
1048
1049
de24da47
JE
1050/* Return whether a symbol name implies a local label. SVR4/860 compilers
1051 generate labels of the form ".ep.function_name" to denote the end of a
1052 function prolog. These should be local.
1053 ??? Do any other SVR4 compilers have this convention? If so, this should
1054 be added to the generic routine. */
1055static boolean
1056elf32_i860_is_local_label_name (abfd, name)
1057 bfd *abfd;
1058 const char *name;
1059{
1060 if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1061 return true;
1062
1063 return _bfd_elf_is_local_label_name (abfd, name);
1064}
1065
1066
fdeafce7 1067\f
9d751335
JE
1068#define TARGET_BIG_SYM bfd_elf32_i860_vec
1069#define TARGET_BIG_NAME "elf32-i860"
1070#define TARGET_LITTLE_SYM bfd_elf32_i860_little_vec
1071#define TARGET_LITTLE_NAME "elf32-i860-little"
0e5136c6
JE
1072#define ELF_ARCH bfd_arch_i860
1073#define ELF_MACHINE_CODE EM_860
1074#define ELF_MAXPAGESIZE 4096
1075
fdeafce7 1076#define elf_info_to_howto_rel NULL
0e5136c6 1077#define elf_info_to_howto elf32_i860_info_to_howto_rela
fdeafce7 1078#define elf_backend_relocate_section elf32_i860_relocate_section
0e5136c6 1079#define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
de24da47 1080#define bfd_elf32_bfd_is_local_label_name elf32_i860_is_local_label_name
252b5132
RH
1081
1082#include "elf32-target.h"
This page took 0.124104 seconds and 4 git commands to generate.