Update year range in copyright notice of all files.
[external/binutils.git] / bfd / elf32-mep.c
1 /* MeP-specific support for 32-bit ELF.
2    Copyright (C) 2001-2017 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   {(unsigned)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 void
379 mep_info_to_howto_rela
380     (bfd *               abfd ATTRIBUTE_UNUSED,
381      arelent *           cache_ptr,
382      Elf_Internal_Rela * dst)
383 {
384   unsigned int r_type;
385
386   r_type = ELF32_R_TYPE (dst->r_info);
387   if (r_type >= R_MEP_max)
388     {
389       /* xgettext:c-format */
390       _bfd_error_handler (_("%B: invalid MEP reloc number: %d"), abfd, r_type);
391       r_type = 0;
392     }
393   cache_ptr->howto = & mep_elf_howto_table [r_type];
394 }
395 \f
396 /* Relocate a MEP ELF section.
397    There is some attempt to make this function usable for many architectures,
398    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
399    if only to serve as a learning tool.
400
401    The RELOCATE_SECTION function is called by the new ELF backend linker
402    to handle the relocations for a section.
403
404    The relocs are always passed as Rela structures; if the section
405    actually uses Rel structures, the r_addend field will always be
406    zero.
407
408    This function is responsible for adjusting the section contents as
409    necessary, and (if using Rela relocs and generating a relocatable
410    output file) adjusting the reloc addend as necessary.
411
412    This function does not have to worry about setting the reloc
413    address or the reloc symbol index.
414
415    LOCAL_SYMS is a pointer to the swapped in local symbols.
416
417    LOCAL_SECTIONS is an array giving the section in the input file
418    corresponding to the st_shndx field of each local symbol.
419
420    The global hash table entry for the global symbols can be found
421    via elf_sym_hashes (input_bfd).
422
423    When generating relocatable output, this function must handle
424    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
425    going to be the section symbol corresponding to the output
426    section, which means that the addend must be adjusted
427    accordingly.  */
428
429 static bfd_boolean
430 mep_elf_relocate_section
431     (bfd *                   output_bfd ATTRIBUTE_UNUSED,
432      struct bfd_link_info *  info,
433      bfd *                   input_bfd,
434      asection *              input_section,
435      bfd_byte *              contents,
436      Elf_Internal_Rela *     relocs,
437      Elf_Internal_Sym *      local_syms,
438      asection **             local_sections)
439 {
440   Elf_Internal_Shdr *           symtab_hdr;
441   struct elf_link_hash_entry ** sym_hashes;
442   Elf_Internal_Rela *           rel;
443   Elf_Internal_Rela *           relend;
444
445   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
446   sym_hashes = elf_sym_hashes (input_bfd);
447   relend     = relocs + input_section->reloc_count;
448
449   mep_info = info;
450
451   for (rel = relocs; rel < relend; rel ++)
452     {
453       reloc_howto_type *           howto;
454       unsigned long                r_symndx;
455       Elf_Internal_Sym *           sym;
456       asection *                   sec;
457       struct elf_link_hash_entry * h;
458       bfd_vma                      relocation;
459       bfd_reloc_status_type        r;
460       const char *                 name = NULL;
461       int                          r_type;
462
463       r_type = ELF32_R_TYPE (rel->r_info);
464       r_symndx = ELF32_R_SYM (rel->r_info);
465       howto  = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
466       h      = NULL;
467       sym    = NULL;
468       sec    = NULL;
469
470       if (r_symndx < symtab_hdr->sh_info)
471         {
472           sym = local_syms + r_symndx;
473           sec = local_sections [r_symndx];
474           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
475
476           name = bfd_elf_string_from_elf_section
477             (input_bfd, symtab_hdr->sh_link, sym->st_name);
478           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
479         }
480       else
481         {
482           bfd_boolean warned, unresolved_reloc, ignored;
483
484           RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
485                                   r_symndx, symtab_hdr, sym_hashes,
486                                   h, sec, relocation,
487                                   unresolved_reloc, warned, ignored);
488
489           name = h->root.root.string;
490         }
491
492       if (sec != NULL && discarded_section (sec))
493         RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
494                                          rel, 1, relend, howto, 0, contents);
495
496       if (bfd_link_relocatable (info))
497         continue;
498
499       if (r_type == R_RELC)
500         r = bfd_elf_perform_complex_relocation (input_bfd, input_section,
501                                                 contents, rel, relocation);
502       else
503         r = mep_final_link_relocate (howto, input_bfd, input_section,
504                                      contents, rel, relocation);
505
506       if (r != bfd_reloc_ok)
507         {
508           const char * msg = (const char *) NULL;
509
510           switch (r)
511             {
512             case bfd_reloc_overflow:
513               (*info->callbacks->reloc_overflow)
514                 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
515                  input_bfd, input_section, rel->r_offset);
516               break;
517
518             case bfd_reloc_undefined:
519               (*info->callbacks->undefined_symbol)
520                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
521               break;
522
523             case bfd_reloc_outofrange:
524               msg = _("internal error: out of range error");
525               break;
526
527             case bfd_reloc_notsupported:
528               msg = _("internal error: unsupported relocation error");
529               break;
530
531             case bfd_reloc_dangerous:
532               msg = _("internal error: dangerous relocation");
533               break;
534
535             default:
536               msg = _("internal error: unknown error");
537               break;
538             }
539
540           if (msg)
541             (*info->callbacks->warning) (info, msg, name, input_bfd,
542                                          input_section, rel->r_offset);
543         }
544     }
545
546   if (warn_tp)
547     info->callbacks->undefined_symbol
548       (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
549   if (warn_sda)
550     info->callbacks->undefined_symbol
551       (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
552   if (warn_sda || warn_tp)
553     return FALSE;
554
555   return TRUE;
556 }
557 \f
558 /* Function to set the ELF flag bits.  */
559
560 static bfd_boolean
561 mep_elf_set_private_flags (bfd *    abfd,
562                            flagword flags)
563 {
564   elf_elfheader (abfd)->e_flags = flags;
565   elf_flags_init (abfd) = TRUE;
566   return TRUE;
567 }
568
569 /* Merge backend specific data from an object file to the output
570    object file when linking.  */
571
572 static bfd_boolean
573 mep_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
574 {
575   bfd *obfd = info->output_bfd;
576   static bfd *last_ibfd = 0;
577   flagword old_flags, new_flags;
578   flagword old_partial, new_partial;
579
580   /* Check if we have the same endianness.  */
581   if (!_bfd_generic_verify_endian_match (ibfd, info))
582     return FALSE;
583
584   new_flags = elf_elfheader (ibfd)->e_flags;
585   old_flags = elf_elfheader (obfd)->e_flags;
586
587 #ifdef DEBUG
588   _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
589                       ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
590 #endif
591
592     /* First call, no flags set.  */
593     if (!elf_flags_init (obfd))
594     {
595       elf_flags_init (obfd) = TRUE;
596       old_flags = new_flags;
597     }
598   else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
599     {
600       /* Non-library flags trump library flags.  The choice doesn't really
601          matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set.  */
602       if (old_flags & EF_MEP_LIBRARY)
603         old_flags = new_flags;
604     }
605   else
606     {
607       /* Make sure they're for the same mach.  Allow upgrade from the "mep"
608          mach.  */
609       new_partial = (new_flags & EF_MEP_CPU_MASK);
610       old_partial = (old_flags & EF_MEP_CPU_MASK);
611       if (new_partial == old_partial)
612         ;
613       else if (new_partial == EF_MEP_CPU_MEP)
614         ;
615       else if (old_partial == EF_MEP_CPU_MEP)
616         old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
617       else
618         {
619           /* xgettext:c-format */
620           _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
621           bfd_set_error (bfd_error_invalid_target);
622           return FALSE;
623         }
624
625       /* Make sure they're for the same me_module.  Allow basic config to
626          mix with any other.  */
627       new_partial = (new_flags & EF_MEP_INDEX_MASK);
628       old_partial = (old_flags & EF_MEP_INDEX_MASK);
629       if (new_partial == old_partial)
630         ;
631       else if (new_partial == 0)
632         ;
633       else if (old_partial == 0)
634         old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
635       else
636         {
637           /* xgettext:c-format */
638           _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
639           bfd_set_error (bfd_error_invalid_target);
640           return FALSE;
641         }
642     }
643
644   elf_elfheader (obfd)->e_flags = old_flags;
645   last_ibfd = ibfd;
646   return TRUE;
647 }
648
649 /* This will be edited by the MeP configration tool.  */
650 static const char * config_names[] =
651 {
652   "basic"
653   /* start-mepcfgtool */
654   ,"default"
655   /* end-mepcfgtool */
656 };
657
658 static const char * core_names[] =
659 {
660   "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
661 };
662
663 static bfd_boolean
664 mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
665 {
666   FILE *   file = (FILE *) ptr;
667   flagword flags, partial_flags;
668
669   BFD_ASSERT (abfd != NULL && ptr != NULL);
670
671   /* Print normal ELF private data.  */
672   _bfd_elf_print_private_bfd_data (abfd, ptr);
673
674   flags = elf_elfheader (abfd)->e_flags;
675   fprintf (file, _("private flags = 0x%lx"), (unsigned long) flags);
676
677   partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
678   if (partial_flags < ARRAY_SIZE (core_names))
679     fprintf (file, "  core: %s", core_names[(long)partial_flags]);
680
681   partial_flags = flags & EF_MEP_INDEX_MASK;
682   if (partial_flags < ARRAY_SIZE (config_names))
683     fprintf (file, "  me_module: %s", config_names[(long)partial_flags]);
684
685   fputc ('\n', file);
686
687   return TRUE;
688 }
689
690 /* Return the machine subcode from the ELF e_flags header.  */
691
692 static int
693 elf32_mep_machine (bfd * abfd)
694 {
695   switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
696     {
697     default: break;
698     case EF_MEP_CPU_C2: return bfd_mach_mep;
699     case EF_MEP_CPU_C3: return bfd_mach_mep;
700     case EF_MEP_CPU_C4: return bfd_mach_mep;
701     case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
702     case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
703     }
704
705   return bfd_mach_mep;
706 }
707
708 static bfd_boolean
709 mep_elf_object_p (bfd * abfd)
710 {
711   bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
712   return TRUE;
713 }
714
715 static bfd_boolean
716 mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
717 {
718   if (hdr->sh_flags & SHF_MEP_VLIW)
719     * flags |= SEC_MEP_VLIW;
720   return TRUE;
721 }
722
723 static bfd_boolean
724 mep_elf_fake_sections (bfd *               abfd ATTRIBUTE_UNUSED,
725                        Elf_Internal_Shdr * hdr,
726                        asection *          sec)
727 {
728   if (sec->flags & SEC_MEP_VLIW)
729     hdr->sh_flags |= SHF_MEP_VLIW;
730   return TRUE;
731 }
732
733 \f
734 #define ELF_ARCH                bfd_arch_mep
735 #define ELF_MACHINE_CODE        EM_CYGNUS_MEP
736 #define ELF_MAXPAGESIZE         0x1000
737
738 #define TARGET_BIG_SYM          mep_elf32_vec
739 #define TARGET_BIG_NAME         "elf32-mep"
740
741 #define TARGET_LITTLE_SYM       mep_elf32_le_vec
742 #define TARGET_LITTLE_NAME      "elf32-mep-little"
743
744 #define elf_info_to_howto_rel                   NULL
745 #define elf_info_to_howto                       mep_info_to_howto_rela
746 #define elf_backend_relocate_section            mep_elf_relocate_section
747 #define elf_backend_object_p                    mep_elf_object_p
748 #define elf_backend_section_flags               mep_elf_section_flags
749 #define elf_backend_fake_sections               mep_elf_fake_sections
750
751 #define bfd_elf32_bfd_reloc_type_lookup         mep_reloc_type_lookup
752 #define bfd_elf32_bfd_reloc_name_lookup         mep_reloc_name_lookup
753 #define bfd_elf32_bfd_set_private_flags         mep_elf_set_private_flags
754 #define bfd_elf32_bfd_merge_private_bfd_data    mep_elf_merge_private_bfd_data
755 #define bfd_elf32_bfd_print_private_bfd_data    mep_elf_print_private_bfd_data
756
757 #define elf_backend_rela_normal                 1
758
759 #include "elf32-target.h"