1 /* BFD back-end for Intel i860 COFF files.
2    Copyright (C) 1990-2016 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 
52 static bfd_reloc_status_type
coff_i860_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section ATTRIBUTE_UNUSED,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)53 coff_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 
136 static bfd_reloc_status_type
coff_i860_reloc_nyi(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry,asymbol * symbol ATTRIBUTE_UNUSED,void * data ATTRIBUTE_UNUSED,asection * input_section ATTRIBUTE_UNUSED,bfd * output_bfd ATTRIBUTE_UNUSED,char ** error_message ATTRIBUTE_UNUSED)137 coff_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 
154 static 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 
478 static reloc_howto_type *
coff_i860_rtype_to_howto(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,struct internal_reloc * rel,struct coff_link_hash_entry * h,struct internal_syment * sym,bfd_vma * addendp)479 coff_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 
528 static reloc_howto_type *
coff_i860_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)529 coff_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 
565 static reloc_howto_type *
coff_i860_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)566 coff_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 
583 static void
i860_reloc_processing(arelent * cache_ptr,struct internal_reloc * dst,asymbol ** symbols,bfd * abfd,asection * asect)584 i860_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 		(_("%B: warning: illegal symbol index %ld in relocs"),
608 		 abfd, dst->r_symndx);
609 	      cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
610 	      ptr = NULL;
611 	    }
612 	  else
613 	    {
614 	      cache_ptr->sym_ptr_ptr = (symbols
615 					+ obj_convert (abfd)[dst->r_symndx]);
616 	      ptr = *(cache_ptr->sym_ptr_ptr);
617 	    }
618 	}
619       else
620 	{
621 	  cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
622 	  ptr = NULL;
623 	}
624 
625       /* The symbols definitions that we have read in have been
626 	 relocated as if their sections started at 0. But the offsets
627 	 refering to the symbols in the raw data have not been
628 	 modified, so we have to have a negative addend to compensate.
629 
630 	 Note that symbols which used to be common must be left alone.  */
631 
632       /* Calculate any reloc addend by looking at the symbol.  */
633       CALC_ADDEND (abfd, ptr, (*dst), cache_ptr);
634       (void) ptr;
635 
636       cache_ptr->address -= asect->vma;
637 
638       /* Fill in the cache_ptr->howto field from dst->r_type.  */
639       RTYPE2HOWTO (cache_ptr, dst);
640     }
641 }
642 
643 #define coff_rtype_to_howto		coff_i860_rtype_to_howto
644 #define coff_bfd_reloc_type_lookup	coff_i860_reloc_type_lookup
645 #define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup
646 
647 #define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
648   i860_reloc_processing (relent, reloc, symbols, abfd, section)
649 
650 #include "coffcode.h"
651 
652 static const bfd_target *
i3coff_object_p(bfd * a)653 i3coff_object_p(bfd *a)
654 {
655   return coff_object_p (a);
656 }
657 
658 const bfd_target
659 #ifdef TARGET_SYM
660   TARGET_SYM =
661 #else
662   i860_coff_vec =
663 #endif
664 {
665 #ifdef TARGET_NAME
666   TARGET_NAME,
667 #else
668   "coff-i860",			/* name */
669 #endif
670   bfd_target_coff_flavour,
671   BFD_ENDIAN_LITTLE,		/* data byte order is little */
672   BFD_ENDIAN_LITTLE,		/* header byte order is little */
673 
674   (HAS_RELOC | EXEC_P |		/* object flags */
675    HAS_LINENO | HAS_DEBUG |
676    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
677 
678   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
679   '_',				/* leading underscore */
680   '/',				/* ar_pad_char */
681   15,				/* ar_max_namelen */
682   0,				/* match priority.  */
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 };
713