X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf64-mmix.c;h=9a37840a23170b0115f2965500dbe1f1db0764ae;hb=c2b4a39dd204173238cb5bb8a367dc68c8d803ad;hp=e18f4a1f5b68434f396a7cee566da6d9177434bc;hpb=74541ad4c01323646d5bebe7ff10828f84af0f49;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index e18f4a1f5b..9a37840a23 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1,23 +1,25 @@ /* MMIX-specific support for 64-bit ELF. - Copyright 2001, 2002, 2003, 2004, 2005, 2006 + Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Contributed by Hans-Peter Nilsson -This file is part of BFD, the Binary File Descriptor library. + 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 -(at your option) any later version. + 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 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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. */ -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. */ /* No specific ABI or "processor-specific supplement" defined. */ @@ -27,8 +29,8 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. - GETA stub relaxation (call a stub for out of range new R_MMIX_GETA_STUBBABLE). */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "elf-bfd.h" #include "elf/mmix.h" @@ -848,6 +850,22 @@ bfd_elf64_bfd_reloc_type_lookup (abfd, code) return NULL; } +static reloc_howto_type * +bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < sizeof (elf_mmix_howto_table) / sizeof (elf_mmix_howto_table[0]); + i++) + if (elf_mmix_howto_table[i].name != NULL + && strcasecmp (elf_mmix_howto_table[i].name, r_name) == 0) + return &elf_mmix_howto_table[i]; + + return NULL; +} + static bfd_boolean mmix_elf_new_section_hook (abfd, sec) bfd *abfd; @@ -1365,22 +1383,53 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, r_symndx = ELF64_R_SYM (rel->r_info); + howto = elf_mmix_howto_table + ELF64_R_TYPE (rel->r_info); + h = NULL; + sym = NULL; + sec = NULL; + + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections [r_symndx]; + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); + + name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); + if (name == NULL) + name = bfd_section_name (input_bfd, sec); + } + else + { + bfd_boolean unresolved_reloc; + + RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, + r_symndx, symtab_hdr, sym_hashes, + h, sec, relocation, + unresolved_reloc, undefined_signalled); + name = h->root.root.string; + } + + 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) { /* This is a relocatable link. For most relocs 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. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections [r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } + if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + rel->r_addend += sec->output_offset; /* For PUSHJ stub relocs however, we may need to change the reloc and the section contents, if the reloc doesn't reach @@ -1454,35 +1503,6 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, continue; } - /* This is a final link. */ - howto = elf_mmix_howto_table + ELF64_R_TYPE (rel->r_info); - h = NULL; - sym = NULL; - sec = NULL; - - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections [r_symndx]; - relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); - - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - name = bfd_section_name (input_bfd, sec); - } - else - { - bfd_boolean unresolved_reloc; - - RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, - r_symndx, symtab_hdr, sym_hashes, - h, sec, relocation, - unresolved_reloc, undefined_signalled); - name = h->root.root.string; - } - r = mmix_final_link_relocate (howto, input_section, contents, rel->r_offset, rel->r_addend, relocation, name, sec); @@ -1958,15 +1978,12 @@ mmix_elf_check_relocs (abfd, info, sec, relocs) 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; 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; /* First we sort the relocs so that any register relocs come before expansion-relocs to the same insn. FIXME: Not done for mmo. */ @@ -2009,7 +2026,9 @@ mmix_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_MMIX_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; }