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