OSDN Git Service

(make_one_lib_file): For IDATA6 take the name from exp->internal_name if it
[pf3gnuchains/pf3gnuchains3x.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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
23 #include "bfd.h"
24 #include "sysdep.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 /* FIXME: This was copied from the i386 version originally but
467    appears to be wrong for i860.  For now we'll do nothing.  */
468 #if 0
469 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
470   {                                                             \
471     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;      \
472     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
473       coffsym = (obj_symbols (abfd)                             \
474                  + (cache_ptr->sym_ptr_ptr - symbols));         \
475     else if (ptr)                                               \
476       coffsym = coff_symbol_from (abfd, ptr);                   \
477     if (coffsym != (coff_symbol_type *) NULL                    \
478         && coffsym->native->u.syment.n_scnum == 0)              \
479       cache_ptr->addend = - coffsym->native->u.syment.n_value;  \
480     else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
481              && ptr->section != (asection *) NULL)              \
482       cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
483     else                                                        \
484       cache_ptr->addend = 0;                                    \
485     if (ptr && howto_table[reloc.r_type].pc_relative)           \
486       cache_ptr->addend += asect->vma;                          \
487   }
488 #else
489 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)
490 #endif
491
492 /* We use the special COFF backend linker.  */
493 #define coff_relocate_section _bfd_coff_generic_relocate_section
494
495 static reloc_howto_type *
496 coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
497                           asection *sec,
498                           struct internal_reloc *rel,
499                           struct coff_link_hash_entry *h,
500                           struct internal_syment *sym,
501                           bfd_vma *addendp)
502 {
503
504   reloc_howto_type *howto;
505
506   if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
507     {
508       bfd_set_error (bfd_error_bad_value);
509       return NULL;
510     }
511
512   howto = howto_table + rel->r_type;
513
514   if (howto->pc_relative)
515     *addendp += sec->vma;
516
517   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
518     {
519       /* This is a common symbol.  The section contents include the
520          size (sym->n_value) as an addend.  The relocate_section
521          function will be adding in the final value of the symbol.  We
522          need to subtract out the current size in order to get the
523          correct result.  */
524
525       BFD_ASSERT (h != NULL);
526
527       /* I think we *do* want to bypass this.  If we don't, I have seen some data
528          parameters get the wrong relocation address.  If I link two versions
529          with and without this section bypassed and then do a binary comparison,
530          the addresses which are different can be looked up in the map.  The
531          case in which this section has been bypassed has addresses which correspond
532          to values I can find in the map.  */
533       *addendp -= sym->n_value;
534     }
535
536   /* If the output symbol is common (in which case this must be a
537      relocatable link), we need to add in the final size of the
538      common symbol.  */
539   if (h != NULL && h->root.type == bfd_link_hash_common)
540     *addendp += h->root.u.c.size;
541
542   return howto;
543 }
544
545 static reloc_howto_type *
546 coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
547                              bfd_reloc_code_real_type code)
548 {
549   switch (code)
550     {
551     case BFD_RELOC_32:
552       return howto_table + R_DIR32;
553     case BFD_RELOC_860_PC26:
554       return howto_table + COFF860_R_BRADDR;
555     case BFD_RELOC_860_PC16:
556       /* ??? How to handle PC16 for COFF?  SPLIT0 is close for now.  */
557       return howto_table + COFF860_R_SPLIT0;
558     case BFD_RELOC_860_LOW0:
559       return howto_table + COFF860_R_LOW0;
560     case BFD_RELOC_860_SPLIT0:
561       return howto_table + COFF860_R_SPLIT0;
562     case BFD_RELOC_860_LOW1:
563       return howto_table + COFF860_R_LOW1;
564     case BFD_RELOC_860_SPLIT1:
565       return howto_table + COFF860_R_SPLIT1;
566     case BFD_RELOC_860_LOW2:
567       return howto_table + COFF860_R_LOW2;
568     case BFD_RELOC_860_SPLIT2:
569       return howto_table + COFF860_R_SPLIT2;
570     case BFD_RELOC_860_LOW3:
571       return howto_table + COFF860_R_LOW3;
572     case BFD_RELOC_860_HIGHADJ:
573       return howto_table + COFF860_R_HIGHADJ;
574     case BFD_RELOC_860_HIGH:
575       return howto_table + COFF860_R_HIGH;
576     default:
577       BFD_FAIL ();
578       return 0;
579     }
580 }
581
582 /* This is called from coff_slurp_reloc_table for each relocation
583    entry.  This special handling is due to the `PAIR' relocation
584    which has a different meaning for the `r_symndx' field.  */
585
586 static void
587 i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst,
588                        asymbol **symbols, bfd *abfd, asection *asect)
589 {
590   if (dst->r_type == COFF860_R_PAIR)
591     {
592       /* Handle the PAIR relocation specially.  */
593       cache_ptr->howto = howto_table + dst->r_type;
594       cache_ptr->address = dst->r_vaddr;
595       cache_ptr->addend = dst->r_symndx;
596       cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr;
597     }
598   else
599     {
600       /* For every other relocation, do exactly what coff_slurp_reloc_table
601          would do (which this code is taken directly from).  */
602       asymbol *ptr = NULL;
603       cache_ptr->address = dst->r_vaddr;
604
605       if (dst->r_symndx != -1)
606         {
607           if (dst->r_symndx < 0 || dst->r_symndx >= obj_conv_table_size (abfd))
608             {
609               (*_bfd_error_handler)
610                 (_("%B: warning: illegal symbol index %ld in relocs"),
611                  abfd, dst->r_symndx);
612               cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
613               ptr = NULL;
614             }
615           else
616             {
617               cache_ptr->sym_ptr_ptr = (symbols
618                                         + obj_convert (abfd)[dst->r_symndx]);
619               ptr = *(cache_ptr->sym_ptr_ptr);
620             }
621         }
622       else
623         {
624           cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
625           ptr = NULL;
626         }
627
628       /* The symbols definitions that we have read in have been
629          relocated as if their sections started at 0. But the offsets
630          refering to the symbols in the raw data have not been
631          modified, so we have to have a negative addend to compensate.
632
633          Note that symbols which used to be common must be left alone.  */
634
635       /* Calculate any reloc addend by looking at the symbol.  */
636       CALC_ADDEND (abfd, ptr, (*dst), cache_ptr);
637
638       cache_ptr->address -= asect->vma;
639
640       /* Fill in the cache_ptr->howto field from dst->r_type.  */
641       RTYPE2HOWTO (cache_ptr, dst);
642     }
643 }
644 \f
645 #define coff_rtype_to_howto             coff_i860_rtype_to_howto
646 #define coff_bfd_reloc_type_lookup      coff_i860_reloc_type_lookup
647
648 #define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
649   i860_reloc_processing (relent, reloc, symbols, abfd, section)
650
651 #include "coffcode.h"
652
653 static const bfd_target *
654 i3coff_object_p(bfd *a)
655 {
656   return coff_object_p (a);
657 }
658
659 const bfd_target
660 #ifdef TARGET_SYM
661   TARGET_SYM =
662 #else
663   i860coff_vec =
664 #endif
665 {
666 #ifdef TARGET_NAME
667   TARGET_NAME,
668 #else
669   "coff-i860",                  /* name */
670 #endif
671   bfd_target_coff_flavour,
672   BFD_ENDIAN_LITTLE,            /* data byte order is little */
673   BFD_ENDIAN_LITTLE,            /* header byte order is little */
674
675   (HAS_RELOC | EXEC_P |         /* object flags */
676    HAS_LINENO | HAS_DEBUG |
677    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
678
679   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
680   '_',                          /* leading underscore */
681   '/',                          /* ar_pad_char */
682   15,                           /* ar_max_namelen */
683
684   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
685      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
686      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
687   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
688      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
689      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
690
691 /* Note that we allow an object file to be treated as a core file as well.  */
692     {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
693        bfd_generic_archive_p, i3coff_object_p},
694     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
695        bfd_false},
696     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
697        _bfd_write_archive_contents, bfd_false},
698
699      BFD_JUMP_TABLE_GENERIC (coff),
700      BFD_JUMP_TABLE_COPY (coff),
701      BFD_JUMP_TABLE_CORE (_bfd_nocore),
702      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
703      BFD_JUMP_TABLE_SYMBOLS (coff),
704      BFD_JUMP_TABLE_RELOCS (coff),
705      BFD_JUMP_TABLE_WRITE (coff),
706      BFD_JUMP_TABLE_LINK (coff),
707      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
708
709   NULL,
710
711   COFF_SWAP_TABLE
712 };