unrecognized/unsupported reloc message
[external/binutils.git] / bfd / coff-i860.c
1 /* BFD back-end for Intel i860 COFF files.
2    Copyright (C) 1990-2018 Free Software Foundation, Inc.
3    Created mostly by substituting "860" for "386" in coff-i386.c
4    Harry Dolan <dolan@ssd.intel.com>, October 1995
5
6    This file is part of BFD, the Binary File Descriptor library.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26
27 #include "coff/i860.h"
28
29 #include "coff/internal.h"
30
31 #ifndef bfd_pe_print_pdata
32 #define bfd_pe_print_pdata      NULL
33 #endif
34
35 #include "libcoff.h"
36
37
38 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
39 /* The page size is a guess based on ELF.  */
40
41 #define COFF_PAGE_SIZE 0x1000
42
43 /* For some reason when using i860 COFF the value stored in the .text
44    section for a reference to a common symbol is the value itself plus
45    any desired offset.  Ian Taylor, Cygnus Support.  */
46
47 /* If we are producing relocatable output, we need to do some
48    adjustments to the object file that are not done by the
49    bfd_perform_relocation function.  This function is called by every
50    reloc type to make any required adjustments.  */
51
52 static bfd_reloc_status_type
53 coff_i860_reloc (bfd *abfd,
54                  arelent *reloc_entry,
55                  asymbol *symbol,
56                  void *data,
57                  asection *input_section ATTRIBUTE_UNUSED,
58                  bfd *output_bfd,
59                  char **error_message ATTRIBUTE_UNUSED)
60 {
61   symvalue diff;
62
63   if (output_bfd == (bfd *) NULL)
64     return bfd_reloc_continue;
65
66   if (bfd_is_com_section (symbol->section))
67     {
68       /* We are relocating a common symbol.  The current value in the
69          object file is ORIG + OFFSET, where ORIG is the value of the
70          common symbol as seen by the object file when it was compiled
71          (this may be zero if the symbol was undefined) and OFFSET is
72          the offset into the common symbol (normally zero, but may be
73          non-zero when referring to a field in a common structure).
74          ORIG is the negative of reloc_entry->addend, which is set by
75          the CALC_ADDEND macro below.  We want to replace the value in
76          the object file with NEW + OFFSET, where NEW is the value of
77          the common symbol which we are going to put in the final
78          object file.  NEW is symbol->value.  */
79       diff = symbol->value + reloc_entry->addend;
80     }
81   else
82     {
83       /* For some reason bfd_perform_relocation always effectively
84          ignores the addend for a COFF target when producing
85          relocatable output.  This seems to be always wrong for 860
86          COFF, so we handle the addend here instead.  */
87       diff = reloc_entry->addend;
88     }
89
90 #define DOIT(x) \
91   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
92
93     if (diff != 0)
94       {
95         reloc_howto_type *howto = reloc_entry->howto;
96         unsigned char *addr = (unsigned char *) data + reloc_entry->address;
97
98         if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
99                                          reloc_entry->address
100                                          * bfd_octets_per_byte (abfd)))
101           return bfd_reloc_outofrange;
102
103         switch (howto->size)
104           {
105           case 0:
106             {
107               char x = bfd_get_8 (abfd, addr);
108               DOIT (x);
109               bfd_put_8 (abfd, x, addr);
110             }
111             break;
112
113           case 1:
114             {
115               short x = bfd_get_16 (abfd, addr);
116               DOIT (x);
117               bfd_put_16 (abfd, (bfd_vma) x, addr);
118             }
119             break;
120
121           case 2:
122             {
123               long x = bfd_get_32 (abfd, addr);
124               DOIT (x);
125               bfd_put_32 (abfd, (bfd_vma) x, addr);
126             }
127             break;
128
129           default:
130             abort ();
131           }
132       }
133
134   /* Now let bfd_perform_relocation finish everything up.  */
135   return bfd_reloc_continue;
136 }
137
138 /* This is just a temporary measure until we teach bfd to generate
139    these relocations.  */
140
141 static bfd_reloc_status_type
142 coff_i860_reloc_nyi (bfd *abfd,
143                      arelent *reloc_entry,
144                      asymbol *symbol ATTRIBUTE_UNUSED,
145                      void *data ATTRIBUTE_UNUSED,
146                      asection *input_section ATTRIBUTE_UNUSED,
147                      bfd *output_bfd ATTRIBUTE_UNUSED,
148                      char **error_message ATTRIBUTE_UNUSED)
149 {
150   reloc_howto_type *howto = reloc_entry->howto;
151   _bfd_error_handler (_("%pB: %s unsupported"), abfd, howto->name);
152   return bfd_reloc_notsupported;
153 }
154
155 #ifndef PCRELOFFSET
156 #define PCRELOFFSET FALSE
157 #endif
158
159 static reloc_howto_type howto_table[] =
160 {
161   EMPTY_HOWTO (0),
162   EMPTY_HOWTO (1),
163   EMPTY_HOWTO (2),
164   EMPTY_HOWTO (3),
165   EMPTY_HOWTO (4),
166   EMPTY_HOWTO (5),
167   HOWTO (R_DIR32,               /* type */
168          0,                     /* rightshift */
169          2,                     /* size (0 = byte, 1 = short, 2 = long) */
170          32,                    /* bitsize */
171          FALSE,                 /* pc_relative */
172          0,                     /* bitpos */
173          complain_overflow_bitfield, /* complain_on_overflow */
174          coff_i860_reloc,       /* special_function */
175          "dir32",               /* name */
176          TRUE,                  /* partial_inplace */
177          0xffffffff,            /* src_mask */
178          0xffffffff,            /* dst_mask */
179          TRUE),                /* pcrel_offset */
180   /* {7}, */
181   HOWTO (R_IMAGEBASE,            /* type */
182          0,                     /* rightshift */
183          2,                     /* size (0 = byte, 1 = short, 2 = long) */
184          32,                    /* bitsize */
185          FALSE,                 /* pc_relative */
186          0,                     /* bitpos */
187          complain_overflow_bitfield, /* complain_on_overflow */
188          coff_i860_reloc,       /* special_function */
189          "rva32",                  /* name */
190          TRUE,                  /* partial_inplace */
191          0xffffffff,            /* src_mask */
192          0xffffffff,            /* dst_mask */
193          FALSE),                /* pcrel_offset */
194   EMPTY_HOWTO (010),
195   EMPTY_HOWTO (011),
196   EMPTY_HOWTO (012),
197   EMPTY_HOWTO (013),
198   EMPTY_HOWTO (014),
199   EMPTY_HOWTO (015),
200   EMPTY_HOWTO (016),
201   HOWTO (R_RELBYTE,             /* type */
202          0,                     /* rightshift */
203          0,                     /* size (0 = byte, 1 = short, 2 = long) */
204          8,                     /* bitsize */
205          FALSE,                 /* pc_relative */
206          0,                     /* bitpos */
207          complain_overflow_bitfield, /* complain_on_overflow */
208          coff_i860_reloc,       /* special_function */
209          "8",                   /* name */
210          TRUE,                  /* partial_inplace */
211          0x000000ff,            /* src_mask */
212          0x000000ff,            /* dst_mask */
213          PCRELOFFSET),          /* pcrel_offset */
214   HOWTO (R_RELWORD,             /* type */
215          0,                     /* rightshift */
216          1,                     /* size (0 = byte, 1 = short, 2 = long) */
217          16,                    /* bitsize */
218          FALSE,                 /* pc_relative */
219          0,                     /* bitpos */
220          complain_overflow_bitfield, /* complain_on_overflow */
221          coff_i860_reloc,       /* special_function */
222          "16",                  /* name */
223          TRUE,                  /* partial_inplace */
224          0x0000ffff,            /* src_mask */
225          0x0000ffff,            /* dst_mask */
226          PCRELOFFSET),          /* pcrel_offset */
227   HOWTO (R_RELLONG,             /* type */
228          0,                     /* rightshift */
229          2,                     /* size (0 = byte, 1 = short, 2 = long) */
230          32,                    /* bitsize */
231          FALSE,                 /* pc_relative */
232          0,                     /* bitpos */
233          complain_overflow_bitfield, /* complain_on_overflow */
234          coff_i860_reloc,       /* special_function */
235          "32",                  /* name */
236          TRUE,                  /* partial_inplace */
237          0xffffffff,            /* src_mask */
238          0xffffffff,            /* dst_mask */
239          PCRELOFFSET),          /* pcrel_offset */
240   HOWTO (R_PCRBYTE,             /* type */
241          0,                     /* rightshift */
242          0,                     /* size (0 = byte, 1 = short, 2 = long) */
243          8,                     /* bitsize */
244          TRUE,                  /* pc_relative */
245          0,                     /* bitpos */
246          complain_overflow_signed, /* complain_on_overflow */
247          coff_i860_reloc,       /* special_function */
248          "DISP8",               /* name */
249          TRUE,                  /* partial_inplace */
250          0x000000ff,            /* src_mask */
251          0x000000ff,            /* dst_mask */
252          PCRELOFFSET),          /* pcrel_offset */
253   HOWTO (R_PCRWORD,             /* type */
254          0,                     /* rightshift */
255          1,                     /* size (0 = byte, 1 = short, 2 = long) */
256          16,                    /* bitsize */
257          TRUE,                  /* pc_relative */
258          0,                     /* bitpos */
259          complain_overflow_signed, /* complain_on_overflow */
260          coff_i860_reloc,       /* special_function */
261          "DISP16",              /* name */
262          TRUE,                  /* partial_inplace */
263          0x0000ffff,            /* src_mask */
264          0x0000ffff,            /* dst_mask */
265          PCRELOFFSET),          /* pcrel_offset */
266   HOWTO (R_PCRLONG,             /* type */
267          0,                     /* rightshift */
268          2,                     /* size (0 = byte, 1 = short, 2 = long) */
269          32,                    /* bitsize */
270          TRUE,                  /* pc_relative */
271          0,                     /* bitpos */
272          complain_overflow_signed, /* complain_on_overflow */
273          coff_i860_reloc,       /* special_function */
274          "DISP32",              /* name */
275          TRUE,                  /* partial_inplace */
276          0xffffffff,            /* src_mask */
277          0xffffffff,            /* dst_mask */
278          PCRELOFFSET),          /* pcrel_offset */
279   EMPTY_HOWTO (0x15),
280   EMPTY_HOWTO (0x16),
281   EMPTY_HOWTO (0x17),
282   EMPTY_HOWTO (0x18),
283   EMPTY_HOWTO (0x19),
284   EMPTY_HOWTO (0x1a),
285   EMPTY_HOWTO (0x1b),
286   HOWTO (COFF860_R_PAIR,        /* type */
287          0,                     /* rightshift */
288          2,                     /* size (0 = byte, 1 = short, 2 = long) */
289          16,                    /* bitsize */
290          FALSE,                 /* pc_relative */
291          0,                     /* bitpos */
292          complain_overflow_dont, /* complain_on_overflow */
293          coff_i860_reloc_nyi,   /* special_function */
294          "PAIR",                /* name */
295          FALSE,                 /* partial_inplace */
296          0xffff,                /* src_mask */
297          0xffff,                /* dst_mask */
298          FALSE),                /* pcrel_offset */
299   EMPTY_HOWTO (0x1d),
300   HOWTO (COFF860_R_HIGH,        /* type */
301          16,                    /* rightshift */
302          2,                     /* size (0 = byte, 1 = short, 2 = long) */
303          16,                    /* bitsize */
304          FALSE,                 /* pc_relative */
305          0,                     /* bitpos */
306          complain_overflow_dont, /* complain_on_overflow */
307          coff_i860_reloc,       /* special_function */
308          "HIGH",                /* name */
309          FALSE,                 /* partial_inplace */
310          0xffff,                /* src_mask */
311          0xffff,                /* dst_mask */
312          FALSE),                /* pcrel_offset */
313   HOWTO (COFF860_R_LOW0,        /* type */
314          0,                     /* rightshift */
315          2,                     /* size (0 = byte, 1 = short, 2 = long) */
316          16,                    /* bitsize */
317          FALSE,                 /* pc_relative */
318          0,                     /* bitpos */
319          complain_overflow_dont, /* complain_on_overflow */
320          coff_i860_reloc,       /* special_function */
321          "LOW0",                /* name */
322          FALSE,                 /* partial_inplace */
323          0xffff,                /* src_mask */
324          0xffff,                /* dst_mask */
325          FALSE),                /* pcrel_offset */
326   HOWTO (COFF860_R_LOW1,        /* type */
327          0,                     /* rightshift */
328          2,                     /* size (0 = byte, 1 = short, 2 = long) */
329          16,                    /* bitsize */
330          FALSE,                 /* pc_relative */
331          0,                     /* bitpos */
332          complain_overflow_dont, /* complain_on_overflow */
333          coff_i860_reloc,       /* special_function */
334          "LOW1",                /* name */
335          FALSE,                 /* partial_inplace */
336          0xfffe,                /* src_mask */
337          0xfffe,                /* dst_mask */
338          FALSE),                /* pcrel_offset */
339   HOWTO (COFF860_R_LOW2,        /* type */
340          0,                     /* rightshift */
341          2,                     /* size (0 = byte, 1 = short, 2 = long) */
342          16,                    /* bitsize */
343          FALSE,                 /* pc_relative */
344          0,                     /* bitpos */
345          complain_overflow_dont, /* complain_on_overflow */
346          coff_i860_reloc,       /* special_function */
347          "LOW2",                /* name */
348          FALSE,                 /* partial_inplace */
349          0xfffc,                /* src_mask */
350          0xfffc,                /* dst_mask */
351          FALSE),                /* pcrel_offset */
352   HOWTO (COFF860_R_LOW3,        /* type */
353          0,                     /* rightshift */
354          2,                     /* size (0 = byte, 1 = short, 2 = long) */
355          16,                    /* bitsize */
356          FALSE,                 /* pc_relative */
357          0,                     /* bitpos */
358          complain_overflow_dont, /* complain_on_overflow */
359          coff_i860_reloc,       /* special_function */
360          "LOW3",                /* name */
361          FALSE,                 /* partial_inplace */
362          0xfff8,                /* src_mask */
363          0xfff8,                /* dst_mask */
364          FALSE),                /* pcrel_offset */
365   HOWTO (COFF860_R_LOW4,        /* type */
366          0,                     /* rightshift */
367          2,                     /* size (0 = byte, 1 = short, 2 = long) */
368          16,                    /* bitsize */
369          FALSE,                 /* pc_relative */
370          0,                     /* bitpos */
371          complain_overflow_dont, /* complain_on_overflow */
372          coff_i860_reloc,       /* special_function */
373          "LOW4",                /* name */
374          FALSE,                 /* partial_inplace */
375          0xfff0,                /* src_mask */
376          0xfff0,                /* dst_mask */
377          FALSE),                /* pcrel_offset */
378   HOWTO (COFF860_R_SPLIT0,      /* type */
379          0,                     /* rightshift */
380          2,                     /* size (0 = byte, 1 = short, 2 = long) */
381          16,                    /* bitsize */
382          FALSE,                 /* pc_relative */
383          0,                     /* bitpos */
384          complain_overflow_dont, /* complain_on_overflow */
385          coff_i860_reloc_nyi,   /* special_function */
386          "SPLIT0",              /* name */
387          FALSE,                 /* partial_inplace */
388          0x1f07ff,              /* src_mask */
389          0x1f07ff,              /* dst_mask */
390          FALSE),                /* pcrel_offset */
391   HOWTO (COFF860_R_SPLIT1,      /* type */
392          0,                     /* rightshift */
393          2,                     /* size (0 = byte, 1 = short, 2 = long) */
394          16,                    /* bitsize */
395          FALSE,                 /* pc_relative */
396          0,                     /* bitpos */
397          complain_overflow_dont, /* complain_on_overflow */
398          coff_i860_reloc_nyi,   /* special_function */
399          "SPLIT1",              /* name */
400          FALSE,                 /* partial_inplace */
401          0x1f07fe,              /* src_mask */
402          0x1f07fe,              /* dst_mask */
403          FALSE),                /* pcrel_offset */
404   HOWTO (COFF860_R_SPLIT2,      /* type */
405          0,                     /* rightshift */
406          2,                     /* size (0 = byte, 1 = short, 2 = long) */
407          16,                    /* bitsize */
408          FALSE,                 /* pc_relative */
409          0,                     /* bitpos */
410          complain_overflow_dont, /* complain_on_overflow */
411          coff_i860_reloc_nyi,   /* special_function */
412          "SPLIT2",              /* name */
413          FALSE,                 /* partial_inplace */
414          0x1f07fc,              /* src_mask */
415          0x1f07fc,              /* dst_mask */
416          FALSE),                /* pcrel_offset */
417   HOWTO (COFF860_R_HIGHADJ,     /* type */
418          0,                     /* rightshift */
419          2,                     /* size (0 = byte, 1 = short, 2 = long) */
420          16,                    /* bitsize */
421          FALSE,                 /* pc_relative */
422          0,                     /* bitpos */
423          complain_overflow_dont, /* complain_on_overflow */
424          coff_i860_reloc_nyi,   /* special_function */
425          "HIGHADJ",             /* name */
426          FALSE,                 /* partial_inplace */
427          0xffff,                /* src_mask */
428          0xffff,                /* dst_mask */
429          FALSE),                /* pcrel_offset */
430   HOWTO (COFF860_R_BRADDR,      /* type */
431          2,                     /* rightshift */
432          2,                     /* size (0 = byte, 1 = short, 2 = long) */
433          26,                    /* bitsize */
434          TRUE,                  /* pc_relative */
435          0,                     /* bitpos */
436          complain_overflow_bitfield, /* complain_on_overflow */
437          coff_i860_reloc_nyi,   /* special_function */
438          "BRADDR",              /* name */
439          FALSE,                 /* partial_inplace */
440          0x3ffffff,             /* src_mask */
441          0x3ffffff,             /* dst_mask */
442          TRUE)                  /* pcrel_offset */
443 };
444
445 /* Turn a howto into a reloc number.  */
446
447 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
448 #define BADMAG(x) I860BADMAG(x)
449 #define I860 1                  /* Customize coffcode.h */
450
451 #define RTYPE2HOWTO(cache_ptr, dst)                                     \
452   ((cache_ptr)->howto =                                                 \
453    ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0])      \
454     ? howto_table + (dst)->r_type                                       \
455     : NULL))
456
457 /* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
458    library.  On some other COFF targets STYP_BSS is normally
459    STYP_NOLOAD.  */
460 #define BSS_NOLOAD_IS_SHARED_LIBRARY
461
462 /* Compute the addend of a reloc.  If the reloc is to a common symbol,
463    the object file contains the value of the common symbol.  By the
464    time this is called, the linker may be using a different symbol
465    from a different object file with a different value.  Therefore, we
466    hack wildly to locate the original symbol from this file so that we
467    can make the correct adjustment.  This macro sets coffsym to the
468    symbol from the original file, and uses it to set the addend value
469    correctly.  If this is not a common symbol, the usual addend
470    calculation is done, except that an additional tweak is needed for
471    PC relative relocs.
472    FIXME: This macro refers to symbols and asect; these are from the
473    calling function, not the macro arguments.  */
474
475 /* PR 17512: file: 0a38fb7c
476    Set an addend value, even if it is not going to be used.  A tool
477    like coffdump might be used to print out the contents of the reloc.  */
478 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) (cache_ptr)->addend = 0
479
480 /* We use the special COFF backend linker.  */
481 #define coff_relocate_section _bfd_coff_generic_relocate_section
482
483 static reloc_howto_type *
484 coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
485                           asection *sec,
486                           struct internal_reloc *rel,
487                           struct coff_link_hash_entry *h,
488                           struct internal_syment *sym,
489                           bfd_vma *addendp)
490 {
491
492   reloc_howto_type *howto;
493
494   if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
495     {
496       bfd_set_error (bfd_error_bad_value);
497       return NULL;
498     }
499
500   howto = howto_table + rel->r_type;
501
502   if (howto->pc_relative)
503     *addendp += sec->vma;
504
505   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
506     {
507       /* This is a common symbol.  The section contents include the
508          size (sym->n_value) as an addend.  The relocate_section
509          function will be adding in the final value of the symbol.  We
510          need to subtract out the current size in order to get the
511          correct result.  */
512
513       BFD_ASSERT (h != NULL);
514
515       /* I think we *do* want to bypass this.  If we don't, I have seen some data
516          parameters get the wrong relocation address.  If I link two versions
517          with and without this section bypassed and then do a binary comparison,
518          the addresses which are different can be looked up in the map.  The
519          case in which this section has been bypassed has addresses which correspond
520          to values I can find in the map.  */
521       *addendp -= sym->n_value;
522     }
523
524   /* If the output symbol is common (in which case this must be a
525      relocatable link), we need to add in the final size of the
526      common symbol.  */
527   if (h != NULL && h->root.type == bfd_link_hash_common)
528     *addendp += h->root.u.c.size;
529
530   return howto;
531 }
532
533 static reloc_howto_type *
534 coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
535                              bfd_reloc_code_real_type code)
536 {
537   switch (code)
538     {
539     case BFD_RELOC_32:
540       return howto_table + R_DIR32;
541     case BFD_RELOC_860_PC26:
542       return howto_table + COFF860_R_BRADDR;
543     case BFD_RELOC_860_PC16:
544       /* ??? How to handle PC16 for COFF?  SPLIT0 is close for now.  */
545       return howto_table + COFF860_R_SPLIT0;
546     case BFD_RELOC_860_LOW0:
547       return howto_table + COFF860_R_LOW0;
548     case BFD_RELOC_860_SPLIT0:
549       return howto_table + COFF860_R_SPLIT0;
550     case BFD_RELOC_860_LOW1:
551       return howto_table + COFF860_R_LOW1;
552     case BFD_RELOC_860_SPLIT1:
553       return howto_table + COFF860_R_SPLIT1;
554     case BFD_RELOC_860_LOW2:
555       return howto_table + COFF860_R_LOW2;
556     case BFD_RELOC_860_SPLIT2:
557       return howto_table + COFF860_R_SPLIT2;
558     case BFD_RELOC_860_LOW3:
559       return howto_table + COFF860_R_LOW3;
560     case BFD_RELOC_860_HIGHADJ:
561       return howto_table + COFF860_R_HIGHADJ;
562     case BFD_RELOC_860_HIGH:
563       return howto_table + COFF860_R_HIGH;
564     default:
565       BFD_FAIL ();
566       return 0;
567     }
568 }
569
570 static reloc_howto_type *
571 coff_i860_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
572                              const char *r_name)
573 {
574   unsigned int i;
575
576   for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
577     if (howto_table[i].name != NULL
578         && strcasecmp (howto_table[i].name, r_name) == 0)
579       return &howto_table[i];
580
581   return NULL;
582 }
583
584 /* This is called from coff_slurp_reloc_table for each relocation
585    entry.  This special handling is due to the `PAIR' relocation
586    which has a different meaning for the `r_symndx' field.  */
587
588 static void
589 i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst,
590                        asymbol **symbols, bfd *abfd, asection *asect)
591 {
592   if (dst->r_type == COFF860_R_PAIR)
593     {
594       /* Handle the PAIR relocation specially.  */
595       cache_ptr->howto = howto_table + dst->r_type;
596       cache_ptr->address = dst->r_vaddr;
597       cache_ptr->addend = dst->r_symndx;
598       cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr;
599     }
600   else
601     {
602       /* For every other relocation, do exactly what coff_slurp_reloc_table
603          would do (which this code is taken directly from).  */
604       asymbol *ptr = NULL;
605       cache_ptr->address = dst->r_vaddr;
606
607       if (dst->r_symndx != -1)
608         {
609           if (dst->r_symndx < 0 || dst->r_symndx >= obj_conv_table_size (abfd))
610             {
611               _bfd_error_handler
612                 /* xgettext: c-format */
613                 (_("%pB: warning: illegal symbol index %ld in relocs"),
614                  abfd, dst->r_symndx);
615               cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
616               ptr = NULL;
617             }
618           else
619             {
620               cache_ptr->sym_ptr_ptr = (symbols
621                                         + obj_convert (abfd)[dst->r_symndx]);
622               ptr = *(cache_ptr->sym_ptr_ptr);
623             }
624         }
625       else
626         {
627           cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
628           ptr = NULL;
629         }
630
631       /* The symbols definitions that we have read in have been
632          relocated as if their sections started at 0. But the offsets
633          refering to the symbols in the raw data have not been
634          modified, so we have to have a negative addend to compensate.
635
636          Note that symbols which used to be common must be left alone.  */
637
638       /* Calculate any reloc addend by looking at the symbol.  */
639       CALC_ADDEND (abfd, ptr, (*dst), cache_ptr);
640       (void) ptr;
641
642       cache_ptr->address -= asect->vma;
643
644       /* Fill in the cache_ptr->howto field from dst->r_type.  */
645       RTYPE2HOWTO (cache_ptr, dst);
646     }
647 }
648 \f
649 #define coff_rtype_to_howto             coff_i860_rtype_to_howto
650 #define coff_bfd_reloc_type_lookup      coff_i860_reloc_type_lookup
651 #define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup
652
653 #define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
654   i860_reloc_processing (relent, reloc, symbols, abfd, section)
655
656 #include "coffcode.h"
657
658 static const bfd_target *
659 i3coff_object_p(bfd *a)
660 {
661   return coff_object_p (a);
662 }
663
664 const bfd_target
665 #ifdef TARGET_SYM
666   TARGET_SYM =
667 #else
668   i860_coff_vec =
669 #endif
670 {
671 #ifdef TARGET_NAME
672   TARGET_NAME,
673 #else
674   "coff-i860",                  /* name */
675 #endif
676   bfd_target_coff_flavour,
677   BFD_ENDIAN_LITTLE,            /* data byte order is little */
678   BFD_ENDIAN_LITTLE,            /* header byte order is little */
679
680   (HAS_RELOC | EXEC_P           /* object flags */
681    | HAS_LINENO | HAS_DEBUG
682    | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
683
684   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
685   '_',                          /* leading underscore */
686   '/',                          /* ar_pad_char */
687   15,                           /* ar_max_namelen */
688   0,                            /* match priority.  */
689
690   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
691      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
692      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
693   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
694      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
695      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
696
697 /* Note that we allow an object file to be treated as a core file as well.  */
698   {                             /* bfd_check_format */
699     _bfd_dummy_target,
700     i3coff_object_p,
701     bfd_generic_archive_p,
702     i3coff_object_p
703   },
704   {                             /* bfd_set_format */
705     _bfd_bool_bfd_false_error,
706     coff_mkobject,
707     _bfd_generic_mkarchive,
708     _bfd_bool_bfd_false_error
709   },
710   {                             /* bfd_write_contents */
711     _bfd_bool_bfd_false_error,
712     coff_write_object_contents,
713     _bfd_write_archive_contents,
714     _bfd_bool_bfd_false_error
715   },
716
717   BFD_JUMP_TABLE_GENERIC (coff),
718   BFD_JUMP_TABLE_COPY (coff),
719   BFD_JUMP_TABLE_CORE (_bfd_nocore),
720   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
721   BFD_JUMP_TABLE_SYMBOLS (coff),
722   BFD_JUMP_TABLE_RELOCS (coff),
723   BFD_JUMP_TABLE_WRITE (coff),
724   BFD_JUMP_TABLE_LINK (coff),
725   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
726
727   NULL,
728
729   COFF_SWAP_TABLE
730 };