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