sim: sh64: delete dv-sockser references
[deliverable/binutils-gdb.git] / bfd / elf32-mep.c
CommitLineData
d9352518 1/* MeP-specific support for 32-bit ELF.
b90efa5b 2 Copyright (C) 2001-2015 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) \
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
39static bfd_reloc_status_type mep_reloc (bfd *, arelent *, struct bfd_symbol *,
40 void *, asection *, bfd *, char **);
41
42static reloc_howto_type mep_elf_howto_table [] =
43{
44 /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask. */
6346d5ca 45 MEPREL (R_MEP_NONE, 3, 0, 0, 0, 0, N, 0),
d9352518
DB
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
79static bfd_reloc_status_type
80mep_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
101static reloc_howto_type *
102mep_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. */
4a97a0e5 156 (*_bfd_error_handler) (_("mep: no reloc for code %d"), code);
d9352518
DB
157 return NULL;
158 }
159
160 if (mep_elf_howto_table[type].type != type)
161 {
4a97a0e5
AM
162 (*_bfd_error_handler) (_("MeP: howto %d has type %d"),
163 type, mep_elf_howto_table[type].type);
d9352518
DB
164 abort ();
165 }
166
167 return mep_elf_howto_table + type;
168}
169
170#undef MAP
171
157090f7
AM
172static reloc_howto_type *
173mep_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}
d9352518
DB
186\f
187/* Perform a single relocation. */
188
189static struct bfd_link_info *mep_info;
190static int warn_tp = 0, warn_sda = 0;
191
192static bfd_vma
193mep_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
216static bfd_vma
217mep_tpoff_base (bfd_vma ofs)
218{
219 static bfd_vma cache = 0;
220 return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
221}
222
223static bfd_vma
224mep_sdaoff_base (bfd_vma ofs)
225{
226 static bfd_vma cache = 0;
227 return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
228}
229
230static bfd_reloc_status_type
231mep_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 */
b4928193
NC
336 if (s & 0x8000)
337 s += 0x10000;
d9352518
DB
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
394static void
395mep_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);
5860e3f8
NC
403 if (r_type >= R_MEP_max)
404 {
64d29018 405 _bfd_error_handler (_("%B: invalid MEP reloc number: %d"), abfd, r_type);
5860e3f8
NC
406 r_type = 0;
407 }
d9352518
DB
408 cache_ptr->howto = & mep_elf_howto_table [r_type];
409}
d9352518
DB
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
444static bfd_boolean
445mep_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);
d9352518 479 r_symndx = ELF32_R_SYM (rel->r_info);
d9352518
DB
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;
d9352518
DB
494 }
495 else
496 {
62d887d4 497 bfd_boolean warned, unresolved_reloc, ignored;
d9352518 498
0f02bbd9
AM
499 RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
500 r_symndx, symtab_hdr, sym_hashes,
501 h, sec, relocation,
62d887d4 502 unresolved_reloc, warned, ignored);
d9352518
DB
503
504 name = h->root.root.string;
d9352518
DB
505 }
506
dbaa2011 507 if (sec != NULL && discarded_section (sec))
e4067dbb 508 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 509 rel, 1, relend, howto, 0, contents);
ab96bf03
AM
510
511 if (info->relocatable)
0f02bbd9 512 continue;
ab96bf03 513
cdfeee4f
AM
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);
d9352518
DB
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}
d9352518
DB
575\f
576/* Function to set the ELF flag bits. */
577
578static bfd_boolean
579mep_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
d9352518
DB
587/* Merge backend specific data from an object file to the output
588 object file when linking. */
589
590static bfd_boolean
591mep_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
cc643b88 597 /* Check if we have the same endianness. */
d9352518
DB
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. */
665static const char * config_names[] =
666{
667 "basic"
668 /* start-mepcfgtool */
c1a0a41f 669 ,"default"
d9352518
DB
670 /* end-mepcfgtool */
671};
672
673static const char * core_names[] =
674{
675 "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
676};
677
678static bfd_boolean
679mep_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;
0af1713e 690 fprintf (file, _("private flags = 0x%lx"), (unsigned long) flags);
d9352518
DB
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
707static int
708elf32_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;
4d28413b 716 case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
d9352518
DB
717 case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
718 }
719
720 return bfd_mach_mep;
721}
722
723static bfd_boolean
724mep_elf_object_p (bfd * abfd)
725{
d9352518
DB
726 bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
727 return TRUE;
728}
729
730static bfd_boolean
731mep_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
738static bfd_boolean
739mep_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
6d00b590 753#define TARGET_BIG_SYM mep_elf32_vec
d9352518
DB
754#define TARGET_BIG_NAME "elf32-mep"
755
6d00b590 756#define TARGET_LITTLE_SYM mep_elf32_le_vec
d9352518
DB
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
d9352518
DB
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
d9352518 766#define bfd_elf32_bfd_reloc_type_lookup mep_reloc_type_lookup
0f02bbd9 767#define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup
d9352518 768#define bfd_elf32_bfd_set_private_flags mep_elf_set_private_flags
d9352518
DB
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
0f02bbd9 772#define elf_backend_rela_normal 1
d9352518
DB
773
774#include "elf32-target.h"
This page took 0.441337 seconds and 4 git commands to generate.