Home | History | Annotate | Download | only in bfd
      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 (at) 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
     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
    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 *
    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 *
    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 *
    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
    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
    642 #define coff_bfd_reloc_type_lookup	coff_i860_reloc_type_lookup
    643 #define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup
    644 
    645 #define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
    646   i860_reloc_processing (relent, reloc, symbols, abfd, section)
    647 
    648 #include "coffcode.h"
    649 
    650 static const bfd_target *
    651 i3coff_object_p(bfd *a)
    652 {
    653   return coff_object_p (a);
    654 }
    655 
    656 const bfd_target
    657 #ifdef TARGET_SYM
    658   TARGET_SYM =
    659 #else
    660   i860_coff_vec =
    661 #endif
    662 {
    663 #ifdef TARGET_NAME
    664   TARGET_NAME,
    665 #else
    666   "coff-i860",			/* name */
    667 #endif
    668   bfd_target_coff_flavour,
    669   BFD_ENDIAN_LITTLE,		/* data byte order is little */
    670   BFD_ENDIAN_LITTLE,		/* header byte order is little */
    671 
    672   (HAS_RELOC | EXEC_P |		/* object flags */
    673    HAS_LINENO | HAS_DEBUG |
    674    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
    675 
    676   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
    677   '_',				/* leading underscore */
    678   '/',				/* ar_pad_char */
    679   15,				/* ar_max_namelen */
    680   0,				/* match priority.  */
    681 
    682   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
    683      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
    684      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
    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, /* hdrs */
    688 
    689 /* Note that we allow an object file to be treated as a core file as well.  */
    690     {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
    691        bfd_generic_archive_p, i3coff_object_p},
    692     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
    693        bfd_false},
    694     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
    695        _bfd_write_archive_contents, bfd_false},
    696 
    697      BFD_JUMP_TABLE_GENERIC (coff),
    698      BFD_JUMP_TABLE_COPY (coff),
    699      BFD_JUMP_TABLE_CORE (_bfd_nocore),
    700      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
    701      BFD_JUMP_TABLE_SYMBOLS (coff),
    702      BFD_JUMP_TABLE_RELOCS (coff),
    703      BFD_JUMP_TABLE_WRITE (coff),
    704      BFD_JUMP_TABLE_LINK (coff),
    705      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
    706 
    707   NULL,
    708 
    709   COFF_SWAP_TABLE
    710 };
    711