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