X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf64-sh64.c;h=920247726763975d5bebcaf9b07686a0bae35841;hb=bb593acb76bc52b23ddbad3f9b5199be26879da5;hp=091849690e768aad8d297f83e21a687d2ba973b0;hpb=f8ecb12b16adaae13e187352852113cda9c5394d;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index 091849690e..9202477267 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, 2009, + 2010, 2011 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" @@ -87,83 +89,18 @@ struct elf_sh64_link_hash_entry struct elf_sh64_pcrel_relocs_copied *pcrel_relocs_copied; }; -/* sh ELF linker hash table. */ - -struct elf_sh64_link_hash_table -{ - struct elf_link_hash_table root; -}; - /* Traverse an sh ELF linker 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), \ +#define sh64_elf64_link_hash_traverse(table, func, info) \ + (elf_link_hash_traverse \ + ((table), \ + (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ (info))) -/* Get the sh ELF linker hash table from a link_info structure. */ - -#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 ((bfd *, 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 *)); -extern 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 +108,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 +198,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 +215,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 +258,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 +317,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 +545,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 +1015,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 +1032,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 +1228,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 +1245,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 +1367,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 +1381,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 +1422,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 +1478,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,26 +1514,52 @@ 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; continue; } + else if (! howto->partial_inplace) + { + 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) + && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + { + asection *msec; + + if (howto->rightshift || howto->src_mask != 0xffffffff) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"), + input_bfd, input_section, + (long) rel->r_offset, howto->name); + return FALSE; + } + + addend = bfd_get_32 (input_bfd, contents + rel->r_offset); + msec = sec; + addend = + _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) + - relocation; + addend += msec->output_section->vma + msec->output_offset; + bfd_put_32 (input_bfd, addend, contents + rel->r_offset); + addend = 0; + } } 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 @@ -1631,8 +1595,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 @@ -1640,8 +1603,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)) @@ -1651,17 +1613,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) @@ -1670,21 +1630,44 @@ 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_elf_section_offset (output_bfd, info, + input_section, + rel->r_offset) + != (bfd_vma) -1)) + { + (*_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)) + RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, + rel, relend, howto, contents); + + if (info->relocatable) + continue; + disp = (relocation - input_section->output_section->vma - input_section->output_offset @@ -1703,7 +1686,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) { @@ -1715,11 +1698,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 @@ -1727,35 +1710,23 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) + return FALSE; } - 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); @@ -1774,10 +1745,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; } @@ -1789,11 +1759,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 @@ -1875,7 +1843,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 @@ -1942,22 +1910,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) @@ -2089,7 +2056,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, default: bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } @@ -2105,27 +2072,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 @@ -2134,178 +2102,126 @@ 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; - Elf_Internal_Shdr *shndx_hdr; asection *input_section = link_order->u.indirect.section; bfd *input_bfd = input_section->owner; asection **sections = NULL; Elf_Internal_Rela *internal_relocs = NULL; - Elf64_External_Sym *external_syms = NULL; - Elf_External_Sym_Shndx *shndx_buf = NULL; - Elf_External_Sym_Shndx *shndx; - Elf_Internal_Sym *internal_syms = NULL; + Elf_Internal_Sym *isymbuf = NULL; /* 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; - shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_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) { Elf_Internal_Sym *isymp; + Elf_Internal_Sym *isymend; asection **secpp; - Elf64_External_Sym *esym, *esymend; - bfd_size_type amt; - if (symtab_hdr->contents != NULL) - external_syms = (Elf64_External_Sym *) symtab_hdr->contents; - else - { - amt = symtab_hdr->sh_info; - amt *= sizeof (Elf64_External_Sym); - - external_syms = (Elf64_External_Sym *) bfd_malloc (amt); - if (external_syms == NULL && symtab_hdr->sh_info > 0) - goto error_return; - - if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 - || (bfd_bread ((PTR) external_syms, amt, input_bfd) != amt)) - goto error_return; - } - - if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0) + /* Read this BFD's local symbols. */ + if (symtab_hdr->sh_info != 0) { - amt = symtab_hdr->sh_info; - amt *= sizeof (Elf_External_Sym_Shndx); - - shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt); - if (shndx_buf == NULL) - goto error_return; - - if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt) + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, + NULL, NULL, NULL); + if (isymbuf == NULL) 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; - internal_syms = ((Elf_Internal_Sym *) - bfd_malloc (symtab_hdr->sh_info - * sizeof (Elf_Internal_Sym))); - if (internal_syms == NULL && symtab_hdr->sh_info > 0) - goto error_return; - sections = (asection **) bfd_malloc (symtab_hdr->sh_info * sizeof (asection *)); if (sections == NULL && symtab_hdr->sh_info > 0) goto error_return; - isymp = internal_syms; secpp = sections; - esym = external_syms; - esymend = esym + symtab_hdr->sh_info; - shndx = shndx_buf; - for (; esym < esymend; - ++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL)) + isymend = isymbuf + symtab_hdr->sh_info; + for (isymp = isymbuf; isymp < isymend; ++isymp, ++secpp) { asection *isec; - bfd_elf64_swap_symbol_in (input_bfd, (const PTR) esym, - (const PTR) shndx, isymp); - 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; } if (! sh_elf64_relocate_section (output_bfd, link_info, input_bfd, input_section, data, internal_relocs, - internal_syms, sections)) + isymbuf, sections)) goto error_return; if (sections != NULL) free (sections); - sections = NULL; - if (internal_syms != NULL) - free (internal_syms); - internal_syms = NULL; - if (external_syms != NULL && symtab_hdr->contents == NULL) - free (external_syms); - external_syms = NULL; if (internal_relocs != elf_section_data (input_section)->relocs) free (internal_relocs); - internal_relocs = NULL; + if (isymbuf != NULL + && (unsigned char *) isymbuf != symtab_hdr->contents) + free (isymbuf); } return data; error_return: + if (sections != NULL) + free (sections); if (internal_relocs != NULL && internal_relocs != elf_section_data (input_section)->relocs) free (internal_relocs); - if (external_syms != NULL && symtab_hdr->contents == NULL) - free (external_syms); - if (internal_syms != NULL) - free (internal_syms); - if (sections != NULL) - free (sections); + if (isymbuf != NULL + && (unsigned char *) isymbuf != symtab_hdr->contents) + free (isymbuf); return NULL; } /* 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; @@ -2318,35 +2234,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; @@ -2354,7 +2266,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) @@ -2373,30 +2285,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) == false) - return false; + if (! _bfd_generic_verify_endian_match (ibfd, obfd)) + 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)) { @@ -2414,7 +2325,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; @@ -2422,7 +2333,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 @@ -2434,7 +2345,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); @@ -2450,70 +2361,33 @@ sh_elf64_merge_private_data (ibfd, obfd) relocation. */ static asection * -sh_elf64_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; - 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: - 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 (abfd, 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; @@ -2526,14 +2400,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); @@ -2548,7 +2419,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) @@ -2577,7 +2453,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: @@ -2590,15 +2466,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: @@ -2622,17 +2500,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; } } @@ -2647,7 +2525,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 { @@ -2656,17 +2534,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 { @@ -2683,7 +2561,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; @@ -2699,7 +2577,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 { @@ -2708,7 +2586,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) @@ -2716,11 +2594,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; @@ -2745,11 +2623,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; @@ -2773,14 +2651,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 @@ -2799,45 +2677,21 @@ 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 section in dynobj and make room for this reloc. */ if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) - { - 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; - 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 @@ -2864,7 +2718,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; @@ -2879,13 +2733,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; @@ -2915,27 +2767,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 @@ -2946,28 +2794,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; + 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, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h)) + *namep, FALSE, + bed->collect, &bh)) { free (dl_name); - return false; + return FALSE; } - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; + h = (struct elf_link_hash_entry *) bh; + h->non_elf = 0; h->type = STT_DATALABEL; } else @@ -2976,9 +2827,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. */ @@ -2986,7 +2837,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. */ @@ -2998,7 +2849,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 @@ -3013,23 +2864,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. */ -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 int +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 1; } /* Set bit 0 on the entry address; it always points to SHmedia code. This @@ -3040,9 +2890,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 @@ -3061,7 +2910,7 @@ static const bfd_byte elf_sh64_plt0_entry_be[PLT_ENTRY_SIZE] = 0xc8, 0x00, 0x01, 0x10, /* shori (.got.plt >> 16) & 65535, r17 */ 0xc8, 0x00, 0x01, 0x10, /* shori .got.plt & 65535, r17 */ 0x8d, 0x10, 0x09, 0x90, /* ld.q r17, 16, r25 */ - 0x6b, 0xf1, 0x46, 0x00, /* ptabs r17, tr0 */ + 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ 0x8d, 0x10, 0x05, 0x10, /* ld.q r17, 8, r17 */ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */ 0x6f, 0xf0, 0xff, 0xf0, /* nop */ @@ -3081,7 +2930,7 @@ static const bfd_byte elf_sh64_plt0_entry_le[PLT_ENTRY_SIZE] = 0x10, 0x01, 0x00, 0xc8, /* shori (.got.plt >> 16) & 65535, r17 */ 0x10, 0x01, 0x00, 0xc8, /* shori .got.plt & 65535, r17 */ 0x90, 0x09, 0x10, 0x8d, /* ld.q r17, 16, r25 */ - 0x00, 0x46, 0xf1, 0x6b, /* ptabs r17, tr0 */ + 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ 0x10, 0x05, 0x10, 0x8d, /* ld.q r17, 8, r17 */ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */ 0xf0, 0xff, 0xf0, 0x6f, /* nop */ @@ -3107,9 +2956,9 @@ static const bfd_byte elf_sh64_plt_entry_be[PLT_ENTRY_SIZE] = 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */ 0x6f, 0xf0, 0xff, 0xf0, /* nop */ - 0xcc, 0x00, 0x01, 0x90, /* movi .PLT0 >> 16, r25 */ - 0xc8, 0x00, 0x01, 0x90, /* shori .PLT0 & 65535, r25 */ - 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ + 0xcc, 0x00, 0x01, 0x90, /* movi (.+8-.PLT0) >> 16, r25 */ + 0xc8, 0x00, 0x01, 0x90, /* shori (.+4-.PLT0) & 65535, r25 */ + 0x6b, 0xf5, 0x66, 0x00, /* ptrel r25, tr0 */ 0xcc, 0x00, 0x01, 0x50, /* movi reloc-offset >> 16, r21 */ 0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */ @@ -3127,9 +2976,9 @@ static const bfd_byte elf_sh64_plt_entry_le[PLT_ENTRY_SIZE] = 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */ 0xf0, 0xff, 0xf0, 0x6f, /* nop */ - 0x90, 0x01, 0x00, 0xcc, /* movi .PLT0 >> 16, r25 */ - 0x90, 0x01, 0x00, 0xc8, /* shori .PLT0 & 65535, r25 */ - 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ + 0x90, 0x01, 0x00, 0xcc, /* movi (.+8-.PLT0) >> 16, r25 */ + 0x90, 0x01, 0x00, 0xc8, /* shori (.+4-.PLT0) & 65535, r25 */ + 0x00, 0x66, 0xf5, 0x6b, /* ptrel r25, tr0 */ 0x50, 0x01, 0x00, 0xcc, /* movi reloc-offset >> 16, r21 */ 0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */ @@ -3150,7 +2999,7 @@ static const bfd_byte elf_sh64_pic_plt_entry_be[PLT_ENTRY_SIZE] = 0x6f, 0xf0, 0xff, 0xf0, /* nop */ 0x6f, 0xf0, 0xff, 0xf0, /* nop */ 0xce, 0x00, 0x01, 0x10, /* movi -GOT_BIAS, r17 */ - 0x00, 0xcb, 0x45, 0x10, /* sub r12, r17, r17 */ + 0x00, 0xc9, 0x45, 0x10, /* add r12, r17, r17 */ 0x8d, 0x10, 0x09, 0x90, /* ld.q r17, 16, r25 */ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */ 0x8d, 0x10, 0x05, 0x10, /* ld.q r17, 8, r17 */ @@ -3170,7 +3019,7 @@ static const bfd_byte elf_sh64_pic_plt_entry_le[PLT_ENTRY_SIZE] = 0xf0, 0xff, 0xf0, 0x6f, /* nop */ 0xf0, 0xff, 0xf0, 0x6f, /* nop */ 0x10, 0x01, 0x00, 0xce, /* movi -GOT_BIAS, r17 */ - 0x10, 0x45, 0xcb, 0x00, /* sub r12, r17, r17 */ + 0x10, 0x45, 0xc9, 0x00, /* add r12, r17, r17 */ 0x90, 0x09, 0x10, 0x8d, /* ld.q r17, 16, r25 */ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */ 0x10, 0x05, 0x10, 0x8d, /* ld.q r17, 8, r17 */ @@ -3186,10 +3035,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; @@ -3219,31 +3067,28 @@ 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; + struct elf_link_hash_table *ret; - ret = ((struct elf_sh64_link_hash_table *) - bfd_malloc (sizeof (struct elf_sh64_link_hash_table))); - if (ret == (struct elf_sh64_link_hash_table *) NULL) + ret = (struct elf_link_hash_table *) bfd_malloc (sizeof (* ret)); + if (ret == (struct elf_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, abfd, + sh64_elf64_link_hash_newfunc, + sizeof (struct elf_sh64_link_hash_entry), + GENERIC_ELF_DATA)) { free (ret); return NULL; } - return &ret->root.root; + return &ret->root; } 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) @@ -3256,10 +3101,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) @@ -3281,14 +3123,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) @@ -3303,7 +3143,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 @@ -3319,40 +3159,42 @@ 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) { /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. */ - struct elf_link_hash_entry *h = NULL; + struct elf_link_hash_entry *h; + struct bfd_link_hash_entry *bh = NULL; + if (! (_bfd_generic_link_add_one_symbol (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; + (bfd_vma) 0, (const char *) NULL, FALSE, bed->collect, &bh))) + return FALSE; + + h = (struct elf_link_hash_entry *) bh; + 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; @@ -3370,11 +3212,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; } } @@ -3386,10 +3228,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 @@ -3404,17 +3246,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 @@ -3423,52 +3265,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"); @@ -3476,8 +3313,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 @@ -3485,43 +3322,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 @@ -3532,12 +3369,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 @@ -3562,33 +3406,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; + srel->size += sizeof (Elf64_External_Rela); + h->needs_copy = 1; } - /* 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; - } - - /* 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 @@ -3598,38 +3420,33 @@ 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; - if (h->root.root.type == bfd_link_hash_warning) - 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); @@ -3637,11 +3454,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; } } @@ -3654,7 +3471,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 @@ -3662,20 +3479,18 @@ sh64_elf64_size_dynamic_sections (output_bfd, info) We allocated space for them in the check_relocs routine, but we 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_link_hash_traverse (elf_hash_table (info), + 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; @@ -3684,38 +3499,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; @@ -3725,7 +3516,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 @@ -3738,7 +3529,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 @@ -3746,22 +3537,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_alloc (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) @@ -3771,49 +3575,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; @@ -3828,6 +3631,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. */ @@ -3850,7 +3654,8 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) The first three are reserved. */ got_offset = (plt_index + 3) * 8; - got_offset -= GOT_BIAS; + if (info->shared) + got_offset -= GOT_BIAS; /* Fill in the entry in the procedure linkage table. */ if (! info->shared) @@ -3869,8 +3674,11 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) (splt->contents + h->plt.offset + elf_sh64_plt_symbol_offset (info))); + /* Set bottom bit because its for a branch to SHmedia */ movi_shori_putval (output_bfd, - (splt->output_section->vma + splt->output_offset), + -(h->plt.offset + + elf_sh64_plt_plt0_offset (info) + 8) + | 1, (splt->contents + h->plt.offset + elf_sh64_plt_plt0_offset (info))); } @@ -3889,7 +3697,8 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym) + elf_sh64_plt_symbol_offset (info))); } - got_offset += GOT_BIAS; + if (info->shared) + got_offset += GOT_BIAS; movi_shori_putval (output_bfd, plt_index * sizeof (Elf64_External_Rela), @@ -3911,11 +3720,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. */ @@ -3928,6 +3736,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. */ @@ -3947,7 +3756,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 @@ -3961,16 +3770,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. */ @@ -3987,26 +3796,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; @@ -4026,12 +3833,13 @@ 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; const char *name; asection *s; + struct elf_link_hash_entry *h; bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); @@ -4040,6 +3848,25 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) default: break; + case DT_INIT: + name = info->init_function; + goto get_sym; + + case DT_FINI: + name = info->fini_function; + get_sym: + if (dyn.d_un.d_val != 0) + { + h = elf_link_hash_lookup (elf_hash_table (info), name, + FALSE, FALSE, TRUE); + if (h != NULL && (h->other & STO_SH5_ISA32)) + { + dyn.d_un.d_val |= 1; + bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); + } + } + break; + case DT_PLTGOT: name = ".got"; goto get_vma; @@ -4056,10 +3883,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; @@ -4075,12 +3899,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; } @@ -4088,7 +3907,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) { @@ -4124,7 +3943,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); @@ -4138,11 +3957,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 } +}; -#ifndef ELF_ARCH #define TARGET_BIG_SYM bfd_elf64_sh64_vec #define TARGET_BIG_NAME "elf64-sh64" #define TARGET_LITTLE_SYM bfd_elf64_sh64l_vec @@ -4152,9 +3996,10 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info) #define ELF_MAXPAGESIZE 128 #define elf_symbol_leading_char '_' -#endif /* ELF_ARCH */ #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. */ @@ -4172,7 +4017,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 @@ -4184,6 +4028,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 @@ -4195,15 +4042,49 @@ 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" + +/* NetBSD support. */ +#undef TARGET_BIG_SYM +#define TARGET_BIG_SYM bfd_elf64_sh64nbsd_vec +#undef TARGET_BIG_NAME +#define TARGET_BIG_NAME "elf64-sh64-nbsd" +#undef TARGET_LITTLE_SYM +#define TARGET_LITTLE_SYM bfd_elf64_sh64lnbsd_vec +#undef TARGET_LITTLE_NAME +#define TARGET_LITTLE_NAME "elf64-sh64l-nbsd" +#undef ELF_MAXPAGESIZE +#define ELF_MAXPAGESIZE 0x10000 +#undef elf_symbol_leading_char +#define elf_symbol_leading_char 0 + +#define elf64_bed elf64_sh64_nbsd_bed + +#include "elf64-target.h" + +/* Linux support. */ +#undef TARGET_BIG_SYM +#define TARGET_BIG_SYM bfd_elf64_sh64blin_vec +#undef TARGET_BIG_NAME +#define TARGET_BIG_NAME "elf64-sh64big-linux" +#undef TARGET_LITTLE_SYM +#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 #include "elf64-target.h"