2000-12-04 Michael Snyder <msnyder@cleaver.cygnus.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 44
c1e8b710
JE
45static bfd_reloc_status_type elf32_i860_relocate_pc26
46 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
47
fdeafce7
JE
48static bfd_reloc_status_type elf32_i860_relocate_highadj
49 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
50
51static 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
55static bfd_reloc_status_type i860_final_link_relocate
56 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
57 Elf_Internal_Rela *, bfd_vma));
58
de24da47
JE
59static boolean elf32_i860_is_local_label_name
60 PARAMS ((bfd *, const char *));
61
fdeafce7 62
0e5136c6
JE
63
64/* This howto table is preliminary. */
65static reloc_howto_type elf32_i860_howto_table [] =
66{
67 /* This relocation does nothing. */
68 HOWTO (R_860_NONE, /* type */
69 0, /* rightshift */
70 2, /* size (0 = byte, 1 = short, 2 = long) */
71 32, /* bitsize */
72 false, /* pc_relative */
73 0, /* bitpos */
74 complain_overflow_bitfield, /* complain_on_overflow */
75 bfd_elf_generic_reloc, /* special_function */
76 "R_860_NONE", /* name */
77 false, /* partial_inplace */
78 0, /* src_mask */
79 0, /* dst_mask */
80 false), /* pcrel_offset */
81
82 /* A 32-bit absolute relocation. */
83 HOWTO (R_860_32, /* type */
84 0, /* rightshift */
85 2, /* size (0 = byte, 1 = short, 2 = long) */
86 32, /* bitsize */
87 false, /* pc_relative */
88 0, /* bitpos */
89 complain_overflow_bitfield, /* complain_on_overflow */
90 bfd_elf_generic_reloc, /* special_function */
91 "R_860_32", /* name */
92 false, /* partial_inplace */
93 0xffffffff, /* src_mask */
94 0xffffffff, /* dst_mask */
95 false), /* pcrel_offset */
96
97 HOWTO (R_860_COPY, /* type */
98 0, /* rightshift */
99 2, /* size (0 = byte, 1 = short, 2 = long) */
100 32, /* bitsize */
101 false, /* pc_relative */
102 0, /* bitpos */
103 complain_overflow_bitfield, /* complain_on_overflow */
104 bfd_elf_generic_reloc, /* special_function */
105 "R_860_COPY", /* name */
106 true, /* partial_inplace */
107 0xffffffff, /* src_mask */
108 0xffffffff, /* dst_mask */
109 false), /* pcrel_offset */
110
111 HOWTO (R_860_GLOB_DAT, /* type */
112 0, /* rightshift */
113 2, /* size (0 = byte, 1 = short, 2 = long) */
114 32, /* bitsize */
115 false, /* pc_relative */
116 0, /* bitpos */
117 complain_overflow_bitfield, /* complain_on_overflow */
118 bfd_elf_generic_reloc, /* special_function */
119 "R_860_GLOB_DAT", /* name */
120 true, /* partial_inplace */
121 0xffffffff, /* src_mask */
122 0xffffffff, /* dst_mask */
123 false), /* pcrel_offset */
124
125 HOWTO (R_860_JUMP_SLOT, /* type */
126 0, /* rightshift */
127 2, /* size (0 = byte, 1 = short, 2 = long) */
128 32, /* bitsize */
129 false, /* pc_relative */
130 0, /* bitpos */
131 complain_overflow_bitfield, /* complain_on_overflow */
132 bfd_elf_generic_reloc, /* special_function */
133 "R_860_JUMP_SLOT", /* name */
134 true, /* partial_inplace */
135 0xffffffff, /* src_mask */
136 0xffffffff, /* dst_mask */
137 false), /* pcrel_offset */
138
139 HOWTO (R_860_RELATIVE, /* type */
140 0, /* rightshift */
141 2, /* size (0 = byte, 1 = short, 2 = long) */
142 32, /* bitsize */
143 false, /* pc_relative */
144 0, /* bitpos */
145 complain_overflow_bitfield, /* complain_on_overflow */
146 bfd_elf_generic_reloc, /* special_function */
147 "R_860_RELATIVE", /* name */
148 true, /* partial_inplace */
149 0xffffffff, /* src_mask */
150 0xffffffff, /* dst_mask */
151 false), /* pcrel_offset */
152
153 /* A 26-bit PC-relative relocation. */
154 HOWTO (R_860_PC26, /* type */
fdeafce7 155 2, /* rightshift */
0e5136c6
JE
156 2, /* size (0 = byte, 1 = short, 2 = long) */
157 26, /* bitsize */
158 true, /* pc_relative */
159 0, /* bitpos */
160 complain_overflow_bitfield, /* complain_on_overflow */
161 bfd_elf_generic_reloc, /* special_function */
162 "R_860_PC26", /* name */
163 false, /* partial_inplace */
164 0x3ffffff, /* src_mask */
165 0x3ffffff, /* dst_mask */
166 true), /* pcrel_offset */
167
168 HOWTO (R_860_PLT26, /* type */
169 0, /* rightshift */
170 2, /* size (0 = byte, 1 = short, 2 = long) */
171 26, /* bitsize */
172 true, /* pc_relative */
173 0, /* bitpos */
174 complain_overflow_bitfield, /* complain_on_overflow */
175 bfd_elf_generic_reloc, /* special_function */
176 "R_860_PLT26", /* name */
177 true, /* partial_inplace */
178 0xffffffff, /* src_mask */
179 0xffffffff, /* dst_mask */
180 true), /* pcrel_offset */
181
182 /* A 16-bit PC-relative relocation. */
183 HOWTO (R_860_PC16, /* type */
fdeafce7 184 2, /* rightshift */
0e5136c6
JE
185 2, /* size (0 = byte, 1 = short, 2 = long) */
186 16, /* bitsize */
187 true, /* pc_relative */
188 0, /* bitpos */
189 complain_overflow_bitfield, /* complain_on_overflow */
190 bfd_elf_generic_reloc, /* special_function */
191 "R_860_PC16", /* name */
192 false, /* partial_inplace */
305d537e
JE
193 0x1f07ff, /* src_mask */
194 0x1f07ff, /* dst_mask */
0e5136c6
JE
195 true), /* pcrel_offset */
196
197 HOWTO (R_860_LOW0, /* type */
198 0, /* rightshift */
199 2, /* size (0 = byte, 1 = short, 2 = long) */
200 16, /* bitsize */
201 false, /* pc_relative */
202 0, /* bitpos */
203 complain_overflow_dont, /* complain_on_overflow */
204 bfd_elf_generic_reloc, /* special_function */
205 "R_860_LOW0", /* name */
206 false, /* partial_inplace */
207 0xffff, /* src_mask */
208 0xffff, /* dst_mask */
209 false), /* pcrel_offset */
210
211 HOWTO (R_860_SPLIT0, /* type */
212 0, /* rightshift */
213 2, /* size (0 = byte, 1 = short, 2 = long) */
214 16, /* bitsize */
215 false, /* pc_relative */
216 0, /* bitpos */
217 complain_overflow_dont, /* complain_on_overflow */
218 bfd_elf_generic_reloc, /* special_function */
219 "R_860_SPLIT0", /* name */
220 false, /* partial_inplace */
221 0x1f07ff, /* src_mask */
222 0x1f07ff, /* dst_mask */
223 false), /* pcrel_offset */
224
225 HOWTO (R_860_LOW1, /* type */
226 0, /* rightshift */
227 2, /* size (0 = byte, 1 = short, 2 = long) */
228 16, /* bitsize */
229 false, /* pc_relative */
230 0, /* bitpos */
231 complain_overflow_dont, /* complain_on_overflow */
232 bfd_elf_generic_reloc, /* special_function */
233 "R_860_LOW1", /* name */
234 false, /* partial_inplace */
235 0xfffe, /* src_mask */
236 0xfffe, /* dst_mask */
237 false), /* pcrel_offset */
238
239 HOWTO (R_860_SPLIT1, /* type */
240 0, /* rightshift */
241 2, /* size (0 = byte, 1 = short, 2 = long) */
242 16, /* bitsize */
243 false, /* pc_relative */
244 0, /* bitpos */
245 complain_overflow_dont, /* complain_on_overflow */
246 bfd_elf_generic_reloc, /* special_function */
247 "R_860_SPLIT1", /* name */
248 false, /* partial_inplace */
305d537e
JE
249 0x1f07fe, /* src_mask */
250 0x1f07fe, /* dst_mask */
0e5136c6
JE
251 false), /* pcrel_offset */
252
253 HOWTO (R_860_LOW2, /* type */
254 0, /* rightshift */
255 2, /* size (0 = byte, 1 = short, 2 = long) */
256 16, /* bitsize */
257 false, /* pc_relative */
258 0, /* bitpos */
259 complain_overflow_dont, /* complain_on_overflow */
260 bfd_elf_generic_reloc, /* special_function */
261 "R_860_LOW2", /* name */
262 false, /* partial_inplace */
263 0xfffc, /* src_mask */
264 0xfffc, /* dst_mask */
265 false), /* pcrel_offset */
266
267 HOWTO (R_860_SPLIT2, /* type */
268 0, /* rightshift */
269 2, /* size (0 = byte, 1 = short, 2 = long) */
270 16, /* bitsize */
271 false, /* pc_relative */
272 0, /* bitpos */
273 complain_overflow_dont, /* complain_on_overflow */
274 bfd_elf_generic_reloc, /* special_function */
275 "R_860_SPLIT2", /* name */
276 false, /* partial_inplace */
305d537e
JE
277 0x1f07fc, /* src_mask */
278 0x1f07fc, /* dst_mask */
0e5136c6
JE
279 false), /* pcrel_offset */
280
281 HOWTO (R_860_LOW3, /* type */
282 0, /* rightshift */
283 2, /* size (0 = byte, 1 = short, 2 = long) */
284 16, /* bitsize */
285 false, /* pc_relative */
286 0, /* bitpos */
287 complain_overflow_dont, /* complain_on_overflow */
288 bfd_elf_generic_reloc, /* special_function */
289 "R_860_LOW3", /* name */
290 false, /* partial_inplace */
291 0xfff8, /* src_mask */
292 0xfff8, /* dst_mask */
293 false), /* pcrel_offset */
294
295 HOWTO (R_860_LOGOT0, /* type */
296 0, /* rightshift */
297 2, /* size (0 = byte, 1 = short, 2 = long) */
298 16, /* bitsize */
299 false, /* pc_relative */
300 0, /* bitpos */
301 complain_overflow_dont, /* complain_on_overflow */
302 bfd_elf_generic_reloc, /* special_function */
303 "R_860_LOGOT0", /* name */
304 false, /* partial_inplace */
305 0, /* src_mask */
306 0xffff, /* dst_mask */
307 true), /* pcrel_offset */
308
309 HOWTO (R_860_SPGOT0, /* type */
310 0, /* rightshift */
311 2, /* size (0 = byte, 1 = short, 2 = long) */
312 16, /* bitsize */
313 false, /* pc_relative */
314 0, /* bitpos */
315 complain_overflow_dont, /* complain_on_overflow */
316 bfd_elf_generic_reloc, /* special_function */
317 "R_860_SPGOT0", /* name */
318 false, /* partial_inplace */
319 0, /* src_mask */
320 0xffff, /* dst_mask */
321 true), /* pcrel_offset */
322
323 HOWTO (R_860_LOGOT1, /* type */
324 0, /* rightshift */
325 2, /* size (0 = byte, 1 = short, 2 = long) */
326 16, /* bitsize */
327 false, /* pc_relative */
328 0, /* bitpos */
329 complain_overflow_dont, /* complain_on_overflow */
330 bfd_elf_generic_reloc, /* special_function */
331 "R_860_LOGOT1", /* name */
332 false, /* partial_inplace */
333 0, /* src_mask */
334 0xffff, /* dst_mask */
335 true), /* pcrel_offset */
336
337 HOWTO (R_860_SPGOT1, /* type */
338 0, /* rightshift */
339 2, /* size (0 = byte, 1 = short, 2 = long) */
340 16, /* bitsize */
341 false, /* pc_relative */
342 0, /* bitpos */
343 complain_overflow_dont, /* complain_on_overflow */
344 bfd_elf_generic_reloc, /* special_function */
345 "R_860_SPGOT1", /* name */
346 false, /* partial_inplace */
347 0, /* src_mask */
348 0xffff, /* dst_mask */
349 true), /* pcrel_offset */
350
351 HOWTO (R_860_LOGOTOFF0, /* type */
352 0, /* rightshift */
353 2, /* size (0 = byte, 1 = short, 2 = long) */
354 32, /* bitsize */
355 false, /* pc_relative */
356 0, /* bitpos */
357 complain_overflow_dont, /* complain_on_overflow */
358 bfd_elf_generic_reloc, /* special_function */
359 "R_860_LOGOTOFF0", /* name */
360 true, /* partial_inplace */
361 0xffffffff, /* src_mask */
362 0xffffffff, /* dst_mask */
363 false), /* pcrel_offset */
364
365 HOWTO (R_860_SPGOTOFF0, /* type */
366 0, /* rightshift */
367 2, /* size (0 = byte, 1 = short, 2 = long) */
368 32, /* bitsize */
369 false, /* pc_relative */
370 0, /* bitpos */
371 complain_overflow_dont, /* complain_on_overflow */
372 bfd_elf_generic_reloc, /* special_function */
373 "R_860_SPGOTOFF0", /* name */
374 true, /* partial_inplace */
375 0xffffffff, /* src_mask */
376 0xffffffff, /* dst_mask */
377 false), /* pcrel_offset */
378
379 HOWTO (R_860_LOGOTOFF1, /* type */
380 0, /* rightshift */
381 2, /* size (0 = byte, 1 = short, 2 = long) */
382 32, /* bitsize */
383 false, /* pc_relative */
384 0, /* bitpos */
385 complain_overflow_dont, /* complain_on_overflow */
386 bfd_elf_generic_reloc, /* special_function */
387 "R_860_LOGOTOFF1", /* name */
388 true, /* partial_inplace */
389 0xffffffff, /* src_mask */
390 0xffffffff, /* dst_mask */
391 false), /* pcrel_offset */
392
393 HOWTO (R_860_SPGOTOFF1, /* type */
394 0, /* rightshift */
395 2, /* size (0 = byte, 1 = short, 2 = long) */
396 32, /* bitsize */
397 false, /* pc_relative */
398 0, /* bitpos */
399 complain_overflow_dont, /* complain_on_overflow */
400 bfd_elf_generic_reloc, /* special_function */
401 "R_860_SPGOTOFF1", /* name */
402 true, /* partial_inplace */
403 0xffffffff, /* src_mask */
404 0xffffffff, /* dst_mask */
405 false), /* pcrel_offset */
406
407 HOWTO (R_860_LOGOTOFF2, /* type */
408 0, /* rightshift */
409 2, /* size (0 = byte, 1 = short, 2 = long) */
410 32, /* bitsize */
411 false, /* pc_relative */
412 0, /* bitpos */
413 complain_overflow_dont, /* complain_on_overflow */
414 bfd_elf_generic_reloc, /* special_function */
415 "R_860_LOGOTOFF2", /* name */
416 true, /* partial_inplace */
417 0xffffffff, /* src_mask */
418 0xffffffff, /* dst_mask */
419 false), /* pcrel_offset */
420
421 HOWTO (R_860_LOGOTOFF3, /* type */
422 0, /* rightshift */
423 2, /* size (0 = byte, 1 = short, 2 = long) */
424 32, /* bitsize */
425 false, /* pc_relative */
426 0, /* bitpos */
427 complain_overflow_dont, /* complain_on_overflow */
428 bfd_elf_generic_reloc, /* special_function */
429 "R_860_LOGOTOFF3", /* name */
430 true, /* partial_inplace */
431 0xffffffff, /* src_mask */
432 0xffffffff, /* dst_mask */
433 false), /* pcrel_offset */
434
435 HOWTO (R_860_LOPC, /* type */
436 0, /* rightshift */
437 2, /* size (0 = byte, 1 = short, 2 = long) */
438 16, /* bitsize */
439 true, /* pc_relative */
440 0, /* bitpos */
441 complain_overflow_bitfield, /* complain_on_overflow */
442 bfd_elf_generic_reloc, /* special_function */
443 "R_860_LOPC", /* name */
444 false, /* partial_inplace */
445 0xffff, /* src_mask */
446 0xffff, /* dst_mask */
447 true), /* pcrel_offset */
448
449 HOWTO (R_860_HIGHADJ, /* type */
450 0, /* rightshift */
451 2, /* size (0 = byte, 1 = short, 2 = long) */
452 16, /* bitsize */
453 false, /* pc_relative */
454 0, /* bitpos */
455 complain_overflow_dont, /* complain_on_overflow */
456 bfd_elf_generic_reloc, /* special_function */
457 "R_860_HIGHADJ", /* name */
458 false, /* partial_inplace */
459 0xffff, /* src_mask */
460 0xffff, /* dst_mask */
461 false), /* pcrel_offset */
462
463 HOWTO (R_860_HAGOT, /* type */
464 0, /* rightshift */
465 2, /* size (0 = byte, 1 = short, 2 = long) */
466 16, /* bitsize */
467 false, /* pc_relative */
468 0, /* bitpos */
469 complain_overflow_dont, /* complain_on_overflow */
470 bfd_elf_generic_reloc, /* special_function */
471 "R_860_HAGOT", /* name */
472 false, /* partial_inplace */
473 0, /* src_mask */
474 0xffff, /* dst_mask */
475 true), /* pcrel_offset */
476
477 HOWTO (R_860_HAGOTOFF, /* type */
478 0, /* rightshift */
479 2, /* size (0 = byte, 1 = short, 2 = long) */
480 32, /* bitsize */
481 false, /* pc_relative */
482 0, /* bitpos */
483 complain_overflow_dont, /* complain_on_overflow */
484 bfd_elf_generic_reloc, /* special_function */
485 "R_860_HAGOTOFF", /* name */
486 true, /* partial_inplace */
487 0xffffffff, /* src_mask */
488 0xffffffff, /* dst_mask */
489 false), /* pcrel_offset */
490
491 HOWTO (R_860_HAPC, /* type */
492 0, /* rightshift */
493 2, /* size (0 = byte, 1 = short, 2 = long) */
494 16, /* bitsize */
495 true, /* pc_relative */
496 0, /* bitpos */
497 complain_overflow_bitfield, /* complain_on_overflow */
498 bfd_elf_generic_reloc, /* special_function */
499 "R_860_HAPC", /* name */
500 false, /* partial_inplace */
501 0xffff, /* src_mask */
502 0xffff, /* dst_mask */
503 true), /* pcrel_offset */
504
505 HOWTO (R_860_HIGH, /* type */
fdeafce7 506 16, /* rightshift */
0e5136c6
JE
507 2, /* size (0 = byte, 1 = short, 2 = long) */
508 16, /* bitsize */
509 false, /* pc_relative */
510 0, /* bitpos */
511 complain_overflow_dont, /* complain_on_overflow */
512 bfd_elf_generic_reloc, /* special_function */
513 "R_860_HIGH", /* name */
514 false, /* partial_inplace */
515 0xffff, /* src_mask */
516 0xffff, /* dst_mask */
517 false), /* pcrel_offset */
518
519 HOWTO (R_860_HIGOT, /* type */
520 0, /* rightshift */
521 2, /* size (0 = byte, 1 = short, 2 = long) */
522 16, /* bitsize */
523 false, /* pc_relative */
524 0, /* bitpos */
525 complain_overflow_dont, /* complain_on_overflow */
526 bfd_elf_generic_reloc, /* special_function */
527 "R_860_HIGOT", /* name */
528 false, /* partial_inplace */
529 0, /* src_mask */
530 0xffff, /* dst_mask */
531 true), /* pcrel_offset */
532
533 HOWTO (R_860_HIGOTOFF, /* type */
534 0, /* rightshift */
535 2, /* size (0 = byte, 1 = short, 2 = long) */
536 32, /* bitsize */
537 false, /* pc_relative */
538 0, /* bitpos */
539 complain_overflow_dont, /* complain_on_overflow */
540 bfd_elf_generic_reloc, /* special_function */
541 "R_860_HIGOTOFF", /* name */
542 true, /* partial_inplace */
543 0xffffffff, /* src_mask */
544 0xffffffff, /* dst_mask */
545 false), /* pcrel_offset */
546};
547
548\f
549static unsigned char elf_code_to_howto_index[R_860_max + 1];
550
551static reloc_howto_type *
552lookup_howto (rtype)
553 unsigned int rtype;
554{
555 static int initialized = 0;
556 int i;
557 int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
558 / sizeof (elf32_i860_howto_table[0]));
559
560 if (! initialized)
561 {
562 initialized = 1;
563 memset (elf_code_to_howto_index, 0xff,
564 sizeof (elf_code_to_howto_index));
565 for (i = 0; i < howto_tbl_size; i++)
566 elf_code_to_howto_index[elf32_i860_howto_table[i].type] = i;
567 }
568
569 BFD_ASSERT (rtype <= R_860_max);
570 i = elf_code_to_howto_index[rtype];
571 if (i >= howto_tbl_size)
572 return 0;
573 return elf32_i860_howto_table + i;
574}
575
576
577/* Given a BFD reloc, return the matching HOWTO structure. */
578static reloc_howto_type *
579elf32_i860_reloc_type_lookup (abfd, code)
580 bfd * abfd ATTRIBUTE_UNUSED;
581 bfd_reloc_code_real_type code;
582{
583 unsigned int rtype;
584
585 switch (code)
586 {
587 case BFD_RELOC_NONE:
588 rtype = R_860_NONE;
589 break;
590 case BFD_RELOC_32:
591 rtype = R_860_32;
592 break;
593 case BFD_RELOC_860_COPY:
594 rtype = R_860_COPY;
595 break;
596 case BFD_RELOC_860_GLOB_DAT:
597 rtype = R_860_GLOB_DAT;
598 break;
599 case BFD_RELOC_860_JUMP_SLOT:
600 rtype = R_860_JUMP_SLOT;
601 break;
602 case BFD_RELOC_860_RELATIVE:
603 rtype = R_860_RELATIVE;
604 break;
605 case BFD_RELOC_860_PC26:
606 rtype = R_860_PC26;
607 break;
608 case BFD_RELOC_860_PLT26:
609 rtype = R_860_PLT26;
610 break;
611 case BFD_RELOC_860_PC16:
612 rtype = R_860_PC16;
613 break;
614 case BFD_RELOC_860_LOW0:
615 rtype = R_860_LOW0;
616 break;
617 case BFD_RELOC_860_SPLIT0:
618 rtype = R_860_SPLIT0;
619 break;
620 case BFD_RELOC_860_LOW1:
621 rtype = R_860_LOW1;
622 break;
623 case BFD_RELOC_860_SPLIT1:
624 rtype = R_860_SPLIT1;
625 break;
626 case BFD_RELOC_860_LOW2:
627 rtype = R_860_LOW2;
628 break;
629 case BFD_RELOC_860_SPLIT2:
630 rtype = R_860_SPLIT2;
631 break;
632 case BFD_RELOC_860_LOW3:
633 rtype = R_860_LOW3;
634 break;
635 case BFD_RELOC_860_LOGOT0:
636 rtype = R_860_LOGOT0;
637 break;
638 case BFD_RELOC_860_SPGOT0:
639 rtype = R_860_SPGOT0;
640 break;
641 case BFD_RELOC_860_LOGOT1:
642 rtype = R_860_LOGOT1;
643 break;
644 case BFD_RELOC_860_SPGOT1:
645 rtype = R_860_SPGOT1;
646 break;
647 case BFD_RELOC_860_LOGOTOFF0:
648 rtype = R_860_LOGOTOFF0;
649 break;
650 case BFD_RELOC_860_SPGOTOFF0:
651 rtype = R_860_SPGOTOFF0;
652 break;
653 case BFD_RELOC_860_LOGOTOFF1:
654 rtype = R_860_LOGOTOFF1;
655 break;
656 case BFD_RELOC_860_SPGOTOFF1:
657 rtype = R_860_SPGOTOFF1;
658 break;
659 case BFD_RELOC_860_LOGOTOFF2:
660 rtype = R_860_LOGOTOFF2;
661 break;
662 case BFD_RELOC_860_LOGOTOFF3:
663 rtype = R_860_LOGOTOFF3;
664 break;
665 case BFD_RELOC_860_LOPC:
666 rtype = R_860_LOPC;
667 break;
668 case BFD_RELOC_860_HIGHADJ:
669 rtype = R_860_HIGHADJ;
670 break;
671 case BFD_RELOC_860_HAGOT:
672 rtype = R_860_HAGOT;
673 break;
674 case BFD_RELOC_860_HAGOTOFF:
675 rtype = R_860_HAGOTOFF;
676 break;
677 case BFD_RELOC_860_HAPC:
678 rtype = R_860_HAPC;
679 break;
680 case BFD_RELOC_860_HIGH:
681 rtype = R_860_HIGH;
682 break;
683 case BFD_RELOC_860_HIGOT:
684 rtype = R_860_HIGOT;
685 break;
686 case BFD_RELOC_860_HIGOTOFF:
687 rtype = R_860_HIGOTOFF;
688 break;
689 default:
690 rtype = 0;
691 break;
692 }
693 return lookup_howto (rtype);
694}
695
696
697/* Given a ELF reloc, return the matching HOWTO structure. */
698static void
699elf32_i860_info_to_howto_rela (abfd, bfd_reloc, elf_reloc)
700 bfd *abfd ATTRIBUTE_UNUSED;
701 arelent *bfd_reloc;
702 Elf64_Internal_Rela *elf_reloc;
703{
704 bfd_reloc->howto = lookup_howto (ELF32_R_TYPE (elf_reloc->r_info));
705}
706
252b5132 707
fdeafce7
JE
708\f
709/* Specialized relocation handler for R_860_SPLITn. These relocations
710 involves a 16-bit field that is split into two contiguous parts. */
711static bfd_reloc_status_type
712elf32_i860_relocate_splitn (input_bfd, rello, contents, value)
713 bfd *input_bfd;
714 Elf_Internal_Rela *rello;
715 bfd_byte *contents;
716 bfd_vma value;
717{
ded0649c 718 bfd_vma insn;
fdeafce7
JE
719 reloc_howto_type *howto;
720 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
721 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
722
fdeafce7 723 /* Relocate. */
ded0649c 724 value += rello->r_addend;
fdeafce7 725
ded0649c 726 /* Separate the fields and insert. */
fdeafce7
JE
727 value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
728 insn = (insn & ~howto->dst_mask) | value;
729
730 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
731 return bfd_reloc_ok;
732}
733
734
fdeafce7
JE
735/* Specialized relocation handler for R_860_PC16. This relocation
736 involves a 16-bit, PC-relative field that is split into two contiguous
737 parts. */
738static bfd_reloc_status_type
d670a150 739elf32_i860_relocate_pc16 (input_bfd, input_section, rello, contents, value)
fdeafce7 740 bfd *input_bfd;
d670a150 741 asection *input_section;
fdeafce7
JE
742 Elf_Internal_Rela *rello;
743 bfd_byte *contents;
744 bfd_vma value;
745{
ded0649c 746 bfd_vma insn;
d670a150
JE
747 reloc_howto_type *howto;
748 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
749 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
750
751 /* Adjust for PC-relative relocation. */
752 value -= (input_section->output_section->vma
753 + input_section->output_offset);
754 value -= rello->r_offset;
755
d670a150 756 /* Relocate. */
ded0649c 757 value += rello->r_addend;
d670a150 758
ded0649c 759 /* Separate the fields and insert. */
d670a150
JE
760 value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
761 insn = (insn & ~howto->dst_mask) | value;
762
763 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
764 return bfd_reloc_ok;
765
fdeafce7 766}
fdeafce7
JE
767
768
c1e8b710
JE
769/* Specialized relocation handler for R_860_PC26. This relocation
770 involves a 26-bit, PC-relative field which must be adjusted by 4. */
771static bfd_reloc_status_type
772elf32_i860_relocate_pc26 (input_bfd, input_section, rello, contents, value)
773 bfd *input_bfd;
774 asection *input_section;
775 Elf_Internal_Rela *rello;
776 bfd_byte *contents;
777 bfd_vma value;
778{
779 bfd_vma insn;
780 reloc_howto_type *howto;
781 howto = lookup_howto (ELF32_R_TYPE (rello->r_info));
782 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
783
784 /* Adjust for PC-relative relocation. */
785 value -= (input_section->output_section->vma
786 + input_section->output_offset);
787 value -= rello->r_offset;
788
789 /* Relocate. */
790 value += rello->r_addend;
791
792 /* Adjust value by 4 and insert the field. */
793 value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
794 insn = (insn & ~howto->dst_mask) | value;
795
796 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
797 return bfd_reloc_ok;
798
799}
800
801
fdeafce7
JE
802/* Specialized relocation handler for R_860_HIGHADJ. */
803static bfd_reloc_status_type
804elf32_i860_relocate_highadj (input_bfd, rel, contents, value)
805 bfd *input_bfd;
806 Elf_Internal_Rela *rel;
807 bfd_byte *contents;
808 bfd_vma value;
809{
810 bfd_vma insn;
811
812 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
813
814 value += ((rel->r_addend & 0x8000) << 1);
815 value += rel->r_addend;
816 value = ((value >> 16) & 0xffff);
fdeafce7
JE
817
818 insn = (insn & 0xffff0000) | value;
819
820 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
821 return bfd_reloc_ok;
822}
823
824
825/* Perform a single relocation. By default we use the standard BFD
826 routines. However, we handle some specially. */
827static bfd_reloc_status_type
828i860_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
829 reloc_howto_type * howto;
830 bfd * input_bfd;
831 asection * input_section;
832 bfd_byte * contents;
833 Elf_Internal_Rela * rel;
834 bfd_vma relocation;
835{
836 return _bfd_final_link_relocate (howto, input_bfd, input_section,
837 contents, rel->r_offset, relocation,
838 rel->r_addend);
839}
840
841
842/* Relocate an i860 ELF section.
252b5132 843
fdeafce7
JE
844 This is boiler-plate code copied from fr30.
845 There is some attempt to make this function usable for many architectures,
846 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
847 if only to serve as a learning tool.
848
849 The RELOCATE_SECTION function is called by the new ELF backend linker
850 to handle the relocations for a section.
851
852 The relocs are always passed as Rela structures; if the section
853 actually uses Rel structures, the r_addend field will always be
854 zero.
855
856 This function is responsible for adjusting the section contents as
857 necessary, and (if using Rela relocs and generating a relocateable
858 output file) adjusting the reloc addend as necessary.
859
860 This function does not have to worry about setting the reloc
861 address or the reloc symbol index.
862
863 LOCAL_SYMS is a pointer to the swapped in local symbols.
864
865 LOCAL_SECTIONS is an array giving the section in the input file
866 corresponding to the st_shndx field of each local symbol.
867
868 The global hash table entry for the global symbols can be found
869 via elf_sym_hashes (input_bfd).
870
871 When generating relocateable output, this function must handle
872 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
873 going to be the section symbol corresponding to the output
874 section, which means that the addend must be adjusted
875 accordingly. */
876static boolean
877elf32_i860_relocate_section (output_bfd, info, input_bfd, input_section,
878 contents, relocs, local_syms, local_sections)
879 bfd * output_bfd ATTRIBUTE_UNUSED;
880 struct bfd_link_info * info;
881 bfd * input_bfd;
882 asection * input_section;
883 bfd_byte * contents;
884 Elf_Internal_Rela * relocs;
885 Elf_Internal_Sym * local_syms;
886 asection ** local_sections;
887{
888 Elf_Internal_Shdr * symtab_hdr;
889 struct elf_link_hash_entry ** sym_hashes;
890 Elf_Internal_Rela * rel;
891 Elf_Internal_Rela * relend;
892
893 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
894 sym_hashes = elf_sym_hashes (input_bfd);
895 relend = relocs + input_section->reloc_count;
896
897 for (rel = relocs; rel < relend; rel ++)
898 {
899 reloc_howto_type * howto;
900 unsigned long r_symndx;
901 Elf_Internal_Sym * sym;
902 asection * sec;
903 struct elf_link_hash_entry * h;
904 bfd_vma relocation;
905 bfd_reloc_status_type r;
906 const char * name = NULL;
907 int r_type;
908
909 r_type = ELF32_R_TYPE (rel->r_info);
910
911#if 0
912 if ( r_type == R_860_GNU_VTINHERIT
913 || r_type == R_860_GNU_VTENTRY)
914 continue;
915#endif
916
917 r_symndx = ELF32_R_SYM (rel->r_info);
918
919 if (info->relocateable)
920 {
921 /* This is a relocateable link. We don't have to change
922 anything, unless the reloc is against a section symbol,
923 in which case we have to adjust according to where the
924 section symbol winds up in the output section. */
925 if (r_symndx < symtab_hdr->sh_info)
926 {
927 sym = local_syms + r_symndx;
928
929 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
930 {
931 sec = local_sections [r_symndx];
932 rel->r_addend += sec->output_offset + sym->st_value;
933 }
934 }
935
936 continue;
937 }
938
939 /* This is a final link. */
940 howto = lookup_howto (ELF32_R_TYPE (rel->r_info));
941 h = NULL;
942 sym = NULL;
943 sec = NULL;
944
945 if (r_symndx < symtab_hdr->sh_info)
946 {
947 sym = local_syms + r_symndx;
948 sec = local_sections [r_symndx];
949 relocation = (sec->output_section->vma
950 + sec->output_offset
951 + sym->st_value);
952
953 name = bfd_elf_string_from_elf_section
954 (input_bfd, symtab_hdr->sh_link, sym->st_name);
955 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
956 }
957 else
958 {
959 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
960
961 while (h->root.type == bfd_link_hash_indirect
962 || h->root.type == bfd_link_hash_warning)
963 h = (struct elf_link_hash_entry *) h->root.u.i.link;
964
965 name = h->root.root.string;
966
967 if (h->root.type == bfd_link_hash_defined
968 || h->root.type == bfd_link_hash_defweak)
969 {
970 sec = h->root.u.def.section;
971 relocation = (h->root.u.def.value
972 + sec->output_section->vma
973 + sec->output_offset);
974 }
975 else if (h->root.type == bfd_link_hash_undefweak)
976 {
977 relocation = 0;
978 }
979 else
980 {
981 if (! ((*info->callbacks->undefined_symbol)
982 (info, h->root.root.string, input_bfd,
983 input_section, rel->r_offset, true)))
984 return false;
985 relocation = 0;
986 }
987 }
988
989 switch (r_type)
990 {
991 default:
992 r = i860_final_link_relocate (howto, input_bfd, input_section,
993 contents, rel, relocation);
994 break;
995
996 case R_860_HIGHADJ:
997 r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
998 relocation);
999 break;
1000
fdeafce7 1001 case R_860_PC16:
d670a150
JE
1002 r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
1003 contents, relocation);
fdeafce7 1004 break;
fdeafce7 1005
c1e8b710
JE
1006 case R_860_PC26:
1007 r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
1008 contents, relocation);
1009 break;
1010
fdeafce7
JE
1011 case R_860_SPLIT0:
1012 case R_860_SPLIT1:
1013 case R_860_SPLIT2:
1014 r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
1015 relocation);
1016 break;
1017
1018 /* We do not yet handle GOT/PLT/Dynamic relocations. */
1019 case R_860_COPY:
1020 case R_860_GLOB_DAT:
1021 case R_860_JUMP_SLOT:
1022 case R_860_RELATIVE:
1023 case R_860_PLT26:
1024 case R_860_LOGOT0:
1025 case R_860_SPGOT0:
1026 case R_860_LOGOT1:
1027 case R_860_SPGOT1:
1028 case R_860_LOGOTOFF0:
1029 case R_860_SPGOTOFF0:
1030 case R_860_LOGOTOFF1:
1031 case R_860_SPGOTOFF1:
1032 case R_860_LOGOTOFF2:
1033 case R_860_LOGOTOFF3:
1034 case R_860_LOPC:
1035 case R_860_HAGOT:
1036 case R_860_HAGOTOFF:
1037 case R_860_HAPC:
1038 case R_860_HIGOT:
1039 case R_860_HIGOTOFF:
1040 r = bfd_reloc_notsupported;
1041 break;
1042 }
1043
1044 if (r != bfd_reloc_ok)
1045 {
1046 const char * msg = (const char *) NULL;
1047
1048 switch (r)
1049 {
1050 case bfd_reloc_overflow:
1051 r = info->callbacks->reloc_overflow
1052 (info, name, howto->name, (bfd_vma) 0,
1053 input_bfd, input_section, rel->r_offset);
1054 break;
1055
1056 case bfd_reloc_undefined:
1057 r = info->callbacks->undefined_symbol
1058 (info, name, input_bfd, input_section, rel->r_offset, true);
1059 break;
1060
1061 case bfd_reloc_outofrange:
1062 msg = _("internal error: out of range error");
1063 break;
1064
1065 case bfd_reloc_notsupported:
1066 msg = _("internal error: unsupported relocation error");
1067 break;
1068
1069 case bfd_reloc_dangerous:
1070 msg = _("internal error: dangerous relocation");
1071 break;
1072
1073 default:
1074 msg = _("internal error: unknown error");
1075 break;
1076 }
1077
1078 if (msg)
1079 r = info->callbacks->warning
1080 (info, msg, name, input_bfd, input_section, rel->r_offset);
1081
1082 if (! r)
1083 return false;
1084 }
1085 }
1086
1087 return true;
1088}
1089
1090
de24da47
JE
1091/* Return whether a symbol name implies a local label. SVR4/860 compilers
1092 generate labels of the form ".ep.function_name" to denote the end of a
1093 function prolog. These should be local.
1094 ??? Do any other SVR4 compilers have this convention? If so, this should
1095 be added to the generic routine. */
1096static boolean
1097elf32_i860_is_local_label_name (abfd, name)
1098 bfd *abfd;
1099 const char *name;
1100{
1101 if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1102 return true;
1103
1104 return _bfd_elf_is_local_label_name (abfd, name);
1105}
1106
1107
fdeafce7 1108\f
9d751335
JE
1109#define TARGET_BIG_SYM bfd_elf32_i860_vec
1110#define TARGET_BIG_NAME "elf32-i860"
1111#define TARGET_LITTLE_SYM bfd_elf32_i860_little_vec
1112#define TARGET_LITTLE_NAME "elf32-i860-little"
0e5136c6
JE
1113#define ELF_ARCH bfd_arch_i860
1114#define ELF_MACHINE_CODE EM_860
1115#define ELF_MAXPAGESIZE 4096
1116
fdeafce7 1117#define elf_info_to_howto_rel NULL
0e5136c6 1118#define elf_info_to_howto elf32_i860_info_to_howto_rela
fdeafce7 1119#define elf_backend_relocate_section elf32_i860_relocate_section
0e5136c6 1120#define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
de24da47 1121#define bfd_elf32_bfd_is_local_label_name elf32_i860_is_local_label_name
252b5132
RH
1122
1123#include "elf32-target.h"
This page took 0.136161 seconds and 4 git commands to generate.