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