X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf32-sh64.c;h=0e696b308d4a0c7010b35c9add74cbca81e7e13e;hb=af60a1ef46d2c4aca22868b0f2819234b949018e;hp=eabc8ee6c857948b903e69d5b40a8108ffc5edd2;hpb=09fd220b8e3cdc177038c45e8d65b103fab62ba6;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-sh64.c b/bfd/elf32-sh64.c index eabc8ee6c8..0e696b308d 100644 --- a/bfd/elf32-sh64.c +++ b/bfd/elf32-sh64.c @@ -1,11 +1,11 @@ /* SuperH SH64-specific support for 32-bit ELF - Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2000-2015 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,12 +15,13 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #define SH64_ELF -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "elf-bfd.h" #include "../opcodes/sh64-opc.h" #include "elf32-sh64.h" @@ -56,13 +57,13 @@ static bfd_boolean shmedia_prepare_reloc static int sh64_elf_get_symbol_type (Elf_Internal_Sym *, int); static bfd_boolean sh64_elf_add_symbol_hook - (bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **, + (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **, flagword *, asection **, bfd_vma *); -static bfd_boolean sh64_elf_link_output_symbol_hook - (bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *, - asection *); +static int sh64_elf_link_output_symbol_hook + (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *, + struct elf_link_hash_entry *); static bfd_boolean sh64_backend_section_from_shdr - (bfd *, Elf_Internal_Shdr *, const char *); + (bfd *, Elf_Internal_Shdr *, const char *, int); static void sh64_elf_final_write_processing (bfd *, bfd_boolean); static bfd_boolean sh64_bfd_elf_copy_private_section_data @@ -85,8 +86,11 @@ static void sh64_find_section_for_address #define elf_backend_add_symbol_hook sh64_elf_add_symbol_hook #define elf_backend_link_output_symbol_hook \ sh64_elf_link_output_symbol_hook +#define elf_backend_merge_symbol_attribute sh64_elf_merge_symbol_attribute #define elf_backend_final_write_processing sh64_elf_final_write_processing #define elf_backend_section_from_shdr sh64_backend_section_from_shdr +#define elf_backend_special_sections sh64_elf_special_sections +#define elf_backend_section_flags sh64_elf_section_flags #define bfd_elf32_new_section_hook sh64_elf_new_section_hook @@ -99,10 +103,12 @@ static void sh64_find_section_for_address /* This COFF-only function (only compiled with COFF support, making ELF-only chains problematic) returns TRUE early for SH4, so let's just define it TRUE here. */ -#define _bfd_sh_align_load_span(a,b,c,d,e,f,g,h,i,j) TRUE +#define _bfd_sh_align_load_span(a,b,c,d,e,f,g,h,i,j) \ + ((void) f, (void) h, (void) i, TRUE) #define GOT_BIAS (-((long)-32768)) #define INCLUDE_SHMEDIA +#define SH_TARGET_ALREADY_DEFINED #include "elf32-sh.c" /* Tack some extra info on struct bfd_elf_section_data. */ @@ -110,13 +116,16 @@ static void sh64_find_section_for_address static bfd_boolean sh64_elf_new_section_hook (bfd *abfd, asection *sec) { - struct _sh64_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + if (!sec->used_by_bfd) + { + struct _sh64_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); - sdata = (struct _sh64_elf_section_data *) bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = sdata; + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } return _bfd_elf_new_section_hook (abfd, sec); } @@ -147,7 +156,6 @@ static bfd_boolean sh64_elf_set_mach_from_flags (bfd *abfd) { flagword flags = elf_elfheader (abfd)->e_flags; - asection *cranges; switch (flags & EF_SH_MACH_MASK) { @@ -162,18 +170,19 @@ sh64_elf_set_mach_from_flags (bfd *abfd) return FALSE; } - /* We also need to set SEC_DEBUGGING on an incoming .cranges section. - We could have used elf_backend_section_flags if it had given us the - section name; the bfd_section member in the header argument is not - set at the point of the call. FIXME: Find out whether that is by - undocumented design or a bug. */ - cranges = bfd_get_section_by_name (abfd, SH64_CRANGES_SECTION_NAME); - if (cranges != NULL - && ! bfd_set_section_flags (abfd, cranges, - bfd_get_section_flags (abfd, cranges) - | SEC_DEBUGGING)) + return TRUE; +} + +static bfd_boolean +sh64_elf_section_flags (flagword *flags, + const Elf_Internal_Shdr *hdr) +{ + if (hdr->bfd_section == NULL) return FALSE; + if (strcmp (hdr->bfd_section->name, SH64_CRANGES_SECTION_NAME) == 0) + *flags |= SEC_DEBUGGING; + return TRUE; } @@ -189,7 +198,8 @@ sh64_elf_copy_private_data (bfd * ibfd, bfd * obfd) == elf_elfheader (ibfd)->e_flags)); elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - return TRUE; + + return _bfd_elf_copy_private_bfd_data (ibfd, obfd); } static bfd_boolean @@ -248,13 +258,14 @@ sh64_elf_merge_private_data (bfd *ibfd, bfd *obfd) } /* Handle a SH64-specific section when reading an object file. This - is called when elfcode.h finds a section with an unknown type. + is called when bfd_section_from_shdr finds a section with an unknown + type. We only recognize SHT_SH5_CR_SORTED, on the .cranges section. */ bfd_boolean sh64_backend_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, - const char *name) + const char *name, int shindex) { flagword flags = 0; @@ -279,7 +290,7 @@ sh64_backend_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, return FALSE; } - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) + if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) return FALSE; if (flags @@ -372,13 +383,13 @@ sh64_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type) static bfd_boolean sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, - const Elf_Internal_Sym *sym, const char **namep, + Elf_Internal_Sym *sym, const char **namep, flagword *flagsp ATTRIBUTE_UNUSED, asection **secp, bfd_vma *valp) { /* We want to do this for relocatable as well as final linking. */ if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL - && info->hash->creator->flavour == bfd_target_elf_flavour) + && is_elf_hash_table (info->hash)) { struct elf_link_hash_entry *h; @@ -409,7 +420,7 @@ sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, { /* No previous datalabel symbol. Make one. */ struct bfd_link_hash_entry *bh = NULL; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name, flags, *secp, *valp, @@ -421,7 +432,7 @@ sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, } h = (struct elf_link_hash_entry *) bh; - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; + h->non_elf = 0; h->type = STT_DATALABEL; } else @@ -467,12 +478,12 @@ sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, we don't need to look up and make sure to emit the main symbol for each DataLabel symbol. */ -bfd_boolean -sh64_elf_link_output_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info, +static int +sh64_elf_link_output_symbol_hook (struct bfd_link_info *info, const char *cname, Elf_Internal_Sym *sym, - asection *input_sec ATTRIBUTE_UNUSED) + asection *input_sec ATTRIBUTE_UNUSED, + struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) { char *name = (char *) cname; @@ -482,7 +493,7 @@ sh64_elf_link_output_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED, name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0; } - return TRUE; + return 1; } /* Check a SH64-specific reloc and put the value to relocate to into @@ -584,9 +595,9 @@ shmedia_prepare_reloc (struct bfd_link_info *info, bfd *abfd, if (dropped != 0) { (*_bfd_error_handler) - (_("%s: error: unaligned relocation type %d at %08x reloc %08x\n"), - bfd_get_filename (input_section->owner), ELF32_R_TYPE (rel->r_info), - (unsigned)rel->r_offset, (unsigned)relocation); + (_("%B: error: unaligned relocation type %d at %08x reloc %p\n"), + input_section->owner, ELF32_R_TYPE (rel->r_info), + (unsigned) rel->r_offset, relocation); return FALSE; } @@ -602,6 +613,7 @@ sh64_find_section_for_address (bfd *abfd ATTRIBUTE_UNUSED, { bfd_vma vma; bfd_size_type size; + struct sh64_find_section_vma_data *fsec_datap = (struct sh64_find_section_vma_data *) data; @@ -617,11 +629,7 @@ sh64_find_section_for_address (bfd *abfd ATTRIBUTE_UNUSED, if (fsec_datap->addr < vma) return; - /* FIXME: section->reloc_done isn't set properly; a generic buglet - preventing us from using bfd_get_section_size_after_reloc. */ - size - = section->_cooked_size ? section->_cooked_size : section->_raw_size; - + size = section->size; if (fsec_datap->addr >= vma + size) return; @@ -652,9 +660,7 @@ sh64_elf_final_write_processing (bfd *abfd, = sh64_elf_section_data (cranges)->sh64_info->cranges_growth) != 0) { bfd_vma incoming_cranges_size - = ((cranges->_cooked_size != 0 - ? cranges->_cooked_size : cranges->_raw_size) - - ld_generated_cranges_size); + = cranges->size - ld_generated_cranges_size; if (! bfd_set_section_contents (abfd, cranges, cranges->contents @@ -697,9 +703,7 @@ sh64_elf_final_write_processing (bfd *abfd, /* If we have a .cranges section, sort the entries. */ if (cranges != NULL) { - bfd_size_type cranges_size - = (cranges->_cooked_size != 0 - ? cranges->_cooked_size : cranges->_raw_size); + bfd_size_type cranges_size = cranges->size; /* We know we always have these in memory at this time. */ BFD_ASSERT (cranges->contents != NULL); @@ -734,12 +738,39 @@ sh64_elf_final_write_processing (bfd *abfd, } } +/* Merge non visibility st_other attribute when the symbol comes from + a dynamic object. */ +static void +sh64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, + const Elf_Internal_Sym *isym, + bfd_boolean definition, + bfd_boolean dynamic ATTRIBUTE_UNUSED) +{ + if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0) + { + unsigned char other; + + /* Take the balance of OTHER from the definition. */ + other = (definition ? isym->st_other : h->other); + other &= ~ ELF_ST_VISIBILITY (-1); + h->other = other | ELF_ST_VISIBILITY (h->other); + } + + return; +} + +static const struct bfd_elf_special_section sh64_elf_special_sections[] = +{ + { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 }, + { NULL, 0, 0, 0, 0 } +}; + #undef TARGET_BIG_SYM -#define TARGET_BIG_SYM bfd_elf32_sh64_vec +#define TARGET_BIG_SYM sh64_elf32_vec #undef TARGET_BIG_NAME #define TARGET_BIG_NAME "elf32-sh64" #undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_sh64l_vec +#define TARGET_LITTLE_SYM sh64_elf32_le_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-sh64l" @@ -747,15 +778,16 @@ sh64_elf_final_write_processing (bfd *abfd, /* NetBSD support. */ #undef TARGET_BIG_SYM -#define TARGET_BIG_SYM bfd_elf32_sh64nbsd_vec +#define TARGET_BIG_SYM sh64_elf32_nbsd_vec #undef TARGET_BIG_NAME #define TARGET_BIG_NAME "elf32-sh64-nbsd" #undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_sh64lnbsd_vec +#define TARGET_LITTLE_SYM sh64_elf32_nbsd_le_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-sh64l-nbsd" #undef ELF_MAXPAGESIZE #define ELF_MAXPAGESIZE 0x10000 +#undef ELF_COMMONPAGESIZE #undef elf_symbol_leading_char #define elf_symbol_leading_char 0 #undef elf32_bed @@ -765,15 +797,17 @@ sh64_elf_final_write_processing (bfd *abfd, /* Linux support. */ #undef TARGET_BIG_SYM -#define TARGET_BIG_SYM bfd_elf32_sh64blin_vec +#define TARGET_BIG_SYM sh64_elf32_linux_be_vec #undef TARGET_BIG_NAME #define TARGET_BIG_NAME "elf32-sh64big-linux" #undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_sh64lin_vec +#define TARGET_LITTLE_SYM sh64_elf32_linux_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-sh64-linux" #undef elf32_bed #define elf32_bed elf32_sh64_lin_bed +#undef ELF_COMMONPAGESIZE +#define ELF_COMMONPAGESIZE 0x1000 #include "elf32-target.h"