* config.bfd: Support crisv32-*-* like cris-*-*.
* archures.c (bfd_mach_cris_v0_v10, bfd_mach_cris_v32) (bfd_mach_cris_v10_v32): New macros. * cpu-cris.c: Tweak formatting. (get_compatible): New function. (N): New macro. (bfd_cris_arch_compat_v10_v32, bfd_cris_arch_v32): New bfd_arch_info_type:s. (bfd_cris_arch): Use bfd_mach_cris_v0_v10 for member mach, get_compatible for member compatible and link bfd_cris_arch_v32 as next. * elf32-cris.c (cris_elf_pcrel_reloc) (cris_elf_set_mach_from_flags): New functions. (cris_elf_howto_table) <R_CRIS_8_PCREL, R_CRIS_16_PCREL> <R_CRIS_32_PCREL>: Use cris_elf_pcrel_reloc. (cris_elf_grok_prstatus, cris_elf_grok_psinfo): Give correct numbers for bfd_mach_cris_v32. (PLT_ENTRY_SIZE_V32): New macro. (elf_cris_plt0_entry): Drop last comma in initializer. (elf_cris_plt0_entry_v32, elf_cris_plt_entry_v32) (elf_cris_pic_plt0_entry_v32, elf_cris_pic_plt_entry_v32): New PLT initializers. (cris_elf_relocate_section): Change all "%B(%A)" messages to "%B, section %A". (elf_cris_finish_dynamic_symbol): Do V32-specific PLT entries. (elf_cris_finish_dynamic_sections): Similar. (elf_cris_adjust_dynamic_symbol): Similar. (cris_elf_check_relocs): Change all "%B(%A)" messages to "%B, section %A". <switch with PIC relocs>: Emit error and return FALSE for bfd_mach_cris_v10_v32. <case R_CRIS_8_PCREL, case R_CRIS_16_PCREL, case R_CRIS_32_PCREL>: Emit warning when generating textrel reloc. (cris_elf_object_p): Call cris_elf_set_mach_from_flags. (cris_elf_final_write_processing): Set flags according to mach. (cris_elf_print_private_bfd_data): Display EF_CRIS_VARIANT_COMMON_V10_V32 and EF_CRIS_VARIANT_V32. (cris_elf_merge_private_bfd_data): Drop variables old_flags, new_flags. Don't call cris_elf_final_write_processing. Don't look at the actual elf header flags at all; use bfd_get_symbol_leading_char to check ibfd, obfd. Trap difference in bfd_get_mach for ibfd and obfd and handle merging of compatible objects. (bfd_elf32_bfd_copy_private_bfd_data): Define. * reloc.c (BFD_RELOC_CRIS_SIGNED_8, BFD_RELOC_CRIS_UNSIGNED_8) (BFD_RELOC_CRIS_SIGNED_16, BFD_RELOC_CRIS_UNSIGNED_16) (BFD_RELOC_CRIS_LAPCQ_OFFSET): New relocs. * bfd-in2.h, libbfd.h: Regenerate.
This commit is contained in:
parent
bd21e58e63
commit
bac23f82ae
@ -1,3 +1,54 @@
|
||||
2004-11-04 Hans-Peter Nilsson <hp@axis.com>
|
||||
|
||||
* config.bfd: Support crisv32-*-* like cris-*-*.
|
||||
* archures.c (bfd_mach_cris_v0_v10, bfd_mach_cris_v32)
|
||||
(bfd_mach_cris_v10_v32): New macros.
|
||||
* cpu-cris.c: Tweak formatting.
|
||||
(get_compatible): New function.
|
||||
(N): New macro.
|
||||
(bfd_cris_arch_compat_v10_v32, bfd_cris_arch_v32): New
|
||||
bfd_arch_info_type:s.
|
||||
(bfd_cris_arch): Use bfd_mach_cris_v0_v10 for member mach,
|
||||
get_compatible for member compatible and link bfd_cris_arch_v32 as
|
||||
next.
|
||||
* elf32-cris.c (cris_elf_pcrel_reloc)
|
||||
(cris_elf_set_mach_from_flags): New functions.
|
||||
(cris_elf_howto_table) <R_CRIS_8_PCREL, R_CRIS_16_PCREL>
|
||||
<R_CRIS_32_PCREL>: Use cris_elf_pcrel_reloc.
|
||||
(cris_elf_grok_prstatus, cris_elf_grok_psinfo): Give correct
|
||||
numbers for bfd_mach_cris_v32.
|
||||
(PLT_ENTRY_SIZE_V32): New macro.
|
||||
(elf_cris_plt0_entry): Drop last comma in initializer.
|
||||
(elf_cris_plt0_entry_v32, elf_cris_plt_entry_v32)
|
||||
(elf_cris_pic_plt0_entry_v32, elf_cris_pic_plt_entry_v32): New
|
||||
PLT initializers.
|
||||
(cris_elf_relocate_section): Change all "%B(%A)" messages to
|
||||
"%B, section %A".
|
||||
(elf_cris_finish_dynamic_symbol): Do V32-specific PLT entries.
|
||||
(elf_cris_finish_dynamic_sections): Similar.
|
||||
(elf_cris_adjust_dynamic_symbol): Similar.
|
||||
(cris_elf_check_relocs): Change all "%B(%A)" messages to "%B,
|
||||
section %A".
|
||||
<switch with PIC relocs>: Emit error and return FALSE for
|
||||
bfd_mach_cris_v10_v32.
|
||||
<case R_CRIS_8_PCREL, case R_CRIS_16_PCREL, case R_CRIS_32_PCREL>:
|
||||
Emit warning when generating textrel reloc.
|
||||
(cris_elf_object_p): Call cris_elf_set_mach_from_flags.
|
||||
(cris_elf_final_write_processing): Set flags according to mach.
|
||||
(cris_elf_print_private_bfd_data): Display
|
||||
EF_CRIS_VARIANT_COMMON_V10_V32 and EF_CRIS_VARIANT_V32.
|
||||
(cris_elf_merge_private_bfd_data): Drop variables old_flags,
|
||||
new_flags. Don't call cris_elf_final_write_processing. Don't
|
||||
look at the actual elf header flags at all; use
|
||||
bfd_get_symbol_leading_char to check ibfd, obfd. Trap difference
|
||||
in bfd_get_mach for ibfd and obfd and handle merging of compatible
|
||||
objects.
|
||||
(bfd_elf32_bfd_copy_private_bfd_data): Define.
|
||||
* reloc.c (BFD_RELOC_CRIS_SIGNED_8, BFD_RELOC_CRIS_UNSIGNED_8)
|
||||
(BFD_RELOC_CRIS_SIGNED_16, BFD_RELOC_CRIS_UNSIGNED_16)
|
||||
(BFD_RELOC_CRIS_LAPCQ_OFFSET): New relocs.
|
||||
* bfd-in2.h, libbfd.h: Regenerate.
|
||||
|
||||
2004-11-04 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf64-ppc.h (ppc64_elf_edit_toc): Declare.
|
||||
|
@ -323,6 +323,9 @@ DESCRIPTION
|
||||
. bfd_arch_crx, {* National Semiconductor CRX. *}
|
||||
.#define bfd_mach_crx 1
|
||||
. bfd_arch_cris, {* Axis CRIS *}
|
||||
.#define bfd_mach_cris_v0_v10 255
|
||||
.#define bfd_mach_cris_v32 32
|
||||
.#define bfd_mach_cris_v10_v32 1032
|
||||
. bfd_arch_s390, {* IBM s390 *}
|
||||
.#define bfd_mach_s390_31 31
|
||||
.#define bfd_mach_s390_64 64
|
||||
|
@ -1774,6 +1774,9 @@ enum bfd_architecture
|
||||
bfd_arch_crx, /* National Semiconductor CRX. */
|
||||
#define bfd_mach_crx 1
|
||||
bfd_arch_cris, /* Axis CRIS */
|
||||
#define bfd_mach_cris_v0_v10 255
|
||||
#define bfd_mach_cris_v32 32
|
||||
#define bfd_mach_cris_v10_v32 1032
|
||||
bfd_arch_s390, /* IBM s390 */
|
||||
#define bfd_mach_s390_31 31
|
||||
#define bfd_mach_s390_64 64
|
||||
@ -3508,6 +3511,11 @@ This is the 5 bits of a value. */
|
||||
BFD_RELOC_CRIS_UNSIGNED_5,
|
||||
BFD_RELOC_CRIS_SIGNED_6,
|
||||
BFD_RELOC_CRIS_UNSIGNED_6,
|
||||
BFD_RELOC_CRIS_SIGNED_8,
|
||||
BFD_RELOC_CRIS_UNSIGNED_8,
|
||||
BFD_RELOC_CRIS_SIGNED_16,
|
||||
BFD_RELOC_CRIS_UNSIGNED_16,
|
||||
BFD_RELOC_CRIS_LAPCQ_OFFSET,
|
||||
BFD_RELOC_CRIS_UNSIGNED_4,
|
||||
|
||||
/* Relocs used in ELF shared libraries for CRIS. */
|
||||
|
@ -54,6 +54,7 @@ arm*) targ_archs=bfd_arm_arch ;;
|
||||
c30*) targ_archs=bfd_tic30_arch ;;
|
||||
c4x*) targ_archs=bfd_tic4x_arch ;;
|
||||
c54x*) targ_archs=bfd_tic54x_arch ;;
|
||||
crisv32) targ_archs=bfd_cris_arch ;;
|
||||
crx*) targ_archs=bfd_crx_arch ;;
|
||||
dlx*) targ_archs=bfd_dlx_arch ;;
|
||||
hppa*) targ_archs=bfd_hppa_arch ;;
|
||||
@ -326,7 +327,7 @@ case "${targ}" in
|
||||
targ_underscore=yes
|
||||
;;
|
||||
|
||||
cris-*-*)
|
||||
cris-*-* | crisv32-*-*)
|
||||
targ_defvec=cris_aout_vec
|
||||
targ_selvecs="bfd_elf32_us_cris_vec bfd_elf32_cris_vec ieee_vec"
|
||||
targ_underscore=yes # Note: not true for bfd_elf32_cris_vec.
|
||||
|
@ -23,8 +23,58 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
const bfd_arch_info_type
|
||||
bfd_cris_arch =
|
||||
/* This routine is provided two arch_infos and returns the lowest common
|
||||
denominator. CRIS v0..v10 vs. v32 are not compatible in general, but
|
||||
there's a compatible subset for which we provide an arch_info. */
|
||||
|
||||
static const bfd_arch_info_type * get_compatible
|
||||
PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
|
||||
|
||||
static const bfd_arch_info_type *
|
||||
get_compatible (a,b)
|
||||
const bfd_arch_info_type *a;
|
||||
const bfd_arch_info_type *b;
|
||||
{
|
||||
/* Arches must match. */
|
||||
if (a->arch != b->arch)
|
||||
return NULL;
|
||||
|
||||
/* If either is the compatible mach, return the other. */
|
||||
if (a->mach == bfd_mach_cris_v10_v32)
|
||||
return b;
|
||||
if (b->mach == bfd_mach_cris_v10_v32)
|
||||
return a;
|
||||
|
||||
#if 0
|
||||
/* See ldlang.c:lang_check. Quite illogically, incompatible arches
|
||||
(as signalled by this function) are only *warned* about, while with
|
||||
this function signalling compatible ones, we can have the
|
||||
cris_elf_merge_private_bfd_data function return an error. This is
|
||||
undoubtedly a FIXME: in general. Also, the
|
||||
command_line.warn_mismatch flag and the --no-warn-mismatch option
|
||||
are misnamed for the multitude of ports that signal compatibility:
|
||||
it is there an error, not a warning. We work around it by
|
||||
pretending matching machs here. */
|
||||
|
||||
/* Except for the compatible mach, machs must match. */
|
||||
if (a->mach != b->mach)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
#define N(NUMBER, PRINT, NEXT) \
|
||||
{ 32, 32, 8, bfd_arch_cris, NUMBER, "cris", PRINT, 1, FALSE, \
|
||||
get_compatible, bfd_default_scan, NEXT }
|
||||
|
||||
static const bfd_arch_info_type bfd_cris_arch_compat_v10_v32 =
|
||||
N (bfd_mach_cris_v10_v32, "cris:common_v10_v32", NULL);
|
||||
|
||||
static const bfd_arch_info_type bfd_cris_arch_v32 =
|
||||
N (bfd_mach_cris_v32, "crisv32", &bfd_cris_arch_compat_v10_v32);
|
||||
|
||||
const bfd_arch_info_type bfd_cris_arch =
|
||||
{
|
||||
32, /* There's 32 bits_per_word. */
|
||||
32, /* There's 32 bits_per_address. */
|
||||
@ -32,20 +82,20 @@ bfd_cris_arch =
|
||||
bfd_arch_cris, /* One of enum bfd_architecture, defined
|
||||
in archures.c and provided in
|
||||
generated header files. */
|
||||
0xff, /* Only 1 machine, but #255 for
|
||||
historical reasons. */
|
||||
bfd_mach_cris_v0_v10, /* Random BFD-internal number for this
|
||||
machine, similarly listed in
|
||||
archures.c. Not emitted in output. */
|
||||
"cris", /* The arch_name. */
|
||||
"cris", /* The printable name is the same. */
|
||||
1, /* Section alignment power; each section
|
||||
is aligned to (only) 2^1 bytes. */
|
||||
TRUE, /* This is the default "machine", since
|
||||
there's only one. */
|
||||
bfd_default_compatible, /* A default function for testing
|
||||
TRUE, /* This is the default "machine". */
|
||||
get_compatible, /* A function for testing
|
||||
"machine" compatibility of two
|
||||
bfd_arch_info_type. */
|
||||
bfd_default_scan, /* Check if a bfd_arch_info_type is a
|
||||
match. */
|
||||
NULL /* Pointer to next bfd_arch_info_type in
|
||||
&bfd_cris_arch_v32 /* Pointer to next bfd_arch_info_type in
|
||||
the same family. */
|
||||
};
|
||||
|
||||
|
454
bfd/elf32-cris.c
454
bfd/elf32-cris.c
@ -33,6 +33,9 @@ static reloc_howto_type * cris_reloc_type_lookup
|
||||
static void cris_info_to_howto_rela
|
||||
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
|
||||
|
||||
static bfd_reloc_status_type cris_elf_pcrel_reloc
|
||||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||
|
||||
static bfd_boolean cris_elf_grok_prstatus
|
||||
PARAMS ((bfd *abfd, Elf_Internal_Note *note));
|
||||
|
||||
@ -59,9 +62,13 @@ static bfd_boolean cris_elf_object_p PARAMS ((bfd *));
|
||||
|
||||
static void cris_elf_final_write_processing PARAMS ((bfd *, bfd_boolean));
|
||||
|
||||
static bfd_boolean cris_elf_set_mach_from_flags
|
||||
PARAMS ((bfd *, unsigned long int));
|
||||
|
||||
static bfd_boolean cris_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
|
||||
|
||||
static bfd_boolean cris_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
|
||||
static bfd_boolean cris_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
|
||||
|
||||
struct elf_cris_link_hash_entry;
|
||||
static bfd_boolean elf_cris_discard_excess_dso_dynamics
|
||||
@ -164,7 +171,7 @@ static reloc_howto_type cris_elf_howto_table [] =
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
cris_elf_pcrel_reloc, /* special_function */
|
||||
"R_CRIS_8_PCREL", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0x0000, /* src_mask */
|
||||
@ -179,7 +186,7 @@ static reloc_howto_type cris_elf_howto_table [] =
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
cris_elf_pcrel_reloc, /* special_function */
|
||||
"R_CRIS_16_PCREL", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0x00000000, /* src_mask */
|
||||
@ -194,7 +201,7 @@ static reloc_howto_type cris_elf_howto_table [] =
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
cris_elf_pcrel_reloc, /* special_function */
|
||||
"R_CRIS_32_PCREL", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0x00000000, /* src_mask */
|
||||
@ -398,7 +405,7 @@ static reloc_howto_type cris_elf_howto_table [] =
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
cris_elf_pcrel_reloc, /* special_function */
|
||||
"R_CRIS_32_PLT_PCREL", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
@ -466,8 +473,39 @@ cris_info_to_howto_rela (abfd, cache_ptr, dst)
|
||||
BFD_ASSERT (r_type < (unsigned int) R_CRIS_max);
|
||||
cache_ptr->howto = & cris_elf_howto_table [r_type];
|
||||
}
|
||||
|
||||
bfd_reloc_status_type
|
||||
cris_elf_pcrel_reloc (abfd, reloc_entry, symbol, data, input_section,
|
||||
output_bfd, error_message)
|
||||
bfd *abfd ATTRIBUTE_UNUSED;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data ATTRIBUTE_UNUSED;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
char **error_message ATTRIBUTE_UNUSED;
|
||||
{
|
||||
/* By default (using only bfd_elf_generic_reloc when linking to
|
||||
non-ELF formats) PC-relative relocs are relative to the beginning
|
||||
of the reloc. CRIS PC-relative relocs are relative to the position
|
||||
*after* the reloc because that's what pre-CRISv32 PC points to
|
||||
after reading an insn field with that reloc. (For CRISv32, PC is
|
||||
actually relative to the start of the insn, but we keep the old
|
||||
definition.) Still, we use as much generic machinery as we can.
|
||||
|
||||
Only adjust when doing a final link. */
|
||||
if (output_bfd == (bfd *) NULL)
|
||||
reloc_entry->addend -= 1 << reloc_entry->howto->size;
|
||||
|
||||
return
|
||||
bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
|
||||
input_section, output_bfd, error_message);
|
||||
}
|
||||
|
||||
/* Support for core dump NOTE sections. */
|
||||
/* Support for core dump NOTE sections.
|
||||
The slightly unintuitive code layout is an attempt to keep at least
|
||||
some similarities with other ports, hoping to simplify general
|
||||
changes, while still keeping Linux/CRIS and Linux/CRISv32 code apart. */
|
||||
|
||||
static bfd_boolean
|
||||
cris_elf_grok_prstatus (abfd, note)
|
||||
@ -477,8 +515,28 @@ cris_elf_grok_prstatus (abfd, note)
|
||||
int offset;
|
||||
size_t size;
|
||||
|
||||
switch (note->descsz)
|
||||
{
|
||||
if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
|
||||
switch (note->descsz)
|
||||
{
|
||||
default:
|
||||
return FALSE;
|
||||
|
||||
case 202: /* Linux/CRISv32 */
|
||||
/* pr_cursig */
|
||||
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
|
||||
|
||||
/* pr_pid */
|
||||
elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 22);
|
||||
|
||||
/* pr_reg */
|
||||
offset = 70;
|
||||
size = 128;
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (note->descsz)
|
||||
{
|
||||
default:
|
||||
return FALSE;
|
||||
|
||||
@ -494,7 +552,7 @@ cris_elf_grok_prstatus (abfd, note)
|
||||
size = 140;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make a ".reg/999" section. */
|
||||
return _bfd_elfcore_make_pseudosection (abfd, ".reg",
|
||||
@ -506,17 +564,30 @@ cris_elf_grok_psinfo (abfd, note)
|
||||
bfd *abfd;
|
||||
Elf_Internal_Note *note;
|
||||
{
|
||||
switch (note->descsz)
|
||||
{
|
||||
if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
|
||||
switch (note->descsz)
|
||||
{
|
||||
default:
|
||||
return FALSE;
|
||||
|
||||
case 124: /* Linux/CRISv32 elf_prpsinfo */
|
||||
elf_tdata (abfd)->core_program
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
|
||||
elf_tdata (abfd)->core_command
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
|
||||
}
|
||||
else
|
||||
switch (note->descsz)
|
||||
{
|
||||
default:
|
||||
return FALSE;
|
||||
|
||||
case 124: /* Linux/CRIS elf_prpsinfo */
|
||||
elf_tdata (abfd)->core_program
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
|
||||
elf_tdata (abfd)->core_command
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
|
||||
}
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
|
||||
}
|
||||
|
||||
/* Note that for some reason, a spurious space is tacked
|
||||
onto the end of the args in some (at least one anyway)
|
||||
@ -541,6 +612,7 @@ cris_elf_grok_psinfo (abfd, note)
|
||||
/* The size in bytes of an entry in the procedure linkage table. */
|
||||
|
||||
#define PLT_ENTRY_SIZE 20
|
||||
#define PLT_ENTRY_SIZE_V32 26
|
||||
|
||||
/* The first entry in an absolute procedure linkage table looks like this. */
|
||||
|
||||
@ -553,7 +625,21 @@ static const bfd_byte elf_cris_plt0_entry[PLT_ENTRY_SIZE] =
|
||||
0x30, 0x7a, /* move [...],mof */
|
||||
0x7f, 0x0d, /* (dip [pc+]) */
|
||||
0, 0, 0, 0, /* Replaced with address of .got + 8. */
|
||||
0x30, 0x09, /* jump [...] */
|
||||
0x30, 0x09 /* jump [...] */
|
||||
};
|
||||
|
||||
static const bfd_byte elf_cris_plt0_entry_v32[PLT_ENTRY_SIZE_V32] =
|
||||
{
|
||||
0x84, 0xe2, /* subq 4,$sp */
|
||||
0x6f, 0xfe, /* move.d 0,$acr */
|
||||
0, 0, 0, 0, /* Replaced by address of .got + 4. */
|
||||
0x7e, 0x7a, /* move $mof,[$sp] */
|
||||
0x3f, 0x7a, /* move [$acr],$mof */
|
||||
0x04, 0xf2, /* addq 4,acr */
|
||||
0x6f, 0xfa, /* move.d [$acr],$acr */
|
||||
0xbf, 0x09, /* jump $acr */
|
||||
0xb0, 0x05, /* nop */
|
||||
0, 0 /* Pad out to 26 bytes. */
|
||||
};
|
||||
|
||||
/* Subsequent entries in an absolute procedure linkage table look like
|
||||
@ -571,6 +657,20 @@ static const bfd_byte elf_cris_plt_entry[PLT_ENTRY_SIZE] =
|
||||
0xff, 0xff /* Replaced with offset to start of .plt. */
|
||||
};
|
||||
|
||||
static const bfd_byte elf_cris_plt_entry_v32[PLT_ENTRY_SIZE_V32] =
|
||||
{
|
||||
0x6f, 0xfe, /* move.d 0,$acr */
|
||||
0, 0, 0, 0, /* Replaced with address of this symbol in .got. */
|
||||
0x6f, 0xfa, /* move.d [$acr],$acr */
|
||||
0xbf, 0x09, /* jump $acr */
|
||||
0xb0, 0x05, /* nop */
|
||||
0x3f, 0x7e, /* move 0,mof */
|
||||
0, 0, 0, 0, /* Replaced with offset into relocation table. */
|
||||
0xbf, 0x0e, /* ba start_of_plt0_entry */
|
||||
0, 0, 0, 0, /* Replaced with offset to plt0 entry. */
|
||||
0xb0, 0x05 /* nop */
|
||||
};
|
||||
|
||||
/* The first entry in a PIC procedure linkage table looks like this. */
|
||||
|
||||
static const bfd_byte elf_cris_pic_plt0_entry[PLT_ENTRY_SIZE] =
|
||||
@ -581,6 +681,21 @@ static const bfd_byte elf_cris_pic_plt0_entry[PLT_ENTRY_SIZE] =
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* Pad out to 20 bytes. */
|
||||
};
|
||||
|
||||
static const bfd_byte elf_cris_pic_plt0_entry_v32[PLT_ENTRY_SIZE_V32] =
|
||||
{
|
||||
0x84, 0xe2, /* subq 4,$sp */
|
||||
0x04, 0x01, /* addoq 4,$r0,$acr */
|
||||
0x7e, 0x7a, /* move $mof,[$sp] */
|
||||
0x3f, 0x7a, /* move [$acr],$mof */
|
||||
0x04, 0xf2, /* addq 4,$acr */
|
||||
0x6f, 0xfa, /* move.d [$acr],$acr */
|
||||
0xbf, 0x09, /* jump $acr */
|
||||
0xb0, 0x05, /* nop */
|
||||
0, 0, /* Pad out to 26 bytes. */
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* Subsequent entries in a PIC procedure linkage table look like this. */
|
||||
|
||||
static const bfd_byte elf_cris_pic_plt_entry[PLT_ENTRY_SIZE] =
|
||||
@ -594,6 +709,20 @@ static const bfd_byte elf_cris_pic_plt_entry[PLT_ENTRY_SIZE] =
|
||||
0xec, 0xff, /* Replaced with offset to start of .plt. */
|
||||
0xff, 0xff
|
||||
};
|
||||
|
||||
static const bfd_byte elf_cris_pic_plt_entry_v32[PLT_ENTRY_SIZE_V32] =
|
||||
{
|
||||
0x6f, 0x0d, /* addo.d 0,$r0,$acr */
|
||||
0, 0, 0, 0, /* Replaced with offset of this symbol in .got. */
|
||||
0x6f, 0xfa, /* move.d [$acr],$acr */
|
||||
0xbf, 0x09, /* jump $acr */
|
||||
0xb0, 0x05, /* nop */
|
||||
0x3f, 0x7e, /* move relocoffs,$mof */
|
||||
0, 0, 0, 0, /* Replaced with offset into relocation table. */
|
||||
0xbf, 0x0e, /* ba start_of_plt */
|
||||
0, 0, 0, 0, /* Replaced with offset to start of .plt. */
|
||||
0xb0, 0x05 /* nop */
|
||||
};
|
||||
|
||||
/* We copy elf32-m68k.c and elf32-i386.c for the basic linker hash bits
|
||||
(and most other PIC/shlib stuff). Check that we don't drift away
|
||||
@ -917,7 +1046,7 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
else if (unresolved_reloc)
|
||||
{
|
||||
_bfd_error_handler
|
||||
(_("%B(%A): unresolvable relocation %s against symbol `%s'"),
|
||||
(_("%B, section %A: unresolvable relocation %s against symbol `%s'"),
|
||||
input_bfd,
|
||||
input_section,
|
||||
cris_elf_howto_table[r_type].name,
|
||||
@ -972,9 +1101,9 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
((h->got.offset == (bfd_vma) -1)
|
||||
? _("%B(%A): No PLT nor GOT for relocation %s"
|
||||
? _("%B, section %A: No PLT nor GOT for relocation %s"
|
||||
" against symbol `%s'")
|
||||
: _("%B(%A): No PLT for relocation %s"
|
||||
: _("%B, section %A: No PLT for relocation %s"
|
||||
" against symbol `%s'"),
|
||||
input_bfd,
|
||||
input_section,
|
||||
@ -1098,7 +1227,7 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
allowed to pass us these kinds of things. */
|
||||
if (h == NULL)
|
||||
(*_bfd_error_handler)
|
||||
(_("%B(%A): relocation %s with non-zero addend %d"
|
||||
(_("%B, section %A: relocation %s with non-zero addend %d"
|
||||
" against local symbol"),
|
||||
input_bfd,
|
||||
input_section,
|
||||
@ -1106,7 +1235,7 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
rel->r_addend);
|
||||
else
|
||||
(*_bfd_error_handler)
|
||||
(_("%B(%A): relocation %s with non-zero addend %d"
|
||||
(_("%B, section %A: relocation %s with non-zero addend %d"
|
||||
" against symbol `%s'"),
|
||||
input_bfd,
|
||||
input_section,
|
||||
@ -1132,7 +1261,8 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
&& h->root.type == bfd_link_hash_undefweak))))
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B(%A): relocation %s is not allowed for global symbol: `%s'"),
|
||||
(_("%B, section %A: relocation %s is"
|
||||
" not allowed for global symbol: `%s'"),
|
||||
input_bfd,
|
||||
input_section,
|
||||
cris_elf_howto_table[r_type].name,
|
||||
@ -1147,7 +1277,7 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
if (sgot == NULL)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B: relocation %s in section %A with no GOT created"),
|
||||
(_("%B, section %A: relocation %s with no GOT created"),
|
||||
input_bfd,
|
||||
input_section,
|
||||
cris_elf_howto_table[r_type].name);
|
||||
@ -1407,8 +1537,33 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
Elf_Internal_Sym *sym;
|
||||
{
|
||||
bfd *dynobj;
|
||||
|
||||
/* Where in the plt entry to put values. */
|
||||
int plt_off1 = 2, plt_off2 = 10, plt_off3 = 16;
|
||||
|
||||
/* What offset to add to the distance to the first PLT entry for the
|
||||
value at plt_off3. */
|
||||
int plt_off3_value_bias = 4;
|
||||
|
||||
/* Where in the PLT entry the call-dynlink-stub is (happens to be same
|
||||
for PIC and non-PIC for v32 and pre-v32). */
|
||||
int plt_stub_offset = 8;
|
||||
int plt_entry_size = PLT_ENTRY_SIZE;
|
||||
const bfd_byte *plt_entry = elf_cris_plt_entry;
|
||||
const bfd_byte *plt_pic_entry = elf_cris_pic_plt_entry;
|
||||
|
||||
/* Adjust the various PLT entry offsets. */
|
||||
if (bfd_get_mach (output_bfd) == bfd_mach_cris_v32)
|
||||
{
|
||||
plt_off2 = 14;
|
||||
plt_off3 = 20;
|
||||
plt_off3_value_bias = -2;
|
||||
plt_stub_offset = 12;
|
||||
plt_entry_size = PLT_ENTRY_SIZE_V32;
|
||||
plt_entry = elf_cris_plt_entry_v32;
|
||||
plt_pic_entry = elf_cris_pic_plt_entry_v32;
|
||||
}
|
||||
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
|
||||
if (h->plt.offset != (bfd_vma) -1)
|
||||
@ -1460,8 +1615,8 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
/* Fill in the entry in the procedure linkage table. */
|
||||
if (! info->shared)
|
||||
{
|
||||
memcpy (splt->contents + h->plt.offset, elf_cris_plt_entry,
|
||||
PLT_ENTRY_SIZE);
|
||||
memcpy (splt->contents + h->plt.offset, plt_entry,
|
||||
plt_entry_size);
|
||||
|
||||
/* We need to enter the absolute address of the GOT entry here. */
|
||||
bfd_put_32 (output_bfd, got_base + got_offset,
|
||||
@ -1469,8 +1624,8 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (splt->contents + h->plt.offset, elf_cris_pic_plt_entry,
|
||||
PLT_ENTRY_SIZE);
|
||||
memcpy (splt->contents + h->plt.offset, plt_pic_entry,
|
||||
plt_entry_size);
|
||||
bfd_put_32 (output_bfd, got_offset,
|
||||
splt->contents + h->plt.offset + plt_off1);
|
||||
}
|
||||
@ -1479,13 +1634,14 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
PLT entry. */
|
||||
if (has_gotplt)
|
||||
{
|
||||
/* Fill in the offset into the reloc table. */
|
||||
/* Fill in the offset to the reloc table. */
|
||||
bfd_put_32 (output_bfd,
|
||||
gotplt_index * sizeof (Elf32_External_Rela),
|
||||
splt->contents + h->plt.offset + plt_off2);
|
||||
|
||||
/* Fill in the offset to the first PLT entry, where to "jump". */
|
||||
bfd_put_32 (output_bfd, - (h->plt.offset + plt_off3 + 4),
|
||||
bfd_put_32 (output_bfd,
|
||||
- (h->plt.offset + plt_off3 + plt_off3_value_bias),
|
||||
splt->contents + h->plt.offset + plt_off3);
|
||||
|
||||
/* Fill in the entry in the global offset table with the address of
|
||||
@ -1494,7 +1650,7 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
(splt->output_section->vma
|
||||
+ splt->output_offset
|
||||
+ h->plt.offset
|
||||
+ 8),
|
||||
+ plt_stub_offset),
|
||||
sgotplt->contents + got_offset);
|
||||
|
||||
/* Fill in the entry in the .rela.plt section. */
|
||||
@ -1695,20 +1851,45 @@ elf_cris_finish_dynamic_sections (output_bfd, info)
|
||||
/* Fill in the first entry in the procedure linkage table. */
|
||||
if (splt->size > 0)
|
||||
{
|
||||
if (info->shared)
|
||||
memcpy (splt->contents, elf_cris_pic_plt0_entry, PLT_ENTRY_SIZE);
|
||||
else
|
||||
{
|
||||
memcpy (splt->contents, elf_cris_plt0_entry, PLT_ENTRY_SIZE);
|
||||
bfd_put_32 (output_bfd,
|
||||
sgot->output_section->vma + sgot->output_offset + 4,
|
||||
splt->contents + 6);
|
||||
bfd_put_32 (output_bfd,
|
||||
sgot->output_section->vma + sgot->output_offset + 8,
|
||||
splt->contents + 14);
|
||||
if (bfd_get_mach (output_bfd) == bfd_mach_cris_v32)
|
||||
{
|
||||
if (info->shared)
|
||||
memcpy (splt->contents, elf_cris_pic_plt0_entry_v32,
|
||||
PLT_ENTRY_SIZE_V32);
|
||||
else
|
||||
{
|
||||
memcpy (splt->contents, elf_cris_plt0_entry_v32,
|
||||
PLT_ENTRY_SIZE_V32);
|
||||
bfd_put_32 (output_bfd,
|
||||
sgot->output_section->vma
|
||||
+ sgot->output_offset + 4,
|
||||
splt->contents + 4);
|
||||
|
||||
elf_section_data (splt->output_section)->this_hdr.sh_entsize
|
||||
= PLT_ENTRY_SIZE;
|
||||
elf_section_data (splt->output_section)->this_hdr.sh_entsize
|
||||
= PLT_ENTRY_SIZE_V32;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->shared)
|
||||
memcpy (splt->contents, elf_cris_pic_plt0_entry,
|
||||
PLT_ENTRY_SIZE);
|
||||
else
|
||||
{
|
||||
memcpy (splt->contents, elf_cris_plt0_entry,
|
||||
PLT_ENTRY_SIZE);
|
||||
bfd_put_32 (output_bfd,
|
||||
sgot->output_section->vma
|
||||
+ sgot->output_offset + 4,
|
||||
splt->contents + 6);
|
||||
bfd_put_32 (output_bfd,
|
||||
sgot->output_section->vma
|
||||
+ sgot->output_offset + 8,
|
||||
splt->contents + 14);
|
||||
|
||||
elf_section_data (splt->output_section)->this_hdr.sh_entsize
|
||||
= PLT_ENTRY_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2018,6 +2199,7 @@ elf_cris_adjust_dynamic_symbol (info, h)
|
||||
bfd *dynobj;
|
||||
asection *s;
|
||||
unsigned int power_of_two;
|
||||
bfd_size_type plt_entry_size;
|
||||
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
|
||||
@ -2029,6 +2211,10 @@ elf_cris_adjust_dynamic_symbol (info, h)
|
||||
&& h->ref_regular
|
||||
&& !h->def_regular)));
|
||||
|
||||
plt_entry_size
|
||||
= (bfd_get_mach (dynobj) == bfd_mach_cris_v32
|
||||
? PLT_ENTRY_SIZE_V32 : PLT_ENTRY_SIZE);
|
||||
|
||||
/* If this is a function, put it in the procedure linkage table. We
|
||||
will fill in the contents of the procedure linkage table later,
|
||||
when we know the address of the .got section. */
|
||||
@ -2089,7 +2275,7 @@ elf_cris_adjust_dynamic_symbol (info, h)
|
||||
/* If this is the first .plt entry, make room for the special
|
||||
first entry. */
|
||||
if (s->size == 0)
|
||||
s->size += PLT_ENTRY_SIZE;
|
||||
s->size += plt_entry_size;
|
||||
|
||||
/* If this symbol is not defined in a regular file, and we are
|
||||
not generating a shared library, then set the symbol to this
|
||||
@ -2113,8 +2299,8 @@ elf_cris_adjust_dynamic_symbol (info, h)
|
||||
|
||||
/* Mark the PLT offset to use the GOT entry by setting the low
|
||||
bit in the plt offset; it is always a multiple of
|
||||
pointer-size. */
|
||||
BFD_ASSERT ((s->size & 3) == 0);
|
||||
plt_entry_size (which is at least a multiple of 2). */
|
||||
BFD_ASSERT ((s->size % plt_entry_size) == 0);
|
||||
|
||||
/* Change the PLT refcount to an offset. */
|
||||
h->plt.offset = s->size;
|
||||
@ -2125,7 +2311,7 @@ elf_cris_adjust_dynamic_symbol (info, h)
|
||||
h)->gotplt_offset == 0);
|
||||
|
||||
/* Make room for this entry. */
|
||||
s->size += PLT_ENTRY_SIZE;
|
||||
s->size += plt_entry_size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -2134,7 +2320,7 @@ elf_cris_adjust_dynamic_symbol (info, h)
|
||||
h->plt.offset = s->size;
|
||||
|
||||
/* Make room for this entry. */
|
||||
s->size += PLT_ENTRY_SIZE;
|
||||
s->size += plt_entry_size;
|
||||
|
||||
/* We also need to make an entry in the .got.plt section, which
|
||||
will be placed in the .got section by the linker script. */
|
||||
@ -2305,6 +2491,18 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
|
||||
{
|
||||
elf_hash_table (info)->dynobj = dynobj = abfd;
|
||||
|
||||
/* We could handle this if we can get a handle on the
|
||||
output bfd in elf_cris_adjust_dynamic_symbol. Failing
|
||||
that, we must insist on dynobj being a specific mach. */
|
||||
if (bfd_get_mach (dynobj) == bfd_mach_cris_v10_v32)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B, section %A:\n v10/v32 compatible object %s"
|
||||
" must not contain a PIC relocation"),
|
||||
abfd, sec);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create the .got section, so we can assume it's always
|
||||
present whenever there's a dynobj. */
|
||||
if (!_bfd_elf_create_got_section (dynobj, info))
|
||||
@ -2486,7 +2684,8 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
|
||||
{
|
||||
/* FIXME: How do we make this optionally a warning only? */
|
||||
(*_bfd_error_handler)
|
||||
(_("%B, section %A:\n relocation %s should not be used in a shared object; recompile with -fPIC"),
|
||||
(_("%B, section %A:\n relocation %s should not"
|
||||
" be used in a shared object; recompile with -fPIC"),
|
||||
abfd,
|
||||
sec,
|
||||
cris_elf_howto_table[r_type].name);
|
||||
@ -2548,6 +2747,17 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
|
||||
&& h->root.type != bfd_link_hash_defweak
|
||||
&& h->def_regular)
|
||||
break;
|
||||
|
||||
if ((sec->flags & SEC_READONLY) != 0)
|
||||
{
|
||||
/* FIXME: How do we make this optionally a warning only? */
|
||||
(*_bfd_error_handler)
|
||||
(_("%B, section %A:\n relocation %s should not be used"
|
||||
" in a shared object; recompile with -fPIC"),
|
||||
abfd,
|
||||
sec,
|
||||
cris_elf_howto_table[r_type].name);
|
||||
}
|
||||
}
|
||||
|
||||
/* We create a reloc section in dynobj and make room for this
|
||||
@ -2932,23 +3142,81 @@ static bfd_boolean
|
||||
cris_elf_object_p (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
if (! cris_elf_set_mach_from_flags (abfd, elf_elfheader (abfd)->e_flags))
|
||||
return FALSE;
|
||||
|
||||
if ((elf_elfheader (abfd)->e_flags & EF_CRIS_UNDERSCORE))
|
||||
return (bfd_get_symbol_leading_char (abfd) == '_');
|
||||
else
|
||||
return (bfd_get_symbol_leading_char (abfd) == 0);
|
||||
}
|
||||
|
||||
/* Mark presence or absence of leading underscore. */
|
||||
/* Mark presence or absence of leading underscore. Set machine type
|
||||
flags from mach type. */
|
||||
|
||||
static void
|
||||
cris_elf_final_write_processing (abfd, linker)
|
||||
bfd *abfd;
|
||||
bfd_boolean linker ATTRIBUTE_UNUSED;
|
||||
{
|
||||
unsigned long e_flags = elf_elfheader (abfd)->e_flags;
|
||||
|
||||
e_flags &= ~EF_CRIS_UNDERSCORE;
|
||||
if (bfd_get_symbol_leading_char (abfd) == '_')
|
||||
elf_elfheader (abfd)->e_flags |= EF_CRIS_UNDERSCORE;
|
||||
else
|
||||
elf_elfheader (abfd)->e_flags &= ~EF_CRIS_UNDERSCORE;
|
||||
e_flags |= EF_CRIS_UNDERSCORE;
|
||||
|
||||
switch (bfd_get_mach (abfd))
|
||||
{
|
||||
case bfd_mach_cris_v0_v10:
|
||||
e_flags |= EF_CRIS_VARIANT_ANY_V0_V10;
|
||||
break;
|
||||
|
||||
case bfd_mach_cris_v10_v32:
|
||||
e_flags |= EF_CRIS_VARIANT_COMMON_V10_V32;
|
||||
break;
|
||||
|
||||
case bfd_mach_cris_v32:
|
||||
e_flags |= EF_CRIS_VARIANT_V32;
|
||||
break;
|
||||
|
||||
default:
|
||||
_bfd_abort (__FILE__, __LINE__,
|
||||
_("Unexpected machine number"));
|
||||
}
|
||||
|
||||
elf_elfheader (abfd)->e_flags = e_flags;
|
||||
}
|
||||
|
||||
/* Set the mach type from e_flags value. */
|
||||
|
||||
static bfd_boolean
|
||||
cris_elf_set_mach_from_flags (abfd, flags)
|
||||
bfd *abfd;
|
||||
unsigned long flags;
|
||||
{
|
||||
switch (flags & EF_CRIS_VARIANT_MASK)
|
||||
{
|
||||
case EF_CRIS_VARIANT_ANY_V0_V10:
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v0_v10);
|
||||
break;
|
||||
|
||||
case EF_CRIS_VARIANT_V32:
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v32);
|
||||
break;
|
||||
|
||||
case EF_CRIS_VARIANT_COMMON_V10_V32:
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v10_v32);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Since we don't recognize them, we obviously can't support them
|
||||
with this code; we'd have to require that all future handling
|
||||
would be optional. */
|
||||
bfd_set_error (bfd_error_wrong_format);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Display the flags field. */
|
||||
@ -2968,6 +3236,12 @@ cris_elf_print_private_bfd_data (abfd, ptr)
|
||||
|
||||
if (elf_elfheader (abfd)->e_flags & EF_CRIS_UNDERSCORE)
|
||||
fprintf (file, _(" [symbols have a _ prefix]"));
|
||||
if ((elf_elfheader (abfd)->e_flags & EF_CRIS_VARIANT_MASK)
|
||||
== EF_CRIS_VARIANT_COMMON_V10_V32)
|
||||
fprintf (file, _(" [v10 and v32]"));
|
||||
if ((elf_elfheader (abfd)->e_flags & EF_CRIS_VARIANT_MASK)
|
||||
== EF_CRIS_VARIANT_V32)
|
||||
fprintf (file, _(" [v32]"));
|
||||
|
||||
fputc ('\n', file);
|
||||
return TRUE;
|
||||
@ -2980,7 +3254,7 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
flagword old_flags, new_flags;
|
||||
int imach, omach;
|
||||
|
||||
if (! _bfd_generic_verify_endian_match (ibfd, obfd))
|
||||
return FALSE;
|
||||
@ -2989,23 +3263,29 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
|
||||
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
|
||||
return TRUE;
|
||||
|
||||
imach = bfd_get_mach (ibfd);
|
||||
|
||||
if (! elf_flags_init (obfd))
|
||||
{
|
||||
/* This happens when ld starts out with a 'blank' output file. */
|
||||
elf_flags_init (obfd) = TRUE;
|
||||
|
||||
/* Set flags according to current bfd_target. */
|
||||
cris_elf_final_write_processing (obfd, FALSE);
|
||||
/* We ignore the linker-set mach, and instead set it according to
|
||||
the first input file. This would also happen if we could
|
||||
somehow filter out the OUTPUT_ARCH () setting from elf.sc.
|
||||
This allows us to keep the same linker config across
|
||||
cris(v0..v10) and crisv32. The drawback is that we can't force
|
||||
the output type, which might be a sane thing to do for a
|
||||
v10+v32 compatibility object. */
|
||||
if (! bfd_set_arch_mach (obfd, bfd_arch_cris, imach))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
old_flags = elf_elfheader (obfd)->e_flags;
|
||||
new_flags = elf_elfheader (ibfd)->e_flags;
|
||||
|
||||
/* Is this good or bad? We'll follow with other excluding flags. */
|
||||
if ((old_flags & EF_CRIS_UNDERSCORE) != (new_flags & EF_CRIS_UNDERSCORE))
|
||||
if (bfd_get_symbol_leading_char (ibfd)
|
||||
!= bfd_get_symbol_leading_char (obfd))
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
((new_flags & EF_CRIS_UNDERSCORE)
|
||||
(bfd_get_symbol_leading_char (ibfd) == '_'
|
||||
? _("%B: uses _-prefixed symbols, but writing file with non-prefixed symbols")
|
||||
: _("%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"),
|
||||
ibfd);
|
||||
@ -3013,9 +3293,61 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
omach = bfd_get_mach (obfd);
|
||||
|
||||
if (imach != omach)
|
||||
{
|
||||
/* We can get an incompatible combination only if either is
|
||||
bfd_mach_cris_v32, and the other one isn't compatible. */
|
||||
if ((imach == bfd_mach_cris_v32
|
||||
&& omach != bfd_mach_cris_v10_v32)
|
||||
|| (omach == bfd_mach_cris_v32
|
||||
&& imach != bfd_mach_cris_v10_v32))
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
((imach == bfd_mach_cris_v32)
|
||||
? _("%B contains CRIS v32 code, incompatible"
|
||||
" with previous objects")
|
||||
: _("%B contains non-CRIS-v32 code, incompatible"
|
||||
" with previous objects"),
|
||||
ibfd);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We don't have to check the case where the input is compatible
|
||||
with v10 and v32, because the output is already known to be set
|
||||
to the other (compatible) mach. */
|
||||
if (omach == bfd_mach_cris_v10_v32
|
||||
&& ! bfd_set_arch_mach (obfd, bfd_arch_cris, imach))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Do side-effects of e_flags copying to obfd. */
|
||||
|
||||
static bfd_boolean
|
||||
cris_elf_copy_private_bfd_data (ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
/* Call the base function. */
|
||||
if (!_bfd_elf_copy_private_bfd_data (ibfd, obfd))
|
||||
return FALSE;
|
||||
|
||||
/* If output is big-endian for some obscure reason, stop here. */
|
||||
if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|
||||
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
|
||||
return TRUE;
|
||||
|
||||
/* Do what we really came here for. */
|
||||
return bfd_set_arch_mach (obfd, bfd_arch_cris, bfd_get_mach (ibfd));
|
||||
}
|
||||
|
||||
static enum elf_reloc_type_class
|
||||
elf_cris_reloc_type_class (rela)
|
||||
@ -3061,6 +3393,8 @@ elf_cris_reloc_type_class (rela)
|
||||
cris_elf_print_private_bfd_data
|
||||
#define bfd_elf32_bfd_merge_private_bfd_data \
|
||||
cris_elf_merge_private_bfd_data
|
||||
#define bfd_elf32_bfd_copy_private_bfd_data \
|
||||
cris_elf_copy_private_bfd_data
|
||||
|
||||
#define bfd_elf32_bfd_reloc_type_lookup cris_reloc_type_lookup
|
||||
|
||||
|
@ -1579,6 +1579,11 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||||
"BFD_RELOC_CRIS_UNSIGNED_5",
|
||||
"BFD_RELOC_CRIS_SIGNED_6",
|
||||
"BFD_RELOC_CRIS_UNSIGNED_6",
|
||||
"BFD_RELOC_CRIS_SIGNED_8",
|
||||
"BFD_RELOC_CRIS_UNSIGNED_8",
|
||||
"BFD_RELOC_CRIS_SIGNED_16",
|
||||
"BFD_RELOC_CRIS_UNSIGNED_16",
|
||||
"BFD_RELOC_CRIS_LAPCQ_OFFSET",
|
||||
"BFD_RELOC_CRIS_UNSIGNED_4",
|
||||
"BFD_RELOC_CRIS_COPY",
|
||||
"BFD_RELOC_CRIS_GLOB_DAT",
|
||||
|
10
bfd/reloc.c
10
bfd/reloc.c
@ -3946,6 +3946,16 @@ ENUMX
|
||||
BFD_RELOC_CRIS_SIGNED_6
|
||||
ENUMX
|
||||
BFD_RELOC_CRIS_UNSIGNED_6
|
||||
ENUMX
|
||||
BFD_RELOC_CRIS_SIGNED_8
|
||||
ENUMX
|
||||
BFD_RELOC_CRIS_UNSIGNED_8
|
||||
ENUMX
|
||||
BFD_RELOC_CRIS_SIGNED_16
|
||||
ENUMX
|
||||
BFD_RELOC_CRIS_UNSIGNED_16
|
||||
ENUMX
|
||||
BFD_RELOC_CRIS_LAPCQ_OFFSET
|
||||
ENUMX
|
||||
BFD_RELOC_CRIS_UNSIGNED_4
|
||||
ENUMDOC
|
||||
|
Loading…
Reference in New Issue
Block a user