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