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