Home | History | Annotate | Download | only in bfd
      1 /* MeP-specific support for 32-bit ELF.
      2    Copyright (C) 2001-2016 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "libbfd.h"
     24 #include "elf-bfd.h"
     25 #include "elf/mep.h"
     26 #include "libiberty.h"
     27 
     28 /* Forward declarations.  */
     29 
     30 /* Private relocation functions.  */
     31 
     32 #define MEPREL(type, size, bits, right, left, pcrel, overflow, mask) \
     34   {(unsigned)type, right, size, bits, pcrel, left, overflow, bfd_elf_generic_reloc, #type, FALSE, 0, mask, 0 }
     35 
     36 #define N complain_overflow_dont
     37 #define S complain_overflow_signed
     38 #define U complain_overflow_unsigned
     39 
     40 static reloc_howto_type mep_elf_howto_table [] =
     41 {
     42   /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask.  */
     43   MEPREL (R_MEP_NONE,     3,  0, 0, 0, 0, N, 0),
     44   MEPREL (R_RELC,         0,  0, 0, 0, 0, N, 0),
     45   /* MEPRELOC:HOWTO */
     46     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
     47   MEPREL (R_MEP_8,        0,  8, 0, 0, 0, U, 0xff),
     48   MEPREL (R_MEP_16,       1, 16, 0, 0, 0, U, 0xffff),
     49   MEPREL (R_MEP_32,       2, 32, 0, 0, 0, U, 0xffffffff),
     50   MEPREL (R_MEP_PCREL8A2, 1,  8, 1, 1, 1, S, 0x00fe),
     51   MEPREL (R_MEP_PCREL12A2,1, 12, 1, 1, 1, S, 0x0ffe),
     52   MEPREL (R_MEP_PCREL17A2,2, 17, 0, 1, 1, S, 0x0000ffff),
     53   MEPREL (R_MEP_PCREL24A2,2, 24, 0, 1, 1, S, 0x07f0ffff),
     54   MEPREL (R_MEP_PCABS24A2,2, 24, 0, 1, 0, U, 0x07f0ffff),
     55   MEPREL (R_MEP_LOW16,    2, 16, 0, 0, 0, N, 0x0000ffff),
     56   MEPREL (R_MEP_HI16U,    2, 32, 0,16, 0, N, 0x0000ffff),
     57   MEPREL (R_MEP_HI16S,    2, 32, 0,16, 0, N, 0x0000ffff),
     58   MEPREL (R_MEP_GPREL,    2, 16, 0, 0, 0, S, 0x0000ffff),
     59   MEPREL (R_MEP_TPREL,    2, 16, 0, 0, 0, S, 0x0000ffff),
     60   MEPREL (R_MEP_TPREL7,   1,  7, 0, 0, 0, U, 0x007f),
     61   MEPREL (R_MEP_TPREL7A2, 1,  7, 1, 1, 0, U, 0x007e),
     62   MEPREL (R_MEP_TPREL7A4, 1,  7, 2, 2, 0, U, 0x007c),
     63   MEPREL (R_MEP_UIMM24,   2, 24, 0, 0, 0, U, 0x00ffffff),
     64   MEPREL (R_MEP_ADDR24A4, 2, 24, 0, 2, 0, U, 0x00fcffff),
     65   MEPREL (R_MEP_GNU_VTINHERIT,1,  0,16,32, 0, N, 0x0000),
     66   MEPREL (R_MEP_GNU_VTENTRY,1,  0,16,32, 0, N, 0x0000),
     67   /* MEPRELOC:END */
     68 };
     69 
     70 #define VALID_MEP_RELOC(N) ((N) >= 0 \
     71   && (N) < ARRAY_SIZE (mep_elf_howto_table)
     72 
     73 #undef N
     74 #undef S
     75 #undef U
     76 
     77 
     79 #define BFD_RELOC_MEP_NONE BFD_RELOC_NONE
     80 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
     81 #define MAP(n) case BFD_RELOC_MEP_##n: type = R_MEP_##n; break
     82 #else
     83 #define MAP(n) case BFD_RELOC_MEP_/**/n: type = R_MEP_/**/n; break
     84 #endif
     85 
     86 static reloc_howto_type *
     87 mep_reloc_type_lookup
     88     (bfd * abfd ATTRIBUTE_UNUSED,
     89      bfd_reloc_code_real_type code)
     90 {
     91   unsigned int type = 0;
     92 
     93   switch (code)
     94     {
     95     MAP(NONE);
     96     case BFD_RELOC_8:
     97       type = R_MEP_8;
     98       break;
     99     case BFD_RELOC_16:
    100       type = R_MEP_16;
    101       break;
    102     case BFD_RELOC_32:
    103       type = R_MEP_32;
    104       break;
    105     case BFD_RELOC_VTABLE_ENTRY:
    106       type = R_MEP_GNU_VTENTRY;
    107       break;
    108     case BFD_RELOC_VTABLE_INHERIT:
    109       type = R_MEP_GNU_VTINHERIT;
    110       break;
    111     case BFD_RELOC_RELC:
    112       type = R_RELC;
    113       break;
    114 
    115     /* MEPRELOC:MAP */
    116     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
    117     MAP(8);
    118     MAP(16);
    119     MAP(32);
    120     MAP(PCREL8A2);
    121     MAP(PCREL12A2);
    122     MAP(PCREL17A2);
    123     MAP(PCREL24A2);
    124     MAP(PCABS24A2);
    125     MAP(LOW16);
    126     MAP(HI16U);
    127     MAP(HI16S);
    128     MAP(GPREL);
    129     MAP(TPREL);
    130     MAP(TPREL7);
    131     MAP(TPREL7A2);
    132     MAP(TPREL7A4);
    133     MAP(UIMM24);
    134     MAP(ADDR24A4);
    135     MAP(GNU_VTINHERIT);
    136     MAP(GNU_VTENTRY);
    137     /* MEPRELOC:END */
    138 
    139     default:
    140       /* Pacify gcc -Wall.  */
    141       (*_bfd_error_handler) (_("mep: no reloc for code %d"), code);
    142       return NULL;
    143     }
    144 
    145   if (mep_elf_howto_table[type].type != type)
    146     {
    147       (*_bfd_error_handler) (_("MeP: howto %d has type %d"),
    148 			     type, mep_elf_howto_table[type].type);
    149       abort ();
    150     }
    151 
    152   return mep_elf_howto_table + type;
    153 }
    154 
    155 #undef MAP
    156 
    157 static reloc_howto_type *
    158 mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
    159 {
    160   unsigned int i;
    161 
    162   for (i = 0;
    163        i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]);
    164        i++)
    165     if (mep_elf_howto_table[i].name != NULL
    166 	&& strcasecmp (mep_elf_howto_table[i].name, r_name) == 0)
    167       return &mep_elf_howto_table[i];
    168 
    169   return NULL;
    170 }
    171 
    172 /* Perform a single relocation.  */
    174 
    175 static struct bfd_link_info *mep_info;
    176 static int warn_tp = 0, warn_sda = 0;
    177 
    178 static bfd_vma
    179 mep_lookup_global
    180     (char *    name,
    181      bfd_vma   ofs,
    182      bfd_vma * cache,
    183      int *     warn)
    184 {
    185   struct bfd_link_hash_entry *h;
    186 
    187   if (*cache || *warn)
    188     return *cache;
    189 
    190   h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE);
    191   if (h == 0 || h->type != bfd_link_hash_defined)
    192     {
    193       *warn = ofs + 1;
    194       return 0;
    195     }
    196   *cache = (h->u.def.value
    197 	  + h->u.def.section->output_section->vma
    198 	  + h->u.def.section->output_offset);
    199   return *cache;
    200 }
    201 
    202 static bfd_vma
    203 mep_tpoff_base (bfd_vma ofs)
    204 {
    205   static bfd_vma cache = 0;
    206   return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
    207 }
    208 
    209 static bfd_vma
    210 mep_sdaoff_base (bfd_vma ofs)
    211 {
    212   static bfd_vma cache = 0;
    213   return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
    214 }
    215 
    216 static bfd_reloc_status_type
    217 mep_final_link_relocate
    218     (reloc_howto_type *  howto,
    219      bfd *               input_bfd,
    220      asection *          input_section,
    221      bfd_byte *          contents,
    222      Elf_Internal_Rela * rel,
    223      bfd_vma             relocation)
    224 {
    225   unsigned long u;
    226   long s;
    227   unsigned char *byte;
    228   bfd_vma pc;
    229   bfd_reloc_status_type r = bfd_reloc_ok;
    230   int e2, e4;
    231 
    232   if (bfd_big_endian (input_bfd))
    233     {
    234       e2 = 0;
    235       e4 = 0;
    236     }
    237   else
    238     {
    239       e2 = 1;
    240       e4 = 3;
    241     }
    242 
    243   pc = (input_section->output_section->vma
    244 	+ input_section->output_offset
    245 	+ rel->r_offset);
    246 
    247   s = relocation + rel->r_addend;
    248 
    249   byte = (unsigned char *)contents + rel->r_offset;
    250 
    251   if (howto->type == R_MEP_PCREL24A2
    252       && s == 0
    253       && pc >= 0x800000)
    254     {
    255       /* This is an unreachable branch to an undefined weak function.
    256 	 Silently ignore it, since the opcode can't do that but should
    257 	 never be executed anyway.  */
    258       return bfd_reloc_ok;
    259     }
    260 
    261   if (howto->pc_relative)
    262     s -= pc;
    263 
    264   u = (unsigned long) s;
    265 
    266   switch (howto->type)
    267     {
    268     /* MEPRELOC:APPLY */
    269     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
    270     case R_MEP_8: /* 76543210 */
    271       if (u > 255) r = bfd_reloc_overflow;
    272       byte[0] = (u & 0xff);
    273       break;
    274     case R_MEP_16: /* fedcba9876543210 */
    275       if (u > 65535) r = bfd_reloc_overflow;
    276       byte[0^e2] = ((u >> 8) & 0xff);
    277       byte[1^e2] = (u & 0xff);
    278       break;
    279     case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */
    280       byte[0^e4] = ((u >> 24) & 0xff);
    281       byte[1^e4] = ((u >> 16) & 0xff);
    282       byte[2^e4] = ((u >> 8) & 0xff);
    283       byte[3^e4] = (u & 0xff);
    284       break;
    285     case R_MEP_PCREL8A2: /* --------7654321- */
    286       if (-128 > s || s > 127) r = bfd_reloc_overflow;
    287       byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
    288       break;
    289     case R_MEP_PCREL12A2: /* ----ba987654321- */
    290       if (-2048 > s || s > 2047) r = bfd_reloc_overflow;
    291       byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f);
    292       byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
    293       break;
    294     case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */
    295       if (-65536 > s || s > 65535) r = bfd_reloc_overflow;
    296       byte[2^e2] = ((s >> 9) & 0xff);
    297       byte[3^e2] = ((s >> 1) & 0xff);
    298       break;
    299     case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */
    300       if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow;
    301       byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07);
    302       byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0);
    303       byte[2^e2] = ((s >> 16) & 0xff);
    304       byte[3^e2] = ((s >> 8) & 0xff);
    305       break;
    306     case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */
    307       if (u > 16777215) r = bfd_reloc_overflow;
    308       byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07);
    309       byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0);
    310       byte[2^e2] = ((u >> 16) & 0xff);
    311       byte[3^e2] = ((u >> 8) & 0xff);
    312       break;
    313     case R_MEP_LOW16: /* ----------------fedcba9876543210 */
    314       byte[2^e2] = ((u >> 8) & 0xff);
    315       byte[3^e2] = (u & 0xff);
    316       break;
    317     case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */
    318       byte[2^e2] = ((u >> 24) & 0xff);
    319       byte[3^e2] = ((u >> 16) & 0xff);
    320       break;
    321     case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */
    322       if (s & 0x8000)
    323 	s += 0x10000;
    324       byte[2^e2] = ((s >> 24) & 0xff);
    325       byte[3^e2] = ((s >> 16) & 0xff);
    326       break;
    327     case R_MEP_GPREL: /* ----------------fedcba9876543210 */
    328       s -= mep_sdaoff_base(rel->r_offset);
    329       if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
    330       byte[2^e2] = ((s >> 8) & 0xff);
    331       byte[3^e2] = (s & 0xff);
    332       break;
    333     case R_MEP_TPREL: /* ----------------fedcba9876543210 */
    334       s -= mep_tpoff_base(rel->r_offset);
    335       if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
    336       byte[2^e2] = ((s >> 8) & 0xff);
    337       byte[3^e2] = (s & 0xff);
    338       break;
    339     case R_MEP_TPREL7: /* ---------6543210 */
    340       u -= mep_tpoff_base(rel->r_offset);
    341       if (u > 127) r = bfd_reloc_overflow;
    342       byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
    343       break;
    344     case R_MEP_TPREL7A2: /* ---------654321- */
    345       u -= mep_tpoff_base(rel->r_offset);
    346       if (u > 127) r = bfd_reloc_overflow;
    347       byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
    348       break;
    349     case R_MEP_TPREL7A4: /* ---------65432-- */
    350       u -= mep_tpoff_base(rel->r_offset);
    351       if (u > 127) r = bfd_reloc_overflow;
    352       byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
    353       break;
    354     case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
    355       if (u > 16777215) r = bfd_reloc_overflow;
    356       byte[1^e2] = (u & 0xff);
    357       byte[2^e2] = ((u >> 16) & 0xff);
    358       byte[3^e2] = ((u >> 8) & 0xff);
    359       break;
    360     case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
    361       if (u > 16777215) r = bfd_reloc_overflow;
    362       byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
    363       byte[2^e2] = ((u >> 16) & 0xff);
    364       byte[3^e2] = ((u >> 8) & 0xff);
    365       break;
    366     case R_MEP_GNU_VTINHERIT: /* ---------------- */
    367       break;
    368     case R_MEP_GNU_VTENTRY: /* ---------------- */
    369       break;
    370     /* MEPRELOC:END */
    371     default:
    372       abort ();
    373     }
    374 
    375   return r;
    376 }
    377 
    378 /* Set the howto pointer for a MEP ELF reloc.  */
    380 
    381 static void
    382 mep_info_to_howto_rela
    383     (bfd *               abfd ATTRIBUTE_UNUSED,
    384      arelent *           cache_ptr,
    385      Elf_Internal_Rela * dst)
    386 {
    387   unsigned int r_type;
    388 
    389   r_type = ELF32_R_TYPE (dst->r_info);
    390   if (r_type >= R_MEP_max)
    391     {
    392       _bfd_error_handler (_("%B: invalid MEP reloc number: %d"), abfd, r_type);
    393       r_type = 0;
    394     }
    395   cache_ptr->howto = & mep_elf_howto_table [r_type];
    396 }
    397 
    398 /* Relocate a MEP ELF section.
    400    There is some attempt to make this function usable for many architectures,
    401    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
    402    if only to serve as a learning tool.
    403 
    404    The RELOCATE_SECTION function is called by the new ELF backend linker
    405    to handle the relocations for a section.
    406 
    407    The relocs are always passed as Rela structures; if the section
    408    actually uses Rel structures, the r_addend field will always be
    409    zero.
    410 
    411    This function is responsible for adjusting the section contents as
    412    necessary, and (if using Rela relocs and generating a relocatable
    413    output file) adjusting the reloc addend as necessary.
    414 
    415    This function does not have to worry about setting the reloc
    416    address or the reloc symbol index.
    417 
    418    LOCAL_SYMS is a pointer to the swapped in local symbols.
    419 
    420    LOCAL_SECTIONS is an array giving the section in the input file
    421    corresponding to the st_shndx field of each local symbol.
    422 
    423    The global hash table entry for the global symbols can be found
    424    via elf_sym_hashes (input_bfd).
    425 
    426    When generating relocatable output, this function must handle
    427    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
    428    going to be the section symbol corresponding to the output
    429    section, which means that the addend must be adjusted
    430    accordingly.  */
    431 
    432 static bfd_boolean
    433 mep_elf_relocate_section
    434     (bfd *                   output_bfd ATTRIBUTE_UNUSED,
    435      struct bfd_link_info *  info,
    436      bfd *                   input_bfd,
    437      asection *              input_section,
    438      bfd_byte *              contents,
    439      Elf_Internal_Rela *     relocs,
    440      Elf_Internal_Sym *      local_syms,
    441      asection **             local_sections)
    442 {
    443   Elf_Internal_Shdr *           symtab_hdr;
    444   struct elf_link_hash_entry ** sym_hashes;
    445   Elf_Internal_Rela *           rel;
    446   Elf_Internal_Rela *           relend;
    447 
    448   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
    449   sym_hashes = elf_sym_hashes (input_bfd);
    450   relend     = relocs + input_section->reloc_count;
    451 
    452   mep_info = info;
    453 
    454   for (rel = relocs; rel < relend; rel ++)
    455     {
    456       reloc_howto_type *           howto;
    457       unsigned long                r_symndx;
    458       Elf_Internal_Sym *           sym;
    459       asection *                   sec;
    460       struct elf_link_hash_entry * h;
    461       bfd_vma                      relocation;
    462       bfd_reloc_status_type        r;
    463       const char *                 name = NULL;
    464       int                          r_type;
    465 
    466       r_type = ELF32_R_TYPE (rel->r_info);
    467       r_symndx = ELF32_R_SYM (rel->r_info);
    468       howto  = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
    469       h      = NULL;
    470       sym    = NULL;
    471       sec    = NULL;
    472 
    473       if (r_symndx < symtab_hdr->sh_info)
    474 	{
    475 	  sym = local_syms + r_symndx;
    476 	  sec = local_sections [r_symndx];
    477 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
    478 
    479 	  name = bfd_elf_string_from_elf_section
    480 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
    481 	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
    482 	}
    483       else
    484 	{
    485 	  bfd_boolean warned, unresolved_reloc, ignored;
    486 
    487 	  RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
    488 				  r_symndx, symtab_hdr, sym_hashes,
    489 				  h, sec, relocation,
    490 				  unresolved_reloc, warned, ignored);
    491 
    492 	  name = h->root.root.string;
    493 	}
    494 
    495       if (sec != NULL && discarded_section (sec))
    496 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    497 					 rel, 1, relend, howto, 0, contents);
    498 
    499       if (bfd_link_relocatable (info))
    500 	continue;
    501 
    502       if (r_type == R_RELC)
    503 	r = bfd_elf_perform_complex_relocation (input_bfd, input_section,
    504 						contents, rel, relocation);
    505       else
    506 	r = mep_final_link_relocate (howto, input_bfd, input_section,
    507 				     contents, rel, relocation);
    508 
    509       if (r != bfd_reloc_ok)
    510 	{
    511 	  const char * msg = (const char *) NULL;
    512 
    513 	  switch (r)
    514 	    {
    515 	    case bfd_reloc_overflow:
    516 	      (*info->callbacks->reloc_overflow)
    517 		(info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
    518 		 input_bfd, input_section, rel->r_offset);
    519 	      break;
    520 
    521 	    case bfd_reloc_undefined:
    522 	      (*info->callbacks->undefined_symbol)
    523 		(info, name, input_bfd, input_section, rel->r_offset, TRUE);
    524 	      break;
    525 
    526 	    case bfd_reloc_outofrange:
    527 	      msg = _("internal error: out of range error");
    528 	      break;
    529 
    530 	    case bfd_reloc_notsupported:
    531 	      msg = _("internal error: unsupported relocation error");
    532 	      break;
    533 
    534 	    case bfd_reloc_dangerous:
    535 	      msg = _("internal error: dangerous relocation");
    536 	      break;
    537 
    538 	    default:
    539 	      msg = _("internal error: unknown error");
    540 	      break;
    541 	    }
    542 
    543 	  if (msg)
    544 	    (*info->callbacks->warning) (info, msg, name, input_bfd,
    545 					 input_section, rel->r_offset);
    546 	}
    547     }
    548 
    549   if (warn_tp)
    550     info->callbacks->undefined_symbol
    551       (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
    552   if (warn_sda)
    553     info->callbacks->undefined_symbol
    554       (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
    555   if (warn_sda || warn_tp)
    556     return FALSE;
    557 
    558   return TRUE;
    559 }
    560 
    561 /* Function to set the ELF flag bits.  */
    563 
    564 static bfd_boolean
    565 mep_elf_set_private_flags (bfd *    abfd,
    566 			   flagword flags)
    567 {
    568   elf_elfheader (abfd)->e_flags = flags;
    569   elf_flags_init (abfd) = TRUE;
    570   return TRUE;
    571 }
    572 
    573 /* Merge backend specific data from an object file to the output
    574    object file when linking.  */
    575 
    576 static bfd_boolean
    577 mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
    578 {
    579   static bfd *last_ibfd = 0;
    580   flagword old_flags, new_flags;
    581   flagword old_partial, new_partial;
    582 
    583   /* Check if we have the same endianness.  */
    584   if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
    585     return FALSE;
    586 
    587   new_flags = elf_elfheader (ibfd)->e_flags;
    588   old_flags = elf_elfheader (obfd)->e_flags;
    589 
    590 #ifdef DEBUG
    591   _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
    592 		      ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
    593 #endif
    594 
    595     /* First call, no flags set.  */
    596     if (!elf_flags_init (obfd))
    597     {
    598       elf_flags_init (obfd) = TRUE;
    599       old_flags = new_flags;
    600     }
    601   else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
    602     {
    603       /* Non-library flags trump library flags.  The choice doesn't really
    604 	 matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set.  */
    605       if (old_flags & EF_MEP_LIBRARY)
    606 	old_flags = new_flags;
    607     }
    608   else
    609     {
    610       /* Make sure they're for the same mach.  Allow upgrade from the "mep"
    611 	 mach.  */
    612       new_partial = (new_flags & EF_MEP_CPU_MASK);
    613       old_partial = (old_flags & EF_MEP_CPU_MASK);
    614       if (new_partial == old_partial)
    615 	;
    616       else if (new_partial == EF_MEP_CPU_MEP)
    617 	;
    618       else if (old_partial == EF_MEP_CPU_MEP)
    619 	old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
    620       else
    621 	{
    622 	  _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
    623 	  bfd_set_error (bfd_error_invalid_target);
    624 	  return FALSE;
    625 	}
    626 
    627       /* Make sure they're for the same me_module.  Allow basic config to
    628 	 mix with any other.  */
    629       new_partial = (new_flags & EF_MEP_INDEX_MASK);
    630       old_partial = (old_flags & EF_MEP_INDEX_MASK);
    631       if (new_partial == old_partial)
    632 	;
    633       else if (new_partial == 0)
    634 	;
    635       else if (old_partial == 0)
    636 	old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
    637       else
    638 	{
    639 	  _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
    640 	  bfd_set_error (bfd_error_invalid_target);
    641 	  return FALSE;
    642 	}
    643     }
    644 
    645   elf_elfheader (obfd)->e_flags = old_flags;
    646   last_ibfd = ibfd;
    647   return TRUE;
    648 }
    649 
    650 /* This will be edited by the MeP configration tool.  */
    651 static const char * config_names[] =
    652 {
    653   "basic"
    654   /* start-mepcfgtool */
    655   ,"default"
    656   /* end-mepcfgtool */
    657 };
    658 
    659 static const char * core_names[] =
    660 {
    661   "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
    662 };
    663 
    664 static bfd_boolean
    665 mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
    666 {
    667   FILE *   file = (FILE *) ptr;
    668   flagword flags, partial_flags;
    669 
    670   BFD_ASSERT (abfd != NULL && ptr != NULL);
    671 
    672   /* Print normal ELF private data.  */
    673   _bfd_elf_print_private_bfd_data (abfd, ptr);
    674 
    675   flags = elf_elfheader (abfd)->e_flags;
    676   fprintf (file, _("private flags = 0x%lx"), (unsigned long) flags);
    677 
    678   partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
    679   if (partial_flags < ARRAY_SIZE (core_names))
    680     fprintf (file, "  core: %s", core_names[(long)partial_flags]);
    681 
    682   partial_flags = flags & EF_MEP_INDEX_MASK;
    683   if (partial_flags < ARRAY_SIZE (config_names))
    684     fprintf (file, "  me_module: %s", config_names[(long)partial_flags]);
    685 
    686   fputc ('\n', file);
    687 
    688   return TRUE;
    689 }
    690 
    691 /* Return the machine subcode from the ELF e_flags header.  */
    692 
    693 static int
    694 elf32_mep_machine (bfd * abfd)
    695 {
    696   switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
    697     {
    698     default: break;
    699     case EF_MEP_CPU_C2: return bfd_mach_mep;
    700     case EF_MEP_CPU_C3: return bfd_mach_mep;
    701     case EF_MEP_CPU_C4: return bfd_mach_mep;
    702     case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
    703     case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
    704     }
    705 
    706   return bfd_mach_mep;
    707 }
    708 
    709 static bfd_boolean
    710 mep_elf_object_p (bfd * abfd)
    711 {
    712   bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
    713   return TRUE;
    714 }
    715 
    716 static bfd_boolean
    717 mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
    718 {
    719   if (hdr->sh_flags & SHF_MEP_VLIW)
    720     * flags |= SEC_MEP_VLIW;
    721   return TRUE;
    722 }
    723 
    724 static bfd_boolean
    725 mep_elf_fake_sections (bfd *               abfd ATTRIBUTE_UNUSED,
    726 		       Elf_Internal_Shdr * hdr,
    727 		       asection *          sec)
    728 {
    729   if (sec->flags & SEC_MEP_VLIW)
    730     hdr->sh_flags |= SHF_MEP_VLIW;
    731   return TRUE;
    732 }
    733 
    734 
    735 #define ELF_ARCH		bfd_arch_mep
    737 #define ELF_MACHINE_CODE	EM_CYGNUS_MEP
    738 #define ELF_MAXPAGESIZE		0x1000
    739 
    740 #define TARGET_BIG_SYM		mep_elf32_vec
    741 #define TARGET_BIG_NAME		"elf32-mep"
    742 
    743 #define TARGET_LITTLE_SYM	mep_elf32_le_vec
    744 #define TARGET_LITTLE_NAME	"elf32-mep-little"
    745 
    746 #define elf_info_to_howto_rel			NULL
    747 #define elf_info_to_howto			mep_info_to_howto_rela
    748 #define elf_backend_relocate_section		mep_elf_relocate_section
    749 #define elf_backend_object_p		        mep_elf_object_p
    750 #define elf_backend_section_flags		mep_elf_section_flags
    751 #define elf_backend_fake_sections		mep_elf_fake_sections
    752 
    753 #define bfd_elf32_bfd_reloc_type_lookup		mep_reloc_type_lookup
    754 #define bfd_elf32_bfd_reloc_name_lookup		mep_reloc_name_lookup
    755 #define bfd_elf32_bfd_set_private_flags		mep_elf_set_private_flags
    756 #define bfd_elf32_bfd_merge_private_bfd_data	mep_elf_merge_private_bfd_data
    757 #define bfd_elf32_bfd_print_private_bfd_data	mep_elf_print_private_bfd_data
    758 
    759 #define elf_backend_rela_normal			1
    760 
    761 #include "elf32-target.h"
    762