1 /* MeP-specific support for 32-bit ELF.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
26 #include "libiberty.h"
28 /* Forward declarations. */
30 /* Private relocation functions. */
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 }
35 #define N complain_overflow_dont
36 #define S complain_overflow_signed
37 #define U complain_overflow_unsigned
39 static bfd_reloc_status_type
mep_reloc (bfd
*, arelent
*, struct bfd_symbol
*,
40 void *, asection
*, bfd
*, char **);
42 static reloc_howto_type mep_elf_howto_table
[] =
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),
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),
72 #define VALID_MEP_RELOC(N) ((N) >= 0 \
73 && (N) < ARRAY_SIZE (mep_elf_howto_table)
79 static bfd_reloc_status_type
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
)
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
98 #define MAP(n) case BFD_RELOC_MEP_/**/n: type = R_MEP_/**/n; break
101 static reloc_howto_type
*
102 mep_reloc_type_lookup
103 (bfd
* abfd ATTRIBUTE_UNUSED
,
104 bfd_reloc_code_real_type code
)
106 unsigned int type
= 0;
120 case BFD_RELOC_VTABLE_ENTRY
:
121 type
= R_MEP_GNU_VTENTRY
;
123 case BFD_RELOC_VTABLE_INHERIT
:
124 type
= R_MEP_GNU_VTINHERIT
;
131 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
155 /* Pacify gcc -Wall. */
156 fprintf (stderr
, "mep: no reloc for code %d\n", code
);
160 if (mep_elf_howto_table
[type
].type
!= type
)
162 fprintf (stderr
, "MeP: howto %d has type %d\n", type
, mep_elf_howto_table
[type
].type
);
166 return mep_elf_howto_table
+ type
;
172 /* Perform a single relocation. */
174 static struct bfd_link_info
*mep_info
;
175 static int warn_tp
= 0, warn_sda
= 0;
184 struct bfd_link_hash_entry
*h
;
189 h
= bfd_link_hash_lookup (mep_info
->hash
, name
, FALSE
, FALSE
, TRUE
);
190 if (h
== 0 || h
->type
!= bfd_link_hash_defined
)
195 *cache
= (h
->u
.def
.value
196 + h
->u
.def
.section
->output_section
->vma
197 + h
->u
.def
.section
->output_offset
);
202 mep_tpoff_base (bfd_vma ofs
)
204 static bfd_vma cache
= 0;
205 return mep_lookup_global ("__tpbase", ofs
, &cache
, &warn_tp
);
209 mep_sdaoff_base (bfd_vma ofs
)
211 static bfd_vma cache
= 0;
212 return mep_lookup_global ("__sdabase", ofs
, &cache
, &warn_sda
);
215 static bfd_reloc_status_type
216 mep_final_link_relocate
217 (reloc_howto_type
* howto
,
219 asection
* input_section
,
221 Elf_Internal_Rela
* rel
,
228 bfd_reloc_status_type r
= bfd_reloc_ok
;
231 if (bfd_big_endian (input_bfd
))
242 pc
= (input_section
->output_section
->vma
243 + input_section
->output_offset
246 s
= relocation
+ rel
->r_addend
;
248 byte
= (unsigned char *)contents
+ rel
->r_offset
;
250 if (howto
->type
== R_MEP_PCREL24A2
254 /* This is an unreachable branch to an undefined weak function.
255 Silently ignore it, since the opcode can't do that but should
256 never be executed anyway. */
260 if (howto
->pc_relative
)
263 u
= (unsigned long) s
;
268 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
269 case R_MEP_8
: /* 76543210 */
270 if (u
> 255) r
= bfd_reloc_overflow
;
271 byte
[0] = (u
& 0xff);
273 case R_MEP_16
: /* fedcba9876543210 */
274 if (u
> 65535) r
= bfd_reloc_overflow
;
275 byte
[0^e2
] = ((u
>> 8) & 0xff);
276 byte
[1^e2
] = (u
& 0xff);
278 case R_MEP_32
: /* vutsrqponmlkjihgfedcba9876543210 */
279 byte
[0^e4
] = ((u
>> 24) & 0xff);
280 byte
[1^e4
] = ((u
>> 16) & 0xff);
281 byte
[2^e4
] = ((u
>> 8) & 0xff);
282 byte
[3^e4
] = (u
& 0xff);
284 case R_MEP_PCREL8A2
: /* --------7654321- */
285 if (-128 > s
|| s
> 127) r
= bfd_reloc_overflow
;
286 byte
[1^e2
] = (byte
[1^e2
] & 0x01) | (s
& 0xfe);
288 case R_MEP_PCREL12A2
: /* ----ba987654321- */
289 if (-2048 > s
|| s
> 2047) r
= bfd_reloc_overflow
;
290 byte
[0^e2
] = (byte
[0^e2
] & 0xf0) | ((s
>> 8) & 0x0f);
291 byte
[1^e2
] = (byte
[1^e2
] & 0x01) | (s
& 0xfe);
293 case R_MEP_PCREL17A2
: /* ----------------gfedcba987654321 */
294 if (-65536 > s
|| s
> 65535) r
= bfd_reloc_overflow
;
295 byte
[2^e2
] = ((s
>> 9) & 0xff);
296 byte
[3^e2
] = ((s
>> 1) & 0xff);
298 case R_MEP_PCREL24A2
: /* -----7654321----nmlkjihgfedcba98 */
299 if (-8388608 > s
|| s
> 8388607) r
= bfd_reloc_overflow
;
300 byte
[0^e2
] = (byte
[0^e2
] & 0xf8) | ((s
>> 5) & 0x07);
301 byte
[1^e2
] = (byte
[1^e2
] & 0x0f) | ((s
<< 3) & 0xf0);
302 byte
[2^e2
] = ((s
>> 16) & 0xff);
303 byte
[3^e2
] = ((s
>> 8) & 0xff);
305 case R_MEP_PCABS24A2
: /* -----7654321----nmlkjihgfedcba98 */
306 if (u
> 16777215) r
= bfd_reloc_overflow
;
307 byte
[0^e2
] = (byte
[0^e2
] & 0xf8) | ((u
>> 5) & 0x07);
308 byte
[1^e2
] = (byte
[1^e2
] & 0x0f) | ((u
<< 3) & 0xf0);
309 byte
[2^e2
] = ((u
>> 16) & 0xff);
310 byte
[3^e2
] = ((u
>> 8) & 0xff);
312 case R_MEP_LOW16
: /* ----------------fedcba9876543210 */
313 byte
[2^e2
] = ((u
>> 8) & 0xff);
314 byte
[3^e2
] = (u
& 0xff);
316 case R_MEP_HI16U
: /* ----------------vutsrqponmlkjihg */
317 byte
[2^e2
] = ((u
>> 24) & 0xff);
318 byte
[3^e2
] = ((u
>> 16) & 0xff);
320 case R_MEP_HI16S
: /* ----------------vutsrqponmlkjihg */
321 byte
[2^e2
] = ((s
>> 24) & 0xff);
322 byte
[3^e2
] = ((s
>> 16) & 0xff);
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);
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);
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);
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);
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);
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);
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);
363 case R_MEP_GNU_VTINHERIT
: /* ---------------- */
365 case R_MEP_GNU_VTENTRY
: /* ---------------- */
375 /* Set the howto pointer for a MEP ELF reloc. */
378 mep_info_to_howto_rela
379 (bfd
* abfd ATTRIBUTE_UNUSED
,
381 Elf_Internal_Rela
* dst
)
385 r_type
= ELF32_R_TYPE (dst
->r_info
);
386 cache_ptr
->howto
= & mep_elf_howto_table
[r_type
];
389 /* Look through the relocs for a section during the first phase.
390 Since we don't do .gots or .plts, we just need to consider the
391 virtual table relocs for gc. */
396 struct bfd_link_info
* info
,
398 const Elf_Internal_Rela
* relocs
)
400 Elf_Internal_Shdr
* symtab_hdr
;
401 struct elf_link_hash_entry
** sym_hashes
;
402 struct elf_link_hash_entry
** sym_hashes_end
;
403 const Elf_Internal_Rela
* rel
;
404 const Elf_Internal_Rela
* rel_end
;
406 if (info
->relocatable
)
409 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
410 sym_hashes
= elf_sym_hashes (abfd
);
411 sym_hashes_end
= sym_hashes
+ symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
);
412 if (!elf_bad_symtab (abfd
))
413 sym_hashes_end
-= symtab_hdr
->sh_info
;
415 rel_end
= relocs
+ sec
->reloc_count
;
416 for (rel
= relocs
; rel
< rel_end
; rel
++)
418 struct elf_link_hash_entry
*h
;
419 unsigned long r_symndx
;
421 r_symndx
= ELF32_R_SYM (rel
->r_info
);
422 if (r_symndx
< symtab_hdr
->sh_info
)
425 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
431 /* Relocate a MEP ELF section.
432 There is some attempt to make this function usable for many architectures,
433 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
434 if only to serve as a learning tool.
436 The RELOCATE_SECTION function is called by the new ELF backend linker
437 to handle the relocations for a section.
439 The relocs are always passed as Rela structures; if the section
440 actually uses Rel structures, the r_addend field will always be
443 This function is responsible for adjusting the section contents as
444 necessary, and (if using Rela relocs and generating a relocatable
445 output file) adjusting the reloc addend as necessary.
447 This function does not have to worry about setting the reloc
448 address or the reloc symbol index.
450 LOCAL_SYMS is a pointer to the swapped in local symbols.
452 LOCAL_SECTIONS is an array giving the section in the input file
453 corresponding to the st_shndx field of each local symbol.
455 The global hash table entry for the global symbols can be found
456 via elf_sym_hashes (input_bfd).
458 When generating relocatable output, this function must handle
459 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
460 going to be the section symbol corresponding to the output
461 section, which means that the addend must be adjusted
465 mep_elf_relocate_section
466 (bfd
* output_bfd ATTRIBUTE_UNUSED
,
467 struct bfd_link_info
* info
,
469 asection
* input_section
,
471 Elf_Internal_Rela
* relocs
,
472 Elf_Internal_Sym
* local_syms
,
473 asection
** local_sections
)
475 Elf_Internal_Shdr
* symtab_hdr
;
476 struct elf_link_hash_entry
** sym_hashes
;
477 Elf_Internal_Rela
* rel
;
478 Elf_Internal_Rela
* relend
;
480 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
481 sym_hashes
= elf_sym_hashes (input_bfd
);
482 relend
= relocs
+ input_section
->reloc_count
;
486 for (rel
= relocs
; rel
< relend
; rel
++)
488 reloc_howto_type
* howto
;
489 unsigned long r_symndx
;
490 Elf_Internal_Sym
* sym
;
492 struct elf_link_hash_entry
* h
;
494 bfd_reloc_status_type r
;
495 const char * name
= NULL
;
498 r_type
= ELF32_R_TYPE (rel
->r_info
);
500 r_symndx
= ELF32_R_SYM (rel
->r_info
);
502 if (info
->relocatable
)
504 /* This is a relocatable link. We don't have to change
505 anything, unless the reloc is against a section symbol,
506 in which case we have to adjust according to where the
507 section symbol winds up in the output section. */
508 if (r_symndx
< symtab_hdr
->sh_info
)
510 sym
= local_syms
+ r_symndx
;
512 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
514 sec
= local_sections
[r_symndx
];
515 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
522 /* Is this a complex relocation? */
523 if (ELF32_R_TYPE (rel
->r_info
) == R_RELC
)
525 bfd_elf_perform_complex_relocation (output_bfd
, info
,
526 input_bfd
, input_section
, contents
,
527 rel
, local_syms
, local_sections
);
531 /* This is a final link. */
532 howto
= mep_elf_howto_table
+ ELF32_R_TYPE (rel
->r_info
);
537 if (r_symndx
< symtab_hdr
->sh_info
)
539 sym
= local_syms
+ r_symndx
;
540 sec
= local_sections
[r_symndx
];
541 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
543 name
= bfd_elf_string_from_elf_section
544 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
545 name
= (name
== NULL
) ? bfd_section_name (input_bfd
, sec
) : name
;
547 fprintf (stderr
, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
548 sec
->name
, name
, sym
->st_name
,
549 sec
->output_section
->vma
, sec
->output_offset
,
550 sym
->st_value
, rel
->r_addend
);
555 h
= sym_hashes
[r_symndx
];
557 while (h
->root
.type
== bfd_link_hash_indirect
558 || h
->root
.type
== bfd_link_hash_warning
)
559 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
561 name
= h
->root
.root
.string
;
563 if (h
->root
.type
== bfd_link_hash_defined
564 || h
->root
.type
== bfd_link_hash_defweak
)
566 sec
= h
->root
.u
.def
.section
;
567 relocation
= (h
->root
.u
.def
.value
568 + sec
->output_section
->vma
569 + sec
->output_offset
);
572 "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
573 sec
->name
, name
, h
->root
.u
.def
.value
,
574 sec
->output_section
->vma
, sec
->output_offset
, relocation
);
577 else if (h
->root
.type
== bfd_link_hash_undefweak
)
580 fprintf (stderr
, "undefined: sec: %s, name: %s\n",
587 if (! ((*info
->callbacks
->undefined_symbol
)
588 (info
, h
->root
.root
.string
, input_bfd
,
589 input_section
, rel
->r_offset
,
590 (!info
->shared
&& info
->unresolved_syms_in_objects
== RM_GENERATE_ERROR
))))
593 fprintf (stderr
, "unknown: name: %s\n", name
);
602 r
= mep_final_link_relocate (howto
, input_bfd
, input_section
,
603 contents
, rel
, relocation
);
607 if (r
!= bfd_reloc_ok
)
609 const char * msg
= (const char *) NULL
;
613 case bfd_reloc_overflow
:
614 r
= info
->callbacks
->reloc_overflow
615 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
, (bfd_vma
) 0,
616 input_bfd
, input_section
, rel
->r_offset
);
619 case bfd_reloc_undefined
:
620 r
= info
->callbacks
->undefined_symbol
621 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, TRUE
);
624 case bfd_reloc_outofrange
:
625 msg
= _("internal error: out of range error");
628 case bfd_reloc_notsupported
:
629 msg
= _("internal error: unsupported relocation error");
632 case bfd_reloc_dangerous
:
633 msg
= _("internal error: dangerous relocation");
637 msg
= _("internal error: unknown error");
642 r
= info
->callbacks
->warning
643 (info
, msg
, name
, input_bfd
, input_section
, rel
->r_offset
);
651 info
->callbacks
->undefined_symbol
652 (info
, "__tpbase", input_bfd
, input_section
, warn_tp
-1, TRUE
);
654 info
->callbacks
->undefined_symbol
655 (info
, "__sdabase", input_bfd
, input_section
, warn_sda
-1, TRUE
);
656 if (warn_sda
|| warn_tp
)
663 /* Update the got entry reference counts for the section being
667 mep_elf_gc_sweep_hook
668 (bfd
* abfd ATTRIBUTE_UNUSED
,
669 struct bfd_link_info
* info ATTRIBUTE_UNUSED
,
670 asection
* sec ATTRIBUTE_UNUSED
,
671 const Elf_Internal_Rela
* relocs ATTRIBUTE_UNUSED
)
676 /* Return the section that should be marked against GC for a given
682 struct bfd_link_info
* info ATTRIBUTE_UNUSED
,
683 Elf_Internal_Rela
* rel
,
684 struct elf_link_hash_entry
* h
,
685 Elf_Internal_Sym
* sym
)
689 switch (ELF32_R_TYPE (rel
->r_info
))
692 switch (h
->root
.type
)
694 case bfd_link_hash_defined
:
695 case bfd_link_hash_defweak
:
696 return h
->root
.u
.def
.section
;
698 case bfd_link_hash_common
:
699 return h
->root
.u
.c
.p
->section
;
708 if (!(elf_bad_symtab (sec
->owner
)
709 && ELF_ST_BIND (sym
->st_info
) != STB_LOCAL
)
710 && ! ((sym
->st_shndx
<= 0 || sym
->st_shndx
>= SHN_LORESERVE
)
711 && sym
->st_shndx
!= SHN_COMMON
))
712 return bfd_section_from_elf_index (sec
->owner
, sym
->st_shndx
);
719 /* Function to set the ELF flag bits. */
722 mep_elf_set_private_flags (bfd
* abfd
,
725 elf_elfheader (abfd
)->e_flags
= flags
;
726 elf_flags_init (abfd
) = TRUE
;
731 mep_elf_copy_private_bfd_data (bfd
* ibfd
, bfd
* obfd
)
733 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
734 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
737 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
738 elf_flags_init (obfd
) = TRUE
;
742 /* Merge backend specific data from an object file to the output
743 object file when linking. */
746 mep_elf_merge_private_bfd_data (bfd
* ibfd
, bfd
* obfd
)
748 static bfd
*last_ibfd
= 0;
749 flagword old_flags
, new_flags
;
750 flagword old_partial
, new_partial
;
752 /* Check if we have the same endianess. */
753 if (_bfd_generic_verify_endian_match (ibfd
, obfd
) == FALSE
)
756 new_flags
= elf_elfheader (ibfd
)->e_flags
;
757 old_flags
= elf_elfheader (obfd
)->e_flags
;
760 _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
761 ibfd
, old_flags
, new_flags
, elf_flags_init (obfd
) ? "yes" : "no");
764 /* First call, no flags set. */
765 if (!elf_flags_init (obfd
))
767 elf_flags_init (obfd
) = TRUE
;
768 old_flags
= new_flags
;
770 else if ((new_flags
| old_flags
) & EF_MEP_LIBRARY
)
772 /* Non-library flags trump library flags. The choice doesn't really
773 matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set. */
774 if (old_flags
& EF_MEP_LIBRARY
)
775 old_flags
= new_flags
;
779 /* Make sure they're for the same mach. Allow upgrade from the "mep"
781 new_partial
= (new_flags
& EF_MEP_CPU_MASK
);
782 old_partial
= (old_flags
& EF_MEP_CPU_MASK
);
783 if (new_partial
== old_partial
)
785 else if (new_partial
== EF_MEP_CPU_MEP
)
787 else if (old_partial
== EF_MEP_CPU_MEP
)
788 old_flags
= (old_flags
& ~EF_MEP_CPU_MASK
) | new_partial
;
791 _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd
, ibfd
);
792 bfd_set_error (bfd_error_invalid_target
);
796 /* Make sure they're for the same me_module. Allow basic config to
797 mix with any other. */
798 new_partial
= (new_flags
& EF_MEP_INDEX_MASK
);
799 old_partial
= (old_flags
& EF_MEP_INDEX_MASK
);
800 if (new_partial
== old_partial
)
802 else if (new_partial
== 0)
804 else if (old_partial
== 0)
805 old_flags
= (old_flags
& ~EF_MEP_INDEX_MASK
) | new_partial
;
808 _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd
, ibfd
);
809 bfd_set_error (bfd_error_invalid_target
);
814 elf_elfheader (obfd
)->e_flags
= old_flags
;
819 /* This will be edited by the MeP configration tool. */
820 static const char * config_names
[] =
823 /* start-mepcfgtool */
829 static const char * core_names
[] =
831 "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
835 mep_elf_print_private_bfd_data (bfd
* abfd
, void * ptr
)
837 FILE * file
= (FILE *) ptr
;
838 flagword flags
, partial_flags
;
840 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
842 /* Print normal ELF private data. */
843 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
845 flags
= elf_elfheader (abfd
)->e_flags
;
846 fprintf (file
, _("private flags = 0x%lx"), (long)flags
);
848 partial_flags
= (flags
& EF_MEP_CPU_MASK
) >> 24;
849 if (partial_flags
< ARRAY_SIZE (core_names
))
850 fprintf (file
, " core: %s", core_names
[(long)partial_flags
]);
852 partial_flags
= flags
& EF_MEP_INDEX_MASK
;
853 if (partial_flags
< ARRAY_SIZE (config_names
))
854 fprintf (file
, " me_module: %s", config_names
[(long)partial_flags
]);
861 /* Return the machine subcode from the ELF e_flags header. */
864 elf32_mep_machine (bfd
* abfd
)
866 switch (elf_elfheader (abfd
)->e_flags
& EF_MEP_CPU_MASK
)
869 case EF_MEP_CPU_C2
: return bfd_mach_mep
;
870 case EF_MEP_CPU_C3
: return bfd_mach_mep
;
871 case EF_MEP_CPU_C4
: return bfd_mach_mep
;
872 case EF_MEP_CPU_H1
: return bfd_mach_mep_h1
;
879 mep_elf_object_p (bfd
* abfd
)
881 /* Irix 5 and 6 is broken. Object file symbol tables are not always
882 sorted correctly such that local symbols preceed global symbols,
883 and the sh_info field in the symbol table is not always right. */
884 /* This is needed for the RELC support code. */
885 elf_bad_symtab (abfd
) = TRUE
;
886 bfd_default_set_arch_mach (abfd
, bfd_arch_mep
, elf32_mep_machine (abfd
));
891 mep_elf_section_flags (flagword
* flags
, const Elf_Internal_Shdr
* hdr
)
893 if (hdr
->sh_flags
& SHF_MEP_VLIW
)
894 * flags
|= SEC_MEP_VLIW
;
899 mep_elf_fake_sections (bfd
* abfd ATTRIBUTE_UNUSED
,
900 Elf_Internal_Shdr
* hdr
,
903 if (sec
->flags
& SEC_MEP_VLIW
)
904 hdr
->sh_flags
|= SHF_MEP_VLIW
;
909 #define ELF_ARCH bfd_arch_mep
910 #define ELF_MACHINE_CODE EM_CYGNUS_MEP
911 #define ELF_MAXPAGESIZE 0x1000
913 #define TARGET_BIG_SYM bfd_elf32_mep_vec
914 #define TARGET_BIG_NAME "elf32-mep"
916 #define TARGET_LITTLE_SYM bfd_elf32_mep_little_vec
917 #define TARGET_LITTLE_NAME "elf32-mep-little"
919 #define elf_info_to_howto_rel NULL
920 #define elf_info_to_howto mep_info_to_howto_rela
921 #define elf_backend_relocate_section mep_elf_relocate_section
922 #define elf_backend_gc_mark_hook mep_elf_gc_mark_hook
923 #define elf_backend_gc_sweep_hook mep_elf_gc_sweep_hook
924 #define elf_backend_check_relocs mep_elf_check_relocs
925 #define elf_backend_object_p mep_elf_object_p
926 #define elf_backend_section_flags mep_elf_section_flags
927 #define elf_backend_fake_sections mep_elf_fake_sections
929 #define elf_backend_can_gc_sections 1
931 #define bfd_elf32_bfd_reloc_type_lookup mep_reloc_type_lookup
932 #define bfd_elf32_bfd_set_private_flags mep_elf_set_private_flags
933 #define bfd_elf32_bfd_copy_private_bfd_data mep_elf_copy_private_bfd_data
934 #define bfd_elf32_bfd_merge_private_bfd_data mep_elf_merge_private_bfd_data
935 #define bfd_elf32_bfd_print_private_bfd_data mep_elf_print_private_bfd_data
937 /* We use only the RELA entries. */
940 #include "elf32-target.h"