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