X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-metag.c;h=596cf761a71cc4bdbdfab9fec2e38792453e239c;hb=ec892a0718dc47c2d009532865c353daa749eaa1;hp=8851845384b050a629935c00cc9e381e62d9e788;hpb=81fbe831fe0239501808446529614a07449695e3;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c index 8851845384..596cf761a7 100644 --- a/bfd/elf32-metag.c +++ b/bfd/elf32-metag.c @@ -1,5 +1,5 @@ /* Meta support for 32-bit ELF - Copyright (C) 2013 Free Software Foundation, Inc. + Copyright (C) 2013-2015 Free Software Foundation, Inc. Contributed by Imagination Technologies Ltd. This file is part of BFD, the Binary File Descriptor library. @@ -142,7 +142,7 @@ static reloc_howto_type elf_metag_howto_table[] = /* No relocation. */ HOWTO (R_METAG_NONE, /* type */ 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ + 3, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ @@ -838,7 +838,7 @@ struct elf_metag_link_hash_table /* Assorted information used by elf_metag_size_stubs. */ unsigned int bfd_count; - int top_index; + unsigned int top_index; asection **input_list; Elf_Internal_Sym **all_local_syms; @@ -896,7 +896,11 @@ metag_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type; r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_METAG_MAX); + if (r_type >= (unsigned int) R_METAG_MAX) + { + _bfd_error_handler (_("%B: invalid METAG reloc number: %d"), abfd, r_type); + r_type = 0; + } cache_ptr->howto = & elf_metag_howto_table [r_type]; } @@ -1017,6 +1021,18 @@ metag_link_hash_newfunc (struct bfd_hash_entry *entry, return entry; } +/* Free the derived linker hash table. */ + +static void +elf_metag_link_hash_table_free (bfd *obfd) +{ + struct elf_metag_link_hash_table *htab + = (struct elf_metag_link_hash_table *) obfd->link.hash; + + bfd_hash_table_free (&htab->bstab); + _bfd_elf_link_hash_table_free (obfd); +} + /* Create the derived linker hash table. The Meta ELF port uses the derived hash table to keep information specific to the Meta ELF linker (without using static variables). */ @@ -1043,23 +1059,15 @@ elf_metag_link_hash_table_create (bfd *abfd) /* Init the stub hash table too. */ if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc, sizeof (struct elf_metag_stub_hash_entry))) - return NULL; + { + _bfd_elf_link_hash_table_free (abfd); + return NULL; + } + htab->etab.root.hash_table_free = elf_metag_link_hash_table_free; return &htab->etab.root; } -/* Free the derived linker hash table. */ - -static void -elf_metag_link_hash_table_free (struct bfd_link_hash_table *btab) -{ - struct elf_metag_link_hash_table *htab - = (struct elf_metag_link_hash_table *) btab; - - bfd_hash_table_free (&htab->bstab); - _bfd_elf_link_hash_table_free (btab); -} - /* Section name for stubs is the associated section name plus this string. */ #define STUB_SUFFIX ".stub" @@ -1410,7 +1418,7 @@ metag_final_link_relocate (reloc_howto_type *howto, _bfd_clear_contents (howto, input_bfd, input_section, \ contents + rel->r_offset); \ \ - if (info->relocatable \ + if (bfd_link_relocatable (info) \ && (input_section->flags & SEC_DEBUGGING)) \ { \ /* Only remove relocations in debug sections since other \ @@ -1536,12 +1544,12 @@ elf_metag_relocate_section (bfd *output_bfd, else { struct elf_link_hash_entry *eh; - bfd_boolean unresolved_reloc, warned; + bfd_boolean unresolved_reloc, warned, ignored; RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, r_symndx, symtab_hdr, eh_syms, eh, sec, relocation, - unresolved_reloc, warned); + unresolved_reloc, warned, ignored); name = eh->root.root.string; hh = (struct elf_metag_link_hash_entry *) eh; @@ -1551,7 +1559,7 @@ elf_metag_relocate_section (bfd *output_bfd, METAG_RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); - if (info->relocatable) + if (bfd_link_relocatable (info)) continue; switch (r_type) @@ -1561,12 +1569,12 @@ elf_metag_relocate_section (bfd *output_bfd, if ((input_section->flags & SEC_ALLOC) == 0) break; - if ((info->shared + if ((bfd_link_pic (info) && r_symndx != STN_UNDEF && (input_section->flags & SEC_ALLOC) != 0 && (r_type != R_METAG_RELBRANCH || !SYMBOL_CALLS_LOCAL (info, &hh->eh))) - || (!info->shared + || (!bfd_link_pic (info) && hh != NULL && hh->eh.dynindx != -1 && !hh->eh.non_got_ref @@ -1701,7 +1709,8 @@ elf_metag_relocate_section (bfd *output_bfd, off = hh->eh.got.offset; dyn = htab->etab.dynamic_sections_created; - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, + bfd_link_pic (info), &hh->eh)) { /* If we aren't going to call finish_dynamic_symbol, @@ -1741,7 +1750,7 @@ elf_metag_relocate_section (bfd *output_bfd, if (do_got) { - if (info->shared) + if (bfd_link_pic (info)) { /* Output a dynamic relocation for this GOT entry. In this case it is relative to the base of the @@ -1788,8 +1797,10 @@ elf_metag_relocate_section (bfd *output_bfd, bfd_boolean dyn; dyn = htab->etab.dynamic_sections_created; - if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, &hh->eh) - && (!info->shared + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, + bfd_link_pic (info), + &hh->eh) + && (!bfd_link_pic (info) || !SYMBOL_REFERENCES_LOCAL (info, &hh->eh))) { indx = hh->eh.dynindx; @@ -1823,7 +1834,7 @@ elf_metag_relocate_section (bfd *output_bfd, now, and emit any relocations. If both an IE GOT and a GD GOT are necessary, we emit the GD first. */ - if ((info->shared || indx != 0) + if ((bfd_link_pic (info) || indx != 0) && (hh == NULL || ELF_ST_VISIBILITY (hh->eh.other) == STV_DEFAULT || hh->eh.root.type != bfd_link_hash_undefweak)) @@ -1915,7 +1926,7 @@ elf_metag_relocate_section (bfd *output_bfd, case R_METAG_TLS_IENONPIC_LO16: case R_METAG_TLS_LE_HI16: case R_METAG_TLS_LE_LO16: - if (info->shared) + if (bfd_link_pic (info)) { (*_bfd_error_handler) (_("%B(%A+0x%lx): R_METAG_TLS_LE/IENONPIC relocation not permitted in shared object"), @@ -1928,7 +1939,7 @@ elf_metag_relocate_section (bfd *output_bfd, break; case R_METAG_TLS_LDO_HI16: case R_METAG_TLS_LDO_LO16: - if (! info->shared) + if (! bfd_link_pic (info)) relocation = tpoff (info, relocation); else relocation -= dtpoff_base (info); @@ -2063,7 +2074,7 @@ elf_metag_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) eh->type = STT_OBJECT; eh->other = STV_HIDDEN; - if (! info->executable + if (! bfd_link_executable (info) && ! bfd_elf_link_record_dynamic_symbol (info, eh)) return FALSE; @@ -2100,7 +2111,7 @@ elf_metag_check_relocs (bfd *abfd, bfd *dynobj; int tls_type = GOT_UNKNOWN, old_tls_type = GOT_UNKNOWN; - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; htab = metag_link_hash_table (info); @@ -2155,7 +2166,7 @@ elf_metag_check_relocs (bfd *abfd, case R_METAG_TLS_GD: case R_METAG_TLS_LDM: case R_METAG_TLS_IE: - if (info->shared) + if (bfd_link_pic (info)) info->flags |= DF_STATIC_TLS; /* Fall through. */ @@ -2269,7 +2280,7 @@ elf_metag_check_relocs (bfd *abfd, cannot be used in shared libs. Don't error out for sections we don't care about, such as debug sections or non-constant sections. */ - if (info->shared + if (bfd_link_pic (info) && (sec->flags & SEC_ALLOC) != 0 && (sec->flags & SEC_READONLY) != 0) { @@ -2290,7 +2301,7 @@ elf_metag_check_relocs (bfd *abfd, case R_METAG_ADDR32: case R_METAG_RELBRANCH: case R_METAG_GETSETOFF: - if (hh != NULL && !info->shared) + if (hh != NULL && !bfd_link_pic (info)) { hh->eh.non_got_ref = 1; hh->eh.plt.refcount += 1; @@ -2315,14 +2326,14 @@ elf_metag_check_relocs (bfd *abfd, may need to keep relocations for symbols satisfied by a dynamic library if we manage to avoid copy relocs for the symbol. */ - if ((info->shared + if ((bfd_link_pic (info) && (sec->flags & SEC_ALLOC) != 0 && (r_type != R_METAG_RELBRANCH || (hh != NULL && (! info->symbolic || hh->eh.root.type == bfd_link_hash_defweak || !hh->eh.def_regular)))) - || (!info->shared + || (!bfd_link_pic (info) && (sec->flags & SEC_ALLOC) != 0 && hh != NULL && (hh->eh.root.type == bfd_link_hash_defweak @@ -2529,7 +2540,7 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, only references to the symbol are via the global offset table. For such cases we need not do anything here; the relocations will be handled correctly by relocate_section. */ - if (info->shared) + if (bfd_link_pic (info)) return TRUE; /* If there are no references to this symbol that do not use the @@ -2583,7 +2594,7 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, s = htab->sdynbss; - return _bfd_elf_adjust_dynamic_copy (eh, s); + return _bfd_elf_adjust_dynamic_copy (info, eh, s); } /* Allocate space in .plt, .got and associated reloc sections for @@ -2618,7 +2629,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) return FALSE; } - if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, eh)) + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), eh)) { asection *s = htab->splt; @@ -2634,7 +2645,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) location in the .plt. This is required to make function pointers compare as equal between the normal executable and the shared library. */ - if (! info->shared + if (! bfd_link_pic (info) && !eh->def_regular) { eh->root.u.def.section = s; @@ -2693,7 +2704,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) htab->srelgot->size += sizeof (Elf32_External_Rela); else if (tls_type == GOT_TLS_GD) htab->srelgot->size += 2 * sizeof (Elf32_External_Rela); - else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, eh)) + else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, + bfd_link_pic (info), + eh)) htab->srelgot->size += sizeof (Elf32_External_Rela); } else @@ -2708,7 +2721,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) defined in a regular object. For the normal shared case, discard space for relocs that have become local due to symbol visibility changes. */ - if (info->shared) + if (bfd_link_pic (info)) { if (SYMBOL_CALLS_LOCAL (info, eh)) { @@ -2835,7 +2848,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (htab->etab.dynamic_sections_created) { /* Set the contents of the .interp section to the interpreter. */ - if (info->executable) + if (bfd_link_executable (info) && !info->nointerp) { s = bfd_get_linker_section (dynobj, ".interp"); if (s == NULL) @@ -2847,7 +2860,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* Set up .got offsets for local syms, and space for local dynamic relocs. */ - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) { bfd_signed_vma *local_got; bfd_signed_vma *end_local_got; @@ -2905,7 +2918,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* R_METAG_TLS_GD relocs need 2 consecutive GOT entries. */ if (*local_tls_type == GOT_TLS_GD) s->size += 4; - if (info->shared) + if (bfd_link_pic (info)) srel->size += sizeof (Elf32_External_Rela); } else @@ -3014,7 +3027,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (!add_dynamic_entry (DT_PLTGOT, 0)) return FALSE; - if (info->executable) + if (bfd_link_executable (info)) { if (!add_dynamic_entry (DT_DEBUG, 0)) return FALSE; @@ -3106,7 +3119,7 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, BFD_ASSERT (plt_index < (1 << 16)); /* Fill in the entry in the procedure linkage table. */ - if (! info->shared) + if (! bfd_link_pic (info)) { bfd_put_32 (output_bfd, (plt_entry[0] @@ -3190,7 +3203,7 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, we just want to emit a RELATIVE reloc. The entry in the global offset table will already have been initialized in the relocate_section function. */ - if (info->shared + if (bfd_link_pic (info) && (info->symbolic || eh->dynindx == -1) && eh->def_regular) { @@ -3249,10 +3262,11 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, /* Set the Meta ELF ABI version. */ static void -elf_metag_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATTRIBUTE_UNUSED) +elf_metag_post_process_headers (bfd * abfd, struct bfd_link_info * link_info) { Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */ + _bfd_elf_post_process_headers (abfd, link_info); i_ehdrp = elf_elfheader (abfd); i_ehdrp->e_ident[EI_ABIVERSION] = METAG_ELF_ABI_VERSION; } @@ -3368,7 +3382,7 @@ elf_metag_finish_dynamic_sections (bfd *output_bfd, /* addr = .got + 4 */ addr = htab->sgot->output_section->vma + htab->sgot->output_offset + 4; - if (info->shared) + if (bfd_link_pic (info)) { addr -= splt->output_section->vma + splt->output_offset; bfd_put_32 (output_bfd, @@ -3454,7 +3468,7 @@ elf_metag_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, bfd_signed_vma *local_plt_refcounts; const Elf_Internal_Rela *rel, *relend; - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; elf_section_data (sec)->local_dynrel = NULL; @@ -3537,7 +3551,7 @@ elf_metag_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, struct elf_metag_dyn_reloc_entry **hdh_pp; struct elf_metag_dyn_reloc_entry *hdh_p; - if (!info->shared && eh->plt.refcount > 0) + if (!bfd_link_pic (info) && eh->plt.refcount > 0) eh->plt.refcount -= 1; hh = (struct elf_metag_link_hash_entry *) eh; @@ -3595,7 +3609,7 @@ metag_type_of_stub (asection *input_sec, if (branch_offset + max_branch_offset >= 2*max_branch_offset) { - if (info->shared) + if (bfd_link_pic (info)) return metag_stub_long_branch_shared; else return metag_stub_long_branch; @@ -3715,7 +3729,7 @@ elf_metag_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) { bfd *input_bfd; unsigned int bfd_count; - int top_id, top_index; + unsigned int top_id, top_index; asection *section; asection **input_list, **list; bfd_size_type amt; @@ -3724,7 +3738,7 @@ elf_metag_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) /* Count the number of input BFDs and find the top input section id. */ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0; input_bfd != NULL; - input_bfd = input_bfd->link_next) + input_bfd = input_bfd->link.next) { bfd_count += 1; for (section = input_bfd->sections; @@ -3906,7 +3920,7 @@ get_local_syms (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *input_bfd, /* Walk over all the input BFDs, swapping in local symbols. */ for (bfd_indx = 0; input_bfd != NULL; - input_bfd = input_bfd->link_next, bfd_indx++) + input_bfd = input_bfd->link.next, bfd_indx++) { Elf_Internal_Shdr *symtab_hdr; @@ -4003,7 +4017,7 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, for (input_bfd = info->input_bfds, bfd_indx = 0; input_bfd != NULL; - input_bfd = input_bfd->link_next, bfd_indx++) + input_bfd = input_bfd->link.next, bfd_indx++) { Elf_Internal_Shdr *symtab_hdr; asection *section; @@ -4136,7 +4150,7 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, } else if (hh->eh.root.type == bfd_link_hash_undefweak) { - if (! info->shared) + if (! bfd_link_pic (info)) continue; } else if (hh->eh.root.type == bfd_link_hash_undefined) @@ -4283,7 +4297,7 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt, #define ELF_MAXPAGESIZE 0x4000 #define ELF_COMMONPAGESIZE 0x1000 -#define TARGET_LITTLE_SYM bfd_elf32_metag_vec +#define TARGET_LITTLE_SYM metag_elf32_vec #define TARGET_LITTLE_NAME "elf32-metag" #define elf_symbol_leading_char '_' @@ -4294,7 +4308,6 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt, #define bfd_elf32_bfd_is_local_label_name elf_metag_is_local_label_name #define bfd_elf32_bfd_link_hash_table_create \ elf_metag_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_free elf_metag_link_hash_table_free #define elf_backend_relocate_section elf_metag_relocate_section #define elf_backend_gc_mark_hook elf_metag_gc_mark_hook #define elf_backend_gc_sweep_hook elf_metag_gc_sweep_hook