X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/dc84ceef3ac53050c218e388b26f08e35462440c..121a04390c79a490f751c6986482d320adbb97db:/bfd/elf64-sh64.c diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index 731995f2b8..a39002597c 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -1,12 +1,12 @@ /* SuperH SH64-specific support for 64-bit ELF - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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" @@ -1392,6 +1393,22 @@ sh_elf64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 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. */ @@ -1487,10 +1504,10 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 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; @@ -1509,13 +1526,15 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, _("Unexpected STO_SH5_ISA32 on local symbol is not handled"), input_bfd, input_section, rel->r_offset)); - if (info->relocatable) + if (sec != NULL && elf_discarded_section (sec)) + /* Handled below. */ + ; + else if (info->relocatable) { /* 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; @@ -1554,12 +1573,6 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, { /* ??? Could we use the RELOC_FOR_GLOBAL_SYMBOL macro here ? */ - /* Section symbols are never (?) placed in the hash table, so - we can just ignore hash relocations when creating a - relocatable object file. */ - if (info->relocatable) - continue; - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) @@ -1619,8 +1632,17 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, || (sec->output_section == NULL && ((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))) - relocation = 0; - else if (sec->output_section == NULL) + ; + else if (sec->output_section != NULL) + relocation = ((h->root.u.def.value + + sec->output_section->vma + + sec->output_offset) + /* A STO_SH5_ISA32 causes a "bitor 1" to the + symbol value, unless we've seen + STT_DATALABEL on the way to it. */ + | ((h->other & STO_SH5_ISA32) != 0 + && ! seen_stt_datalabel)); + else if (!info->relocatable) { (*_bfd_error_handler) (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), @@ -1629,24 +1651,14 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, (long) rel->r_offset, howto->name, h->root.root.string); - relocation = 0; } - else - relocation = ((h->root.u.def.value - + sec->output_section->vma - + sec->output_offset) - /* A STO_SH5_ISA32 causes a "bitor 1" to the - symbol value, unless we've seen - STT_DATALABEL on the way to it. */ - | ((h->other & STO_SH5_ISA32) != 0 - && ! seen_stt_datalabel)); } else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; + ; else if (info->unresolved_syms_in_objects == RM_IGNORE && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - relocation = 0; - else + ; + else if (!info->relocatable) { if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, @@ -1654,10 +1666,23 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, (info->unresolved_syms_in_objects == RM_GENERATE_ERROR || ELF_ST_VISIBILITY (h->other))))) return FALSE; - relocation = 0; } } + if (sec != NULL && elf_discarded_section (sec)) + { + /* For relocs against symbols from removed linkonce sections, + or sections discarded by a linker script, we just want the + section contents zeroed. Avoid any special processing. */ + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + rel->r_info = 0; + rel->r_addend = 0; + continue; + } + + if (info->relocatable) + continue; + disp = (relocation - input_section->output_section->vma - input_section->output_offset @@ -2170,17 +2195,12 @@ sh_elf64_get_relocated_section_contents (bfd *output_bfd, 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; } @@ -2292,6 +2312,9 @@ sh_elf64_copy_private_data_internal (bfd *ibfd, bfd *obfd) } } + /* Copy object attributes. */ + _bfd_elf_copy_obj_attributes (ibfd, obfd); + return sh_elf64_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags); } @@ -2391,7 +2414,7 @@ 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; @@ -2409,9 +2432,6 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info, 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); @@ -2480,7 +2500,9 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info, /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_SH_GNU_VTENTRY: - if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + BFD_ASSERT (h != NULL); + if (h != NULL + && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -3300,7 +3322,6 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info, { bfd *dynobj; asection *s; - unsigned int power_of_two; dynobj = elf_hash_table (info)->dynobj; @@ -3440,28 +3461,7 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info, 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->size = BFD_ALIGN (s->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->size; - - /* Increment the section size to make room for the symbol. */ - s->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 @@ -4052,6 +4052,8 @@ static const struct bfd_elf_special_section sh64_elf64_special_sections[]= #define elf_symbol_leading_char '_' #define bfd_elf64_bfd_reloc_type_lookup sh_elf64_reloc_type_lookup +#define bfd_elf64_bfd_reloc_name_lookup \ + sh_elf64_reloc_name_lookup #define elf_info_to_howto sh_elf64_info_to_howto /* Note: there's no relaxation at present. */ @@ -4136,6 +4138,7 @@ static const struct bfd_elf_special_section sh64_elf64_special_sections[]= #define TARGET_LITTLE_SYM bfd_elf64_sh64lin_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf64-sh64-linux" +#undef elf64_bed +#define elf64_bed elf64_sh64_linux_bed -#define INCLUDED_TARGET_FILE #include "elf64-target.h"