X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf64-mmix.c;h=2038813067041be5f6e0da334710dade234556c8;hb=68c398921742291719d97f803891b5113874a22b;hp=63176eb1ebf0374a7248996b52cc192d420308fa;hpb=07adf1816db141e2cc9c0cd5d9a6aa1a712bc979;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 63176eb1eb..2038813067 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1,23 +1,24 @@ /* MMIX-specific support for 64-bit ELF. - Copyright 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 2001-2016 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 +28,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" @@ -73,6 +74,13 @@ struct _mmix_elf_section_data stubs_size_sum for relocation. */ bfd_size_type stub_offset; } pjs; + + /* Whether there has been a warning that this section could not be + linked due to a specific cause. FIXME: a way to access the + linker info or output section, then stuff the limiter guard + there. */ + bfd_boolean has_warned_bpo; + bfd_boolean has_warned_pushj; }; #define mmix_elf_section_data(sec) \ @@ -157,70 +165,24 @@ struct bpo_greg_section_info struct bpo_reloc_request *reloc_request; }; -static bfd_boolean mmix_elf_link_output_symbol_hook - PARAMS ((struct bfd_link_info *, const char *, Elf_Internal_Sym *, - asection *, struct elf_link_hash_entry *)); - -static bfd_reloc_status_type mmix_elf_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - -static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); - -static void mmix_info_to_howto_rela - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); - -static int mmix_elf_sort_relocs PARAMS ((const PTR, const PTR)); - -static bfd_boolean mmix_elf_new_section_hook - PARAMS ((bfd *, asection *)); - -static bfd_boolean mmix_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); - -static bfd_boolean mmix_elf_check_common_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); - -static bfd_boolean mmix_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); - -static bfd_reloc_status_type mmix_final_link_relocate - PARAMS ((reloc_howto_type *, asection *, bfd_byte *, - bfd_vma, bfd_signed_vma, bfd_vma, const char *, asection *)); - -static bfd_reloc_status_type mmix_elf_perform_relocation - PARAMS ((asection *, reloc_howto_type *, PTR, bfd_vma, bfd_vma)); - -static bfd_boolean mmix_elf_section_from_bfd_section - PARAMS ((bfd *, asection *, int *)); - -static bfd_boolean mmix_elf_add_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *, - const char **, flagword *, asection **, bfd_vma *)); -static bfd_boolean mmix_elf_is_local_label_name - PARAMS ((bfd *, const char *)); +extern bfd_boolean mmix_elf_final_link (bfd *, struct bfd_link_info *); -static int bpo_reloc_request_sort_fn PARAMS ((const PTR, const PTR)); - -static bfd_boolean mmix_elf_relax_section - PARAMS ((bfd *abfd, asection *sec, struct bfd_link_info *link_info, - bfd_boolean *again)); - -extern bfd_boolean mmix_elf_final_link PARAMS ((bfd *, struct bfd_link_info *)); - -extern void mmix_elf_symbol_processing PARAMS ((bfd *, asymbol *)); +extern void mmix_elf_symbol_processing (bfd *, asymbol *); /* Only intended to be called from a debugger. */ extern void mmix_dump_bpo_gregs - PARAMS ((struct bfd_link_info *, bfd_error_handler_type)); + (struct bfd_link_info *, bfd_error_handler_type); static void -mmix_set_relaxable_size - PARAMS ((bfd *, asection *, void *)); +mmix_set_relaxable_size (bfd *, asection *, void *); +static bfd_reloc_status_type +mmix_elf_reloc (bfd *, arelent *, asymbol *, void *, + asection *, bfd *, char **); +static bfd_reloc_status_type +mmix_final_link_relocate (reloc_howto_type *, asection *, bfd_byte *, bfd_vma, + bfd_signed_vma, bfd_vma, const char *, asection *, + char **); /* Watch out: this currently needs to have elements with the same index as @@ -230,11 +192,11 @@ static reloc_howto_type elf_mmix_howto_table[] = /* This reloc does nothing. */ HOWTO (R_MMIX_NONE, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + 3, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ + complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_MMIX_NONE", /* name */ FALSE, /* partial_inplace */ @@ -831,9 +793,8 @@ static const struct mmix_reloc_map mmix_reloc_map[] = }; static reloc_howto_type * -bfd_elf64_bfd_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; @@ -848,10 +809,24 @@ 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; - asection *sec; +mmix_elf_new_section_hook (bfd *abfd, asection *sec) { if (!sec->used_by_bfd) { @@ -916,12 +891,9 @@ mmix_elf_new_section_hook (abfd, sec) R_MMIX_ADDR19 and R_MMIX_ADDR27 are just filled in. */ static bfd_reloc_status_type -mmix_elf_perform_relocation (isec, howto, datap, addr, value) - asection *isec; - reloc_howto_type *howto; - PTR datap; - bfd_vma addr; - bfd_vma value; +mmix_elf_perform_relocation (asection *isec, reloc_howto_type *howto, + void *datap, bfd_vma addr, bfd_vma value, + char **error_message) { bfd *abfd = isec->owner; bfd_reloc_status_type flag = bfd_reloc_ok; @@ -995,6 +967,36 @@ mmix_elf_perform_relocation (isec, howto, datap, addr, value) + mmix_elf_section_data (isec)->pjs.stub_offset); bfd_vma stubaddr; + if (mmix_elf_section_data (isec)->pjs.n_pushj_relocs == 0) + { + /* This shouldn't happen when linking to ELF or mmo, so + this is an attempt to link to "binary", right? We + can't access the output bfd, so we can't verify that + assumption. We only know that the critical + mmix_elf_check_common_relocs has not been called, + which happens when the output format is different + from the input format (and is not mmo). */ + if (! mmix_elf_section_data (isec)->has_warned_pushj) + { + /* For the first such error per input section, produce + a verbose message. */ + *error_message + = _("invalid input relocation when producing" + " non-ELF, non-mmo format output." + "\n Please use the objcopy program to convert from" + " ELF or mmo," + "\n or assemble using" + " \"-no-expand\" (for gcc, \"-Wa,-no-expand\""); + mmix_elf_section_data (isec)->has_warned_pushj = TRUE; + return bfd_reloc_dangerous; + } + + /* For subsequent errors, return this one, which is + rate-limited but looks a little bit different, + hopefully without affecting user-friendliness. */ + return bfd_reloc_overflow; + } + /* The address doesn't fit, so redirect the PUSHJ to the location of the stub. */ r = mmix_elf_perform_relocation (isec, @@ -1007,7 +1009,8 @@ mmix_elf_perform_relocation (isec, howto, datap, addr, value) + size + (mmix_elf_section_data (isec) ->pjs.stub_offset) - - addr); + - addr, + error_message); if (r != bfd_reloc_ok) return r; @@ -1031,7 +1034,8 @@ mmix_elf_perform_relocation (isec, howto, datap, addr, value) [R_MMIX_ADDR27], stubcontents, stubaddr, - value + addr - stubaddr); + value + addr - stubaddr, + error_message); mmix_elf_section_data (isec)->pjs.stub_offset += 4; if (size + mmix_elf_section_data (isec)->pjs.stub_offset @@ -1143,12 +1147,43 @@ mmix_elf_perform_relocation (isec, howto, datap, addr, value) { struct bpo_reloc_section_info *bpodata = mmix_elf_section_data (isec)->bpo.reloc; - asection *bpo_greg_section - = bpodata->bpo_greg_section; - struct bpo_greg_section_info *gregdata - = mmix_elf_section_data (bpo_greg_section)->bpo.greg; - size_t bpo_index - = gregdata->bpo_reloc_indexes[bpodata->bpo_index++]; + asection *bpo_greg_section; + struct bpo_greg_section_info *gregdata; + size_t bpo_index; + + if (bpodata == NULL) + { + /* This shouldn't happen when linking to ELF or mmo, so + this is an attempt to link to "binary", right? We + can't access the output bfd, so we can't verify that + assumption. We only know that the critical + mmix_elf_check_common_relocs has not been called, which + happens when the output format is different from the + input format (and is not mmo). */ + if (! mmix_elf_section_data (isec)->has_warned_bpo) + { + /* For the first such error per input section, produce + a verbose message. */ + *error_message + = _("invalid input relocation when producing" + " non-ELF, non-mmo format output." + "\n Please use the objcopy program to convert from" + " ELF or mmo," + "\n or compile using the gcc-option" + " \"-mno-base-addresses\"."); + mmix_elf_section_data (isec)->has_warned_bpo = TRUE; + return bfd_reloc_dangerous; + } + + /* For subsequent errors, return this one, which is + rate-limited but looks a little bit different, + hopefully without affecting user-friendliness. */ + return bfd_reloc_overflow; + } + + bpo_greg_section = bpodata->bpo_greg_section; + gregdata = mmix_elf_section_data (bpo_greg_section)->bpo.greg; + bpo_index = gregdata->bpo_reloc_indexes[bpodata->bpo_index++]; /* A consistency check: The value we now have in "relocation" must be the same as the value we stored for that relocation. It @@ -1217,15 +1252,18 @@ mmix_elf_perform_relocation (isec, howto, datap, addr, value) /* Set the howto pointer for an MMIX ELF reloc (type RELA). */ static void -mmix_info_to_howto_rela (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +mmix_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type; r_type = ELF64_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_MMIX_max); + if (r_type >= (unsigned int) R_MMIX_max) + { + _bfd_error_handler (_("%B: invalid MMIX reloc number: %d"), abfd, r_type); + r_type = 0; + } cache_ptr->howto = &elf_mmix_howto_table[r_type]; } @@ -1234,22 +1272,19 @@ mmix_info_to_howto_rela (abfd, cache_ptr, dst) the reloc_table. We don't get here for final pure ELF linking. */ static bfd_reloc_status_type -mmix_elf_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +mmix_elf_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message) { bfd_vma relocation; bfd_reloc_status_type r; asection *reloc_target_output_section; bfd_reloc_status_type flag = bfd_reloc_ok; bfd_vma output_base = 0; - bfd_vma addr; r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); @@ -1288,9 +1323,6 @@ mmix_elf_reloc (abfd, reloc_entry, symbol, data, input_section, relocation += output_base + symbol->section->output_offset; - /* Get position of relocation. */ - addr = (reloc_entry->address + input_section->output_section->vma - + input_section->output_offset); if (output_bfd != (bfd *) NULL) { /* Add in supplied addend. */ @@ -1308,23 +1340,22 @@ mmix_elf_reloc (abfd, reloc_entry, symbol, data, input_section, data, reloc_entry->address, reloc_entry->addend, relocation, bfd_asymbol_name (symbol), - reloc_target_output_section); + reloc_target_output_section, + error_message); } /* Relocate an MMIX ELF section. Modified from elf32-fr30.c; look to it for guidance if you're thinking of copying this. */ static bfd_boolean -mmix_elf_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; +mmix_elf_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; @@ -1365,22 +1396,47 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, r_symndx = ELF64_R_SYM (rel->r_info); - if (info->relocatable) + 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, ignored; + + RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, + r_symndx, symtab_hdr, sym_hashes, + h, sec, relocation, + unresolved_reloc, undefined_signalled, + ignored); + name = h->root.root.string; + } + + if (sec != NULL && discarded_section (sec)) + RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, + rel, 1, relend, howto, 0, contents); + + if (bfd_link_relocatable (info)) { /* 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 @@ -1416,7 +1472,7 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, + size + mmix_elf_section_data (input_section) ->pjs.stub_offset, - NULL, NULL) != bfd_reloc_ok) + NULL, NULL, NULL) != bfd_reloc_ok) return FALSE; /* Put a JMP insn at the stub; it goes with the @@ -1454,48 +1510,18 @@ 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); + rel->r_addend, relocation, name, sec, NULL); if (r != bfd_reloc_ok) { - bfd_boolean check_ok = TRUE; const char * msg = (const char *) NULL; switch (r) { case bfd_reloc_overflow: - check_ok = info->callbacks->reloc_overflow + info->callbacks->reloc_overflow (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_offset); break; @@ -1503,9 +1529,8 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, case bfd_reloc_undefined: /* We may have sent this message above. */ if (! undefined_signalled) - check_ok = info->callbacks->undefined_symbol - (info, name, input_bfd, input_section, rel->r_offset, - TRUE); + info->callbacks->undefined_symbol + (info, name, input_bfd, input_section, rel->r_offset, TRUE); undefined_signalled = TRUE; break; @@ -1527,11 +1552,8 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, } if (msg) - check_ok = info->callbacks->warning - (info, msg, name, input_bfd, input_section, rel->r_offset); - - if (! check_ok) - return FALSE; + (*info->callbacks->warning) (info, msg, name, input_bfd, + input_section, rel->r_offset); } } @@ -1542,16 +1564,11 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, routines. A few relocs we have to do ourselves. */ static bfd_reloc_status_type -mmix_final_link_relocate (howto, input_section, contents, - r_offset, r_addend, relocation, symname, symsec) - reloc_howto_type *howto; - asection *input_section; - bfd_byte *contents; - bfd_vma r_offset; - bfd_signed_vma r_addend; - bfd_vma relocation; - const char *symname; - asection *symsec; +mmix_final_link_relocate (reloc_howto_type *howto, asection *input_section, + bfd_byte *contents, bfd_vma r_offset, + bfd_signed_vma r_addend, bfd_vma relocation, + const char *symname, asection *symsec, + char **error_message) { bfd_reloc_status_type r = bfd_reloc_ok; bfd_vma addr @@ -1578,7 +1595,7 @@ mmix_final_link_relocate (howto, input_section, contents, + r_offset); r = mmix_elf_perform_relocation (input_section, howto, contents, - addr, srel); + addr, srel, error_message); break; case R_MMIX_BASE_PLUS_OFFSET: @@ -1660,7 +1677,7 @@ mmix_final_link_relocate (howto, input_section, contents, do_mmix_reloc: contents += r_offset; r = mmix_elf_perform_relocation (input_section, howto, contents, - addr, srel); + addr, srel, error_message); break; case R_MMIX_LOCAL: @@ -1698,7 +1715,9 @@ mmix_final_link_relocate (howto, input_section, contents, first_global = 255; else { - first_global = bfd_get_section_vma (abfd, regsec) / 8; + first_global + = bfd_get_section_vma (input_section->output_section->owner, + regsec) / 8; if (strcmp (bfd_get_section_name (symsec->owner, symsec), MMIX_REG_CONTENTS_SECTION_NAME) == 0) { @@ -1783,9 +1802,7 @@ mmix_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, /* Sort register relocs to come before expanding relocs. */ static int -mmix_elf_sort_relocs (p1, p2) - const PTR p1; - const PTR p2; +mmix_elf_sort_relocs (const void * p1, const void * p2) { const Elf_Internal_Rela *r1 = (const Elf_Internal_Rela *) p1; const Elf_Internal_Rela *r2 = (const Elf_Internal_Rela *) p2; @@ -1818,11 +1835,10 @@ mmix_elf_sort_relocs (p1, p2) /* Subset of mmix_elf_check_relocs, common to ELF and mmo linking. */ static bfd_boolean -mmix_elf_check_common_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +mmix_elf_check_common_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { bfd *bpo_greg_owner = NULL; asection *allocated_gregs_section = NULL; @@ -1849,13 +1865,13 @@ mmix_elf_check_common_relocs (abfd, info, sec, relocs) DSO-related stuff if that member is non-NULL. */ case R_MMIX_BASE_PLUS_OFFSET: /* We don't do anything with this reloc for a relocatable link. */ - if (info->relocatable) + if (bfd_link_relocatable (info)) break; if (bpo_greg_owner == NULL) { bpo_greg_owner = abfd; - info->base_file = (PTR) bpo_greg_owner; + info->base_file = bpo_greg_owner; } if (allocated_gregs_section == NULL) @@ -1951,33 +1967,29 @@ mmix_elf_check_common_relocs (abfd, info, sec, relocs) /* Look through the relocs for a section during the first phase. */ static bfd_boolean -mmix_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +mmix_elf_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; 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. */ - qsort ((PTR) relocs, sec->reloc_count, sizeof (Elf_Internal_Rela), + qsort ((void *) relocs, sec->reloc_count, sizeof (Elf_Internal_Rela), mmix_elf_sort_relocs); /* Do the common part. */ if (!mmix_elf_check_common_relocs (abfd, info, sec, relocs)) return FALSE; - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; rel_end = relocs + sec->reloc_count; @@ -1995,6 +2007,10 @@ mmix_elf_check_relocs (abfd, info, sec, relocs) 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; + + /* PR15323, ref flags aren't set for references in the same + object. */ + h->root.non_ir_ref = 1; } switch (ELF64_R_TYPE (rel->r_info)) @@ -2009,7 +2025,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; } @@ -2022,9 +2040,7 @@ mmix_elf_check_relocs (abfd, info, sec, relocs) Copied from elf_link_add_object_symbols. */ bfd_boolean -_bfd_mmix_check_all_relocs (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +_bfd_mmix_check_all_relocs (bfd *abfd, struct bfd_link_info *info) { asection *o; @@ -2041,7 +2057,7 @@ _bfd_mmix_check_all_relocs (abfd, info) continue; internal_relocs - = _bfd_elf_link_read_relocs (abfd, o, (PTR) NULL, + = _bfd_elf_link_read_relocs (abfd, o, NULL, (Elf_Internal_Rela *) NULL, info->keep_memory); if (internal_relocs == NULL) @@ -2063,13 +2079,12 @@ _bfd_mmix_check_all_relocs (abfd, info) the register section, and scale them down to correspond to the register number. */ -static bfd_boolean -mmix_elf_link_output_symbol_hook (info, name, sym, input_sec, h) - struct bfd_link_info *info ATTRIBUTE_UNUSED; - const char *name ATTRIBUTE_UNUSED; - Elf_Internal_Sym *sym; - asection *input_sec; - struct elf_link_hash_entry *h ATTRIBUTE_UNUSED; +static int +mmix_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED, + Elf_Internal_Sym *sym, + asection *input_sec, + struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) { if (input_sec != NULL && input_sec->name != NULL @@ -2080,7 +2095,7 @@ mmix_elf_link_output_symbol_hook (info, name, sym, input_sec, h) sym->st_shndx = SHN_REGISTER; } - return TRUE; + return 1; } /* We fake a register section that holds values that are register numbers. @@ -2094,9 +2109,7 @@ static asymbol *mmix_elf_reg_section_symbol_ptr; /* Handle the special section numbers that a symbol may use. */ void -mmix_elf_symbol_processing (abfd, asym) - bfd *abfd ATTRIBUTE_UNUSED; - asymbol *asym; +mmix_elf_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym) { elf_symbol_type *elfsym; @@ -2129,10 +2142,9 @@ mmix_elf_symbol_processing (abfd, asym) index. */ static bfd_boolean -mmix_elf_section_from_bfd_section (abfd, sec, retval) - bfd * abfd ATTRIBUTE_UNUSED; - asection * sec; - int * retval; +mmix_elf_section_from_bfd_section (bfd * abfd ATTRIBUTE_UNUSED, + asection * sec, + int * retval) { if (strcmp (bfd_get_section_name (abfd, sec), MMIX_REG_SECTION_NAME) == 0) *retval = SHN_REGISTER; @@ -2149,15 +2161,14 @@ mmix_elf_section_from_bfd_section (abfd, sec, retval) symbols, since otherwise having two with the same value would cause them to be "merged", but with the contents serialized. */ -bfd_boolean -mmix_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Sym *sym; - const char **namep ATTRIBUTE_UNUSED; - flagword *flagsp ATTRIBUTE_UNUSED; - asection **secp; - bfd_vma *valp ATTRIBUTE_UNUSED; +static bfd_boolean +mmix_elf_add_symbol_hook (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Sym *sym, + const char **namep ATTRIBUTE_UNUSED, + flagword *flagsp ATTRIBUTE_UNUSED, + asection **secp, + bfd_vma *valp ATTRIBUTE_UNUSED) { if (sym->st_shndx == SHN_REGISTER) { @@ -2192,10 +2203,8 @@ mmix_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) /* We consider symbols matching "L.*:[0-9]+" to be local symbols. */ -bfd_boolean -mmix_elf_is_local_label_name (abfd, name) - bfd *abfd; - const char *name; +static bfd_boolean +mmix_elf_is_local_label_name (bfd *abfd, const char *name) { const char *colpos; int digits; @@ -2223,9 +2232,7 @@ mmix_elf_is_local_label_name (abfd, name) /* We get rid of the register section here. */ bfd_boolean -mmix_elf_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +mmix_elf_final_link (bfd *abfd, struct bfd_link_info *info) { /* We never output a register section, though we create one for temporary measures. Check that nobody entered contents into it. */ @@ -2272,10 +2279,9 @@ mmix_elf_final_link (abfd, info) section size. This is expected to shrink during linker relaxation. */ static void -mmix_set_relaxable_size (abfd, sec, ptr) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - void *ptr; +mmix_set_relaxable_size (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + void *ptr) { struct bfd_link_info *info = ptr; @@ -2290,7 +2296,7 @@ mmix_set_relaxable_size (abfd, sec, ptr) /* For use in relocatable link, we start with a max stubs size. See mmix_elf_relax_section. */ - if (info->relocatable && sec->output_section) + if (bfd_link_relocatable (info) && sec->output_section) mmix_elf_section_data (sec->output_section)->pjs.stubs_size_sum += (mmix_elf_section_data (sec)->pjs.n_pushj_relocs * MAX_PUSHJ_STUB_SIZE); @@ -2300,9 +2306,8 @@ mmix_set_relaxable_size (abfd, sec, ptr) R_MMIX_BASE_PLUS_OFFSET relocs seen by the linker. */ bfd_boolean -_bfd_mmix_before_linker_allocation (abfd, info) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; +_bfd_mmix_before_linker_allocation (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) { asection *bpo_gregs_section; bfd *bpo_greg_owner; @@ -2314,7 +2319,7 @@ _bfd_mmix_before_linker_allocation (abfd, info) bfd *ibfd; /* Set the initial size of sections. */ - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) bfd_map_over_sections (ibfd, mmix_set_relaxable_size, info); /* The bpo_greg_owner bfd is supposed to have been set by @@ -2379,9 +2384,8 @@ _bfd_mmix_before_linker_allocation (abfd, info) calculated at this point; we just move the contents into place here. */ bfd_boolean -_bfd_mmix_after_linker_allocation (abfd, link_info) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *link_info; +_bfd_mmix_after_linker_allocation (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *link_info) { asection *bpo_gregs_section; bfd *bpo_greg_owner; @@ -2452,9 +2456,7 @@ _bfd_mmix_after_linker_allocation (abfd, link_info) value. */ static int -bpo_reloc_request_sort_fn (p1, p2) - const PTR p1; - const PTR p2; +bpo_reloc_request_sort_fn (const void * p1, const void * p2) { const struct bpo_reloc_request *r1 = (const struct bpo_reloc_request *) p1; const struct bpo_reloc_request *r2 = (const struct bpo_reloc_request *) p2; @@ -2482,9 +2484,8 @@ bpo_reloc_request_sort_fn (p1, p2) from base-plus-offset relocs. */ void -mmix_dump_bpo_gregs (link_info, pf) - struct bfd_link_info *link_info; - bfd_error_handler_type pf; +mmix_dump_bpo_gregs (struct bfd_link_info *link_info, + bfd_error_handler_type pf) { bfd *bpo_greg_owner; asection *bpo_gregs_section; @@ -2538,18 +2539,17 @@ mmix_dump_bpo_gregs (link_info, pf) when the last such reloc is done, an index-array is sorted according to the values and iterated over to produce register numbers (indexed by 0 from the first allocated register number) and offsets for use in real - relocation. + relocation. (N.B.: Relocatable runs are handled, not just punted.) PUSHJ stub accounting is also done here. Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */ static bfd_boolean -mmix_elf_relax_section (abfd, sec, link_info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - bfd_boolean *again; +mmix_elf_relax_section (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + bfd_boolean *again) { Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Rela *internal_relocs; @@ -2562,7 +2562,6 @@ mmix_elf_relax_section (abfd, sec, link_info, again) spot a missing actual initialization. */ size_t bpono = (size_t) -1; size_t pjsno = 0; - bfd *bpo_greg_owner; Elf_Internal_Sym *isymbuf = NULL; bfd_size_type size = sec->rawsize ? sec->rawsize : sec->size; @@ -2585,8 +2584,6 @@ mmix_elf_relax_section (abfd, sec, link_info, again) symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - bpo_greg_owner = (bfd *) link_info->base_file; - if (bpodata != NULL) { bpo_gregs_section = bpodata->bpo_greg_section; @@ -2598,7 +2595,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again) /* Get a copy of the native relocations. */ internal_relocs - = _bfd_elf_link_read_relocs (abfd, sec, (PTR) NULL, + = _bfd_elf_link_read_relocs (abfd, sec, NULL, (Elf_Internal_Rela *) NULL, link_info->keep_memory); if (internal_relocs == NULL) @@ -2619,7 +2616,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again) /* We process relocs in a distinctly different way when this is a relocatable link (for one, we don't look at symbols), so we avoid mixing its code with that for the "normal" relaxation. */ - if (link_info->relocatable) + if (bfd_link_relocatable (link_info)) { /* The only transformation in a relocatable link is to generate a full stub at the location of the stub calculated for the @@ -2802,7 +2799,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again) gregdata->n_remaining_bpo_relocs_this_relaxation_round = gregdata->n_bpo_relocs; - qsort ((PTR) gregdata->reloc_request, + qsort (gregdata->reloc_request, gregdata->n_max_bpo_relocs, sizeof (struct bpo_reloc_request), bpo_reloc_request_sort_fn); @@ -2901,7 +2898,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again) alignment. */ #define ELF_MAXPAGESIZE 0x100 -#define TARGET_BIG_SYM bfd_elf64_mmix_vec +#define TARGET_BIG_SYM mmix_elf64_vec #define TARGET_BIG_NAME "elf64-mmix" #define elf_info_to_howto_rel NULL @@ -2916,6 +2913,8 @@ mmix_elf_relax_section (abfd, sec, link_info, again) #define elf_backend_check_relocs mmix_elf_check_relocs #define elf_backend_symbol_processing mmix_elf_symbol_processing +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define bfd_elf64_bfd_is_local_label_name \ mmix_elf_is_local_label_name