bfd:
[binutils-gdb.git] / bfd / elf32-i860.c
1 /* Intel i860 specific support for 32-bit ELF.
2 Copyright 1993, 1995, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4
5 Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
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.
13
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.
18
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. */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "elf/i860.h"
28
29
30 /* This howto table is preliminary. */
31 static reloc_howto_type elf32_i860_howto_table [] =
32 {
33 /* This relocation does nothing. */
34 HOWTO (R_860_NONE, /* type */
35 0, /* rightshift */
36 2, /* size (0 = byte, 1 = short, 2 = long) */
37 32, /* bitsize */
38 FALSE, /* pc_relative */
39 0, /* bitpos */
40 complain_overflow_bitfield, /* complain_on_overflow */
41 bfd_elf_generic_reloc, /* special_function */
42 "R_860_NONE", /* name */
43 FALSE, /* partial_inplace */
44 0, /* src_mask */
45 0, /* dst_mask */
46 FALSE), /* pcrel_offset */
47
48 /* A 32-bit absolute relocation. */
49 HOWTO (R_860_32, /* type */
50 0, /* rightshift */
51 2, /* size (0 = byte, 1 = short, 2 = long) */
52 32, /* bitsize */
53 FALSE, /* pc_relative */
54 0, /* bitpos */
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 */
62
63 HOWTO (R_860_COPY, /* type */
64 0, /* rightshift */
65 2, /* size (0 = byte, 1 = short, 2 = long) */
66 32, /* bitsize */
67 FALSE, /* pc_relative */
68 0, /* bitpos */
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 */
76
77 HOWTO (R_860_GLOB_DAT, /* type */
78 0, /* rightshift */
79 2, /* size (0 = byte, 1 = short, 2 = long) */
80 32, /* bitsize */
81 FALSE, /* pc_relative */
82 0, /* bitpos */
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 */
90
91 HOWTO (R_860_JUMP_SLOT, /* type */
92 0, /* rightshift */
93 2, /* size (0 = byte, 1 = short, 2 = long) */
94 32, /* bitsize */
95 FALSE, /* pc_relative */
96 0, /* bitpos */
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 */
104
105 HOWTO (R_860_RELATIVE, /* type */
106 0, /* rightshift */
107 2, /* size (0 = byte, 1 = short, 2 = long) */
108 32, /* bitsize */
109 FALSE, /* pc_relative */
110 0, /* bitpos */
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 */
118
119 /* A 26-bit PC-relative relocation. */
120 HOWTO (R_860_PC26, /* type */
121 2, /* rightshift */
122 2, /* size (0 = byte, 1 = short, 2 = long) */
123 26, /* bitsize */
124 TRUE, /* pc_relative */
125 0, /* bitpos */
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 */
133
134 HOWTO (R_860_PLT26, /* type */
135 0, /* rightshift */
136 2, /* size (0 = byte, 1 = short, 2 = long) */
137 26, /* bitsize */
138 TRUE, /* pc_relative */
139 0, /* bitpos */
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 */
147
148 /* A 16-bit PC-relative relocation. */
149 HOWTO (R_860_PC16, /* type */
150 2, /* rightshift */
151 2, /* size (0 = byte, 1 = short, 2 = long) */
152 16, /* bitsize */
153 TRUE, /* pc_relative */
154 0, /* bitpos */
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 */
162
163 HOWTO (R_860_LOW0, /* type */
164 0, /* rightshift */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
166 16, /* bitsize */
167 FALSE, /* pc_relative */
168 0, /* bitpos */
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 */
176
177 HOWTO (R_860_SPLIT0, /* type */
178 0, /* rightshift */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
180 16, /* bitsize */
181 FALSE, /* pc_relative */
182 0, /* bitpos */
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 */
190
191 HOWTO (R_860_LOW1, /* type */
192 0, /* rightshift */
193 2, /* size (0 = byte, 1 = short, 2 = long) */
194 16, /* bitsize */
195 FALSE, /* pc_relative */
196 0, /* bitpos */
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 */
204
205 HOWTO (R_860_SPLIT1, /* type */
206 0, /* rightshift */
207 2, /* size (0 = byte, 1 = short, 2 = long) */
208 16, /* bitsize */
209 FALSE, /* pc_relative */
210 0, /* bitpos */
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 */
218
219 HOWTO (R_860_LOW2, /* type */
220 0, /* rightshift */
221 2, /* size (0 = byte, 1 = short, 2 = long) */
222 16, /* bitsize */
223 FALSE, /* pc_relative */
224 0, /* bitpos */
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 */
232
233 HOWTO (R_860_SPLIT2, /* type */
234 0, /* rightshift */
235 2, /* size (0 = byte, 1 = short, 2 = long) */
236 16, /* bitsize */
237 FALSE, /* pc_relative */
238 0, /* bitpos */
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 */
246
247 HOWTO (R_860_LOW3, /* type */
248 0, /* rightshift */
249 2, /* size (0 = byte, 1 = short, 2 = long) */
250 16, /* bitsize */
251 FALSE, /* pc_relative */
252 0, /* bitpos */
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 */
260
261 HOWTO (R_860_LOGOT0, /* type */
262 0, /* rightshift */
263 2, /* size (0 = byte, 1 = short, 2 = long) */
264 16, /* bitsize */
265 FALSE, /* pc_relative */
266 0, /* bitpos */
267 complain_overflow_dont, /* complain_on_overflow */
268 bfd_elf_generic_reloc, /* special_function */
269 "R_860_LOGOT0", /* name */
270 FALSE, /* partial_inplace */
271 0, /* src_mask */
272 0xffff, /* dst_mask */
273 TRUE), /* pcrel_offset */
274
275 HOWTO (R_860_SPGOT0, /* type */
276 0, /* rightshift */
277 2, /* size (0 = byte, 1 = short, 2 = long) */
278 16, /* bitsize */
279 FALSE, /* pc_relative */
280 0, /* bitpos */
281 complain_overflow_dont, /* complain_on_overflow */
282 bfd_elf_generic_reloc, /* special_function */
283 "R_860_SPGOT0", /* name */
284 FALSE, /* partial_inplace */
285 0, /* src_mask */
286 0xffff, /* dst_mask */
287 TRUE), /* pcrel_offset */
288
289 HOWTO (R_860_LOGOT1, /* type */
290 0, /* rightshift */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
292 16, /* bitsize */
293 FALSE, /* pc_relative */
294 0, /* bitpos */
295 complain_overflow_dont, /* complain_on_overflow */
296 bfd_elf_generic_reloc, /* special_function */
297 "R_860_LOGOT1", /* name */
298 FALSE, /* partial_inplace */
299 0, /* src_mask */
300 0xffff, /* dst_mask */
301 TRUE), /* pcrel_offset */
302
303 HOWTO (R_860_SPGOT1, /* type */
304 0, /* rightshift */
305 2, /* size (0 = byte, 1 = short, 2 = long) */
306 16, /* bitsize */
307 FALSE, /* pc_relative */
308 0, /* bitpos */
309 complain_overflow_dont, /* complain_on_overflow */
310 bfd_elf_generic_reloc, /* special_function */
311 "R_860_SPGOT1", /* name */
312 FALSE, /* partial_inplace */
313 0, /* src_mask */
314 0xffff, /* dst_mask */
315 TRUE), /* pcrel_offset */
316
317 HOWTO (R_860_LOGOTOFF0, /* type */
318 0, /* rightshift */
319 2, /* size (0 = byte, 1 = short, 2 = long) */
320 32, /* bitsize */
321 FALSE, /* pc_relative */
322 0, /* bitpos */
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 */
330
331 HOWTO (R_860_SPGOTOFF0, /* type */
332 0, /* rightshift */
333 2, /* size (0 = byte, 1 = short, 2 = long) */
334 32, /* bitsize */
335 FALSE, /* pc_relative */
336 0, /* bitpos */
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 */
344
345 HOWTO (R_860_LOGOTOFF1, /* type */
346 0, /* rightshift */
347 2, /* size (0 = byte, 1 = short, 2 = long) */
348 32, /* bitsize */
349 FALSE, /* pc_relative */
350 0, /* bitpos */
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 */
358
359 HOWTO (R_860_SPGOTOFF1, /* type */
360 0, /* rightshift */
361 2, /* size (0 = byte, 1 = short, 2 = long) */
362 32, /* bitsize */
363 FALSE, /* pc_relative */
364 0, /* bitpos */
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 */
372
373 HOWTO (R_860_LOGOTOFF2, /* type */
374 0, /* rightshift */
375 2, /* size (0 = byte, 1 = short, 2 = long) */
376 32, /* bitsize */
377 FALSE, /* pc_relative */
378 0, /* bitpos */
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 */
386
387 HOWTO (R_860_LOGOTOFF3, /* type */
388 0, /* rightshift */
389 2, /* size (0 = byte, 1 = short, 2 = long) */
390 32, /* bitsize */
391 FALSE, /* pc_relative */
392 0, /* bitpos */
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 */
400
401 HOWTO (R_860_LOPC, /* type */
402 0, /* rightshift */
403 2, /* size (0 = byte, 1 = short, 2 = long) */
404 16, /* bitsize */
405 TRUE, /* pc_relative */
406 0, /* bitpos */
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 */
414
415 HOWTO (R_860_HIGHADJ, /* type */
416 0, /* rightshift */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
418 16, /* bitsize */
419 FALSE, /* pc_relative */
420 0, /* bitpos */
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 */
428
429 HOWTO (R_860_HAGOT, /* type */
430 0, /* rightshift */
431 2, /* size (0 = byte, 1 = short, 2 = long) */
432 16, /* bitsize */
433 FALSE, /* pc_relative */
434 0, /* bitpos */
435 complain_overflow_dont, /* complain_on_overflow */
436 bfd_elf_generic_reloc, /* special_function */
437 "R_860_HAGOT", /* name */
438 FALSE, /* partial_inplace */
439 0, /* src_mask */
440 0xffff, /* dst_mask */
441 TRUE), /* pcrel_offset */
442
443 HOWTO (R_860_HAGOTOFF, /* type */
444 0, /* rightshift */
445 2, /* size (0 = byte, 1 = short, 2 = long) */
446 32, /* bitsize */
447 FALSE, /* pc_relative */
448 0, /* bitpos */
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 */
456
457 HOWTO (R_860_HAPC, /* type */
458 0, /* rightshift */
459 2, /* size (0 = byte, 1 = short, 2 = long) */
460 16, /* bitsize */
461 TRUE, /* pc_relative */
462 0, /* bitpos */
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 */
470
471 HOWTO (R_860_HIGH, /* type */
472 16, /* rightshift */
473 2, /* size (0 = byte, 1 = short, 2 = long) */
474 16, /* bitsize */
475 FALSE, /* pc_relative */
476 0, /* bitpos */
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 */
484
485 HOWTO (R_860_HIGOT, /* type */
486 0, /* rightshift */
487 2, /* size (0 = byte, 1 = short, 2 = long) */
488 16, /* bitsize */
489 FALSE, /* pc_relative */
490 0, /* bitpos */
491 complain_overflow_dont, /* complain_on_overflow */
492 bfd_elf_generic_reloc, /* special_function */
493 "R_860_HIGOT", /* name */
494 FALSE, /* partial_inplace */
495 0, /* src_mask */
496 0xffff, /* dst_mask */
497 TRUE), /* pcrel_offset */
498
499 HOWTO (R_860_HIGOTOFF, /* type */
500 0, /* rightshift */
501 2, /* size (0 = byte, 1 = short, 2 = long) */
502 32, /* bitsize */
503 FALSE, /* pc_relative */
504 0, /* bitpos */
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 */
512 };
513 \f
514 static unsigned char elf_code_to_howto_index[R_860_max + 1];
515
516 static reloc_howto_type *
517 lookup_howto (unsigned int rtype)
518 {
519 static int initialized = 0;
520 int i;
521 int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
522 / sizeof (elf32_i860_howto_table[0]));
523
524 if (! initialized)
525 {
526 initialized = 1;
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;
531 }
532
533 BFD_ASSERT (rtype <= R_860_max);
534 i = elf_code_to_howto_index[rtype];
535 if (i >= howto_tbl_size)
536 return 0;
537 return elf32_i860_howto_table + i;
538 }
539
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)
544 {
545 unsigned int rtype;
546
547 switch (code)
548 {
549 case BFD_RELOC_NONE:
550 rtype = R_860_NONE;
551 break;
552 case BFD_RELOC_32:
553 rtype = R_860_32;
554 break;
555 case BFD_RELOC_860_COPY:
556 rtype = R_860_COPY;
557 break;
558 case BFD_RELOC_860_GLOB_DAT:
559 rtype = R_860_GLOB_DAT;
560 break;
561 case BFD_RELOC_860_JUMP_SLOT:
562 rtype = R_860_JUMP_SLOT;
563 break;
564 case BFD_RELOC_860_RELATIVE:
565 rtype = R_860_RELATIVE;
566 break;
567 case BFD_RELOC_860_PC26:
568 rtype = R_860_PC26;
569 break;
570 case BFD_RELOC_860_PLT26:
571 rtype = R_860_PLT26;
572 break;
573 case BFD_RELOC_860_PC16:
574 rtype = R_860_PC16;
575 break;
576 case BFD_RELOC_860_LOW0:
577 rtype = R_860_LOW0;
578 break;
579 case BFD_RELOC_860_SPLIT0:
580 rtype = R_860_SPLIT0;
581 break;
582 case BFD_RELOC_860_LOW1:
583 rtype = R_860_LOW1;
584 break;
585 case BFD_RELOC_860_SPLIT1:
586 rtype = R_860_SPLIT1;
587 break;
588 case BFD_RELOC_860_LOW2:
589 rtype = R_860_LOW2;
590 break;
591 case BFD_RELOC_860_SPLIT2:
592 rtype = R_860_SPLIT2;
593 break;
594 case BFD_RELOC_860_LOW3:
595 rtype = R_860_LOW3;
596 break;
597 case BFD_RELOC_860_LOGOT0:
598 rtype = R_860_LOGOT0;
599 break;
600 case BFD_RELOC_860_SPGOT0:
601 rtype = R_860_SPGOT0;
602 break;
603 case BFD_RELOC_860_LOGOT1:
604 rtype = R_860_LOGOT1;
605 break;
606 case BFD_RELOC_860_SPGOT1:
607 rtype = R_860_SPGOT1;
608 break;
609 case BFD_RELOC_860_LOGOTOFF0:
610 rtype = R_860_LOGOTOFF0;
611 break;
612 case BFD_RELOC_860_SPGOTOFF0:
613 rtype = R_860_SPGOTOFF0;
614 break;
615 case BFD_RELOC_860_LOGOTOFF1:
616 rtype = R_860_LOGOTOFF1;
617 break;
618 case BFD_RELOC_860_SPGOTOFF1:
619 rtype = R_860_SPGOTOFF1;
620 break;
621 case BFD_RELOC_860_LOGOTOFF2:
622 rtype = R_860_LOGOTOFF2;
623 break;
624 case BFD_RELOC_860_LOGOTOFF3:
625 rtype = R_860_LOGOTOFF3;
626 break;
627 case BFD_RELOC_860_LOPC:
628 rtype = R_860_LOPC;
629 break;
630 case BFD_RELOC_860_HIGHADJ:
631 rtype = R_860_HIGHADJ;
632 break;
633 case BFD_RELOC_860_HAGOT:
634 rtype = R_860_HAGOT;
635 break;
636 case BFD_RELOC_860_HAGOTOFF:
637 rtype = R_860_HAGOTOFF;
638 break;
639 case BFD_RELOC_860_HAPC:
640 rtype = R_860_HAPC;
641 break;
642 case BFD_RELOC_860_HIGH:
643 rtype = R_860_HIGH;
644 break;
645 case BFD_RELOC_860_HIGOT:
646 rtype = R_860_HIGOT;
647 break;
648 case BFD_RELOC_860_HIGOTOFF:
649 rtype = R_860_HIGOTOFF;
650 break;
651 default:
652 rtype = 0;
653 break;
654 }
655 return lookup_howto (rtype);
656 }
657
658 /* Given a ELF reloc, return the matching HOWTO structure. */
659 static void
660 elf32_i860_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
661 arelent *bfd_reloc,
662 Elf_Internal_Rela *elf_reloc)
663 {
664 bfd_reloc->howto
665 = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc->r_info));
666 }
667 \f
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,
673 bfd_byte *contents,
674 bfd_vma value)
675 {
676 bfd_vma insn;
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);
680
681 /* Relocate. */
682 value += rello->r_addend;
683
684 /* Separate the fields and insert. */
685 value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
686 insn = (insn & ~howto->dst_mask) | value;
687
688 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
689 return bfd_reloc_ok;
690 }
691
692 /* Specialized relocation handler for R_860_PC16. This relocation
693 involves a 16-bit, PC-relative field that is split into two contiguous
694 parts. */
695 static bfd_reloc_status_type
696 elf32_i860_relocate_pc16 (bfd *input_bfd,
697 asection *input_section,
698 Elf_Internal_Rela *rello,
699 bfd_byte *contents,
700 bfd_vma value)
701 {
702 bfd_vma insn;
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);
706
707 /* Adjust for PC-relative relocation. */
708 value -= (input_section->output_section->vma
709 + input_section->output_offset);
710 value -= rello->r_offset;
711
712 /* Relocate. */
713 value += rello->r_addend;
714
715 /* Separate the fields and insert. */
716 value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
717 insn = (insn & ~howto->dst_mask) | value;
718
719 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
720 return bfd_reloc_ok;
721
722 }
723
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,
730 bfd_byte *contents,
731 bfd_vma value)
732 {
733 bfd_vma insn;
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);
737
738 /* Adjust for PC-relative relocation. */
739 value -= (input_section->output_section->vma
740 + input_section->output_offset);
741 value -= rello->r_offset;
742
743 /* Relocate. */
744 value += rello->r_addend;
745
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;
749
750 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
751 return bfd_reloc_ok;
752
753 }
754
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,
759 bfd_byte *contents,
760 bfd_vma value)
761 {
762 bfd_vma insn;
763
764 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
765
766 value += rel->r_addend;
767 value += 0x8000;
768 value = ((value >> 16) & 0xffff);
769
770 insn = (insn & 0xffff0000) | value;
771
772 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
773 return bfd_reloc_ok;
774 }
775
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,
780 bfd *input_bfd,
781 asection *input_section,
782 bfd_byte *contents,
783 Elf_Internal_Rela *rel,
784 bfd_vma relocation)
785 {
786 return _bfd_final_link_relocate (howto, input_bfd, input_section,
787 contents, rel->r_offset, relocation,
788 rel->r_addend);
789 }
790
791 /* Relocate an i860 ELF section.
792
793 This is boiler-plate code copied from fr30.
794
795 The RELOCATE_SECTION function is called by the new ELF backend linker
796 to handle the relocations for a section.
797
798 The relocs are always passed as Rela structures; if the section
799 actually uses Rel structures, the r_addend field will always be
800 zero.
801
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.
805
806 This function does not have to worry about setting the reloc
807 address or the reloc symbol index.
808
809 LOCAL_SYMS is a pointer to the swapped in local symbols.
810
811 LOCAL_SECTIONS is an array giving the section in the input file
812 corresponding to the st_shndx field of each local symbol.
813
814 The global hash table entry for the global symbols can be found
815 via elf_sym_hashes (input_bfd).
816
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
821 accordingly. */
822 static bfd_boolean
823 elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
824 struct bfd_link_info *info,
825 bfd *input_bfd,
826 asection *input_section,
827 bfd_byte *contents,
828 Elf_Internal_Rela *relocs,
829 Elf_Internal_Sym *local_syms,
830 asection **local_sections)
831 {
832 Elf_Internal_Shdr *symtab_hdr;
833 struct elf_link_hash_entry **sym_hashes;
834 Elf_Internal_Rela *rel;
835 Elf_Internal_Rela *relend;
836
837 if (info->relocatable)
838 return TRUE;
839
840 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
841 sym_hashes = elf_sym_hashes (input_bfd);
842 relend = relocs + input_section->reloc_count;
843
844 for (rel = relocs; rel < relend; rel ++)
845 {
846 reloc_howto_type * howto;
847 unsigned long r_symndx;
848 Elf_Internal_Sym * sym;
849 asection * sec;
850 struct elf_link_hash_entry * h;
851 bfd_vma relocation;
852 bfd_reloc_status_type r;
853 const char * name = NULL;
854 int r_type;
855
856 r_type = ELF32_R_TYPE (rel->r_info);
857
858 #if 0
859 if ( r_type == R_860_GNU_VTINHERIT
860 || r_type == R_860_GNU_VTENTRY)
861 continue;
862 #endif
863
864 r_symndx = ELF32_R_SYM (rel->r_info);
865
866 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
867 h = NULL;
868 sym = NULL;
869 sec = NULL;
870
871 if (r_symndx < symtab_hdr->sh_info)
872 {
873 sym = local_syms + r_symndx;
874 sec = local_sections [r_symndx];
875 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
876
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;
880 }
881 else
882 {
883 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
884
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;
888
889 name = h->root.root.string;
890
891 if (h->root.type == bfd_link_hash_defined
892 || h->root.type == bfd_link_hash_defweak)
893 {
894 sec = h->root.u.def.section;
895 relocation = (h->root.u.def.value
896 + sec->output_section->vma
897 + sec->output_offset);
898 }
899 else if (h->root.type == bfd_link_hash_undefweak)
900 {
901 relocation = 0;
902 }
903 else
904 {
905 if (! ((*info->callbacks->undefined_symbol)
906 (info, h->root.root.string, input_bfd,
907 input_section, rel->r_offset, TRUE)))
908 return FALSE;
909 relocation = 0;
910 }
911 }
912
913 switch (r_type)
914 {
915 default:
916 r = i860_final_link_relocate (howto, input_bfd, input_section,
917 contents, rel, relocation);
918 break;
919
920 case R_860_HIGHADJ:
921 r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
922 relocation);
923 break;
924
925 case R_860_PC16:
926 r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
927 contents, relocation);
928 break;
929
930 case R_860_PC26:
931 r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
932 contents, relocation);
933 break;
934
935 case R_860_SPLIT0:
936 case R_860_SPLIT1:
937 case R_860_SPLIT2:
938 r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
939 relocation);
940 break;
941
942 /* We do not yet handle GOT/PLT/Dynamic relocations. */
943 case R_860_COPY:
944 case R_860_GLOB_DAT:
945 case R_860_JUMP_SLOT:
946 case R_860_RELATIVE:
947 case R_860_PLT26:
948 case R_860_LOGOT0:
949 case R_860_SPGOT0:
950 case R_860_LOGOT1:
951 case R_860_SPGOT1:
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:
958 case R_860_LOPC:
959 case R_860_HAGOT:
960 case R_860_HAGOTOFF:
961 case R_860_HAPC:
962 case R_860_HIGOT:
963 case R_860_HIGOTOFF:
964 r = bfd_reloc_notsupported;
965 break;
966 }
967
968 if (r != bfd_reloc_ok)
969 {
970 const char * msg = (const char *) NULL;
971
972 switch (r)
973 {
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);
978 break;
979
980 case bfd_reloc_undefined:
981 r = info->callbacks->undefined_symbol
982 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
983 break;
984
985 case bfd_reloc_outofrange:
986 msg = _("internal error: out of range error");
987 break;
988
989 case bfd_reloc_notsupported:
990 msg = _("internal error: unsupported relocation error");
991 break;
992
993 case bfd_reloc_dangerous:
994 msg = _("internal error: dangerous relocation");
995 break;
996
997 default:
998 msg = _("internal error: unknown error");
999 break;
1000 }
1001
1002 if (msg)
1003 r = info->callbacks->warning
1004 (info, msg, name, input_bfd, input_section, rel->r_offset);
1005
1006 if (! r)
1007 return FALSE;
1008 }
1009 }
1010
1011 return TRUE;
1012 }
1013
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. */
1019 static bfd_boolean
1020 elf32_i860_is_local_label_name (bfd *abfd, const char *name)
1021 {
1022 if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1023 return TRUE;
1024
1025 return _bfd_elf_is_local_label_name (abfd, name);
1026 }
1027 \f
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
1035
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
1042
1043 #include "elf32-target.h"