X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf32-sh.c;h=9ec745be199388b3183f0e67b1b6b06d5989d97d;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=c0a3368cc88a57bee68875c54e1462c47883949b;hpb=695344c018c8e462280c47a644df02ea472b0a4e;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index c0a3368cc8..9ec745be19 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -1,5 +1,5 @@ /* Renesas / SuperH SH specific support for 32-bit ELF - Copyright (C) 1996-2016 Free Software Foundation, Inc. + Copyright (C) 1996-2020 Free Software Foundation, Inc. Contributed by Ian Lance Taylor, Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -30,6 +30,9 @@ #include "libiberty.h" #include "../opcodes/sh-opc.h" +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ +#define OCTETS_PER_BYTE(ABFD, SEC) 1 + static bfd_reloc_status_type sh_elf_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type sh_elf_ignore_reloc @@ -38,10 +41,8 @@ static bfd_boolean sh_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int); static bfd_boolean sh_elf_align_loads (bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_boolean *); -#ifndef SH64_ELF static bfd_boolean sh_elf_swap_insns (bfd *, asection *, void *, bfd_byte *, bfd_vma); -#endif static int sh_elf_optimized_tls_reloc (struct bfd_link_info *, int, int); static bfd_vma dtpoff_base @@ -87,7 +88,7 @@ static reloc_howto_type sh_vxworks_howto_table[] = static bfd_boolean vxworks_object_p (bfd *abfd ATTRIBUTE_UNUSED) { -#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED +#if !defined SH_TARGET_ALREADY_DEFINED extern const bfd_target sh_elf32_vxworks_le_vec; extern const bfd_target sh_elf32_vxworks_vec; @@ -103,7 +104,7 @@ vxworks_object_p (bfd *abfd ATTRIBUTE_UNUSED) static bfd_boolean fdpic_object_p (bfd *abfd ATTRIBUTE_UNUSED) { -#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED +#if !defined SH_TARGET_ALREADY_DEFINED extern const bfd_target sh_elf32_fdpic_le_vec; extern const bfd_target sh_elf32_fdpic_be_vec; @@ -166,8 +167,7 @@ sh_elf_reloc_loop (int r_type ATTRIBUTE_UNUSED, bfd *input_bfd, if (!bfd_malloc_and_get_section (input_bfd, symbol_section, &contents)) { - if (contents != NULL) - free (contents); + free (contents); return bfd_reloc_outofrange; } } @@ -202,8 +202,7 @@ sh_elf_reloc_loop (int r_type ATTRIBUTE_UNUSED, bfd *input_bfd, end = start0; } - if (contents != NULL - && elf_section_data (symbol_section)->this_hdr.contents != contents) + if (elf_section_data (symbol_section)->this_hdr.contents != contents) free (contents); insn = bfd_get_16 (input_bfd, contents + addr); @@ -231,11 +230,12 @@ sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in, void *data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) { - unsigned long insn; + bfd_vma insn; bfd_vma sym_value; enum elf_sh_reloc_type r_type; bfd_vma addr = reloc_entry->address; - bfd_byte *hit_data = addr + (bfd_byte *) data; + bfd_size_type octets = addr * OCTETS_PER_BYTE (abfd, input_section); + bfd_byte *hit_data = (bfd_byte *) data + octets; r_type = (enum elf_sh_reloc_type) reloc_entry->howto->type; @@ -256,7 +256,7 @@ sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in, return bfd_reloc_undefined; /* PR 17512: file: 9891ca98. */ - if (addr * bfd_octets_per_byte (abfd) + bfd_get_reloc_size (reloc_entry->howto) + if (octets + bfd_get_reloc_size (reloc_entry->howto) > bfd_get_section_limit_octets (abfd, input_section)) return bfd_reloc_outofrange; @@ -272,7 +272,7 @@ sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in, case R_SH_DIR32: insn = bfd_get_32 (abfd, hit_data); insn += sym_value + reloc_entry->addend; - bfd_put_32 (abfd, (bfd_vma) insn, hit_data); + bfd_put_32 (abfd, insn, hit_data); break; case R_SH_IND12W: insn = bfd_get_16 (abfd, hit_data); @@ -281,12 +281,10 @@ sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in, + input_section->output_offset + addr + 4); - sym_value += (insn & 0xfff) << 1; - if (insn & 0x800) - sym_value -= 0x1000; - insn = (insn & 0xf000) | (sym_value & 0xfff); - bfd_put_16 (abfd, (bfd_vma) insn, hit_data); - if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000) + sym_value += (((insn & 0xfff) ^ 0x800) - 0x800) << 1; + insn = (insn & 0xf000) | ((sym_value >> 1) & 0xfff); + bfd_put_16 (abfd, insn, hit_data); + if (sym_value + 0x1000 >= 0x2000 || (sym_value & 1) != 0) return bfd_reloc_overflow; break; default: @@ -371,57 +369,6 @@ static const struct elf_reloc_map sh_reloc_map[] = { BFD_RELOC_SH_GOTOFFFUNCDESC, R_SH_GOTOFFFUNCDESC }, { BFD_RELOC_SH_GOTOFFFUNCDESC20, R_SH_GOTOFFFUNCDESC20 }, { BFD_RELOC_SH_FUNCDESC, R_SH_FUNCDESC }, -#ifdef INCLUDE_SHMEDIA - { BFD_RELOC_SH_GOT_LOW16, R_SH_GOT_LOW16 }, - { BFD_RELOC_SH_GOT_MEDLOW16, R_SH_GOT_MEDLOW16 }, - { BFD_RELOC_SH_GOT_MEDHI16, R_SH_GOT_MEDHI16 }, - { BFD_RELOC_SH_GOT_HI16, R_SH_GOT_HI16 }, - { BFD_RELOC_SH_GOTPLT_LOW16, R_SH_GOTPLT_LOW16 }, - { BFD_RELOC_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDLOW16 }, - { BFD_RELOC_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_MEDHI16 }, - { BFD_RELOC_SH_GOTPLT_HI16, R_SH_GOTPLT_HI16 }, - { BFD_RELOC_SH_PLT_LOW16, R_SH_PLT_LOW16 }, - { BFD_RELOC_SH_PLT_MEDLOW16, R_SH_PLT_MEDLOW16 }, - { BFD_RELOC_SH_PLT_MEDHI16, R_SH_PLT_MEDHI16 }, - { BFD_RELOC_SH_PLT_HI16, R_SH_PLT_HI16 }, - { BFD_RELOC_SH_GOTOFF_LOW16, R_SH_GOTOFF_LOW16 }, - { BFD_RELOC_SH_GOTOFF_MEDLOW16, R_SH_GOTOFF_MEDLOW16 }, - { BFD_RELOC_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_MEDHI16 }, - { BFD_RELOC_SH_GOTOFF_HI16, R_SH_GOTOFF_HI16 }, - { BFD_RELOC_SH_GOTPC_LOW16, R_SH_GOTPC_LOW16 }, - { BFD_RELOC_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDLOW16 }, - { BFD_RELOC_SH_GOTPC_MEDHI16, R_SH_GOTPC_MEDHI16 }, - { BFD_RELOC_SH_GOTPC_HI16, R_SH_GOTPC_HI16 }, - { BFD_RELOC_SH_COPY64, R_SH_COPY64 }, - { BFD_RELOC_SH_GLOB_DAT64, R_SH_GLOB_DAT64 }, - { BFD_RELOC_SH_JMP_SLOT64, R_SH_JMP_SLOT64 }, - { BFD_RELOC_SH_RELATIVE64, R_SH_RELATIVE64 }, - { BFD_RELOC_SH_GOT10BY4, R_SH_GOT10BY4 }, - { BFD_RELOC_SH_GOT10BY8, R_SH_GOT10BY8 }, - { BFD_RELOC_SH_GOTPLT10BY4, R_SH_GOTPLT10BY4 }, - { BFD_RELOC_SH_GOTPLT10BY8, R_SH_GOTPLT10BY8 }, - { BFD_RELOC_SH_PT_16, R_SH_PT_16 }, - { BFD_RELOC_SH_SHMEDIA_CODE, R_SH_SHMEDIA_CODE }, - { BFD_RELOC_SH_IMMU5, R_SH_DIR5U }, - { BFD_RELOC_SH_IMMS6, R_SH_DIR6S }, - { BFD_RELOC_SH_IMMU6, R_SH_DIR6U }, - { BFD_RELOC_SH_IMMS10, R_SH_DIR10S }, - { BFD_RELOC_SH_IMMS10BY2, R_SH_DIR10SW }, - { BFD_RELOC_SH_IMMS10BY4, R_SH_DIR10SL }, - { BFD_RELOC_SH_IMMS10BY8, R_SH_DIR10SQ }, - { BFD_RELOC_SH_IMMS16, R_SH_IMMS16 }, - { BFD_RELOC_SH_IMMU16, R_SH_IMMU16 }, - { BFD_RELOC_SH_IMM_LOW16, R_SH_IMM_LOW16 }, - { BFD_RELOC_SH_IMM_LOW16_PCREL, R_SH_IMM_LOW16_PCREL }, - { BFD_RELOC_SH_IMM_MEDLOW16, R_SH_IMM_MEDLOW16 }, - { BFD_RELOC_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDLOW16_PCREL }, - { BFD_RELOC_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16 }, - { BFD_RELOC_SH_IMM_MEDHI16_PCREL, R_SH_IMM_MEDHI16_PCREL }, - { BFD_RELOC_SH_IMM_HI16, R_SH_IMM_HI16 }, - { BFD_RELOC_SH_IMM_HI16_PCREL, R_SH_IMM_HI16_PCREL }, - { BFD_RELOC_64, R_SH_64 }, - { BFD_RELOC_64_PCREL, R_SH_64_PCREL }, -#endif /* not INCLUDE_SHMEDIA */ }; /* Given a BFD reloc code, return the howto structure for the @@ -472,7 +419,7 @@ sh_elf_reloc_name_lookup (bfd *abfd, const char *r_name) /* Given an ELF reloc, fill in the howto field of a relent. */ -static void +static bfd_boolean sh_elf_info_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) { unsigned int r; @@ -488,13 +435,14 @@ sh_elf_info_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) || (r >= R_SH_FIRST_INVALID_RELOC_6 && r <= R_SH_LAST_INVALID_RELOC_6)) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: unrecognised SH reloc number: %d"), + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r); bfd_set_error (bfd_error_bad_value); - r = R_SH_NONE; + return FALSE; } cache_ptr->howto = get_howto_table (abfd) + r; + return TRUE; } /* This function handles relaxing for SH ELF. See the corresponding @@ -525,14 +473,6 @@ sh_elf_relax_section (bfd *abfd, asection *sec, || sec->reloc_count == 0) return TRUE; -#ifdef INCLUDE_SHMEDIA - if (elf_section_data (sec)->this_hdr.sh_flags - & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) - { - return TRUE; - } -#endif - symtab_hdr = &elf_symtab_hdr (abfd); internal_relocs = (_bfd_elf_link_read_relocs @@ -577,8 +517,9 @@ sh_elf_relax_section (bfd *abfd, asection *sec, if (laddr >= sec->size) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: 0x%lx: warning: bad R_SH_USES offset"), - abfd, (unsigned long) irel->r_offset); + _bfd_error_handler + (_("%pB: %#" PRIx64 ": warning: bad R_SH_USES offset"), + abfd, (uint64_t) irel->r_offset); continue; } insn = bfd_get_16 (abfd, contents + laddr); @@ -589,8 +530,9 @@ sh_elf_relax_section (bfd *abfd, asection *sec, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"), - abfd, (unsigned long) irel->r_offset, insn); + (_("%pB: %#" PRIx64 ": warning: " + "R_SH_USES points to unrecognized insn 0x%x"), + abfd, (uint64_t) irel->r_offset, insn); continue; } @@ -607,8 +549,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: warning: bad R_SH_USES load offset"), - abfd, (unsigned long) irel->r_offset); + (_("%pB: %#" PRIx64 ": warning: bad R_SH_USES load offset"), + abfd, (uint64_t) irel->r_offset); continue; } @@ -623,8 +565,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: warning: could not find expected reloc"), - abfd, (unsigned long) paddr); + (_("%pB: %#" PRIx64 ": warning: could not find expected reloc"), + abfd, (uint64_t) paddr); continue; } @@ -652,8 +594,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: warning: symbol in unexpected section"), - abfd, (unsigned long) paddr); + (_("%pB: %#" PRIx64 ": warning: symbol in unexpected section"), + abfd, (uint64_t) paddr); continue; } @@ -782,8 +724,9 @@ sh_elf_relax_section (bfd *abfd, asection *sec, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: warning: could not find expected COUNT reloc"), - abfd, (unsigned long) paddr); + (_("%pB: %#" PRIx64 ": warning: " + "could not find expected COUNT reloc"), + abfd, (uint64_t) paddr); continue; } @@ -792,8 +735,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec, if (irelcount->r_addend == 0) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: 0x%lx: warning: bad count"), - abfd, (unsigned long) paddr); + _bfd_error_handler (_("%pB: %#" PRIx64 ": warning: bad count"), + abfd, (uint64_t) paddr); continue; } @@ -866,21 +809,17 @@ sh_elf_relax_section (bfd *abfd, asection *sec, } } - if (internal_relocs != NULL - && elf_section_data (sec)->relocs != internal_relocs) + if (elf_section_data (sec)->relocs != internal_relocs) free (internal_relocs); return TRUE; error_return: - if (isymbuf != NULL - && symtab_hdr->contents != (unsigned char *) isymbuf) + if (symtab_hdr->contents != (unsigned char *) isymbuf) free (isymbuf); - if (contents != NULL - && elf_section_data (sec)->this_hdr.contents != contents) + if (elf_section_data (sec)->this_hdr.contents != contents) free (contents); - if (internal_relocs != NULL - && elf_section_data (sec)->relocs != internal_relocs) + if (elf_section_data (sec)->relocs != internal_relocs) free (internal_relocs); return FALSE; @@ -913,7 +852,7 @@ sh_elf_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, contents = elf_section_data (sec)->this_hdr.contents; - /* The deletion must stop at the next ALIGN reloc for an aligment + /* The deletion must stop at the next ALIGN reloc for an alignment power larger than the number of bytes we are deleting. */ irelalign = NULL; @@ -1196,8 +1135,8 @@ sh_elf_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: fatal: reloc overflow while relaxing"), - abfd, (unsigned long) irel->r_offset); + (_("%pB: %#" PRIx64 ": fatal: reloc overflow while relaxing"), + abfd, (uint64_t) irel->r_offset); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1250,8 +1189,7 @@ sh_elf_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, when we leave sh_coff_relax_section. */ if (!bfd_malloc_and_get_section (abfd, o, &ocontents)) { - if (ocontents != NULL) - free (ocontents); + free (ocontents); return FALSE; } @@ -1308,8 +1246,7 @@ sh_elf_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, when we leave sh_coff_relax_section. */ if (!bfd_malloc_and_get_section (abfd, o, &ocontents)) { - if (ocontents != NULL) - free (ocontents); + free (ocontents); return FALSE; } @@ -1442,12 +1379,10 @@ sh_elf_align_loads (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, return TRUE; error_return: - if (labels != NULL) - free (labels); + free (labels); return FALSE; } -#ifndef SH64_ELF /* Swap two SH instructions. This is like sh_swap_insns in coff-sh.c. */ static bfd_boolean @@ -1567,8 +1502,8 @@ sh_elf_swap_insns (bfd *abfd, asection *sec, void *relocs, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: fatal: reloc overflow while relaxing"), - abfd, (unsigned long) irel->r_offset); + (_("%pB: %#" PRIx64 ": fatal: reloc overflow while relaxing"), + abfd, (uint64_t) irel->r_offset); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1577,7 +1512,6 @@ sh_elf_swap_insns (bfd *abfd, asection *sec, void *relocs, return TRUE; } -#endif /* defined SH64_ELF */ /* Describes one of the various PLT styles. */ @@ -1622,223 +1556,6 @@ struct elf_sh_plt_info const struct elf_sh_plt_info *short_plt; }; -#ifdef INCLUDE_SHMEDIA - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define ELF_PLT_ENTRY_SIZE 64 - -/* First entry in an absolute procedure linkage table look like this. */ - -static const bfd_byte elf_sh_plt0_entry_be[ELF_PLT_ENTRY_SIZE] = -{ - 0xcc, 0x00, 0x01, 0x10, /* movi .got.plt >> 16, r17 */ - 0xc8, 0x00, 0x01, 0x10, /* shori .got.plt & 65535, r17 */ - 0x89, 0x10, 0x09, 0x90, /* ld.l r17, 8, r25 */ - 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ - 0x89, 0x10, 0x05, 0x10, /* ld.l r17, 4, r17 */ - 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ -}; - -static const bfd_byte elf_sh_plt0_entry_le[ELF_PLT_ENTRY_SIZE] = -{ - 0x10, 0x01, 0x00, 0xcc, /* movi .got.plt >> 16, r17 */ - 0x10, 0x01, 0x00, 0xc8, /* shori .got.plt & 65535, r17 */ - 0x90, 0x09, 0x10, 0x89, /* ld.l r17, 8, r25 */ - 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ - 0x10, 0x05, 0x10, 0x89, /* ld.l r17, 4, r17 */ - 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ -}; - -/* Sebsequent entries in an absolute procedure linkage table look like - this. */ - -static const bfd_byte elf_sh_plt_entry_be[ELF_PLT_ENTRY_SIZE] = -{ - 0xcc, 0x00, 0x01, 0x90, /* movi nameN-in-GOT >> 16, r25 */ - 0xc8, 0x00, 0x01, 0x90, /* shori nameN-in-GOT & 65535, r25 */ - 0x89, 0x90, 0x01, 0x90, /* ld.l r25, 0, r25 */ - 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ - 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0xcc, 0x00, 0x01, 0x90, /* movi .PLT0 >> 16, r25 */ - 0xc8, 0x00, 0x01, 0x90, /* shori .PLT0 & 65535, r25 */ - 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ - 0xcc, 0x00, 0x01, 0x50, /* movi reloc-offset >> 16, r21 */ - 0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */ - 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ -}; - -static const bfd_byte elf_sh_plt_entry_le[ELF_PLT_ENTRY_SIZE] = -{ - 0x90, 0x01, 0x00, 0xcc, /* movi nameN-in-GOT >> 16, r25 */ - 0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */ - 0x90, 0x01, 0x90, 0x89, /* ld.l r25, 0, r25 */ - 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ - 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0x90, 0x01, 0x00, 0xcc, /* movi .PLT0 >> 16, r25 */ - 0x90, 0x01, 0x00, 0xc8, /* shori .PLT0 & 65535, r25 */ - 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ - 0x50, 0x01, 0x00, 0xcc, /* movi reloc-offset >> 16, r21 */ - 0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */ - 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ -}; - -/* Entries in a PIC procedure linkage table look like this. */ - -static const bfd_byte elf_sh_pic_plt_entry_be[ELF_PLT_ENTRY_SIZE] = -{ - 0xcc, 0x00, 0x01, 0x90, /* movi nameN@GOT >> 16, r25 */ - 0xc8, 0x00, 0x01, 0x90, /* shori nameN@GOT & 65535, r25 */ - 0x40, 0xc2, 0x65, 0x90, /* ldx.l r12, r25, r25 */ - 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ - 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0xce, 0x00, 0x01, 0x10, /* movi -GOT_BIAS, r17 */ - 0x00, 0xc8, 0x45, 0x10, /* add.l r12, r17, r17 */ - 0x89, 0x10, 0x09, 0x90, /* ld.l r17, 8, r25 */ - 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ - 0x89, 0x10, 0x05, 0x10, /* ld.l r17, 4, r17 */ - 0xcc, 0x00, 0x01, 0x50, /* movi reloc-offset >> 16, r21 */ - 0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */ - 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */ -}; - -static const bfd_byte elf_sh_pic_plt_entry_le[ELF_PLT_ENTRY_SIZE] = -{ - 0x90, 0x01, 0x00, 0xcc, /* movi nameN@GOT >> 16, r25 */ - 0x90, 0x01, 0x00, 0xc8, /* shori nameN@GOT & 65535, r25 */ - 0x90, 0x65, 0xc2, 0x40, /* ldx.l r12, r25, r25 */ - 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ - 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0x10, 0x01, 0x00, 0xce, /* movi -GOT_BIAS, r17 */ - 0x10, 0x45, 0xc8, 0x00, /* add.l r12, r17, r17 */ - 0x90, 0x09, 0x10, 0x89, /* ld.l r17, 8, r25 */ - 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ - 0x10, 0x05, 0x10, 0x89, /* ld.l r17, 4, r17 */ - 0x50, 0x01, 0x00, 0xcc, /* movi reloc-offset >> 16, r21 */ - 0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */ - 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */ -}; - -static const struct elf_sh_plt_info elf_sh_plts[2][2] = { - { - { - /* Big-endian non-PIC. */ - elf_sh_plt0_entry_be, - ELF_PLT_ENTRY_SIZE, - { 0, MINUS_ONE, MINUS_ONE }, - elf_sh_plt_entry_be, - ELF_PLT_ENTRY_SIZE, - { 0, 32, 48, FALSE }, - 33, /* includes ISA encoding */ - NULL - }, - { - /* Little-endian non-PIC. */ - elf_sh_plt0_entry_le, - ELF_PLT_ENTRY_SIZE, - { 0, MINUS_ONE, MINUS_ONE }, - elf_sh_plt_entry_le, - ELF_PLT_ENTRY_SIZE, - { 0, 32, 48, FALSE }, - 33, /* includes ISA encoding */ - NULL - }, - }, - { - { - /* Big-endian PIC. */ - elf_sh_plt0_entry_be, - ELF_PLT_ENTRY_SIZE, - { MINUS_ONE, MINUS_ONE, MINUS_ONE }, - elf_sh_pic_plt_entry_be, - ELF_PLT_ENTRY_SIZE, - { 0, MINUS_ONE, 52, FALSE }, - 33, /* includes ISA encoding */ - NULL - }, - { - /* Little-endian PIC. */ - elf_sh_plt0_entry_le, - ELF_PLT_ENTRY_SIZE, - { MINUS_ONE, MINUS_ONE, MINUS_ONE }, - elf_sh_pic_plt_entry_le, - ELF_PLT_ENTRY_SIZE, - { 0, MINUS_ONE, 52, FALSE }, - 33, /* includes ISA encoding */ - NULL - }, - } -}; - -/* Return offset of the linker in PLT0 entry. */ -#define elf_sh_plt0_gotplt_offset(info) 0 - -/* Install a 32-bit PLT field starting at ADDR, which occurs in OUTPUT_BFD. - VALUE is the field's value and CODE_P is true if VALUE refers to code, - not data. - - On SH64, each 32-bit field is loaded by a movi/shori pair. */ - -inline static void -install_plt_field (bfd *output_bfd, bfd_boolean code_p, - unsigned long value, bfd_byte *addr) -{ - value |= code_p; - bfd_put_32 (output_bfd, - bfd_get_32 (output_bfd, addr) - | ((value >> 6) & 0x3fffc00), - addr); - bfd_put_32 (output_bfd, - bfd_get_32 (output_bfd, addr + 4) - | ((value << 10) & 0x3fffc00), - addr + 4); -} - -/* Return the type of PLT associated with ABFD. PIC_P is true if - the object is position-independent. */ - -static const struct elf_sh_plt_info * -get_plt_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean pic_p) -{ - return &elf_sh_plts[pic_p][!bfd_big_endian (abfd)]; -} -#else /* The size in bytes of an entry in the procedure linkage table. */ #define ELF_PLT_ENTRY_SIZE 28 @@ -2317,7 +2034,6 @@ install_plt_field (bfd *output_bfd, bfd_boolean code_p ATTRIBUTE_UNUSED, { bfd_put_32 (output_bfd, value, addr); } -#endif /* The number of PLT entries which can use a shorter PLT, if any. Currently always 64K, since only SH-2A FDPIC uses this; a @@ -2367,26 +2083,6 @@ get_plt_offset (const struct elf_sh_plt_info *info, bfd_vma plt_index) + (plt_index * info->symbol_entry_size)); } -/* The sh linker needs to keep track of the number of relocs that it - decides to copy as dynamic relocs in check_relocs for each symbol. - This is so that it can later discard them if they are found to be - unnecessary. We store the information in a field extending the - regular ELF linker hash table. */ - -struct elf_sh_dyn_relocs -{ - struct elf_sh_dyn_relocs *next; - - /* The input section of the reloc. */ - asection *sec; - - /* Total number of relocs copied for the input section. */ - bfd_size_type count; - - /* Number of pc-relative relocs copied for the input section. */ - bfd_size_type pc_count; -}; - union gotref { bfd_signed_vma refcount; @@ -2399,17 +2095,6 @@ struct elf_sh_link_hash_entry { struct elf_link_hash_entry root; -#ifdef INCLUDE_SHMEDIA - union - { - bfd_signed_vma refcount; - bfd_vma offset; - } datalabel_got; -#endif - - /* Track dynamic relocs copied for this symbol. */ - struct elf_sh_dyn_relocs *dyn_relocs; - bfd_signed_vma gotplt_refcount; /* A local function descriptor, for FDPIC. The refcount counts @@ -2475,11 +2160,6 @@ struct elf_sh_link_hash_table struct elf_link_hash_table root; /* Short-cuts to get to dynamic linker sections. */ - asection *sgot; - asection *sgotplt; - asection *srelgot; - asection *splt; - asection *srelplt; asection *sdynbss; asection *srelbss; asection *sfuncdesc; @@ -2548,11 +2228,7 @@ sh_elf_link_hash_newfunc (struct bfd_hash_entry *entry, table, string)); if (ret != (struct elf_sh_link_hash_entry *) NULL) { - ret->dyn_relocs = NULL; ret->gotplt_refcount = 0; -#ifdef INCLUDE_SHMEDIA - ret->datalabel_got.refcount = ret->root.got.refcount; -#endif ret->funcdesc.refcount = 0; ret->abs_funcdesc_refcount = 0; ret->got_type = GOT_UNKNOWN; @@ -2567,7 +2243,7 @@ static struct bfd_link_hash_table * sh_elf_link_hash_table_create (bfd *abfd) { struct elf_sh_link_hash_table *ret; - bfd_size_type amt = sizeof (struct elf_sh_link_hash_table); + size_t amt = sizeof (struct elf_sh_link_hash_table); ret = (struct elf_sh_link_hash_table *) bfd_zmalloc (amt); if (ret == (struct elf_sh_link_hash_table *) NULL) @@ -2631,19 +2307,13 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info) if (htab == NULL) return FALSE; - htab->sgot = bfd_get_linker_section (dynobj, ".got"); - htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt"); - htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got"); - if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot) - abort (); - htab->sfuncdesc = bfd_make_section_anyway_with_flags (dynobj, ".got.funcdesc", (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)); if (htab->sfuncdesc == NULL - || ! bfd_set_section_alignment (dynobj, htab->sfuncdesc, 2)) + || !bfd_set_section_alignment (htab->sfuncdesc, 2)) return FALSE; htab->srelfuncdesc = bfd_make_section_anyway_with_flags (dynobj, @@ -2654,7 +2324,7 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info) | SEC_LINKER_CREATED | SEC_READONLY)); if (htab->srelfuncdesc == NULL - || ! bfd_set_section_alignment (dynobj, htab->srelfuncdesc, 2)) + || !bfd_set_section_alignment (htab->srelfuncdesc, 2)) return FALSE; /* Also create .rofixup. */ @@ -2665,7 +2335,7 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info) | SEC_LINKER_CREATED | SEC_READONLY)); if (htab->srofixup == NULL - || ! bfd_set_section_alignment (dynobj, htab->srofixup, 2)) + || !bfd_set_section_alignment (htab->srofixup, 2)) return FALSE; return TRUE; @@ -2718,9 +2388,9 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) pltflags |= SEC_READONLY; s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags); - htab->splt = s; + htab->root.splt = s; if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) + || !bfd_set_section_alignment (s, bed->plt_alignment)) return FALSE; if (bed->want_plt_sym) @@ -2750,12 +2420,12 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) bed->default_use_rela_p ? ".rela.plt" : ".rel.plt", flags | SEC_READONLY); - htab->srelplt = s; + htab->root.srelplt = s; if (s == NULL - || ! bfd_set_section_alignment (abfd, s, ptralign)) + || !bfd_set_section_alignment (s, ptralign)) return FALSE; - if (htab->sgot == NULL + if (htab->root.sgot == NULL && !create_got_section (abfd, info)) return FALSE; @@ -2792,7 +2462,7 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) flags | SEC_READONLY); htab->srelbss = s; if (s == NULL - || ! bfd_set_section_alignment (abfd, s, ptralign)) + || !bfd_set_section_alignment (s, ptralign)) return FALSE; } } @@ -2817,8 +2487,6 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h) { struct elf_sh_link_hash_table *htab; - struct elf_sh_link_hash_entry *eh; - struct elf_sh_dyn_relocs *p; asection *s; htab = sh_elf_hash_table (info); @@ -2828,7 +2496,7 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info, /* Make sure we know what is going on here. */ BFD_ASSERT (htab->root.dynobj != NULL && (h->needs_plt - || h->u.weakdef != NULL + || h->is_weakalias || (h->def_dynamic && h->ref_regular && !h->def_regular))); @@ -2861,14 +2529,14 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info, /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the real definition first, and we can just use the same value. */ - if (h->u.weakdef != NULL) + if (h->is_weakalias) { - BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined - || h->u.weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->u.weakdef->root.u.def.section; - h->root.u.def.value = h->u.weakdef->root.u.def.value; + struct elf_link_hash_entry *def = weakdef (h); + BFD_ASSERT (def->root.type == bfd_link_hash_defined); + h->root.u.def.section = def->root.u.def.section; + h->root.u.def.value = def->root.u.def.value; if (info->nocopyreloc) - h->non_got_ref = h->u.weakdef->non_got_ref; + h->non_got_ref = def->non_got_ref; return TRUE; } @@ -2888,24 +2556,15 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info, return TRUE; /* If -z nocopyreloc was given, we won't generate them either. */ - if (info->nocopyreloc) + if (0 && info->nocopyreloc) { h->non_got_ref = 0; return TRUE; } - eh = (struct elf_sh_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - s = p->sec->output_section; - if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0) - break; - } - - /* If we didn't find any dynamic relocs in sections which needs the - copy reloc, then we'll be keeping the dynamic relocs and avoiding - the copy reloc. */ - if (p == NULL) + /* If we don't find any dynamic relocs in read-only sections, then + we'll be keeping the dynamic relocs and avoiding the copy reloc. */ + if (0 && !_bfd_elf_readonly_dynrelocs (h)) { h->non_got_ref = 0; return TRUE; @@ -2950,7 +2609,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) struct bfd_link_info *info; struct elf_sh_link_hash_table *htab; struct elf_sh_link_hash_entry *eh; - struct elf_sh_dyn_relocs *p; + struct elf_dyn_relocs *p; if (h->root.type == bfd_link_hash_indirect) return TRUE; @@ -2989,7 +2648,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) { - asection *s = htab->splt; + asection *s = htab->root.splt; const struct elf_sh_plt_info *plt_info; /* If this is the first .plt entry, make room for the special @@ -3022,12 +2681,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* We also need to make an entry in the .got.plt section, which will be placed in the .got section by the linker script. */ if (!htab->fdpic_p) - htab->sgotplt->size += 4; + htab->root.sgotplt->size += 4; else - htab->sgotplt->size += 8; + htab->root.sgotplt->size += 8; /* We also need to make an entry in the .rel.plt section. */ - htab->srelplt->size += sizeof (Elf32_External_Rela); + htab->root.srelplt->size += sizeof (Elf32_External_Rela); if (htab->vxworks_p && !bfd_link_pic (info)) { @@ -3073,7 +2732,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return FALSE; } - s = htab->sgot; + s = htab->root.sgot; h->got.offset = s->size; s->size += 4; /* R_SH_TLS_GD needs 2 consecutive GOT slots. */ @@ -3097,21 +2756,21 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) R_SH_TLS_GD needs one if local symbol and two if global. */ else if ((got_type == GOT_TLS_GD && h->dynindx == -1) || got_type == GOT_TLS_IE) - htab->srelgot->size += sizeof (Elf32_External_Rela); + htab->root.srelgot->size += sizeof (Elf32_External_Rela); else if (got_type == GOT_TLS_GD) - htab->srelgot->size += 2 * sizeof (Elf32_External_Rela); + htab->root.srelgot->size += 2 * sizeof (Elf32_External_Rela); else if (got_type == GOT_FUNCDESC) { if (!bfd_link_pic (info) && SYMBOL_FUNCDESC_LOCAL (info, h)) htab->srofixup->size += 4; else - htab->srelgot->size += sizeof (Elf32_External_Rela); + htab->root.srelgot->size += sizeof (Elf32_External_Rela); } else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || h->root.type != bfd_link_hash_undefweak) && (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) - htab->srelgot->size += sizeof (Elf32_External_Rela); + htab->root.srelgot->size += sizeof (Elf32_External_Rela); else if (htab->fdpic_p && !bfd_link_pic (info) && got_type == GOT_NORMAL @@ -3122,32 +2781,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) else h->got.offset = (bfd_vma) -1; -#ifdef INCLUDE_SHMEDIA - if (eh->datalabel_got.refcount > 0) - { - asection *s; - bfd_boolean dyn; - - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (h->dynindx == -1 - && !h->forced_local) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - - s = htab->sgot; - eh->datalabel_got.offset = s->size; - s->size += 4; - dyn = htab->root.dynamic_sections_created; - if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)) - htab->srelgot->size += sizeof (Elf32_External_Rela); - } - else - eh->datalabel_got.offset = (bfd_vma) -1; -#endif - /* Allocate space for any dynamic relocations to function descriptors, canonical or otherwise. We need to relocate the reference unless it resolves to zero, which only happens for @@ -3161,7 +2794,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (!bfd_link_pic (info) && SYMBOL_FUNCDESC_LOCAL (info, h)) htab->srofixup->size += eh->abs_funcdesc_refcount * 4; else - htab->srelgot->size + htab->root.srelgot->size += eh->abs_funcdesc_refcount * sizeof (Elf32_External_Rela); } @@ -3188,7 +2821,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) htab->srelfuncdesc->size += sizeof (Elf32_External_Rela); } - if (eh->dyn_relocs == NULL) + if (h->dyn_relocs == NULL) return TRUE; /* In the shared -Bsymbolic case, discard space allocated for @@ -3201,9 +2834,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) { if (SYMBOL_CALLS_LOCAL (info, h)) { - struct elf_sh_dyn_relocs **pp; + struct elf_dyn_relocs **pp; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + for (pp = &h->dyn_relocs; (p = *pp) != NULL; ) { p->count -= p->pc_count; p->pc_count = 0; @@ -3216,9 +2849,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (htab->vxworks_p) { - struct elf_sh_dyn_relocs **pp; + struct elf_dyn_relocs **pp; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + for (pp = &h->dyn_relocs; (p = *pp) != NULL; ) { if (strcmp (p->sec->output_section->name, ".tls_vars") == 0) *pp = p->next; @@ -3229,11 +2862,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Also discard relocs on undefined weak syms with non-default visibility. */ - if (eh->dyn_relocs != NULL + if (h->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak) { - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - eh->dyn_relocs = NULL; + if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) + h->dyn_relocs = NULL; /* Make sure undefined weak symbols are output as a dynamic symbol in PIEs. */ @@ -3273,13 +2907,13 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) goto keep; } - eh->dyn_relocs = NULL; + h->dyn_relocs = NULL; keep: ; } /* Finally, allocate space. */ - for (p = eh->dyn_relocs; p != NULL; p = p->next) + for (p = h->dyn_relocs; p != NULL; p = p->next) { asection *sreloc = elf_section_data (p->sec)->sreloc; sreloc->size += p->count * sizeof (Elf32_External_Rela); @@ -3292,32 +2926,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ - -static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) -{ - struct elf_sh_link_hash_entry *eh; - struct elf_sh_dyn_relocs *p; - - eh = (struct elf_sh_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; - - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; - - info->flags |= DF_TEXTREL; - - /* Not an error, just cut short the traversal. */ - return FALSE; - } - } - return TRUE; -} - /* This function is called after all the input files have been read, and the input sections have been assigned to output sections. It's a convenient place to determine the PLT style. */ @@ -3383,9 +2991,9 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, for (s = ibfd->sections; s != NULL; s = s->next) { - struct elf_sh_dyn_relocs *p; + struct elf_dyn_relocs *p; - for (p = ((struct elf_sh_dyn_relocs *) + for (p = ((struct elf_dyn_relocs *) elf_section_data (s)->local_dynrel); p != NULL; p = p->next) @@ -3410,7 +3018,11 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, srel = elf_section_data (p->sec)->sreloc; srel->size += p->count * sizeof (Elf32_External_Rela); if ((p->sec->output_section->flags & SEC_READONLY) != 0) - info->flags |= DF_TEXTREL; + { + info->flags |= DF_TEXTREL; + info->callbacks->minfo (_("%pB: dynamic relocation in read-only section `%pA'\n"), + p->sec->owner, p->sec); + } /* If we need relocations, we do not need fixups. */ if (htab->fdpic_p && !bfd_link_pic (info)) @@ -3421,12 +3033,8 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, symtab_hdr = &elf_symtab_hdr (ibfd); locsymcount = symtab_hdr->sh_info; -#ifdef INCLUDE_SHMEDIA - /* Count datalabel local GOT. */ - locsymcount *= 2; -#endif - s = htab->sgot; - srel = htab->srelgot; + s = htab->root.sgot; + srel = htab->root.srelgot; local_got = elf_local_got_refcounts (ibfd); if (local_got) @@ -3499,9 +3107,9 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, { /* Allocate 2 got entries and 1 dynamic reloc for R_SH_TLS_LD_32 relocs. */ - htab->tls_ldm_got.offset = htab->sgot->size; - htab->sgot->size += 8; - htab->srelgot->size += sizeof (Elf32_External_Rela); + htab->tls_ldm_got.offset = htab->root.sgot->size; + htab->root.sgot->size += 8; + htab->root.srelgot->size += sizeof (Elf32_External_Rela); } else htab->tls_ldm_got.offset = -1; @@ -3510,8 +3118,8 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, the end of .got.plt. */ if (htab->fdpic_p) { - BFD_ASSERT (htab->sgotplt && htab->sgotplt->size == 12); - htab->sgotplt->size = 0; + BFD_ASSERT (htab->root.sgotplt && htab->root.sgotplt->size == 12); + htab->root.sgotplt->size = 0; } /* Allocate global sym .plt and .got entries, and space for global @@ -3522,8 +3130,8 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, end of the FDPIC .got.plt. */ if (htab->fdpic_p) { - htab->root.hgot->root.u.def.value = htab->sgotplt->size; - htab->sgotplt->size += 12; + htab->root.hgot->root.u.def.value = htab->root.sgotplt->size; + htab->root.sgotplt->size += 12; } /* At the very end of the .rofixup section is a pointer to the GOT. */ @@ -3538,9 +3146,9 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if ((s->flags & SEC_LINKER_CREATED) == 0) continue; - if (s == htab->splt - || s == htab->sgot - || s == htab->sgotplt + if (s == htab->root.splt + || s == htab->root.sgot + || s == htab->root.sgotplt || s == htab->sfuncdesc || s == htab->srofixup || s == htab->sdynbss) @@ -3548,9 +3156,9 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* Strip this section if we don't need it; see the comment below. */ } - else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela")) + else if (CONST_STRNEQ (bfd_section_name (s), ".rela")) { - if (s->size != 0 && s != htab->srelplt && s != htab->srelplt2) + if (s->size != 0 && s != htab->root.srelplt && s != htab->srelplt2) relocs = TRUE; /* We use the reloc_count field as a counter if we need @@ -3608,7 +3216,7 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (htab->splt->size != 0) + if (htab->root.splt->size != 0) { if (! add_dynamic_entry (DT_PLTGOT, 0) || ! add_dynamic_entry (DT_PLTRELSZ, 0) @@ -3633,7 +3241,8 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->root, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->root, + _bfd_elf_maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { @@ -3690,7 +3299,7 @@ sh_elf_add_rofixup (bfd *output_bfd, asection *srofixup, bfd_vma offset) static bfd_signed_vma sh_elf_got_offset (struct elf_sh_link_hash_table *htab) { - return (htab->sgot->output_offset - htab->sgotplt->output_offset + return (htab->root.sgot->output_offset - htab->root.sgotplt->output_offset - htab->root.hgot->root.u.def.value); } @@ -3837,7 +3446,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; Elf_Internal_Rela *rel, *relend; - bfd *dynobj = NULL; bfd_vma *local_got_offsets; asection *sgot = NULL; asection *sgotplt = NULL; @@ -3848,15 +3456,19 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, unsigned isec_segment, got_segment, plt_segment, check_segment[2]; bfd_boolean fdpic_p = FALSE; - BFD_ASSERT (is_sh_elf (input_bfd)); + if (!is_sh_elf (input_bfd)) + { + bfd_set_error (bfd_error_wrong_format); + return FALSE; + } htab = sh_elf_hash_table (info); if (htab != NULL) { - dynobj = htab->root.dynobj; - sgot = htab->sgot; - sgotplt = htab->sgotplt; - splt = htab->splt; + sgot = htab->root.sgot; + sgotplt = htab->root.sgotplt; + srelgot = htab->root.srelgot; + splt = htab->root.splt; fdpic_p = htab->fdpic_p; } symtab_hdr = &elf_symtab_hdr (input_bfd); @@ -3895,10 +3507,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd_vma relocation; bfd_vma addend = (bfd_vma) 0; bfd_reloc_status_type r; - int seen_stt_datalabel = 0; bfd_vma off; enum got_type got_type; const char *symname = NULL; + bfd_boolean resolved_to_zero; r_symndx = ELF32_R_SYM (rel->r_info); @@ -3938,6 +3550,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (! howto->partial_inplace) addend = rel->r_addend; + resolved_to_zero = FALSE; h = NULL; sym = NULL; sec = NULL; @@ -3951,19 +3564,11 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, symname = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); if (symname == NULL || *symname == '\0') - symname = bfd_section_name (input_bfd, sec); + symname = bfd_section_name (sec); relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); - /* A local symbol never has STO_SH5_ISA32, so we don't need - datalabel processing here. Make sure this does not change - without notice. */ - if ((sym->st_other & STO_SH5_ISA32) != 0) - (*info->callbacks->reloc_dangerous) - (info, - _("Unexpected STO_SH5_ISA32 on local symbol is not handled"), - input_bfd, input_section, rel->r_offset); if (sec != NULL && discarded_section (sec)) /* Handled below. */ @@ -4018,9 +3623,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"), + (_("%pB(%pA+%#" PRIx64 "): " + "%s relocation against SEC_MERGE section"), input_bfd, input_section, - (long) rel->r_offset, howto->name); + (uint64_t) rel->r_offset, howto->name); return FALSE; } @@ -4043,15 +3649,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, symname = h->root.root.string; while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) - { -#ifdef INCLUDE_SHMEDIA - /* If the reference passes a symbol marked with - STT_DATALABEL, then any STO_SH5_ISA32 on the final value - doesn't count. */ - seen_stt_datalabel |= h->type == STT_DATALABEL; -#endif - h = (struct elf_link_hash_entry *) h->root.u.i.link; - } + h = (struct elf_link_hash_entry *) h->root.u.i.link; if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { @@ -4120,14 +3718,9 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, || sh_elf_hash_entry (h)->got_type == GOT_TLS_GD))) ; else if (sec->output_section != NULL) - relocation = ((h->root.u.def.value + relocation = (h->root.u.def.value + sec->output_section->vma - + sec->output_offset) - /* A STO_SH5_ISA32 causes a "bitor 1" to the - symbol value, unless we've seen - STT_DATALABEL on the way to it. */ - | ((h->other & STO_SH5_ISA32) != 0 - && ! seen_stt_datalabel)); + + sec->output_offset); else if (!bfd_link_relocatable (info) && (_bfd_elf_section_offset (output_bfd, info, input_section, @@ -4136,27 +3729,29 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), + (_("%pB(%pA+%#" PRIx64 "): " + "unresolvable %s relocation against symbol `%s'"), input_bfd, input_section, - (long) rel->r_offset, + (uint64_t) rel->r_offset, howto->name, h->root.root.string); return FALSE; } } else if (h->root.type == bfd_link_hash_undefweak) - ; + resolved_to_zero = UNDEFWEAK_NO_DYNAMIC_RELOC (info, h); else if (info->unresolved_syms_in_objects == RM_IGNORE && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ; else if (!bfd_link_relocatable (info)) - (*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->unresolved_syms_in_objects == RM_GENERATE_ERROR - || ELF_ST_VISIBILITY (h->other))); - } + info->callbacks->undefined_symbol + (info, h->root.root.string, input_bfd, input_section, + rel->r_offset, + (info->unresolved_syms_in_objects == RM_DIAGNOSE + && !info->warn_unresolved_syms) + || ELF_ST_VISIBILITY (h->other)); + } if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, @@ -4215,9 +3810,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"), + (_("%pB: %#" PRIx64 ": fatal: " + "unaligned branch target for relax-support relocation"), input_section->owner, - (unsigned long) rel->r_offset); + (uint64_t) rel->r_offset); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -4228,11 +3824,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, break; default: -#ifdef INCLUDE_SHMEDIA - if (shmedia_prepare_reloc (info, input_bfd, input_section, - contents, rel, &relocation)) - goto final_link_relocate; -#endif bfd_set_error (bfd_error_bad_value); return FALSE; @@ -4249,10 +3840,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"), - input_section->owner, - (unsigned long) rel->r_offset, howto->name, - (unsigned long) relocation); + (_("%pB: %#" PRIx64 ": fatal: " + "unaligned %s relocation %#" PRIx64), + input_section->owner, (uint64_t) rel->r_offset, + howto->name, (uint64_t) relocation); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -4265,10 +3856,11 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"), + (_("%pB: %#" PRIx64 ": fatal: " + "unaligned %s relocation %#" PRIx64 ""), input_section->owner, - (unsigned long) rel->r_offset, howto->name, - (unsigned long) relocation); + (uint64_t) rel->r_offset, howto->name, + (uint64_t) relocation); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -4280,10 +3872,11 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"), + (_("%pB: %#" PRIx64 ": fatal: R_SH_PSHA relocation %" PRId64 + " not in range -32..32"), input_section->owner, - (unsigned long) rel->r_offset, - (unsigned long) relocation); + (uint64_t) rel->r_offset, + (int64_t) relocation); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -4295,10 +3888,11 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"), + (_("%pB: %#" PRIx64 ": fatal: R_SH_PSHL relocation %" PRId64 + " not in range -32..32"), input_section->owner, - (unsigned long) rel->r_offset, - (unsigned long) relocation); + (uint64_t) rel->r_offset, + (int64_t) relocation); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -4306,15 +3900,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_SH_DIR32: case R_SH_REL32: -#ifdef INCLUDE_SHMEDIA - case R_SH_IMM_LOW16_PCREL: - case R_SH_IMM_MEDLOW16_PCREL: - case R_SH_IMM_MEDHI16_PCREL: - case R_SH_IMM_HI16_PCREL: -#endif if (bfd_link_pic (info) && (h == NULL - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && !resolved_to_zero) || h->root.type != bfd_link_hash_undefweak) && r_symndx != STN_UNDEF && (input_section->flags & SEC_ALLOC) != 0 @@ -4362,17 +3951,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, ? bfd_get_32 (input_bfd, contents + rel->r_offset) : addend); } -#ifdef INCLUDE_SHMEDIA - else if (r_type == R_SH_IMM_LOW16_PCREL - || r_type == R_SH_IMM_MEDLOW16_PCREL - || r_type == R_SH_IMM_MEDHI16_PCREL - || r_type == R_SH_IMM_HI16_PCREL) - { - BFD_ASSERT (h != NULL && h->dynindx != -1); - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - outrel.r_addend = addend; - } -#endif else if (fdpic_p && (h == NULL || ((info->symbolic || h->dynindx == -1) @@ -4440,10 +4018,11 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"), + (_("%pB(%pA+%#" PRIx64 "): " + "cannot emit fixup to `%s' in read-only section"), input_bfd, input_section, - (long) rel->r_offset, + (uint64_t) rel->r_offset, symname); return FALSE; } @@ -4467,14 +4046,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, goto final_link_relocate; case R_SH_GOTPLT32: -#ifdef INCLUDE_SHMEDIA - case R_SH_GOTPLT_LOW16: - case R_SH_GOTPLT_MEDLOW16: - case R_SH_GOTPLT_MEDHI16: - case R_SH_GOTPLT_HI16: - case R_SH_GOTPLT10BY4: - case R_SH_GOTPLT10BY8: -#endif /* Relocation is to the entry for this symbol in the procedure linkage table. */ @@ -4505,14 +4076,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, force_got: case R_SH_GOT32: case R_SH_GOT20: -#ifdef INCLUDE_SHMEDIA - case R_SH_GOT_LOW16: - case R_SH_GOT_MEDLOW16: - case R_SH_GOT_MEDHI16: - case R_SH_GOT_HI16: - case R_SH_GOT10BY4: - case R_SH_GOT10BY8: -#endif /* Relocation is to the entry for this symbol in the global offset table. */ @@ -4525,15 +4088,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd_boolean dyn; off = h->got.offset; -#ifdef INCLUDE_SHMEDIA - if (seen_stt_datalabel) - { - struct elf_sh_link_hash_entry *hsh; - - hsh = (struct elf_sh_link_hash_entry *)h; - off = hsh->datalabel_got.offset; - } -#endif BFD_ASSERT (off != (bfd_vma) -1); dyn = htab->root.dynamic_sections_created; @@ -4542,7 +4096,8 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, h) || (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h)) - || (ELF_ST_VISIBILITY (h->other) + || ((ELF_ST_VISIBILITY (h->other) + || resolved_to_zero) && h->root.type == bfd_link_hash_undefweak)) { /* This is actually a static link, or it is a @@ -4563,17 +4118,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { bfd_put_32 (output_bfd, relocation, sgot->contents + off); -#ifdef INCLUDE_SHMEDIA - if (seen_stt_datalabel) - { - struct elf_sh_link_hash_entry *hsh; - - hsh = (struct elf_sh_link_hash_entry *)h; - hsh->datalabel_got.offset |= 1; - } - else -#endif - h->got.offset |= 1; + h->got.offset |= 1; /* If we initialize the GOT entry here with a valid symbol address, also add a fixup. */ @@ -4592,27 +4137,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } else { -#ifdef INCLUDE_SHMEDIA - if (rel->r_addend) - { - BFD_ASSERT (local_got_offsets != NULL - && (local_got_offsets[symtab_hdr->sh_info - + r_symndx] - != (bfd_vma) -1)); - - off = local_got_offsets[symtab_hdr->sh_info - + r_symndx]; - } - else - { -#endif BFD_ASSERT (local_got_offsets != NULL && local_got_offsets[r_symndx] != (bfd_vma) -1); off = local_got_offsets[r_symndx]; -#ifdef INCLUDE_SHMEDIA - } -#endif /* The offset must always be a multiple of 4. We use the least significant bit to record whether we have @@ -4628,13 +4156,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, Elf_Internal_Rela outrel; bfd_byte *loc; - if (srelgot == NULL) - { - srelgot = bfd_get_linker_section (dynobj, - ".rela.got"); - BFD_ASSERT (srelgot != NULL); - } - outrel.r_offset = (sgot->output_section->vma + sgot->output_offset + off); @@ -4663,12 +4184,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, + sgot->output_offset + off); -#ifdef INCLUDE_SHMEDIA - if (rel->r_addend) - local_got_offsets[symtab_hdr->sh_info + r_symndx] |= 1; - else -#endif - local_got_offsets[r_symndx] |= 1; + local_got_offsets[r_symndx] |= 1; } relocation = sh_elf_got_offset (htab) + off; @@ -4690,12 +4206,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_SH_GOTOFF: case R_SH_GOTOFF20: -#ifdef INCLUDE_SHMEDIA - case R_SH_GOTOFF_LOW16: - case R_SH_GOTOFF_MEDLOW16: - case R_SH_GOTOFF_MEDHI16: - case R_SH_GOTOFF_HI16: -#endif /* GOTOFF relocations are relative to _GLOBAL_OFFSET_TABLE_, which we place at the start of the .got.plt section. This is the same as the start of the output .got section, unless there are function @@ -4723,12 +4233,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, goto final_link_relocate; case R_SH_GOTPC: -#ifdef INCLUDE_SHMEDIA - case R_SH_GOTPC_LOW16: - case R_SH_GOTPC_MEDLOW16: - case R_SH_GOTPC_MEDHI16: - case R_SH_GOTPC_HI16: -#endif /* Use global offset table as symbol value. */ BFD_ASSERT (sgotplt != NULL); @@ -4743,12 +4247,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, goto final_link_relocate; case R_SH_PLT32: -#ifdef INCLUDE_SHMEDIA - case R_SH_PLT_LOW16: - case R_SH_PLT_MEDLOW16: - case R_SH_PLT_MEDHI16: - case R_SH_PLT_HI16: -#endif /* Relocation is to the entry for this symbol in the procedure linkage table. */ @@ -4781,10 +4279,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, + splt->output_offset + h->plt.offset); -#ifdef INCLUDE_SHMEDIA - relocation++; -#endif - addend = rel->r_addend; goto final_link_relocate; @@ -4919,10 +4413,11 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"), + (_("%pB(%pA+%#" PRIx64 "): " + "cannot emit fixup to `%s' in read-only section"), input_bfd, input_section, - (long) rel->r_offset, + (uint64_t) rel->r_offset, symname); return FALSE; } @@ -4951,12 +4446,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, return FALSE; } - if (srelgot == NULL) - { - srelgot = bfd_get_linker_section (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); - } - offset = _bfd_elf_section_offset (output_bfd, info, reloc_section, reloc_offset); @@ -5027,9 +4516,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+0x%lx): %s relocation against external symbol \"%s\""), - input_bfd, input_section, (long) rel->r_offset, howto->name, - h->root.root.string); + (_("%pB(%pA+%#" PRIx64 "): " + "%s relocation against external symbol \"%s\""), + input_bfd, input_section, (uint64_t) rel->r_offset, + howto->name, h->root.root.string); return FALSE; } else @@ -5141,7 +4631,15 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 1: .long x@TPOFF; 2: .long __tls_get_addr@PLT; 3:. */ offset = rel->r_offset; - BFD_ASSERT (offset >= 16); + if (offset < 16) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): offset in relocation for GD->LE translation is too small: %#" PRIx64), + input_bfd, input_section, (uint64_t) offset); + return FALSE; + } + /* Size of GD instructions is 16 or 18. */ offset -= 16; insn = bfd_get_16 (input_bfd, contents + offset + 0); @@ -5152,17 +4650,47 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, insn = bfd_get_16 (input_bfd, contents + offset + 0); } - BFD_ASSERT ((insn & 0xff00) == 0xd400); + if ((insn & 0xff00) != 0xd400) + _bfd_error_handler + /* xgettext:c-format */ /* The backslash is to prevent bogus trigraph detection. */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0xd4?\?)"), + input_bfd, input_section, (uint64_t) offset, (int) insn); + insn = bfd_get_16 (input_bfd, contents + offset + 2); - BFD_ASSERT ((insn & 0xff00) == 0xc700); + + if ((insn & 0xff00) != 0xc700) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0xc7?\?)"), + input_bfd, input_section, (uint64_t) offset, (int) insn); + insn = bfd_get_16 (input_bfd, contents + offset + 4); - BFD_ASSERT ((insn & 0xff00) == 0xd100); + if ((insn & 0xff00) != 0xd100) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0xd1?\?)"), + input_bfd, input_section, (uint64_t) offset, (int) insn); + insn = bfd_get_16 (input_bfd, contents + offset + 6); - BFD_ASSERT (insn == 0x310c); + if (insn != 0x310c) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0x310c)"), + input_bfd, input_section, (uint64_t) offset, (int) insn); + insn = bfd_get_16 (input_bfd, contents + offset + 8); - BFD_ASSERT (insn == 0x410b); + if (insn != 0x410b) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0x410b)"), + input_bfd, input_section, (uint64_t) offset, (int) insn); + insn = bfd_get_16 (input_bfd, contents + offset + 10); - BFD_ASSERT (insn == 0x34cc); + if (insn != 0x34cc) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0x34cc)"), + input_bfd, input_section, (uint64_t) offset, (int) insn); bfd_put_16 (output_bfd, 0x0012, contents + offset + 2); bfd_put_16 (output_bfd, 0x304c, contents + offset + 4); @@ -5175,14 +4703,32 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, int target; /* IE->LE transition: - mov.l 1f,r0; stc gbr,rN; mov.l @(r0,r12),rM; - bra 2f; add ...; .align 2; 1: x@GOTTPOFF; 2: + mov.l 1f,r0; + stc gbr,rN; + mov.l @(r0,r12),rM; + bra 2f; + add ...; + .align 2; + 1: x@GOTTPOFF; + 2: We change it into: - mov.l .Ln,rM; stc gbr,rN; nop; ...; - 1: x@TPOFF; 2:. */ + mov.l .Ln,rM; + stc gbr,rN; + nop; + ...; + 1: x@TPOFF; + 2:. */ offset = rel->r_offset; - BFD_ASSERT (offset >= 16); + if (offset < 16) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): offset in relocation for IE->LE translation is too small: %#" PRIx64), + input_bfd, input_section, (uint64_t) offset); + return FALSE; + } + /* Size of IE instructions is 10 or 12. */ offset -= 10; insn = bfd_get_16 (input_bfd, contents + offset + 0); @@ -5193,12 +4739,28 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, insn = bfd_get_16 (input_bfd, contents + offset + 0); } - BFD_ASSERT ((insn & 0xff00) == 0xd000); + if ((insn & 0xff00) != 0xd000) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0xd0??: mov.l)"), + input_bfd, input_section, (uint64_t) offset, (int) insn); + target = insn & 0x00ff; + insn = bfd_get_16 (input_bfd, contents + offset + 2); - BFD_ASSERT ((insn & 0xf0ff) == 0x0012); + if ((insn & 0xf0ff) != 0x0012) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0x0?12: stc)"), + input_bfd, input_section, (uint64_t) (offset + 2), (int) insn); + insn = bfd_get_16 (input_bfd, contents + offset + 4); - BFD_ASSERT ((insn & 0xf0ff) == 0x00ce); + if ((insn & 0xf0ff) != 0x00ce) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA+%#" PRIx64 "): unexpected instruction %#04X (expected 0x0?ce: mov.l)"), + input_bfd, input_section, (uint64_t) (offset + 4), (int) insn); + insn = 0xd000 | (insn & 0x0f00) | target; bfd_put_16 (output_bfd, insn, contents + offset + 0); bfd_put_16 (output_bfd, 0x0009, contents + offset + 4); @@ -5242,12 +4804,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd_byte *loc; int dr_type, indx; - if (srelgot == NULL) - { - srelgot = bfd_get_linker_section (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); - } - outrel.r_offset = (sgot->output_section->vma + sgot->output_offset + off); @@ -5313,7 +4869,15 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 1: .long x@TPOFF; 2:...; 3:. */ offset = rel->r_offset; - BFD_ASSERT (offset >= 16); + if (offset < 16) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): offset in relocation for GD->IE translation is too small: %#" PRIx64), + input_bfd, input_section, (uint64_t) offset); + return FALSE; + } + /* Size of GD instructions is 16 or 18. */ offset -= 16; insn = bfd_get_16 (input_bfd, contents + offset + 0); @@ -5373,7 +4937,15 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, nop; nop; bra 3f; ...; 3:. */ offset = rel->r_offset; - BFD_ASSERT (offset >= 16); + if (offset < 16) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): offset in relocation for LD->LE translation is too small: %#" PRIx64), + input_bfd, input_section, (uint64_t) offset); + return FALSE; + } + /* Size of LD instructions is 16 or 18. */ offset -= 16; insn = bfd_get_16 (input_bfd, contents + offset + 0); @@ -5417,10 +4989,6 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, Elf_Internal_Rela outrel; bfd_byte *loc; - srelgot = htab->srelgot; - if (srelgot == NULL) - abort (); - outrel.r_offset = (sgot->output_section->vma + sgot->output_offset + off); outrel.r_addend = 0; @@ -5535,7 +5103,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (name == NULL) return FALSE; if (*name == '\0') - name = bfd_section_name (input_bfd, sec); + name = bfd_section_name (sec); } (*info->callbacks->reloc_overflow) (info, (h ? &h->root : NULL), name, howto->name, @@ -5633,10 +5201,8 @@ sh_elf_get_relocated_section_contents (bfd *output_bfd, isymbuf, sections)) goto error_return; - if (sections != NULL) - free (sections); - if (isymbuf != NULL - && symtab_hdr->contents != (unsigned char *) isymbuf) + free (sections); + if (symtab_hdr->contents != (unsigned char *) isymbuf) free (isymbuf); if (elf_section_data (input_section)->relocs != internal_relocs) free (internal_relocs); @@ -5645,13 +5211,10 @@ sh_elf_get_relocated_section_contents (bfd *output_bfd, return data; error_return: - if (sections != NULL) - free (sections); - if (isymbuf != NULL - && symtab_hdr->contents != (unsigned char *) isymbuf) + free (sections); + if (symtab_hdr->contents != (unsigned char *) isymbuf) free (isymbuf); - if (internal_relocs != NULL - && elf_section_data (input_section)->relocs != internal_relocs) + if (elf_section_data (input_section)->relocs != internal_relocs) free (internal_relocs); return NULL; } @@ -5714,42 +5277,8 @@ sh_elf_copy_indirect_symbol (struct bfd_link_info *info, edir = (struct elf_sh_link_hash_entry *) dir; eind = (struct elf_sh_link_hash_entry *) ind; - if (eind->dyn_relocs != NULL) - { - if (edir->dyn_relocs != NULL) - { - struct elf_sh_dyn_relocs **pp; - struct elf_sh_dyn_relocs *p; - - /* Add reloc counts against the indirect sym to the direct sym - list. Merge any entries against the same section. */ - for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) - { - struct elf_sh_dyn_relocs *q; - - for (q = edir->dyn_relocs; q != NULL; q = q->next) - if (q->sec == p->sec) - { - q->pc_count += p->pc_count; - q->count += p->count; - *pp = p->next; - break; - } - if (q == NULL) - pp = &p->next; - } - *pp = edir->dyn_relocs; - } - - edir->dyn_relocs = eind->dyn_relocs; - eind->dyn_relocs = NULL; - } edir->gotplt_refcount = eind->gotplt_refcount; eind->gotplt_refcount = 0; -#ifdef INCLUDE_SHMEDIA - edir->datalabel_got.refcount += eind->datalabel_got.refcount; - eind->datalabel_got.refcount = 0; -#endif edir->funcdesc.refcount += eind->funcdesc.refcount; eind->funcdesc.refcount = 0; edir->abs_funcdesc_refcount += eind->abs_funcdesc_refcount; @@ -5768,7 +5297,8 @@ sh_elf_copy_indirect_symbol (struct bfd_link_info *info, /* If called to transfer flags for a weakdef during processing of elf_adjust_dynamic_symbol, don't copy non_got_ref. We clear it ourselves for ELIMINATE_COPY_RELOCS. */ - dir->ref_dynamic |= ind->ref_dynamic; + if (dir->versioned != versioned_hidden) + dir->ref_dynamic |= ind->ref_dynamic; dir->ref_regular |= ind->ref_regular; dir->ref_regular_nonweak |= ind->ref_regular_nonweak; dir->needs_plt |= ind->needs_plt; @@ -5820,6 +5350,15 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, if (bfd_link_relocatable (info)) return TRUE; + /* Don't do anything special with non-loaded, non-alloced sections. + In particular, any relocs in such sections should not affect GOT + and PLT reference counting (ie. we don't allow them to create GOT + or PLT entries), there's no possibility or desire to optimize TLS + relocs, and there's not much point in propagating relocs to shared + libs that the dynamic linker won't relocate. */ + if ((sec->flags & SEC_ALLOC) == 0) + return TRUE; + BFD_ASSERT (is_sh_elf (abfd)); symtab_hdr = &elf_symtab_hdr (abfd); @@ -5834,9 +5373,6 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, { struct elf_link_hash_entry *h; unsigned long r_symndx; -#ifdef INCLUDE_SHMEDIA - int seen_stt_datalabel = 0; -#endif r_symndx = ELF32_R_SYM (rel->r_info); r_type = ELF32_R_TYPE (rel->r_info); @@ -5848,16 +5384,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, h = sym_hashes[r_symndx - symtab_hdr->sh_info]; while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) - { -#ifdef INCLUDE_SHMEDIA - seen_stt_datalabel |= h->type == STT_DATALABEL; -#endif - h = (struct elf_link_hash_entry *) h->root.u.i.link; - } - - /* PR15323, ref flags aren't set for references in the same - object. */ - h->root.non_ir_ref = 1; + h = (struct elf_link_hash_entry *) h->root.u.i.link; } r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL); @@ -5895,7 +5422,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, } /* Some relocs require a global offset table. */ - if (htab->sgot == NULL) + if (htab->root.sgot == NULL) { switch (r_type) { @@ -5915,28 +5442,6 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, case R_SH_GOTOFFFUNCDESC: case R_SH_GOTOFFFUNCDESC20: case R_SH_GOTPC: -#ifdef INCLUDE_SHMEDIA - case R_SH_GOTPLT_LOW16: - case R_SH_GOTPLT_MEDLOW16: - case R_SH_GOTPLT_MEDHI16: - case R_SH_GOTPLT_HI16: - case R_SH_GOTPLT10BY4: - case R_SH_GOTPLT10BY8: - case R_SH_GOT_LOW16: - case R_SH_GOT_MEDLOW16: - case R_SH_GOT_MEDHI16: - case R_SH_GOT_HI16: - case R_SH_GOT10BY4: - case R_SH_GOT10BY8: - case R_SH_GOTOFF_LOW16: - case R_SH_GOTOFF_MEDLOW16: - case R_SH_GOTOFF_MEDHI16: - case R_SH_GOTOFF_HI16: - case R_SH_GOTPC_LOW16: - case R_SH_GOTPC_MEDLOW16: - case R_SH_GOTPC_MEDHI16: - case R_SH_GOTPC_HI16: -#endif case R_SH_TLS_GD_32: case R_SH_TLS_LD_32: case R_SH_TLS_IE_32: @@ -5963,9 +5468,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_SH_GNU_VTENTRY: - BFD_ASSERT (h != NULL); - if (h != NULL - && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -5978,14 +5481,6 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, case R_SH_TLS_GD_32: case R_SH_GOT32: case R_SH_GOT20: -#ifdef INCLUDE_SHMEDIA - case R_SH_GOT_LOW16: - case R_SH_GOT_MEDLOW16: - case R_SH_GOT_MEDHI16: - case R_SH_GOT_HI16: - case R_SH_GOT10BY4: - case R_SH_GOT10BY8: -#endif case R_SH_GOTFUNCDESC: case R_SH_GOTFUNCDESC20: switch (r_type) @@ -6007,17 +5502,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, if (h != NULL) { -#ifdef INCLUDE_SHMEDIA - if (seen_stt_datalabel) - { - struct elf_sh_link_hash_entry *eh - = (struct elf_sh_link_hash_entry *) h; - - eh->datalabel_got.refcount += 1; - } - else -#endif - h->got.refcount += 1; + h->got.refcount += 1; old_got_type = sh_elf_hash_entry (h)->got_type; } else @@ -6033,33 +5518,16 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, size = symtab_hdr->sh_info; size *= sizeof (bfd_signed_vma); -#ifdef INCLUDE_SHMEDIA - /* Reserve space for both the datalabel and - codelabel local GOT offsets. */ - size *= 2; -#endif size += symtab_hdr->sh_info; local_got_refcounts = ((bfd_signed_vma *) bfd_zalloc (abfd, size)); if (local_got_refcounts == NULL) return FALSE; elf_local_got_refcounts (abfd) = local_got_refcounts; -#ifdef INCLUDE_SHMEDIA - /* Take care of both the datalabel and codelabel local - GOT offsets. */ - sh_elf_local_got_type (abfd) - = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info); -#else sh_elf_local_got_type (abfd) = (char *) (local_got_refcounts + symtab_hdr->sh_info); -#endif } -#ifdef INCLUDE_SHMEDIA - if (rel->r_addend & 1) - local_got_refcounts[symtab_hdr->sh_info + r_symndx] += 1; - else -#endif - local_got_refcounts[r_symndx] += 1; + local_got_refcounts[r_symndx] += 1; old_got_type = sh_elf_local_got_type (abfd) [r_symndx]; } @@ -6076,18 +5544,18 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, && (old_got_type == GOT_NORMAL || got_type == GOT_NORMAL)) _bfd_error_handler /* xgettext:c-format */ - (_("%B: `%s' accessed both as normal and FDPIC symbol"), + (_("%pB: `%s' accessed both as normal and FDPIC symbol"), abfd, h->root.root.string); else if (old_got_type == GOT_FUNCDESC || got_type == GOT_FUNCDESC) _bfd_error_handler /* xgettext:c-format */ - (_("%B: `%s' accessed both as FDPIC and thread local symbol"), + (_("%pB: `%s' accessed both as FDPIC and thread local symbol"), abfd, h->root.root.string); else _bfd_error_handler /* xgettext:c-format */ - (_("%B: `%s' accessed both as normal and thread local symbol"), + (_("%pB: `%s' accessed both as normal and thread local symbol"), abfd, h->root.root.string); return FALSE; } @@ -6113,7 +5581,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, if (rel->r_addend) { _bfd_error_handler - (_("%B: Function descriptor relocation with non-zero addend"), + (_("%pB: Function descriptor relocation with non-zero addend"), abfd); return FALSE; } @@ -6129,10 +5597,6 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, bfd_size_type size; size = symtab_hdr->sh_info * sizeof (union gotref); -#ifdef INCLUDE_SHMEDIA - /* Count datalabel local GOT. */ - size *= 2; -#endif local_funcdesc = (union gotref *) bfd_zalloc (abfd, size); if (local_funcdesc == NULL) return FALSE; @@ -6145,7 +5609,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, if (!bfd_link_pic (info)) htab->srofixup->size += 4; else - htab->srelgot->size += sizeof (Elf32_External_Rela); + htab->root.srelgot->size += sizeof (Elf32_External_Rela); } } else @@ -6162,26 +5626,18 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, if (old_got_type == GOT_NORMAL) _bfd_error_handler /* xgettext:c-format */ - (_("%B: `%s' accessed both as normal and FDPIC symbol"), + (_("%pB: `%s' accessed both as normal and FDPIC symbol"), abfd, h->root.root.string); else _bfd_error_handler /* xgettext:c-format */ - (_("%B: `%s' accessed both as FDPIC and thread local symbol"), + (_("%pB: `%s' accessed both as FDPIC and thread local symbol"), abfd, h->root.root.string); } } break; case R_SH_GOTPLT32: -#ifdef INCLUDE_SHMEDIA - case R_SH_GOTPLT_LOW16: - case R_SH_GOTPLT_MEDLOW16: - case R_SH_GOTPLT_MEDHI16: - case R_SH_GOTPLT_HI16: - case R_SH_GOTPLT10BY4: - case R_SH_GOTPLT10BY8: -#endif /* If this is a local symbol, we resolve it directly without creating a procedure linkage table entry. */ @@ -6199,12 +5655,6 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, break; case R_SH_PLT32: -#ifdef INCLUDE_SHMEDIA - case R_SH_PLT_LOW16: - case R_SH_PLT_MEDLOW16: - case R_SH_PLT_MEDHI16: - case R_SH_PLT_HI16: -#endif /* This symbol requires a procedure linkage table entry. We actually build the entry in adjust_dynamic_symbol, because this might be a case of linking PIC code which is @@ -6226,12 +5676,6 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, case R_SH_DIR32: case R_SH_REL32: -#ifdef INCLUDE_SHMEDIA - case R_SH_IMM_LOW16_PCREL: - case R_SH_IMM_MEDLOW16_PCREL: - case R_SH_IMM_MEDHI16_PCREL: - case R_SH_IMM_HI16_PCREL: -#endif if (h != NULL && ! bfd_link_pic (info)) { h->non_got_ref = 1; @@ -6270,8 +5714,8 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, && (h->root.type == bfd_link_hash_defweak || !h->def_regular))) { - struct elf_sh_dyn_relocs *p; - struct elf_sh_dyn_relocs **head; + struct elf_dyn_relocs *p; + struct elf_dyn_relocs **head; if (htab->root.dynobj == NULL) htab->root.dynobj = abfd; @@ -6291,7 +5735,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, /* If this is a global symbol, we count the number of relocations we need for this symbol. */ if (h != NULL) - head = &((struct elf_sh_link_hash_entry *) h)->dyn_relocs; + head = &h->dyn_relocs; else { /* Track dynamic relocs needed for local syms too. */ @@ -6309,13 +5753,13 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, s = sec; vpp = &elf_section_data (s)->local_dynrel; - head = (struct elf_sh_dyn_relocs **) vpp; + head = (struct elf_dyn_relocs **) vpp; } p = *head; if (p == NULL || p->sec != sec) { - bfd_size_type amt = sizeof (*p); + size_t amt = sizeof (*p); p = bfd_alloc (htab->root.dynobj, amt); if (p == NULL) return FALSE; @@ -6327,14 +5771,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, } p->count += 1; - if (r_type == R_SH_REL32 -#ifdef INCLUDE_SHMEDIA - || r_type == R_SH_IMM_LOW16_PCREL - || r_type == R_SH_IMM_MEDLOW16_PCREL - || r_type == R_SH_IMM_MEDHI16_PCREL - || r_type == R_SH_IMM_HI16_PCREL -#endif - ) + if (r_type == R_SH_REL32) p->pc_count += 1; } @@ -6351,7 +5788,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, if (bfd_link_dll (info)) { _bfd_error_handler - (_("%B: TLS local exec code cannot be linked into shared objects"), + (_("%pB: TLS local exec code cannot be linked into shared objects"), abfd); return FALSE; } @@ -6378,7 +5815,7 @@ sh_elf_set_mach_from_flags (bfd *abfd) { flagword flags = elf_elfheader (abfd)->e_flags & EF_SH_MACH_MASK; - if (flags >= sizeof(sh_ef_bfd_table)) + if (flags >= ARRAY_SIZE (sh_ef_bfd_table)) return FALSE; if (sh_ef_bfd_table[flags] == 0) @@ -6466,7 +5903,7 @@ sh_merge_bfd_arch (bfd *ibfd, struct bfd_link_info *info) { _bfd_error_handler /* xgettext:c-format */ - (_("%B: uses %s instructions while previous modules " + (_("%pB: uses %s instructions while previous modules " "use %s instructions"), ibfd, SH_ARCH_SET_HAS_DSP (new_arch) ? "dsp" : "floating point", @@ -6500,6 +5937,10 @@ sh_elf_merge_private_data (bfd *ibfd, struct bfd_link_info *info) { bfd *obfd = info->output_bfd; + /* FIXME: What should be checked when linking shared libraries? */ + if ((ibfd->flags & DYNAMIC) != 0) + return TRUE; + if (! is_sh_elf (ibfd) || ! is_sh_elf (obfd)) return TRUE; @@ -6515,7 +5956,7 @@ sh_elf_merge_private_data (bfd *ibfd, struct bfd_link_info *info) if (! sh_merge_bfd_arch (ibfd, info)) { - _bfd_error_handler (_("%B: uses instructions which are incompatible " + _bfd_error_handler (_("%pB: uses instructions which are incompatible " "with instructions used in previous modules"), ibfd); bfd_set_error (bfd_error_bad_value); @@ -6528,7 +5969,7 @@ sh_elf_merge_private_data (bfd *ibfd, struct bfd_link_info *info) if (fdpic_object_p (ibfd) != fdpic_object_p (obfd)) { - _bfd_error_handler (_("%B: attempt to mix FDPIC and non-FDPIC objects"), + _bfd_error_handler (_("%pB: attempt to mix FDPIC and non-FDPIC objects"), ibfd); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -6583,9 +6024,9 @@ sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, BFD_ASSERT (h->dynindx != -1); - splt = htab->splt; - sgotplt = htab->sgotplt; - srelplt = htab->srelplt; + splt = htab->root.splt; + sgotplt = htab->root.sgotplt; + srelplt = htab->root.srelplt; BFD_ASSERT (splt != NULL && sgotplt != NULL && srelplt != NULL); /* Get the index in the procedure linkage table which @@ -6711,8 +6152,7 @@ sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, sgotplt->contents + got_offset); if (htab->fdpic_p) bfd_put_32 (output_bfd, - sh_elf_osec_to_segment (output_bfd, - htab->splt->output_section), + sh_elf_osec_to_segment (output_bfd, splt->output_section), sgotplt->contents + got_offset + 4); /* Fill in the entry in the .rela.plt section. */ @@ -6739,8 +6179,8 @@ sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, /* Create a .rela.plt.unloaded R_SH_DIR32 relocation for the PLT entry's pointer to the .got.plt entry. */ - rel.r_offset = (htab->splt->output_section->vma - + htab->splt->output_offset + rel.r_offset = (splt->output_section->vma + + splt->output_offset + h->plt.offset + plt_info->symbol_fields.got_entry); rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_SH_DIR32); @@ -6779,8 +6219,8 @@ sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, /* This symbol has an entry in the global offset table. Set it up. */ - sgot = htab->sgot; - srelgot = htab->srelgot; + sgot = htab->root.sgot; + srelgot = htab->root.srelgot; BFD_ASSERT (sgot != NULL && srelgot != NULL); rel.r_offset = (sgot->output_section->vma @@ -6825,70 +6265,6 @@ sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); } -#ifdef INCLUDE_SHMEDIA - { - struct elf_sh_link_hash_entry *eh; - - eh = (struct elf_sh_link_hash_entry *) h; - if (eh->datalabel_got.offset != (bfd_vma) -1) - { - asection *sgot; - asection *srelgot; - Elf_Internal_Rela rel; - bfd_byte *loc; - - /* This symbol has a datalabel entry in the global offset table. - Set it up. */ - - sgot = htab->sgot; - srelgot = htab->srelgot; - BFD_ASSERT (sgot != NULL && srelgot != NULL); - - rel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + (eh->datalabel_got.offset &~ (bfd_vma) 1)); - - /* If this is a static link, or it is a -Bsymbolic link and the - symbol is defined locally or was forced to be local because - of a version file, we just want to emit a RELATIVE reloc. - The entry in the global offset table will already have been - initialized in the relocate_section function. */ - if (bfd_link_pic (info) - && SYMBOL_REFERENCES_LOCAL (info, h)) - { - if (htab->fdpic_p) - { - asection *sec = h->root.u.def.section; - int dynindx - = elf_section_data (sec->output_section)->dynindx; - - rel.r_info = ELF32_R_INFO (dynindx, R_SH_DIR32); - rel.r_addend = (h->root.u.def.value - + h->root.u.def.section->output_offset); - } - else - { - rel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE); - rel.r_addend = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - } - else - { - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents - + eh->datalabel_got.offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_GLOB_DAT); - rel.r_addend = 0; - } - - loc = srelgot->contents; - loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela); - bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); - } - } -#endif - if (h->needs_copy) { asection *s; @@ -6936,7 +6312,7 @@ sh_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) if (htab == NULL) return FALSE; - sgotplt = htab->sgotplt; + sgotplt = htab->root.sgotplt; sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic"); if (htab->root.dynamic_sections_created) @@ -6952,9 +6328,6 @@ sh_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { Elf_Internal_Dyn dyn; asection *s; -#ifdef INCLUDE_SHMEDIA - const char *name; -#endif bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn); @@ -6966,29 +6339,6 @@ sh_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); break; -#ifdef INCLUDE_SHMEDIA - case DT_INIT: - name = info->init_function; - goto get_sym; - - case DT_FINI: - name = info->fini_function; - get_sym: - if (dyn.d_un.d_val != 0) - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (&htab->root, name, - FALSE, FALSE, TRUE); - if (h != NULL && (h->other & STO_SH5_ISA32)) - { - dyn.d_un.d_val |= 1; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - } - } - break; -#endif - case DT_PLTGOT: BFD_ASSERT (htab->root.hgot != NULL); s = htab->root.hgot->root.u.def.section; @@ -6998,41 +6348,23 @@ sh_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) break; case DT_JMPREL: - s = htab->srelplt->output_section; + s = htab->root.srelplt->output_section; BFD_ASSERT (s != NULL); dyn.d_un.d_ptr = s->vma; bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); break; case DT_PLTRELSZ: - s = htab->srelplt->output_section; + s = htab->root.srelplt->output_section; BFD_ASSERT (s != NULL); dyn.d_un.d_val = s->size; bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); break; - - case DT_RELASZ: - /* My reading of the SVR4 ABI indicates that the - procedure linkage table relocs (DT_JMPREL) should be - included in the overall relocs (DT_RELA). This is - what Solaris does. However, UnixWare can not handle - that case. Therefore, we override the DT_RELASZ entry - here to make it not include the JMPREL relocs. Since - the linker script arranges for .rela.plt to follow all - other relocation sections, we don't have to worry - about changing the DT_RELA entry. */ - if (htab->srelplt != NULL) - { - s = htab->srelplt->output_section; - dyn.d_un.d_val -= s->size; - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; } } /* Fill in the first entry in the procedure linkage table. */ - splt = htab->splt; + splt = htab->root.splt; if (splt && splt->size > 0 && htab->plt_info->plt0_entry) { unsigned int i; @@ -7128,9 +6460,9 @@ sh_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) BFD_ASSERT (htab->srelfuncdesc->reloc_count * sizeof (Elf32_External_Rela) == htab->srelfuncdesc->size); - if (htab->srelgot) - BFD_ASSERT (htab->srelgot->reloc_count * sizeof (Elf32_External_Rela) - == htab->srelgot->size); + if (htab->root.srelgot) + BFD_ASSERT (htab->root.srelgot->reloc_count * sizeof (Elf32_External_Rela) + == htab->root.srelgot->size); return TRUE; } @@ -7352,8 +6684,11 @@ sh_elf_encode_eh_address (bfd *abfd, #define elf_backend_plt_readonly 1 #define elf_backend_want_plt_sym 0 #define elf_backend_got_header_size 12 +#define elf_backend_dtrel_excludes_plt 1 + +#define elf_backend_linux_prpsinfo32_ugid16 TRUE -#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED +#if !defined SH_TARGET_ALREADY_DEFINED #include "elf32-target.h" @@ -7414,8 +6749,6 @@ sh_elf_encode_eh_address (bfd *abfd, #include "elf32-target.h" -#undef elf_backend_modify_program_headers - /* VxWorks support. */ #undef TARGET_BIG_SYM #define TARGET_BIG_SYM sh_elf32_vxworks_vec @@ -7451,4 +6784,4 @@ sh_elf_encode_eh_address (bfd *abfd, #include "elf32-target.h" -#endif /* neither INCLUDE_SHMEDIA nor SH_TARGET_ALREADY_DEFINED */ +#endif /* not SH_TARGET_ALREADY_DEFINED */