source: trunk/src/binutils/bfd/elf32-i860.c@ 657

Last change on this file since 657 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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