* elf-bfd.h (struct elf_size_info): Add swap_symbol_in field.
[platform/upstream/binutils.git] / bfd / elf32-i860.c
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
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 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.  */
30 static reloc_howto_type *lookup_howto
31   PARAMS ((unsigned int));
32
33 static reloc_howto_type *elf32_i860_reloc_type_lookup
34   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
35
36 static void elf32_i860_info_to_howto_rela
37   PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
38
39 static bfd_reloc_status_type elf32_i860_relocate_splitn
40   PARAMS ((bfd *,  Elf_Internal_Rela *, bfd_byte *, bfd_vma));
41
42 static bfd_reloc_status_type elf32_i860_relocate_pc16
43   PARAMS ((bfd *,  asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
44
45 static bfd_reloc_status_type elf32_i860_relocate_pc26
46   PARAMS ((bfd *,  asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
47
48 static bfd_reloc_status_type elf32_i860_relocate_highadj
49   PARAMS ((bfd *,  Elf_Internal_Rela *, bfd_byte *, bfd_vma));
50
51 static 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
55 static bfd_reloc_status_type i860_final_link_relocate
56   PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
57            Elf_Internal_Rela *, bfd_vma));
58
59 static boolean elf32_i860_is_local_label_name
60   PARAMS ((bfd *, const char *));
61
62 /* This howto table is preliminary.  */
63 static 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 \f
546 static unsigned char elf_code_to_howto_index[R_860_max + 1];
547
548 static reloc_howto_type *
549 lookup_howto (rtype)
550      unsigned int rtype;
551 {
552   static int initialized = 0;
553   int i;
554   int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
555                         / sizeof (elf32_i860_howto_table[0]));
556
557   if (! initialized)
558     {
559       initialized = 1;
560       memset (elf_code_to_howto_index, 0xff,
561               sizeof (elf_code_to_howto_index));
562       for (i = 0; i < howto_tbl_size; i++)
563         elf_code_to_howto_index[elf32_i860_howto_table[i].type] = i;
564     }
565
566   BFD_ASSERT (rtype <= R_860_max);
567   i = elf_code_to_howto_index[rtype];
568   if (i >= howto_tbl_size)
569     return 0;
570   return elf32_i860_howto_table + i;
571 }
572
573 /* Given a BFD reloc, return the matching HOWTO structure.  */
574 static reloc_howto_type *
575 elf32_i860_reloc_type_lookup (abfd, code)
576      bfd * abfd ATTRIBUTE_UNUSED;
577      bfd_reloc_code_real_type code;
578 {
579   unsigned int rtype;
580
581   switch (code)
582     {
583     case BFD_RELOC_NONE:
584       rtype = R_860_NONE;
585       break;
586     case BFD_RELOC_32:
587       rtype = R_860_32;
588       break;
589     case BFD_RELOC_860_COPY:
590       rtype = R_860_COPY;
591       break;
592     case BFD_RELOC_860_GLOB_DAT:
593       rtype = R_860_GLOB_DAT;
594       break;
595     case BFD_RELOC_860_JUMP_SLOT:
596       rtype = R_860_JUMP_SLOT;
597       break;
598     case BFD_RELOC_860_RELATIVE:
599       rtype = R_860_RELATIVE;
600       break;
601     case BFD_RELOC_860_PC26:
602       rtype = R_860_PC26;
603       break;
604     case BFD_RELOC_860_PLT26:
605       rtype = R_860_PLT26;
606       break;
607     case BFD_RELOC_860_PC16:
608       rtype = R_860_PC16;
609       break;
610     case BFD_RELOC_860_LOW0:
611       rtype = R_860_LOW0;
612       break;
613     case BFD_RELOC_860_SPLIT0:
614       rtype = R_860_SPLIT0;
615       break;
616     case BFD_RELOC_860_LOW1:
617       rtype = R_860_LOW1;
618       break;
619     case BFD_RELOC_860_SPLIT1:
620       rtype = R_860_SPLIT1;
621       break;
622     case BFD_RELOC_860_LOW2:
623       rtype = R_860_LOW2;
624       break;
625     case BFD_RELOC_860_SPLIT2:
626       rtype = R_860_SPLIT2;
627       break;
628     case BFD_RELOC_860_LOW3:
629       rtype = R_860_LOW3;
630       break;
631     case BFD_RELOC_860_LOGOT0:
632       rtype = R_860_LOGOT0;
633       break;
634     case BFD_RELOC_860_SPGOT0:
635       rtype = R_860_SPGOT0;
636       break;
637     case BFD_RELOC_860_LOGOT1:
638       rtype = R_860_LOGOT1;
639       break;
640     case BFD_RELOC_860_SPGOT1:
641       rtype = R_860_SPGOT1;
642       break;
643     case BFD_RELOC_860_LOGOTOFF0:
644       rtype = R_860_LOGOTOFF0;
645       break;
646     case BFD_RELOC_860_SPGOTOFF0:
647       rtype = R_860_SPGOTOFF0;
648       break;
649     case BFD_RELOC_860_LOGOTOFF1:
650       rtype = R_860_LOGOTOFF1;
651       break;
652     case BFD_RELOC_860_SPGOTOFF1:
653       rtype = R_860_SPGOTOFF1;
654       break;
655     case BFD_RELOC_860_LOGOTOFF2:
656       rtype = R_860_LOGOTOFF2;
657       break;
658     case BFD_RELOC_860_LOGOTOFF3:
659       rtype = R_860_LOGOTOFF3;
660       break;
661     case BFD_RELOC_860_LOPC:
662       rtype = R_860_LOPC;
663       break;
664     case BFD_RELOC_860_HIGHADJ:
665       rtype = R_860_HIGHADJ;
666       break;
667     case BFD_RELOC_860_HAGOT:
668       rtype = R_860_HAGOT;
669       break;
670     case BFD_RELOC_860_HAGOTOFF:
671       rtype = R_860_HAGOTOFF;
672       break;
673     case BFD_RELOC_860_HAPC:
674       rtype = R_860_HAPC;
675       break;
676     case BFD_RELOC_860_HIGH:
677       rtype = R_860_HIGH;
678       break;
679     case BFD_RELOC_860_HIGOT:
680       rtype = R_860_HIGOT;
681       break;
682     case BFD_RELOC_860_HIGOTOFF:
683       rtype = R_860_HIGOTOFF;
684       break;
685     default:
686       rtype = 0;
687       break;
688     }
689   return lookup_howto (rtype);
690 }
691
692 /* Given a ELF reloc, return the matching HOWTO structure.  */
693 static void
694 elf32_i860_info_to_howto_rela (abfd, bfd_reloc, elf_reloc)
695      bfd *abfd ATTRIBUTE_UNUSED;
696      arelent *bfd_reloc;
697      Elf64_Internal_Rela *elf_reloc;
698 {
699   bfd_reloc->howto
700     = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc->r_info));
701 }
702 \f
703 /* Specialized relocation handler for R_860_SPLITn.  These relocations
704    involves a 16-bit field that is split into two contiguous parts.  */
705 static bfd_reloc_status_type
706 elf32_i860_relocate_splitn (input_bfd, rello, contents, value)
707      bfd *input_bfd;
708      Elf_Internal_Rela *rello;
709      bfd_byte *contents;
710      bfd_vma value;
711 {
712   bfd_vma insn;
713   reloc_howto_type *howto;
714   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
715   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
716
717   /* Relocate.  */
718   value += rello->r_addend;
719
720   /* Separate the fields and insert.  */
721   value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
722   insn = (insn & ~howto->dst_mask) | value;
723
724   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
725   return bfd_reloc_ok;
726 }
727
728 /* Specialized relocation handler for R_860_PC16.  This relocation
729    involves a 16-bit, PC-relative field that is split into two contiguous
730    parts.  */
731 static bfd_reloc_status_type
732 elf32_i860_relocate_pc16 (input_bfd, input_section, rello, contents, value)
733      bfd *input_bfd;
734      asection *input_section;
735      Elf_Internal_Rela *rello;
736      bfd_byte *contents;
737      bfd_vma value;
738 {
739   bfd_vma insn;
740   reloc_howto_type *howto;
741   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
742   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
743
744   /* Adjust for PC-relative relocation.  */
745   value -= (input_section->output_section->vma
746             + input_section->output_offset);
747   value -= rello->r_offset;
748
749   /* Relocate.  */
750   value += rello->r_addend;
751
752   /* Separate the fields and insert.  */
753   value = (((value & 0xf8) << 5) | (value & 0x7ff)) & howto->dst_mask;
754   insn = (insn & ~howto->dst_mask) | value;
755
756   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
757   return bfd_reloc_ok;
758
759 }
760
761 /* Specialized relocation handler for R_860_PC26.  This relocation
762    involves a 26-bit, PC-relative field which must be adjusted by 4.  */
763 static bfd_reloc_status_type
764 elf32_i860_relocate_pc26 (input_bfd, input_section, rello, contents, value)
765      bfd *input_bfd;
766      asection *input_section;
767      Elf_Internal_Rela *rello;
768      bfd_byte *contents;
769      bfd_vma value;
770 {
771   bfd_vma insn;
772   reloc_howto_type *howto;
773   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
774   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
775
776   /* Adjust for PC-relative relocation.  */
777   value -= (input_section->output_section->vma
778             + input_section->output_offset);
779   value -= rello->r_offset;
780
781   /* Relocate.  */
782   value += rello->r_addend;
783
784   /* Adjust value by 4 and insert the field.  */
785   value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
786   insn = (insn & ~howto->dst_mask) | value;
787
788   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
789   return bfd_reloc_ok;
790
791 }
792
793 /* Specialized relocation handler for R_860_HIGHADJ.  */
794 static bfd_reloc_status_type
795 elf32_i860_relocate_highadj (input_bfd, rel, contents, value)
796      bfd *input_bfd;
797      Elf_Internal_Rela *rel;
798      bfd_byte *contents;
799      bfd_vma value;
800 {
801   bfd_vma insn;
802
803   insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
804
805   value += ((rel->r_addend & 0x8000) << 1);
806   value += rel->r_addend;
807   value = ((value >> 16) & 0xffff);
808
809   insn = (insn & 0xffff0000) | value;
810
811   bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
812   return bfd_reloc_ok;
813 }
814
815 /* Perform a single relocation.  By default we use the standard BFD
816    routines. However, we handle some specially.  */
817 static bfd_reloc_status_type
818 i860_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
819      reloc_howto_type *  howto;
820      bfd *               input_bfd;
821      asection *          input_section;
822      bfd_byte *          contents;
823      Elf_Internal_Rela * rel;
824      bfd_vma             relocation;
825 {
826   return _bfd_final_link_relocate (howto, input_bfd, input_section,
827                                    contents, rel->r_offset, relocation,
828                                    rel->r_addend);
829 }
830
831 /* Relocate an i860 ELF section.
832
833    This is boiler-plate code copied from fr30.
834    There is some attempt to make this function usable for many architectures,
835    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
836    if only to serve as a learning tool.
837
838    The RELOCATE_SECTION function is called by the new ELF backend linker
839    to handle the relocations for a section.
840
841    The relocs are always passed as Rela structures; if the section
842    actually uses Rel structures, the r_addend field will always be
843    zero.
844
845    This function is responsible for adjusting the section contents as
846    necessary, and (if using Rela relocs and generating a relocateable
847    output file) adjusting the reloc addend as necessary.
848
849    This function does not have to worry about setting the reloc
850    address or the reloc symbol index.
851
852    LOCAL_SYMS is a pointer to the swapped in local symbols.
853
854    LOCAL_SECTIONS is an array giving the section in the input file
855    corresponding to the st_shndx field of each local symbol.
856
857    The global hash table entry for the global symbols can be found
858    via elf_sym_hashes (input_bfd).
859
860    When generating relocateable output, this function must handle
861    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
862    going to be the section symbol corresponding to the output
863    section, which means that the addend must be adjusted
864    accordingly.  */
865 static boolean
866 elf32_i860_relocate_section (output_bfd, info, input_bfd, input_section,
867                              contents, relocs, local_syms, local_sections)
868      bfd *                   output_bfd ATTRIBUTE_UNUSED;
869      struct bfd_link_info *  info;
870      bfd *                   input_bfd;
871      asection *              input_section;
872      bfd_byte *              contents;
873      Elf_Internal_Rela *     relocs;
874      Elf_Internal_Sym *      local_syms;
875      asection **             local_sections;
876 {
877   Elf_Internal_Shdr *           symtab_hdr;
878   struct elf_link_hash_entry ** sym_hashes;
879   Elf_Internal_Rela *           rel;
880   Elf_Internal_Rela *           relend;
881
882   if (info->relocateable)
883     return true;
884
885   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
886   sym_hashes = elf_sym_hashes (input_bfd);
887   relend     = relocs + input_section->reloc_count;
888
889   for (rel = relocs; rel < relend; rel ++)
890     {
891       reloc_howto_type *           howto;
892       unsigned long                r_symndx;
893       Elf_Internal_Sym *           sym;
894       asection *                   sec;
895       struct elf_link_hash_entry * h;
896       bfd_vma                      relocation;
897       bfd_reloc_status_type        r;
898       const char *                 name = NULL;
899       int                          r_type;
900
901       r_type = ELF32_R_TYPE (rel->r_info);
902
903 #if 0
904       if (   r_type == R_860_GNU_VTINHERIT
905           || r_type == R_860_GNU_VTENTRY)
906         continue;
907 #endif
908
909       r_symndx = ELF32_R_SYM (rel->r_info);
910
911       howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
912       h     = NULL;
913       sym   = NULL;
914       sec   = NULL;
915
916       if (r_symndx < symtab_hdr->sh_info)
917         {
918           sym = local_syms + r_symndx;
919           sec = local_sections [r_symndx];
920           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
921
922           name = bfd_elf_string_from_elf_section
923             (input_bfd, symtab_hdr->sh_link, sym->st_name);
924           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
925         }
926       else
927         {
928           h = sym_hashes [r_symndx - symtab_hdr->sh_info];
929
930           while (h->root.type == bfd_link_hash_indirect
931                  || h->root.type == bfd_link_hash_warning)
932             h = (struct elf_link_hash_entry *) h->root.u.i.link;
933
934           name = h->root.root.string;
935
936           if (h->root.type == bfd_link_hash_defined
937               || h->root.type == bfd_link_hash_defweak)
938             {
939               sec = h->root.u.def.section;
940               relocation = (h->root.u.def.value
941                             + sec->output_section->vma
942                             + sec->output_offset);
943             }
944           else if (h->root.type == bfd_link_hash_undefweak)
945             {
946               relocation = 0;
947             }
948           else
949             {
950               if (! ((*info->callbacks->undefined_symbol)
951                      (info, h->root.root.string, input_bfd,
952                       input_section, rel->r_offset, true)))
953                 return false;
954               relocation = 0;
955             }
956         }
957
958       switch (r_type)
959         {
960         default:
961           r = i860_final_link_relocate (howto, input_bfd, input_section,
962                                         contents, rel, relocation);
963           break;
964
965         case R_860_HIGHADJ:
966           r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
967                                            relocation);
968           break;
969
970         case R_860_PC16:
971           r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
972                                         contents, relocation);
973           break;
974
975         case R_860_PC26:
976           r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
977                                         contents, relocation);
978           break;
979
980         case R_860_SPLIT0:
981         case R_860_SPLIT1:
982         case R_860_SPLIT2:
983           r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
984                                           relocation);
985           break;
986
987         /* We do not yet handle GOT/PLT/Dynamic relocations.  */
988         case R_860_COPY:
989         case R_860_GLOB_DAT:
990         case R_860_JUMP_SLOT:
991         case R_860_RELATIVE:
992         case R_860_PLT26:
993         case R_860_LOGOT0:
994         case R_860_SPGOT0:
995         case R_860_LOGOT1:
996         case R_860_SPGOT1:
997         case R_860_LOGOTOFF0:
998         case R_860_SPGOTOFF0:
999         case R_860_LOGOTOFF1:
1000         case R_860_SPGOTOFF1:
1001         case R_860_LOGOTOFF2:
1002         case R_860_LOGOTOFF3:
1003         case R_860_LOPC:
1004         case R_860_HAGOT:
1005         case R_860_HAGOTOFF:
1006         case R_860_HAPC:
1007         case R_860_HIGOT:
1008         case R_860_HIGOTOFF:
1009           r = bfd_reloc_notsupported;
1010           break;
1011         }
1012
1013       if (r != bfd_reloc_ok)
1014         {
1015           const char * msg = (const char *) NULL;
1016
1017           switch (r)
1018             {
1019             case bfd_reloc_overflow:
1020               r = info->callbacks->reloc_overflow
1021                 (info, name, howto->name, (bfd_vma) 0,
1022                  input_bfd, input_section, rel->r_offset);
1023               break;
1024
1025             case bfd_reloc_undefined:
1026               r = info->callbacks->undefined_symbol
1027                 (info, name, input_bfd, input_section, rel->r_offset, true);
1028               break;
1029
1030             case bfd_reloc_outofrange:
1031               msg = _("internal error: out of range error");
1032               break;
1033
1034             case bfd_reloc_notsupported:
1035               msg = _("internal error: unsupported relocation error");
1036               break;
1037
1038             case bfd_reloc_dangerous:
1039               msg = _("internal error: dangerous relocation");
1040               break;
1041
1042             default:
1043               msg = _("internal error: unknown error");
1044               break;
1045             }
1046
1047           if (msg)
1048             r = info->callbacks->warning
1049               (info, msg, name, input_bfd, input_section, rel->r_offset);
1050
1051           if (! r)
1052             return false;
1053         }
1054     }
1055
1056   return true;
1057 }
1058
1059 /* Return whether a symbol name implies a local label.  SVR4/860 compilers
1060    generate labels of the form ".ep.function_name" to denote the end of a
1061    function prolog. These should be local.
1062    ??? Do any other SVR4 compilers have this convention? If so, this should
1063    be added to the generic routine.  */
1064 static boolean
1065 elf32_i860_is_local_label_name (abfd, name)
1066      bfd *abfd;
1067      const char *name;
1068 {
1069   if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1070     return true;
1071
1072   return _bfd_elf_is_local_label_name (abfd, name);
1073 }
1074 \f
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"