X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf64-sh64.c;h=a39002597cf45eebc080492a5d1481dc28f7805e;hb=6bba1048d63e0476b94b9934527defd81c590a13;hp=da02505d5c538081a09b92a3a8dc70eb70716b9a;hpb=a0087177c36f698e2687727057e2efbb8973051d;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index da02505d5c..a39002597c 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -1,11 +1,12 @@ -/* Hitachi SH64-specific support for 64-bit ELF - Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +/* SuperH SH64-specific support for 64-bit ELF + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,12 +16,13 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #define SH64_ELF64 -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "bfdlink.h" #include "libbfd.h" #include "elf-bfd.h" @@ -99,7 +101,7 @@ struct elf_sh64_link_hash_table #define sh64_elf64_link_hash_traverse(table, func, info) \ (elf_link_hash_traverse \ (&(table)->root, \ - (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ + (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ (info))) /* Get the sh ELF linker hash table from a link_info structure. */ @@ -107,63 +109,10 @@ struct elf_sh64_link_hash_table #define sh64_elf64_hash_table(p) \ ((struct elf_sh64_link_hash_table *) ((p)->hash)) -static boolean sh_elf64_copy_private_data PARAMS ((bfd *, bfd *)); -static boolean sh_elf64_copy_private_data_internal PARAMS ((bfd *, bfd *)); -static boolean sh_elf64_merge_private_data PARAMS ((bfd *, bfd *)); static bfd_reloc_status_type sh_elf64_ignore_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type sh_elf64_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *sh_elf64_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void sh_elf64_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static boolean sh_elf64_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static bfd_byte *sh_elf64_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean, asymbol **)); -static boolean sh_elf64_set_mach_from_flags PARAMS ((bfd *)); -static boolean sh_elf64_set_private_flags PARAMS ((bfd *, flagword)); -static asection *sh_elf64_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static boolean sh_elf64_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean sh_elf64_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static int sh64_elf64_get_symbol_type PARAMS ((Elf_Internal_Sym *, int)); -static boolean sh64_elf64_add_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, - const char **, flagword *, asection **, bfd_vma *)); -static boolean sh64_elf64_link_output_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *, - asection *)); -static boolean sh64_elf64_fake_sections - PARAMS ((bfd *, Elf_Internal_Shdr *, asection *)); -static void sh64_elf64_final_write_processing PARAMS ((bfd *, boolean)); -static struct bfd_hash_entry *sh64_elf64_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *sh64_elf64_link_hash_table_create - PARAMS ((bfd *)); -inline static void movi_shori_putval PARAMS ((bfd *, unsigned long, char *)); -inline static void movi_3shori_putval PARAMS ((bfd *, bfd_vma, char *)); -static boolean sh64_elf64_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean sh64_elf64_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *)); -static boolean sh64_elf64_discard_copies - PARAMS ((struct elf_sh64_link_hash_entry *, PTR)); -static boolean sh64_elf64_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean sh64_elf64_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean sh64_elf64_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static reloc_howto_type sh_elf64_howto_table[] = { /* No relocation. */ @@ -171,46 +120,46 @@ static reloc_howto_type sh_elf64_howto_table[] = { 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ sh_elf64_ignore_reloc, /* special_function */ "R_SH_NONE", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ - /* 32 bit absolute relocation. Setting partial_inplace to true and + /* 32 bit absolute relocation. Setting partial_inplace to TRUE and src_mask to a non-zero value is similar to the COFF toolchain. */ HOWTO (R_SH_DIR32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_elf64_reloc, /* special_function */ "R_SH_DIR32", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* 32 bit PC relative relocation. */ HOWTO (R_SH_REL32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ sh_elf64_ignore_reloc, /* special_function */ "R_SH_REL32", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* For 32-bit sh, this is R_SH_DIR8WPN. */ EMPTY_HOWTO (3), @@ -261,15 +210,15 @@ static reloc_howto_type sh_elf64_howto_table[] = { 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ sh_elf64_ignore_reloc, /* special_function */ "R_SH_SWITCH16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* A 32 bit switch table entry. This is generated for an expression such as ``.long L1 - L2''. The offset holds the difference @@ -278,15 +227,15 @@ static reloc_howto_type sh_elf64_howto_table[] = { 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ sh_elf64_ignore_reloc, /* special_function */ "R_SH_SWITCH32", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* For 32-bit sh, this is R_SH_USES. */ EMPTY_HOWTO (27), @@ -321,45 +270,45 @@ static reloc_howto_type sh_elf64_howto_table[] = { 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ sh_elf64_ignore_reloc, /* special_function */ "R_SH_SWITCH8", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* GNU extension to record C++ vtable hierarchy */ HOWTO (R_SH_GNU_VTINHERIT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ NULL, /* special_function */ "R_SH_GNU_VTINHERIT", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* GNU extension to record C++ vtable member usage */ HOWTO (R_SH_GNU_VTENTRY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ _bfd_elf_rel_vtable_reloc_fn, /* special_function */ "R_SH_GNU_VTENTRY", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* For 32-bit sh, this is R_SH_LOOP_START. */ EMPTY_HOWTO (36), @@ -380,105 +329,105 @@ static reloc_howto_type sh_elf64_howto_table[] = { 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 5, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_DIR5U", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xfc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in SHARI, SHLLI et al. */ HOWTO (R_SH_DIR6U, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 6, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_DIR6U", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xfc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in BxxI, LDHI.L et al. */ HOWTO (R_SH_DIR6S, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 6, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_DIR6S", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xfc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in ADDI, ANDI et al. */ HOWTO (R_SH_DIR10S, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 10, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_DIR10S", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in LD.UW, ST.W et al. */ HOWTO (R_SH_DIR10SW, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 11, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_DIR10SW", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in LD.L, FLD.S et al. */ HOWTO (R_SH_DIR10SL, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 12, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_DIR10SL", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in FLD.D, FST.P et al. */ HOWTO (R_SH_DIR10SQ, /* type */ 3, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 13, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_DIR10SQ", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ EMPTY_HOWTO (52), EMPTY_HOWTO (53), @@ -608,416 +557,416 @@ static reloc_howto_type sh_elf64_howto_table[] = { 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOT_LOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 16) & 65536). */ HOWTO (R_SH_GOT_MEDLOW16, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOT_MEDLOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 32) & 65536). */ HOWTO (R_SH_GOT_MEDHI16, /* type */ 32, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOT_MEDHI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 48) & 65536). */ HOWTO (R_SH_GOT_HI16, /* type */ 48, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOT_HI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI (x & 65536). */ HOWTO (R_SH_GOTPLT_LOW16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPLT_LOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 16) & 65536). */ HOWTO (R_SH_GOTPLT_MEDLOW16, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPLT_MEDLOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 32) & 65536). */ HOWTO (R_SH_GOTPLT_MEDHI16, /* type */ 32, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPLT_MEDHI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 48) & 65536). */ HOWTO (R_SH_GOTPLT_HI16, /* type */ 48, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPLT_HI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI (x & 65536). */ HOWTO (R_SH_PLT_LOW16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_PLT_LOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 16) & 65536). */ HOWTO (R_SH_PLT_MEDLOW16, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_PLT_MEDLOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 32) & 65536). */ HOWTO (R_SH_PLT_MEDHI16, /* type */ 32, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_PLT_MEDHI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 48) & 65536). */ HOWTO (R_SH_PLT_HI16, /* type */ 48, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_PLT_HI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI (x & 65536). */ HOWTO (R_SH_GOTOFF_LOW16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTOFF_LOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 16) & 65536). */ HOWTO (R_SH_GOTOFF_MEDLOW16, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTOFF_MEDLOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 32) & 65536). */ HOWTO (R_SH_GOTOFF_MEDHI16, /* type */ 32, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTOFF_MEDHI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 48) & 65536). */ HOWTO (R_SH_GOTOFF_HI16, /* type */ 48, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTOFF_HI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI (x & 65536). */ HOWTO (R_SH_GOTPC_LOW16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPC_LOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 16) & 65536). */ HOWTO (R_SH_GOTPC_MEDLOW16, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPC_MEDLOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 32) & 65536). */ HOWTO (R_SH_GOTPC_MEDHI16, /* type */ 32, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPC_MEDHI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 48) & 65536). */ HOWTO (R_SH_GOTPC_HI16, /* type */ 48, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPC_HI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in LD.L, FLD.S et al. */ HOWTO (R_SH_GOT10BY4, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 12, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOT10BY4", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in LD.L, FLD.S et al. */ HOWTO (R_SH_GOTPLT10BY4, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 12, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPLT10BY4", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in FLD.D, FST.P et al. */ HOWTO (R_SH_GOT10BY8, /* type */ 3, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 13, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOT10BY8", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in FLD.D, FST.P et al. */ HOWTO (R_SH_GOTPLT10BY8, /* type */ 3, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 13, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GOTPLT10BY8", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0xffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_COPY64, /* type */ 0, /* rightshift */ 4, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_COPY64", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ ((bfd_vma) 0) - 1, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_GLOB_DAT64, /* type */ 0, /* rightshift */ 4, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_GLOB_DAT64", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ ((bfd_vma) 0) - 1, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_JMP_SLOT64, /* type */ 0, /* rightshift */ 4, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_JMP_SLOT64", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ ((bfd_vma) 0) - 1, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_RELATIVE64, /* type */ 0, /* rightshift */ 4, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_RELATIVE64", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ ((bfd_vma) 0) - 1, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ EMPTY_HOWTO (197), EMPTY_HOWTO (198), @@ -1078,15 +1027,15 @@ static reloc_howto_type sh_elf64_howto_table[] = { 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ sh_elf64_ignore_reloc, /* special_function */ "R_SH_SHMEDIA_CODE", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* The assembler will generate this reloc at a PTA or PTB instruction, and the linker checks the right type of target, or changes a PTA to a @@ -1095,195 +1044,195 @@ static reloc_howto_type sh_elf64_howto_table[] = { 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 18, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_PT_16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in unexpanded MOVI. */ HOWTO (R_SH_IMMS16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMMS16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in SHORI. */ HOWTO (R_SH_IMMU16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMMU16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI (x & 65536). */ HOWTO (R_SH_IMM_LOW16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMM_LOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x - $) & 65536). */ HOWTO (R_SH_IMM_LOW16_PCREL, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMM_LOW16_PCREL", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 16) & 65536). */ HOWTO (R_SH_IMM_MEDLOW16, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMM_MEDLOW16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI (((x - $) >> 16) & 65536). */ HOWTO (R_SH_IMM_MEDLOW16_PCREL, /* type */ 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMM_MEDLOW16_PCREL", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 32) & 65536). */ HOWTO (R_SH_IMM_MEDHI16, /* type */ 32, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMM_MEDHI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI (((x - $) >> 32) & 65536). */ HOWTO (R_SH_IMM_MEDHI16_PCREL, /* type */ 32, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMM_MEDHI16_PCREL", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* Used in MOVI and SHORI ((x >> 48) & 65536). */ HOWTO (R_SH_IMM_HI16, /* type */ 48, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMM_HI16", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* Used in MOVI and SHORI (((x - $) >> 48) & 65536). */ HOWTO (R_SH_IMM_HI16_PCREL, /* type */ 48, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_IMM_HI16_PCREL", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0x3fffc00, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ /* For the .uaquad pseudo. */ HOWTO (R_SH_64, /* type */ 0, /* rightshift */ 4, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_64", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ ((bfd_vma) 0) - 1, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ /* For the .uaquad pseudo, (x - $). */ HOWTO (R_SH_64_PCREL, /* type */ 48, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 10, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_SH_64_PCREL", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ ((bfd_vma) 0) - 1, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ }; @@ -1291,15 +1240,11 @@ static reloc_howto_type sh_elf64_howto_table[] = { which the linker should otherwise ignore. */ static bfd_reloc_status_type -sh_elf64_ignore_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol ATTRIBUTE_UNUSED; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +sh_elf64_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED, asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { if (output_bfd != NULL) reloc_entry->address += input_section->output_offset; @@ -1312,15 +1257,9 @@ sh_elf64_ignore_reloc (abfd, reloc_entry, symbol, data, input_section, See sh_elf_reloc in elf32-sh.c for the original. */ static bfd_reloc_status_type -sh_elf64_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +sh_elf64_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 sym_value; @@ -1440,9 +1379,8 @@ static const struct elf_reloc_map sh64_reloc_map[] = corresponding SH ELf reloc. */ static reloc_howto_type * -sh_elf64_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +sh_elf64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; @@ -1455,15 +1393,29 @@ sh_elf64_reloc_type_lookup (abfd, code) return NULL; } +static reloc_howto_type * +sh_elf64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < sizeof (sh_elf64_howto_table) / sizeof (sh_elf64_howto_table[0]); + i++) + if (sh_elf64_howto_table[i].name != NULL + && strcasecmp (sh_elf64_howto_table[i].name, r_name) == 0) + return &sh_elf64_howto_table[i]; + + return NULL; +} + /* Given an ELF reloc, fill in the howto field of a relent. See sh_elf_info_to_howto in elf32-sh.c for the original. */ static void -sh_elf64_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +sh_elf64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r; @@ -1482,17 +1434,13 @@ sh_elf64_info_to_howto (abfd, cache_ptr, dst) See sh_elf_info_to_howto in elf32-sh.c for the original. */ -static boolean -sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +static bfd_boolean +sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info, bfd *input_bfd, + asection *input_section, bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1542,22 +1490,24 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, || (r_type >= (int) R_SH_FIRST_INVALID_RELOC && r_type <= (int) R_SH_LAST_INVALID_RELOC) || (r_type >= (int) R_SH_DIR8WPN - && r_type <= (int) R_SH_LAST_INVALID_RELOC_2) - || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_3 + && r_type <= (int) R_SH_LAST_INVALID_RELOC) + || (r_type >= (int) R_SH_GNU_VTINHERIT + && r_type <= (int) R_SH_PSHL) + || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2 && r_type <= R_SH_GOTPLT32) || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_4 && r_type <= (int) R_SH_LAST_INVALID_RELOC_4)) { bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } howto = sh_elf64_howto_table + r_type; - /* This is a final link. */ h = NULL; sym = NULL; sec = NULL; + relocation = 0; if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; @@ -1576,13 +1526,15 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, _("Unexpected STO_SH5_ISA32 on local symbol is not handled"), input_bfd, input_section, rel->r_offset)); - if (info->relocateable) + if (sec != NULL && elf_discarded_section (sec)) + /* Handled below. */ + ; + else if (info->relocatable) { - /* This is a relocateable link. We don't have to change + /* This is a relocatable link. We don't have to change anything, unless the reloc is against a section symbol, in which case we have to adjust according to where the section symbol winds up in the output section. */ - sym = local_syms + r_symndx; if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) goto final_link_relocate; @@ -1590,7 +1542,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, } else if (! howto->partial_inplace) { - relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); relocation |= ((sym->st_other & STO_SH5_ISA32) != 0); } else if ((sec->flags & SEC_MERGE) @@ -1601,11 +1553,10 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, if (howto->rightshift || howto->src_mask != 0xffffffff) { (*_bfd_error_handler) - (_("%s(%s+0x%lx): %s relocation against SEC_MERGE section"), - bfd_archive_filename (input_bfd), - bfd_get_section_name (input_bfd, input_section), + (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"), + input_bfd, input_section, (long) rel->r_offset, howto->name); - return false; + return FALSE; } addend = bfd_get_32 (input_bfd, contents + rel->r_offset); @@ -1620,11 +1571,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, } else { - /* Section symbols are never (?) placed in the hash table, so - we can just ignore hash relocations when creating a - relocateable object file. */ - if (info->relocateable) - continue; + /* ??? Could we use the RELOC_FOR_GLOBAL_SYMBOL macro here ? */ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; while (h->root.type == bfd_link_hash_indirect @@ -1660,8 +1607,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, && elf_hash_table (info)->dynamic_sections_created && (! info->shared || (! info->symbolic && h->dynindx != -1) - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) + || !h->def_regular)) /* The cases above are those in which relocation is overwritten in the switch block below. The cases below are those in which we must defer relocation @@ -1669,8 +1615,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, addresses when creating a shared library. */ || (info->shared && ((! info->symbolic && h->dynindx != -1) - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) + || !h->def_regular) && ((r_type == R_SH_64 && !(ELF_ST_VISIBILITY (h->other) == STV_INTERNAL || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)) @@ -1680,17 +1625,15 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, sections against symbols defined externally in shared libraries. We can't do anything with them here. */ - || (input_section->flags & SEC_DEBUGGING) != 0))) - relocation = 0; - else if (sec->output_section == NULL) - { - (*_bfd_error_handler) - (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"), - bfd_get_filename (input_bfd), h->root.root.string, - bfd_get_section_name (input_bfd, input_section)); - relocation = 0; - } - else + || (input_section->flags & SEC_DEBUGGING) != 0)) + /* Dynamic relocs are not propagated for SEC_DEBUGGING + sections because such sections are not SEC_ALLOC and + thus ld.so will not process them. */ + || (sec->output_section == NULL + && ((input_section->flags & SEC_DEBUGGING) != 0 + && h->def_dynamic))) + ; + else if (sec->output_section != NULL) relocation = ((h->root.u.def.value + sec->output_section->vma + sec->output_offset) @@ -1699,21 +1642,47 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, STT_DATALABEL on the way to it. */ | ((h->other & STO_SH5_ISA32) != 0 && ! seen_stt_datalabel)); + else if (!info->relocatable) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), + input_bfd, + input_section, + (long) rel->r_offset, + howto->name, + h->root.root.string); + } } else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic && !info->no_undefined) - relocation = 0; - else + ; + else if (info->unresolved_syms_in_objects == RM_IGNORE + && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) + ; + else if (!info->relocatable) { if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, true))) - return false; - relocation = 0; + input_section, rel->r_offset, + (info->unresolved_syms_in_objects == RM_GENERATE_ERROR + || ELF_ST_VISIBILITY (h->other))))) + return FALSE; } } + if (sec != NULL && elf_discarded_section (sec)) + { + /* For relocs against symbols from removed linkonce sections, + or sections discarded by a linker script, we just want the + section contents zeroed. Avoid any special processing. */ + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + rel->r_info = 0; + rel->r_addend = 0; + continue; + } + + if (info->relocatable) + continue; + disp = (relocation - input_section->output_section->vma - input_section->output_offset @@ -1732,7 +1701,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, (_("%s: error: unaligned relocation type %d at %08x reloc %08x\n"), bfd_get_filename (input_bfd), (int)r_type, (unsigned)rel->r_offset, (unsigned)relocation); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } switch ((int)r_type) { @@ -1744,11 +1713,11 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, || (h != NULL && h->dynindx != -1 && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + || !h->def_regular)))) { Elf_Internal_Rela outrel; - boolean skip, relocate; + bfd_byte *loc; + bfd_boolean skip, relocate; /* When generating a shared object, these relocations are copied into the output file to be resolved at run @@ -1763,9 +1732,9 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, elf_elfheader (input_bfd)->e_shstrndx, elf_section_data (input_section)->rel_hdr.sh_name)); if (name == NULL) - return false; + return FALSE; - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 + BFD_ASSERT (CONST_STRNEQ (name, ".rela") && strcmp (bfd_get_section_name (input_bfd, input_section), name + 5) == 0); @@ -1774,17 +1743,17 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (sreloc != NULL); } - skip = false; - relocate = false; + skip = FALSE; + relocate = FALSE; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) - skip = true; + skip = TRUE; else if (outrel.r_offset == (bfd_vma) -2) - skip = true, relocate = true; + skip = TRUE, relocate = TRUE; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); @@ -1803,10 +1772,9 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, become local. */ if (h == NULL || ((info->symbolic || h->dynindx == -1) - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) != 0)) + && h->def_regular)) { - relocate = true; + relocate = TRUE; outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64); outrel.r_addend = relocation + rel->r_addend; } @@ -1818,11 +1786,9 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, } } - bfd_elf64_swap_reloca_out (output_bfd, &outrel, - (((Elf64_External_Rela *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; + loc = sreloc->contents; + loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela); + bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); /* If this reloc is against an external symbol, we do not want to fiddle with the addend. Otherwise, we @@ -1904,7 +1870,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, && (info->symbolic || h->dynindx == -1 || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + && h->def_regular)) { /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined @@ -1971,22 +1937,21 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, if (info->shared) { - asection *srelgot; + asection *s; Elf_Internal_Rela outrel; + bfd_byte *loc; - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); + s = bfd_get_section_by_name (dynobj, ".rela.got"); + BFD_ASSERT (s != NULL); outrel.r_offset = (sgot->output_section->vma + sgot->output_offset + off); outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64); outrel.r_addend = relocation; - bfd_elf64_swap_reloca_out (output_bfd, &outrel, - (((Elf64_External_Rela *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; + loc = s->contents; + loc += s->reloc_count++ * sizeof (Elf64_External_Rela); + bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); } if (rel->r_addend) @@ -2118,7 +2083,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, default: bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } @@ -2134,27 +2099,28 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, const char *name; if (h != NULL) - name = h->root.root.string; + name = NULL; else { name = (bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name)); if (name == NULL) - return false; + return FALSE; if (*name == '\0') name = bfd_section_name (input_bfd, sec); } if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; + (info, (h ? &h->root : NULL), name, howto->name, + (bfd_vma) 0, input_bfd, input_section, + rel->r_offset))) + return FALSE; } break; } } } - return true; + return TRUE; } /* This is a version of bfd_generic_get_relocated_section_contents @@ -2163,14 +2129,12 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, See sh_elf_relocate_section in elf32-sh.c for the original. */ static bfd_byte * -sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order, - data, relocateable, symbols) - bfd *output_bfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; +sh_elf64_get_relocated_section_contents (bfd *output_bfd, + struct bfd_link_info *link_info, + struct bfd_link_order *link_order, + bfd_byte *data, + bfd_boolean relocatable, + asymbol **symbols) { Elf_Internal_Shdr *symtab_hdr; asection *input_section = link_order->u.indirect.section; @@ -2181,17 +2145,17 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order, /* We only need to handle the case of relaxing, or of having a particular set of section contents, specially. */ - if (relocateable + if (relocatable || elf_section_data (input_section)->this_hdr.contents == NULL) return bfd_generic_get_relocated_section_contents (output_bfd, link_info, link_order, data, - relocateable, + relocatable, symbols); symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; memcpy (data, elf_section_data (input_section)->this_hdr.contents, - input_section->_raw_size); + input_section->size); if ((input_section->flags & SEC_RELOC) != 0 && input_section->reloc_count > 0) @@ -2212,9 +2176,9 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order, goto error_return; } - internal_relocs = (_bfd_elf64_link_read_relocs - (input_bfd, input_section, (PTR) NULL, - (Elf_Internal_Rela *) NULL, false)); + internal_relocs = (_bfd_elf_link_read_relocs + (input_bfd, input_section, NULL, + (Elf_Internal_Rela *) NULL, FALSE)); if (internal_relocs == NULL) goto error_return; @@ -2231,17 +2195,12 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order, if (isymp->st_shndx == SHN_UNDEF) isec = bfd_und_section_ptr; - else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE) - isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx); else if (isymp->st_shndx == SHN_ABS) isec = bfd_abs_section_ptr; else if (isymp->st_shndx == SHN_COMMON) isec = bfd_com_section_ptr; else - { - /* Who knows? */ - isec = NULL; - } + isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx); *secpp = isec; } @@ -2276,22 +2235,20 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order, /* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections. */ -boolean -sh64_elf64_fake_sections (output_bfd, elf_section_hdr, asect) - bfd *output_bfd ATTRIBUTE_UNUSED; - Elf_Internal_Shdr *elf_section_hdr; - asection *asect; +static bfd_boolean +sh64_elf64_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *elf_section_hdr, + asection *asect) { /* Code sections can only contain SH64 code, so mark them as such. */ if (bfd_get_section_flags (output_bfd, asect) & SEC_CODE) elf_section_hdr->sh_flags |= SHF_SH5_ISA32; - return true; + return TRUE; } -static boolean -sh_elf64_set_mach_from_flags (abfd) - bfd *abfd; +static bfd_boolean +sh_elf64_set_mach_from_flags (bfd *abfd) { flagword flags = elf_elfheader (abfd)->e_flags; @@ -2304,35 +2261,31 @@ sh_elf64_set_mach_from_flags (abfd) default: bfd_set_error (bfd_error_wrong_format); - return false; + return FALSE; } - return true; + return TRUE; } /* Function to keep SH64 specific file flags. See sh64_elf_set_private_flags in elf32-sh64.c for the original. */ -static boolean -sh_elf64_set_private_flags (abfd, flags) - bfd * abfd; - flagword flags; +static bfd_boolean +sh_elf64_set_private_flags (bfd *abfd, flagword flags) { BFD_ASSERT (! elf_flags_init (abfd) || elf_elfheader (abfd)->e_flags == flags); elf_elfheader (abfd)->e_flags = flags; - elf_flags_init (abfd) = true; + elf_flags_init (abfd) = TRUE; return sh_elf64_set_mach_from_flags (abfd); } /* Copy the SHF_SH5_ISA32 attribute that we keep on all sections with code, to keep attributes the same as for SHmedia in 32-bit ELF. */ -static boolean -sh_elf64_copy_private_data_internal (ibfd, obfd) - bfd * ibfd; - bfd * obfd; +static bfd_boolean +sh_elf64_copy_private_data_internal (bfd *ibfd, bfd *obfd) { Elf_Internal_Shdr **o_shdrp; asection *isec; @@ -2340,7 +2293,7 @@ sh_elf64_copy_private_data_internal (ibfd, obfd) if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; + return TRUE; o_shdrp = elf_elfsections (obfd); for (osec = obfd->sections; osec; osec = osec->next) @@ -2359,30 +2312,29 @@ sh_elf64_copy_private_data_internal (ibfd, obfd) } } + /* Copy object attributes. */ + _bfd_elf_copy_obj_attributes (ibfd, obfd); + return sh_elf64_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags); } -static boolean -sh_elf64_copy_private_data (ibfd, obfd) - bfd * ibfd; - bfd * obfd; +static bfd_boolean +sh_elf64_copy_private_data (bfd *ibfd, bfd *obfd) { return sh_elf64_copy_private_data_internal (ibfd, obfd); } -static boolean -sh_elf64_merge_private_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +static bfd_boolean +sh_elf64_merge_private_data (bfd *ibfd, bfd *obfd) { flagword old_flags, new_flags; if (! _bfd_generic_verify_endian_match (ibfd, obfd)) - return false; + return FALSE; if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; + return TRUE; if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd)) { @@ -2400,7 +2352,7 @@ sh_elf64_merge_private_data (ibfd, obfd) (*_bfd_error_handler) (msg, bfd_get_filename (ibfd), bfd_get_filename (obfd)); bfd_set_error (bfd_error_wrong_format); - return false; + return FALSE; } old_flags = elf_elfheader (obfd)->e_flags; @@ -2408,7 +2360,7 @@ sh_elf64_merge_private_data (ibfd, obfd) if (! elf_flags_init (obfd)) { /* This happens when ld starts out with a 'blank' output file. */ - elf_flags_init (obfd) = true; + elf_flags_init (obfd) = TRUE; elf_elfheader (obfd)->e_flags = old_flags = new_flags; } /* We don't allow linking in anything else than SH64 code, and since @@ -2420,7 +2372,7 @@ sh_elf64_merge_private_data (ibfd, obfd) ("%s: does not use the SH64 64-bit ABI as previous modules do", bfd_get_filename (ibfd)); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } sh_elf64_copy_private_data_internal (ibfd, obfd); @@ -2436,71 +2388,33 @@ sh_elf64_merge_private_data (ibfd, obfd) relocation. */ static asection * -sh_elf64_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +sh_elf64_gc_mark_hook (asection *sec, + struct bfd_link_info *info, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { if (h != NULL) - { - switch (ELF64_R_TYPE (rel->r_info)) - { - case R_SH_GNU_VTINHERIT: - case R_SH_GNU_VTENTRY: - break; - - default: - while (h->root.type == bfd_link_hash_indirect - && h->root.u.i.link) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - switch (h->root.type) - { - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - return h->root.u.def.section; - - case bfd_link_hash_common: - return h->root.u.c.p->section; - - default: - break; - } - } - } - else - return bfd_section_from_elf_index (sec->owner, sym->st_shndx); - - return NULL; -} - -/* Update the got entry reference counts for the section being removed. */ + switch (ELF64_R_TYPE (rel->r_info)) + { + case R_SH_GNU_VTINHERIT: + case R_SH_GNU_VTENTRY: + return NULL; + } -static boolean -sh_elf64_gc_sweep_hook (abfd, info, sec, relocs) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - asection *sec ATTRIBUTE_UNUSED; - const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; -{ - /* No got and plt entries for 64-bit SH at present. */ - return true; + return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); } /* Look through the relocs for a section during the first phase. Since we don't do .gots or .plts, we just need to consider the virtual table relocs for gc. */ -static boolean -sh_elf64_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +static bfd_boolean +sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info, + asection *sec, const Elf_Internal_Rela *relocs) { Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; + struct elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; bfd *dynobj; @@ -2513,14 +2427,11 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) srelgot = NULL; sreloc = NULL; - if (info->relocateable) - return true; + if (info->relocatable) + return TRUE; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); - sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf64_External_Sym); - if (!elf_bad_symtab (abfd)) - sym_hashes_end -= symtab_hdr->sh_info; dynobj = elf_hash_table (info)->dynobj; local_got_offsets = elf_local_got_offsets (abfd); @@ -2535,7 +2446,12 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) if (r_symndx < symtab_hdr->sh_info) h = NULL; else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + } /* Some relocs require a global offset table. */ if (dynobj == NULL) @@ -2564,7 +2480,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) case R_SH_GOTPC_HI16: elf_hash_table (info)->dynobj = dynobj = abfd; if (! _bfd_elf_create_got_section (dynobj, info)) - return false; + return FALSE; break; default: @@ -2577,15 +2493,17 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_SH_GNU_VTINHERIT: - if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) - return false; + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_SH_GNU_VTENTRY: - if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) - return false; + BFD_ASSERT (h != NULL); + if (h != NULL + && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + return FALSE; break; force_got: @@ -2609,17 +2527,17 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); if (srelgot == NULL) { - srelgot = bfd_make_section (dynobj, ".rela.got"); + srelgot = bfd_make_section_with_flags (dynobj, + ".rela.got", + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED + | SEC_READONLY)); if (srelgot == NULL - || ! bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)) || ! bfd_set_section_alignment (dynobj, srelgot, 2)) - return false; + return FALSE; } } @@ -2634,7 +2552,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) if (hsh->datalabel_got_offset != (bfd_vma) -1) break; - hsh->datalabel_got_offset = sgot->_raw_size; + hsh->datalabel_got_offset = sgot->size; } else { @@ -2643,17 +2561,17 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) /* We have already allocated space in the .got. */ break; } - h->got.offset = sgot->_raw_size; + h->got.offset = sgot->size; } /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) - return false; + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; } - srelgot->_raw_size += sizeof (Elf64_External_Rela); + srelgot->size += sizeof (Elf64_External_Rela); } else { @@ -2670,7 +2588,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) size *= 2; local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); if (local_got_offsets == NULL) - return false; + return FALSE; elf_local_got_offsets (abfd) = local_got_offsets; for (i = 0; i < symtab_hdr->sh_info; i++) local_got_offsets[i] = (bfd_vma) -1; @@ -2686,7 +2604,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) break; } local_got_offsets[symtab_hdr->sh_info - + r_symndx] = sgot->_raw_size; + + r_symndx] = sgot->size; } else { @@ -2695,7 +2613,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) /* We have already allocated space in the .got. */ break; } - local_got_offsets[r_symndx] = sgot->_raw_size; + local_got_offsets[r_symndx] = sgot->size; } if (info->shared) @@ -2703,11 +2621,11 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) /* If we are generating a shared object, we need to output a R_SH_RELATIVE reloc so that the dynamic linker can adjust this GOT entry. */ - srelgot->_raw_size += sizeof (Elf64_External_Rela); + srelgot->size += sizeof (Elf64_External_Rela); } } - sgot->_raw_size += 8; + sgot->size += 8; break; @@ -2732,11 +2650,11 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) - return false; + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; } - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + h->needs_plt = 1; break; @@ -2760,14 +2678,14 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN) break; - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + h->needs_plt = 1; break; case R_SH_64: case R_SH_64_PCREL: if (h != NULL) - h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; + h->non_got_ref = 1; /* If we are creating a shared library, and this is a reloc against a global symbol, or a non PC relative reloc @@ -2786,8 +2704,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) && (ELF32_R_TYPE (rel->r_info) != R_SH_64_PCREL || (h != NULL && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + || !h->def_regular)))) { /* When creating a shared object, we must copy these reloc types into the output file. We create a reloc @@ -2801,9 +2718,9 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) elf_elfheader (abfd)->e_shstrndx, elf_section_data (sec)->rel_hdr.sh_name)); if (name == NULL) - return false; + return FALSE; - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 + BFD_ASSERT (CONST_STRNEQ (name, ".rela") && strcmp (bfd_get_section_name (abfd, sec), name + 5) == 0); @@ -2812,19 +2729,20 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) { flagword flags; - sreloc = bfd_make_section (dynobj, name); flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_IN_MEMORY | SEC_LINKER_CREATED); if ((sec->flags & SEC_ALLOC) != 0) flags |= SEC_ALLOC | SEC_LOAD; + sreloc = bfd_make_section_with_flags (dynobj, + name, + flags); if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, flags) || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; + return FALSE; } } - sreloc->_raw_size += sizeof (Elf64_External_Rela); + sreloc->size += sizeof (Elf64_External_Rela); /* If we are linking with -Bsymbolic, and this is a global symbol, we count the number of PC relative @@ -2851,7 +2769,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) p = ((struct elf_sh64_pcrel_relocs_copied *) bfd_alloc (dynobj, sizeof *p)); if (p == NULL) - return false; + return FALSE; p->next = eh->pcrel_relocs_copied; eh->pcrel_relocs_copied = p; p->section = sreloc; @@ -2866,13 +2784,11 @@ sh_elf64_check_relocs (abfd, info, sec, relocs) } } - return true; + return TRUE; } static int -sh64_elf64_get_symbol_type (elf_sym, type) - Elf_Internal_Sym * elf_sym; - int type; +sh64_elf64_get_symbol_type (Elf_Internal_Sym * elf_sym, int type) { if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL) return STT_DATALABEL; @@ -2902,27 +2818,23 @@ sh64_elf64_get_symbol_type (elf_sym, type) or the hash entry, alternatively adding the index to Elf_Internal_Sym (not so good). */ -static boolean -sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - const Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp ATTRIBUTE_UNUSED; - asection **secp; - bfd_vma *valp; +static bfd_boolean +sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, + Elf_Internal_Sym *sym, const char **namep, + flagword *flagsp ATTRIBUTE_UNUSED, + asection **secp, bfd_vma *valp) { /* We want to do this for relocatable as well as final linking. */ if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL - && info->hash->creator->flavour == bfd_target_elf_flavour) + && is_elf_hash_table (info->hash)) { struct elf_link_hash_entry *h; - /* For relocateable links, we register the DataLabel sym in its own + /* For relocatable links, we register the DataLabel sym in its own right, and tweak the name when it's output. Otherwise, we make an indirect symbol of it. */ flagword flags - = info->relocateable || info->emitrelocations + = info->relocatable || info->emitrelocations ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT; char *dl_name @@ -2933,31 +2845,31 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) /* Allocation may fail. */ if (dl_name == NULL) - return false; + return FALSE; strcpy (dl_name, *namep); strcat (dl_name, DATALABEL_SUFFIX); h = (struct elf_link_hash_entry *) - bfd_link_hash_lookup (info->hash, dl_name, false, false, false); + bfd_link_hash_lookup (info->hash, dl_name, FALSE, FALSE, FALSE); if (h == NULL) { /* No previous datalabel symbol. Make one. */ struct bfd_link_hash_entry *bh = NULL; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name, flags, *secp, *valp, - *namep, false, + *namep, FALSE, bed->collect, &bh)) { free (dl_name); - return false; + return FALSE; } h = (struct elf_link_hash_entry *) bh; - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; + h->non_elf = 0; h->type = STT_DATALABEL; } else @@ -2966,9 +2878,9 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) free (dl_name); if (h->type != STT_DATALABEL - || ((info->relocateable || info->emitrelocations) + || ((info->relocatable || info->emitrelocations) && h->root.type != bfd_link_hash_undefined) - || (! info->relocateable && !info->emitrelocations + || (! info->relocatable && !info->emitrelocations && h->root.type != bfd_link_hash_indirect)) { /* Make sure we don't get confused on invalid input. */ @@ -2976,7 +2888,7 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) (_("%s: encountered datalabel symbol in input"), bfd_get_filename (abfd)); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } /* Now find the hash-table slot for this entry and fill it in. */ @@ -2988,7 +2900,7 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) *namep = NULL; } - return true; + return TRUE; } /* This hook function is called before the linker writes out a global @@ -3003,23 +2915,22 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) we don't need to look up and make sure to emit the main symbol for each DataLabel symbol. */ -static boolean -sh64_elf64_link_output_symbol_hook (abfd, info, cname, sym, input_sec) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; - const char *cname; - Elf_Internal_Sym *sym; - asection *input_sec ATTRIBUTE_UNUSED; +static bfd_boolean +sh64_elf64_link_output_symbol_hook (struct bfd_link_info *info, + const char *cname, + Elf_Internal_Sym *sym, + asection *input_sec ATTRIBUTE_UNUSED, + struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) { char *name = (char *) cname; - if (info->relocateable || info->emitrelocations) + if (info->relocatable || info->emitrelocations) { if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL) name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0; } - return true; + return TRUE; } /* Set bit 0 on the entry address; it always points to SHmedia code. This @@ -3030,9 +2941,8 @@ sh64_elf64_link_output_symbol_hook (abfd, info, cname, sym, input_sec) before jumping to the program entry. */ static void -sh64_elf64_final_write_processing (abfd, linker) - bfd *abfd; - boolean linker ATTRIBUTE_UNUSED; +sh64_elf64_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { /* FIXME: Perhaps we shouldn't do this if the entry address was supplied numerically, but we currently lack the infrastructure to recognize @@ -3176,10 +3086,9 @@ static const bfd_byte *elf_sh64_pic_plt_entry; /* Create an entry in an sh ELF linker hash table. */ static struct bfd_hash_entry * -sh64_elf64_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; +sh64_elf64_link_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) { struct elf_sh64_link_hash_entry *ret = (struct elf_sh64_link_hash_entry *) entry; @@ -3209,8 +3118,7 @@ sh64_elf64_link_hash_newfunc (entry, table, string) /* Create an sh64 ELF linker hash table. */ static struct bfd_link_hash_table * -sh64_elf64_link_hash_table_create (abfd) - bfd *abfd; +sh64_elf64_link_hash_table_create (bfd *abfd) { struct elf_sh64_link_hash_table *ret; @@ -3219,8 +3127,9 @@ sh64_elf64_link_hash_table_create (abfd) if (ret == (struct elf_sh64_link_hash_table *) NULL) return NULL; - if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, - sh64_elf64_link_hash_newfunc)) + if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, + sh64_elf64_link_hash_newfunc, + sizeof (struct elf_sh64_link_hash_entry))) { free (ret); return NULL; @@ -3230,10 +3139,7 @@ sh64_elf64_link_hash_table_create (abfd) } inline static void -movi_shori_putval (output_bfd, value, addr) - bfd *output_bfd; - unsigned long value; - char *addr; +movi_shori_putval (bfd *output_bfd, unsigned long value, bfd_byte *addr) { bfd_put_32 (output_bfd, bfd_get_32 (output_bfd, addr) @@ -3246,10 +3152,7 @@ movi_shori_putval (output_bfd, value, addr) } inline static void -movi_3shori_putval (output_bfd, value, addr) - bfd *output_bfd; - bfd_vma value; - char *addr; +movi_3shori_putval (bfd *output_bfd, bfd_vma value, bfd_byte *addr) { bfd_put_32 (output_bfd, bfd_get_32 (output_bfd, addr) @@ -3271,14 +3174,12 @@ movi_3shori_putval (output_bfd, value, addr) /* Create dynamic sections when linking against a dynamic object. */ -static boolean -sh64_elf64_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +static bfd_boolean +sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) { flagword flags, pltflags; register asection *s; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); int ptralign = 0; switch (bed->s->arch_size) @@ -3293,7 +3194,7 @@ sh64_elf64_create_dynamic_sections (abfd, info) default: bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and @@ -3309,11 +3210,10 @@ sh64_elf64_create_dynamic_sections (abfd, info) if (bed->plt_readonly) pltflags |= SEC_READONLY; - s = bfd_make_section (abfd, ".plt"); + s = bfd_make_section_with_flags (abfd, ".plt", pltflags); if (s == NULL - || ! bfd_set_section_flags (abfd, s, pltflags) || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) - return false; + return FALSE; if (bed->want_plt_sym) { @@ -3324,27 +3224,28 @@ sh64_elf64_create_dynamic_sections (abfd, info) if (! (_bfd_generic_link_add_one_symbol (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, - (bfd_vma) 0, (const char *) NULL, false, bed->collect, &bh))) - return false; + (bfd_vma) 0, (const char *) NULL, FALSE, bed->collect, &bh))) + return FALSE; h = (struct elf_link_hash_entry *) bh; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; + h->def_regular = 1; h->type = STT_OBJECT; + elf_hash_table (info)->hplt = h; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; + && ! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; } - s = bfd_make_section (abfd, - bed->default_use_rela_p ? ".rela.plt" : ".rel.plt"); + s = bfd_make_section_with_flags (abfd, + bed->default_use_rela_p ? ".rela.plt" : ".rel.plt", + flags | SEC_READONLY); if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) || ! bfd_set_section_alignment (abfd, s, ptralign)) - return false; + return FALSE; if (! _bfd_elf_create_got_section (abfd, info)) - return false; + return FALSE; { const char *secname; @@ -3362,11 +3263,11 @@ sh64_elf64_create_dynamic_sections (abfd, info) relname = (char *) bfd_malloc (strlen (secname) + 6); strcpy (relname, ".rela"); strcat (relname, secname); - s = bfd_make_section (abfd, relname); + s = bfd_make_section_with_flags (abfd, relname, + flags | SEC_READONLY); if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) || ! bfd_set_section_alignment (abfd, s, ptralign)) - return false; + return FALSE; } } @@ -3378,10 +3279,10 @@ sh64_elf64_create_dynamic_sections (abfd, info) image and use a R_*_COPY reloc to tell the dynamic linker to initialize them at run time. The linker script puts the .dynbss section into the .bss section of the final image. */ - s = bfd_make_section (abfd, ".dynbss"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, SEC_ALLOC)) - return false; + s = bfd_make_section_with_flags (abfd, ".dynbss", + SEC_ALLOC | SEC_LINKER_CREATED); + if (s == NULL) + return FALSE; /* The .rel[a].bss section holds copy relocs. This section is not normally needed. We need to create it here, though, so that the @@ -3396,17 +3297,17 @@ sh64_elf64_create_dynamic_sections (abfd, info) copy relocs. */ if (! info->shared) { - s = bfd_make_section (abfd, - (bed->default_use_rela_p - ? ".rela.bss" : ".rel.bss")); + s = bfd_make_section_with_flags (abfd, + (bed->default_use_rela_p + ? ".rela.bss" : ".rel.bss"), + flags | SEC_READONLY); if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) || ! bfd_set_section_alignment (abfd, s, ptralign)) - return false; + return FALSE; } } - return true; + return TRUE; } /* Adjust a symbol defined by a dynamic object and referenced by a @@ -3415,52 +3316,47 @@ sh64_elf64_create_dynamic_sections (abfd, info) change the definition to something the rest of the link can understand. */ -static boolean -sh64_elf64_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; +static bfd_boolean +sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) { bfd *dynobj; asection *s; - unsigned int power_of_two; dynobj = elf_hash_table (info)->dynobj; /* Make sure we know what is going on here. */ BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); + && (h->needs_plt + || h->u.weakdef != NULL + || (h->def_dynamic + && h->ref_regular + && !h->def_regular))); /* 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. */ if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) + || h->needs_plt) { if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0) + && !h->def_dynamic + && !h->ref_dynamic) { /* This case can occur if we saw a PLT reloc in an input file, but the symbol was never referred to by a dynamic object. In such a case, we don't actually need to build a procedure linkage table, and we can just do a REL64 reloc instead. */ - BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); - return true; + BFD_ASSERT (h->needs_plt); + return TRUE; } /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) - return false; + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; } s = bfd_get_section_by_name (dynobj, ".plt"); @@ -3468,8 +3364,8 @@ sh64_elf64_adjust_dynamic_symbol (info, h) /* If this is the first .plt entry, make room for the special first entry. */ - if (s->_raw_size == 0) - s->_raw_size += PLT_ENTRY_SIZE; + if (s->size == 0) + 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 @@ -3477,43 +3373,43 @@ sh64_elf64_adjust_dynamic_symbol (info, h) pointers compare as equal between the normal executable and the shared library. */ if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + && !h->def_regular) { h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; + h->root.u.def.value = s->size; } - h->plt.offset = s->_raw_size; + h->plt.offset = s->size; /* Make room for this entry. */ - s->_raw_size += elf_sh64_sizeof_plt (info); + s->size += elf_sh64_sizeof_plt (info); /* We also need to make an entry in the .got.plt section, which will be placed in the .got section by the linker script. */ s = bfd_get_section_by_name (dynobj, ".got.plt"); BFD_ASSERT (s != NULL); - s->_raw_size += 8; + s->size += 8; /* We also need to make an entry in the .rela.plt section. */ s = bfd_get_section_by_name (dynobj, ".rela.plt"); BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf64_External_Rela); + s->size += sizeof (Elf64_External_Rela); - return true; + return TRUE; } /* 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->weakdef != NULL) + if (h->u.weakdef != NULL) { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; + 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; + return TRUE; } /* This is a reference to a symbol defined by a dynamic object which @@ -3524,12 +3420,19 @@ sh64_elf64_adjust_dynamic_symbol (info, h) For such cases we need not do anything here; the relocations will be handled correctly by relocate_section. */ if (info->shared) - return true; + return TRUE; /* If there are no references to this symbol that do not use the GOT, we don't need to generate a copy reloc. */ - if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0) - return true; + if (!h->non_got_ref) + return TRUE; + + if (h->size == 0) + { + (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"), + h->root.root.string); + return TRUE; + } /* We must allocate the symbol in our .dynbss section, which will become part of the .bss section of the executable. There will be @@ -3554,33 +3457,11 @@ sh64_elf64_adjust_dynamic_symbol (info, h) srel = bfd_get_section_by_name (dynobj, ".rela.bss"); BFD_ASSERT (srel != NULL); - srel->_raw_size += sizeof (Elf64_External_Rela); - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; - } - - /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. */ - power_of_two = bfd_log2 (h->size); - if (power_of_two > 3) - power_of_two = 3; - - /* Apply the required alignment. */ - s->_raw_size = BFD_ALIGN (s->_raw_size, - (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) - { - if (! bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; + srel->size += sizeof (Elf64_External_Rela); + h->needs_copy = 1; } - /* Define the symbol as being at this point in the section. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Increment the section size to make room for the symbol. */ - s->_raw_size += h->size; - - return true; + return _bfd_elf_adjust_dynamic_copy (h, s); } /* This function is called via sh_elf_link_hash_traverse if we are @@ -3590,10 +3471,9 @@ sh64_elf64_adjust_dynamic_symbol (info, h) check_relocs routine, but we won't fill them in in the relocate_section routine. */ -static boolean -sh64_elf64_discard_copies (h, ignore) - struct elf_sh64_link_hash_entry *h; - PTR ignore ATTRIBUTE_UNUSED; +static bfd_boolean +sh64_elf64_discard_copies (struct elf_sh64_link_hash_entry *h, + void *ignore ATTRIBUTE_UNUSED) { struct elf_sh64_pcrel_relocs_copied *s; @@ -3601,27 +3481,26 @@ sh64_elf64_discard_copies (h, ignore) h = (struct elf_sh64_link_hash_entry *) h->root.root.u.i.link; /* We only discard relocs for symbols defined in a regular object. */ - if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - return true; + if (!h->root.def_regular) + return TRUE; for (s = h->pcrel_relocs_copied; s != NULL; s = s->next) - s->section->_raw_size -= s->count * sizeof (Elf64_External_Rela); + s->section->size -= s->count * sizeof (Elf64_External_Rela); - return true; + return TRUE; } /* Set the sizes of the dynamic sections. */ -static boolean -sh64_elf64_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; +static bfd_boolean +sh64_elf64_size_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) { bfd *dynobj; asection *s; - boolean plt; - boolean relocs; - boolean reltext; + bfd_boolean plt; + bfd_boolean relocs; + bfd_boolean reltext; dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); @@ -3629,11 +3508,11 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) if (elf_hash_table (info)->dynamic_sections_created) { /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) + if (info->executable) { s = bfd_get_section_by_name (dynobj, ".interp"); BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; + s->size = sizeof ELF_DYNAMIC_INTERPRETER; s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; } } @@ -3646,7 +3525,7 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) below. */ s = bfd_get_section_by_name (dynobj, ".rela.got"); if (s != NULL) - s->_raw_size = 0; + s->size = 0; } /* If this is a -Bsymbolic shared link, then we need to discard all @@ -3655,19 +3534,17 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) will not fill them in in the relocate_section routine. */ if (info->shared && info->symbolic) sh64_elf64_link_hash_traverse (sh64_elf64_hash_table (info), - sh64_elf64_discard_copies, - (PTR) NULL); + sh64_elf64_discard_copies, NULL); /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ - plt = false; - relocs = false; - reltext = false; + plt = FALSE; + relocs = FALSE; + reltext = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { const char *name; - boolean strip; if ((s->flags & SEC_LINKER_CREATED) == 0) continue; @@ -3676,38 +3553,14 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) of the dynobj section names depend upon the input files. */ name = bfd_get_section_name (dynobj, s); - strip = false; - if (strcmp (name, ".plt") == 0) { - if (s->_raw_size == 0) - { - /* Strip this section if we don't need it; see the - comment below. */ - strip = true; - } - else - { - /* Remember whether there is a PLT. */ - plt = true; - } + /* Remember whether there is a PLT. */ + plt = s->size != 0; } - else if (strncmp (name, ".rela", 5) == 0) + else if (CONST_STRNEQ (name, ".rela")) { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rela.bss and - .rela.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else + if (s->size != 0) { asection *target; @@ -3717,7 +3570,7 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) { const char *outname; - relocs = true; + relocs = TRUE; /* If this relocation section applies to a read only section, then we probably need a DT_TEXTREL @@ -3730,7 +3583,7 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) if (target != NULL && (target->flags & SEC_READONLY) != 0 && (target->flags & SEC_ALLOC) != 0) - reltext = true; + reltext = TRUE; } /* We use the reloc_count field as a counter if we need @@ -3738,22 +3591,35 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) s->reloc_count = 0; } } - else if (strncmp (name, ".got", 4) != 0) + else if (! CONST_STRNEQ (name, ".got") + && strcmp (name, ".dynbss") != 0) { /* It's not one of our sections, so don't allocate space. */ continue; } - if (strip) + if (s->size == 0) { - _bfd_strip_section_from_output (info, s); + /* If we don't need this section, strip it from the + output file. This is mostly to handle .rela.bss and + .rela.plt. We must create both sections in + create_dynamic_sections, because they must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + s->flags |= SEC_EXCLUDE; continue; } + if ((s->flags & SEC_HAS_CONTENTS) == 0) + continue; + /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; + s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); + if (s->contents == NULL) + return FALSE; } if (elf_hash_table (info)->dynamic_sections_created) @@ -3763,49 +3629,48 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) must add the entries now so that we get the correct size for the .dynamic section. The DT_DEBUG entry is filled in by the dynamic linker and used by the debugger. */ - if (! info->shared) + if (info->executable) { - if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; + if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0)) + return FALSE; } if (plt) { - if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0) - || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; + if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0) + || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0) + || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA) + || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)) + return FALSE; } if (relocs) { - if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0) - || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0) - || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf64_External_Rela))) - return false; + if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0) + || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0) + || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT, + sizeof (Elf64_External_Rela))) + return FALSE; } if (reltext) { - if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; + if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0)) + return FALSE; } } - return true; + return TRUE; } /* Finish up dynamic symbol handling. We set the contents of various dynamic sections here. */ -static boolean -sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +static bfd_boolean +sh64_elf64_finish_dynamic_symbol (bfd *output_bfd, + struct bfd_link_info *info, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { bfd *dynobj; @@ -3820,6 +3685,7 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) bfd_vma plt_index; bfd_vma got_offset; Elf_Internal_Rela rel; + bfd_byte *loc; /* This symbol has an entry in the procedure linkage table. Set it up. */ @@ -3908,11 +3774,10 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_JMP_SLOT64); rel.r_addend = 0; rel.r_addend = GOT_BIAS; - bfd_elf64_swap_reloca_out (output_bfd, &rel, - ((Elf64_External_Rela *) srel->contents - + plt_index)); + loc = srel->contents + plt_index * sizeof (Elf64_External_Rela); + bfd_elf64_swap_reloca_out (output_bfd, &rel, loc); - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + if (!h->def_regular) { /* Mark the symbol as undefined, rather than as defined in the .plt section. Leave the value alone. */ @@ -3925,6 +3790,7 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) asection *sgot; asection *srel; Elf_Internal_Rela rel; + bfd_byte *loc; /* This symbol has an entry in the global offset table. Set it up. */ @@ -3944,7 +3810,7 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) initialized in the relocate_section function. */ if (info->shared && (info->symbolic || h->dynindx == -1) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + && h->def_regular) { rel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64); rel.r_addend = (h->root.u.def.value @@ -3958,16 +3824,16 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) rel.r_addend = 0; } - bfd_elf64_swap_reloca_out (output_bfd, &rel, - ((Elf64_External_Rela *) srel->contents - + srel->reloc_count)); - ++srel->reloc_count; + loc = srel->contents; + loc += srel->reloc_count++ * sizeof (Elf64_External_Rela); + bfd_elf64_swap_reloca_out (output_bfd, &rel, loc); } - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) + if (h->needs_copy) { asection *s; Elf_Internal_Rela rel; + bfd_byte *loc; /* This symbol needs a copy reloc. Set it up. */ @@ -3984,26 +3850,24 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) + h->root.u.def.section->output_offset); rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_COPY64); rel.r_addend = 0; - bfd_elf64_swap_reloca_out (output_bfd, &rel, - ((Elf64_External_Rela *) s->contents - + s->reloc_count)); - ++s->reloc_count; + loc = s->contents; + loc += s->reloc_count++ * sizeof (Elf64_External_Rela); + bfd_elf64_swap_reloca_out (output_bfd, &rel, loc); } /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) + || h == elf_hash_table (info)->hgot) sym->st_shndx = SHN_ABS; - return true; + return TRUE; } /* Finish up the dynamic sections. */ -static boolean -sh64_elf64_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; +static bfd_boolean +sh64_elf64_finish_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) { bfd *dynobj; asection *sgot; @@ -4023,7 +3887,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) BFD_ASSERT (sdyn != NULL); dyncon = (Elf64_External_Dyn *) sdyn->contents; - dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size); + dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size); for (; dyncon < dynconend; dyncon++) { Elf_Internal_Dyn dyn; @@ -4048,7 +3912,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) if (dyn.d_un.d_val != 0) { h = elf_link_hash_lookup (elf_hash_table (info), name, - false, false, true); + FALSE, FALSE, TRUE); if (h != NULL && (h->other & STO_SH5_ISA32)) { dyn.d_un.d_val |= 1; @@ -4073,10 +3937,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) case DT_PLTRELSZ: s = bfd_get_section_by_name (output_bfd, ".rela.plt"); BFD_ASSERT (s != NULL); - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; + dyn.d_un.d_val = s->size; bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); break; @@ -4092,12 +3953,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) about changing the DT_RELA entry. */ s = bfd_get_section_by_name (output_bfd, ".rela.plt"); if (s != NULL) - { - if (s->_cooked_size != 0) - dyn.d_un.d_val -= s->_cooked_size; - else - dyn.d_un.d_val -= s->_raw_size; - } + dyn.d_un.d_val -= s->size; bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); break; } @@ -4105,7 +3961,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) /* Fill in the first entry in the procedure linkage table. */ splt = bfd_get_section_by_name (dynobj, ".plt"); - if (splt && splt->_raw_size > 0) + if (splt && splt->size > 0) { if (info->shared) { @@ -4141,7 +3997,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) } /* Fill in the first three entries in the global offset table. */ - if (sgot->_raw_size > 0) + if (sgot->size > 0) { if (sdyn == NULL) bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents); @@ -4155,9 +4011,36 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 8; - return true; + return TRUE; } +/* Merge non visibility st_other attribute when the symbol comes from + a dynamic object. */ +static void +sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h, + const Elf_Internal_Sym *isym, + bfd_boolean definition, + bfd_boolean dynamic ATTRIBUTE_UNUSED) +{ + if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0) + { + unsigned char other; + + /* Take the balance of OTHER from the definition. */ + other = (definition ? isym->st_other : h->other); + other &= ~ ELF_ST_VISIBILITY (-1); + h->other = other | ELF_ST_VISIBILITY (h->other); + } + + return; +} + +static const struct bfd_elf_special_section sh64_elf64_special_sections[]= +{ + { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 }, + { NULL, 0, 0, 0, 0 } +}; + #define TARGET_BIG_SYM bfd_elf64_sh64_vec #define TARGET_BIG_NAME "elf64-sh64" #define TARGET_LITTLE_SYM bfd_elf64_sh64l_vec @@ -4169,6 +4052,8 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) #define elf_symbol_leading_char '_' #define bfd_elf64_bfd_reloc_type_lookup sh_elf64_reloc_type_lookup +#define bfd_elf64_bfd_reloc_name_lookup \ + sh_elf64_reloc_name_lookup #define elf_info_to_howto sh_elf64_info_to_howto /* Note: there's no relaxation at present. */ @@ -4186,7 +4071,6 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) #define elf_backend_fake_sections sh64_elf64_fake_sections #define elf_backend_gc_mark_hook sh_elf64_gc_mark_hook -#define elf_backend_gc_sweep_hook sh_elf64_gc_sweep_hook #define elf_backend_check_relocs sh_elf64_check_relocs #define elf_backend_can_gc_sections 1 @@ -4198,6 +4082,9 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) #define elf_backend_link_output_symbol_hook \ sh64_elf64_link_output_symbol_hook +#define elf_backend_merge_symbol_attribute \ + sh64_elf64_merge_symbol_attribute + #define elf_backend_final_write_processing \ sh64_elf64_final_write_processing @@ -4209,16 +4096,18 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) sh64_elf64_adjust_dynamic_symbol #define elf_backend_size_dynamic_sections \ sh64_elf64_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_finish_dynamic_symbol \ sh64_elf64_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections \ sh64_elf64_finish_dynamic_sections +#define elf_backend_special_sections sh64_elf64_special_sections #define elf_backend_want_got_plt 1 #define elf_backend_plt_readonly 1 #define elf_backend_want_plt_sym 0 #define elf_backend_got_header_size 24 -#define elf_backend_plt_header_size PLT_ENTRY_SIZE #include "elf64-target.h" @@ -4249,6 +4138,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) #define TARGET_LITTLE_SYM bfd_elf64_sh64lin_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf64-sh64-linux" +#undef elf64_bed +#define elf64_bed elf64_sh64_linux_bed -#define INCLUDED_TARGET_FILE #include "elf64-target.h"