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