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