2000-12-05 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / bfd / elf32-i860.c
1 /* Intel i860 specific support for 32-bit ELF.
2 Copyright 1993, 2000 Free Software Foundation, Inc.
3
4 Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
5
6 This file is part of BFD, the Binary File Descriptor library.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 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"
26 #include "elf/i860.h"
27
28 /* Prototypes. */
29 static reloc_howto_type *lookup_howto
30 PARAMS ((unsigned int));
31
32 static reloc_howto_type *elf32_i860_reloc_type_lookup
33 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
34
35 static void elf32_i860_info_to_howto_rela
36 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
37
38 static bfd_reloc_status_type elf32_i860_relocate_splitn
39 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
40
41 static bfd_reloc_status_type elf32_i860_relocate_pc16
42 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
43
44 static bfd_reloc_status_type elf32_i860_relocate_pc26
45 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
46
47 static bfd_reloc_status_type elf32_i860_relocate_highadj
48 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
49
50 static boolean elf32_i860_relocate_section
51 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
52 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
53
54 static bfd_reloc_status_type i860_final_link_relocate
55 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
56 Elf_Internal_Rela *, bfd_vma));
57
58 static boolean elf32_i860_is_local_label_name
59 PARAMS ((bfd *, const char *));
60
61 /* This howto table is preliminary. */
62 static 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 */
152 2, /* rightshift */
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 */
181 2, /* rightshift */
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 */
190 0x1f07ff, /* src_mask */
191 0x1f07ff, /* dst_mask */
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 */
246 0x1f07fe, /* src_mask */
247 0x1f07fe, /* dst_mask */
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 */
274 0x1f07fc, /* src_mask */
275 0x1f07fc, /* dst_mask */
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 */
503 16, /* rightshift */
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
546 static unsigned char elf_code_to_howto_index[R_860_max + 1];
547
548 static reloc_howto_type *
549 lookup_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 /* Given a BFD reloc, return the matching HOWTO structure. */
574 static reloc_howto_type *
575 elf32_i860_reloc_type_lookup (abfd, code)
576 bfd * abfd ATTRIBUTE_UNUSED;
577 bfd_reloc_code_real_type code;
578 {
579 unsigned int rtype;
580
581 switch (code)
582 {
583 case BFD_RELOC_NONE:
584 rtype = R_860_NONE;
585 break;
586 case BFD_RELOC_32:
587 rtype = R_860_32;
588 break;
589 case BFD_RELOC_860_COPY:
590 rtype = R_860_COPY;
591 break;
592 case BFD_RELOC_860_GLOB_DAT:
593 rtype = R_860_GLOB_DAT;
594 break;
595 case BFD_RELOC_860_JUMP_SLOT:
596 rtype = R_860_JUMP_SLOT;
597 break;
598 case BFD_RELOC_860_RELATIVE:
599 rtype = R_860_RELATIVE;
600 break;
601 case BFD_RELOC_860_PC26:
602 rtype = R_860_PC26;
603 break;
604 case BFD_RELOC_860_PLT26:
605 rtype = R_860_PLT26;
606 break;
607 case BFD_RELOC_860_PC16:
608 rtype = R_860_PC16;
609 break;
610 case BFD_RELOC_860_LOW0:
611 rtype = R_860_LOW0;
612 break;
613 case BFD_RELOC_860_SPLIT0:
614 rtype = R_860_SPLIT0;
615 break;
616 case BFD_RELOC_860_LOW1:
617 rtype = R_860_LOW1;
618 break;
619 case BFD_RELOC_860_SPLIT1:
620 rtype = R_860_SPLIT1;
621 break;
622 case BFD_RELOC_860_LOW2:
623 rtype = R_860_LOW2;
624 break;
625 case BFD_RELOC_860_SPLIT2:
626 rtype = R_860_SPLIT2;
627 break;
628 case BFD_RELOC_860_LOW3:
629 rtype = R_860_LOW3;
630 break;
631 case BFD_RELOC_860_LOGOT0:
632 rtype = R_860_LOGOT0;
633 break;
634 case BFD_RELOC_860_SPGOT0:
635 rtype = R_860_SPGOT0;
636 break;
637 case BFD_RELOC_860_LOGOT1:
638 rtype = R_860_LOGOT1;
639 break;
640 case BFD_RELOC_860_SPGOT1:
641 rtype = R_860_SPGOT1;
642 break;
643 case BFD_RELOC_860_LOGOTOFF0:
644 rtype = R_860_LOGOTOFF0;
645 break;
646 case BFD_RELOC_860_SPGOTOFF0:
647 rtype = R_860_SPGOTOFF0;
648 break;
649 case BFD_RELOC_860_LOGOTOFF1:
650 rtype = R_860_LOGOTOFF1;
651 break;
652 case BFD_RELOC_860_SPGOTOFF1:
653 rtype = R_860_SPGOTOFF1;
654 break;
655 case BFD_RELOC_860_LOGOTOFF2:
656 rtype = R_860_LOGOTOFF2;
657 break;
658 case BFD_RELOC_860_LOGOTOFF3:
659 rtype = R_860_LOGOTOFF3;
660 break;
661 case BFD_RELOC_860_LOPC:
662 rtype = R_860_LOPC;
663 break;
664 case BFD_RELOC_860_HIGHADJ:
665 rtype = R_860_HIGHADJ;
666 break;
667 case BFD_RELOC_860_HAGOT:
668 rtype = R_860_HAGOT;
669 break;
670 case BFD_RELOC_860_HAGOTOFF:
671 rtype = R_860_HAGOTOFF;
672 break;
673 case BFD_RELOC_860_HAPC:
674 rtype = R_860_HAPC;
675 break;
676 case BFD_RELOC_860_HIGH:
677 rtype = R_860_HIGH;
678 break;
679 case BFD_RELOC_860_HIGOT:
680 rtype = R_860_HIGOT;
681 break;
682 case BFD_RELOC_860_HIGOTOFF:
683 rtype = R_860_HIGOTOFF;
684 break;
685 default:
686 rtype = 0;
687 break;
688 }
689 return lookup_howto (rtype);
690 }
691
692 /* Given a ELF reloc, return the matching HOWTO structure. */
693 static void
694 elf32_i860_info_to_howto_rela (abfd, bfd_reloc, elf_reloc)
695 bfd *abfd ATTRIBUTE_UNUSED;
696 arelent *bfd_reloc;
697 Elf64_Internal_Rela *elf_reloc;
698 {
699 bfd_reloc->howto = lookup_howto (ELF32_R_TYPE (elf_reloc->r_info));
700 }
701
702 \f
703 /* Specialized relocation handler for R_860_SPLITn. These relocations
704 involves a 16-bit field that is split into two contiguous parts. */
705 static bfd_reloc_status_type
706 elf32_i860_relocate_splitn (input_bfd, rello, contents, value)
707 bfd *input_bfd;
708 Elf_Internal_Rela *rello;
709 bfd_byte *contents;
710 bfd_vma value;
711 {
712 bfd_vma insn;
713 reloc_howto_type *howto;
714 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
715 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
716
717 /* Relocate. */
718 value += rello->r_addend;
719
720 /* Separate the fields and insert. */
721 value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
722 insn = (insn & ~howto->dst_mask) | value;
723
724 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
725 return bfd_reloc_ok;
726 }
727
728 /* Specialized relocation handler for R_860_PC16. This relocation
729 involves a 16-bit, PC-relative field that is split into two contiguous
730 parts. */
731 static bfd_reloc_status_type
732 elf32_i860_relocate_pc16 (input_bfd, input_section, rello, contents, value)
733 bfd *input_bfd;
734 asection *input_section;
735 Elf_Internal_Rela *rello;
736 bfd_byte *contents;
737 bfd_vma value;
738 {
739 bfd_vma insn;
740 reloc_howto_type *howto;
741 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
742 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
743
744 /* Adjust for PC-relative relocation. */
745 value -= (input_section->output_section->vma
746 + input_section->output_offset);
747 value -= rello->r_offset;
748
749 /* Relocate. */
750 value += rello->r_addend;
751
752 /* Separate the fields and insert. */
753 value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
754 insn = (insn & ~howto->dst_mask) | value;
755
756 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
757 return bfd_reloc_ok;
758
759 }
760
761 /* Specialized relocation handler for R_860_PC26. This relocation
762 involves a 26-bit, PC-relative field which must be adjusted by 4. */
763 static bfd_reloc_status_type
764 elf32_i860_relocate_pc26 (input_bfd, input_section, rello, contents, value)
765 bfd *input_bfd;
766 asection *input_section;
767 Elf_Internal_Rela *rello;
768 bfd_byte *contents;
769 bfd_vma value;
770 {
771 bfd_vma insn;
772 reloc_howto_type *howto;
773 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
774 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
775
776 /* Adjust for PC-relative relocation. */
777 value -= (input_section->output_section->vma
778 + input_section->output_offset);
779 value -= rello->r_offset;
780
781 /* Relocate. */
782 value += rello->r_addend;
783
784 /* Adjust value by 4 and insert the field. */
785 value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
786 insn = (insn & ~howto->dst_mask) | value;
787
788 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
789 return bfd_reloc_ok;
790
791 }
792
793 /* Specialized relocation handler for R_860_HIGHADJ. */
794 static bfd_reloc_status_type
795 elf32_i860_relocate_highadj (input_bfd, rel, contents, value)
796 bfd *input_bfd;
797 Elf_Internal_Rela *rel;
798 bfd_byte *contents;
799 bfd_vma value;
800 {
801 bfd_vma insn;
802
803 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
804
805 value += ((rel->r_addend & 0x8000) << 1);
806 value += rel->r_addend;
807 value = ((value >> 16) & 0xffff);
808
809 insn = (insn & 0xffff0000) | value;
810
811 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
812 return bfd_reloc_ok;
813 }
814
815 /* Perform a single relocation. By default we use the standard BFD
816 routines. However, we handle some specially. */
817 static bfd_reloc_status_type
818 i860_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
819 reloc_howto_type * howto;
820 bfd * input_bfd;
821 asection * input_section;
822 bfd_byte * contents;
823 Elf_Internal_Rela * rel;
824 bfd_vma relocation;
825 {
826 return _bfd_final_link_relocate (howto, input_bfd, input_section,
827 contents, rel->r_offset, relocation,
828 rel->r_addend);
829 }
830
831 /* Relocate an i860 ELF section.
832
833 This is boiler-plate code copied from fr30.
834 There is some attempt to make this function usable for many architectures,
835 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
836 if only to serve as a learning tool.
837
838 The RELOCATE_SECTION function is called by the new ELF backend linker
839 to handle the relocations for a section.
840
841 The relocs are always passed as Rela structures; if the section
842 actually uses Rel structures, the r_addend field will always be
843 zero.
844
845 This function is responsible for adjusting the section contents as
846 necessary, and (if using Rela relocs and generating a relocateable
847 output file) adjusting the reloc addend as necessary.
848
849 This function does not have to worry about setting the reloc
850 address or the reloc symbol index.
851
852 LOCAL_SYMS is a pointer to the swapped in local symbols.
853
854 LOCAL_SECTIONS is an array giving the section in the input file
855 corresponding to the st_shndx field of each local symbol.
856
857 The global hash table entry for the global symbols can be found
858 via elf_sym_hashes (input_bfd).
859
860 When generating relocateable output, this function must handle
861 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
862 going to be the section symbol corresponding to the output
863 section, which means that the addend must be adjusted
864 accordingly. */
865 static boolean
866 elf32_i860_relocate_section (output_bfd, info, input_bfd, input_section,
867 contents, relocs, local_syms, local_sections)
868 bfd * output_bfd ATTRIBUTE_UNUSED;
869 struct bfd_link_info * info;
870 bfd * input_bfd;
871 asection * input_section;
872 bfd_byte * contents;
873 Elf_Internal_Rela * relocs;
874 Elf_Internal_Sym * local_syms;
875 asection ** local_sections;
876 {
877 Elf_Internal_Shdr * symtab_hdr;
878 struct elf_link_hash_entry ** sym_hashes;
879 Elf_Internal_Rela * rel;
880 Elf_Internal_Rela * relend;
881
882 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
883 sym_hashes = elf_sym_hashes (input_bfd);
884 relend = relocs + input_section->reloc_count;
885
886 for (rel = relocs; rel < relend; rel ++)
887 {
888 reloc_howto_type * howto;
889 unsigned long r_symndx;
890 Elf_Internal_Sym * sym;
891 asection * sec;
892 struct elf_link_hash_entry * h;
893 bfd_vma relocation;
894 bfd_reloc_status_type r;
895 const char * name = NULL;
896 int r_type;
897
898 r_type = ELF32_R_TYPE (rel->r_info);
899
900 #if 0
901 if ( r_type == R_860_GNU_VTINHERIT
902 || r_type == R_860_GNU_VTENTRY)
903 continue;
904 #endif
905
906 r_symndx = ELF32_R_SYM (rel->r_info);
907
908 if (info->relocateable)
909 {
910 /* This is a relocateable link. We don't have to change
911 anything, unless the reloc is against a section symbol,
912 in which case we have to adjust according to where the
913 section symbol winds up in the output section. */
914 if (r_symndx < symtab_hdr->sh_info)
915 {
916 sym = local_syms + r_symndx;
917
918 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
919 {
920 sec = local_sections [r_symndx];
921 rel->r_addend += sec->output_offset + sym->st_value;
922 }
923 }
924
925 continue;
926 }
927
928 /* This is a final link. */
929 howto = lookup_howto (ELF32_R_TYPE (rel->r_info));
930 h = NULL;
931 sym = NULL;
932 sec = NULL;
933
934 if (r_symndx < symtab_hdr->sh_info)
935 {
936 sym = local_syms + r_symndx;
937 sec = local_sections [r_symndx];
938 relocation = (sec->output_section->vma
939 + sec->output_offset
940 + sym->st_value);
941
942 name = bfd_elf_string_from_elf_section
943 (input_bfd, symtab_hdr->sh_link, sym->st_name);
944 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
945 }
946 else
947 {
948 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
949
950 while (h->root.type == bfd_link_hash_indirect
951 || h->root.type == bfd_link_hash_warning)
952 h = (struct elf_link_hash_entry *) h->root.u.i.link;
953
954 name = h->root.root.string;
955
956 if (h->root.type == bfd_link_hash_defined
957 || h->root.type == bfd_link_hash_defweak)
958 {
959 sec = h->root.u.def.section;
960 relocation = (h->root.u.def.value
961 + sec->output_section->vma
962 + sec->output_offset);
963 }
964 else if (h->root.type == bfd_link_hash_undefweak)
965 {
966 relocation = 0;
967 }
968 else
969 {
970 if (! ((*info->callbacks->undefined_symbol)
971 (info, h->root.root.string, input_bfd,
972 input_section, rel->r_offset, true)))
973 return false;
974 relocation = 0;
975 }
976 }
977
978 switch (r_type)
979 {
980 default:
981 r = i860_final_link_relocate (howto, input_bfd, input_section,
982 contents, rel, relocation);
983 break;
984
985 case R_860_HIGHADJ:
986 r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
987 relocation);
988 break;
989
990 case R_860_PC16:
991 r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
992 contents, relocation);
993 break;
994
995 case R_860_PC26:
996 r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
997 contents, relocation);
998 break;
999
1000 case R_860_SPLIT0:
1001 case R_860_SPLIT1:
1002 case R_860_SPLIT2:
1003 r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
1004 relocation);
1005 break;
1006
1007 /* We do not yet handle GOT/PLT/Dynamic relocations. */
1008 case R_860_COPY:
1009 case R_860_GLOB_DAT:
1010 case R_860_JUMP_SLOT:
1011 case R_860_RELATIVE:
1012 case R_860_PLT26:
1013 case R_860_LOGOT0:
1014 case R_860_SPGOT0:
1015 case R_860_LOGOT1:
1016 case R_860_SPGOT1:
1017 case R_860_LOGOTOFF0:
1018 case R_860_SPGOTOFF0:
1019 case R_860_LOGOTOFF1:
1020 case R_860_SPGOTOFF1:
1021 case R_860_LOGOTOFF2:
1022 case R_860_LOGOTOFF3:
1023 case R_860_LOPC:
1024 case R_860_HAGOT:
1025 case R_860_HAGOTOFF:
1026 case R_860_HAPC:
1027 case R_860_HIGOT:
1028 case R_860_HIGOTOFF:
1029 r = bfd_reloc_notsupported;
1030 break;
1031 }
1032
1033 if (r != bfd_reloc_ok)
1034 {
1035 const char * msg = (const char *) NULL;
1036
1037 switch (r)
1038 {
1039 case bfd_reloc_overflow:
1040 r = info->callbacks->reloc_overflow
1041 (info, name, howto->name, (bfd_vma) 0,
1042 input_bfd, input_section, rel->r_offset);
1043 break;
1044
1045 case bfd_reloc_undefined:
1046 r = info->callbacks->undefined_symbol
1047 (info, name, input_bfd, input_section, rel->r_offset, true);
1048 break;
1049
1050 case bfd_reloc_outofrange:
1051 msg = _("internal error: out of range error");
1052 break;
1053
1054 case bfd_reloc_notsupported:
1055 msg = _("internal error: unsupported relocation error");
1056 break;
1057
1058 case bfd_reloc_dangerous:
1059 msg = _("internal error: dangerous relocation");
1060 break;
1061
1062 default:
1063 msg = _("internal error: unknown error");
1064 break;
1065 }
1066
1067 if (msg)
1068 r = info->callbacks->warning
1069 (info, msg, name, input_bfd, input_section, rel->r_offset);
1070
1071 if (! r)
1072 return false;
1073 }
1074 }
1075
1076 return true;
1077 }
1078
1079 /* Return whether a symbol name implies a local label. SVR4/860 compilers
1080 generate labels of the form ".ep.function_name" to denote the end of a
1081 function prolog. These should be local.
1082 ??? Do any other SVR4 compilers have this convention? If so, this should
1083 be added to the generic routine. */
1084 static boolean
1085 elf32_i860_is_local_label_name (abfd, name)
1086 bfd *abfd;
1087 const char *name;
1088 {
1089 if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1090 return true;
1091
1092 return _bfd_elf_is_local_label_name (abfd, name);
1093 }
1094
1095 \f
1096 #define TARGET_BIG_SYM bfd_elf32_i860_vec
1097 #define TARGET_BIG_NAME "elf32-i860"
1098 #define TARGET_LITTLE_SYM bfd_elf32_i860_little_vec
1099 #define TARGET_LITTLE_NAME "elf32-i860-little"
1100 #define ELF_ARCH bfd_arch_i860
1101 #define ELF_MACHINE_CODE EM_860
1102 #define ELF_MAXPAGESIZE 4096
1103
1104 #define elf_info_to_howto_rel NULL
1105 #define elf_info_to_howto elf32_i860_info_to_howto_rela
1106 #define elf_backend_relocate_section elf32_i860_relocate_section
1107 #define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
1108 #define bfd_elf32_bfd_is_local_label_name elf32_i860_is_local_label_name
1109
1110 #include "elf32-target.h"
This page took 0.053288 seconds and 4 git commands to generate.