diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d1ab32b43c..1f3198afbc 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,26 @@ +2007-02-02 Bob Wilson + + * elf32-xtensa.c (plt_reloc_count): Move into link hash table. + (struct elf_xtensa_link_hash_table): New. + (elf_xtensa_hash_table): New. + (elf_xtensa_link_hash_table_create): New. + (elf_xtensa_check_relocs): Update plt_reloc_count references. + Update arguments to add_extra_plt_sections. + (elf_xtensa_create_dynamic_sections): Record new sections in the hash + table. Update for plt_reloc_count and add_extra_plt_sections. + (add_extra_plt_sections, elf_xtensa_create_plt_entry): Replace dynobj + argument with link info. Update calls to elf_xtensa_get_plt_section + and elf_xtensa_get_gotplt_section. + (elf_xtensa_allocate_local_got_size, elf_xtensa_size_dynamic_sections) + (elf_xtensa_relocate_section, elf_xtensa_finish_dynamic_sections) + (elf_xtensa_discard_info_for_section, shrink_dynamic_reloc_sections) + (relax_property_section): Get sections from the hash table and update + function calls. + (elf_xtensa_get_plt_section, elf_xtensa_get_gotplt_section): Replace + dynobj argument with link info. Get sections for first plt chunk from + the hash table. + (bfd_elf32_bfd_link_hash_table_create): Define. + 2007-02-02 Jakub Jelinek * elf-bfd.h (struct elf_obj_tdata): Change symbuf type to void *. diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index bb1983025f..97b13b7e8e 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -1,5 +1,5 @@ /* Xtensa-specific support for 32-bit ELF. - Copyright 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -35,7 +35,7 @@ /* Local helper functions. */ -static bfd_boolean add_extra_plt_sections (bfd *, int); +static bfd_boolean add_extra_plt_sections (struct bfd_link_info *, int); static char *vsprint_msg (const char *, const char *, int, ...) ATTRIBUTE_PRINTF(2,4); static bfd_reloc_status_type bfd_elf_xtensa_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); @@ -94,8 +94,8 @@ static Elf_Internal_Sym *retrieve_local_syms (bfd *); /* Miscellaneous utility functions. */ -static asection *elf_xtensa_get_plt_section (bfd *, int); -static asection *elf_xtensa_get_gotplt_section (bfd *, int); +static asection *elf_xtensa_get_plt_section (struct bfd_link_info *, int); +static asection *elf_xtensa_get_gotplt_section (struct bfd_link_info *, int); static asection *get_elf_r_symndx_section (bfd *, unsigned long); static struct elf_link_hash_entry *get_elf_r_symndx_hash_entry (bfd *, unsigned long); @@ -132,16 +132,6 @@ int elf32xtensa_size_opt; typedef struct xtensa_relax_info_struct xtensa_relax_info; -/* Total count of PLT relocations seen during check_relocs. - The actual PLT code must be split into multiple sections and all - the sections have to be created before size_dynamic_sections, - where we figure out the exact number of PLT entries that will be - needed. It is OK if this count is an overestimate, e.g., some - relocations may be removed by GC. */ - -static int plt_reloc_count = 0; - - /* The GNU tools do not easily allow extending interfaces to pass around the pointer to the Xtensa ISA information, so instead we add a global variable here (in BFD) that can be used by any of the tools that need @@ -496,6 +486,67 @@ static const bfd_byte elf_xtensa_le_plt_entry[PLT_ENTRY_SIZE] = 0 /* unused */ }; +/* Xtensa ELF linker hash table. */ + +struct elf_xtensa_link_hash_table +{ + struct elf_link_hash_table elf; + + /* Short-cuts to get to dynamic linker sections. */ + asection *sgot; + asection *sgotplt; + asection *srelgot; + asection *splt; + asection *srelplt; + asection *sgotloc; + asection *spltlittbl; + + /* Total count of PLT relocations seen during check_relocs. + The actual PLT code must be split into multiple sections and all + the sections have to be created before size_dynamic_sections, + where we figure out the exact number of PLT entries that will be + needed. It is OK if this count is an overestimate, e.g., some + relocations may be removed by GC. */ + int plt_reloc_count; +}; + +/* Get the Xtensa ELF linker hash table from a link_info structure. */ + +#define elf_xtensa_hash_table(p) \ + ((struct elf_xtensa_link_hash_table *) ((p)->hash)) + +/* Create an Xtensa ELF linker hash table. */ + +static struct bfd_link_hash_table * +elf_xtensa_link_hash_table_create (bfd *abfd) +{ + struct elf_xtensa_link_hash_table *ret; + bfd_size_type amt = sizeof (struct elf_xtensa_link_hash_table); + + ret = bfd_malloc (amt); + if (ret == NULL) + return NULL; + + if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, + _bfd_elf_link_hash_newfunc, + sizeof (struct elf_link_hash_entry))) + { + free (ret); + return NULL; + } + + ret->sgot = NULL; + ret->sgotplt = NULL; + ret->srelgot = NULL; + ret->splt = NULL; + ret->srelplt = NULL; + ret->sgotloc = NULL; + ret->spltlittbl = NULL; + + ret->plt_reloc_count = 0; + + return &ret->elf.root; +} static inline bfd_boolean xtensa_elf_dynamic_symbol_p (struct elf_link_hash_entry *h, @@ -754,6 +805,7 @@ elf_xtensa_check_relocs (bfd *abfd, asection *sec, const Elf_Internal_Rela *relocs) { + struct elf_xtensa_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel; @@ -762,6 +814,7 @@ elf_xtensa_check_relocs (bfd *abfd, if (info->relocatable) return TRUE; + htab = elf_xtensa_hash_table (info); symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); @@ -826,12 +879,11 @@ elf_xtensa_check_relocs (bfd *abfd, /* Keep track of the total PLT relocation count even if we don't yet know whether the dynamic sections will be created. */ - plt_reloc_count += 1; + htab->plt_reloc_count += 1; if (elf_hash_table (info)->dynamic_sections_created) { - if (!add_extra_plt_sections (elf_hash_table (info)->dynobj, - plt_reloc_count)) + if (! add_extra_plt_sections (info, htab->plt_reloc_count)) return FALSE; } } @@ -1056,16 +1108,22 @@ elf_xtensa_gc_sweep_hook (bfd *abfd, static bfd_boolean elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) { + struct elf_xtensa_link_hash_table *htab; flagword flags, noalloc_flags; - asection *s; + + htab = elf_xtensa_hash_table (info); /* First do all the standard stuff. */ if (! _bfd_elf_create_dynamic_sections (dynobj, info)) return FALSE; + htab->splt = bfd_get_section_by_name (dynobj, ".plt"); + htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); + htab->sgot = bfd_get_section_by_name (dynobj, ".got"); + htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); /* Create any extra PLT sections in case check_relocs has already been called on all the non-dynamic input files. */ - if (!add_extra_plt_sections (dynobj, plt_reloc_count)) + if (! add_extra_plt_sections (info, htab->plt_reloc_count)) return FALSE; noalloc_flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY @@ -1073,28 +1131,27 @@ elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) flags = noalloc_flags | SEC_ALLOC | SEC_LOAD; /* Mark the ".got.plt" section READONLY. */ - s = bfd_get_section_by_name (dynobj, ".got.plt"); - if (s == NULL - || ! bfd_set_section_flags (dynobj, s, flags)) + if (htab->sgotplt == NULL + || ! bfd_set_section_flags (dynobj, htab->sgotplt, flags)) return FALSE; /* Create ".rela.got". */ - s = bfd_make_section_with_flags (dynobj, ".rela.got", flags); - if (s == NULL - || ! bfd_set_section_alignment (dynobj, s, 2)) + htab->srelgot = bfd_make_section_with_flags (dynobj, ".rela.got", flags); + if (htab->srelgot == NULL + || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2)) return FALSE; /* Create ".got.loc" (literal tables for use by dynamic linker). */ - s = bfd_make_section_with_flags (dynobj, ".got.loc", flags); - if (s == NULL - || ! bfd_set_section_alignment (dynobj, s, 2)) + htab->sgotloc = bfd_make_section_with_flags (dynobj, ".got.loc", flags); + if (htab->sgotloc == NULL + || ! bfd_set_section_alignment (dynobj, htab->sgotloc, 2)) return FALSE; /* Create ".xt.lit.plt" (literal table for ".got.plt*"). */ - s = bfd_make_section_with_flags (dynobj, ".xt.lit.plt", - noalloc_flags); - if (s == NULL - || ! bfd_set_section_alignment (dynobj, s, 2)) + htab->spltlittbl = bfd_make_section_with_flags (dynobj, ".xt.lit.plt", + noalloc_flags); + if (htab->spltlittbl == NULL + || ! bfd_set_section_alignment (dynobj, htab->spltlittbl, 2)) return FALSE; return TRUE; @@ -1102,8 +1159,9 @@ elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) static bfd_boolean -add_extra_plt_sections (bfd *dynobj, int count) +add_extra_plt_sections (struct bfd_link_info *info, int count) { + bfd *dynobj = elf_hash_table (info)->dynobj; int chunk; /* Iterate over all chunks except 0 which uses the standard ".plt" and @@ -1115,7 +1173,7 @@ add_extra_plt_sections (bfd *dynobj, int count) asection *s; /* Stop when we find a section has already been created. */ - if (elf_xtensa_get_plt_section (dynobj, chunk)) + if (elf_xtensa_get_plt_section (info, chunk)) break; flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY @@ -1216,11 +1274,13 @@ elf_xtensa_allocate_got_size (struct elf_link_hash_entry *h, void *arg) static void -elf_xtensa_allocate_local_got_size (struct bfd_link_info *info, - asection *srelgot) +elf_xtensa_allocate_local_got_size (struct bfd_link_info *info) { + struct elf_xtensa_link_hash_table *htab; bfd *i; + htab = elf_xtensa_hash_table (info); + for (i = info->input_bfds; i; i = i->link_next) { bfd_signed_vma *local_got_refcounts; @@ -1237,8 +1297,8 @@ elf_xtensa_allocate_local_got_size (struct bfd_link_info *info, for (j = 0; j < cnt; ++j) { if (local_got_refcounts[j] > 0) - srelgot->size += (local_got_refcounts[j] - * sizeof (Elf32_External_Rela)); + htab->srelgot->size += (local_got_refcounts[j] + * sizeof (Elf32_External_Rela)); } } } @@ -1250,6 +1310,7 @@ static bfd_boolean elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) { + struct elf_xtensa_link_hash_table *htab; bfd *dynobj, *abfd; asection *s, *srelplt, *splt, *sgotplt, *srelgot, *spltlittbl, *sgotloc; bfd_boolean relplt, relgot; @@ -1257,14 +1318,22 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, plt_entries = 0; plt_chunks = 0; - srelgot = 0; + htab = elf_xtensa_hash_table (info); dynobj = elf_hash_table (info)->dynobj; if (dynobj == NULL) abort (); + srelgot = htab->srelgot; + srelplt = htab->srelplt; if (elf_hash_table (info)->dynamic_sections_created) { + BFD_ASSERT (htab->srelgot != NULL + && htab->srelplt != NULL + && htab->sgot != NULL + && htab->spltlittbl != NULL + && htab->sgotloc != NULL); + /* Set the contents of the .interp section to the interpreter. */ if (info->executable) { @@ -1276,10 +1345,7 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, } /* Allocate room for one word in ".got". */ - s = bfd_get_section_by_name (dynobj, ".got"); - if (s == NULL) - abort (); - s->size = 4; + htab->sgot->size = 4; /* Adjust refcounts for symbols that we now know are not "dynamic". */ elf_link_hash_traverse (elf_hash_table (info), @@ -1288,9 +1354,6 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* Allocate space in ".rela.got" for literals that reference global symbols. */ - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - if (srelgot == NULL) - abort (); elf_link_hash_traverse (elf_hash_table (info), elf_xtensa_allocate_got_size, (void *) srelgot); @@ -1299,12 +1362,9 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, ".rela.got" for R_XTENSA_RELATIVE relocs for literals that reference local symbols. */ if (info->shared) - elf_xtensa_allocate_local_got_size (info, srelgot); + elf_xtensa_allocate_local_got_size (info); /* Allocate space in ".rela.plt" for literals that have PLT entries. */ - srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); - if (srelplt == NULL) - abort (); elf_link_hash_traverse (elf_hash_table (info), elf_xtensa_allocate_plt_size, (void *) srelplt); @@ -1314,10 +1374,7 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, For each chunk of ".plt", we also need two more 4-byte literals, two corresponding entries in ".rela.got", and an 8-byte entry in ".xt.lit.plt". */ - spltlittbl = bfd_get_section_by_name (dynobj, ".xt.lit.plt"); - if (spltlittbl == NULL) - abort (); - + spltlittbl = htab->spltlittbl; plt_entries = srelplt->size / sizeof (Elf32_External_Rela); plt_chunks = (plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK; @@ -1326,14 +1383,13 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, created earlier because the initial count of PLT relocations was an overestimate. */ for (chunk = 0; - (splt = elf_xtensa_get_plt_section (dynobj, chunk)) != NULL; + (splt = elf_xtensa_get_plt_section (info, chunk)) != NULL; chunk++) { int chunk_entries; - sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk); - if (sgotplt == NULL) - abort (); + sgotplt = elf_xtensa_get_gotplt_section (info, chunk); + BFD_ASSERT (sgotplt != NULL); if (chunk < plt_chunks - 1) chunk_entries = PLT_ENTRIES_PER_CHUNK; @@ -1358,9 +1414,7 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* Allocate space in ".got.loc" to match the total size of all the literal tables. */ - sgotloc = bfd_get_section_by_name (dynobj, ".got.loc"); - if (sgotloc == NULL) - abort (); + sgotloc = htab->sgotloc; sgotloc->size = spltlittbl->size; for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) { @@ -1443,8 +1497,6 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* Add the special XTENSA_RTLD relocations now. The offsets won't be known until finish_dynamic_sections, but we need to get the relocs in place before they are sorted. */ - if (srelgot == NULL) - abort (); for (chunk = 0; chunk < plt_chunks; chunk++) { Elf_Internal_Rela irela; @@ -1890,7 +1942,7 @@ bfd_elf_xtensa_reloc (bfd *abfd, /* Set up an entry in the procedure linkage table. */ static bfd_vma -elf_xtensa_create_plt_entry (bfd *dynobj, +elf_xtensa_create_plt_entry (struct bfd_link_info *info, bfd *output_bfd, unsigned reloc_index) { @@ -1900,8 +1952,8 @@ elf_xtensa_create_plt_entry (bfd *dynobj, int chunk; chunk = reloc_index / PLT_ENTRIES_PER_CHUNK; - splt = elf_xtensa_get_plt_section (dynobj, chunk); - sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk); + splt = elf_xtensa_get_plt_section (info, chunk); + sgotplt = elf_xtensa_get_gotplt_section (info, chunk); BFD_ASSERT (splt != NULL && sgotplt != NULL); plt_base = splt->output_section->vma + splt->output_offset; @@ -1948,12 +2000,11 @@ elf_xtensa_relocate_section (bfd *output_bfd, Elf_Internal_Sym *local_syms, asection **local_sections) { + struct elf_xtensa_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; struct elf_link_hash_entry **sym_hashes; - asection *srelgot, *srelplt; - bfd *dynobj; property_table_entry *lit_table = 0; int ltblsize = 0; char *error_message = NULL; @@ -1962,18 +2013,10 @@ elf_xtensa_relocate_section (bfd *output_bfd, if (!xtensa_default_isa) xtensa_default_isa = xtensa_isa_init (0, 0); - dynobj = elf_hash_table (info)->dynobj; + htab = elf_xtensa_hash_table (info); symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; sym_hashes = elf_sym_hashes (input_bfd); - srelgot = NULL; - srelplt = NULL; - if (dynobj) - { - srelgot = bfd_get_section_by_name (dynobj, ".rela.got");; - srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); - } - if (elf_hash_table (info)->dynamic_sections_created) { ltblsize = xtensa_read_table_entries (input_bfd, input_section, @@ -2181,9 +2224,9 @@ elf_xtensa_relocate_section (bfd *output_bfd, asection *srel; if (dynamic_symbol && r_type == R_XTENSA_PLT) - srel = srelplt; + srel = htab->srelplt; else - srel = srelgot; + srel = htab->srelgot; BFD_ASSERT (srel != NULL); @@ -2232,7 +2275,7 @@ elf_xtensa_relocate_section (bfd *output_bfd, contents of the literal entry to the address of the PLT entry. */ relocation = - elf_xtensa_create_plt_entry (dynobj, output_bfd, + elf_xtensa_create_plt_entry (info, output_bfd, srel->reloc_count); } unresolved_reloc = FALSE; @@ -2480,6 +2523,7 @@ static bfd_boolean elf_xtensa_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { + struct elf_xtensa_link_hash_table *htab; bfd *dynobj; asection *sdyn, *srelplt, *sgot, *sxtlit, *sgotloc; Elf32_External_Dyn *dyncon, *dynconend; @@ -2488,13 +2532,14 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd, if (! elf_hash_table (info)->dynamic_sections_created) return TRUE; + htab = elf_xtensa_hash_table (info); dynobj = elf_hash_table (info)->dynobj; sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); BFD_ASSERT (sdyn != NULL); /* Set the first entry in the global offset table to the address of the dynamic section. */ - sgot = bfd_get_section_by_name (dynobj, ".got"); + sgot = htab->sgot; if (sgot) { BFD_ASSERT (sgot->size == 4); @@ -2506,7 +2551,7 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd, sgot->contents); } - srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); + srelplt = htab->srelplt; if (srelplt && srelplt->size != 0) { asection *sgotplt, *srelgot, *spltlittbl; @@ -2515,11 +2560,9 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd, bfd_byte *loc; unsigned rtld_reloc; - srelgot = bfd_get_section_by_name (dynobj, ".rela.got");; - BFD_ASSERT (srelgot != NULL); - - spltlittbl = bfd_get_section_by_name (dynobj, ".xt.lit.plt"); - BFD_ASSERT (spltlittbl != NULL); + srelgot = htab->srelgot; + spltlittbl = htab->spltlittbl; + BFD_ASSERT (srelgot != NULL && spltlittbl != NULL); /* Find the first XTENSA_RTLD relocation. Presumably the rest of them follow immediately after.... */ @@ -2540,7 +2583,7 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd, { int chunk_entries = 0; - sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk); + sgotplt = elf_xtensa_get_gotplt_section (info, chunk); BFD_ASSERT (sgotplt != NULL); /* Emit special RTLD relocations for the first two entries in @@ -2608,7 +2651,7 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd, /* Combine adjacent literal table entries. */ BFD_ASSERT (! info->relocatable); sxtlit = bfd_get_section_by_name (output_bfd, ".xt.lit"); - sgotloc = bfd_get_section_by_name (dynobj, ".got.loc"); + sgotloc = htab->sgotloc; BFD_ASSERT (sxtlit && sgotloc); num_xtlit_entries = elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc); @@ -2620,8 +2663,6 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd, for (; dyncon < dynconend; dyncon++) { Elf_Internal_Dyn dyn; - const char *name; - asection *s; bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); @@ -2635,23 +2676,19 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd, break; case DT_XTENSA_GOT_LOC_OFF: - name = ".got.loc"; - goto get_vma; + dyn.d_un.d_ptr = htab->sgotloc->vma; + break; + case DT_PLTGOT: - name = ".got"; - goto get_vma; + dyn.d_un.d_ptr = htab->sgot->vma; + break; + case DT_JMPREL: - name = ".rela.plt"; - get_vma: - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s); - dyn.d_un.d_ptr = s->vma; + dyn.d_un.d_ptr = htab->srelplt->vma; break; case DT_PLTRELSZ: - s = bfd_get_section_by_name (output_bfd, ".rela.plt"); - BFD_ASSERT (s); - dyn.d_un.d_val = s->size; + dyn.d_un.d_val = htab->srelplt->size; break; case DT_RELASZ: @@ -2661,9 +2698,8 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd, seems to be unresolved. Since the linker script arranges for .rela.plt to follow all other relocation sections, we don't have to worry about changing the DT_RELA entry. */ - s = bfd_get_section_by_name (output_bfd, ".rela.plt"); - if (s) - dyn.d_un.d_val -= s->size; + if (htab->srelplt) + dyn.d_un.d_val -= htab->srelplt->size; break; } @@ -2932,14 +2968,9 @@ elf_xtensa_discard_info_for_section (bfd *abfd, if (xtensa_is_littable_section (sec)) { - bfd *dynobj = elf_hash_table (info)->dynobj; - if (dynobj) - { - asection *sgotloc = - bfd_get_section_by_name (dynobj, ".got.loc"); - if (sgotloc) - sgotloc->size -= removed_bytes; - } + asection *sgotloc = elf_xtensa_hash_table (info)->sgotloc; + if (sgotloc) + sgotloc->size -= removed_bytes; } } else @@ -8611,6 +8642,7 @@ shrink_dynamic_reloc_sections (struct bfd_link_info *info, asection *input_section, Elf_Internal_Rela *rel) { + struct elf_xtensa_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; unsigned long r_symndx; @@ -8618,6 +8650,7 @@ shrink_dynamic_reloc_sections (struct bfd_link_info *info, struct elf_link_hash_entry *h; bfd_boolean dynamic_symbol; + htab = elf_xtensa_hash_table (info); symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); @@ -8635,24 +8668,18 @@ shrink_dynamic_reloc_sections (struct bfd_link_info *info, && (input_section->flags & SEC_ALLOC) != 0 && (dynamic_symbol || info->shared)) { - bfd *dynobj; - const char *srel_name; asection *srel; bfd_boolean is_plt = FALSE; - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - if (dynamic_symbol && r_type == R_XTENSA_PLT) { - srel_name = ".rela.plt"; + srel = htab->srelplt; is_plt = TRUE; } else - srel_name = ".rela.got"; + srel = htab->srelgot; /* Reduce size of the .rela.* section by one reloc. */ - srel = bfd_get_section_by_name (dynobj, srel_name); BFD_ASSERT (srel != NULL); BFD_ASSERT (srel->size >= sizeof (Elf32_External_Rela)); srel->size -= sizeof (Elf32_External_Rela); @@ -8671,15 +8698,15 @@ shrink_dynamic_reloc_sections (struct bfd_link_info *info, reloc_index = srel->size / sizeof (Elf32_External_Rela); chunk = reloc_index / PLT_ENTRIES_PER_CHUNK; - splt = elf_xtensa_get_plt_section (dynobj, chunk); - sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk); + splt = elf_xtensa_get_plt_section (info, chunk); + sgotplt = elf_xtensa_get_gotplt_section (info, chunk); BFD_ASSERT (splt != NULL && sgotplt != NULL); /* Check if an entire PLT chunk has just been eliminated. */ if (reloc_index % PLT_ENTRIES_PER_CHUNK == 0) { /* The two magic GOT entries for that chunk can go away. */ - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); + srelgot = htab->srelgot; BFD_ASSERT (srelgot != NULL); srelgot->reloc_count -= 2; srelgot->size -= 2 * sizeof (Elf32_External_Rela); @@ -9167,14 +9194,9 @@ relax_property_section (bfd *abfd, if (xtensa_is_littable_section (sec)) { - bfd *dynobj = elf_hash_table (link_info)->dynobj; - if (dynobj) - { - asection *sgotloc = - bfd_get_section_by_name (dynobj, ".got.loc"); - if (sgotloc) - sgotloc->size -= removed_bytes; - } + asection *sgotloc = elf_xtensa_hash_table (link_info)->sgotloc; + if (sgotloc) + sgotloc->size -= removed_bytes; } } } @@ -9360,26 +9382,38 @@ do_fix_for_final_link (Elf_Internal_Rela *rel, /* Miscellaneous utility functions.... */ static asection * -elf_xtensa_get_plt_section (bfd *dynobj, int chunk) +elf_xtensa_get_plt_section (struct bfd_link_info *info, int chunk) { + struct elf_xtensa_link_hash_table *htab; + bfd *dynobj; char plt_name[10]; if (chunk == 0) - return bfd_get_section_by_name (dynobj, ".plt"); + { + htab = elf_xtensa_hash_table (info); + return htab->splt; + } + dynobj = elf_hash_table (info)->dynobj; sprintf (plt_name, ".plt.%u", chunk); return bfd_get_section_by_name (dynobj, plt_name); } static asection * -elf_xtensa_get_gotplt_section (bfd *dynobj, int chunk) +elf_xtensa_get_gotplt_section (struct bfd_link_info *info, int chunk) { + struct elf_xtensa_link_hash_table *htab; + bfd *dynobj; char got_name[14]; if (chunk == 0) - return bfd_get_section_by_name (dynobj, ".got.plt"); + { + htab = elf_xtensa_hash_table (info); + return htab->sgotplt; + } + dynobj = elf_hash_table (info)->dynobj; sprintf (got_name, ".got.plt.%u", chunk); return bfd_get_section_by_name (dynobj, got_name); } @@ -9837,6 +9871,7 @@ static const struct bfd_elf_special_section elf_xtensa_special_sections[] = #define bfd_elf32_bfd_relax_section elf_xtensa_relax_section #define bfd_elf32_bfd_reloc_type_lookup elf_xtensa_reloc_type_lookup #define bfd_elf32_bfd_set_private_flags elf_xtensa_set_private_flags +#define bfd_elf32_bfd_link_hash_table_create elf_xtensa_link_hash_table_create #define elf_backend_adjust_dynamic_symbol elf_xtensa_adjust_dynamic_symbol #define elf_backend_check_relocs elf_xtensa_check_relocs