ChangeLog rotatation and copyright year update
[external/binutils.git] / bfd / elf32-mep.c
1 /* MeP-specific support for 32-bit ELF.
2    Copyright (C) 2001-2015 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, mep_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 bfd_reloc_status_type mep_reloc (bfd *, arelent *, struct bfd_symbol *,
40                                         void *, asection *, bfd *, char **);
41
42 static reloc_howto_type mep_elf_howto_table [] =
43 {
44   /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask.  */
45   MEPREL (R_MEP_NONE,     0,  0, 0, 0, 0, N, 0),
46   MEPREL (R_RELC,         0,  0, 0, 0, 0, N, 0),
47   /* MEPRELOC:HOWTO */
48     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
49   MEPREL (R_MEP_8,        0,  8, 0, 0, 0, U, 0xff),
50   MEPREL (R_MEP_16,       1, 16, 0, 0, 0, U, 0xffff),
51   MEPREL (R_MEP_32,       2, 32, 0, 0, 0, U, 0xffffffff),
52   MEPREL (R_MEP_PCREL8A2, 1,  8, 1, 1, 1, S, 0x00fe),
53   MEPREL (R_MEP_PCREL12A2,1, 12, 1, 1, 1, S, 0x0ffe),
54   MEPREL (R_MEP_PCREL17A2,2, 17, 0, 1, 1, S, 0x0000ffff),
55   MEPREL (R_MEP_PCREL24A2,2, 24, 0, 1, 1, S, 0x07f0ffff),
56   MEPREL (R_MEP_PCABS24A2,2, 24, 0, 1, 0, U, 0x07f0ffff),
57   MEPREL (R_MEP_LOW16,    2, 16, 0, 0, 0, N, 0x0000ffff),
58   MEPREL (R_MEP_HI16U,    2, 32, 0,16, 0, N, 0x0000ffff),
59   MEPREL (R_MEP_HI16S,    2, 32, 0,16, 0, N, 0x0000ffff),
60   MEPREL (R_MEP_GPREL,    2, 16, 0, 0, 0, S, 0x0000ffff),
61   MEPREL (R_MEP_TPREL,    2, 16, 0, 0, 0, S, 0x0000ffff),
62   MEPREL (R_MEP_TPREL7,   1,  7, 0, 0, 0, U, 0x007f),
63   MEPREL (R_MEP_TPREL7A2, 1,  7, 1, 1, 0, U, 0x007e),
64   MEPREL (R_MEP_TPREL7A4, 1,  7, 2, 2, 0, U, 0x007c),
65   MEPREL (R_MEP_UIMM24,   2, 24, 0, 0, 0, U, 0x00ffffff),
66   MEPREL (R_MEP_ADDR24A4, 2, 24, 0, 2, 0, U, 0x00fcffff),
67   MEPREL (R_MEP_GNU_VTINHERIT,1,  0,16,32, 0, N, 0x0000),
68   MEPREL (R_MEP_GNU_VTENTRY,1,  0,16,32, 0, N, 0x0000),
69   /* MEPRELOC:END */
70 };
71
72 #define VALID_MEP_RELOC(N) ((N) >= 0 \
73   && (N) < ARRAY_SIZE (mep_elf_howto_table)
74
75 #undef N
76 #undef S
77 #undef U
78
79 static bfd_reloc_status_type
80 mep_reloc
81     (bfd *               abfd ATTRIBUTE_UNUSED,
82      arelent *           reloc_entry ATTRIBUTE_UNUSED,
83      struct bfd_symbol * symbol ATTRIBUTE_UNUSED,
84      void *              data ATTRIBUTE_UNUSED,
85      asection *          input_section ATTRIBUTE_UNUSED,
86      bfd *               output_bfd ATTRIBUTE_UNUSED,
87      char **             error_message ATTRIBUTE_UNUSED)
88 {
89   return bfd_reloc_ok;
90 }
91
92 \f
93
94 #define BFD_RELOC_MEP_NONE BFD_RELOC_NONE
95 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
96 #define MAP(n) case BFD_RELOC_MEP_##n: type = R_MEP_##n; break
97 #else
98 #define MAP(n) case BFD_RELOC_MEP_/**/n: type = R_MEP_/**/n; break
99 #endif
100
101 static reloc_howto_type *
102 mep_reloc_type_lookup
103     (bfd * abfd ATTRIBUTE_UNUSED,
104      bfd_reloc_code_real_type code)
105 {
106   unsigned int type = 0;
107
108   switch (code)
109     {
110     MAP(NONE);
111     case BFD_RELOC_8:
112       type = R_MEP_8;
113       break;
114     case BFD_RELOC_16:
115       type = R_MEP_16;
116       break;
117     case BFD_RELOC_32:
118       type = R_MEP_32;
119       break;
120     case BFD_RELOC_VTABLE_ENTRY:
121       type = R_MEP_GNU_VTENTRY;
122       break;
123     case BFD_RELOC_VTABLE_INHERIT:
124       type = R_MEP_GNU_VTINHERIT;
125       break;
126     case BFD_RELOC_RELC:
127       type = R_RELC;
128       break;
129
130     /* MEPRELOC:MAP */
131     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
132     MAP(8);
133     MAP(16);
134     MAP(32);
135     MAP(PCREL8A2);
136     MAP(PCREL12A2);
137     MAP(PCREL17A2);
138     MAP(PCREL24A2);
139     MAP(PCABS24A2);
140     MAP(LOW16);
141     MAP(HI16U);
142     MAP(HI16S);
143     MAP(GPREL);
144     MAP(TPREL);
145     MAP(TPREL7);
146     MAP(TPREL7A2);
147     MAP(TPREL7A4);
148     MAP(UIMM24);
149     MAP(ADDR24A4);
150     MAP(GNU_VTINHERIT);
151     MAP(GNU_VTENTRY);
152     /* MEPRELOC:END */
153
154     default:
155       /* Pacify gcc -Wall.  */
156       (*_bfd_error_handler) (_("mep: no reloc for code %d"), code);
157       return NULL;
158     }
159
160   if (mep_elf_howto_table[type].type != type)
161     {
162       (*_bfd_error_handler) (_("MeP: howto %d has type %d"),
163                              type, mep_elf_howto_table[type].type);
164       abort ();
165     }
166
167   return mep_elf_howto_table + type;
168 }
169
170 #undef MAP
171
172 static reloc_howto_type *
173 mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
174 {
175   unsigned int i;
176
177   for (i = 0;
178        i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]);
179        i++)
180     if (mep_elf_howto_table[i].name != NULL
181         && strcasecmp (mep_elf_howto_table[i].name, r_name) == 0)
182       return &mep_elf_howto_table[i];
183
184   return NULL;
185 }
186 \f
187 /* Perform a single relocation.  */
188
189 static struct bfd_link_info *mep_info;
190 static int warn_tp = 0, warn_sda = 0;
191
192 static bfd_vma
193 mep_lookup_global
194     (char *    name,
195      bfd_vma   ofs,
196      bfd_vma * cache,
197      int *     warn)
198 {
199   struct bfd_link_hash_entry *h;
200
201   if (*cache || *warn)
202     return *cache;
203
204   h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE);
205   if (h == 0 || h->type != bfd_link_hash_defined)
206     {
207       *warn = ofs + 1;
208       return 0;
209     }
210   *cache = (h->u.def.value
211           + h->u.def.section->output_section->vma
212           + h->u.def.section->output_offset);
213   return *cache;
214 }
215
216 static bfd_vma
217 mep_tpoff_base (bfd_vma ofs)
218 {
219   static bfd_vma cache = 0;
220   return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
221 }
222
223 static bfd_vma
224 mep_sdaoff_base (bfd_vma ofs)
225 {
226   static bfd_vma cache = 0;
227   return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
228 }
229
230 static bfd_reloc_status_type
231 mep_final_link_relocate
232     (reloc_howto_type *  howto,
233      bfd *               input_bfd,
234      asection *          input_section,
235      bfd_byte *          contents,
236      Elf_Internal_Rela * rel,
237      bfd_vma             relocation)
238 {
239   unsigned long u;
240   long s;
241   unsigned char *byte;
242   bfd_vma pc;
243   bfd_reloc_status_type r = bfd_reloc_ok;
244   int e2, e4;
245
246   if (bfd_big_endian (input_bfd))
247     {
248       e2 = 0;
249       e4 = 0;
250     }
251   else
252     {
253       e2 = 1;
254       e4 = 3;
255     }
256
257   pc = (input_section->output_section->vma
258         + input_section->output_offset
259         + rel->r_offset);
260
261   s = relocation + rel->r_addend;
262
263   byte = (unsigned char *)contents + rel->r_offset;
264
265   if (howto->type == R_MEP_PCREL24A2
266       && s == 0
267       && pc >= 0x800000)
268     {
269       /* This is an unreachable branch to an undefined weak function.
270          Silently ignore it, since the opcode can't do that but should
271          never be executed anyway.  */
272       return bfd_reloc_ok;
273     }
274
275   if (howto->pc_relative)
276     s -= pc;
277
278   u = (unsigned long) s;
279
280   switch (howto->type)
281     {
282     /* MEPRELOC:APPLY */
283     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
284     case R_MEP_8: /* 76543210 */
285       if (u > 255) r = bfd_reloc_overflow;
286       byte[0] = (u & 0xff);
287       break;
288     case R_MEP_16: /* fedcba9876543210 */
289       if (u > 65535) r = bfd_reloc_overflow;
290       byte[0^e2] = ((u >> 8) & 0xff);
291       byte[1^e2] = (u & 0xff);
292       break;
293     case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */
294       byte[0^e4] = ((u >> 24) & 0xff);
295       byte[1^e4] = ((u >> 16) & 0xff);
296       byte[2^e4] = ((u >> 8) & 0xff);
297       byte[3^e4] = (u & 0xff);
298       break;
299     case R_MEP_PCREL8A2: /* --------7654321- */
300       if (-128 > s || s > 127) r = bfd_reloc_overflow;
301       byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
302       break;
303     case R_MEP_PCREL12A2: /* ----ba987654321- */
304       if (-2048 > s || s > 2047) r = bfd_reloc_overflow;
305       byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f);
306       byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
307       break;
308     case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */
309       if (-65536 > s || s > 65535) r = bfd_reloc_overflow;
310       byte[2^e2] = ((s >> 9) & 0xff);
311       byte[3^e2] = ((s >> 1) & 0xff);
312       break;
313     case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */
314       if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow;
315       byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07);
316       byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0);
317       byte[2^e2] = ((s >> 16) & 0xff);
318       byte[3^e2] = ((s >> 8) & 0xff);
319       break;
320     case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */
321       if (u > 16777215) r = bfd_reloc_overflow;
322       byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07);
323       byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0);
324       byte[2^e2] = ((u >> 16) & 0xff);
325       byte[3^e2] = ((u >> 8) & 0xff);
326       break;
327     case R_MEP_LOW16: /* ----------------fedcba9876543210 */
328       byte[2^e2] = ((u >> 8) & 0xff);
329       byte[3^e2] = (u & 0xff);
330       break;
331     case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */
332       byte[2^e2] = ((u >> 24) & 0xff);
333       byte[3^e2] = ((u >> 16) & 0xff);
334       break;
335     case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */
336       if (s & 0x8000)
337         s += 0x10000;
338       byte[2^e2] = ((s >> 24) & 0xff);
339       byte[3^e2] = ((s >> 16) & 0xff);
340       break;
341     case R_MEP_GPREL: /* ----------------fedcba9876543210 */
342       s -= mep_sdaoff_base(rel->r_offset);
343       if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
344       byte[2^e2] = ((s >> 8) & 0xff);
345       byte[3^e2] = (s & 0xff);
346       break;
347     case R_MEP_TPREL: /* ----------------fedcba9876543210 */
348       s -= mep_tpoff_base(rel->r_offset);
349       if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
350       byte[2^e2] = ((s >> 8) & 0xff);
351       byte[3^e2] = (s & 0xff);
352       break;
353     case R_MEP_TPREL7: /* ---------6543210 */
354       u -= mep_tpoff_base(rel->r_offset);
355       if (u > 127) r = bfd_reloc_overflow;
356       byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
357       break;
358     case R_MEP_TPREL7A2: /* ---------654321- */
359       u -= mep_tpoff_base(rel->r_offset);
360       if (u > 127) r = bfd_reloc_overflow;
361       byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
362       break;
363     case R_MEP_TPREL7A4: /* ---------65432-- */
364       u -= mep_tpoff_base(rel->r_offset);
365       if (u > 127) r = bfd_reloc_overflow;
366       byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
367       break;
368     case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
369       if (u > 16777215) r = bfd_reloc_overflow;
370       byte[1^e2] = (u & 0xff);
371       byte[2^e2] = ((u >> 16) & 0xff);
372       byte[3^e2] = ((u >> 8) & 0xff);
373       break;
374     case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
375       if (u > 16777215) r = bfd_reloc_overflow;
376       byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
377       byte[2^e2] = ((u >> 16) & 0xff);
378       byte[3^e2] = ((u >> 8) & 0xff);
379       break;
380     case R_MEP_GNU_VTINHERIT: /* ---------------- */
381       break;
382     case R_MEP_GNU_VTENTRY: /* ---------------- */
383       break;
384     /* MEPRELOC:END */
385     default:
386       abort ();
387     }
388
389   return r;
390 }
391 \f
392 /* Set the howto pointer for a MEP ELF reloc.  */
393
394 static void
395 mep_info_to_howto_rela
396     (bfd *               abfd ATTRIBUTE_UNUSED,
397      arelent *           cache_ptr,
398      Elf_Internal_Rela * dst)
399 {
400   unsigned int r_type;
401
402   r_type = ELF32_R_TYPE (dst->r_info);
403   if (r_type >= R_MEP_max)
404     {
405       _bfd_error_handler (_("%A: invalid MEP reloc number: %d"), abfd, r_type);
406       r_type = 0;
407     }
408   cache_ptr->howto = & mep_elf_howto_table [r_type];
409 }
410 \f
411 /* 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 \f
576 /* Function to set the ELF flag bits.  */
577
578 static bfd_boolean
579 mep_elf_set_private_flags (bfd *    abfd,
580                            flagword flags)
581 {
582   elf_elfheader (abfd)->e_flags = flags;
583   elf_flags_init (abfd) = TRUE;
584   return TRUE;
585 }
586
587 /* Merge backend specific data from an object file to the output
588    object file when linking.  */
589
590 static bfd_boolean
591 mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
592 {
593   static bfd *last_ibfd = 0;
594   flagword old_flags, new_flags;
595   flagword old_partial, new_partial;
596
597   /* Check if we have the same endianness.  */
598   if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
599     return FALSE;
600
601   new_flags = elf_elfheader (ibfd)->e_flags;
602   old_flags = elf_elfheader (obfd)->e_flags;
603
604 #ifdef DEBUG
605   _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
606                       ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
607 #endif
608
609     /* First call, no flags set.  */
610     if (!elf_flags_init (obfd))
611     {
612       elf_flags_init (obfd) = TRUE;
613       old_flags = new_flags;
614     }
615   else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
616     {
617       /* Non-library flags trump library flags.  The choice doesn't really
618          matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set.  */
619       if (old_flags & EF_MEP_LIBRARY)
620         old_flags = new_flags;
621     }
622   else
623     {
624       /* Make sure they're for the same mach.  Allow upgrade from the "mep"
625          mach.  */
626       new_partial = (new_flags & EF_MEP_CPU_MASK);
627       old_partial = (old_flags & EF_MEP_CPU_MASK);
628       if (new_partial == old_partial)
629         ;
630       else if (new_partial == EF_MEP_CPU_MEP)
631         ;
632       else if (old_partial == EF_MEP_CPU_MEP)
633         old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
634       else
635         {
636           _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
637           bfd_set_error (bfd_error_invalid_target);
638           return FALSE;
639         }
640
641       /* Make sure they're for the same me_module.  Allow basic config to
642          mix with any other.  */
643       new_partial = (new_flags & EF_MEP_INDEX_MASK);
644       old_partial = (old_flags & EF_MEP_INDEX_MASK);
645       if (new_partial == old_partial)
646         ;
647       else if (new_partial == 0)
648         ;
649       else if (old_partial == 0)
650         old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
651       else
652         {
653           _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
654           bfd_set_error (bfd_error_invalid_target);
655           return FALSE;
656         }
657     }
658
659   elf_elfheader (obfd)->e_flags = old_flags;
660   last_ibfd = ibfd;
661   return TRUE;
662 }
663
664 /* This will be edited by the MeP configration tool.  */
665 static const char * config_names[] =
666 {
667   "basic"
668   /* start-mepcfgtool */
669   ,"default"
670   /* end-mepcfgtool */
671 };
672
673 static const char * core_names[] =
674 {
675   "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
676 };
677
678 static bfd_boolean
679 mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
680 {
681   FILE *   file = (FILE *) ptr;
682   flagword flags, partial_flags;
683
684   BFD_ASSERT (abfd != NULL && ptr != NULL);
685
686   /* Print normal ELF private data.  */
687   _bfd_elf_print_private_bfd_data (abfd, ptr);
688
689   flags = elf_elfheader (abfd)->e_flags;
690   fprintf (file, _("private flags = 0x%lx"), (unsigned long) flags);
691
692   partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
693   if (partial_flags < ARRAY_SIZE (core_names))
694     fprintf (file, "  core: %s", core_names[(long)partial_flags]);
695
696   partial_flags = flags & EF_MEP_INDEX_MASK;
697   if (partial_flags < ARRAY_SIZE (config_names))
698     fprintf (file, "  me_module: %s", config_names[(long)partial_flags]);
699
700   fputc ('\n', file);
701
702   return TRUE;
703 }
704
705 /* Return the machine subcode from the ELF e_flags header.  */
706
707 static int
708 elf32_mep_machine (bfd * abfd)
709 {
710   switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
711     {
712     default: break;
713     case EF_MEP_CPU_C2: return bfd_mach_mep;
714     case EF_MEP_CPU_C3: return bfd_mach_mep;
715     case EF_MEP_CPU_C4: return bfd_mach_mep;
716     case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
717     case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
718     }
719
720   return bfd_mach_mep;
721 }
722
723 static bfd_boolean
724 mep_elf_object_p (bfd * abfd)
725 {
726   bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
727   return TRUE;
728 }
729
730 static bfd_boolean
731 mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
732 {
733   if (hdr->sh_flags & SHF_MEP_VLIW)
734     * flags |= SEC_MEP_VLIW;
735   return TRUE;
736 }
737
738 static bfd_boolean
739 mep_elf_fake_sections (bfd *               abfd ATTRIBUTE_UNUSED,
740                        Elf_Internal_Shdr * hdr,
741                        asection *          sec)
742 {
743   if (sec->flags & SEC_MEP_VLIW)
744     hdr->sh_flags |= SHF_MEP_VLIW;
745   return TRUE;
746 }
747
748 \f
749 #define ELF_ARCH                bfd_arch_mep
750 #define ELF_MACHINE_CODE        EM_CYGNUS_MEP
751 #define ELF_MAXPAGESIZE         0x1000
752
753 #define TARGET_BIG_SYM          mep_elf32_vec
754 #define TARGET_BIG_NAME         "elf32-mep"
755
756 #define TARGET_LITTLE_SYM       mep_elf32_le_vec
757 #define TARGET_LITTLE_NAME      "elf32-mep-little"
758
759 #define elf_info_to_howto_rel                   NULL
760 #define elf_info_to_howto                       mep_info_to_howto_rela
761 #define elf_backend_relocate_section            mep_elf_relocate_section
762 #define elf_backend_object_p                    mep_elf_object_p
763 #define elf_backend_section_flags               mep_elf_section_flags
764 #define elf_backend_fake_sections               mep_elf_fake_sections
765
766 #define bfd_elf32_bfd_reloc_type_lookup         mep_reloc_type_lookup
767 #define bfd_elf32_bfd_reloc_name_lookup         mep_reloc_name_lookup
768 #define bfd_elf32_bfd_set_private_flags         mep_elf_set_private_flags
769 #define bfd_elf32_bfd_merge_private_bfd_data    mep_elf_merge_private_bfd_data
770 #define bfd_elf32_bfd_print_private_bfd_data    mep_elf_print_private_bfd_data
771
772 #define elf_backend_rela_normal                 1
773
774 #include "elf32-target.h"