X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf32-m68hc1x.c;h=2660c890cb80d4b88b444ad20300d7f0e7ea46c6;hb=c1031b409f133f4cd32a432113bc1f6379a3e279;hp=b31fc7b454b6cae20a7bfe9b8d5ce6af06030283;hpb=9c5bfbb7fd76589a332126f99a4e195e46da207f;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index b31fc7b454..2660c890cb 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -1,25 +1,27 @@ /* Motorola 68HC11/HC12-specific support for 32-bit ELF - Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. Contributed by Stephane Carrez (stcarrez@nerim.fr) -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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "bfdlink.h" #include "libbfd.h" #include "elf-bfd.h" @@ -33,31 +35,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ bfd_hash_lookup ((table), (string), (create), (copy))) static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub - PARAMS((const char *stub_name, - asection *section, - struct m68hc11_elf_link_hash_table *htab)); + (const char *stub_name, + asection *section, + struct m68hc11_elf_link_hash_table *htab); static struct bfd_hash_entry *stub_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); -static void m68hc11_elf_set_symbol - PARAMS ((bfd* abfd, struct bfd_link_info *info, - const char* name, bfd_vma value, asection* sec)); +static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info, + const char* name, bfd_vma value, + asection* sec); static bfd_boolean m68hc11_elf_export_one_stub - PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg)); + (struct bfd_hash_entry *gen_entry, void *in_arg); -static bfd_boolean m68hc11_get_relocation_value - PARAMS ((bfd* abfd, - struct bfd_link_info* info, - asection **local_sections, - Elf_Internal_Sym* local_syms, - Elf_Internal_Rela* rel, - const char** name, - bfd_vma* relocation, - bfd_boolean* is_far)); - -static void scan_sections_for_abi PARAMS ((bfd*, asection*, PTR)); +static void scan_sections_for_abi (bfd*, asection*, PTR); struct m68hc11_scan_param { @@ -69,8 +61,7 @@ struct m68hc11_scan_param /* Create a 68HC11/68HC12 ELF linker hash table. */ struct m68hc11_elf_link_hash_table* -m68hc11_elf_hash_table_create (abfd) - bfd *abfd; +m68hc11_elf_hash_table_create (bfd *abfd) { struct m68hc11_elf_link_hash_table *ret; bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table); @@ -80,8 +71,9 @@ m68hc11_elf_hash_table_create (abfd) return NULL; memset (ret, 0, amt); - if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, - _bfd_elf_link_hash_newfunc)) + if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, + _bfd_elf_link_hash_newfunc, + sizeof (struct elf_link_hash_entry))) { free (ret); return NULL; @@ -95,7 +87,8 @@ m68hc11_elf_hash_table_create (abfd) free (ret); return NULL; } - if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc)) + if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc, + sizeof (struct elf32_m68hc11_stub_hash_entry))) return NULL; ret->stub_bfd = NULL; @@ -109,8 +102,7 @@ m68hc11_elf_hash_table_create (abfd) /* Free the derived linker hash table. */ void -m68hc11_elf_bfd_link_hash_table_free (hash) - struct bfd_link_hash_table *hash; +m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash) { struct m68hc11_elf_link_hash_table *ret = (struct m68hc11_elf_link_hash_table *) hash; @@ -125,10 +117,8 @@ m68hc11_elf_bfd_link_hash_table_free (hash) /* Initialize an entry in the stub hash table. */ static struct bfd_hash_entry * -stub_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; +stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, + const char *string) { /* Allocate the structure if it has not already been allocated by a subclass. */ @@ -161,10 +151,8 @@ stub_hash_newfunc (entry, table, string) stub entry are initialised. */ static struct elf32_m68hc11_stub_hash_entry * -m68hc12_add_stub (stub_name, section, htab) - const char *stub_name; - asection *section; - struct m68hc11_elf_link_hash_table *htab; +m68hc12_add_stub (const char *stub_name, asection *section, + struct m68hc11_elf_link_hash_table *htab) { struct elf32_m68hc11_stub_hash_entry *stub_entry; @@ -173,9 +161,8 @@ m68hc12_add_stub (stub_name, section, htab) TRUE, FALSE); if (stub_entry == NULL) { - (*_bfd_error_handler) (_("%s: cannot create stub entry %s"), - bfd_archive_filename (section->owner), - stub_name); + (*_bfd_error_handler) (_("%B: cannot create stub entry %s"), + section->owner, stub_name); return NULL; } @@ -195,14 +182,12 @@ m68hc12_add_stub (stub_name, section, htab) the trampoline handler. */ bfd_boolean -elf32_m68hc11_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 ATTRIBUTE_UNUSED; - flagword *flagsp ATTRIBUTE_UNUSED; - asection **secp ATTRIBUTE_UNUSED; - bfd_vma *valp ATTRIBUTE_UNUSED; +elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, + Elf_Internal_Sym *sym, + const char **namep ATTRIBUTE_UNUSED, + flagword *flagsp ATTRIBUTE_UNUSED, + asection **secp ATTRIBUTE_UNUSED, + bfd_vma *valp ATTRIBUTE_UNUSED) { if (sym->st_other & STO_M68HC12_FAR) { @@ -234,9 +219,7 @@ elf32_m68hc11_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) 0 when no stubs will be needed, and 1 on success. */ int -elf32_m68hc11_setup_section_lists (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; +elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) { bfd *input_bfd; unsigned int bfd_count; @@ -249,7 +232,7 @@ elf32_m68hc11_setup_section_lists (output_bfd, info) htab = m68hc11_elf_hash_table (info); - if (htab->root.root.creator->flavour != bfd_target_elf_flavour) + if (bfd_get_flavour (info->output_bfd) != bfd_target_elf_flavour) return 0; /* Count the number of input BFDs and find the top input section id. @@ -285,7 +268,7 @@ elf32_m68hc11_setup_section_lists (output_bfd, info) /* We can't use output_bfd->section_count here to find the top output section index as some sections may have been removed, and - _bfd_strip_section_from_output doesn't renumber the indices. */ + strip_excluded_output_sections doesn't renumber the indices. */ for (section = output_bfd->sections, top_index = 0; section != NULL; section = section->next) @@ -326,11 +309,9 @@ elf32_m68hc11_setup_section_lists (output_bfd, info) instruction. */ bfd_boolean -elf32_m68hc11_size_stubs (output_bfd, stub_bfd, info, add_stub_section) - bfd *output_bfd; - bfd *stub_bfd; - struct bfd_link_info *info; - asection * (*add_stub_section) PARAMS ((const char *, asection *)); +elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd, + struct bfd_link_info *info, + asection * (*add_stub_section) (const char*, asection*)) { bfd *input_bfd; asection *section; @@ -367,76 +348,29 @@ elf32_m68hc11_size_stubs (output_bfd, stub_bfd, info, add_stub_section) input_bfd = input_bfd->link_next, bfd_indx++) { Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *shndx_hdr; - Elf_Internal_Sym *isym; - Elf32_External_Sym *extsyms, *esym, *end_sy; - Elf_External_Sym_Shndx *shndx_buf, *shndx; - bfd_size_type sec_size; /* We'll need the symbol table in a second. */ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; if (symtab_hdr->sh_info == 0) continue; - /* We need an array of the local symbols attached to the input bfd. - Unfortunately, we're going to have to read & swap them in. */ - sec_size = symtab_hdr->sh_info; - sec_size *= sizeof (Elf_Internal_Sym); - local_syms = (Elf_Internal_Sym *) bfd_malloc (sec_size); + /* We need an array of the local symbols attached to the input bfd. */ + local_syms = (Elf_Internal_Sym *) symtab_hdr->contents; + if (local_syms == NULL) + { + local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, + NULL, NULL, NULL); + /* Cache them for elf_link_input_bfd. */ + symtab_hdr->contents = (unsigned char *) local_syms; + } if (local_syms == NULL) - goto error_ret_free_local; - - all_local_syms[bfd_indx] = local_syms; - sec_size = symtab_hdr->sh_info; - sec_size *= sizeof (Elf32_External_Sym); - - /* Get the cached copy. */ - if (symtab_hdr->contents != NULL) - extsyms = (Elf32_External_Sym *) symtab_hdr->contents; - else - { - /* Go get them off disk. */ - bfd_size_type amt = symtab_hdr->sh_size; - extsyms = (Elf32_External_Sym *) bfd_malloc (amt); - if (extsyms == NULL) - goto error_ret_free_local; - - if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread ((PTR) extsyms, amt, input_bfd) != amt) - { - error_ret_free_ext_syms: - free (extsyms); - goto error_ret_free_local; - } - } - shndx_buf = NULL; - shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr; - if (shndx_hdr->sh_size != 0) { - bfd_size_type amt; - - amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx); - shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt); - if (shndx_buf == NULL) - goto error_ret_free_ext_syms; - if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt) - { - free (shndx_buf); - goto error_ret_free_ext_syms; - } - shndx_hdr->contents = (PTR) shndx_buf; + free (all_local_syms); + return FALSE; } - /* Swap the local symbols in. */ - for (esym = extsyms, end_sy = esym + symtab_hdr->sh_info, - isym = local_syms, shndx = shndx_buf; - esym < end_sy; - esym++, isym++, shndx = (shndx ? shndx + 1 : NULL)) - bfd_elf32_swap_symbol_in (input_bfd, esym, shndx, isym); - - /* Now we can free the external symbols. */ - free (shndx_buf); + all_local_syms[bfd_indx] = local_syms; } for (input_bfd = info->input_bfds, bfd_indx = 0; @@ -516,8 +450,13 @@ elf32_m68hc11_size_stubs (output_bfd, stub_bfd, info, add_stub_section) if (!is_far) continue; - hdr = elf_elfsections (input_bfd)[sym->st_shndx]; - sym_sec = hdr->bfd_section; + if (sym->st_shndx >= elf_numsections (input_bfd)) + sym_sec = NULL; + else + { + hdr = elf_elfsections (input_bfd)[sym->st_shndx]; + sym_sec = hdr->bfd_section; + } stub_name = (bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name)); @@ -539,7 +478,8 @@ elf32_m68hc11_size_stubs (output_bfd, stub_bfd, info, add_stub_section) hash->root.u.i.link); if (hash->root.type == bfd_link_hash_defined - || hash->root.type == bfd_link_hash_defweak) + || hash->root.type == bfd_link_hash_defweak + || hash->root.type == bfd_link_hash_new) { if (!(hash->other & STO_M68HC12_FAR)) continue; @@ -602,25 +542,22 @@ elf32_m68hc11_size_stubs (output_bfd, stub_bfd, info, add_stub_section) stub_sec != NULL; stub_sec = stub_sec->next) { - stub_sec->_raw_size = 0; - stub_sec->_cooked_size = 0; + stub_sec->size = 0; } bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab); } - free (htab->all_local_syms); + free (all_local_syms); return TRUE; error_ret_free_local: - free (htab->all_local_syms); + free (all_local_syms); return FALSE; } /* Export the trampoline addresses in the symbol table. */ static bfd_boolean -m68hc11_elf_export_one_stub (gen_entry, in_arg) - struct bfd_hash_entry *gen_entry; - PTR in_arg; +m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) { struct bfd_link_info *info; struct m68hc11_elf_link_hash_table *htab; @@ -650,12 +587,8 @@ m68hc11_elf_export_one_stub (gen_entry, in_arg) /* Export a symbol or set its value and section. */ static void -m68hc11_elf_set_symbol (abfd, info, name, value, sec) - bfd* abfd; - struct bfd_link_info *info; - const char* name; - bfd_vma value; - asection* sec; +m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info, + const char *name, bfd_vma value, asection *sec) { struct elf_link_hash_entry *h; @@ -686,9 +619,7 @@ m68hc11_elf_set_symbol (abfd, info, name, value, sec) linker. */ bfd_boolean -elf32_m68hc11_build_stubs (abfd, info) - bfd* abfd; - struct bfd_link_info *info; +elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info) { asection *stub_sec; struct bfd_hash_table *table; @@ -705,11 +636,11 @@ elf32_m68hc11_build_stubs (abfd, info) bfd_size_type size; /* Allocate memory to hold the linker stubs. */ - size = stub_sec->_raw_size; + size = stub_sec->size; stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size); if (stub_sec->contents == NULL && size != 0) return FALSE; - stub_sec->_raw_size = 0; + stub_sec->size = 0; } /* Build the stubs as directed by the stub hash table. */ @@ -741,8 +672,7 @@ elf32_m68hc11_build_stubs (abfd, info) } void -m68hc11_elf_get_bank_parameters (info) - struct bfd_link_info *info; +m68hc11_elf_get_bank_parameters (struct bfd_link_info *info) { unsigned i; struct m68hc11_page_info *pinfo; @@ -802,9 +732,7 @@ m68hc11_elf_get_bank_parameters (info) /* Return 1 if the address is in banked memory. This can be applied to a virtual address and to a physical address. */ int -m68hc11_addr_is_banked (pinfo, addr) - struct m68hc11_page_info *pinfo; - bfd_vma addr; +m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr) { if (addr >= pinfo->bank_virtual) return 1; @@ -818,9 +746,7 @@ m68hc11_addr_is_banked (pinfo, addr) /* Return the physical address seen by the processor, taking into account banked memory. */ bfd_vma -m68hc11_phys_addr (pinfo, addr) - struct m68hc11_page_info *pinfo; - bfd_vma addr; +m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr) { if (addr < pinfo->bank_virtual) return addr; @@ -834,9 +760,7 @@ m68hc11_phys_addr (pinfo, addr) /* Return the page number corresponding to an address in banked memory. */ bfd_vma -m68hc11_phys_page (pinfo, addr) - struct m68hc11_page_info *pinfo; - bfd_vma addr; +m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr) { if (addr < pinfo->bank_virtual) return 0; @@ -852,15 +776,13 @@ m68hc11_phys_page (pinfo, addr) which the linker should otherwise ignore. */ bfd_reloc_status_type -m68hc11_elf_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; +m68hc11_elf_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; @@ -868,15 +790,13 @@ m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section, } bfd_reloc_status_type -m68hc11_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +m68hc11_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol, + void *data ATTRIBUTE_UNUSED, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { if (output_bfd != (bfd *) NULL && (symbol->flags & BSF_SECTION_SYM) == 0 @@ -890,70 +810,22 @@ m68hc11_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section, if (output_bfd != NULL) return bfd_reloc_continue; - if (reloc_entry->address > input_section->_cooked_size) + if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) return bfd_reloc_outofrange; abort(); } -asection * -elf32_m68hc11_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; -{ - if (h != NULL) - { - switch (ELF32_R_TYPE (rel->r_info)) - { - 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); - - return NULL; -} - -bfd_boolean -elf32_m68hc11_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; -{ - /* We don't use got and plt entries for 68hc11/68hc12. */ - return TRUE; -} - /* 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. */ bfd_boolean -elf32_m68hc11_check_relocs (abfd, info, sec, relocs) - bfd * abfd; - struct bfd_link_info * info; - asection * sec; - const Elf_Internal_Rela * relocs; +elf32_m68hc11_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; - struct elf_link_hash_entry ** sym_hashes_end; const Elf_Internal_Rela * rel; const Elf_Internal_Rela * rel_end; @@ -962,10 +834,6 @@ elf32_m68hc11_check_relocs (abfd, info, sec, relocs) symtab_hdr = & elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); - sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym); - if (!elf_bad_symtab (abfd)) - sym_hashes_end -= symtab_hdr->sh_info; - rel_end = relocs + sec->reloc_count; for (rel = relocs; rel < rel_end; rel++) @@ -978,21 +846,28 @@ elf32_m68hc11_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; + } switch (ELF32_R_TYPE (rel->r_info)) { /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_M68HC11_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + 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_M68HC11_GNU_VTENTRY: - if (!_bfd_elf32_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; } @@ -1001,123 +876,19 @@ elf32_m68hc11_check_relocs (abfd, info, sec, relocs) return TRUE; } -static bfd_boolean -m68hc11_get_relocation_value (abfd, info, local_sections, local_syms, - rel, name, - relocation, is_far) - bfd *abfd; - struct bfd_link_info *info; - asection **local_sections; - Elf_Internal_Sym* local_syms; - Elf_Internal_Rela* rel; - const char** name; - bfd_vma* relocation; - bfd_boolean* is_far; -{ - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - unsigned long r_symndx; - asection *sec; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - const char* stub_name = 0; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - - r_symndx = ELF32_R_SYM (rel->r_info); - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - *relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - *is_far = (sym && (sym->st_other & STO_M68HC12_FAR)); - if (*is_far) - stub_name = (bfd_elf_string_from_elf_section - (abfd, symtab_hdr->sh_link, - sym->st_name)); - } - else - { - 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; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - *relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - *relocation = 0; - else - { - if (!((*info->callbacks->undefined_symbol) - (info, h->root.root.string, abfd, - sec, rel->r_offset, TRUE))) - return FALSE; - *relocation = 0; - } - *is_far = (h && (h->other & STO_M68HC12_FAR)); - stub_name = h->root.root.string; - } - - if (h != NULL) - *name = h->root.root.string; - else - { - *name = (bfd_elf_string_from_elf_section - (abfd, symtab_hdr->sh_link, sym->st_name)); - if (*name == NULL || **name == '\0') - *name = bfd_section_name (input_bfd, sec); - } - - if (*is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16) - { - struct elf32_m68hc11_stub_hash_entry* stub; - struct m68hc11_elf_link_hash_table *htab; - - htab = m68hc11_elf_hash_table (info); - stub = m68hc12_stub_hash_lookup (htab->stub_hash_table, - *name, FALSE, FALSE); - if (stub) - { - *relocation = stub->stub_offset - + stub->stub_sec->output_section->vma - + stub->stub_sec->output_offset; - *is_far = FALSE; - } - } - return TRUE; -} - /* Relocate a 68hc11/68hc12 ELF section. */ bfd_boolean -elf32_m68hc11_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; +elf32_m68hc11_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; Elf_Internal_Rela *rel, *relend; - const char *name; + const char *name = NULL; struct m68hc11_page_info *pinfo; const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd); @@ -1138,13 +909,15 @@ elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section, unsigned long r_symndx; Elf_Internal_Sym *sym; asection *sec; - bfd_vma relocation; + bfd_vma relocation = 0; bfd_reloc_status_type r = bfd_reloc_undefined; bfd_vma phys_page; bfd_vma phys_addr; bfd_vma insn_addr; bfd_vma insn_page; - bfd_boolean is_far; + bfd_boolean is_far = FALSE; + struct elf_link_hash_entry *h; + const char* stub_name = 0; r_symndx = ELF32_R_SYM (rel->r_info); r_type = ELF32_R_TYPE (rel->r_info); @@ -1153,30 +926,86 @@ elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section, || r_type == R_M68HC11_GNU_VTINHERIT ) continue; + (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel); + howto = arel.howto; + + h = NULL; + sym = NULL; + sec = NULL; + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = (sec->output_section->vma + + sec->output_offset + + sym->st_value); + is_far = (sym && (sym->st_other & STO_M68HC12_FAR)); + if (is_far) + stub_name = (bfd_elf_string_from_elf_section + (input_bfd, symtab_hdr->sh_link, + sym->st_name)); + } + else + { + bfd_boolean unresolved_reloc, warned; + + RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, + r_symndx, symtab_hdr, sym_hashes, + h, sec, relocation, unresolved_reloc, + warned); + + is_far = (h && (h->other & STO_M68HC12_FAR)); + stub_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. 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; continue; } - (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel); - howto = arel.howto; - m68hc11_get_relocation_value (input_bfd, info, - local_sections, local_syms, - rel, &name, &relocation, &is_far); + if (h != NULL) + name = h->root.root.string; + else + { + name = (bfd_elf_string_from_elf_section + (input_bfd, symtab_hdr->sh_link, sym->st_name)); + if (name == NULL || *name == '\0') + name = bfd_section_name (input_bfd, sec); + } + + if (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16) + { + struct elf32_m68hc11_stub_hash_entry* stub; + struct m68hc11_elf_link_hash_table *htab; + + htab = m68hc11_elf_hash_table (info); + stub = m68hc12_stub_hash_lookup (htab->stub_hash_table, + name, FALSE, FALSE); + if (stub) + { + relocation = stub->stub_offset + + stub->stub_sec->output_section->vma + + stub->stub_sec->output_offset; + is_far = FALSE; + } + } /* Do the memory bank mapping. */ phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend); @@ -1290,7 +1119,7 @@ elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section, { case bfd_reloc_overflow: if (!((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, + (info, NULL, name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_offset))) return FALSE; break; @@ -1336,9 +1165,7 @@ elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section, /* Set and control ELF flags in ELF header. */ bfd_boolean -_bfd_m68hc11_elf_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; +_bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags) { BFD_ASSERT (!elf_flags_init (abfd) || elf_elfheader (abfd)->e_flags == flags); @@ -1352,9 +1179,7 @@ _bfd_m68hc11_elf_set_private_flags (abfd, flags) object file when linking. */ bfd_boolean -_bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +_bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { flagword old_flags; flagword new_flags; @@ -1394,17 +1219,15 @@ _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd) if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32)) { (*_bfd_error_handler) - (_("%s: linking files compiled for 16-bit integers (-mshort) " - "and others for 32-bit integers"), - bfd_archive_filename (ibfd)); + (_("%B: linking files compiled for 16-bit integers (-mshort) " + "and others for 32-bit integers"), ibfd); ok = FALSE; } if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64)) { (*_bfd_error_handler) - (_("%s: linking files compiled for 32-bit double (-fshort-double) " - "and others for 64-bit double"), - bfd_archive_filename (ibfd)); + (_("%B: linking files compiled for 32-bit double (-fshort-double) " + "and others for 64-bit double"), ibfd); ok = FALSE; } @@ -1412,9 +1235,8 @@ _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd) if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags)) { (*_bfd_error_handler) - (_("%s: linking files compiled for HCS12 with " - "others compiled for HC12"), - bfd_archive_filename (ibfd)); + (_("%B: linking files compiled for HCS12 with " + "others compiled for HC12"), ibfd); ok = FALSE; } new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK) @@ -1422,16 +1244,15 @@ _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd) elf_elfheader (obfd)->e_flags = new_flags; - new_flags &= ~EF_M68HC11_ABI; - old_flags &= ~EF_M68HC11_ABI; + new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK); + old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK); /* Warn about any other mismatches */ if (new_flags != old_flags) { (*_bfd_error_handler) - (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"), - bfd_archive_filename (ibfd), (unsigned long) new_flags, - (unsigned long) old_flags); + (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"), + ibfd, (unsigned long) new_flags, (unsigned long) old_flags); ok = FALSE; } @@ -1445,9 +1266,7 @@ _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd) } bfd_boolean -_bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr) - bfd *abfd; - PTR ptr; +_bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr) { FILE *file = (FILE *) ptr; @@ -1486,10 +1305,8 @@ _bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr) return TRUE; } -static void scan_sections_for_abi (abfd, asect, arg) - bfd* abfd ATTRIBUTE_UNUSED; - asection* asect; - PTR arg; +static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED, + asection *asect, void *arg) { struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg; @@ -1500,9 +1317,7 @@ static void scan_sections_for_abi (abfd, asect, arg) /* Tweak the OSABI field of the elf header. */ void -elf32_m68hc11_post_process_headers (abfd, link_info) - bfd *abfd; - struct bfd_link_info *link_info; +elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info) { struct m68hc11_scan_param param;