X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Felf32-rx.c;h=92c046abfae94482e6765afd6c9b2be54e98357e;hb=708e2187a341e9eee46669dbb8c4d6603be5cf40;hp=99cffc0e0092f010652a4f605194a4efea2a9f4e;hpb=d4cb0ea0caf03bea93ae6891017bb2301facb33f;p=binutils-gdb.git diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c index 99cffc0e009..92c046abfae 100644 --- a/bfd/elf32-rx.c +++ b/bfd/elf32-rx.c @@ -1,5 +1,5 @@ /* Renesas RX specific support for 32-bit ELF. - Copyright (C) 2008, 2009, 2010, 2011 + Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -32,6 +32,7 @@ endian-swap we would otherwise get. We check for this in rx_elf_object_p(). */ const bfd_target bfd_elf32_rx_be_ns_vec; +const bfd_target bfd_elf32_rx_be_vec; #ifdef DEBUG char * rx_get_reloc (long); @@ -520,9 +521,9 @@ rx_elf_relocate_section name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, - rel, relend, howto, contents); + rel, 1, relend, howto, 0, contents); if (info->relocatable) { @@ -1652,7 +1653,7 @@ rx_offset_for_reloc (bfd * abfd, if (ssec) { if ((ssec->flags & SEC_MERGE) - && ssec->sec_info_type == ELF_INFO_TYPE_MERGE) + && ssec->sec_info_type == SEC_INFO_TYPE_MERGE) symval = _bfd_merged_section_offset (abfd, & ssec, elf_section_data (ssec)->sec_info, symval); @@ -1925,14 +1926,14 @@ elf32_rx_relax_section (bfd * abfd, if (shndx_buf == NULL) goto error_return; if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt) + || bfd_bread (shndx_buf, amt, abfd) != amt) goto error_return; shndx_hdr->contents = (bfd_byte *) shndx_buf; } /* Get a copy of the native relocations. */ internal_relocs = (_bfd_elf_link_read_relocs - (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL, + (abfd, sec, NULL, (Elf_Internal_Rela *) NULL, link_info->keep_memory)); if (internal_relocs == NULL) goto error_return; @@ -2114,7 +2115,7 @@ elf32_rx_relax_section (bfd * abfd, /* Decodable bits. */ && (insn[0] & 0xcc) == 0xcc /* Width. */ - && (insn[0] & 0x30) != 3 + && (insn[0] & 0x30) != 0x30 /* Register MSBs. */ && (insn[1] & 0x88) == 0x00) { @@ -2218,7 +2219,7 @@ elf32_rx_relax_section (bfd * abfd, /* Decodable bits. */ && (insn[0] & 0xc3) == 0xc3 /* Width. */ - && (insn[0] & 0x30) != 3 + && (insn[0] & 0x30) != 0x30 /* Register MSBs. */ && (insn[1] & 0x88) == 0x00) { @@ -2936,6 +2937,39 @@ bfd_elf32_rx_set_target_flags (bfd_boolean user_no_warn_mismatch, ignore_lma = user_ignore_lma; } +/* Converts FLAGS into a descriptive string. + Returns a static pointer. */ + +static const char * +describe_flags (flagword flags) +{ + static char buf [128]; + + buf[0] = 0; + + if (flags & E_FLAG_RX_64BIT_DOUBLES) + strcat (buf, "64-bit doubles"); + else + strcat (buf, "32-bit doubles"); + + if (flags & E_FLAG_RX_DSP) + strcat (buf, ", dsp"); + else + strcat (buf, ", no dsp"); + + if (flags & E_FLAG_RX_PID) + strcat (buf, ", pid"); + else + strcat (buf, ", no pid"); + + if (flags & E_FLAG_RX_ABI) + strcat (buf, ", RX ABI"); + else + strcat (buf, ", GCC ABI"); + + return buf; +} + /* Merge backend specific data from an object file to the output object file when linking. */ @@ -2957,7 +2991,10 @@ rx_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) } else if (old_flags != new_flags) { - flagword known_flags = E_FLAG_RX_64BIT_DOUBLES | E_FLAG_RX_DSP | E_FLAG_RX_PID; + flagword known_flags; + + known_flags = E_FLAG_RX_ABI | E_FLAG_RX_64BIT_DOUBLES + | E_FLAG_RX_DSP | E_FLAG_RX_PID; if ((old_flags ^ new_flags) & known_flags) { @@ -2970,9 +3007,12 @@ rx_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) } else { - (*_bfd_error_handler) - ("ELF header flags mismatch: old_flags = 0x%.8lx, new_flags = 0x%.8lx, filename = %s", - old_flags, new_flags, bfd_get_filename (ibfd)); + _bfd_error_handler ("There is a conflict merging the ELF header flags from %s", + bfd_get_filename (ibfd)); + _bfd_error_handler (" the input file's flags: %s", + describe_flags (new_flags)); + _bfd_error_handler (" the output file's flags: %s", + describe_flags (old_flags)); error = TRUE; } } @@ -3000,21 +3040,20 @@ rx_elf_print_private_bfd_data (bfd * abfd, void * ptr) flags = elf_elfheader (abfd)->e_flags; fprintf (file, _("private flags = 0x%lx:"), (long) flags); - if (flags & E_FLAG_RX_64BIT_DOUBLES) - fprintf (file, _(" [64-bit doubles]")); - if (flags & E_FLAG_RX_DSP) - fprintf (file, _(" [dsp]")); - - fputc ('\n', file); + fprintf (file, describe_flags (flags)); return TRUE; } /* Return the MACH for an e_flags value. */ static int -elf32_rx_machine (bfd * abfd) +elf32_rx_machine (bfd * abfd ATTRIBUTE_UNUSED) { +#if 0 /* FIXME: EF_RX_CPU_MASK collides with E_FLAG_RX_... + Need to sort out how these flag bits are used. + For now we assume that the flags are OK. */ if ((elf_elfheader (abfd)->e_flags & EF_RX_CPU_MASK) == EF_RX_CPU_RX) +#endif return bfd_mach_rx; return 0; @@ -3028,6 +3067,7 @@ rx_elf_object_p (bfd * abfd) Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr; int nphdrs = elf_elfheader (abfd)->e_phnum; sec_ptr bsec; + static int saw_be = FALSE; /* We never want to automatically choose the non-swapping big-endian target. The user can only get that explicitly, such as with -I @@ -3036,6 +3076,15 @@ rx_elf_object_p (bfd * abfd) && abfd->target_defaulted) return FALSE; + /* BFD->target_defaulted is not set to TRUE when a target is chosen + as a fallback, so we check for "scanning" to know when to stop + using the non-swapping target. */ + if (abfd->xvec == &bfd_elf32_rx_be_ns_vec + && saw_be) + return FALSE; + if (abfd->xvec == &bfd_elf32_rx_be_vec) + saw_be = TRUE; + bfd_default_set_arch_mach (abfd, bfd_arch_rx, elf32_rx_machine (abfd)); @@ -3049,7 +3098,8 @@ rx_elf_object_p (bfd * abfd) { Elf_Internal_Shdr *sec = elf_tdata(abfd)->elf_sect_ptr[u]; - if (phdr[i].p_offset <= (bfd_vma) sec->sh_offset + if (phdr[i].p_filesz + && phdr[i].p_offset <= (bfd_vma) sec->sh_offset && (bfd_vma)sec->sh_offset <= phdr[i].p_offset + (phdr[i].p_filesz - 1)) { /* Found one! The difference between the two addresses, @@ -3073,7 +3123,8 @@ rx_elf_object_p (bfd * abfd) bsec = abfd->sections; while (bsec) { - if (phdr[i].p_vaddr <= bsec->lma + if (phdr[i].p_filesz + && phdr[i].p_vaddr <= bsec->vma && bsec->vma <= phdr[i].p_vaddr + (phdr[i].p_filesz - 1)) { bsec->lma = phdr[i].p_paddr + (bsec->vma - phdr[i].p_vaddr); @@ -3482,6 +3533,17 @@ elf32_rx_modify_program_headers (bfd * abfd ATTRIBUTE_UNUSED, return TRUE; } + +/* The default literal sections should always be marked as "code" (i.e., + SHF_EXECINSTR). This is particularly important for big-endian mode + when we do not want their contents byte reversed. */ +static const struct bfd_elf_special_section elf32_rx_special_sections[] = +{ + { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_EXECINSTR }, + { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_EXECINSTR }, + { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_EXECINSTR }, + { NULL, 0, 0, 0, 0 } +}; #define ELF_ARCH bfd_arch_rx #define ELF_MACHINE_CODE EM_RX @@ -3510,6 +3572,7 @@ elf32_rx_modify_program_headers (bfd * abfd ATTRIBUTE_UNUSED, #define bfd_elf32_set_section_contents rx_set_section_contents #define bfd_elf32_bfd_final_link rx_final_link #define bfd_elf32_bfd_relax_section elf32_rx_relax_section_wrapper +#define elf_backend_special_sections elf32_rx_special_sections #include "elf32-target.h"