Update ARC instruction data-base.
[deliverable/binutils-gdb.git] / bfd / elf32-mep.c
CommitLineData
d9352518 1/* MeP-specific support for 32-bit ELF.
6f2750fe 2 Copyright (C) 2001-2016 Free Software Foundation, Inc.
d9352518
DB
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
cd123cb7 8 the Free Software Foundation; either version 3 of the License, or
d9352518
DB
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
cd123cb7
NC
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 MA 02110-1301, USA. */
d9352518 20
d9352518 21#include "sysdep.h"
3db64b00 22#include "bfd.h"
d9352518
DB
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) \
153a2776 33 {(unsigned)type, right, size, bits, pcrel, left, overflow, bfd_elf_generic_reloc, #type, FALSE, 0, mask, 0 }
d9352518
DB
34
35#define N complain_overflow_dont
36#define S complain_overflow_signed
37#define U complain_overflow_unsigned
38
d9352518
DB
39static reloc_howto_type mep_elf_howto_table [] =
40{
41 /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask. */
6346d5ca 42 MEPREL (R_MEP_NONE, 3, 0, 0, 0, 0, N, 0),
d9352518
DB
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
d9352518
DB
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
84static reloc_howto_type *
85mep_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. */
4a97a0e5 139 (*_bfd_error_handler) (_("mep: no reloc for code %d"), code);
d9352518
DB
140 return NULL;
141 }
142
143 if (mep_elf_howto_table[type].type != type)
144 {
4a97a0e5
AM
145 (*_bfd_error_handler) (_("MeP: howto %d has type %d"),
146 type, mep_elf_howto_table[type].type);
d9352518
DB
147 abort ();
148 }
149
150 return mep_elf_howto_table + type;
151}
152
153#undef MAP
154
157090f7
AM
155static reloc_howto_type *
156mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
157{
158 unsigned int i;
159
160 for (i = 0;
161 i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]);
162 i++)
163 if (mep_elf_howto_table[i].name != NULL
164 && strcasecmp (mep_elf_howto_table[i].name, r_name) == 0)
165 return &mep_elf_howto_table[i];
166
167 return NULL;
168}
d9352518
DB
169\f
170/* Perform a single relocation. */
171
172static struct bfd_link_info *mep_info;
173static int warn_tp = 0, warn_sda = 0;
174
175static bfd_vma
176mep_lookup_global
177 (char * name,
178 bfd_vma ofs,
179 bfd_vma * cache,
180 int * warn)
181{
182 struct bfd_link_hash_entry *h;
183
184 if (*cache || *warn)
185 return *cache;
186
187 h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE);
188 if (h == 0 || h->type != bfd_link_hash_defined)
189 {
190 *warn = ofs + 1;
191 return 0;
192 }
193 *cache = (h->u.def.value
194 + h->u.def.section->output_section->vma
195 + h->u.def.section->output_offset);
196 return *cache;
197}
198
199static bfd_vma
200mep_tpoff_base (bfd_vma ofs)
201{
202 static bfd_vma cache = 0;
203 return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
204}
205
206static bfd_vma
207mep_sdaoff_base (bfd_vma ofs)
208{
209 static bfd_vma cache = 0;
210 return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
211}
212
213static bfd_reloc_status_type
214mep_final_link_relocate
215 (reloc_howto_type * howto,
216 bfd * input_bfd,
217 asection * input_section,
218 bfd_byte * contents,
219 Elf_Internal_Rela * rel,
220 bfd_vma relocation)
221{
222 unsigned long u;
223 long s;
224 unsigned char *byte;
225 bfd_vma pc;
226 bfd_reloc_status_type r = bfd_reloc_ok;
227 int e2, e4;
228
229 if (bfd_big_endian (input_bfd))
230 {
231 e2 = 0;
232 e4 = 0;
233 }
234 else
235 {
236 e2 = 1;
237 e4 = 3;
238 }
239
240 pc = (input_section->output_section->vma
241 + input_section->output_offset
242 + rel->r_offset);
243
244 s = relocation + rel->r_addend;
245
246 byte = (unsigned char *)contents + rel->r_offset;
247
248 if (howto->type == R_MEP_PCREL24A2
249 && s == 0
250 && pc >= 0x800000)
251 {
252 /* This is an unreachable branch to an undefined weak function.
253 Silently ignore it, since the opcode can't do that but should
254 never be executed anyway. */
255 return bfd_reloc_ok;
256 }
257
258 if (howto->pc_relative)
259 s -= pc;
260
261 u = (unsigned long) s;
262
263 switch (howto->type)
264 {
265 /* MEPRELOC:APPLY */
266 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
267 case R_MEP_8: /* 76543210 */
268 if (u > 255) r = bfd_reloc_overflow;
269 byte[0] = (u & 0xff);
270 break;
271 case R_MEP_16: /* fedcba9876543210 */
272 if (u > 65535) r = bfd_reloc_overflow;
273 byte[0^e2] = ((u >> 8) & 0xff);
274 byte[1^e2] = (u & 0xff);
275 break;
276 case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */
277 byte[0^e4] = ((u >> 24) & 0xff);
278 byte[1^e4] = ((u >> 16) & 0xff);
279 byte[2^e4] = ((u >> 8) & 0xff);
280 byte[3^e4] = (u & 0xff);
281 break;
282 case R_MEP_PCREL8A2: /* --------7654321- */
283 if (-128 > s || s > 127) r = bfd_reloc_overflow;
284 byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
285 break;
286 case R_MEP_PCREL12A2: /* ----ba987654321- */
287 if (-2048 > s || s > 2047) r = bfd_reloc_overflow;
288 byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f);
289 byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
290 break;
291 case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */
292 if (-65536 > s || s > 65535) r = bfd_reloc_overflow;
293 byte[2^e2] = ((s >> 9) & 0xff);
294 byte[3^e2] = ((s >> 1) & 0xff);
295 break;
296 case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */
297 if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow;
298 byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07);
299 byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0);
300 byte[2^e2] = ((s >> 16) & 0xff);
301 byte[3^e2] = ((s >> 8) & 0xff);
302 break;
303 case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */
304 if (u > 16777215) r = bfd_reloc_overflow;
305 byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07);
306 byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0);
307 byte[2^e2] = ((u >> 16) & 0xff);
308 byte[3^e2] = ((u >> 8) & 0xff);
309 break;
310 case R_MEP_LOW16: /* ----------------fedcba9876543210 */
311 byte[2^e2] = ((u >> 8) & 0xff);
312 byte[3^e2] = (u & 0xff);
313 break;
314 case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */
315 byte[2^e2] = ((u >> 24) & 0xff);
316 byte[3^e2] = ((u >> 16) & 0xff);
317 break;
318 case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */
b4928193
NC
319 if (s & 0x8000)
320 s += 0x10000;
d9352518
DB
321 byte[2^e2] = ((s >> 24) & 0xff);
322 byte[3^e2] = ((s >> 16) & 0xff);
323 break;
324 case R_MEP_GPREL: /* ----------------fedcba9876543210 */
325 s -= mep_sdaoff_base(rel->r_offset);
326 if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
327 byte[2^e2] = ((s >> 8) & 0xff);
328 byte[3^e2] = (s & 0xff);
329 break;
330 case R_MEP_TPREL: /* ----------------fedcba9876543210 */
331 s -= mep_tpoff_base(rel->r_offset);
332 if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
333 byte[2^e2] = ((s >> 8) & 0xff);
334 byte[3^e2] = (s & 0xff);
335 break;
336 case R_MEP_TPREL7: /* ---------6543210 */
337 u -= mep_tpoff_base(rel->r_offset);
338 if (u > 127) r = bfd_reloc_overflow;
339 byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
340 break;
341 case R_MEP_TPREL7A2: /* ---------654321- */
342 u -= mep_tpoff_base(rel->r_offset);
343 if (u > 127) r = bfd_reloc_overflow;
344 byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
345 break;
346 case R_MEP_TPREL7A4: /* ---------65432-- */
347 u -= mep_tpoff_base(rel->r_offset);
348 if (u > 127) r = bfd_reloc_overflow;
349 byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
350 break;
351 case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
352 if (u > 16777215) r = bfd_reloc_overflow;
353 byte[1^e2] = (u & 0xff);
354 byte[2^e2] = ((u >> 16) & 0xff);
355 byte[3^e2] = ((u >> 8) & 0xff);
356 break;
357 case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
358 if (u > 16777215) r = bfd_reloc_overflow;
359 byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
360 byte[2^e2] = ((u >> 16) & 0xff);
361 byte[3^e2] = ((u >> 8) & 0xff);
362 break;
363 case R_MEP_GNU_VTINHERIT: /* ---------------- */
364 break;
365 case R_MEP_GNU_VTENTRY: /* ---------------- */
366 break;
367 /* MEPRELOC:END */
368 default:
369 abort ();
370 }
371
372 return r;
373}
374\f
375/* Set the howto pointer for a MEP ELF reloc. */
376
377static void
378mep_info_to_howto_rela
379 (bfd * abfd ATTRIBUTE_UNUSED,
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);
5860e3f8
NC
386 if (r_type >= R_MEP_max)
387 {
64d29018 388 _bfd_error_handler (_("%B: invalid MEP reloc number: %d"), abfd, r_type);
5860e3f8
NC
389 r_type = 0;
390 }
d9352518
DB
391 cache_ptr->howto = & mep_elf_howto_table [r_type];
392}
d9352518
DB
393\f
394/* Relocate a MEP ELF section.
395 There is some attempt to make this function usable for many architectures,
396 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
397 if only to serve as a learning tool.
398
399 The RELOCATE_SECTION function is called by the new ELF backend linker
400 to handle the relocations for a section.
401
402 The relocs are always passed as Rela structures; if the section
403 actually uses Rel structures, the r_addend field will always be
404 zero.
405
406 This function is responsible for adjusting the section contents as
407 necessary, and (if using Rela relocs and generating a relocatable
408 output file) adjusting the reloc addend as necessary.
409
410 This function does not have to worry about setting the reloc
411 address or the reloc symbol index.
412
413 LOCAL_SYMS is a pointer to the swapped in local symbols.
414
415 LOCAL_SECTIONS is an array giving the section in the input file
416 corresponding to the st_shndx field of each local symbol.
417
418 The global hash table entry for the global symbols can be found
419 via elf_sym_hashes (input_bfd).
420
421 When generating relocatable output, this function must handle
422 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
423 going to be the section symbol corresponding to the output
424 section, which means that the addend must be adjusted
425 accordingly. */
426
427static bfd_boolean
428mep_elf_relocate_section
429 (bfd * output_bfd ATTRIBUTE_UNUSED,
430 struct bfd_link_info * info,
431 bfd * input_bfd,
432 asection * input_section,
433 bfd_byte * contents,
434 Elf_Internal_Rela * relocs,
435 Elf_Internal_Sym * local_syms,
436 asection ** local_sections)
437{
438 Elf_Internal_Shdr * symtab_hdr;
439 struct elf_link_hash_entry ** sym_hashes;
440 Elf_Internal_Rela * rel;
441 Elf_Internal_Rela * relend;
442
443 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
444 sym_hashes = elf_sym_hashes (input_bfd);
445 relend = relocs + input_section->reloc_count;
446
447 mep_info = info;
448
449 for (rel = relocs; rel < relend; rel ++)
450 {
451 reloc_howto_type * howto;
452 unsigned long r_symndx;
453 Elf_Internal_Sym * sym;
454 asection * sec;
455 struct elf_link_hash_entry * h;
456 bfd_vma relocation;
457 bfd_reloc_status_type r;
458 const char * name = NULL;
459 int r_type;
460
461 r_type = ELF32_R_TYPE (rel->r_info);
d9352518 462 r_symndx = ELF32_R_SYM (rel->r_info);
d9352518
DB
463 howto = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
464 h = NULL;
465 sym = NULL;
466 sec = NULL;
467
468 if (r_symndx < symtab_hdr->sh_info)
469 {
470 sym = local_syms + r_symndx;
471 sec = local_sections [r_symndx];
472 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
473
474 name = bfd_elf_string_from_elf_section
475 (input_bfd, symtab_hdr->sh_link, sym->st_name);
476 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
d9352518
DB
477 }
478 else
479 {
62d887d4 480 bfd_boolean warned, unresolved_reloc, ignored;
d9352518 481
0f02bbd9
AM
482 RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
483 r_symndx, symtab_hdr, sym_hashes,
484 h, sec, relocation,
62d887d4 485 unresolved_reloc, warned, ignored);
d9352518
DB
486
487 name = h->root.root.string;
d9352518
DB
488 }
489
dbaa2011 490 if (sec != NULL && discarded_section (sec))
e4067dbb 491 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 492 rel, 1, relend, howto, 0, contents);
ab96bf03 493
0e1862bb 494 if (bfd_link_relocatable (info))
0f02bbd9 495 continue;
ab96bf03 496
cdfeee4f
AM
497 if (r_type == R_RELC)
498 r = bfd_elf_perform_complex_relocation (input_bfd, input_section,
499 contents, rel, relocation);
500 else
501 r = mep_final_link_relocate (howto, input_bfd, input_section,
502 contents, rel, relocation);
d9352518
DB
503
504 if (r != bfd_reloc_ok)
505 {
506 const char * msg = (const char *) NULL;
507
508 switch (r)
509 {
510 case bfd_reloc_overflow:
511 r = info->callbacks->reloc_overflow
512 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
513 input_bfd, input_section, rel->r_offset);
514 break;
515
516 case bfd_reloc_undefined:
517 r = info->callbacks->undefined_symbol
518 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
519 break;
520
521 case bfd_reloc_outofrange:
522 msg = _("internal error: out of range error");
523 break;
524
525 case bfd_reloc_notsupported:
526 msg = _("internal error: unsupported relocation error");
527 break;
528
529 case bfd_reloc_dangerous:
530 msg = _("internal error: dangerous relocation");
531 break;
532
533 default:
534 msg = _("internal error: unknown error");
535 break;
536 }
537
538 if (msg)
539 r = info->callbacks->warning
540 (info, msg, name, input_bfd, input_section, rel->r_offset);
541
542 if (! r)
543 return FALSE;
544 }
545 }
546
547 if (warn_tp)
548 info->callbacks->undefined_symbol
549 (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
550 if (warn_sda)
551 info->callbacks->undefined_symbol
552 (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
553 if (warn_sda || warn_tp)
554 return FALSE;
555
556 return TRUE;
557}
d9352518
DB
558\f
559/* Function to set the ELF flag bits. */
560
561static bfd_boolean
562mep_elf_set_private_flags (bfd * abfd,
563 flagword flags)
564{
565 elf_elfheader (abfd)->e_flags = flags;
566 elf_flags_init (abfd) = TRUE;
567 return TRUE;
568}
569
d9352518
DB
570/* Merge backend specific data from an object file to the output
571 object file when linking. */
572
573static bfd_boolean
574mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
575{
576 static bfd *last_ibfd = 0;
577 flagword old_flags, new_flags;
578 flagword old_partial, new_partial;
579
cc643b88 580 /* Check if we have the same endianness. */
d9352518
DB
581 if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
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 _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
620 bfd_set_error (bfd_error_invalid_target);
621 return FALSE;
622 }
623
624 /* Make sure they're for the same me_module. Allow basic config to
625 mix with any other. */
626 new_partial = (new_flags & EF_MEP_INDEX_MASK);
627 old_partial = (old_flags & EF_MEP_INDEX_MASK);
628 if (new_partial == old_partial)
629 ;
630 else if (new_partial == 0)
631 ;
632 else if (old_partial == 0)
633 old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
634 else
635 {
636 _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
637 bfd_set_error (bfd_error_invalid_target);
638 return FALSE;
639 }
640 }
641
642 elf_elfheader (obfd)->e_flags = old_flags;
643 last_ibfd = ibfd;
644 return TRUE;
645}
646
647/* This will be edited by the MeP configration tool. */
648static const char * config_names[] =
649{
650 "basic"
651 /* start-mepcfgtool */
c1a0a41f 652 ,"default"
d9352518
DB
653 /* end-mepcfgtool */
654};
655
656static const char * core_names[] =
657{
658 "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
659};
660
661static bfd_boolean
662mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
663{
664 FILE * file = (FILE *) ptr;
665 flagword flags, partial_flags;
666
667 BFD_ASSERT (abfd != NULL && ptr != NULL);
668
669 /* Print normal ELF private data. */
670 _bfd_elf_print_private_bfd_data (abfd, ptr);
671
672 flags = elf_elfheader (abfd)->e_flags;
0af1713e 673 fprintf (file, _("private flags = 0x%lx"), (unsigned long) flags);
d9352518
DB
674
675 partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
676 if (partial_flags < ARRAY_SIZE (core_names))
677 fprintf (file, " core: %s", core_names[(long)partial_flags]);
678
679 partial_flags = flags & EF_MEP_INDEX_MASK;
680 if (partial_flags < ARRAY_SIZE (config_names))
681 fprintf (file, " me_module: %s", config_names[(long)partial_flags]);
682
683 fputc ('\n', file);
684
685 return TRUE;
686}
687
688/* Return the machine subcode from the ELF e_flags header. */
689
690static int
691elf32_mep_machine (bfd * abfd)
692{
693 switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
694 {
695 default: break;
696 case EF_MEP_CPU_C2: return bfd_mach_mep;
697 case EF_MEP_CPU_C3: return bfd_mach_mep;
698 case EF_MEP_CPU_C4: return bfd_mach_mep;
4d28413b 699 case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
d9352518
DB
700 case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
701 }
702
703 return bfd_mach_mep;
704}
705
706static bfd_boolean
707mep_elf_object_p (bfd * abfd)
708{
d9352518
DB
709 bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
710 return TRUE;
711}
712
713static bfd_boolean
714mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
715{
716 if (hdr->sh_flags & SHF_MEP_VLIW)
717 * flags |= SEC_MEP_VLIW;
718 return TRUE;
719}
720
721static bfd_boolean
722mep_elf_fake_sections (bfd * abfd ATTRIBUTE_UNUSED,
723 Elf_Internal_Shdr * hdr,
724 asection * sec)
725{
726 if (sec->flags & SEC_MEP_VLIW)
727 hdr->sh_flags |= SHF_MEP_VLIW;
728 return TRUE;
729}
730
731\f
732#define ELF_ARCH bfd_arch_mep
733#define ELF_MACHINE_CODE EM_CYGNUS_MEP
734#define ELF_MAXPAGESIZE 0x1000
735
6d00b590 736#define TARGET_BIG_SYM mep_elf32_vec
d9352518
DB
737#define TARGET_BIG_NAME "elf32-mep"
738
6d00b590 739#define TARGET_LITTLE_SYM mep_elf32_le_vec
d9352518
DB
740#define TARGET_LITTLE_NAME "elf32-mep-little"
741
742#define elf_info_to_howto_rel NULL
743#define elf_info_to_howto mep_info_to_howto_rela
744#define elf_backend_relocate_section mep_elf_relocate_section
d9352518
DB
745#define elf_backend_object_p mep_elf_object_p
746#define elf_backend_section_flags mep_elf_section_flags
747#define elf_backend_fake_sections mep_elf_fake_sections
748
d9352518 749#define bfd_elf32_bfd_reloc_type_lookup mep_reloc_type_lookup
0f02bbd9 750#define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup
d9352518 751#define bfd_elf32_bfd_set_private_flags mep_elf_set_private_flags
d9352518
DB
752#define bfd_elf32_bfd_merge_private_bfd_data mep_elf_merge_private_bfd_data
753#define bfd_elf32_bfd_print_private_bfd_data mep_elf_print_private_bfd_data
754
0f02bbd9 755#define elf_backend_rela_normal 1
d9352518
DB
756
757#include "elf32-target.h"
This page took 0.501624 seconds and 4 git commands to generate.