Automatic date update in version.in
[platform/upstream/binutils.git] / bfd / coff-i860.c
1 /* BFD back-end for Intel i860 COFF files.
2    Copyright (C) 1990-2014 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         switch (howto->size)
99           {
100           case 0:
101             {
102               char x = bfd_get_8 (abfd, addr);
103               DOIT (x);
104               bfd_put_8 (abfd, x, addr);
105             }
106             break;
107
108           case 1:
109             {
110               short x = bfd_get_16 (abfd, addr);
111               DOIT (x);
112               bfd_put_16 (abfd, (bfd_vma) x, addr);
113             }
114             break;
115
116           case 2:
117             {
118               long x = bfd_get_32 (abfd, addr);
119               DOIT (x);
120               bfd_put_32 (abfd, (bfd_vma) x, addr);
121             }
122             break;
123
124           default:
125             abort ();
126           }
127       }
128
129   /* Now let bfd_perform_relocation finish everything up.  */
130   return bfd_reloc_continue;
131 }
132
133 /* This is just a temporary measure until we teach bfd to generate
134    these relocations.  */
135
136 static bfd_reloc_status_type
137 coff_i860_reloc_nyi (bfd *abfd ATTRIBUTE_UNUSED,
138                      arelent *reloc_entry,
139                      asymbol *symbol ATTRIBUTE_UNUSED,
140                      void *data ATTRIBUTE_UNUSED,
141                      asection *input_section ATTRIBUTE_UNUSED,
142                      bfd *output_bfd ATTRIBUTE_UNUSED,
143                      char **error_message ATTRIBUTE_UNUSED)
144 {
145   reloc_howto_type *howto = reloc_entry->howto;
146   (*_bfd_error_handler) (_("relocation `%s' not yet implemented"), howto->name);
147   return bfd_reloc_notsupported;
148 }
149
150 #ifndef PCRELOFFSET
151 #define PCRELOFFSET FALSE
152 #endif
153
154 static reloc_howto_type howto_table[] =
155 {
156   EMPTY_HOWTO (0),
157   EMPTY_HOWTO (1),
158   EMPTY_HOWTO (2),
159   EMPTY_HOWTO (3),
160   EMPTY_HOWTO (4),
161   EMPTY_HOWTO (5),
162   HOWTO (R_DIR32,               /* type */
163          0,                     /* rightshift */
164          2,                     /* size (0 = byte, 1 = short, 2 = long) */
165          32,                    /* bitsize */
166          FALSE,                 /* pc_relative */
167          0,                     /* bitpos */
168          complain_overflow_bitfield, /* complain_on_overflow */
169          coff_i860_reloc,       /* special_function */
170          "dir32",               /* name */
171          TRUE,                  /* partial_inplace */
172          0xffffffff,            /* src_mask */
173          0xffffffff,            /* dst_mask */
174          TRUE),                /* pcrel_offset */
175   /* {7}, */
176   HOWTO (R_IMAGEBASE,            /* type */
177          0,                     /* rightshift */
178          2,                     /* size (0 = byte, 1 = short, 2 = long) */
179          32,                    /* bitsize */
180          FALSE,                 /* pc_relative */
181          0,                     /* bitpos */
182          complain_overflow_bitfield, /* complain_on_overflow */
183          coff_i860_reloc,       /* special_function */
184          "rva32",                  /* name */
185          TRUE,                  /* partial_inplace */
186          0xffffffff,            /* src_mask */
187          0xffffffff,            /* dst_mask */
188          FALSE),                /* pcrel_offset */
189   EMPTY_HOWTO (010),
190   EMPTY_HOWTO (011),
191   EMPTY_HOWTO (012),
192   EMPTY_HOWTO (013),
193   EMPTY_HOWTO (014),
194   EMPTY_HOWTO (015),
195   EMPTY_HOWTO (016),
196   HOWTO (R_RELBYTE,             /* type */
197          0,                     /* rightshift */
198          0,                     /* size (0 = byte, 1 = short, 2 = long) */
199          8,                     /* bitsize */
200          FALSE,                 /* pc_relative */
201          0,                     /* bitpos */
202          complain_overflow_bitfield, /* complain_on_overflow */
203          coff_i860_reloc,       /* special_function */
204          "8",                   /* name */
205          TRUE,                  /* partial_inplace */
206          0x000000ff,            /* src_mask */
207          0x000000ff,            /* dst_mask */
208          PCRELOFFSET),          /* pcrel_offset */
209   HOWTO (R_RELWORD,             /* type */
210          0,                     /* rightshift */
211          1,                     /* size (0 = byte, 1 = short, 2 = long) */
212          16,                    /* bitsize */
213          FALSE,                 /* pc_relative */
214          0,                     /* bitpos */
215          complain_overflow_bitfield, /* complain_on_overflow */
216          coff_i860_reloc,       /* special_function */
217          "16",                  /* name */
218          TRUE,                  /* partial_inplace */
219          0x0000ffff,            /* src_mask */
220          0x0000ffff,            /* dst_mask */
221          PCRELOFFSET),          /* pcrel_offset */
222   HOWTO (R_RELLONG,             /* type */
223          0,                     /* rightshift */
224          2,                     /* size (0 = byte, 1 = short, 2 = long) */
225          32,                    /* bitsize */
226          FALSE,                 /* pc_relative */
227          0,                     /* bitpos */
228          complain_overflow_bitfield, /* complain_on_overflow */
229          coff_i860_reloc,       /* special_function */
230          "32",                  /* name */
231          TRUE,                  /* partial_inplace */
232          0xffffffff,            /* src_mask */
233          0xffffffff,            /* dst_mask */
234          PCRELOFFSET),          /* pcrel_offset */
235   HOWTO (R_PCRBYTE,             /* type */
236          0,                     /* rightshift */
237          0,                     /* size (0 = byte, 1 = short, 2 = long) */
238          8,                     /* bitsize */
239          TRUE,                  /* pc_relative */
240          0,                     /* bitpos */
241          complain_overflow_signed, /* complain_on_overflow */
242          coff_i860_reloc,       /* special_function */
243          "DISP8",               /* name */
244          TRUE,                  /* partial_inplace */
245          0x000000ff,            /* src_mask */
246          0x000000ff,            /* dst_mask */
247          PCRELOFFSET),          /* pcrel_offset */
248   HOWTO (R_PCRWORD,             /* type */
249          0,                     /* rightshift */
250          1,                     /* size (0 = byte, 1 = short, 2 = long) */
251          16,                    /* bitsize */
252          TRUE,                  /* pc_relative */
253          0,                     /* bitpos */
254          complain_overflow_signed, /* complain_on_overflow */
255          coff_i860_reloc,       /* special_function */
256          "DISP16",              /* name */
257          TRUE,                  /* partial_inplace */
258          0x0000ffff,            /* src_mask */
259          0x0000ffff,            /* dst_mask */
260          PCRELOFFSET),          /* pcrel_offset */
261   HOWTO (R_PCRLONG,             /* type */
262          0,                     /* rightshift */
263          2,                     /* size (0 = byte, 1 = short, 2 = long) */
264          32,                    /* bitsize */
265          TRUE,                  /* pc_relative */
266          0,                     /* bitpos */
267          complain_overflow_signed, /* complain_on_overflow */
268          coff_i860_reloc,       /* special_function */
269          "DISP32",              /* name */
270          TRUE,                  /* partial_inplace */
271          0xffffffff,            /* src_mask */
272          0xffffffff,            /* dst_mask */
273          PCRELOFFSET),          /* pcrel_offset */
274   EMPTY_HOWTO (0x15),
275   EMPTY_HOWTO (0x16),
276   EMPTY_HOWTO (0x17),
277   EMPTY_HOWTO (0x18),
278   EMPTY_HOWTO (0x19),
279   EMPTY_HOWTO (0x1a),
280   EMPTY_HOWTO (0x1b),
281   HOWTO (COFF860_R_PAIR,        /* type */
282          0,                     /* rightshift */
283          2,                     /* size (0 = byte, 1 = short, 2 = long) */
284          16,                    /* bitsize */
285          FALSE,                 /* pc_relative */
286          0,                     /* bitpos */
287          complain_overflow_dont, /* complain_on_overflow */
288          coff_i860_reloc_nyi,   /* special_function */
289          "PAIR",                /* name */
290          FALSE,                 /* partial_inplace */
291          0xffff,                /* src_mask */
292          0xffff,                /* dst_mask */
293          FALSE),                /* pcrel_offset */
294   EMPTY_HOWTO (0x1d),
295   HOWTO (COFF860_R_HIGH,        /* type */
296          16,                    /* rightshift */
297          2,                     /* size (0 = byte, 1 = short, 2 = long) */
298          16,                    /* bitsize */
299          FALSE,                 /* pc_relative */
300          0,                     /* bitpos */
301          complain_overflow_dont, /* complain_on_overflow */
302          coff_i860_reloc,       /* special_function */
303          "HIGH",                /* name */
304          FALSE,                 /* partial_inplace */
305          0xffff,                /* src_mask */
306          0xffff,                /* dst_mask */
307          FALSE),                /* pcrel_offset */
308   HOWTO (COFF860_R_LOW0,        /* type */
309          0,                     /* rightshift */
310          2,                     /* size (0 = byte, 1 = short, 2 = long) */
311          16,                    /* bitsize */
312          FALSE,                 /* pc_relative */
313          0,                     /* bitpos */
314          complain_overflow_dont, /* complain_on_overflow */
315          coff_i860_reloc,       /* special_function */
316          "LOW0",                /* name */
317          FALSE,                 /* partial_inplace */
318          0xffff,                /* src_mask */
319          0xffff,                /* dst_mask */
320          FALSE),                /* pcrel_offset */
321   HOWTO (COFF860_R_LOW1,        /* 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          coff_i860_reloc,       /* special_function */
329          "LOW1",                /* name */
330          FALSE,                 /* partial_inplace */
331          0xfffe,                /* src_mask */
332          0xfffe,                /* dst_mask */
333          FALSE),                /* pcrel_offset */
334   HOWTO (COFF860_R_LOW2,        /* 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          coff_i860_reloc,       /* special_function */
342          "LOW2",                /* name */
343          FALSE,                 /* partial_inplace */
344          0xfffc,                /* src_mask */
345          0xfffc,                /* dst_mask */
346          FALSE),                /* pcrel_offset */
347   HOWTO (COFF860_R_LOW3,        /* type */
348          0,                     /* rightshift */
349          2,                     /* size (0 = byte, 1 = short, 2 = long) */
350          16,                    /* bitsize */
351          FALSE,                 /* pc_relative */
352          0,                     /* bitpos */
353          complain_overflow_dont, /* complain_on_overflow */
354          coff_i860_reloc,       /* special_function */
355          "LOW3",                /* name */
356          FALSE,                 /* partial_inplace */
357          0xfff8,                /* src_mask */
358          0xfff8,                /* dst_mask */
359          FALSE),                /* pcrel_offset */
360   HOWTO (COFF860_R_LOW4,        /* type */
361          0,                     /* rightshift */
362          2,                     /* size (0 = byte, 1 = short, 2 = long) */
363          16,                    /* bitsize */
364          FALSE,                 /* pc_relative */
365          0,                     /* bitpos */
366          complain_overflow_dont, /* complain_on_overflow */
367          coff_i860_reloc,       /* special_function */
368          "LOW4",                /* name */
369          FALSE,                 /* partial_inplace */
370          0xfff0,                /* src_mask */
371          0xfff0,                /* dst_mask */
372          FALSE),                /* pcrel_offset */
373   HOWTO (COFF860_R_SPLIT0,      /* type */
374          0,                     /* rightshift */
375          2,                     /* size (0 = byte, 1 = short, 2 = long) */
376          16,                    /* bitsize */
377          FALSE,                 /* pc_relative */
378          0,                     /* bitpos */
379          complain_overflow_dont, /* complain_on_overflow */
380          coff_i860_reloc_nyi,   /* special_function */
381          "SPLIT0",              /* name */
382          FALSE,                 /* partial_inplace */
383          0x1f07ff,              /* src_mask */
384          0x1f07ff,              /* dst_mask */
385          FALSE),                /* pcrel_offset */
386   HOWTO (COFF860_R_SPLIT1,      /* type */
387          0,                     /* rightshift */
388          2,                     /* size (0 = byte, 1 = short, 2 = long) */
389          16,                    /* bitsize */
390          FALSE,                 /* pc_relative */
391          0,                     /* bitpos */
392          complain_overflow_dont, /* complain_on_overflow */
393          coff_i860_reloc_nyi,   /* special_function */
394          "SPLIT1",              /* name */
395          FALSE,                 /* partial_inplace */
396          0x1f07fe,              /* src_mask */
397          0x1f07fe,              /* dst_mask */
398          FALSE),                /* pcrel_offset */
399   HOWTO (COFF860_R_SPLIT2,      /* type */
400          0,                     /* rightshift */
401          2,                     /* size (0 = byte, 1 = short, 2 = long) */
402          16,                    /* bitsize */
403          FALSE,                 /* pc_relative */
404          0,                     /* bitpos */
405          complain_overflow_dont, /* complain_on_overflow */
406          coff_i860_reloc_nyi,   /* special_function */
407          "SPLIT2",              /* name */
408          FALSE,                 /* partial_inplace */
409          0x1f07fc,              /* src_mask */
410          0x1f07fc,              /* dst_mask */
411          FALSE),                /* pcrel_offset */
412   HOWTO (COFF860_R_HIGHADJ,     /* type */
413          0,                     /* rightshift */
414          2,                     /* size (0 = byte, 1 = short, 2 = long) */
415          16,                    /* bitsize */
416          FALSE,                 /* pc_relative */
417          0,                     /* bitpos */
418          complain_overflow_dont, /* complain_on_overflow */
419          coff_i860_reloc_nyi,   /* special_function */
420          "HIGHADJ",             /* name */
421          FALSE,                 /* partial_inplace */
422          0xffff,                /* src_mask */
423          0xffff,                /* dst_mask */
424          FALSE),                /* pcrel_offset */
425   HOWTO (COFF860_R_BRADDR,      /* type */
426          2,                     /* rightshift */
427          2,                     /* size (0 = byte, 1 = short, 2 = long) */
428          26,                    /* bitsize */
429          TRUE,                  /* pc_relative */
430          0,                     /* bitpos */
431          complain_overflow_bitfield, /* complain_on_overflow */
432          coff_i860_reloc_nyi,   /* special_function */
433          "BRADDR",              /* name */
434          FALSE,                 /* partial_inplace */
435          0x3ffffff,             /* src_mask */
436          0x3ffffff,             /* dst_mask */
437          TRUE)                  /* pcrel_offset */
438 };
439
440 /* Turn a howto into a reloc number.  */
441
442 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
443 #define BADMAG(x) I860BADMAG(x)
444 #define I860 1                  /* Customize coffcode.h */
445
446 #define RTYPE2HOWTO(cache_ptr, dst)                                     \
447   ((cache_ptr)->howto =                                                 \
448    ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0])      \
449     ? howto_table + (dst)->r_type                                       \
450     : NULL))
451
452 /* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
453    library.  On some other COFF targets STYP_BSS is normally
454    STYP_NOLOAD.  */
455 #define BSS_NOLOAD_IS_SHARED_LIBRARY
456
457 /* Compute the addend of a reloc.  If the reloc is to a common symbol,
458    the object file contains the value of the common symbol.  By the
459    time this is called, the linker may be using a different symbol
460    from a different object file with a different value.  Therefore, we
461    hack wildly to locate the original symbol from this file so that we
462    can make the correct adjustment.  This macro sets coffsym to the
463    symbol from the original file, and uses it to set the addend value
464    correctly.  If this is not a common symbol, the usual addend
465    calculation is done, except that an additional tweak is needed for
466    PC relative relocs.
467    FIXME: This macro refers to symbols and asect; these are from the
468    calling function, not the macro arguments.  */
469
470 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)
471
472 /* We use the special COFF backend linker.  */
473 #define coff_relocate_section _bfd_coff_generic_relocate_section
474
475 static reloc_howto_type *
476 coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
477                           asection *sec,
478                           struct internal_reloc *rel,
479                           struct coff_link_hash_entry *h,
480                           struct internal_syment *sym,
481                           bfd_vma *addendp)
482 {
483
484   reloc_howto_type *howto;
485
486   if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
487     {
488       bfd_set_error (bfd_error_bad_value);
489       return NULL;
490     }
491
492   howto = howto_table + rel->r_type;
493
494   if (howto->pc_relative)
495     *addendp += sec->vma;
496
497   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
498     {
499       /* This is a common symbol.  The section contents include the
500          size (sym->n_value) as an addend.  The relocate_section
501          function will be adding in the final value of the symbol.  We
502          need to subtract out the current size in order to get the
503          correct result.  */
504
505       BFD_ASSERT (h != NULL);
506
507       /* I think we *do* want to bypass this.  If we don't, I have seen some data
508          parameters get the wrong relocation address.  If I link two versions
509          with and without this section bypassed and then do a binary comparison,
510          the addresses which are different can be looked up in the map.  The
511          case in which this section has been bypassed has addresses which correspond
512          to values I can find in the map.  */
513       *addendp -= sym->n_value;
514     }
515
516   /* If the output symbol is common (in which case this must be a
517      relocatable link), we need to add in the final size of the
518      common symbol.  */
519   if (h != NULL && h->root.type == bfd_link_hash_common)
520     *addendp += h->root.u.c.size;
521
522   return howto;
523 }
524
525 static reloc_howto_type *
526 coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
527                              bfd_reloc_code_real_type code)
528 {
529   switch (code)
530     {
531     case BFD_RELOC_32:
532       return howto_table + R_DIR32;
533     case BFD_RELOC_860_PC26:
534       return howto_table + COFF860_R_BRADDR;
535     case BFD_RELOC_860_PC16:
536       /* ??? How to handle PC16 for COFF?  SPLIT0 is close for now.  */
537       return howto_table + COFF860_R_SPLIT0;
538     case BFD_RELOC_860_LOW0:
539       return howto_table + COFF860_R_LOW0;
540     case BFD_RELOC_860_SPLIT0:
541       return howto_table + COFF860_R_SPLIT0;
542     case BFD_RELOC_860_LOW1:
543       return howto_table + COFF860_R_LOW1;
544     case BFD_RELOC_860_SPLIT1:
545       return howto_table + COFF860_R_SPLIT1;
546     case BFD_RELOC_860_LOW2:
547       return howto_table + COFF860_R_LOW2;
548     case BFD_RELOC_860_SPLIT2:
549       return howto_table + COFF860_R_SPLIT2;
550     case BFD_RELOC_860_LOW3:
551       return howto_table + COFF860_R_LOW3;
552     case BFD_RELOC_860_HIGHADJ:
553       return howto_table + COFF860_R_HIGHADJ;
554     case BFD_RELOC_860_HIGH:
555       return howto_table + COFF860_R_HIGH;
556     default:
557       BFD_FAIL ();
558       return 0;
559     }
560 }
561
562 static reloc_howto_type *
563 coff_i860_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
564                              const char *r_name)
565 {
566   unsigned int i;
567
568   for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
569     if (howto_table[i].name != NULL
570         && strcasecmp (howto_table[i].name, r_name) == 0)
571       return &howto_table[i];
572
573   return NULL;
574 }
575
576 /* This is called from coff_slurp_reloc_table for each relocation
577    entry.  This special handling is due to the `PAIR' relocation
578    which has a different meaning for the `r_symndx' field.  */
579
580 static void
581 i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst,
582                        asymbol **symbols, bfd *abfd, asection *asect)
583 {
584   if (dst->r_type == COFF860_R_PAIR)
585     {
586       /* Handle the PAIR relocation specially.  */
587       cache_ptr->howto = howto_table + dst->r_type;
588       cache_ptr->address = dst->r_vaddr;
589       cache_ptr->addend = dst->r_symndx;
590       cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr;
591     }
592   else
593     {
594       /* For every other relocation, do exactly what coff_slurp_reloc_table
595          would do (which this code is taken directly from).  */
596       asymbol *ptr = NULL;
597       cache_ptr->address = dst->r_vaddr;
598
599       if (dst->r_symndx != -1)
600         {
601           if (dst->r_symndx < 0 || dst->r_symndx >= obj_conv_table_size (abfd))
602             {
603               (*_bfd_error_handler)
604                 (_("%B: warning: illegal symbol index %ld in relocs"),
605                  abfd, dst->r_symndx);
606               cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
607               ptr = NULL;
608             }
609           else
610             {
611               cache_ptr->sym_ptr_ptr = (symbols
612                                         + obj_convert (abfd)[dst->r_symndx]);
613               ptr = *(cache_ptr->sym_ptr_ptr);
614             }
615         }
616       else
617         {
618           cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
619           ptr = NULL;
620         }
621
622       /* The symbols definitions that we have read in have been
623          relocated as if their sections started at 0. But the offsets
624          refering to the symbols in the raw data have not been
625          modified, so we have to have a negative addend to compensate.
626
627          Note that symbols which used to be common must be left alone.  */
628
629       /* Calculate any reloc addend by looking at the symbol.  */
630       CALC_ADDEND (abfd, ptr, (*dst), cache_ptr);
631       (void) ptr;
632
633       cache_ptr->address -= asect->vma;
634
635       /* Fill in the cache_ptr->howto field from dst->r_type.  */
636       RTYPE2HOWTO (cache_ptr, dst);
637     }
638 }
639 \f
640 #define coff_rtype_to_howto             coff_i860_rtype_to_howto
641 #define coff_bfd_reloc_type_lookup      coff_i860_reloc_type_lookup
642 #define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup
643
644 #define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
645   i860_reloc_processing (relent, reloc, symbols, abfd, section)
646
647 #include "coffcode.h"
648
649 static const bfd_target *
650 i3coff_object_p(bfd *a)
651 {
652   return coff_object_p (a);
653 }
654
655 const bfd_target
656 #ifdef TARGET_SYM
657   TARGET_SYM =
658 #else
659   i860_coff_vec =
660 #endif
661 {
662 #ifdef TARGET_NAME
663   TARGET_NAME,
664 #else
665   "coff-i860",                  /* name */
666 #endif
667   bfd_target_coff_flavour,
668   BFD_ENDIAN_LITTLE,            /* data byte order is little */
669   BFD_ENDIAN_LITTLE,            /* header byte order is little */
670
671   (HAS_RELOC | EXEC_P |         /* object flags */
672    HAS_LINENO | HAS_DEBUG |
673    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
674
675   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
676   '_',                          /* leading underscore */
677   '/',                          /* ar_pad_char */
678   15,                           /* ar_max_namelen */
679   0,                            /* match priority.  */
680
681   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
682      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
683      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
684   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
685      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
686      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
687
688 /* Note that we allow an object file to be treated as a core file as well.  */
689     {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
690        bfd_generic_archive_p, i3coff_object_p},
691     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
692        bfd_false},
693     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
694        _bfd_write_archive_contents, bfd_false},
695
696      BFD_JUMP_TABLE_GENERIC (coff),
697      BFD_JUMP_TABLE_COPY (coff),
698      BFD_JUMP_TABLE_CORE (_bfd_nocore),
699      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
700      BFD_JUMP_TABLE_SYMBOLS (coff),
701      BFD_JUMP_TABLE_RELOCS (coff),
702      BFD_JUMP_TABLE_WRITE (coff),
703      BFD_JUMP_TABLE_LINK (coff),
704      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
705
706   NULL,
707
708   COFF_SWAP_TABLE
709 };