Home | History | Annotate | Line # | Download | only in bfd
elf32-visium.c revision 1.1
      1  1.1  christos /* Visium-specific support for 32-bit ELF.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2003-2015 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program; if not, write to the Free Software
     19  1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor,
     20  1.1  christos    Boston, MA 02110-1301, USA.  */
     21  1.1  christos 
     22  1.1  christos #include "sysdep.h"
     23  1.1  christos #include "bfd.h"
     24  1.1  christos #include "sysdep.h"
     25  1.1  christos #include "libbfd.h"
     26  1.1  christos #include "elf-bfd.h"
     27  1.1  christos #include "elf/visium.h"
     28  1.1  christos 
     29  1.1  christos static bfd_reloc_status_type visium_elf_howto_parity_reloc
     30  1.1  christos   (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
     31  1.1  christos 
     32  1.1  christos static reloc_howto_type visium_elf_howto_table[] = {
     33  1.1  christos   /* This reloc does nothing.  */
     34  1.1  christos   HOWTO (R_VISIUM_NONE,		/* type */
     35  1.1  christos 	 0,			/* rightshift */
     36  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
     37  1.1  christos 	 32,			/* bitsize */
     38  1.1  christos 	 FALSE,			/* pc_relative */
     39  1.1  christos 	 0,			/* bitpos */
     40  1.1  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
     41  1.1  christos 	 bfd_elf_generic_reloc,	/* special_function */
     42  1.1  christos 	 "R_VISIUM_NONE",	/* name */
     43  1.1  christos 	 FALSE,			/* partial_inplace */
     44  1.1  christos 	 0,			/* src_mask */
     45  1.1  christos 	 0,			/* dst_mask */
     46  1.1  christos 	 FALSE),		/* pcrel_offset */
     47  1.1  christos 
     48  1.1  christos   /* A 8 bit absolute relocation.  */
     49  1.1  christos   HOWTO (R_VISIUM_8,		/* type */
     50  1.1  christos 	 0,			/* rightshift */
     51  1.1  christos 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
     52  1.1  christos 	 8,			/* bitsize */
     53  1.1  christos 	 FALSE,			/* pc_relative */
     54  1.1  christos 	 0,			/* bitpos */
     55  1.1  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
     56  1.1  christos 	 bfd_elf_generic_reloc,	/* special_function */
     57  1.1  christos 	 "R_VISIUM_8",		/* name */
     58  1.1  christos 	 FALSE,			/* partial_inplace */
     59  1.1  christos 	 0x00,			/* src_mask */
     60  1.1  christos 	 0xff,			/* dst_mask */
     61  1.1  christos 	 FALSE),		/* pcrel_offset */
     62  1.1  christos 
     63  1.1  christos   /* A 16 bit absolute relocation.  */
     64  1.1  christos   HOWTO (R_VISIUM_16,		/* type */
     65  1.1  christos 	 0,			/* rightshift */
     66  1.1  christos 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
     67  1.1  christos 	 16,			/* bitsize */
     68  1.1  christos 	 FALSE,			/* pc_relative */
     69  1.1  christos 	 0,			/* bitpos */
     70  1.1  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
     71  1.1  christos 	 bfd_elf_generic_reloc,	/* special_function */
     72  1.1  christos 	 "R_VISIUM_16",		/* name */
     73  1.1  christos 	 FALSE,			/* partial_inplace */
     74  1.1  christos 	 0x0000,		/* src_mask */
     75  1.1  christos 	 0xffff,		/* dst_mask */
     76  1.1  christos 	 FALSE),		/* pcrel_offset */
     77  1.1  christos 
     78  1.1  christos   /* A 32 bit absolute relocation.  */
     79  1.1  christos   HOWTO (R_VISIUM_32,		/* type */
     80  1.1  christos 	 0,			/* rightshift */
     81  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
     82  1.1  christos 	 32,			/* bitsize */
     83  1.1  christos 	 FALSE,			/* pc_relative */
     84  1.1  christos 	 0,			/* bitpos */
     85  1.1  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
     86  1.1  christos 	 bfd_elf_generic_reloc,	/* special_function */
     87  1.1  christos 	 "R_VISIUM_32",		/* name */
     88  1.1  christos 	 FALSE,			/* partial_inplace */
     89  1.1  christos 	 0x00000000,		/* src_mask */
     90  1.1  christos 	 0xffffffff,		/* dst_mask */
     91  1.1  christos 	 FALSE),		/* pcrel_offset */
     92  1.1  christos 
     93  1.1  christos 
     94  1.1  christos   /* A 8 bit PC relative relocation.  */
     95  1.1  christos   HOWTO (R_VISIUM_8_PCREL,		/* type */
     96  1.1  christos 	 0,			/* rightshift */
     97  1.1  christos 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
     98  1.1  christos 	 8,			/* bitsize */
     99  1.1  christos 	 TRUE,			/* pc_relative */
    100  1.1  christos 	 0,			/* bitpos */
    101  1.1  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
    102  1.1  christos 	 bfd_elf_generic_reloc,	/* special_function */
    103  1.1  christos 	 "R_VISIUM_8_PCREL",	/* name */
    104  1.1  christos 	 FALSE,			/* partial_inplace */
    105  1.1  christos 	 0x00,			/* src_mask */
    106  1.1  christos 	 0xff,			/* dst_mask */
    107  1.1  christos 	 TRUE),			/* pcrel_offset */
    108  1.1  christos 
    109  1.1  christos   /* A 16 bit PC relative relocation.  */
    110  1.1  christos   HOWTO (R_VISIUM_16_PCREL,	/* type */
    111  1.1  christos 	 0,			/* rightshift */
    112  1.1  christos 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
    113  1.1  christos 	 16,			/* bitsize */
    114  1.1  christos 	 TRUE,			/* pc_relative */
    115  1.1  christos 	 0,			/* bitpos */
    116  1.1  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
    117  1.1  christos 	 bfd_elf_generic_reloc,	/* special_function */
    118  1.1  christos 	 "R_VISIUM_16_PCREL",	/* name */
    119  1.1  christos 	 FALSE,			/* partial inplace */
    120  1.1  christos 	 0x0000,		/* src_mask */
    121  1.1  christos 	 0xffff,		/* dst_mask */
    122  1.1  christos 	 TRUE),			/* pcrel_offset */
    123  1.1  christos 
    124  1.1  christos   /* A 32-bit PC relative relocation.  */
    125  1.1  christos   HOWTO (R_VISIUM_32_PCREL,	/* type */
    126  1.1  christos 	 0,			/* rightshift */
    127  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    128  1.1  christos 	 32,			/* bitsize */
    129  1.1  christos 	 TRUE,			/* pc_relative */
    130  1.1  christos 	 0,			/* bitpos */
    131  1.1  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
    132  1.1  christos 	 bfd_elf_generic_reloc,	/* special_function */
    133  1.1  christos 	 "R_VISIUM_32_PCREL",	/* name */
    134  1.1  christos 	 FALSE,			/* partial_inplace */
    135  1.1  christos 	 0,			/* src_mask */
    136  1.1  christos 	 0xffffffff,		/* dst_mask */
    137  1.1  christos 	 TRUE),			/* pcrel_offset */
    138  1.1  christos 
    139  1.1  christos   /* A 16-bit PC word relative offset, relative to start of instruction
    140  1.1  christos      and always in the second half of the instruction.  */
    141  1.1  christos   HOWTO (R_VISIUM_PC16,		/* type */
    142  1.1  christos 	 2,			/* rightshift */
    143  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    144  1.1  christos 	 16,			/* bitsize */
    145  1.1  christos 	 TRUE,			/* pc_relative */
    146  1.1  christos 	 0,			/* bitpos */
    147  1.1  christos 	 complain_overflow_signed,	/* complain_on_overflow */
    148  1.1  christos 	 visium_elf_howto_parity_reloc,	/* special_function */
    149  1.1  christos 	 "R_VISIUM_PC16",	/* name */
    150  1.1  christos 	 FALSE,			/* partial_inplace */
    151  1.1  christos 	 0x00000000,		/* src_mask */
    152  1.1  christos 	 0x0000ffff,		/* dst_mask */
    153  1.1  christos 	 TRUE),			/* pcrel_offset */
    154  1.1  christos 
    155  1.1  christos   /* The high 16 bits of symbol value.  */
    156  1.1  christos   HOWTO (R_VISIUM_HI16,		/* type */
    157  1.1  christos 	 16,			/* rightshift */
    158  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    159  1.1  christos 	 16,			/* bitsize */
    160  1.1  christos 	 FALSE,			/* pc_relative */
    161  1.1  christos 	 0,			/* bitpos */
    162  1.1  christos 	 complain_overflow_dont,	/* complain_on_overflow */
    163  1.1  christos 	 visium_elf_howto_parity_reloc,	/* special_function */
    164  1.1  christos 	 "R_VISIUM_HI16",	/* name */
    165  1.1  christos 	 FALSE,			/* partial_inplace */
    166  1.1  christos 	 0x00000000,		/* src_mask */
    167  1.1  christos 	 0x0000ffff,		/* dst_mask */
    168  1.1  christos 	 FALSE),		/* pcrel_offset */
    169  1.1  christos 
    170  1.1  christos   /* The low 16 bits of symbol value.  */
    171  1.1  christos   HOWTO (R_VISIUM_LO16,		/* type */
    172  1.1  christos 	 0,			/* rightshift */
    173  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    174  1.1  christos 	 16,			/* bitsize */
    175  1.1  christos 	 FALSE,			/* pc_relative */
    176  1.1  christos 	 0,			/* bitpos */
    177  1.1  christos 	 complain_overflow_dont,	/* complain_on_overflow */
    178  1.1  christos 	 visium_elf_howto_parity_reloc,	/* special_function */
    179  1.1  christos 	 "R_VISIUM_LO16",	/* name */
    180  1.1  christos 	 FALSE,			/* partial_inplace */
    181  1.1  christos 	 0x00000000,		/* src_mask */
    182  1.1  christos 	 0x0000ffff,		/* dst_mask */
    183  1.1  christos 	 FALSE),		/* pcrel_offset */
    184  1.1  christos 
    185  1.1  christos   /* A 16 bit immediate value.  */
    186  1.1  christos   HOWTO (R_VISIUM_IM16,		/* type */
    187  1.1  christos 	 0,			/* rightshift */
    188  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    189  1.1  christos 	 16,			/* bitsize */
    190  1.1  christos 	 FALSE,			/* pc_relative */
    191  1.1  christos 	 0,			/* bitpos */
    192  1.1  christos 	 complain_overflow_unsigned,	/* complain_on_overflow */
    193  1.1  christos 	 visium_elf_howto_parity_reloc,	/* special_function */
    194  1.1  christos 	 "R_VISIUM_IM16",	/* name */
    195  1.1  christos 	 FALSE,			/* partial_inplace */
    196  1.1  christos 	 0x0000000,		/* src_mask */
    197  1.1  christos 	 0x000ffff,		/* dst_mask */
    198  1.1  christos 	 FALSE),		/* pcrel_offset */
    199  1.1  christos 
    200  1.1  christos   /* The high 16 bits of symbol value, pc relative.  */
    201  1.1  christos   HOWTO (R_VISIUM_HI16_PCREL,	/* type */
    202  1.1  christos 	 16,			/* rightshift */
    203  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    204  1.1  christos 	 16,			/* bitsize */
    205  1.1  christos 	 TRUE,			/* pc_relative */
    206  1.1  christos 	 0,			/* bitpos */
    207  1.1  christos 	 complain_overflow_dont,	/* complain_on_overflow */
    208  1.1  christos 	 visium_elf_howto_parity_reloc,	/* special_function */
    209  1.1  christos 	 "R_VISIUM_HI16_PCREL",	/* name */
    210  1.1  christos 	 FALSE,			/* partial_inplace */
    211  1.1  christos 	 0x00000000,		/* src_mask */
    212  1.1  christos 	 0x0000ffff,		/* dst_mask */
    213  1.1  christos 	 TRUE),			/* pcrel_offset */
    214  1.1  christos 
    215  1.1  christos   /* The low 16 bits of symbol value, pc relative.  */
    216  1.1  christos   HOWTO (R_VISIUM_LO16_PCREL,	/* type */
    217  1.1  christos 	 0,			/* rightshift */
    218  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    219  1.1  christos 	 16,			/* bitsize */
    220  1.1  christos 	 TRUE,			/* pc_relative */
    221  1.1  christos 	 0,			/* bitpos */
    222  1.1  christos 	 complain_overflow_dont,	/* complain_on_overflow */
    223  1.1  christos 	 visium_elf_howto_parity_reloc,	/* special_function */
    224  1.1  christos 	 "R_VISIUM_LO16_PCREL",	/* name */
    225  1.1  christos 	 FALSE,			/* partial_inplace */
    226  1.1  christos 	 0x00000000,		/* src_mask */
    227  1.1  christos 	 0x0000ffff,		/* dst_mask */
    228  1.1  christos 	 TRUE),			/* pcrel_offset */
    229  1.1  christos 
    230  1.1  christos   /* A 16 bit immediate value, pc relative.  */
    231  1.1  christos   HOWTO (R_VISIUM_IM16_PCREL,	/* type */
    232  1.1  christos 	 0,			/* rightshift */
    233  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    234  1.1  christos 	 16,			/* bitsize */
    235  1.1  christos 	 TRUE,			/* pc_relative */
    236  1.1  christos 	 0,			/* bitpos */
    237  1.1  christos 	 complain_overflow_unsigned,	/* complain_on_overflow */
    238  1.1  christos 	 visium_elf_howto_parity_reloc,	/* special_function */
    239  1.1  christos 	 "R_VISIUM_IM16_PCREL",	/* name */
    240  1.1  christos 	 FALSE,			/* partial_inplace */
    241  1.1  christos 	 0x0000000,		/* src_mask */
    242  1.1  christos 	 0x000ffff,		/* dst_mask */
    243  1.1  christos 	 TRUE),			/* pcrel_offset */
    244  1.1  christos 
    245  1.1  christos };
    246  1.1  christos 
    247  1.1  christos /* GNU extension to record C++ vtable hierarchy.  */
    248  1.1  christos static reloc_howto_type visium_elf_vtinherit_howto =
    249  1.1  christos   HOWTO (R_VISIUM_GNU_VTINHERIT,      /* type */
    250  1.1  christos 	 0,			   /* rightshift */
    251  1.1  christos 	 2,			   /* size (0 = byte, 1 = short, 2 = long) */
    252  1.1  christos 	 0,			   /* bitsize */
    253  1.1  christos 	 FALSE,			   /* pc_relative */
    254  1.1  christos 	 0,			   /* bitpos */
    255  1.1  christos 	 complain_overflow_dont,   /* complain_on_overflow */
    256  1.1  christos 	 NULL,			   /* special_function */
    257  1.1  christos 	 "R_VISIUM_GNU_VTINHERIT", /* name */
    258  1.1  christos 	 FALSE,			   /* partial_inplace */
    259  1.1  christos 	 0,			   /* src_mask */
    260  1.1  christos 	 0,			   /* dst_mask */
    261  1.1  christos 	 FALSE);		   /* pcrel_offset */
    262  1.1  christos 
    263  1.1  christos /* GNU extension to record C++ vtable member usage.  */
    264  1.1  christos static reloc_howto_type visium_elf_vtentry_howto =
    265  1.1  christos   HOWTO (R_VISIUM_GNU_VTENTRY,	   /* type */
    266  1.1  christos 	 0,			   /* rightshift */
    267  1.1  christos 	 2,			   /* size (0 = byte, 1 = short, 2 = long) */
    268  1.1  christos 	 0,			   /* bitsize */
    269  1.1  christos 	 FALSE,			   /* pc_relative */
    270  1.1  christos 	 0,			   /* bitpos */
    271  1.1  christos 	 complain_overflow_dont,   /* complain_on_overflow */
    272  1.1  christos 	 NULL,			   /* special_function */
    273  1.1  christos 	 "R_VISIUM_GNU_VTENTRY",   /* name */
    274  1.1  christos 	 FALSE,			   /* partial_inplace */
    275  1.1  christos 	 0,			   /* src_mask */
    276  1.1  christos 	 0,			   /* dst_mask */
    277  1.1  christos 	 FALSE);		   /* pcrel_offset */
    278  1.1  christos 
    279  1.1  christos /* Map BFD reloc types to VISIUM ELF reloc types.  */
    280  1.1  christos struct visium_reloc_map
    281  1.1  christos {
    282  1.1  christos   bfd_reloc_code_real_type bfd_reloc_val;
    283  1.1  christos   unsigned int visium_reloc_val;
    284  1.1  christos };
    285  1.1  christos 
    286  1.1  christos static const struct visium_reloc_map visium_reloc_map[] = {
    287  1.1  christos   {BFD_RELOC_NONE, 		R_VISIUM_NONE},
    288  1.1  christos   {BFD_RELOC_8, 		R_VISIUM_8},
    289  1.1  christos   {BFD_RELOC_16,		R_VISIUM_16},
    290  1.1  christos   {BFD_RELOC_32, 		R_VISIUM_32},
    291  1.1  christos   {BFD_RELOC_8_PCREL,		R_VISIUM_8_PCREL},
    292  1.1  christos   {BFD_RELOC_16_PCREL,		R_VISIUM_16_PCREL},
    293  1.1  christos   {BFD_RELOC_32_PCREL,		R_VISIUM_32_PCREL},
    294  1.1  christos   {BFD_RELOC_VISIUM_REL16,	R_VISIUM_PC16},
    295  1.1  christos   {BFD_RELOC_VISIUM_HI16,	R_VISIUM_HI16},
    296  1.1  christos   {BFD_RELOC_VISIUM_LO16,	R_VISIUM_LO16},
    297  1.1  christos   {BFD_RELOC_VISIUM_IM16,	R_VISIUM_IM16},
    298  1.1  christos   {BFD_RELOC_VISIUM_HI16_PCREL,	R_VISIUM_HI16_PCREL},
    299  1.1  christos   {BFD_RELOC_VISIUM_LO16_PCREL,	R_VISIUM_LO16_PCREL},
    300  1.1  christos   {BFD_RELOC_VISIUM_IM16_PCREL,	R_VISIUM_IM16_PCREL},
    301  1.1  christos   {BFD_RELOC_VTABLE_INHERIT,	R_VISIUM_GNU_VTINHERIT},
    302  1.1  christos   {BFD_RELOC_VTABLE_ENTRY,	R_VISIUM_GNU_VTENTRY},
    303  1.1  christos };
    304  1.1  christos 
    305  1.1  christos /* Return the parity bit for INSN shifted to its final position.  */
    306  1.1  christos 
    307  1.1  christos static bfd_vma
    308  1.1  christos visium_parity_bit (bfd_vma insn)
    309  1.1  christos {
    310  1.1  christos   bfd_vma p = 0;
    311  1.1  christos   int i;
    312  1.1  christos 
    313  1.1  christos   for (i = 0; i < 31; i++)
    314  1.1  christos     {
    315  1.1  christos       p ^= (insn & 1);
    316  1.1  christos       insn >>= 1;
    317  1.1  christos     }
    318  1.1  christos 
    319  1.1  christos   return p << 31;
    320  1.1  christos }
    321  1.1  christos 
    322  1.1  christos /* This "special function" will only be used when the input and
    323  1.1  christos    output files have different formats ie. when generating S-records
    324  1.1  christos    directly using "--oformat srec". Otherwise we use
    325  1.1  christos    _bfd_final_link_relocate which uses a howto structure, but does
    326  1.1  christos    not use the special_function field.
    327  1.1  christos 
    328  1.1  christos    It sets instruction parity to even.  This cannot be done by a howto.  */
    329  1.1  christos 
    330  1.1  christos static bfd_reloc_status_type
    331  1.1  christos visium_elf_howto_parity_reloc (bfd * input_bfd, arelent *reloc_entry,
    332  1.1  christos 			       asymbol *symbol, PTR data,
    333  1.1  christos 			       asection *input_section, bfd *output_bfd,
    334  1.1  christos 			       char **error_message ATTRIBUTE_UNUSED)
    335  1.1  christos {
    336  1.1  christos   bfd_reloc_status_type ret;
    337  1.1  christos   bfd_vma relocation;
    338  1.1  christos   bfd_byte *inplace_address;
    339  1.1  christos   bfd_vma insn;
    340  1.1  christos   const bfd_vma signmask = 0xffff8000;
    341  1.1  christos 
    342  1.1  christos   /* This part is from bfd_elf_generic_reloc.
    343  1.1  christos      If we're relocating, and this an external symbol, we don't want
    344  1.1  christos      to change anything.  */
    345  1.1  christos   if (output_bfd != (bfd *) NULL && (symbol->flags & BSF_SECTION_SYM) == 0)
    346  1.1  christos     {
    347  1.1  christos       reloc_entry->address += input_section->output_offset;
    348  1.1  christos       return bfd_reloc_ok;
    349  1.1  christos     }
    350  1.1  christos 
    351  1.1  christos   /* Now do the reloc in the usual way.  */
    352  1.1  christos 
    353  1.1  christos   /* Sanity check the address (offset in section).  */
    354  1.1  christos   if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section))
    355  1.1  christos     return bfd_reloc_outofrange;
    356  1.1  christos 
    357  1.1  christos   ret = bfd_reloc_ok;
    358  1.1  christos   if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
    359  1.1  christos     ret = bfd_reloc_undefined;
    360  1.1  christos 
    361  1.1  christos   if (bfd_is_com_section (symbol->section) || output_bfd != (bfd *) NULL)
    362  1.1  christos     relocation = 0;
    363  1.1  christos   else
    364  1.1  christos     relocation = symbol->value;
    365  1.1  christos 
    366  1.1  christos   /* Only do this for a final link.  */
    367  1.1  christos   if (output_bfd == (bfd *) NULL)
    368  1.1  christos     {
    369  1.1  christos       relocation += symbol->section->output_section->vma;
    370  1.1  christos       relocation += symbol->section->output_offset;
    371  1.1  christos     }
    372  1.1  christos 
    373  1.1  christos   relocation += reloc_entry->addend;
    374  1.1  christos   inplace_address = (bfd_byte *) data + reloc_entry->address;
    375  1.1  christos   insn = bfd_get_32 (input_bfd, inplace_address);
    376  1.1  christos 
    377  1.1  christos   if (reloc_entry->howto->pc_relative)
    378  1.1  christos     {
    379  1.1  christos       relocation -= input_section->output_section->vma
    380  1.1  christos 	+ input_section->output_offset;
    381  1.1  christos       relocation -= reloc_entry->address;
    382  1.1  christos     }
    383  1.1  christos 
    384  1.1  christos   switch (reloc_entry->howto->type)
    385  1.1  christos     {
    386  1.1  christos     case R_VISIUM_PC16:
    387  1.1  christos       relocation >>= 2;
    388  1.1  christos       if (ret == bfd_reloc_ok && (relocation & signmask) != 0
    389  1.1  christos 	  && (relocation & signmask) != signmask)
    390  1.1  christos 	ret = bfd_reloc_overflow;
    391  1.1  christos       relocation &= 0xffff;
    392  1.1  christos       break;
    393  1.1  christos     case R_VISIUM_HI16:
    394  1.1  christos     case R_VISIUM_HI16_PCREL:
    395  1.1  christos       relocation = (relocation >> 16) & 0xffff;
    396  1.1  christos       break;
    397  1.1  christos     case R_VISIUM_LO16:
    398  1.1  christos     case R_VISIUM_LO16_PCREL:
    399  1.1  christos       relocation &= 0xffff;
    400  1.1  christos       break;
    401  1.1  christos     case R_VISIUM_IM16:
    402  1.1  christos     case R_VISIUM_IM16_PCREL:
    403  1.1  christos       if (ret == bfd_reloc_ok && (relocation & 0xffff0000) != 0)
    404  1.1  christos 	ret = bfd_reloc_overflow;
    405  1.1  christos       relocation &= 0xffff;
    406  1.1  christos       break;
    407  1.1  christos     }
    408  1.1  christos   insn = (insn & 0x7fff0000) | relocation;
    409  1.1  christos   insn |= visium_parity_bit (insn);
    410  1.1  christos   bfd_put_32 (input_bfd, insn, inplace_address);
    411  1.1  christos 
    412  1.1  christos   if (output_bfd != (bfd *) NULL)
    413  1.1  christos     reloc_entry->address += input_section->output_offset;
    414  1.1  christos 
    415  1.1  christos   return ret;
    416  1.1  christos }
    417  1.1  christos 
    418  1.1  christos static reloc_howto_type *
    419  1.1  christos visium_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    420  1.1  christos 			  bfd_reloc_code_real_type code)
    421  1.1  christos {
    422  1.1  christos   /* Note that the visium_elf_howto_table is indexed by the R_
    423  1.1  christos      constants. Thus, the order that the howto records appear in the
    424  1.1  christos      table *must* match the order of the relocation types defined in
    425  1.1  christos      include/elf/visium.h.  */
    426  1.1  christos   switch (code)
    427  1.1  christos     {
    428  1.1  christos     case BFD_RELOC_NONE:
    429  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_NONE];
    430  1.1  christos     case BFD_RELOC_8:
    431  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_8];
    432  1.1  christos     case BFD_RELOC_16:
    433  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_16];
    434  1.1  christos     case BFD_RELOC_32:
    435  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_32];
    436  1.1  christos     case BFD_RELOC_8_PCREL:
    437  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_8_PCREL];
    438  1.1  christos     case BFD_RELOC_16_PCREL:
    439  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_16_PCREL];
    440  1.1  christos     case BFD_RELOC_32_PCREL:
    441  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_32_PCREL];
    442  1.1  christos     case BFD_RELOC_VISIUM_REL16:
    443  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_PC16];
    444  1.1  christos     case BFD_RELOC_VISIUM_HI16:
    445  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_HI16];
    446  1.1  christos     case BFD_RELOC_VISIUM_LO16:
    447  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_LO16];
    448  1.1  christos     case BFD_RELOC_VISIUM_IM16:
    449  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_IM16];
    450  1.1  christos     case BFD_RELOC_VISIUM_HI16_PCREL:
    451  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_HI16_PCREL];
    452  1.1  christos     case BFD_RELOC_VISIUM_LO16_PCREL:
    453  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_LO16_PCREL];
    454  1.1  christos     case BFD_RELOC_VISIUM_IM16_PCREL:
    455  1.1  christos       return &visium_elf_howto_table[(int) R_VISIUM_IM16_PCREL];
    456  1.1  christos     case BFD_RELOC_VTABLE_INHERIT:
    457  1.1  christos       return &visium_elf_vtinherit_howto;
    458  1.1  christos     case BFD_RELOC_VTABLE_ENTRY:
    459  1.1  christos       return &visium_elf_vtentry_howto;
    460  1.1  christos     default:
    461  1.1  christos       return NULL;
    462  1.1  christos     }
    463  1.1  christos }
    464  1.1  christos 
    465  1.1  christos static reloc_howto_type *
    466  1.1  christos visium_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
    467  1.1  christos {
    468  1.1  christos   unsigned int i;
    469  1.1  christos 
    470  1.1  christos   for (i = 0;
    471  1.1  christos        i < (sizeof (visium_elf_howto_table)
    472  1.1  christos 	    / sizeof (visium_elf_howto_table[0])); i++)
    473  1.1  christos     if (visium_elf_howto_table[i].name != NULL
    474  1.1  christos 	&& strcasecmp (visium_elf_howto_table[i].name, r_name) == 0)
    475  1.1  christos       return &visium_elf_howto_table[i];
    476  1.1  christos 
    477  1.1  christos   if (strcasecmp (visium_elf_vtinherit_howto.name, r_name) == 0)
    478  1.1  christos     return &visium_elf_vtinherit_howto;
    479  1.1  christos   if (strcasecmp (visium_elf_vtentry_howto.name, r_name) == 0)
    480  1.1  christos     return &visium_elf_vtentry_howto;
    481  1.1  christos 
    482  1.1  christos   return NULL;
    483  1.1  christos }
    484  1.1  christos 
    485  1.1  christos /* Set the howto pointer for a VISIUM ELF reloc.  */
    486  1.1  christos 
    487  1.1  christos static void
    488  1.1  christos visium_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
    489  1.1  christos 			   Elf_Internal_Rela *dst)
    490  1.1  christos {
    491  1.1  christos   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
    492  1.1  christos 
    493  1.1  christos   switch (r_type)
    494  1.1  christos     {
    495  1.1  christos     case R_VISIUM_GNU_VTINHERIT:
    496  1.1  christos       cache_ptr->howto = &visium_elf_vtinherit_howto;
    497  1.1  christos       break;
    498  1.1  christos 
    499  1.1  christos     case R_VISIUM_GNU_VTENTRY:
    500  1.1  christos       cache_ptr->howto = &visium_elf_vtentry_howto;
    501  1.1  christos       break;
    502  1.1  christos 
    503  1.1  christos     default:
    504  1.1  christos       if (r_type >= (unsigned int) R_VISIUM_max)
    505  1.1  christos 	{
    506  1.1  christos 	  _bfd_error_handler (_("%A: invalid Visium reloc number: %d"), abfd, r_type);
    507  1.1  christos 	  r_type = 0;
    508  1.1  christos 	}
    509  1.1  christos       cache_ptr->howto = &visium_elf_howto_table[r_type];
    510  1.1  christos       break;
    511  1.1  christos     }
    512  1.1  christos }
    513  1.1  christos 
    514  1.1  christos /* Look through the relocs for a section during the first phase.
    515  1.1  christos    Since we don't do .gots or .plts, we just need to consider the
    516  1.1  christos    virtual table relocs for gc.  */
    517  1.1  christos 
    518  1.1  christos static bfd_boolean
    519  1.1  christos visium_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
    520  1.1  christos 			 asection *sec, const Elf_Internal_Rela *relocs)
    521  1.1  christos {
    522  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
    523  1.1  christos   struct elf_link_hash_entry **sym_hashes;
    524  1.1  christos   const Elf_Internal_Rela *rel;
    525  1.1  christos   const Elf_Internal_Rela *rel_end;
    526  1.1  christos 
    527  1.1  christos   if (info->relocatable)
    528  1.1  christos     return TRUE;
    529  1.1  christos 
    530  1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    531  1.1  christos   sym_hashes = elf_sym_hashes (abfd);
    532  1.1  christos 
    533  1.1  christos   rel_end = relocs + sec->reloc_count;
    534  1.1  christos   for (rel = relocs; rel < rel_end; rel++)
    535  1.1  christos     {
    536  1.1  christos       struct elf_link_hash_entry *h;
    537  1.1  christos       unsigned long r_symndx;
    538  1.1  christos 
    539  1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
    540  1.1  christos       if (r_symndx < symtab_hdr->sh_info)
    541  1.1  christos 	h = NULL;
    542  1.1  christos       else
    543  1.1  christos 	{
    544  1.1  christos 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
    545  1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
    546  1.1  christos 		 || h->root.type == bfd_link_hash_warning)
    547  1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    548  1.1  christos 	}
    549  1.1  christos 
    550  1.1  christos       switch (ELF32_R_TYPE (rel->r_info))
    551  1.1  christos 	{
    552  1.1  christos 	  /* This relocation describes the C++ object vtable hierarchy.
    553  1.1  christos 	     Reconstruct it for later use during GC.  */
    554  1.1  christos 	case R_VISIUM_GNU_VTINHERIT:
    555  1.1  christos 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
    556  1.1  christos 	    return FALSE;
    557  1.1  christos 	  break;
    558  1.1  christos 
    559  1.1  christos 	  /* This relocation describes which C++ vtable entries are actually
    560  1.1  christos 	     used.  Record for later use during GC.  */
    561  1.1  christos 	case R_VISIUM_GNU_VTENTRY:
    562  1.1  christos 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
    563  1.1  christos 	    return FALSE;
    564  1.1  christos 	  break;
    565  1.1  christos 	}
    566  1.1  christos     }
    567  1.1  christos 
    568  1.1  christos   return TRUE;
    569  1.1  christos }
    570  1.1  christos 
    571  1.1  christos /* Relocate a VISIUM ELF section.  */
    572  1.1  christos 
    573  1.1  christos static bfd_boolean
    574  1.1  christos visium_elf_relocate_section (bfd *output_bfd,
    575  1.1  christos 			     struct bfd_link_info *info, bfd *input_bfd,
    576  1.1  christos 			     asection *input_section, bfd_byte *contents,
    577  1.1  christos 			     Elf_Internal_Rela *relocs,
    578  1.1  christos 			     Elf_Internal_Sym *local_syms,
    579  1.1  christos 			     asection **local_sections)
    580  1.1  christos {
    581  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
    582  1.1  christos   struct elf_link_hash_entry **sym_hashes;
    583  1.1  christos   Elf_Internal_Rela *rel;
    584  1.1  christos   Elf_Internal_Rela *relend;
    585  1.1  christos 
    586  1.1  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    587  1.1  christos   sym_hashes = elf_sym_hashes (input_bfd);
    588  1.1  christos   relend = relocs + input_section->reloc_count;
    589  1.1  christos 
    590  1.1  christos   for (rel = relocs; rel < relend; rel++)
    591  1.1  christos     {
    592  1.1  christos       reloc_howto_type *howto;
    593  1.1  christos       unsigned long r_symndx;
    594  1.1  christos       Elf_Internal_Sym *sym;
    595  1.1  christos       asection *sec;
    596  1.1  christos       struct elf_link_hash_entry *h;
    597  1.1  christos       bfd_vma relocation;
    598  1.1  christos       bfd_reloc_status_type r;
    599  1.1  christos       const char *name = NULL;
    600  1.1  christos       int r_type;
    601  1.1  christos       bfd_vma insn;
    602  1.1  christos 
    603  1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
    604  1.1  christos 
    605  1.1  christos       if (r_type == R_VISIUM_GNU_VTINHERIT || r_type == R_VISIUM_GNU_VTENTRY)
    606  1.1  christos 	continue;
    607  1.1  christos 
    608  1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
    609  1.1  christos 
    610  1.1  christos       howto = visium_elf_howto_table + ELF32_R_TYPE (rel->r_info);
    611  1.1  christos       h = NULL;
    612  1.1  christos       sym = NULL;
    613  1.1  christos       sec = NULL;
    614  1.1  christos 
    615  1.1  christos       if (r_symndx < symtab_hdr->sh_info)
    616  1.1  christos 	{
    617  1.1  christos 	  /* This is a local symbol.  */
    618  1.1  christos 	  sym = local_syms + r_symndx;
    619  1.1  christos 	  sec = local_sections[r_symndx];
    620  1.1  christos 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
    621  1.1  christos 
    622  1.1  christos 	  name = bfd_elf_string_from_elf_section
    623  1.1  christos 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
    624  1.1  christos 	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
    625  1.1  christos 	}
    626  1.1  christos       else
    627  1.1  christos 	{
    628  1.1  christos 	  bfd_boolean unresolved_reloc;
    629  1.1  christos 	  bfd_boolean warned, ignored;
    630  1.1  christos 
    631  1.1  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    632  1.1  christos 				   r_symndx, symtab_hdr, sym_hashes,
    633  1.1  christos 				   h, sec, relocation,
    634  1.1  christos 				   unresolved_reloc, warned, ignored);
    635  1.1  christos 
    636  1.1  christos 	  name = h->root.root.string;
    637  1.1  christos 	}
    638  1.1  christos 
    639  1.1  christos       if (sec != NULL && discarded_section (sec))
    640  1.1  christos 	{
    641  1.1  christos 	  /* For relocs against symbols from removed linkonce sections,
    642  1.1  christos 	     or sections discarded by a linker script, we just want the
    643  1.1  christos 	     section contents zeroed.  Avoid any special processing.  */
    644  1.1  christos 	  _bfd_clear_contents (howto, input_bfd, input_section,
    645  1.1  christos 			       contents + rel->r_offset);
    646  1.1  christos 
    647  1.1  christos 	  rel->r_info = 0;
    648  1.1  christos 	  rel->r_addend = 0;
    649  1.1  christos 	  continue;
    650  1.1  christos 	}
    651  1.1  christos 
    652  1.1  christos       if (info->relocatable)
    653  1.1  christos 	continue;
    654  1.1  christos 
    655  1.1  christos       switch (r_type)
    656  1.1  christos 	{
    657  1.1  christos 	case R_VISIUM_PC16:
    658  1.1  christos 	case R_VISIUM_HI16:
    659  1.1  christos 	case R_VISIUM_LO16:
    660  1.1  christos 	case R_VISIUM_IM16:
    661  1.1  christos 	case R_VISIUM_HI16_PCREL:
    662  1.1  christos 	case R_VISIUM_LO16_PCREL:
    663  1.1  christos 	case R_VISIUM_IM16_PCREL:
    664  1.1  christos 	  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
    665  1.1  christos 					contents, rel->r_offset,
    666  1.1  christos 					relocation, rel->r_addend);
    667  1.1  christos 
    668  1.1  christos 	  /* For instruction relocations, the parity needs correcting.  */
    669  1.1  christos 	  if (r == bfd_reloc_ok)
    670  1.1  christos 	    {
    671  1.1  christos 	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
    672  1.1  christos 	      insn = (insn & 0x7fffffff) | visium_parity_bit (insn);
    673  1.1  christos 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
    674  1.1  christos 	    }
    675  1.1  christos 	  break;
    676  1.1  christos 
    677  1.1  christos 	default:
    678  1.1  christos 	  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
    679  1.1  christos 					contents, rel->r_offset,
    680  1.1  christos 					relocation, rel->r_addend);
    681  1.1  christos 	  break;
    682  1.1  christos 	}
    683  1.1  christos 
    684  1.1  christos       if (r != bfd_reloc_ok)
    685  1.1  christos 	{
    686  1.1  christos 	  const char *msg = (const char *) NULL;
    687  1.1  christos 
    688  1.1  christos 	  switch (r)
    689  1.1  christos 	    {
    690  1.1  christos 	    case bfd_reloc_overflow:
    691  1.1  christos 	      r = info->callbacks->reloc_overflow
    692  1.1  christos 		(info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
    693  1.1  christos 		 input_bfd, input_section, rel->r_offset);
    694  1.1  christos 	      break;
    695  1.1  christos 
    696  1.1  christos 	    case bfd_reloc_undefined:
    697  1.1  christos 	      r = info->callbacks->undefined_symbol
    698  1.1  christos 		(info, name, input_bfd, input_section, rel->r_offset, TRUE);
    699  1.1  christos 	      break;
    700  1.1  christos 
    701  1.1  christos 	    case bfd_reloc_outofrange:
    702  1.1  christos 	      msg = _("internal error: out of range error");
    703  1.1  christos 	      break;
    704  1.1  christos 
    705  1.1  christos 	    case bfd_reloc_notsupported:
    706  1.1  christos 	      msg = _("internal error: unsupported relocation error");
    707  1.1  christos 	      break;
    708  1.1  christos 
    709  1.1  christos 	    case bfd_reloc_dangerous:
    710  1.1  christos 	      msg = _("internal error: dangerous relocation");
    711  1.1  christos 	      break;
    712  1.1  christos 
    713  1.1  christos 	    default:
    714  1.1  christos 	      msg = _("internal error: unknown error");
    715  1.1  christos 	      break;
    716  1.1  christos 	    }
    717  1.1  christos 
    718  1.1  christos 	  if (msg)
    719  1.1  christos 	    r = info->callbacks->warning
    720  1.1  christos 	      (info, msg, name, input_bfd, input_section, rel->r_offset);
    721  1.1  christos 
    722  1.1  christos 	  if (!r)
    723  1.1  christos 	    return FALSE;
    724  1.1  christos 	}
    725  1.1  christos     }
    726  1.1  christos 
    727  1.1  christos   return TRUE;
    728  1.1  christos }
    729  1.1  christos 
    730  1.1  christos /* This function is called during section gc to discover the section a
    731  1.1  christos    to which a particular relocation refers.  Return the section that
    732  1.1  christos    should be marked against GC for a given relocation.  */
    733  1.1  christos 
    734  1.1  christos static asection *
    735  1.1  christos visium_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
    736  1.1  christos 			 Elf_Internal_Rela *rel, struct elf_link_hash_entry *h,
    737  1.1  christos 			 Elf_Internal_Sym *sym)
    738  1.1  christos {
    739  1.1  christos   if (h != NULL)
    740  1.1  christos     switch (ELF32_R_TYPE (rel->r_info))
    741  1.1  christos       {
    742  1.1  christos       case R_VISIUM_GNU_VTINHERIT:
    743  1.1  christos       case R_VISIUM_GNU_VTENTRY:
    744  1.1  christos 	return NULL;
    745  1.1  christos       }
    746  1.1  christos 
    747  1.1  christos   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
    748  1.1  christos }
    749  1.1  christos 
    750  1.1  christos static void
    751  1.1  christos visium_elf_post_process_headers (bfd *abfd,
    752  1.1  christos 				 struct bfd_link_info *info ATTRIBUTE_UNUSED)
    753  1.1  christos {
    754  1.1  christos   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
    755  1.1  christos   i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_STANDALONE;
    756  1.1  christos   i_ehdrp->e_ident[EI_ABIVERSION] = 1;
    757  1.1  christos }
    758  1.1  christos 
    759  1.1  christos /* Function to set the ELF flag bits.  */
    760  1.1  christos 
    761  1.1  christos static bfd_boolean
    762  1.1  christos visium_elf_set_private_flags (bfd *abfd, flagword flags)
    763  1.1  christos {
    764  1.1  christos   elf_elfheader (abfd)->e_flags = flags;
    765  1.1  christos   elf_flags_init (abfd) = TRUE;
    766  1.1  christos   return TRUE;
    767  1.1  christos }
    768  1.1  christos 
    769  1.1  christos /* Copy backend specific data from one object module to another.  */
    770  1.1  christos 
    771  1.1  christos static bfd_boolean
    772  1.1  christos visium_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
    773  1.1  christos {
    774  1.1  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
    775  1.1  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    776  1.1  christos     return TRUE;
    777  1.1  christos 
    778  1.1  christos   BFD_ASSERT (!elf_flags_init (obfd)
    779  1.1  christos 	      || elf_elfheader (obfd)->e_flags ==
    780  1.1  christos 	      elf_elfheader (ibfd)->e_flags);
    781  1.1  christos 
    782  1.1  christos   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
    783  1.1  christos   elf_flags_init (obfd) = TRUE;
    784  1.1  christos 
    785  1.1  christos   /* Copy object attributes.  */
    786  1.1  christos   _bfd_elf_copy_obj_attributes (ibfd, obfd);
    787  1.1  christos 
    788  1.1  christos   return TRUE;
    789  1.1  christos }
    790  1.1  christos 
    791  1.1  christos /* Merge backend specific data from an object
    792  1.1  christos    file to the output object file when linking.  */
    793  1.1  christos 
    794  1.1  christos static bfd_boolean
    795  1.1  christos visium_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
    796  1.1  christos {
    797  1.1  christos   flagword old_flags;
    798  1.1  christos   flagword new_flags;
    799  1.1  christos   flagword mismatch;
    800  1.1  christos   const char *opt_arch = NULL;
    801  1.1  christos   const char *new_opt_with = NULL;
    802  1.1  christos   const char *old_opt_with = NULL;
    803  1.1  christos   const char *with = "with";
    804  1.1  christos   const char *without = "without";
    805  1.1  christos   const char *mcm = "mcm";
    806  1.1  christos   const char *mcm24 = "mcm24";
    807  1.1  christos   const char *gr6 = "gr6";
    808  1.1  christos 
    809  1.1  christos   new_flags = elf_elfheader (ibfd)->e_flags;
    810  1.1  christos   old_flags = elf_elfheader (obfd)->e_flags;
    811  1.1  christos 
    812  1.1  christos   if (!elf_flags_init (obfd))
    813  1.1  christos     {
    814  1.1  christos       /* First call, no flags set.  */
    815  1.1  christos       elf_flags_init (obfd) = TRUE;
    816  1.1  christos       elf_elfheader (obfd)->e_flags = new_flags;
    817  1.1  christos     }
    818  1.1  christos   else
    819  1.1  christos     {
    820  1.1  christos       mismatch = (new_flags ^ old_flags)
    821  1.1  christos 	& (EF_VISIUM_ARCH_MCM | EF_VISIUM_ARCH_MCM24 | EF_VISIUM_ARCH_GR6);
    822  1.1  christos       if (mismatch & EF_VISIUM_ARCH_GR6)
    823  1.1  christos 	{
    824  1.1  christos 	  opt_arch = gr6;
    825  1.1  christos 	  new_opt_with = new_flags & EF_VISIUM_ARCH_GR6 ? with : without;
    826  1.1  christos 	  old_opt_with = old_flags & EF_VISIUM_ARCH_GR6 ? with : without;
    827  1.1  christos 	}
    828  1.1  christos       else if (mismatch & EF_VISIUM_ARCH_MCM)
    829  1.1  christos 	{
    830  1.1  christos 	  opt_arch = mcm;
    831  1.1  christos 	  new_opt_with = new_flags & EF_VISIUM_ARCH_MCM ? with : without;
    832  1.1  christos 	  old_opt_with = old_flags & EF_VISIUM_ARCH_MCM ? with : without;
    833  1.1  christos 	}
    834  1.1  christos       else if (mismatch & EF_VISIUM_ARCH_MCM24)
    835  1.1  christos 	{
    836  1.1  christos 	  opt_arch = mcm24;
    837  1.1  christos 	  new_opt_with = new_flags & EF_VISIUM_ARCH_MCM24 ? with : without;
    838  1.1  christos 	  old_opt_with = old_flags & EF_VISIUM_ARCH_MCM24 ? with : without;
    839  1.1  christos 	}
    840  1.1  christos 
    841  1.1  christos       if (mismatch)
    842  1.1  christos 	_bfd_error_handler
    843  1.1  christos 	  (_
    844  1.1  christos 	   ("%s: compiled %s -mtune=%s and linked with modules"
    845  1.1  christos 	    " compiled %s -mtune=%s"),
    846  1.1  christos 	   bfd_get_filename (ibfd), new_opt_with, opt_arch, old_opt_with,
    847  1.1  christos 	   opt_arch);
    848  1.1  christos     }
    849  1.1  christos 
    850  1.1  christos   return TRUE;
    851  1.1  christos }
    852  1.1  christos 
    853  1.1  christos static bfd_boolean
    854  1.1  christos visium_elf_print_private_bfd_data (bfd *abfd, void *ptr)
    855  1.1  christos {
    856  1.1  christos   FILE *file = (FILE *) ptr;
    857  1.1  christos   flagword flags;
    858  1.1  christos 
    859  1.1  christos   BFD_ASSERT (abfd != NULL && ptr != NULL);
    860  1.1  christos 
    861  1.1  christos   /* Print normal ELF private data.  */
    862  1.1  christos   _bfd_elf_print_private_bfd_data (abfd, ptr);
    863  1.1  christos 
    864  1.1  christos   flags = elf_elfheader (abfd)->e_flags;
    865  1.1  christos   fprintf (file, _("private flags = 0x%lx:"), (long) flags);
    866  1.1  christos 
    867  1.1  christos   if (flags & EF_VISIUM_ARCH_GR6)
    868  1.1  christos     fprintf (file, " -mtune=gr6");
    869  1.1  christos   else if (flags & EF_VISIUM_ARCH_MCM)
    870  1.1  christos     fprintf (file, " -mtune=mcm");
    871  1.1  christos   else if (flags & EF_VISIUM_ARCH_MCM24)
    872  1.1  christos     fprintf (file, " -mtune=mcm24");
    873  1.1  christos 
    874  1.1  christos   fputc ('\n', file);
    875  1.1  christos   return TRUE;
    876  1.1  christos }
    877  1.1  christos 
    878  1.1  christos #define ELF_ARCH		bfd_arch_visium
    879  1.1  christos #define ELF_MACHINE_CODE	EM_VISIUM
    880  1.1  christos #define ELF_MAXPAGESIZE		1
    881  1.1  christos 
    882  1.1  christos #define TARGET_BIG_SYM		visium_elf32_vec
    883  1.1  christos #define TARGET_BIG_NAME		"elf32-visium"
    884  1.1  christos 
    885  1.1  christos #define elf_info_to_howto_rel			NULL
    886  1.1  christos #define elf_info_to_howto			visium_info_to_howto_rela
    887  1.1  christos #define elf_backend_relocate_section		visium_elf_relocate_section
    888  1.1  christos #define elf_backend_gc_mark_hook		visium_elf_gc_mark_hook
    889  1.1  christos #define elf_backend_check_relocs		visium_elf_check_relocs
    890  1.1  christos #define elf_backend_rela_normal			1
    891  1.1  christos 
    892  1.1  christos #define elf_backend_can_gc_sections		1
    893  1.1  christos 
    894  1.1  christos #define bfd_elf32_bfd_reloc_type_lookup		visium_reloc_type_lookup
    895  1.1  christos #define bfd_elf32_bfd_reloc_name_lookup		visium_reloc_name_lookup
    896  1.1  christos 
    897  1.1  christos #define bfd_elf32_bfd_set_private_flags		visium_elf_set_private_flags
    898  1.1  christos #define bfd_elf32_bfd_copy_private_bfd_data	visium_elf_copy_private_bfd_data
    899  1.1  christos #define bfd_elf32_bfd_merge_private_bfd_data	visium_elf_merge_private_bfd_data
    900  1.1  christos #define bfd_elf32_bfd_print_private_bfd_data	visium_elf_print_private_bfd_data
    901  1.1  christos #define elf_backend_post_process_headers	visium_elf_post_process_headers
    902  1.1  christos 
    903  1.1  christos #include "elf32-target.h"
    904