X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bfd%2Felf64-mmix.c;h=58fca928209e83817d8635cd865a296829d59778;hb=48e6666a0d550f290ea174682c78b0d62a027076;hp=6f88fe102f5905ac6e8878b65910a165a7b759c6;hpb=01f0fe5e0450edf168c1f612feb93cf588e4e7ea;p=platform%2Fupstream%2Fbinutils.git diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 6f88fe1..58fca92 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1,22 +1,24 @@ /* MMIX-specific support for 64-bit ELF. - Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001-2014 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. */ @@ -26,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" @@ -72,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) \ @@ -156,78 +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 asection * mmix_elf_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); - -static bfd_boolean mmix_elf_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); - -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 @@ -838,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; @@ -855,18 +809,35 @@ 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) { - struct _mmix_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + struct _mmix_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = (struct _mmix_elf_section_data *) bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = (PTR) sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } return _bfd_elf_new_section_hook (abfd, sec); } @@ -920,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; @@ -999,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, @@ -1011,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; @@ -1035,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 @@ -1147,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 @@ -1221,10 +1252,9 @@ 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; @@ -1238,22 +1268,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); @@ -1292,9 +1319,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. */ @@ -1312,23 +1336,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; @@ -1369,22 +1392,47 @@ 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, 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 (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 @@ -1420,7 +1468,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 @@ -1458,38 +1506,9 @@ 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) { @@ -1546,16 +1565,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 @@ -1582,7 +1596,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: @@ -1664,7 +1678,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: @@ -1702,7 +1716,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) { @@ -1740,40 +1756,21 @@ mmix_final_link_relocate (howto, input_section, contents, relocation. */ static asection * -mmix_elf_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +mmix_elf_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_MMIX_GNU_VTINHERIT: - case R_MMIX_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 (sec->owner, sym->st_shndx); + switch (ELF64_R_TYPE (rel->r_info)) + { + case R_MMIX_GNU_VTINHERIT: + case R_MMIX_GNU_VTENTRY: + return NULL; + } - return NULL; + return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); } /* Update relocation info for a GC-excluded section. We could supposedly @@ -1782,11 +1779,10 @@ mmix_elf_gc_mark_hook (sec, info, rel, h, sym) present. Better to waste some memory and (perhaps) a little time. */ static bfd_boolean -mmix_elf_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; +mmix_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec, + const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) { struct bpo_reloc_section_info *bpodata = mmix_elf_section_data (sec)->bpo.reloc; @@ -1807,9 +1803,7 @@ mmix_elf_gc_sweep_hook (abfd, info, sec, relocs) /* 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; @@ -1842,11 +1836,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; @@ -1879,7 +1872,7 @@ mmix_elf_check_common_relocs (abfd, info, sec, relocs) 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) @@ -1975,26 +1968,22 @@ 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. */ @@ -2019,6 +2008,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)) @@ -2033,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; } @@ -2046,9 +2041,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; @@ -2065,7 +2058,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) @@ -2087,13 +2080,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 @@ -2104,7 +2096,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. @@ -2153,10 +2145,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; @@ -2173,15 +2164,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) { @@ -2189,8 +2179,7 @@ mmix_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) (*secp)->flags |= SEC_LINKER_CREATED; } else if ((*namep)[0] == '_' && (*namep)[1] == '_' && (*namep)[2] == '.' - && strncmp (*namep, MMIX_LOC_SECTION_START_SYMBOL_PREFIX, - strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX)) == 0) + && CONST_STRNEQ (*namep, MMIX_LOC_SECTION_START_SYMBOL_PREFIX)) { /* See if we have another one. */ struct bfd_link_hash_entry *h = bfd_link_hash_lookup (info->hash, @@ -2217,10 +2206,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; @@ -2248,9 +2235,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. */ @@ -2297,10 +2282,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; @@ -2325,9 +2309,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; @@ -2339,7 +2322,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 @@ -2404,9 +2387,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; @@ -2477,9 +2459,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; @@ -2563,18 +2543,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; @@ -2587,7 +2566,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; @@ -2610,8 +2588,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; @@ -2623,7 +2599,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) @@ -2827,7 +2803,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); @@ -2926,7 +2902,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 @@ -2941,6 +2917,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