1 /* Intel i860 specific support for 32-bit ELF.
2 Copyright 1993, 1995, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
5 Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
30 /* This howto table is preliminary. */
31 static reloc_howto_type elf32_i860_howto_table
[] =
33 /* This relocation does nothing. */
34 HOWTO (R_860_NONE
, /* type */
36 2, /* size (0 = byte, 1 = short, 2 = long) */
38 FALSE
, /* pc_relative */
40 complain_overflow_bitfield
, /* complain_on_overflow */
41 bfd_elf_generic_reloc
, /* special_function */
42 "R_860_NONE", /* name */
43 FALSE
, /* partial_inplace */
46 FALSE
), /* pcrel_offset */
48 /* A 32-bit absolute relocation. */
49 HOWTO (R_860_32
, /* type */
51 2, /* size (0 = byte, 1 = short, 2 = long) */
53 FALSE
, /* pc_relative */
55 complain_overflow_bitfield
, /* complain_on_overflow */
56 bfd_elf_generic_reloc
, /* special_function */
57 "R_860_32", /* name */
58 FALSE
, /* partial_inplace */
59 0xffffffff, /* src_mask */
60 0xffffffff, /* dst_mask */
61 FALSE
), /* pcrel_offset */
63 HOWTO (R_860_COPY
, /* type */
65 2, /* size (0 = byte, 1 = short, 2 = long) */
67 FALSE
, /* pc_relative */
69 complain_overflow_bitfield
, /* complain_on_overflow */
70 bfd_elf_generic_reloc
, /* special_function */
71 "R_860_COPY", /* name */
72 TRUE
, /* partial_inplace */
73 0xffffffff, /* src_mask */
74 0xffffffff, /* dst_mask */
75 FALSE
), /* pcrel_offset */
77 HOWTO (R_860_GLOB_DAT
, /* type */
79 2, /* size (0 = byte, 1 = short, 2 = long) */
81 FALSE
, /* pc_relative */
83 complain_overflow_bitfield
, /* complain_on_overflow */
84 bfd_elf_generic_reloc
, /* special_function */
85 "R_860_GLOB_DAT", /* name */
86 TRUE
, /* partial_inplace */
87 0xffffffff, /* src_mask */
88 0xffffffff, /* dst_mask */
89 FALSE
), /* pcrel_offset */
91 HOWTO (R_860_JUMP_SLOT
, /* type */
93 2, /* size (0 = byte, 1 = short, 2 = long) */
95 FALSE
, /* pc_relative */
97 complain_overflow_bitfield
, /* complain_on_overflow */
98 bfd_elf_generic_reloc
, /* special_function */
99 "R_860_JUMP_SLOT", /* name */
100 TRUE
, /* partial_inplace */
101 0xffffffff, /* src_mask */
102 0xffffffff, /* dst_mask */
103 FALSE
), /* pcrel_offset */
105 HOWTO (R_860_RELATIVE
, /* type */
107 2, /* size (0 = byte, 1 = short, 2 = long) */
109 FALSE
, /* pc_relative */
111 complain_overflow_bitfield
, /* complain_on_overflow */
112 bfd_elf_generic_reloc
, /* special_function */
113 "R_860_RELATIVE", /* name */
114 TRUE
, /* partial_inplace */
115 0xffffffff, /* src_mask */
116 0xffffffff, /* dst_mask */
117 FALSE
), /* pcrel_offset */
119 /* A 26-bit PC-relative relocation. */
120 HOWTO (R_860_PC26
, /* type */
122 2, /* size (0 = byte, 1 = short, 2 = long) */
124 TRUE
, /* pc_relative */
126 complain_overflow_bitfield
, /* complain_on_overflow */
127 bfd_elf_generic_reloc
, /* special_function */
128 "R_860_PC26", /* name */
129 FALSE
, /* partial_inplace */
130 0x3ffffff, /* src_mask */
131 0x3ffffff, /* dst_mask */
132 TRUE
), /* pcrel_offset */
134 HOWTO (R_860_PLT26
, /* type */
136 2, /* size (0 = byte, 1 = short, 2 = long) */
138 TRUE
, /* pc_relative */
140 complain_overflow_bitfield
, /* complain_on_overflow */
141 bfd_elf_generic_reloc
, /* special_function */
142 "R_860_PLT26", /* name */
143 TRUE
, /* partial_inplace */
144 0xffffffff, /* src_mask */
145 0xffffffff, /* dst_mask */
146 TRUE
), /* pcrel_offset */
148 /* A 16-bit PC-relative relocation. */
149 HOWTO (R_860_PC16
, /* type */
151 2, /* size (0 = byte, 1 = short, 2 = long) */
153 TRUE
, /* pc_relative */
155 complain_overflow_bitfield
, /* complain_on_overflow */
156 bfd_elf_generic_reloc
, /* special_function */
157 "R_860_PC16", /* name */
158 FALSE
, /* partial_inplace */
159 0x1f07ff, /* src_mask */
160 0x1f07ff, /* dst_mask */
161 TRUE
), /* pcrel_offset */
163 HOWTO (R_860_LOW0
, /* type */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
167 FALSE
, /* pc_relative */
169 complain_overflow_dont
, /* complain_on_overflow */
170 bfd_elf_generic_reloc
, /* special_function */
171 "R_860_LOW0", /* name */
172 FALSE
, /* partial_inplace */
173 0xffff, /* src_mask */
174 0xffff, /* dst_mask */
175 FALSE
), /* pcrel_offset */
177 HOWTO (R_860_SPLIT0
, /* type */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
181 FALSE
, /* pc_relative */
183 complain_overflow_dont
, /* complain_on_overflow */
184 bfd_elf_generic_reloc
, /* special_function */
185 "R_860_SPLIT0", /* name */
186 FALSE
, /* partial_inplace */
187 0x1f07ff, /* src_mask */
188 0x1f07ff, /* dst_mask */
189 FALSE
), /* pcrel_offset */
191 HOWTO (R_860_LOW1
, /* type */
193 2, /* size (0 = byte, 1 = short, 2 = long) */
195 FALSE
, /* pc_relative */
197 complain_overflow_dont
, /* complain_on_overflow */
198 bfd_elf_generic_reloc
, /* special_function */
199 "R_860_LOW1", /* name */
200 FALSE
, /* partial_inplace */
201 0xfffe, /* src_mask */
202 0xfffe, /* dst_mask */
203 FALSE
), /* pcrel_offset */
205 HOWTO (R_860_SPLIT1
, /* type */
207 2, /* size (0 = byte, 1 = short, 2 = long) */
209 FALSE
, /* pc_relative */
211 complain_overflow_dont
, /* complain_on_overflow */
212 bfd_elf_generic_reloc
, /* special_function */
213 "R_860_SPLIT1", /* name */
214 FALSE
, /* partial_inplace */
215 0x1f07fe, /* src_mask */
216 0x1f07fe, /* dst_mask */
217 FALSE
), /* pcrel_offset */
219 HOWTO (R_860_LOW2
, /* type */
221 2, /* size (0 = byte, 1 = short, 2 = long) */
223 FALSE
, /* pc_relative */
225 complain_overflow_dont
, /* complain_on_overflow */
226 bfd_elf_generic_reloc
, /* special_function */
227 "R_860_LOW2", /* name */
228 FALSE
, /* partial_inplace */
229 0xfffc, /* src_mask */
230 0xfffc, /* dst_mask */
231 FALSE
), /* pcrel_offset */
233 HOWTO (R_860_SPLIT2
, /* type */
235 2, /* size (0 = byte, 1 = short, 2 = long) */
237 FALSE
, /* pc_relative */
239 complain_overflow_dont
, /* complain_on_overflow */
240 bfd_elf_generic_reloc
, /* special_function */
241 "R_860_SPLIT2", /* name */
242 FALSE
, /* partial_inplace */
243 0x1f07fc, /* src_mask */
244 0x1f07fc, /* dst_mask */
245 FALSE
), /* pcrel_offset */
247 HOWTO (R_860_LOW3
, /* type */
249 2, /* size (0 = byte, 1 = short, 2 = long) */
251 FALSE
, /* pc_relative */
253 complain_overflow_dont
, /* complain_on_overflow */
254 bfd_elf_generic_reloc
, /* special_function */
255 "R_860_LOW3", /* name */
256 FALSE
, /* partial_inplace */
257 0xfff8, /* src_mask */
258 0xfff8, /* dst_mask */
259 FALSE
), /* pcrel_offset */
261 HOWTO (R_860_LOGOT0
, /* type */
263 2, /* size (0 = byte, 1 = short, 2 = long) */
265 FALSE
, /* pc_relative */
267 complain_overflow_dont
, /* complain_on_overflow */
268 bfd_elf_generic_reloc
, /* special_function */
269 "R_860_LOGOT0", /* name */
270 FALSE
, /* partial_inplace */
272 0xffff, /* dst_mask */
273 TRUE
), /* pcrel_offset */
275 HOWTO (R_860_SPGOT0
, /* type */
277 2, /* size (0 = byte, 1 = short, 2 = long) */
279 FALSE
, /* pc_relative */
281 complain_overflow_dont
, /* complain_on_overflow */
282 bfd_elf_generic_reloc
, /* special_function */
283 "R_860_SPGOT0", /* name */
284 FALSE
, /* partial_inplace */
286 0xffff, /* dst_mask */
287 TRUE
), /* pcrel_offset */
289 HOWTO (R_860_LOGOT1
, /* type */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
293 FALSE
, /* pc_relative */
295 complain_overflow_dont
, /* complain_on_overflow */
296 bfd_elf_generic_reloc
, /* special_function */
297 "R_860_LOGOT1", /* name */
298 FALSE
, /* partial_inplace */
300 0xffff, /* dst_mask */
301 TRUE
), /* pcrel_offset */
303 HOWTO (R_860_SPGOT1
, /* type */
305 2, /* size (0 = byte, 1 = short, 2 = long) */
307 FALSE
, /* pc_relative */
309 complain_overflow_dont
, /* complain_on_overflow */
310 bfd_elf_generic_reloc
, /* special_function */
311 "R_860_SPGOT1", /* name */
312 FALSE
, /* partial_inplace */
314 0xffff, /* dst_mask */
315 TRUE
), /* pcrel_offset */
317 HOWTO (R_860_LOGOTOFF0
, /* type */
319 2, /* size (0 = byte, 1 = short, 2 = long) */
321 FALSE
, /* pc_relative */
323 complain_overflow_dont
, /* complain_on_overflow */
324 bfd_elf_generic_reloc
, /* special_function */
325 "R_860_LOGOTOFF0", /* name */
326 TRUE
, /* partial_inplace */
327 0xffffffff, /* src_mask */
328 0xffffffff, /* dst_mask */
329 FALSE
), /* pcrel_offset */
331 HOWTO (R_860_SPGOTOFF0
, /* type */
333 2, /* size (0 = byte, 1 = short, 2 = long) */
335 FALSE
, /* pc_relative */
337 complain_overflow_dont
, /* complain_on_overflow */
338 bfd_elf_generic_reloc
, /* special_function */
339 "R_860_SPGOTOFF0", /* name */
340 TRUE
, /* partial_inplace */
341 0xffffffff, /* src_mask */
342 0xffffffff, /* dst_mask */
343 FALSE
), /* pcrel_offset */
345 HOWTO (R_860_LOGOTOFF1
, /* type */
347 2, /* size (0 = byte, 1 = short, 2 = long) */
349 FALSE
, /* pc_relative */
351 complain_overflow_dont
, /* complain_on_overflow */
352 bfd_elf_generic_reloc
, /* special_function */
353 "R_860_LOGOTOFF1", /* name */
354 TRUE
, /* partial_inplace */
355 0xffffffff, /* src_mask */
356 0xffffffff, /* dst_mask */
357 FALSE
), /* pcrel_offset */
359 HOWTO (R_860_SPGOTOFF1
, /* type */
361 2, /* size (0 = byte, 1 = short, 2 = long) */
363 FALSE
, /* pc_relative */
365 complain_overflow_dont
, /* complain_on_overflow */
366 bfd_elf_generic_reloc
, /* special_function */
367 "R_860_SPGOTOFF1", /* name */
368 TRUE
, /* partial_inplace */
369 0xffffffff, /* src_mask */
370 0xffffffff, /* dst_mask */
371 FALSE
), /* pcrel_offset */
373 HOWTO (R_860_LOGOTOFF2
, /* type */
375 2, /* size (0 = byte, 1 = short, 2 = long) */
377 FALSE
, /* pc_relative */
379 complain_overflow_dont
, /* complain_on_overflow */
380 bfd_elf_generic_reloc
, /* special_function */
381 "R_860_LOGOTOFF2", /* name */
382 TRUE
, /* partial_inplace */
383 0xffffffff, /* src_mask */
384 0xffffffff, /* dst_mask */
385 FALSE
), /* pcrel_offset */
387 HOWTO (R_860_LOGOTOFF3
, /* type */
389 2, /* size (0 = byte, 1 = short, 2 = long) */
391 FALSE
, /* pc_relative */
393 complain_overflow_dont
, /* complain_on_overflow */
394 bfd_elf_generic_reloc
, /* special_function */
395 "R_860_LOGOTOFF3", /* name */
396 TRUE
, /* partial_inplace */
397 0xffffffff, /* src_mask */
398 0xffffffff, /* dst_mask */
399 FALSE
), /* pcrel_offset */
401 HOWTO (R_860_LOPC
, /* type */
403 2, /* size (0 = byte, 1 = short, 2 = long) */
405 TRUE
, /* pc_relative */
407 complain_overflow_bitfield
, /* complain_on_overflow */
408 bfd_elf_generic_reloc
, /* special_function */
409 "R_860_LOPC", /* name */
410 FALSE
, /* partial_inplace */
411 0xffff, /* src_mask */
412 0xffff, /* dst_mask */
413 TRUE
), /* pcrel_offset */
415 HOWTO (R_860_HIGHADJ
, /* type */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
419 FALSE
, /* pc_relative */
421 complain_overflow_dont
, /* complain_on_overflow */
422 bfd_elf_generic_reloc
, /* special_function */
423 "R_860_HIGHADJ", /* name */
424 FALSE
, /* partial_inplace */
425 0xffff, /* src_mask */
426 0xffff, /* dst_mask */
427 FALSE
), /* pcrel_offset */
429 HOWTO (R_860_HAGOT
, /* type */
431 2, /* size (0 = byte, 1 = short, 2 = long) */
433 FALSE
, /* pc_relative */
435 complain_overflow_dont
, /* complain_on_overflow */
436 bfd_elf_generic_reloc
, /* special_function */
437 "R_860_HAGOT", /* name */
438 FALSE
, /* partial_inplace */
440 0xffff, /* dst_mask */
441 TRUE
), /* pcrel_offset */
443 HOWTO (R_860_HAGOTOFF
, /* type */
445 2, /* size (0 = byte, 1 = short, 2 = long) */
447 FALSE
, /* pc_relative */
449 complain_overflow_dont
, /* complain_on_overflow */
450 bfd_elf_generic_reloc
, /* special_function */
451 "R_860_HAGOTOFF", /* name */
452 TRUE
, /* partial_inplace */
453 0xffffffff, /* src_mask */
454 0xffffffff, /* dst_mask */
455 FALSE
), /* pcrel_offset */
457 HOWTO (R_860_HAPC
, /* type */
459 2, /* size (0 = byte, 1 = short, 2 = long) */
461 TRUE
, /* pc_relative */
463 complain_overflow_bitfield
, /* complain_on_overflow */
464 bfd_elf_generic_reloc
, /* special_function */
465 "R_860_HAPC", /* name */
466 FALSE
, /* partial_inplace */
467 0xffff, /* src_mask */
468 0xffff, /* dst_mask */
469 TRUE
), /* pcrel_offset */
471 HOWTO (R_860_HIGH
, /* type */
473 2, /* size (0 = byte, 1 = short, 2 = long) */
475 FALSE
, /* pc_relative */
477 complain_overflow_dont
, /* complain_on_overflow */
478 bfd_elf_generic_reloc
, /* special_function */
479 "R_860_HIGH", /* name */
480 FALSE
, /* partial_inplace */
481 0xffff, /* src_mask */
482 0xffff, /* dst_mask */
483 FALSE
), /* pcrel_offset */
485 HOWTO (R_860_HIGOT
, /* type */
487 2, /* size (0 = byte, 1 = short, 2 = long) */
489 FALSE
, /* pc_relative */
491 complain_overflow_dont
, /* complain_on_overflow */
492 bfd_elf_generic_reloc
, /* special_function */
493 "R_860_HIGOT", /* name */
494 FALSE
, /* partial_inplace */
496 0xffff, /* dst_mask */
497 TRUE
), /* pcrel_offset */
499 HOWTO (R_860_HIGOTOFF
, /* type */
501 2, /* size (0 = byte, 1 = short, 2 = long) */
503 FALSE
, /* pc_relative */
505 complain_overflow_dont
, /* complain_on_overflow */
506 bfd_elf_generic_reloc
, /* special_function */
507 "R_860_HIGOTOFF", /* name */
508 TRUE
, /* partial_inplace */
509 0xffffffff, /* src_mask */
510 0xffffffff, /* dst_mask */
511 FALSE
), /* pcrel_offset */
514 static unsigned char elf_code_to_howto_index
[R_860_max
+ 1];
516 static reloc_howto_type
*
517 lookup_howto (unsigned int rtype
)
519 static int initialized
= 0;
521 int howto_tbl_size
= (int) (sizeof (elf32_i860_howto_table
)
522 / sizeof (elf32_i860_howto_table
[0]));
527 memset (elf_code_to_howto_index
, 0xff,
528 sizeof (elf_code_to_howto_index
));
529 for (i
= 0; i
< howto_tbl_size
; i
++)
530 elf_code_to_howto_index
[elf32_i860_howto_table
[i
].type
] = i
;
533 BFD_ASSERT (rtype
<= R_860_max
);
534 i
= elf_code_to_howto_index
[rtype
];
535 if (i
>= howto_tbl_size
)
537 return elf32_i860_howto_table
+ i
;
540 /* Given a BFD reloc, return the matching HOWTO structure. */
541 static reloc_howto_type
*
542 elf32_i860_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
543 bfd_reloc_code_real_type code
)
555 case BFD_RELOC_860_COPY
:
558 case BFD_RELOC_860_GLOB_DAT
:
559 rtype
= R_860_GLOB_DAT
;
561 case BFD_RELOC_860_JUMP_SLOT
:
562 rtype
= R_860_JUMP_SLOT
;
564 case BFD_RELOC_860_RELATIVE
:
565 rtype
= R_860_RELATIVE
;
567 case BFD_RELOC_860_PC26
:
570 case BFD_RELOC_860_PLT26
:
573 case BFD_RELOC_860_PC16
:
576 case BFD_RELOC_860_LOW0
:
579 case BFD_RELOC_860_SPLIT0
:
580 rtype
= R_860_SPLIT0
;
582 case BFD_RELOC_860_LOW1
:
585 case BFD_RELOC_860_SPLIT1
:
586 rtype
= R_860_SPLIT1
;
588 case BFD_RELOC_860_LOW2
:
591 case BFD_RELOC_860_SPLIT2
:
592 rtype
= R_860_SPLIT2
;
594 case BFD_RELOC_860_LOW3
:
597 case BFD_RELOC_860_LOGOT0
:
598 rtype
= R_860_LOGOT0
;
600 case BFD_RELOC_860_SPGOT0
:
601 rtype
= R_860_SPGOT0
;
603 case BFD_RELOC_860_LOGOT1
:
604 rtype
= R_860_LOGOT1
;
606 case BFD_RELOC_860_SPGOT1
:
607 rtype
= R_860_SPGOT1
;
609 case BFD_RELOC_860_LOGOTOFF0
:
610 rtype
= R_860_LOGOTOFF0
;
612 case BFD_RELOC_860_SPGOTOFF0
:
613 rtype
= R_860_SPGOTOFF0
;
615 case BFD_RELOC_860_LOGOTOFF1
:
616 rtype
= R_860_LOGOTOFF1
;
618 case BFD_RELOC_860_SPGOTOFF1
:
619 rtype
= R_860_SPGOTOFF1
;
621 case BFD_RELOC_860_LOGOTOFF2
:
622 rtype
= R_860_LOGOTOFF2
;
624 case BFD_RELOC_860_LOGOTOFF3
:
625 rtype
= R_860_LOGOTOFF3
;
627 case BFD_RELOC_860_LOPC
:
630 case BFD_RELOC_860_HIGHADJ
:
631 rtype
= R_860_HIGHADJ
;
633 case BFD_RELOC_860_HAGOT
:
636 case BFD_RELOC_860_HAGOTOFF
:
637 rtype
= R_860_HAGOTOFF
;
639 case BFD_RELOC_860_HAPC
:
642 case BFD_RELOC_860_HIGH
:
645 case BFD_RELOC_860_HIGOT
:
648 case BFD_RELOC_860_HIGOTOFF
:
649 rtype
= R_860_HIGOTOFF
;
655 return lookup_howto (rtype
);
658 /* Given a ELF reloc, return the matching HOWTO structure. */
660 elf32_i860_info_to_howto_rela (bfd
*abfd ATTRIBUTE_UNUSED
,
662 Elf_Internal_Rela
*elf_reloc
)
665 = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc
->r_info
));
668 /* Specialized relocation handler for R_860_SPLITn. These relocations
669 involves a 16-bit field that is split into two contiguous parts. */
670 static bfd_reloc_status_type
671 elf32_i860_relocate_splitn (bfd
*input_bfd
,
672 Elf_Internal_Rela
*rello
,
677 reloc_howto_type
*howto
;
678 howto
= lookup_howto ((unsigned) ELF32_R_TYPE (rello
->r_info
));
679 insn
= bfd_get_32 (input_bfd
, contents
+ rello
->r_offset
);
682 value
+= rello
->r_addend
;
684 /* Separate the fields and insert. */
685 value
= (((value
& 0xf800) << 5) | (value
& 0x7ff)) & howto
->dst_mask
;
686 insn
= (insn
& ~howto
->dst_mask
) | value
;
688 bfd_put_32 (input_bfd
, insn
, contents
+ rello
->r_offset
);
692 /* Specialized relocation handler for R_860_PC16. This relocation
693 involves a 16-bit, PC-relative field that is split into two contiguous
695 static bfd_reloc_status_type
696 elf32_i860_relocate_pc16 (bfd
*input_bfd
,
697 asection
*input_section
,
698 Elf_Internal_Rela
*rello
,
703 reloc_howto_type
*howto
;
704 howto
= lookup_howto ((unsigned) ELF32_R_TYPE (rello
->r_info
));
705 insn
= bfd_get_32 (input_bfd
, contents
+ rello
->r_offset
);
707 /* Adjust for PC-relative relocation. */
708 value
-= (input_section
->output_section
->vma
709 + input_section
->output_offset
);
710 value
-= rello
->r_offset
;
713 value
+= rello
->r_addend
;
715 /* Separate the fields and insert. */
716 value
= (((value
& 0xf800) << 5) | (value
& 0x7ff)) & howto
->dst_mask
;
717 insn
= (insn
& ~howto
->dst_mask
) | value
;
719 bfd_put_32 (input_bfd
, insn
, contents
+ rello
->r_offset
);
724 /* Specialized relocation handler for R_860_PC26. This relocation
725 involves a 26-bit, PC-relative field which must be adjusted by 4. */
726 static bfd_reloc_status_type
727 elf32_i860_relocate_pc26 (bfd
*input_bfd
,
728 asection
*input_section
,
729 Elf_Internal_Rela
*rello
,
734 reloc_howto_type
*howto
;
735 howto
= lookup_howto ((unsigned) ELF32_R_TYPE (rello
->r_info
));
736 insn
= bfd_get_32 (input_bfd
, contents
+ rello
->r_offset
);
738 /* Adjust for PC-relative relocation. */
739 value
-= (input_section
->output_section
->vma
740 + input_section
->output_offset
);
741 value
-= rello
->r_offset
;
744 value
+= rello
->r_addend
;
746 /* Adjust value by 4 and insert the field. */
747 value
= ((value
- 4) >> howto
->rightshift
) & howto
->dst_mask
;
748 insn
= (insn
& ~howto
->dst_mask
) | value
;
750 bfd_put_32 (input_bfd
, insn
, contents
+ rello
->r_offset
);
755 /* Specialized relocation handler for R_860_HIGHADJ. */
756 static bfd_reloc_status_type
757 elf32_i860_relocate_highadj (bfd
*input_bfd
,
758 Elf_Internal_Rela
*rel
,
764 insn
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
766 value
+= rel
->r_addend
;
768 value
= ((value
>> 16) & 0xffff);
770 insn
= (insn
& 0xffff0000) | value
;
772 bfd_put_32 (input_bfd
, insn
, contents
+ rel
->r_offset
);
776 /* Perform a single relocation. By default we use the standard BFD
777 routines. However, we handle some specially. */
778 static bfd_reloc_status_type
779 i860_final_link_relocate (reloc_howto_type
*howto
,
781 asection
*input_section
,
783 Elf_Internal_Rela
*rel
,
786 return _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
787 contents
, rel
->r_offset
, relocation
,
791 /* Relocate an i860 ELF section.
793 This is boiler-plate code copied from fr30.
795 The RELOCATE_SECTION function is called by the new ELF backend linker
796 to handle the relocations for a section.
798 The relocs are always passed as Rela structures; if the section
799 actually uses Rel structures, the r_addend field will always be
802 This function is responsible for adjusting the section contents as
803 necessary, and (if using Rela relocs and generating a relocatable
804 output file) adjusting the reloc addend as necessary.
806 This function does not have to worry about setting the reloc
807 address or the reloc symbol index.
809 LOCAL_SYMS is a pointer to the swapped in local symbols.
811 LOCAL_SECTIONS is an array giving the section in the input file
812 corresponding to the st_shndx field of each local symbol.
814 The global hash table entry for the global symbols can be found
815 via elf_sym_hashes (input_bfd).
817 When generating relocatable output, this function must handle
818 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
819 going to be the section symbol corresponding to the output
820 section, which means that the addend must be adjusted
823 elf32_i860_relocate_section (bfd
*output_bfd ATTRIBUTE_UNUSED
,
824 struct bfd_link_info
*info
,
826 asection
*input_section
,
828 Elf_Internal_Rela
*relocs
,
829 Elf_Internal_Sym
*local_syms
,
830 asection
**local_sections
)
832 Elf_Internal_Shdr
*symtab_hdr
;
833 struct elf_link_hash_entry
**sym_hashes
;
834 Elf_Internal_Rela
*rel
;
835 Elf_Internal_Rela
*relend
;
837 if (info
->relocatable
)
840 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
841 sym_hashes
= elf_sym_hashes (input_bfd
);
842 relend
= relocs
+ input_section
->reloc_count
;
844 for (rel
= relocs
; rel
< relend
; rel
++)
846 reloc_howto_type
* howto
;
847 unsigned long r_symndx
;
848 Elf_Internal_Sym
* sym
;
850 struct elf_link_hash_entry
* h
;
852 bfd_reloc_status_type r
;
853 const char * name
= NULL
;
856 r_type
= ELF32_R_TYPE (rel
->r_info
);
859 if ( r_type
== R_860_GNU_VTINHERIT
860 || r_type
== R_860_GNU_VTENTRY
)
864 r_symndx
= ELF32_R_SYM (rel
->r_info
);
866 howto
= lookup_howto ((unsigned) ELF32_R_TYPE (rel
->r_info
));
871 if (r_symndx
< symtab_hdr
->sh_info
)
873 sym
= local_syms
+ r_symndx
;
874 sec
= local_sections
[r_symndx
];
875 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sec
, rel
);
877 name
= bfd_elf_string_from_elf_section
878 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
879 name
= (name
== NULL
) ? bfd_section_name (input_bfd
, sec
) : name
;
883 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
885 while (h
->root
.type
== bfd_link_hash_indirect
886 || h
->root
.type
== bfd_link_hash_warning
)
887 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
889 name
= h
->root
.root
.string
;
891 if (h
->root
.type
== bfd_link_hash_defined
892 || h
->root
.type
== bfd_link_hash_defweak
)
894 sec
= h
->root
.u
.def
.section
;
895 relocation
= (h
->root
.u
.def
.value
896 + sec
->output_section
->vma
897 + sec
->output_offset
);
899 else if (h
->root
.type
== bfd_link_hash_undefweak
)
905 if (! ((*info
->callbacks
->undefined_symbol
)
906 (info
, h
->root
.root
.string
, input_bfd
,
907 input_section
, rel
->r_offset
, TRUE
)))
916 r
= i860_final_link_relocate (howto
, input_bfd
, input_section
,
917 contents
, rel
, relocation
);
921 r
= elf32_i860_relocate_highadj (input_bfd
, rel
, contents
,
926 r
= elf32_i860_relocate_pc16 (input_bfd
, input_section
, rel
,
927 contents
, relocation
);
931 r
= elf32_i860_relocate_pc26 (input_bfd
, input_section
, rel
,
932 contents
, relocation
);
938 r
= elf32_i860_relocate_splitn (input_bfd
, rel
, contents
,
942 /* We do not yet handle GOT/PLT/Dynamic relocations. */
945 case R_860_JUMP_SLOT
:
952 case R_860_LOGOTOFF0
:
953 case R_860_SPGOTOFF0
:
954 case R_860_LOGOTOFF1
:
955 case R_860_SPGOTOFF1
:
956 case R_860_LOGOTOFF2
:
957 case R_860_LOGOTOFF3
:
964 r
= bfd_reloc_notsupported
;
968 if (r
!= bfd_reloc_ok
)
970 const char * msg
= (const char *) NULL
;
974 case bfd_reloc_overflow
:
975 r
= info
->callbacks
->reloc_overflow
976 (info
, name
, howto
->name
, (bfd_vma
) 0,
977 input_bfd
, input_section
, rel
->r_offset
);
980 case bfd_reloc_undefined
:
981 r
= info
->callbacks
->undefined_symbol
982 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, TRUE
);
985 case bfd_reloc_outofrange
:
986 msg
= _("internal error: out of range error");
989 case bfd_reloc_notsupported
:
990 msg
= _("internal error: unsupported relocation error");
993 case bfd_reloc_dangerous
:
994 msg
= _("internal error: dangerous relocation");
998 msg
= _("internal error: unknown error");
1003 r
= info
->callbacks
->warning
1004 (info
, msg
, name
, input_bfd
, input_section
, rel
->r_offset
);
1014 /* Return whether a symbol name implies a local label. SVR4/860 compilers
1015 generate labels of the form ".ep.function_name" to denote the end of a
1016 function prolog. These should be local.
1017 ??? Do any other SVR4 compilers have this convention? If so, this should
1018 be added to the generic routine. */
1020 elf32_i860_is_local_label_name (bfd
*abfd
, const char *name
)
1022 if (name
[0] == '.' && name
[1] == 'e' && name
[2] == 'p' && name
[3] == '.')
1025 return _bfd_elf_is_local_label_name (abfd
, name
);
1028 #define TARGET_BIG_SYM bfd_elf32_i860_vec
1029 #define TARGET_BIG_NAME "elf32-i860"
1030 #define TARGET_LITTLE_SYM bfd_elf32_i860_little_vec
1031 #define TARGET_LITTLE_NAME "elf32-i860-little"
1032 #define ELF_ARCH bfd_arch_i860
1033 #define ELF_MACHINE_CODE EM_860
1034 #define ELF_MAXPAGESIZE 4096
1036 #define elf_backend_rela_normal 1
1037 #define elf_info_to_howto_rel NULL
1038 #define elf_info_to_howto elf32_i860_info_to_howto_rela
1039 #define elf_backend_relocate_section elf32_i860_relocate_section
1040 #define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
1041 #define bfd_elf32_bfd_is_local_label_name elf32_i860_is_local_label_name
1043 #include "elf32-target.h"