Home | History | Annotate | Line # | Download | only in bfd
      1       1.1     skrll /* Motorola MCore specific support for 32-bit ELF
      2  1.1.1.12  christos    Copyright (C) 1994-2026 Free Software Foundation, Inc.
      3       1.1     skrll 
      4       1.1     skrll    This file is part of BFD, the Binary File Descriptor library.
      5       1.1     skrll 
      6       1.1     skrll    This program is free software; you can redistribute it and/or modify
      7       1.1     skrll    it under the terms of the GNU General Public License as published by
      8       1.1     skrll    the Free Software Foundation; either version 3 of the License, or
      9       1.1     skrll    (at your option) any later version.
     10       1.1     skrll 
     11       1.1     skrll    This program is distributed in the hope that it will be useful,
     12       1.1     skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13       1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14       1.1     skrll    GNU General Public License for more details.
     15       1.1     skrll 
     16       1.1     skrll    You should have received a copy of the GNU General Public License
     17       1.1     skrll    along with this program; if not, write to the Free Software
     18       1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19       1.1     skrll    MA 02110-1301, USA.  */
     20       1.1     skrll 
     21       1.1     skrll 
     22       1.1     skrll /* This file is based on a preliminary RCE ELF ABI.  The
     23       1.1     skrll    information may not match the final RCE ELF ABI.   */
     24       1.1     skrll 
     25       1.1     skrll #include "sysdep.h"
     26       1.1     skrll #include "bfd.h"
     27       1.1     skrll #include "bfdlink.h"
     28       1.1     skrll #include "libbfd.h"
     29       1.1     skrll #include "elf-bfd.h"
     30       1.1     skrll #include "elf/mcore.h"
     31       1.1     skrll #include <assert.h>
     32       1.1     skrll 
     33       1.1     skrll /* RELA relocs are used here...  */
     34       1.1     skrll 
     35       1.1     skrll /* Function to set whether a module needs the -mrelocatable bit set.  */
     36       1.1     skrll 
     37   1.1.1.9  christos static bool
     38       1.1     skrll mcore_elf_set_private_flags (bfd * abfd, flagword flags)
     39       1.1     skrll {
     40       1.1     skrll   BFD_ASSERT (! elf_flags_init (abfd)
     41       1.1     skrll 	      || elf_elfheader (abfd)->e_flags == flags);
     42       1.1     skrll 
     43       1.1     skrll   elf_elfheader (abfd)->e_flags = flags;
     44   1.1.1.9  christos   elf_flags_init (abfd) = true;
     45   1.1.1.9  christos   return true;
     46       1.1     skrll }
     47       1.1     skrll 
     48       1.1     skrll /* Merge backend specific data from an object file to the output
     49       1.1     skrll    object file when linking.  */
     50       1.1     skrll 
     51   1.1.1.9  christos static bool
     52   1.1.1.6  christos mcore_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
     53       1.1     skrll {
     54   1.1.1.6  christos   bfd *obfd = info->output_bfd;
     55       1.1     skrll   flagword old_flags;
     56       1.1     skrll   flagword new_flags;
     57       1.1     skrll 
     58   1.1.1.3  christos   /* Check if we have the same endianness.  */
     59   1.1.1.6  christos   if (! _bfd_generic_verify_endian_match (ibfd, info))
     60   1.1.1.9  christos     return false;
     61       1.1     skrll 
     62  1.1.1.12  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
     63   1.1.1.9  christos     return true;
     64       1.1     skrll 
     65       1.1     skrll   new_flags = elf_elfheader (ibfd)->e_flags;
     66       1.1     skrll   old_flags = elf_elfheader (obfd)->e_flags;
     67       1.1     skrll 
     68       1.1     skrll   if (! elf_flags_init (obfd))
     69       1.1     skrll     {
     70   1.1.1.6  christos       /* First call, no flags set.  */
     71   1.1.1.9  christos       elf_flags_init (obfd) = true;
     72       1.1     skrll       elf_elfheader (obfd)->e_flags = new_flags;
     73       1.1     skrll     }
     74       1.1     skrll   else if (new_flags == old_flags)
     75       1.1     skrll     /* Compatible flags are OK.  */
     76       1.1     skrll     ;
     77       1.1     skrll   else
     78       1.1     skrll     {
     79       1.1     skrll       /* FIXME */
     80       1.1     skrll     }
     81       1.1     skrll 
     82   1.1.1.9  christos   return true;
     83       1.1     skrll }
     84       1.1     skrll 
     85       1.1     skrll /* Don't pretend we can deal with unsupported relocs.  */
     87       1.1     skrll 
     88       1.1     skrll static bfd_reloc_status_type
     89       1.1     skrll mcore_elf_unsupported_reloc (bfd * abfd,
     90       1.1     skrll 			     arelent * reloc_entry,
     91   1.1.1.3  christos 			     asymbol * symbol ATTRIBUTE_UNUSED,
     92       1.1     skrll 			     void * data ATTRIBUTE_UNUSED,
     93       1.1     skrll 			     asection * input_section ATTRIBUTE_UNUSED,
     94       1.1     skrll 			     bfd * output_bfd ATTRIBUTE_UNUSED,
     95       1.1     skrll 			     char ** error_message ATTRIBUTE_UNUSED)
     96       1.1     skrll {
     97       1.1     skrll   BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
     98   1.1.1.6  christos 
     99   1.1.1.7  christos   /* xgettext:c-format */
    100       1.1     skrll   _bfd_error_handler (_("%pB: %s unsupported"),
    101   1.1.1.7  christos 		      abfd,
    102       1.1     skrll 		      reloc_entry->howto->name);
    103       1.1     skrll 
    104       1.1     skrll   return bfd_reloc_notsupported;
    105       1.1     skrll }
    106       1.1     skrll 
    107       1.1     skrll static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];
    108       1.1     skrll 
    109       1.1     skrll static reloc_howto_type mcore_elf_howto_raw[] =
    110       1.1     skrll {
    111       1.1     skrll   /* This reloc does nothing.  */
    112       1.1     skrll   HOWTO (R_MCORE_NONE,		/* type */
    113   1.1.1.9  christos 	 0,			/* rightshift */
    114   1.1.1.4  christos 	 0,			/* size */
    115   1.1.1.9  christos 	 0,			/* bitsize */
    116       1.1     skrll 	 false,			/* pc_relative */
    117   1.1.1.4  christos 	 0,			/* bitpos */
    118   1.1.1.6  christos 	 complain_overflow_dont,  /* complain_on_overflow */
    119       1.1     skrll 	 NULL,			/* special_function */
    120   1.1.1.9  christos 	 "R_MCORE_NONE",	/* name */
    121       1.1     skrll 	 false,			/* partial_inplace */
    122       1.1     skrll 	 0,			/* src_mask */
    123   1.1.1.9  christos 	 0,			/* dst_mask */
    124       1.1     skrll 	 false),		/* pcrel_offset */
    125       1.1     skrll 
    126       1.1     skrll   /* A standard 32 bit relocation.  */
    127       1.1     skrll   HOWTO (R_MCORE_ADDR32,	/* type */
    128   1.1.1.9  christos 	 0,			/* rightshift */
    129       1.1     skrll 	 4,			/* size */
    130   1.1.1.9  christos 	 32,			/* bitsize */
    131       1.1     skrll 	 false,			/* pc_relative */
    132       1.1     skrll 	 0,			/* bitpos */
    133       1.1     skrll 	 complain_overflow_bitfield, /* complain_on_overflow */
    134       1.1     skrll 	 bfd_elf_generic_reloc,	/* special_function */
    135   1.1.1.9  christos 	 "ADDR32",		/* name *//* For compatibility with coff/pe port.  */
    136       1.1     skrll 	 false,			/* partial_inplace */
    137       1.1     skrll 	 0x0,			/* src_mask */
    138   1.1.1.9  christos 	 0xffffffff,		/* dst_mask */
    139       1.1     skrll 	 false),		/* pcrel_offset */
    140       1.1     skrll 
    141       1.1     skrll   /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
    142       1.1     skrll      Should not appear in object files.  */
    143       1.1     skrll   HOWTO (R_MCORE_PCRELIMM8BY4,	/* type */
    144   1.1.1.9  christos 	 2,			/* rightshift */
    145       1.1     skrll 	 2,			/* size */
    146   1.1.1.9  christos 	 8,			/* bitsize */
    147       1.1     skrll 	 true,			/* pc_relative */
    148       1.1     skrll 	 0,			/* bitpos */
    149       1.1     skrll 	 complain_overflow_bitfield, /* complain_on_overflow */
    150       1.1     skrll 	 mcore_elf_unsupported_reloc,	/* special_function */
    151   1.1.1.9  christos 	 "R_MCORE_PCRELIMM8BY4",/* name */
    152       1.1     skrll 	 false,			/* partial_inplace */
    153       1.1     skrll 	 0,			/* src_mask */
    154   1.1.1.9  christos 	 0,			/* dst_mask */
    155       1.1     skrll 	 true),			/* pcrel_offset */
    156       1.1     skrll 
    157       1.1     skrll   /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
    158       1.1     skrll      Span 2k instructions == 4k bytes.
    159       1.1     skrll      Only useful pieces at the relocated address are the opcode (5 bits) */
    160       1.1     skrll   HOWTO (R_MCORE_PCRELIMM11BY2,/* type */
    161   1.1.1.9  christos 	 1,			/* rightshift */
    162       1.1     skrll 	 2,			/* size */
    163   1.1.1.9  christos 	 11,			/* bitsize */
    164       1.1     skrll 	 true,			/* pc_relative */
    165       1.1     skrll 	 0,			/* bitpos */
    166       1.1     skrll 	 complain_overflow_signed, /* complain_on_overflow */
    167       1.1     skrll 	 bfd_elf_generic_reloc,	/* special_function */
    168   1.1.1.9  christos 	 "R_MCORE_PCRELIMM11BY2",/* name */
    169       1.1     skrll 	 false,			/* partial_inplace */
    170       1.1     skrll 	 0x0,			/* src_mask */
    171   1.1.1.9  christos 	 0x7ff,			/* dst_mask */
    172       1.1     skrll 	 true),			/* pcrel_offset */
    173       1.1     skrll 
    174       1.1     skrll   /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported.  */
    175       1.1     skrll   HOWTO (R_MCORE_PCRELIMM4BY2,	/* type */
    176   1.1.1.9  christos 	 1,			/* rightshift */
    177       1.1     skrll 	 2,			/* size */
    178   1.1.1.9  christos 	 4,			/* bitsize */
    179       1.1     skrll 	 true,			/* pc_relative */
    180       1.1     skrll 	 0,			/* bitpos */
    181       1.1     skrll 	 complain_overflow_bitfield, /* complain_on_overflow */
    182       1.1     skrll 	 mcore_elf_unsupported_reloc,/* special_function */
    183   1.1.1.9  christos 	 "R_MCORE_PCRELIMM4BY2",/* name */
    184       1.1     skrll 	 false,			/* partial_inplace */
    185       1.1     skrll 	 0,			/* src_mask */
    186   1.1.1.9  christos 	 0,			/* dst_mask */
    187       1.1     skrll 	 true),			/* pcrel_offset */
    188       1.1     skrll 
    189       1.1     skrll   /* 32-bit pc-relative. Eventually this will help support PIC code.  */
    190       1.1     skrll   HOWTO (R_MCORE_PCREL32,	/* type */
    191   1.1.1.9  christos 	 0,			/* rightshift */
    192       1.1     skrll 	 4,			/* size */
    193   1.1.1.9  christos 	 32,			/* bitsize */
    194       1.1     skrll 	 true,			/* pc_relative */
    195       1.1     skrll 	 0,			/* bitpos */
    196       1.1     skrll 	 complain_overflow_bitfield, /* complain_on_overflow */
    197       1.1     skrll 	 bfd_elf_generic_reloc,	/* special_function */
    198   1.1.1.9  christos 	 "R_MCORE_PCREL32",	/* name */
    199       1.1     skrll 	 false,			/* partial_inplace */
    200       1.1     skrll 	 0x0,			/* src_mask */
    201   1.1.1.9  christos 	 0xffffffff,		/* dst_mask */
    202       1.1     skrll 	 true),			/* pcrel_offset */
    203       1.1     skrll 
    204       1.1     skrll   /* Like PCRELIMM11BY2, this relocation indicates that there is a
    205       1.1     skrll      'jsri' at the specified address. There is a separate relocation
    206       1.1     skrll      entry for the literal pool entry that it references, but we
    207       1.1     skrll      might be able to change the jsri to a bsr if the target turns out
    208       1.1     skrll      to be close enough [even though we won't reclaim the literal pool
    209       1.1     skrll      entry, we'll get some runtime efficiency back]. Note that this
    210       1.1     skrll      is a relocation that we are allowed to safely ignore.  */
    211       1.1     skrll   HOWTO (R_MCORE_PCRELJSR_IMM11BY2,/* type */
    212   1.1.1.9  christos 	 1,			/* rightshift */
    213       1.1     skrll 	 2,			/* size */
    214   1.1.1.9  christos 	 11,			/* bitsize */
    215       1.1     skrll 	 true,			/* pc_relative */
    216       1.1     skrll 	 0,			/* bitpos */
    217       1.1     skrll 	 complain_overflow_signed, /* complain_on_overflow */
    218       1.1     skrll 	 bfd_elf_generic_reloc,	/* special_function */
    219   1.1.1.9  christos 	 "R_MCORE_PCRELJSR_IMM11BY2", /* name */
    220       1.1     skrll 	 false,			/* partial_inplace */
    221       1.1     skrll 	 0x0,			/* src_mask */
    222   1.1.1.9  christos 	 0x7ff,			/* dst_mask */
    223       1.1     skrll 	 true),			/* pcrel_offset */
    224       1.1     skrll 
    225       1.1     skrll   /* GNU extension to record C++ vtable hierarchy.  */
    226   1.1.1.6  christos   HOWTO (R_MCORE_GNU_VTINHERIT, /* type */
    227   1.1.1.9  christos 	 0,			/* rightshift */
    228   1.1.1.6  christos 	 4,			/* size */
    229   1.1.1.9  christos 	 0,			/* bitsize */
    230   1.1.1.6  christos 	 false,			/* pc_relative */
    231   1.1.1.6  christos 	 0,			/* bitpos */
    232   1.1.1.6  christos 	 complain_overflow_dont, /* complain_on_overflow */
    233   1.1.1.6  christos 	 NULL,			/* special_function */
    234   1.1.1.9  christos 	 "R_MCORE_GNU_VTINHERIT", /* name */
    235   1.1.1.6  christos 	 false,			/* partial_inplace */
    236   1.1.1.6  christos 	 0,			/* src_mask */
    237   1.1.1.9  christos 	 0,			/* dst_mask */
    238       1.1     skrll 	 false),		/* pcrel_offset */
    239       1.1     skrll 
    240   1.1.1.6  christos   /* GNU extension to record C++ vtable member usage.  */
    241   1.1.1.6  christos   HOWTO (R_MCORE_GNU_VTENTRY,	/* type */
    242   1.1.1.9  christos 	 0,			/* rightshift */
    243   1.1.1.6  christos 	 4,			/* size */
    244   1.1.1.9  christos 	 0,			/* bitsize */
    245   1.1.1.6  christos 	 false,			/* pc_relative */
    246   1.1.1.6  christos 	 0,			/* bitpos */
    247   1.1.1.6  christos 	 complain_overflow_dont,/* complain_on_overflow */
    248   1.1.1.6  christos 	 _bfd_elf_rel_vtable_reloc_fn,	/* special_function */
    249   1.1.1.9  christos 	 "R_MCORE_GNU_VTENTRY", /* name */
    250   1.1.1.6  christos 	 false,			/* partial_inplace */
    251   1.1.1.6  christos 	 0,			/* src_mask */
    252   1.1.1.9  christos 	 0,			/* dst_mask */
    253       1.1     skrll 	 false),		/* pcrel_offset */
    254   1.1.1.6  christos 
    255       1.1     skrll   HOWTO (R_MCORE_RELATIVE,	/* type */
    256   1.1.1.9  christos 	 0,			/* rightshift */
    257       1.1     skrll 	 4,			/* size */
    258   1.1.1.9  christos 	 32,			/* bitsize */
    259       1.1     skrll 	 false,			/* pc_relative */
    260       1.1     skrll 	 0,			/* bitpos */
    261   1.1.1.6  christos 	 complain_overflow_signed, /* complain_on_overflow */
    262   1.1.1.6  christos 	 NULL,			/* special_function */
    263   1.1.1.9  christos 	 "R_MCORE_RELATIVE",	/* name */
    264       1.1     skrll 	 true,			/* partial_inplace */
    265       1.1     skrll 	 0xffffffff,		/* src_mask */
    266   1.1.1.9  christos 	 0xffffffff,		/* dst_mask */
    267       1.1     skrll 	 false)			/* pcrel_offset */
    268       1.1     skrll };
    269       1.1     skrll 
    270       1.1     skrll #ifndef NUM_ELEM
    271       1.1     skrll #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
    272       1.1     skrll #endif
    273       1.1     skrll 
    274       1.1     skrll /* Initialize the mcore_elf_howto_table, so that linear accesses can be done.  */
    276       1.1     skrll static void
    277       1.1     skrll mcore_elf_howto_init (void)
    278       1.1     skrll {
    279       1.1     skrll   unsigned int i;
    280       1.1     skrll 
    281       1.1     skrll   for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
    282       1.1     skrll     {
    283       1.1     skrll       unsigned int type;
    284       1.1     skrll 
    285       1.1     skrll       type = mcore_elf_howto_raw[i].type;
    286       1.1     skrll 
    287       1.1     skrll       BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));
    288       1.1     skrll 
    289       1.1     skrll       mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
    290       1.1     skrll     }
    291       1.1     skrll }
    292       1.1     skrll 
    293       1.1     skrll static reloc_howto_type *
    295       1.1     skrll mcore_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
    296       1.1     skrll 			     bfd_reloc_code_real_type code)
    297       1.1     skrll {
    298       1.1     skrll   enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
    299       1.1     skrll 
    300       1.1     skrll   switch (code)
    301       1.1     skrll     {
    302       1.1     skrll     case BFD_RELOC_NONE:		     mcore_reloc = R_MCORE_NONE; break;
    303       1.1     skrll     case BFD_RELOC_32:			     mcore_reloc = R_MCORE_ADDR32; break;
    304       1.1     skrll     case BFD_RELOC_MCORE_PCREL_IMM8BY4:	     mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
    305       1.1     skrll     case BFD_RELOC_MCORE_PCREL_IMM11BY2:     mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
    306   1.1.1.6  christos     case BFD_RELOC_MCORE_PCREL_IMM4BY2:	     mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
    307   1.1.1.6  christos     case BFD_RELOC_32_PCREL:		     mcore_reloc = R_MCORE_PCREL32; break;
    308   1.1.1.6  christos     case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
    309       1.1     skrll     case BFD_RELOC_VTABLE_INHERIT:	     mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
    310       1.1     skrll     case BFD_RELOC_VTABLE_ENTRY:	     mcore_reloc = R_MCORE_GNU_VTENTRY; break;
    311       1.1     skrll     case BFD_RELOC_RVA:			     mcore_reloc = R_MCORE_RELATIVE; break;
    312       1.1     skrll     default:
    313       1.1     skrll       return NULL;
    314       1.1     skrll     }
    315       1.1     skrll 
    316       1.1     skrll   if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
    317       1.1     skrll     /* Initialize howto table if needed.  */
    318       1.1     skrll     mcore_elf_howto_init ();
    319       1.1     skrll 
    320       1.1     skrll   return mcore_elf_howto_table [(int) mcore_reloc];
    321       1.1     skrll };
    322       1.1     skrll 
    323       1.1     skrll static reloc_howto_type *
    324       1.1     skrll mcore_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    325       1.1     skrll 			     const char *r_name)
    326       1.1     skrll {
    327       1.1     skrll   unsigned int i;
    328       1.1     skrll 
    329       1.1     skrll   for (i = 0;
    330       1.1     skrll        i < sizeof (mcore_elf_howto_raw) / sizeof (mcore_elf_howto_raw[0]);
    331       1.1     skrll        i++)
    332       1.1     skrll     if (mcore_elf_howto_raw[i].name != NULL
    333       1.1     skrll 	&& strcasecmp (mcore_elf_howto_raw[i].name, r_name) == 0)
    334       1.1     skrll       return &mcore_elf_howto_raw[i];
    335       1.1     skrll 
    336       1.1     skrll   return NULL;
    337       1.1     skrll }
    338   1.1.1.9  christos 
    339   1.1.1.7  christos /* Set the howto pointer for a RCE ELF reloc.  */
    340       1.1     skrll 
    341       1.1     skrll static bool
    342       1.1     skrll mcore_elf_info_to_howto (bfd * abfd,
    343   1.1.1.4  christos 			 arelent * cache_ptr,
    344   1.1.1.4  christos 			 Elf_Internal_Rela * dst)
    345       1.1     skrll {
    346       1.1     skrll   unsigned int r_type;
    347       1.1     skrll 
    348       1.1     skrll   if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
    349   1.1.1.4  christos     /* Initialize howto table if needed.  */
    350   1.1.1.4  christos     mcore_elf_howto_init ();
    351   1.1.1.4  christos 
    352   1.1.1.6  christos   r_type = ELF32_R_TYPE (dst->r_info);
    353   1.1.1.7  christos   if (r_type >= R_MCORE_max)
    354   1.1.1.6  christos     {
    355   1.1.1.4  christos       /* xgettext:c-format */
    356   1.1.1.9  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    357   1.1.1.4  christos 			  abfd, r_type);
    358       1.1     skrll       bfd_set_error (bfd_error_bad_value);
    359   1.1.1.4  christos       return false;
    360   1.1.1.9  christos     }
    361       1.1     skrll 
    362       1.1     skrll   cache_ptr->howto = mcore_elf_howto_table [r_type];
    363       1.1     skrll   return true;
    364       1.1     skrll }
    365       1.1     skrll 
    366       1.1     skrll /* The RELOCATE_SECTION function is called by the ELF backend linker
    368       1.1     skrll    to handle the relocations for a section.
    369       1.1     skrll 
    370       1.1     skrll    The relocs are always passed as Rela structures; if the section
    371       1.1     skrll    actually uses Rel structures, the r_addend field will always be
    372       1.1     skrll    zero.
    373       1.1     skrll 
    374       1.1     skrll    This function is responsible for adjust the section contents as
    375       1.1     skrll    necessary, and (if using Rela relocs and generating a
    376       1.1     skrll    relocatable output file) adjusting the reloc addend as
    377       1.1     skrll    necessary.
    378       1.1     skrll 
    379       1.1     skrll    This function does not have to worry about setting the reloc
    380       1.1     skrll    address or the reloc symbol index.
    381       1.1     skrll 
    382       1.1     skrll    LOCAL_SYMS is a pointer to the swapped in local symbols.
    383       1.1     skrll 
    384       1.1     skrll    LOCAL_SECTIONS is an array giving the section in the input file
    385       1.1     skrll    corresponding to the st_shndx field of each local symbol.
    386       1.1     skrll 
    387       1.1     skrll    The global hash table entry for the global symbols can be found
    388       1.1     skrll    via elf_sym_hashes (input_bfd).
    389       1.1     skrll 
    390       1.1     skrll    When generating relocatable output, this function must handle
    391       1.1     skrll    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
    392   1.1.1.9  christos    going to be the section symbol corresponding to the output
    393       1.1     skrll    section, which means that the addend must be adjusted
    394       1.1     skrll    accordingly.  */
    395       1.1     skrll 
    396       1.1     skrll static int
    397       1.1     skrll mcore_elf_relocate_section (bfd * output_bfd,
    398       1.1     skrll 			    struct bfd_link_info * info,
    399       1.1     skrll 			    bfd * input_bfd,
    400       1.1     skrll 			    asection * input_section,
    401       1.1     skrll 			    bfd_byte * contents,
    402       1.1     skrll 			    Elf_Internal_Rela * relocs,
    403       1.1     skrll 			    Elf_Internal_Sym * local_syms,
    404       1.1     skrll 			    asection ** local_sections)
    405       1.1     skrll {
    406   1.1.1.9  christos   Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
    407       1.1     skrll   struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
    408       1.1     skrll   Elf_Internal_Rela * rel = relocs;
    409       1.1     skrll   Elf_Internal_Rela * relend = relocs + input_section->reloc_count;
    410   1.1.1.7  christos   bool ret = true;
    411       1.1     skrll 
    412       1.1     skrll #ifdef DEBUG
    413   1.1.1.6  christos   _bfd_error_handler
    414   1.1.1.4  christos     ("mcore_elf_relocate_section called for %pB section %pA, %u relocations%s",
    415       1.1     skrll      input_bfd,
    416       1.1     skrll      input_section,
    417       1.1     skrll      input_section->reloc_count,
    418       1.1     skrll      (bfd_link_relocatable (info)) ? " (relocatable)" : "");
    419       1.1     skrll #endif
    420       1.1     skrll 
    421       1.1     skrll   if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])	/* Initialize howto table if needed */
    422   1.1.1.6  christos     mcore_elf_howto_init ();
    423   1.1.1.6  christos 
    424   1.1.1.6  christos   for (; rel < relend; rel++)
    425   1.1.1.6  christos     {
    426   1.1.1.6  christos       enum elf_mcore_reloc_type	   r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
    427   1.1.1.6  christos       bfd_vma			   offset = rel->r_offset;
    428   1.1.1.6  christos       bfd_vma			   addend = rel->r_addend;
    429   1.1.1.6  christos       bfd_reloc_status_type	   r = bfd_reloc_other;
    430   1.1.1.6  christos       asection *		   sec = NULL;
    431       1.1     skrll       reloc_howto_type *	   howto;
    432   1.1.1.6  christos       bfd_vma			   relocation;
    433       1.1     skrll       Elf_Internal_Sym *	   sym = NULL;
    434       1.1     skrll       unsigned long		   r_symndx;
    435       1.1     skrll       struct elf_link_hash_entry * h = NULL;
    436       1.1     skrll       unsigned short		   oldinst = 0;
    437       1.1     skrll 
    438   1.1.1.6  christos       /* Unknown relocation handling.  */
    439   1.1.1.7  christos       if ((unsigned) r_type >= (unsigned) R_MCORE_max
    440       1.1     skrll 	  || ! mcore_elf_howto_table [(int)r_type])
    441       1.1     skrll 	{
    442       1.1     skrll 	  /* xgettext:c-format */
    443   1.1.1.9  christos 	  _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    444       1.1     skrll 			      input_bfd, (int) r_type);
    445       1.1     skrll 
    446       1.1     skrll 	  bfd_set_error (bfd_error_bad_value);
    447       1.1     skrll 	  ret = false;
    448       1.1     skrll 	  continue;
    449       1.1     skrll 	}
    450       1.1     skrll 
    451       1.1     skrll       howto = mcore_elf_howto_table [(int) r_type];
    452       1.1     skrll       r_symndx = ELF32_R_SYM (rel->r_info);
    453   1.1.1.6  christos 
    454   1.1.1.7  christos       /* Complain about known relocation that are not yet supported.  */
    455       1.1     skrll       if (howto->special_function == mcore_elf_unsupported_reloc)
    456   1.1.1.7  christos 	{
    457       1.1     skrll 	  /* xgettext:c-format */
    458       1.1     skrll 	  _bfd_error_handler (_("%pB: %s unsupported"),
    459   1.1.1.9  christos 			      input_bfd,
    460       1.1     skrll 			      howto->name);
    461       1.1     skrll 
    462       1.1     skrll 	  bfd_set_error (bfd_error_bad_value);
    463       1.1     skrll 	  ret = false;
    464       1.1     skrll 	  continue;
    465       1.1     skrll 	}
    466       1.1     skrll 
    467       1.1     skrll       if (r_symndx < symtab_hdr->sh_info)
    468       1.1     skrll 	{
    469       1.1     skrll 	  sym = local_syms + r_symndx;
    470       1.1     skrll 	  sec = local_sections [r_symndx];
    471       1.1     skrll 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
    472   1.1.1.9  christos 	  addend = rel->r_addend;
    473       1.1     skrll 	}
    474       1.1     skrll       else
    475       1.1     skrll 	{
    476       1.1     skrll 	  bool unresolved_reloc, warned, ignored;
    477   1.1.1.4  christos 
    478       1.1     skrll 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    479       1.1     skrll 				   r_symndx, symtab_hdr, sym_hashes,
    480   1.1.1.3  christos 				   h, sec, relocation,
    481   1.1.1.2  christos 				   unresolved_reloc, warned, ignored);
    482  1.1.1.12  christos 	}
    483  1.1.1.12  christos 
    484       1.1     skrll       if (sec != NULL && discarded_section (sec))
    485   1.1.1.4  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    486       1.1     skrll 					 rel, 1, relend, R_MCORE_NONE,
    487       1.1     skrll 					 howto, 0, contents);
    488       1.1     skrll 
    489       1.1     skrll       if (bfd_link_relocatable (info))
    490       1.1     skrll 	continue;
    491       1.1     skrll 
    492       1.1     skrll       switch (r_type)
    493       1.1     skrll 	{
    494       1.1     skrll 	default:
    495       1.1     skrll 	  break;
    496       1.1     skrll 
    497       1.1     skrll 	case R_MCORE_PCRELJSR_IMM11BY2:
    498       1.1     skrll 	  oldinst = bfd_get_16 (input_bfd, contents + offset);
    499       1.1     skrll #define	MCORE_INST_BSR	0xF800
    500       1.1     skrll 	  bfd_put_16 (input_bfd, (bfd_vma) MCORE_INST_BSR, contents + offset);
    501       1.1     skrll 	  break;
    502       1.1     skrll 	}
    503       1.1     skrll 
    504       1.1     skrll #ifdef DEBUG
    505       1.1     skrll       fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
    506       1.1     skrll 	       howto->name, r_type, r_symndx, (long) offset, (long) addend);
    507       1.1     skrll #endif
    508       1.1     skrll 
    509       1.1     skrll       r = _bfd_final_link_relocate
    510       1.1     skrll 	(howto, input_bfd, input_section, contents, offset, relocation, addend);
    511       1.1     skrll 
    512       1.1     skrll       if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
    513       1.1     skrll 	{
    514       1.1     skrll 	  /* Wasn't ok, back it out and give up.  */
    515       1.1     skrll 	  bfd_put_16 (input_bfd, (bfd_vma) oldinst, contents + offset);
    516       1.1     skrll 	  r = bfd_reloc_ok;
    517   1.1.1.9  christos 	}
    518       1.1     skrll 
    519       1.1     skrll       if (r != bfd_reloc_ok)
    520       1.1     skrll 	{
    521       1.1     skrll 	  ret = false;
    522       1.1     skrll 
    523       1.1     skrll 	  switch (r)
    524       1.1     skrll 	    {
    525       1.1     skrll 	    default:
    526       1.1     skrll 	      break;
    527       1.1     skrll 
    528       1.1     skrll 	    case bfd_reloc_overflow:
    529       1.1     skrll 	      {
    530       1.1     skrll 		const char * name;
    531       1.1     skrll 
    532       1.1     skrll 		if (h != NULL)
    533       1.1     skrll 		  name = NULL;
    534       1.1     skrll 		else
    535       1.1     skrll 		  {
    536       1.1     skrll 		    name = bfd_elf_string_from_elf_section
    537       1.1     skrll 		      (input_bfd, symtab_hdr->sh_link, sym->st_name);
    538       1.1     skrll 
    539   1.1.1.8  christos 		    if (name == NULL)
    540       1.1     skrll 		      break;
    541       1.1     skrll 
    542       1.1     skrll 		    if (* name == '\0')
    543       1.1     skrll 		      name = bfd_section_name (sec);
    544       1.1     skrll 		  }
    545       1.1     skrll 
    546       1.1     skrll 		(*info->callbacks->reloc_overflow)
    547       1.1     skrll 		  (info, (h ? &h->root : NULL), name, howto->name,
    548       1.1     skrll 		   (bfd_vma) 0, input_bfd, input_section, offset);
    549       1.1     skrll 	      }
    550       1.1     skrll 	      break;
    551       1.1     skrll 	    }
    552       1.1     skrll 	}
    553       1.1     skrll     }
    554       1.1     skrll 
    555       1.1     skrll #ifdef DEBUG
    556       1.1     skrll   fprintf (stderr, "\n");
    557       1.1     skrll #endif
    558       1.1     skrll 
    559       1.1     skrll   return ret;
    560       1.1     skrll }
    561       1.1     skrll 
    562       1.1     skrll /* Return the section that should be marked against GC for a given
    564  1.1.1.12  christos    relocation.  */
    565       1.1     skrll 
    566  1.1.1.12  christos static asection *
    567       1.1     skrll mcore_elf_gc_mark_hook (asection *sec,
    568       1.1     skrll 			struct bfd_link_info *info,
    569  1.1.1.12  christos 			struct elf_reloc_cookie *cookie,
    570       1.1     skrll 			struct elf_link_hash_entry *h,
    571       1.1     skrll 			unsigned int symndx)
    572       1.1     skrll {
    573       1.1     skrll   if (h != NULL)
    574       1.1     skrll     switch (ELF32_R_TYPE (cookie->rel->r_info))
    575       1.1     skrll       {
    576  1.1.1.12  christos       case R_MCORE_GNU_VTINHERIT:
    577       1.1     skrll       case R_MCORE_GNU_VTENTRY:
    578       1.1     skrll 	return NULL;
    579       1.1     skrll       }
    580       1.1     skrll 
    581       1.1     skrll   return _bfd_elf_gc_mark_hook (sec, info, cookie, h, symndx);
    582       1.1     skrll }
    583   1.1.1.9  christos 
    584       1.1     skrll /* Look through the relocs for a section during the first phase.
    585       1.1     skrll    Since we don't do .gots or .plts, we just need to consider the
    586       1.1     skrll    virtual table relocs for gc.  */
    587       1.1     skrll 
    588       1.1     skrll static bool
    589       1.1     skrll mcore_elf_check_relocs (bfd * abfd,
    590       1.1     skrll 			struct bfd_link_info * info,
    591       1.1     skrll 			asection * sec,
    592       1.1     skrll 			const Elf_Internal_Rela * relocs)
    593       1.1     skrll {
    594   1.1.1.4  christos   Elf_Internal_Shdr * symtab_hdr;
    595   1.1.1.9  christos   struct elf_link_hash_entry ** sym_hashes;
    596       1.1     skrll   const Elf_Internal_Rela * rel;
    597       1.1     skrll   const Elf_Internal_Rela * rel_end;
    598       1.1     skrll 
    599       1.1     skrll   if (bfd_link_relocatable (info))
    600       1.1     skrll     return true;
    601       1.1     skrll 
    602       1.1     skrll   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
    603       1.1     skrll   sym_hashes = elf_sym_hashes (abfd);
    604       1.1     skrll 
    605       1.1     skrll   rel_end = relocs + sec->reloc_count;
    606       1.1     skrll 
    607       1.1     skrll   for (rel = relocs; rel < rel_end; rel++)
    608       1.1     skrll     {
    609       1.1     skrll       struct elf_link_hash_entry * h;
    610   1.1.1.6  christos       unsigned long r_symndx;
    611       1.1     skrll 
    612       1.1     skrll       r_symndx = ELF32_R_SYM (rel->r_info);
    613       1.1     skrll 
    614       1.1     skrll       if (r_symndx < symtab_hdr->sh_info)
    615       1.1     skrll 	h = NULL;
    616       1.1     skrll       else
    617       1.1     skrll 	{
    618       1.1     skrll 	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
    619       1.1     skrll 	  while (h->root.type == bfd_link_hash_indirect
    620   1.1.1.6  christos 		 || h->root.type == bfd_link_hash_warning)
    621   1.1.1.6  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    622   1.1.1.6  christos 	}
    623   1.1.1.6  christos 
    624   1.1.1.6  christos       switch (ELF32_R_TYPE (rel->r_info))
    625   1.1.1.9  christos 	{
    626   1.1.1.6  christos 	/* This relocation describes the C++ object vtable hierarchy.
    627   1.1.1.6  christos 	   Reconstruct it for later use during GC.  */
    628   1.1.1.6  christos 	case R_MCORE_GNU_VTINHERIT:
    629   1.1.1.6  christos 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
    630   1.1.1.6  christos 	    return false;
    631   1.1.1.8  christos 	  break;
    632   1.1.1.9  christos 
    633   1.1.1.6  christos 	/* This relocation describes which C++ vtable entries are actually
    634   1.1.1.6  christos 	   used.  Record for later use during GC.  */
    635       1.1     skrll 	case R_MCORE_GNU_VTENTRY:
    636       1.1     skrll 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
    637   1.1.1.9  christos 	    return false;
    638       1.1     skrll 	  break;
    639       1.1     skrll 	}
    640       1.1     skrll     }
    641       1.1     skrll 
    642       1.1     skrll   return true;
    643       1.1     skrll }
    644   1.1.1.6  christos 
    645       1.1     skrll static const struct bfd_elf_special_section mcore_elf_special_sections[]=
    646       1.1     skrll {
    647   1.1.1.4  christos   { STRING_COMMA_LEN (".ctors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
    648       1.1     skrll   { STRING_COMMA_LEN (".dtors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
    649   1.1.1.6  christos   { NULL,		      0,  0, 0,		   0 }
    650   1.1.1.6  christos };
    651       1.1     skrll 
    652       1.1     skrll #define TARGET_BIG_SYM		mcore_elf32_be_vec
    653       1.1     skrll #define TARGET_BIG_NAME		"elf32-mcore-big"
    654       1.1     skrll #define TARGET_LITTLE_SYM	mcore_elf32_le_vec
    655       1.1     skrll #define TARGET_LITTLE_NAME	"elf32-mcore-little"
    656       1.1     skrll 
    657       1.1     skrll #define ELF_ARCH		bfd_arch_mcore
    658       1.1     skrll #define ELF_MACHINE_CODE	EM_MCORE
    659       1.1     skrll #define ELF_MAXPAGESIZE		0x1000		/* 4k, if we ever have 'em */
    660       1.1     skrll #define elf_info_to_howto	mcore_elf_info_to_howto
    661       1.1     skrll #define elf_info_to_howto_rel	NULL
    662       1.1     skrll 
    663       1.1     skrll #define bfd_elf32_bfd_merge_private_bfd_data	mcore_elf_merge_private_bfd_data
    664   1.1.1.6  christos #define bfd_elf32_bfd_set_private_flags		mcore_elf_set_private_flags
    665       1.1     skrll #define bfd_elf32_bfd_reloc_type_lookup		mcore_elf_reloc_type_lookup
    666       1.1     skrll #define bfd_elf32_bfd_reloc_name_lookup	mcore_elf_reloc_name_lookup
    667       1.1     skrll #define elf_backend_relocate_section		mcore_elf_relocate_section
    668       1.1     skrll #define elf_backend_gc_mark_hook		mcore_elf_gc_mark_hook
    669       1.1     skrll #define elf_backend_check_relocs		mcore_elf_check_relocs
    670       1.1     skrll #define elf_backend_special_sections		mcore_elf_special_sections
    671                     
    672                     #define elf_backend_can_gc_sections		1
    673                     #define elf_backend_rela_normal			1
    674                     
    675                     #include "elf32-target.h"
    676