* elf32-frv.c (elf32_frv_relocate_section): Use
[deliverable/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 /* Adjust the value by 4, then separate the fields and insert. */
716 value = (value - 4) >> howto->rightshift;
717 value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
718 insn = (insn & ~howto->dst_mask) | value;
719
720 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
721 return bfd_reloc_ok;
722
723 }
724
725 /* Specialized relocation handler for R_860_PC26. This relocation
726 involves a 26-bit, PC-relative field which must be adjusted by 4. */
727 static bfd_reloc_status_type
728 elf32_i860_relocate_pc26 (bfd *input_bfd,
729 asection *input_section,
730 Elf_Internal_Rela *rello,
731 bfd_byte *contents,
732 bfd_vma value)
733 {
734 bfd_vma insn;
735 reloc_howto_type *howto;
736 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
737 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
738
739 /* Adjust for PC-relative relocation. */
740 value -= (input_section->output_section->vma
741 + input_section->output_offset);
742 value -= rello->r_offset;
743
744 /* Relocate. */
745 value += rello->r_addend;
746
747 /* Adjust value by 4 and insert the field. */
748 value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
749 insn = (insn & ~howto->dst_mask) | value;
750
751 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
752 return bfd_reloc_ok;
753
754 }
755
756 /* Specialized relocation handler for R_860_HIGHADJ. */
757 static bfd_reloc_status_type
758 elf32_i860_relocate_highadj (bfd *input_bfd,
759 Elf_Internal_Rela *rel,
760 bfd_byte *contents,
761 bfd_vma value)
762 {
763 bfd_vma insn;
764
765 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
766
767 value += rel->r_addend;
768 value += 0x8000;
769 value = ((value >> 16) & 0xffff);
770
771 insn = (insn & 0xffff0000) | value;
772
773 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
774 return bfd_reloc_ok;
775 }
776
777 /* Perform a single relocation. By default we use the standard BFD
778 routines. However, we handle some specially. */
779 static bfd_reloc_status_type
780 i860_final_link_relocate (reloc_howto_type *howto,
781 bfd *input_bfd,
782 asection *input_section,
783 bfd_byte *contents,
784 Elf_Internal_Rela *rel,
785 bfd_vma relocation)
786 {
787 return _bfd_final_link_relocate (howto, input_bfd, input_section,
788 contents, rel->r_offset, relocation,
789 rel->r_addend);
790 }
791
792 /* Relocate an i860 ELF section.
793
794 This is boiler-plate code copied from fr30.
795
796 The RELOCATE_SECTION function is called by the new ELF backend linker
797 to handle the relocations for a section.
798
799 The relocs are always passed as Rela structures; if the section
800 actually uses Rel structures, the r_addend field will always be
801 zero.
802
803 This function is responsible for adjusting the section contents as
804 necessary, and (if using Rela relocs and generating a relocatable
805 output file) adjusting the reloc addend as necessary.
806
807 This function does not have to worry about setting the reloc
808 address or the reloc symbol index.
809
810 LOCAL_SYMS is a pointer to the swapped in local symbols.
811
812 LOCAL_SECTIONS is an array giving the section in the input file
813 corresponding to the st_shndx field of each local symbol.
814
815 The global hash table entry for the global symbols can be found
816 via elf_sym_hashes (input_bfd).
817
818 When generating relocatable output, this function must handle
819 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
820 going to be the section symbol corresponding to the output
821 section, which means that the addend must be adjusted
822 accordingly. */
823 static bfd_boolean
824 elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
825 struct bfd_link_info *info,
826 bfd *input_bfd,
827 asection *input_section,
828 bfd_byte *contents,
829 Elf_Internal_Rela *relocs,
830 Elf_Internal_Sym *local_syms,
831 asection **local_sections)
832 {
833 Elf_Internal_Shdr *symtab_hdr;
834 struct elf_link_hash_entry **sym_hashes;
835 Elf_Internal_Rela *rel;
836 Elf_Internal_Rela *relend;
837
838 if (info->relocatable)
839 return TRUE;
840
841 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
842 sym_hashes = elf_sym_hashes (input_bfd);
843 relend = relocs + input_section->reloc_count;
844
845 for (rel = relocs; rel < relend; rel ++)
846 {
847 reloc_howto_type * howto;
848 unsigned long r_symndx;
849 Elf_Internal_Sym * sym;
850 asection * sec;
851 struct elf_link_hash_entry * h;
852 bfd_vma relocation;
853 bfd_reloc_status_type r;
854 const char * name = NULL;
855 int r_type;
856
857 r_type = ELF32_R_TYPE (rel->r_info);
858
859 #if 0
860 if ( r_type == R_860_GNU_VTINHERIT
861 || r_type == R_860_GNU_VTENTRY)
862 continue;
863 #endif
864
865 r_symndx = ELF32_R_SYM (rel->r_info);
866
867 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
868 h = NULL;
869 sym = NULL;
870 sec = NULL;
871
872 if (r_symndx < symtab_hdr->sh_info)
873 {
874 sym = local_syms + r_symndx;
875 sec = local_sections [r_symndx];
876 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
877
878 name = bfd_elf_string_from_elf_section
879 (input_bfd, symtab_hdr->sh_link, sym->st_name);
880 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
881 }
882 else
883 {
884 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
885
886 while (h->root.type == bfd_link_hash_indirect
887 || h->root.type == bfd_link_hash_warning)
888 h = (struct elf_link_hash_entry *) h->root.u.i.link;
889
890 name = h->root.root.string;
891
892 if (h->root.type == bfd_link_hash_defined
893 || h->root.type == bfd_link_hash_defweak)
894 {
895 sec = h->root.u.def.section;
896 relocation = (h->root.u.def.value
897 + sec->output_section->vma
898 + sec->output_offset);
899 }
900 else if (h->root.type == bfd_link_hash_undefweak)
901 {
902 relocation = 0;
903 }
904 else
905 {
906 if (! ((*info->callbacks->undefined_symbol)
907 (info, h->root.root.string, input_bfd,
908 input_section, rel->r_offset, TRUE)))
909 return FALSE;
910 relocation = 0;
911 }
912 }
913
914 switch (r_type)
915 {
916 default:
917 r = i860_final_link_relocate (howto, input_bfd, input_section,
918 contents, rel, relocation);
919 break;
920
921 case R_860_HIGHADJ:
922 r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
923 relocation);
924 break;
925
926 case R_860_PC16:
927 r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
928 contents, relocation);
929 break;
930
931 case R_860_PC26:
932 r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
933 contents, relocation);
934 break;
935
936 case R_860_SPLIT0:
937 case R_860_SPLIT1:
938 case R_860_SPLIT2:
939 r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
940 relocation);
941 break;
942
943 /* We do not yet handle GOT/PLT/Dynamic relocations. */
944 case R_860_COPY:
945 case R_860_GLOB_DAT:
946 case R_860_JUMP_SLOT:
947 case R_860_RELATIVE:
948 case R_860_PLT26:
949 case R_860_LOGOT0:
950 case R_860_SPGOT0:
951 case R_860_LOGOT1:
952 case R_860_SPGOT1:
953 case R_860_LOGOTOFF0:
954 case R_860_SPGOTOFF0:
955 case R_860_LOGOTOFF1:
956 case R_860_SPGOTOFF1:
957 case R_860_LOGOTOFF2:
958 case R_860_LOGOTOFF3:
959 case R_860_LOPC:
960 case R_860_HAGOT:
961 case R_860_HAGOTOFF:
962 case R_860_HAPC:
963 case R_860_HIGOT:
964 case R_860_HIGOTOFF:
965 r = bfd_reloc_notsupported;
966 break;
967 }
968
969 if (r != bfd_reloc_ok)
970 {
971 const char * msg = (const char *) NULL;
972
973 switch (r)
974 {
975 case bfd_reloc_overflow:
976 r = info->callbacks->reloc_overflow
977 (info, name, howto->name, (bfd_vma) 0,
978 input_bfd, input_section, rel->r_offset);
979 break;
980
981 case bfd_reloc_undefined:
982 r = info->callbacks->undefined_symbol
983 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
984 break;
985
986 case bfd_reloc_outofrange:
987 msg = _("internal error: out of range error");
988 break;
989
990 case bfd_reloc_notsupported:
991 msg = _("internal error: unsupported relocation error");
992 break;
993
994 case bfd_reloc_dangerous:
995 msg = _("internal error: dangerous relocation");
996 break;
997
998 default:
999 msg = _("internal error: unknown error");
1000 break;
1001 }
1002
1003 if (msg)
1004 r = info->callbacks->warning
1005 (info, msg, name, input_bfd, input_section, rel->r_offset);
1006
1007 if (! r)
1008 return FALSE;
1009 }
1010 }
1011
1012 return TRUE;
1013 }
1014
1015 /* Return whether a symbol name implies a local label. SVR4/860 compilers
1016 generate labels of the form ".ep.function_name" to denote the end of a
1017 function prolog. These should be local.
1018 ??? Do any other SVR4 compilers have this convention? If so, this should
1019 be added to the generic routine. */
1020 static bfd_boolean
1021 elf32_i860_is_local_label_name (bfd *abfd, const char *name)
1022 {
1023 if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1024 return TRUE;
1025
1026 return _bfd_elf_is_local_label_name (abfd, name);
1027 }
1028 \f
1029 #define TARGET_BIG_SYM bfd_elf32_i860_vec
1030 #define TARGET_BIG_NAME "elf32-i860"
1031 #define TARGET_LITTLE_SYM bfd_elf32_i860_little_vec
1032 #define TARGET_LITTLE_NAME "elf32-i860-little"
1033 #define ELF_ARCH bfd_arch_i860
1034 #define ELF_MACHINE_CODE EM_860
1035 #define ELF_MAXPAGESIZE 4096
1036
1037 #define elf_backend_rela_normal 1
1038 #define elf_info_to_howto_rel NULL
1039 #define elf_info_to_howto elf32_i860_info_to_howto_rela
1040 #define elf_backend_relocate_section elf32_i860_relocate_section
1041 #define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
1042 #define bfd_elf32_bfd_is_local_label_name elf32_i860_is_local_label_name
1043
1044 #include "elf32-target.h"
This page took 0.063959 seconds and 5 git commands to generate.