2000-09-02 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / bfd / elf32-i860.c
CommitLineData
0e5136c6 1/* Intel i860 specific support for 32-bit ELF.
9d751335
JE
2 Copyright 1993, 2000 Free Software Foundation, Inc.
3
0e5136c6 4 Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
252b5132
RH
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, 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"
0e5136c6
JE
26#include "elf/i860.h"
27
28
29/* Prototypes. */
30static reloc_howto_type *lookup_howto
31 PARAMS ((unsigned int));
32
33static reloc_howto_type *elf32_i860_reloc_type_lookup
34 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
35
36static void elf32_i860_info_to_howto_rela
37 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
38
fdeafce7
JE
39static bfd_reloc_status_type elf32_i860_relocate_splitn
40 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
41
fdeafce7 42static bfd_reloc_status_type elf32_i860_relocate_pc16
d670a150 43 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
fdeafce7
JE
44
45static bfd_reloc_status_type elf32_i860_relocate_highadj
46 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
47
48static boolean elf32_i860_relocate_section
49 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
50 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
51
52static bfd_reloc_status_type i860_final_link_relocate
53 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
54 Elf_Internal_Rela *, bfd_vma));
55
56
0e5136c6
JE
57
58/* This howto table is preliminary. */
59static reloc_howto_type elf32_i860_howto_table [] =
60{
61 /* This relocation does nothing. */
62 HOWTO (R_860_NONE, /* type */
63 0, /* rightshift */
64 2, /* size (0 = byte, 1 = short, 2 = long) */
65 32, /* bitsize */
66 false, /* pc_relative */
67 0, /* bitpos */
68 complain_overflow_bitfield, /* complain_on_overflow */
69 bfd_elf_generic_reloc, /* special_function */
70 "R_860_NONE", /* name */
71 false, /* partial_inplace */
72 0, /* src_mask */
73 0, /* dst_mask */
74 false), /* pcrel_offset */
75
76 /* A 32-bit absolute relocation. */
77 HOWTO (R_860_32, /* 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_32", /* name */
86 false, /* partial_inplace */
87 0xffffffff, /* src_mask */
88 0xffffffff, /* dst_mask */
89 false), /* pcrel_offset */
90
91 HOWTO (R_860_COPY, /* 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_COPY", /* name */
100 true, /* partial_inplace */
101 0xffffffff, /* src_mask */
102 0xffffffff, /* dst_mask */
103 false), /* pcrel_offset */
104
105 HOWTO (R_860_GLOB_DAT, /* 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_GLOB_DAT", /* name */
114 true, /* partial_inplace */
115 0xffffffff, /* src_mask */
116 0xffffffff, /* dst_mask */
117 false), /* pcrel_offset */
118
119 HOWTO (R_860_JUMP_SLOT, /* type */
120 0, /* rightshift */
121 2, /* size (0 = byte, 1 = short, 2 = long) */
122 32, /* bitsize */
123 false, /* pc_relative */
124 0, /* bitpos */
125 complain_overflow_bitfield, /* complain_on_overflow */
126 bfd_elf_generic_reloc, /* special_function */
127 "R_860_JUMP_SLOT", /* name */
128 true, /* partial_inplace */
129 0xffffffff, /* src_mask */
130 0xffffffff, /* dst_mask */
131 false), /* pcrel_offset */
132
133 HOWTO (R_860_RELATIVE, /* type */
134 0, /* rightshift */
135 2, /* size (0 = byte, 1 = short, 2 = long) */
136 32, /* bitsize */
137 false, /* pc_relative */
138 0, /* bitpos */
139 complain_overflow_bitfield, /* complain_on_overflow */
140 bfd_elf_generic_reloc, /* special_function */
141 "R_860_RELATIVE", /* name */
142 true, /* partial_inplace */
143 0xffffffff, /* src_mask */
144 0xffffffff, /* dst_mask */
145 false), /* pcrel_offset */
146
147 /* A 26-bit PC-relative relocation. */
148 HOWTO (R_860_PC26, /* type */
fdeafce7 149 2, /* rightshift */
0e5136c6
JE
150 2, /* size (0 = byte, 1 = short, 2 = long) */
151 26, /* bitsize */
152 true, /* pc_relative */
153 0, /* bitpos */
154 complain_overflow_bitfield, /* complain_on_overflow */
155 bfd_elf_generic_reloc, /* special_function */
156 "R_860_PC26", /* name */
157 false, /* partial_inplace */
158 0x3ffffff, /* src_mask */
159 0x3ffffff, /* dst_mask */
160 true), /* pcrel_offset */
161
162 HOWTO (R_860_PLT26, /* type */
163 0, /* rightshift */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
165 26, /* bitsize */
166 true, /* pc_relative */
167 0, /* bitpos */
168 complain_overflow_bitfield, /* complain_on_overflow */
169 bfd_elf_generic_reloc, /* special_function */
170 "R_860_PLT26", /* name */
171 true, /* partial_inplace */
172 0xffffffff, /* src_mask */
173 0xffffffff, /* dst_mask */
174 true), /* pcrel_offset */
175
176 /* A 16-bit PC-relative relocation. */
177 HOWTO (R_860_PC16, /* type */
fdeafce7 178 2, /* rightshift */
0e5136c6
JE
179 2, /* size (0 = byte, 1 = short, 2 = long) */
180 16, /* bitsize */
181 true, /* pc_relative */
182 0, /* bitpos */
183 complain_overflow_bitfield, /* complain_on_overflow */
184 bfd_elf_generic_reloc, /* special_function */
185 "R_860_PC16", /* name */
186 false, /* partial_inplace */
305d537e
JE
187 0x1f07ff, /* src_mask */
188 0x1f07ff, /* dst_mask */
0e5136c6
JE
189 true), /* pcrel_offset */
190
191 HOWTO (R_860_LOW0, /* 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_LOW0", /* name */
200 false, /* partial_inplace */
201 0xffff, /* src_mask */
202 0xffff, /* dst_mask */
203 false), /* pcrel_offset */
204
205 HOWTO (R_860_SPLIT0, /* 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_SPLIT0", /* name */
214 false, /* partial_inplace */
215 0x1f07ff, /* src_mask */
216 0x1f07ff, /* dst_mask */
217 false), /* pcrel_offset */
218
219 HOWTO (R_860_LOW1, /* 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_LOW1", /* name */
228 false, /* partial_inplace */
229 0xfffe, /* src_mask */
230 0xfffe, /* dst_mask */
231 false), /* pcrel_offset */
232
233 HOWTO (R_860_SPLIT1, /* 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_SPLIT1", /* name */
242 false, /* partial_inplace */
305d537e
JE
243 0x1f07fe, /* src_mask */
244 0x1f07fe, /* dst_mask */
0e5136c6
JE
245 false), /* pcrel_offset */
246
247 HOWTO (R_860_LOW2, /* 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_LOW2", /* name */
256 false, /* partial_inplace */
257 0xfffc, /* src_mask */
258 0xfffc, /* dst_mask */
259 false), /* pcrel_offset */
260
261 HOWTO (R_860_SPLIT2, /* 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_SPLIT2", /* name */
270 false, /* partial_inplace */
305d537e
JE
271 0x1f07fc, /* src_mask */
272 0x1f07fc, /* dst_mask */
0e5136c6
JE
273 false), /* pcrel_offset */
274
275 HOWTO (R_860_LOW3, /* 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_LOW3", /* name */
284 false, /* partial_inplace */
285 0xfff8, /* src_mask */
286 0xfff8, /* dst_mask */
287 false), /* pcrel_offset */
288
289 HOWTO (R_860_LOGOT0, /* 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_LOGOT0", /* name */
298 false, /* partial_inplace */
299 0, /* src_mask */
300 0xffff, /* dst_mask */
301 true), /* pcrel_offset */
302
303 HOWTO (R_860_SPGOT0, /* 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_SPGOT0", /* name */
312 false, /* partial_inplace */
313 0, /* src_mask */
314 0xffff, /* dst_mask */
315 true), /* pcrel_offset */
316
317 HOWTO (R_860_LOGOT1, /* type */
318 0, /* rightshift */
319 2, /* size (0 = byte, 1 = short, 2 = long) */
320 16, /* 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_LOGOT1", /* name */
326 false, /* partial_inplace */
327 0, /* src_mask */
328 0xffff, /* dst_mask */
329 true), /* pcrel_offset */
330
331 HOWTO (R_860_SPGOT1, /* type */
332 0, /* rightshift */
333 2, /* size (0 = byte, 1 = short, 2 = long) */
334 16, /* 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_SPGOT1", /* name */
340 false, /* partial_inplace */
341 0, /* src_mask */
342 0xffff, /* dst_mask */
343 true), /* pcrel_offset */
344
345 HOWTO (R_860_LOGOTOFF0, /* 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_LOGOTOFF0", /* name */
354 true, /* partial_inplace */
355 0xffffffff, /* src_mask */
356 0xffffffff, /* dst_mask */
357 false), /* pcrel_offset */
358
359 HOWTO (R_860_SPGOTOFF0, /* 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_SPGOTOFF0", /* name */
368 true, /* partial_inplace */
369 0xffffffff, /* src_mask */
370 0xffffffff, /* dst_mask */
371 false), /* pcrel_offset */
372
373 HOWTO (R_860_LOGOTOFF1, /* 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_LOGOTOFF1", /* name */
382 true, /* partial_inplace */
383 0xffffffff, /* src_mask */
384 0xffffffff, /* dst_mask */
385 false), /* pcrel_offset */
386
387 HOWTO (R_860_SPGOTOFF1, /* 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_SPGOTOFF1", /* name */
396 true, /* partial_inplace */
397 0xffffffff, /* src_mask */
398 0xffffffff, /* dst_mask */
399 false), /* pcrel_offset */
400
401 HOWTO (R_860_LOGOTOFF2, /* type */
402 0, /* rightshift */
403 2, /* size (0 = byte, 1 = short, 2 = long) */
404 32, /* bitsize */
405 false, /* pc_relative */
406 0, /* bitpos */
407 complain_overflow_dont, /* complain_on_overflow */
408 bfd_elf_generic_reloc, /* special_function */
409 "R_860_LOGOTOFF2", /* name */
410 true, /* partial_inplace */
411 0xffffffff, /* src_mask */
412 0xffffffff, /* dst_mask */
413 false), /* pcrel_offset */
414
415 HOWTO (R_860_LOGOTOFF3, /* type */
416 0, /* rightshift */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
418 32, /* 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_LOGOTOFF3", /* name */
424 true, /* partial_inplace */
425 0xffffffff, /* src_mask */
426 0xffffffff, /* dst_mask */
427 false), /* pcrel_offset */
428
429 HOWTO (R_860_LOPC, /* type */
430 0, /* rightshift */
431 2, /* size (0 = byte, 1 = short, 2 = long) */
432 16, /* bitsize */
433 true, /* pc_relative */
434 0, /* bitpos */
435 complain_overflow_bitfield, /* complain_on_overflow */
436 bfd_elf_generic_reloc, /* special_function */
437 "R_860_LOPC", /* name */
438 false, /* partial_inplace */
439 0xffff, /* src_mask */
440 0xffff, /* dst_mask */
441 true), /* pcrel_offset */
442
443 HOWTO (R_860_HIGHADJ, /* type */
444 0, /* rightshift */
445 2, /* size (0 = byte, 1 = short, 2 = long) */
446 16, /* 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_HIGHADJ", /* name */
452 false, /* partial_inplace */
453 0xffff, /* src_mask */
454 0xffff, /* dst_mask */
455 false), /* pcrel_offset */
456
457 HOWTO (R_860_HAGOT, /* type */
458 0, /* rightshift */
459 2, /* size (0 = byte, 1 = short, 2 = long) */
460 16, /* bitsize */
461 false, /* pc_relative */
462 0, /* bitpos */
463 complain_overflow_dont, /* complain_on_overflow */
464 bfd_elf_generic_reloc, /* special_function */
465 "R_860_HAGOT", /* name */
466 false, /* partial_inplace */
467 0, /* src_mask */
468 0xffff, /* dst_mask */
469 true), /* pcrel_offset */
470
471 HOWTO (R_860_HAGOTOFF, /* type */
472 0, /* rightshift */
473 2, /* size (0 = byte, 1 = short, 2 = long) */
474 32, /* 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_HAGOTOFF", /* name */
480 true, /* partial_inplace */
481 0xffffffff, /* src_mask */
482 0xffffffff, /* dst_mask */
483 false), /* pcrel_offset */
484
485 HOWTO (R_860_HAPC, /* type */
486 0, /* rightshift */
487 2, /* size (0 = byte, 1 = short, 2 = long) */
488 16, /* bitsize */
489 true, /* pc_relative */
490 0, /* bitpos */
491 complain_overflow_bitfield, /* complain_on_overflow */
492 bfd_elf_generic_reloc, /* special_function */
493 "R_860_HAPC", /* name */
494 false, /* partial_inplace */
495 0xffff, /* src_mask */
496 0xffff, /* dst_mask */
497 true), /* pcrel_offset */
498
499 HOWTO (R_860_HIGH, /* type */
fdeafce7 500 16, /* rightshift */
0e5136c6
JE
501 2, /* size (0 = byte, 1 = short, 2 = long) */
502 16, /* 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_HIGH", /* name */
508 false, /* partial_inplace */
509 0xffff, /* src_mask */
510 0xffff, /* dst_mask */
511 false), /* pcrel_offset */
512
513 HOWTO (R_860_HIGOT, /* type */
514 0, /* rightshift */
515 2, /* size (0 = byte, 1 = short, 2 = long) */
516 16, /* bitsize */
517 false, /* pc_relative */
518 0, /* bitpos */
519 complain_overflow_dont, /* complain_on_overflow */
520 bfd_elf_generic_reloc, /* special_function */
521 "R_860_HIGOT", /* name */
522 false, /* partial_inplace */
523 0, /* src_mask */
524 0xffff, /* dst_mask */
525 true), /* pcrel_offset */
526
527 HOWTO (R_860_HIGOTOFF, /* type */
528 0, /* rightshift */
529 2, /* size (0 = byte, 1 = short, 2 = long) */
530 32, /* bitsize */
531 false, /* pc_relative */
532 0, /* bitpos */
533 complain_overflow_dont, /* complain_on_overflow */
534 bfd_elf_generic_reloc, /* special_function */
535 "R_860_HIGOTOFF", /* name */
536 true, /* partial_inplace */
537 0xffffffff, /* src_mask */
538 0xffffffff, /* dst_mask */
539 false), /* pcrel_offset */
540};
541
542\f
543static unsigned char elf_code_to_howto_index[R_860_max + 1];
544
545static reloc_howto_type *
546lookup_howto (rtype)
547 unsigned int rtype;
548{
549 static int initialized = 0;
550 int i;
551 int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
552 / sizeof (elf32_i860_howto_table[0]));
553
554 if (! initialized)
555 {
556 initialized = 1;
557 memset (elf_code_to_howto_index, 0xff,
558 sizeof (elf_code_to_howto_index));
559 for (i = 0; i < howto_tbl_size; i++)
560 elf_code_to_howto_index[elf32_i860_howto_table[i].type] = i;
561 }
562
563 BFD_ASSERT (rtype <= R_860_max);
564 i = elf_code_to_howto_index[rtype];
565 if (i >= howto_tbl_size)
566 return 0;
567 return elf32_i860_howto_table + i;
568}
569
570
571/* Given a BFD reloc, return the matching HOWTO structure. */
572static reloc_howto_type *
573elf32_i860_reloc_type_lookup (abfd, code)
574 bfd * abfd ATTRIBUTE_UNUSED;
575 bfd_reloc_code_real_type code;
576{
577 unsigned int rtype;
578
579 switch (code)
580 {
581 case BFD_RELOC_NONE:
582 rtype = R_860_NONE;
583 break;
584 case BFD_RELOC_32:
585 rtype = R_860_32;
586 break;
587 case BFD_RELOC_860_COPY:
588 rtype = R_860_COPY;
589 break;
590 case BFD_RELOC_860_GLOB_DAT:
591 rtype = R_860_GLOB_DAT;
592 break;
593 case BFD_RELOC_860_JUMP_SLOT:
594 rtype = R_860_JUMP_SLOT;
595 break;
596 case BFD_RELOC_860_RELATIVE:
597 rtype = R_860_RELATIVE;
598 break;
599 case BFD_RELOC_860_PC26:
600 rtype = R_860_PC26;
601 break;
602 case BFD_RELOC_860_PLT26:
603 rtype = R_860_PLT26;
604 break;
605 case BFD_RELOC_860_PC16:
606 rtype = R_860_PC16;
607 break;
608 case BFD_RELOC_860_LOW0:
609 rtype = R_860_LOW0;
610 break;
611 case BFD_RELOC_860_SPLIT0:
612 rtype = R_860_SPLIT0;
613 break;
614 case BFD_RELOC_860_LOW1:
615 rtype = R_860_LOW1;
616 break;
617 case BFD_RELOC_860_SPLIT1:
618 rtype = R_860_SPLIT1;
619 break;
620 case BFD_RELOC_860_LOW2:
621 rtype = R_860_LOW2;
622 break;
623 case BFD_RELOC_860_SPLIT2:
624 rtype = R_860_SPLIT2;
625 break;
626 case BFD_RELOC_860_LOW3:
627 rtype = R_860_LOW3;
628 break;
629 case BFD_RELOC_860_LOGOT0:
630 rtype = R_860_LOGOT0;
631 break;
632 case BFD_RELOC_860_SPGOT0:
633 rtype = R_860_SPGOT0;
634 break;
635 case BFD_RELOC_860_LOGOT1:
636 rtype = R_860_LOGOT1;
637 break;
638 case BFD_RELOC_860_SPGOT1:
639 rtype = R_860_SPGOT1;
640 break;
641 case BFD_RELOC_860_LOGOTOFF0:
642 rtype = R_860_LOGOTOFF0;
643 break;
644 case BFD_RELOC_860_SPGOTOFF0:
645 rtype = R_860_SPGOTOFF0;
646 break;
647 case BFD_RELOC_860_LOGOTOFF1:
648 rtype = R_860_LOGOTOFF1;
649 break;
650 case BFD_RELOC_860_SPGOTOFF1:
651 rtype = R_860_SPGOTOFF1;
652 break;
653 case BFD_RELOC_860_LOGOTOFF2:
654 rtype = R_860_LOGOTOFF2;
655 break;
656 case BFD_RELOC_860_LOGOTOFF3:
657 rtype = R_860_LOGOTOFF3;
658 break;
659 case BFD_RELOC_860_LOPC:
660 rtype = R_860_LOPC;
661 break;
662 case BFD_RELOC_860_HIGHADJ:
663 rtype = R_860_HIGHADJ;
664 break;
665 case BFD_RELOC_860_HAGOT:
666 rtype = R_860_HAGOT;
667 break;
668 case BFD_RELOC_860_HAGOTOFF:
669 rtype = R_860_HAGOTOFF;
670 break;
671 case BFD_RELOC_860_HAPC:
672 rtype = R_860_HAPC;
673 break;
674 case BFD_RELOC_860_HIGH:
675 rtype = R_860_HIGH;
676 break;
677 case BFD_RELOC_860_HIGOT:
678 rtype = R_860_HIGOT;
679 break;
680 case BFD_RELOC_860_HIGOTOFF:
681 rtype = R_860_HIGOTOFF;
682 break;
683 default:
684 rtype = 0;
685 break;
686 }
687 return lookup_howto (rtype);
688}
689
690
691/* Given a ELF reloc, return the matching HOWTO structure. */
692static void
693elf32_i860_info_to_howto_rela (abfd, bfd_reloc, elf_reloc)
694 bfd *abfd ATTRIBUTE_UNUSED;
695 arelent *bfd_reloc;
696 Elf64_Internal_Rela *elf_reloc;
697{
698 bfd_reloc->howto = lookup_howto (ELF32_R_TYPE (elf_reloc->r_info));
699}
700
252b5132 701
fdeafce7
JE
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. */
705static bfd_reloc_status_type
706elf32_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{
ded0649c 712 bfd_vma insn;
fdeafce7
JE
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
fdeafce7 717 /* Relocate. */
ded0649c 718 value += rello->r_addend;
fdeafce7 719
ded0649c 720 /* Separate the fields and insert. */
fdeafce7
JE
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
fdeafce7
JE
729/* Specialized relocation handler for R_860_PC16. This relocation
730 involves a 16-bit, PC-relative field that is split into two contiguous
731 parts. */
732static bfd_reloc_status_type
d670a150 733elf32_i860_relocate_pc16 (input_bfd, input_section, rello, contents, value)
fdeafce7 734 bfd *input_bfd;
d670a150 735 asection *input_section;
fdeafce7
JE
736 Elf_Internal_Rela *rello;
737 bfd_byte *contents;
738 bfd_vma value;
739{
ded0649c 740 bfd_vma insn;
d670a150
JE
741 reloc_howto_type *howto;
742 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
743 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
744
745 /* Adjust for PC-relative relocation. */
746 value -= (input_section->output_section->vma
747 + input_section->output_offset);
748 value -= rello->r_offset;
749
d670a150 750 /* Relocate. */
ded0649c 751 value += rello->r_addend;
d670a150 752
ded0649c 753 /* Separate the fields and insert. */
d670a150
JE
754 value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
755 insn = (insn & ~howto->dst_mask) | value;
756
757 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
758 return bfd_reloc_ok;
759
fdeafce7 760}
fdeafce7
JE
761
762
763/* Specialized relocation handler for R_860_HIGHADJ. */
764static bfd_reloc_status_type
765elf32_i860_relocate_highadj (input_bfd, rel, contents, value)
766 bfd *input_bfd;
767 Elf_Internal_Rela *rel;
768 bfd_byte *contents;
769 bfd_vma value;
770{
771 bfd_vma insn;
772
773 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
774
775 value += ((rel->r_addend & 0x8000) << 1);
776 value += rel->r_addend;
777 value = ((value >> 16) & 0xffff);
fdeafce7
JE
778
779 insn = (insn & 0xffff0000) | value;
780
781 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
782 return bfd_reloc_ok;
783}
784
785
786/* Perform a single relocation. By default we use the standard BFD
787 routines. However, we handle some specially. */
788static bfd_reloc_status_type
789i860_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
790 reloc_howto_type * howto;
791 bfd * input_bfd;
792 asection * input_section;
793 bfd_byte * contents;
794 Elf_Internal_Rela * rel;
795 bfd_vma relocation;
796{
797 return _bfd_final_link_relocate (howto, input_bfd, input_section,
798 contents, rel->r_offset, relocation,
799 rel->r_addend);
800}
801
802
803/* Relocate an i860 ELF section.
252b5132 804
fdeafce7
JE
805 This is boiler-plate code copied from fr30.
806 There is some attempt to make this function usable for many architectures,
807 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
808 if only to serve as a learning tool.
809
810 The RELOCATE_SECTION function is called by the new ELF backend linker
811 to handle the relocations for a section.
812
813 The relocs are always passed as Rela structures; if the section
814 actually uses Rel structures, the r_addend field will always be
815 zero.
816
817 This function is responsible for adjusting the section contents as
818 necessary, and (if using Rela relocs and generating a relocateable
819 output file) adjusting the reloc addend as necessary.
820
821 This function does not have to worry about setting the reloc
822 address or the reloc symbol index.
823
824 LOCAL_SYMS is a pointer to the swapped in local symbols.
825
826 LOCAL_SECTIONS is an array giving the section in the input file
827 corresponding to the st_shndx field of each local symbol.
828
829 The global hash table entry for the global symbols can be found
830 via elf_sym_hashes (input_bfd).
831
832 When generating relocateable output, this function must handle
833 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
834 going to be the section symbol corresponding to the output
835 section, which means that the addend must be adjusted
836 accordingly. */
837static boolean
838elf32_i860_relocate_section (output_bfd, info, input_bfd, input_section,
839 contents, relocs, local_syms, local_sections)
840 bfd * output_bfd ATTRIBUTE_UNUSED;
841 struct bfd_link_info * info;
842 bfd * input_bfd;
843 asection * input_section;
844 bfd_byte * contents;
845 Elf_Internal_Rela * relocs;
846 Elf_Internal_Sym * local_syms;
847 asection ** local_sections;
848{
849 Elf_Internal_Shdr * symtab_hdr;
850 struct elf_link_hash_entry ** sym_hashes;
851 Elf_Internal_Rela * rel;
852 Elf_Internal_Rela * relend;
853
854 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
855 sym_hashes = elf_sym_hashes (input_bfd);
856 relend = relocs + input_section->reloc_count;
857
858 for (rel = relocs; rel < relend; rel ++)
859 {
860 reloc_howto_type * howto;
861 unsigned long r_symndx;
862 Elf_Internal_Sym * sym;
863 asection * sec;
864 struct elf_link_hash_entry * h;
865 bfd_vma relocation;
866 bfd_reloc_status_type r;
867 const char * name = NULL;
868 int r_type;
869
870 r_type = ELF32_R_TYPE (rel->r_info);
871
872#if 0
873 if ( r_type == R_860_GNU_VTINHERIT
874 || r_type == R_860_GNU_VTENTRY)
875 continue;
876#endif
877
878 r_symndx = ELF32_R_SYM (rel->r_info);
879
880 if (info->relocateable)
881 {
882 /* This is a relocateable link. We don't have to change
883 anything, unless the reloc is against a section symbol,
884 in which case we have to adjust according to where the
885 section symbol winds up in the output section. */
886 if (r_symndx < symtab_hdr->sh_info)
887 {
888 sym = local_syms + r_symndx;
889
890 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
891 {
892 sec = local_sections [r_symndx];
893 rel->r_addend += sec->output_offset + sym->st_value;
894 }
895 }
896
897 continue;
898 }
899
900 /* This is a final link. */
901 howto = lookup_howto (ELF32_R_TYPE (rel->r_info));
902 h = NULL;
903 sym = NULL;
904 sec = NULL;
905
906 if (r_symndx < symtab_hdr->sh_info)
907 {
908 sym = local_syms + r_symndx;
909 sec = local_sections [r_symndx];
910 relocation = (sec->output_section->vma
911 + sec->output_offset
912 + sym->st_value);
913
914 name = bfd_elf_string_from_elf_section
915 (input_bfd, symtab_hdr->sh_link, sym->st_name);
916 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
917 }
918 else
919 {
920 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
921
922 while (h->root.type == bfd_link_hash_indirect
923 || h->root.type == bfd_link_hash_warning)
924 h = (struct elf_link_hash_entry *) h->root.u.i.link;
925
926 name = h->root.root.string;
927
928 if (h->root.type == bfd_link_hash_defined
929 || h->root.type == bfd_link_hash_defweak)
930 {
931 sec = h->root.u.def.section;
932 relocation = (h->root.u.def.value
933 + sec->output_section->vma
934 + sec->output_offset);
935 }
936 else if (h->root.type == bfd_link_hash_undefweak)
937 {
938 relocation = 0;
939 }
940 else
941 {
942 if (! ((*info->callbacks->undefined_symbol)
943 (info, h->root.root.string, input_bfd,
944 input_section, rel->r_offset, true)))
945 return false;
946 relocation = 0;
947 }
948 }
949
950 switch (r_type)
951 {
952 default:
953 r = i860_final_link_relocate (howto, input_bfd, input_section,
954 contents, rel, relocation);
955 break;
956
957 case R_860_HIGHADJ:
958 r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
959 relocation);
960 break;
961
fdeafce7 962 case R_860_PC16:
d670a150
JE
963 r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
964 contents, relocation);
fdeafce7 965 break;
fdeafce7
JE
966
967 case R_860_SPLIT0:
968 case R_860_SPLIT1:
969 case R_860_SPLIT2:
970 r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
971 relocation);
972 break;
973
974 /* We do not yet handle GOT/PLT/Dynamic relocations. */
975 case R_860_COPY:
976 case R_860_GLOB_DAT:
977 case R_860_JUMP_SLOT:
978 case R_860_RELATIVE:
979 case R_860_PLT26:
980 case R_860_LOGOT0:
981 case R_860_SPGOT0:
982 case R_860_LOGOT1:
983 case R_860_SPGOT1:
984 case R_860_LOGOTOFF0:
985 case R_860_SPGOTOFF0:
986 case R_860_LOGOTOFF1:
987 case R_860_SPGOTOFF1:
988 case R_860_LOGOTOFF2:
989 case R_860_LOGOTOFF3:
990 case R_860_LOPC:
991 case R_860_HAGOT:
992 case R_860_HAGOTOFF:
993 case R_860_HAPC:
994 case R_860_HIGOT:
995 case R_860_HIGOTOFF:
996 r = bfd_reloc_notsupported;
997 break;
998 }
999
1000 if (r != bfd_reloc_ok)
1001 {
1002 const char * msg = (const char *) NULL;
1003
1004 switch (r)
1005 {
1006 case bfd_reloc_overflow:
1007 r = info->callbacks->reloc_overflow
1008 (info, name, howto->name, (bfd_vma) 0,
1009 input_bfd, input_section, rel->r_offset);
1010 break;
1011
1012 case bfd_reloc_undefined:
1013 r = info->callbacks->undefined_symbol
1014 (info, name, input_bfd, input_section, rel->r_offset, true);
1015 break;
1016
1017 case bfd_reloc_outofrange:
1018 msg = _("internal error: out of range error");
1019 break;
1020
1021 case bfd_reloc_notsupported:
1022 msg = _("internal error: unsupported relocation error");
1023 break;
1024
1025 case bfd_reloc_dangerous:
1026 msg = _("internal error: dangerous relocation");
1027 break;
1028
1029 default:
1030 msg = _("internal error: unknown error");
1031 break;
1032 }
1033
1034 if (msg)
1035 r = info->callbacks->warning
1036 (info, msg, name, input_bfd, input_section, rel->r_offset);
1037
1038 if (! r)
1039 return false;
1040 }
1041 }
1042
1043 return true;
1044}
1045
1046
1047\f
9d751335
JE
1048#define TARGET_BIG_SYM bfd_elf32_i860_vec
1049#define TARGET_BIG_NAME "elf32-i860"
1050#define TARGET_LITTLE_SYM bfd_elf32_i860_little_vec
1051#define TARGET_LITTLE_NAME "elf32-i860-little"
0e5136c6
JE
1052#define ELF_ARCH bfd_arch_i860
1053#define ELF_MACHINE_CODE EM_860
1054#define ELF_MAXPAGESIZE 4096
1055
fdeafce7 1056#define elf_info_to_howto_rel NULL
0e5136c6 1057#define elf_info_to_howto elf32_i860_info_to_howto_rela
fdeafce7 1058#define elf_backend_relocate_section elf32_i860_relocate_section
0e5136c6 1059#define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
252b5132
RH
1060
1061#include "elf32-target.h"
This page took 0.137576 seconds and 4 git commands to generate.