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 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
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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
48static bfd_reloc_status_type
49coff_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
132static bfd_reloc_status_type
133coff_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
150static 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
471static reloc_howto_type *
472coff_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
521static reloc_howto_type *
522coff_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/* This is called from coff_slurp_reloc_table for each relocation
559   entry.  This special handling is due to the `PAIR' relocation
560   which has a different meaning for the `r_symndx' field.  */
561
562static void
563i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst,
564		       asymbol **symbols, bfd *abfd, asection *asect)
565{
566  if (dst->r_type == COFF860_R_PAIR)
567    {
568      /* Handle the PAIR relocation specially.  */
569      cache_ptr->howto = howto_table + dst->r_type;
570      cache_ptr->address = dst->r_vaddr;
571      cache_ptr->addend = dst->r_symndx;
572      cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr;
573    }
574  else
575    {
576      /* For every other relocation, do exactly what coff_slurp_reloc_table
577         would do (which this code is taken directly from).  */
578      asymbol *ptr = NULL;
579      cache_ptr->address = dst->r_vaddr;
580
581      if (dst->r_symndx != -1)
582	{
583	  if (dst->r_symndx < 0 || dst->r_symndx >= obj_conv_table_size (abfd))
584	    {
585	      (*_bfd_error_handler)
586		(_("%B: warning: illegal symbol index %ld in relocs"),
587		 abfd, dst->r_symndx);
588	      cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
589	      ptr = NULL;
590	    }
591	  else
592	    {
593	      cache_ptr->sym_ptr_ptr = (symbols
594					+ obj_convert (abfd)[dst->r_symndx]);
595	      ptr = *(cache_ptr->sym_ptr_ptr);
596	    }
597	}
598      else
599	{
600	  cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
601	  ptr = NULL;
602	}
603
604      /* The symbols definitions that we have read in have been
605	 relocated as if their sections started at 0. But the offsets
606	 refering to the symbols in the raw data have not been
607	 modified, so we have to have a negative addend to compensate.
608
609	 Note that symbols which used to be common must be left alone.  */
610
611      /* Calculate any reloc addend by looking at the symbol.  */
612      CALC_ADDEND (abfd, ptr, (*dst), cache_ptr);
613
614      cache_ptr->address -= asect->vma;
615
616      /* Fill in the cache_ptr->howto field from dst->r_type.  */
617      RTYPE2HOWTO (cache_ptr, dst);
618    }
619}
620
621#define coff_rtype_to_howto		coff_i860_rtype_to_howto
622#define coff_bfd_reloc_type_lookup	coff_i860_reloc_type_lookup
623
624#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
625  i860_reloc_processing (relent, reloc, symbols, abfd, section)
626
627#include "coffcode.h"
628
629static const bfd_target *
630i3coff_object_p(bfd *a)
631{
632  return coff_object_p (a);
633}
634
635const bfd_target
636#ifdef TARGET_SYM
637  TARGET_SYM =
638#else
639  i860coff_vec =
640#endif
641{
642#ifdef TARGET_NAME
643  TARGET_NAME,
644#else
645  "coff-i860",			/* name */
646#endif
647  bfd_target_coff_flavour,
648  BFD_ENDIAN_LITTLE,		/* data byte order is little */
649  BFD_ENDIAN_LITTLE,		/* header byte order is little */
650
651  (HAS_RELOC | EXEC_P |		/* object flags */
652   HAS_LINENO | HAS_DEBUG |
653   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
654
655  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
656  '_',				/* leading underscore */
657  '/',				/* ar_pad_char */
658  15,				/* ar_max_namelen */
659
660  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
661     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
662     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
663  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
664     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
665     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
666
667/* Note that we allow an object file to be treated as a core file as well.  */
668    {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
669       bfd_generic_archive_p, i3coff_object_p},
670    {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
671       bfd_false},
672    {bfd_false, coff_write_object_contents, /* bfd_write_contents */
673       _bfd_write_archive_contents, bfd_false},
674
675     BFD_JUMP_TABLE_GENERIC (coff),
676     BFD_JUMP_TABLE_COPY (coff),
677     BFD_JUMP_TABLE_CORE (_bfd_nocore),
678     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
679     BFD_JUMP_TABLE_SYMBOLS (coff),
680     BFD_JUMP_TABLE_RELOCS (coff),
681     BFD_JUMP_TABLE_WRITE (coff),
682     BFD_JUMP_TABLE_LINK (coff),
683     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
684
685  NULL,
686
687  COFF_SWAP_TABLE
688};
689