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