2002-06-25 Don Howard <dhoward@redhat.com>
[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
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 /* Prototypes. */
30 static reloc_howto_type *lookup_howto
31 PARAMS ((unsigned int));
32
33 static reloc_howto_type *elf32_i860_reloc_type_lookup
34 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
35
36 static void elf32_i860_info_to_howto_rela
37 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
38
39 static bfd_reloc_status_type elf32_i860_relocate_splitn
40 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
41
42 static bfd_reloc_status_type elf32_i860_relocate_pc16
43 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
44
45 static bfd_reloc_status_type elf32_i860_relocate_pc26
46 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
47
48 static bfd_reloc_status_type elf32_i860_relocate_highadj
49 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
50
51 static boolean elf32_i860_relocate_section
52 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
53 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
54
55 static bfd_reloc_status_type i860_final_link_relocate
56 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
57 Elf_Internal_Rela *, bfd_vma));
58
59 static boolean elf32_i860_is_local_label_name
60 PARAMS ((bfd *, const char *));
61
62 /* This howto table is preliminary. */
63 static reloc_howto_type elf32_i860_howto_table [] =
64 {
65 /* This relocation does nothing. */
66 HOWTO (R_860_NONE, /* type */
67 0, /* rightshift */
68 2, /* size (0 = byte, 1 = short, 2 = long) */
69 32, /* bitsize */
70 false, /* pc_relative */
71 0, /* bitpos */
72 complain_overflow_bitfield, /* complain_on_overflow */
73 bfd_elf_generic_reloc, /* special_function */
74 "R_860_NONE", /* name */
75 false, /* partial_inplace */
76 0, /* src_mask */
77 0, /* dst_mask */
78 false), /* pcrel_offset */
79
80 /* A 32-bit absolute relocation. */
81 HOWTO (R_860_32, /* type */
82 0, /* rightshift */
83 2, /* size (0 = byte, 1 = short, 2 = long) */
84 32, /* bitsize */
85 false, /* pc_relative */
86 0, /* bitpos */
87 complain_overflow_bitfield, /* complain_on_overflow */
88 bfd_elf_generic_reloc, /* special_function */
89 "R_860_32", /* name */
90 false, /* partial_inplace */
91 0xffffffff, /* src_mask */
92 0xffffffff, /* dst_mask */
93 false), /* pcrel_offset */
94
95 HOWTO (R_860_COPY, /* type */
96 0, /* rightshift */
97 2, /* size (0 = byte, 1 = short, 2 = long) */
98 32, /* bitsize */
99 false, /* pc_relative */
100 0, /* bitpos */
101 complain_overflow_bitfield, /* complain_on_overflow */
102 bfd_elf_generic_reloc, /* special_function */
103 "R_860_COPY", /* name */
104 true, /* partial_inplace */
105 0xffffffff, /* src_mask */
106 0xffffffff, /* dst_mask */
107 false), /* pcrel_offset */
108
109 HOWTO (R_860_GLOB_DAT, /* type */
110 0, /* rightshift */
111 2, /* size (0 = byte, 1 = short, 2 = long) */
112 32, /* bitsize */
113 false, /* pc_relative */
114 0, /* bitpos */
115 complain_overflow_bitfield, /* complain_on_overflow */
116 bfd_elf_generic_reloc, /* special_function */
117 "R_860_GLOB_DAT", /* name */
118 true, /* partial_inplace */
119 0xffffffff, /* src_mask */
120 0xffffffff, /* dst_mask */
121 false), /* pcrel_offset */
122
123 HOWTO (R_860_JUMP_SLOT, /* type */
124 0, /* rightshift */
125 2, /* size (0 = byte, 1 = short, 2 = long) */
126 32, /* bitsize */
127 false, /* pc_relative */
128 0, /* bitpos */
129 complain_overflow_bitfield, /* complain_on_overflow */
130 bfd_elf_generic_reloc, /* special_function */
131 "R_860_JUMP_SLOT", /* name */
132 true, /* partial_inplace */
133 0xffffffff, /* src_mask */
134 0xffffffff, /* dst_mask */
135 false), /* pcrel_offset */
136
137 HOWTO (R_860_RELATIVE, /* type */
138 0, /* rightshift */
139 2, /* size (0 = byte, 1 = short, 2 = long) */
140 32, /* bitsize */
141 false, /* pc_relative */
142 0, /* bitpos */
143 complain_overflow_bitfield, /* complain_on_overflow */
144 bfd_elf_generic_reloc, /* special_function */
145 "R_860_RELATIVE", /* name */
146 true, /* partial_inplace */
147 0xffffffff, /* src_mask */
148 0xffffffff, /* dst_mask */
149 false), /* pcrel_offset */
150
151 /* A 26-bit PC-relative relocation. */
152 HOWTO (R_860_PC26, /* type */
153 2, /* rightshift */
154 2, /* size (0 = byte, 1 = short, 2 = long) */
155 26, /* bitsize */
156 true, /* pc_relative */
157 0, /* bitpos */
158 complain_overflow_bitfield, /* complain_on_overflow */
159 bfd_elf_generic_reloc, /* special_function */
160 "R_860_PC26", /* name */
161 false, /* partial_inplace */
162 0x3ffffff, /* src_mask */
163 0x3ffffff, /* dst_mask */
164 true), /* pcrel_offset */
165
166 HOWTO (R_860_PLT26, /* type */
167 0, /* rightshift */
168 2, /* size (0 = byte, 1 = short, 2 = long) */
169 26, /* bitsize */
170 true, /* pc_relative */
171 0, /* bitpos */
172 complain_overflow_bitfield, /* complain_on_overflow */
173 bfd_elf_generic_reloc, /* special_function */
174 "R_860_PLT26", /* name */
175 true, /* partial_inplace */
176 0xffffffff, /* src_mask */
177 0xffffffff, /* dst_mask */
178 true), /* pcrel_offset */
179
180 /* A 16-bit PC-relative relocation. */
181 HOWTO (R_860_PC16, /* type */
182 2, /* rightshift */
183 2, /* size (0 = byte, 1 = short, 2 = long) */
184 16, /* bitsize */
185 true, /* pc_relative */
186 0, /* bitpos */
187 complain_overflow_bitfield, /* complain_on_overflow */
188 bfd_elf_generic_reloc, /* special_function */
189 "R_860_PC16", /* name */
190 false, /* partial_inplace */
191 0x1f07ff, /* src_mask */
192 0x1f07ff, /* dst_mask */
193 true), /* pcrel_offset */
194
195 HOWTO (R_860_LOW0, /* type */
196 0, /* rightshift */
197 2, /* size (0 = byte, 1 = short, 2 = long) */
198 16, /* bitsize */
199 false, /* pc_relative */
200 0, /* bitpos */
201 complain_overflow_dont, /* complain_on_overflow */
202 bfd_elf_generic_reloc, /* special_function */
203 "R_860_LOW0", /* name */
204 false, /* partial_inplace */
205 0xffff, /* src_mask */
206 0xffff, /* dst_mask */
207 false), /* pcrel_offset */
208
209 HOWTO (R_860_SPLIT0, /* type */
210 0, /* rightshift */
211 2, /* size (0 = byte, 1 = short, 2 = long) */
212 16, /* bitsize */
213 false, /* pc_relative */
214 0, /* bitpos */
215 complain_overflow_dont, /* complain_on_overflow */
216 bfd_elf_generic_reloc, /* special_function */
217 "R_860_SPLIT0", /* name */
218 false, /* partial_inplace */
219 0x1f07ff, /* src_mask */
220 0x1f07ff, /* dst_mask */
221 false), /* pcrel_offset */
222
223 HOWTO (R_860_LOW1, /* type */
224 0, /* rightshift */
225 2, /* size (0 = byte, 1 = short, 2 = long) */
226 16, /* bitsize */
227 false, /* pc_relative */
228 0, /* bitpos */
229 complain_overflow_dont, /* complain_on_overflow */
230 bfd_elf_generic_reloc, /* special_function */
231 "R_860_LOW1", /* name */
232 false, /* partial_inplace */
233 0xfffe, /* src_mask */
234 0xfffe, /* dst_mask */
235 false), /* pcrel_offset */
236
237 HOWTO (R_860_SPLIT1, /* type */
238 0, /* rightshift */
239 2, /* size (0 = byte, 1 = short, 2 = long) */
240 16, /* bitsize */
241 false, /* pc_relative */
242 0, /* bitpos */
243 complain_overflow_dont, /* complain_on_overflow */
244 bfd_elf_generic_reloc, /* special_function */
245 "R_860_SPLIT1", /* name */
246 false, /* partial_inplace */
247 0x1f07fe, /* src_mask */
248 0x1f07fe, /* dst_mask */
249 false), /* pcrel_offset */
250
251 HOWTO (R_860_LOW2, /* type */
252 0, /* rightshift */
253 2, /* size (0 = byte, 1 = short, 2 = long) */
254 16, /* bitsize */
255 false, /* pc_relative */
256 0, /* bitpos */
257 complain_overflow_dont, /* complain_on_overflow */
258 bfd_elf_generic_reloc, /* special_function */
259 "R_860_LOW2", /* name */
260 false, /* partial_inplace */
261 0xfffc, /* src_mask */
262 0xfffc, /* dst_mask */
263 false), /* pcrel_offset */
264
265 HOWTO (R_860_SPLIT2, /* type */
266 0, /* rightshift */
267 2, /* size (0 = byte, 1 = short, 2 = long) */
268 16, /* bitsize */
269 false, /* pc_relative */
270 0, /* bitpos */
271 complain_overflow_dont, /* complain_on_overflow */
272 bfd_elf_generic_reloc, /* special_function */
273 "R_860_SPLIT2", /* name */
274 false, /* partial_inplace */
275 0x1f07fc, /* src_mask */
276 0x1f07fc, /* dst_mask */
277 false), /* pcrel_offset */
278
279 HOWTO (R_860_LOW3, /* type */
280 0, /* rightshift */
281 2, /* size (0 = byte, 1 = short, 2 = long) */
282 16, /* bitsize */
283 false, /* pc_relative */
284 0, /* bitpos */
285 complain_overflow_dont, /* complain_on_overflow */
286 bfd_elf_generic_reloc, /* special_function */
287 "R_860_LOW3", /* name */
288 false, /* partial_inplace */
289 0xfff8, /* src_mask */
290 0xfff8, /* dst_mask */
291 false), /* pcrel_offset */
292
293 HOWTO (R_860_LOGOT0, /* type */
294 0, /* rightshift */
295 2, /* size (0 = byte, 1 = short, 2 = long) */
296 16, /* bitsize */
297 false, /* pc_relative */
298 0, /* bitpos */
299 complain_overflow_dont, /* complain_on_overflow */
300 bfd_elf_generic_reloc, /* special_function */
301 "R_860_LOGOT0", /* name */
302 false, /* partial_inplace */
303 0, /* src_mask */
304 0xffff, /* dst_mask */
305 true), /* pcrel_offset */
306
307 HOWTO (R_860_SPGOT0, /* type */
308 0, /* rightshift */
309 2, /* size (0 = byte, 1 = short, 2 = long) */
310 16, /* bitsize */
311 false, /* pc_relative */
312 0, /* bitpos */
313 complain_overflow_dont, /* complain_on_overflow */
314 bfd_elf_generic_reloc, /* special_function */
315 "R_860_SPGOT0", /* name */
316 false, /* partial_inplace */
317 0, /* src_mask */
318 0xffff, /* dst_mask */
319 true), /* pcrel_offset */
320
321 HOWTO (R_860_LOGOT1, /* type */
322 0, /* rightshift */
323 2, /* size (0 = byte, 1 = short, 2 = long) */
324 16, /* bitsize */
325 false, /* pc_relative */
326 0, /* bitpos */
327 complain_overflow_dont, /* complain_on_overflow */
328 bfd_elf_generic_reloc, /* special_function */
329 "R_860_LOGOT1", /* name */
330 false, /* partial_inplace */
331 0, /* src_mask */
332 0xffff, /* dst_mask */
333 true), /* pcrel_offset */
334
335 HOWTO (R_860_SPGOT1, /* type */
336 0, /* rightshift */
337 2, /* size (0 = byte, 1 = short, 2 = long) */
338 16, /* bitsize */
339 false, /* pc_relative */
340 0, /* bitpos */
341 complain_overflow_dont, /* complain_on_overflow */
342 bfd_elf_generic_reloc, /* special_function */
343 "R_860_SPGOT1", /* name */
344 false, /* partial_inplace */
345 0, /* src_mask */
346 0xffff, /* dst_mask */
347 true), /* pcrel_offset */
348
349 HOWTO (R_860_LOGOTOFF0, /* type */
350 0, /* rightshift */
351 2, /* size (0 = byte, 1 = short, 2 = long) */
352 32, /* bitsize */
353 false, /* pc_relative */
354 0, /* bitpos */
355 complain_overflow_dont, /* complain_on_overflow */
356 bfd_elf_generic_reloc, /* special_function */
357 "R_860_LOGOTOFF0", /* name */
358 true, /* partial_inplace */
359 0xffffffff, /* src_mask */
360 0xffffffff, /* dst_mask */
361 false), /* pcrel_offset */
362
363 HOWTO (R_860_SPGOTOFF0, /* type */
364 0, /* rightshift */
365 2, /* size (0 = byte, 1 = short, 2 = long) */
366 32, /* bitsize */
367 false, /* pc_relative */
368 0, /* bitpos */
369 complain_overflow_dont, /* complain_on_overflow */
370 bfd_elf_generic_reloc, /* special_function */
371 "R_860_SPGOTOFF0", /* name */
372 true, /* partial_inplace */
373 0xffffffff, /* src_mask */
374 0xffffffff, /* dst_mask */
375 false), /* pcrel_offset */
376
377 HOWTO (R_860_LOGOTOFF1, /* type */
378 0, /* rightshift */
379 2, /* size (0 = byte, 1 = short, 2 = long) */
380 32, /* bitsize */
381 false, /* pc_relative */
382 0, /* bitpos */
383 complain_overflow_dont, /* complain_on_overflow */
384 bfd_elf_generic_reloc, /* special_function */
385 "R_860_LOGOTOFF1", /* name */
386 true, /* partial_inplace */
387 0xffffffff, /* src_mask */
388 0xffffffff, /* dst_mask */
389 false), /* pcrel_offset */
390
391 HOWTO (R_860_SPGOTOFF1, /* type */
392 0, /* rightshift */
393 2, /* size (0 = byte, 1 = short, 2 = long) */
394 32, /* bitsize */
395 false, /* pc_relative */
396 0, /* bitpos */
397 complain_overflow_dont, /* complain_on_overflow */
398 bfd_elf_generic_reloc, /* special_function */
399 "R_860_SPGOTOFF1", /* name */
400 true, /* partial_inplace */
401 0xffffffff, /* src_mask */
402 0xffffffff, /* dst_mask */
403 false), /* pcrel_offset */
404
405 HOWTO (R_860_LOGOTOFF2, /* type */
406 0, /* rightshift */
407 2, /* size (0 = byte, 1 = short, 2 = long) */
408 32, /* bitsize */
409 false, /* pc_relative */
410 0, /* bitpos */
411 complain_overflow_dont, /* complain_on_overflow */
412 bfd_elf_generic_reloc, /* special_function */
413 "R_860_LOGOTOFF2", /* name */
414 true, /* partial_inplace */
415 0xffffffff, /* src_mask */
416 0xffffffff, /* dst_mask */
417 false), /* pcrel_offset */
418
419 HOWTO (R_860_LOGOTOFF3, /* type */
420 0, /* rightshift */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
422 32, /* bitsize */
423 false, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_dont, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_860_LOGOTOFF3", /* name */
428 true, /* partial_inplace */
429 0xffffffff, /* src_mask */
430 0xffffffff, /* dst_mask */
431 false), /* pcrel_offset */
432
433 HOWTO (R_860_LOPC, /* type */
434 0, /* rightshift */
435 2, /* size (0 = byte, 1 = short, 2 = long) */
436 16, /* bitsize */
437 true, /* pc_relative */
438 0, /* bitpos */
439 complain_overflow_bitfield, /* complain_on_overflow */
440 bfd_elf_generic_reloc, /* special_function */
441 "R_860_LOPC", /* name */
442 false, /* partial_inplace */
443 0xffff, /* src_mask */
444 0xffff, /* dst_mask */
445 true), /* pcrel_offset */
446
447 HOWTO (R_860_HIGHADJ, /* type */
448 0, /* rightshift */
449 2, /* size (0 = byte, 1 = short, 2 = long) */
450 16, /* bitsize */
451 false, /* pc_relative */
452 0, /* bitpos */
453 complain_overflow_dont, /* complain_on_overflow */
454 bfd_elf_generic_reloc, /* special_function */
455 "R_860_HIGHADJ", /* name */
456 false, /* partial_inplace */
457 0xffff, /* src_mask */
458 0xffff, /* dst_mask */
459 false), /* pcrel_offset */
460
461 HOWTO (R_860_HAGOT, /* type */
462 0, /* rightshift */
463 2, /* size (0 = byte, 1 = short, 2 = long) */
464 16, /* bitsize */
465 false, /* pc_relative */
466 0, /* bitpos */
467 complain_overflow_dont, /* complain_on_overflow */
468 bfd_elf_generic_reloc, /* special_function */
469 "R_860_HAGOT", /* name */
470 false, /* partial_inplace */
471 0, /* src_mask */
472 0xffff, /* dst_mask */
473 true), /* pcrel_offset */
474
475 HOWTO (R_860_HAGOTOFF, /* type */
476 0, /* rightshift */
477 2, /* size (0 = byte, 1 = short, 2 = long) */
478 32, /* bitsize */
479 false, /* pc_relative */
480 0, /* bitpos */
481 complain_overflow_dont, /* complain_on_overflow */
482 bfd_elf_generic_reloc, /* special_function */
483 "R_860_HAGOTOFF", /* name */
484 true, /* partial_inplace */
485 0xffffffff, /* src_mask */
486 0xffffffff, /* dst_mask */
487 false), /* pcrel_offset */
488
489 HOWTO (R_860_HAPC, /* type */
490 0, /* rightshift */
491 2, /* size (0 = byte, 1 = short, 2 = long) */
492 16, /* bitsize */
493 true, /* pc_relative */
494 0, /* bitpos */
495 complain_overflow_bitfield, /* complain_on_overflow */
496 bfd_elf_generic_reloc, /* special_function */
497 "R_860_HAPC", /* name */
498 false, /* partial_inplace */
499 0xffff, /* src_mask */
500 0xffff, /* dst_mask */
501 true), /* pcrel_offset */
502
503 HOWTO (R_860_HIGH, /* type */
504 16, /* rightshift */
505 2, /* size (0 = byte, 1 = short, 2 = long) */
506 16, /* bitsize */
507 false, /* pc_relative */
508 0, /* bitpos */
509 complain_overflow_dont, /* complain_on_overflow */
510 bfd_elf_generic_reloc, /* special_function */
511 "R_860_HIGH", /* name */
512 false, /* partial_inplace */
513 0xffff, /* src_mask */
514 0xffff, /* dst_mask */
515 false), /* pcrel_offset */
516
517 HOWTO (R_860_HIGOT, /* type */
518 0, /* rightshift */
519 2, /* size (0 = byte, 1 = short, 2 = long) */
520 16, /* bitsize */
521 false, /* pc_relative */
522 0, /* bitpos */
523 complain_overflow_dont, /* complain_on_overflow */
524 bfd_elf_generic_reloc, /* special_function */
525 "R_860_HIGOT", /* name */
526 false, /* partial_inplace */
527 0, /* src_mask */
528 0xffff, /* dst_mask */
529 true), /* pcrel_offset */
530
531 HOWTO (R_860_HIGOTOFF, /* type */
532 0, /* rightshift */
533 2, /* size (0 = byte, 1 = short, 2 = long) */
534 32, /* bitsize */
535 false, /* pc_relative */
536 0, /* bitpos */
537 complain_overflow_dont, /* complain_on_overflow */
538 bfd_elf_generic_reloc, /* special_function */
539 "R_860_HIGOTOFF", /* name */
540 true, /* partial_inplace */
541 0xffffffff, /* src_mask */
542 0xffffffff, /* dst_mask */
543 false), /* pcrel_offset */
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
700 = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc->r_info));
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 ((unsigned) 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 ((unsigned) 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 ((unsigned) 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 if (info->relocateable)
883 return true;
884
885 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
886 sym_hashes = elf_sym_hashes (input_bfd);
887 relend = relocs + input_section->reloc_count;
888
889 for (rel = relocs; rel < relend; rel ++)
890 {
891 reloc_howto_type * howto;
892 unsigned long r_symndx;
893 Elf_Internal_Sym * sym;
894 asection * sec;
895 struct elf_link_hash_entry * h;
896 bfd_vma relocation;
897 bfd_reloc_status_type r;
898 const char * name = NULL;
899 int r_type;
900
901 r_type = ELF32_R_TYPE (rel->r_info);
902
903 #if 0
904 if ( r_type == R_860_GNU_VTINHERIT
905 || r_type == R_860_GNU_VTENTRY)
906 continue;
907 #endif
908
909 r_symndx = ELF32_R_SYM (rel->r_info);
910
911 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
912 h = NULL;
913 sym = NULL;
914 sec = NULL;
915
916 if (r_symndx < symtab_hdr->sh_info)
917 {
918 sym = local_syms + r_symndx;
919 sec = local_sections [r_symndx];
920 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
921
922 name = bfd_elf_string_from_elf_section
923 (input_bfd, symtab_hdr->sh_link, sym->st_name);
924 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
925 }
926 else
927 {
928 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
929
930 while (h->root.type == bfd_link_hash_indirect
931 || h->root.type == bfd_link_hash_warning)
932 h = (struct elf_link_hash_entry *) h->root.u.i.link;
933
934 name = h->root.root.string;
935
936 if (h->root.type == bfd_link_hash_defined
937 || h->root.type == bfd_link_hash_defweak)
938 {
939 sec = h->root.u.def.section;
940 relocation = (h->root.u.def.value
941 + sec->output_section->vma
942 + sec->output_offset);
943 }
944 else if (h->root.type == bfd_link_hash_undefweak)
945 {
946 relocation = 0;
947 }
948 else
949 {
950 if (! ((*info->callbacks->undefined_symbol)
951 (info, h->root.root.string, input_bfd,
952 input_section, rel->r_offset, true)))
953 return false;
954 relocation = 0;
955 }
956 }
957
958 switch (r_type)
959 {
960 default:
961 r = i860_final_link_relocate (howto, input_bfd, input_section,
962 contents, rel, relocation);
963 break;
964
965 case R_860_HIGHADJ:
966 r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
967 relocation);
968 break;
969
970 case R_860_PC16:
971 r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
972 contents, relocation);
973 break;
974
975 case R_860_PC26:
976 r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
977 contents, relocation);
978 break;
979
980 case R_860_SPLIT0:
981 case R_860_SPLIT1:
982 case R_860_SPLIT2:
983 r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
984 relocation);
985 break;
986
987 /* We do not yet handle GOT/PLT/Dynamic relocations. */
988 case R_860_COPY:
989 case R_860_GLOB_DAT:
990 case R_860_JUMP_SLOT:
991 case R_860_RELATIVE:
992 case R_860_PLT26:
993 case R_860_LOGOT0:
994 case R_860_SPGOT0:
995 case R_860_LOGOT1:
996 case R_860_SPGOT1:
997 case R_860_LOGOTOFF0:
998 case R_860_SPGOTOFF0:
999 case R_860_LOGOTOFF1:
1000 case R_860_SPGOTOFF1:
1001 case R_860_LOGOTOFF2:
1002 case R_860_LOGOTOFF3:
1003 case R_860_LOPC:
1004 case R_860_HAGOT:
1005 case R_860_HAGOTOFF:
1006 case R_860_HAPC:
1007 case R_860_HIGOT:
1008 case R_860_HIGOTOFF:
1009 r = bfd_reloc_notsupported;
1010 break;
1011 }
1012
1013 if (r != bfd_reloc_ok)
1014 {
1015 const char * msg = (const char *) NULL;
1016
1017 switch (r)
1018 {
1019 case bfd_reloc_overflow:
1020 r = info->callbacks->reloc_overflow
1021 (info, name, howto->name, (bfd_vma) 0,
1022 input_bfd, input_section, rel->r_offset);
1023 break;
1024
1025 case bfd_reloc_undefined:
1026 r = info->callbacks->undefined_symbol
1027 (info, name, input_bfd, input_section, rel->r_offset, true);
1028 break;
1029
1030 case bfd_reloc_outofrange:
1031 msg = _("internal error: out of range error");
1032 break;
1033
1034 case bfd_reloc_notsupported:
1035 msg = _("internal error: unsupported relocation error");
1036 break;
1037
1038 case bfd_reloc_dangerous:
1039 msg = _("internal error: dangerous relocation");
1040 break;
1041
1042 default:
1043 msg = _("internal error: unknown error");
1044 break;
1045 }
1046
1047 if (msg)
1048 r = info->callbacks->warning
1049 (info, msg, name, input_bfd, input_section, rel->r_offset);
1050
1051 if (! r)
1052 return false;
1053 }
1054 }
1055
1056 return true;
1057 }
1058
1059 /* Return whether a symbol name implies a local label. SVR4/860 compilers
1060 generate labels of the form ".ep.function_name" to denote the end of a
1061 function prolog. These should be local.
1062 ??? Do any other SVR4 compilers have this convention? If so, this should
1063 be added to the generic routine. */
1064 static boolean
1065 elf32_i860_is_local_label_name (abfd, name)
1066 bfd *abfd;
1067 const char *name;
1068 {
1069 if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1070 return true;
1071
1072 return _bfd_elf_is_local_label_name (abfd, name);
1073 }
1074 \f
1075 #define TARGET_BIG_SYM bfd_elf32_i860_vec
1076 #define TARGET_BIG_NAME "elf32-i860"
1077 #define TARGET_LITTLE_SYM bfd_elf32_i860_little_vec
1078 #define TARGET_LITTLE_NAME "elf32-i860-little"
1079 #define ELF_ARCH bfd_arch_i860
1080 #define ELF_MACHINE_CODE EM_860
1081 #define ELF_MAXPAGESIZE 4096
1082
1083 #define elf_backend_rela_normal 1
1084 #define elf_info_to_howto_rel NULL
1085 #define elf_info_to_howto elf32_i860_info_to_howto_rela
1086 #define elf_backend_relocate_section elf32_i860_relocate_section
1087 #define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
1088 #define bfd_elf32_bfd_is_local_label_name elf32_i860_is_local_label_name
1089
1090 #include "elf32-target.h"
This page took 0.129125 seconds and 4 git commands to generate.