2009-06-16 H.J. Lu <hongjiu.lu@intel.com>

* configure.in (elf): Add elf-ifunc.lo.

	* configure: Regenerated.
	* Makefile.in: Likewise.

	* elf-bfd.h (elf_link_hash_table): Add sgot, sgotplt,
	srelgot, splt, srelplt, igotplt, iplt, irelplt and irelifunc.

	* elf32-i386.c (elf_i386_link_hash_table): Remove sgot,
	sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and
	irelifunc.
	(elf_i386_link_hash_table_create): Likewise.
	(elf_i386_create_dynamic_sections): Likewise.
	(elf_i386_check_relocs): Likewise.
	(elf_i386_allocate_dynrelocs): Likewise.
	(elf_i386_size_dynamic_sections): Likewise.
	(elf_i386_relocate_section): Likewise.
	(elf_i386_finish_dynamic_symbol): Likewise.
	(elf_i386_finish_dynamic_sections): Likewise.
	(elf_i386_create_got_section): Removed.

	* elf64-x86-64.c (elf64_x86_64_link_hash_table): Remove sgot,
	sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and
	irelifunc.
	(elf64_x86_64_compute_jump_table_size): Updated.
	(elf64_x86_64_link_hash_table_create): Likewise.
	(elf64_x86_64_create_dynamic_sections): Likewise.
	(elf64_x86_64_check_relocs): Likewise.
	(elf64_x86_64_allocate_dynrelocs): Likewise.
	(elf64_x86_64_size_dynamic_sections): Likewise.
	(elf64_x86_64_relocate_section): Likewise.
	(elf64_x86_64_finish_dynamic_symbol): Likewise.
	(elf64_x86_64_finish_dynamic_sections): Likewise.
	(elf64_x86_64_create_got_section): Removed.

	* elflink.c (_bfd_elf_create_got_section): Use log_file_align
	for pointer alignment.  Set up section pointers.
	(_bfd_elf_create_dynamic_sections): Likewise.
	(_bfd_elf_create_ifunc_sections): Moved to ...
	* elf-ifunc.c: Here.  New.

	* Makefile.am (BFD32_BACKENDS): Add elf-ifunc.lo.
	(BFD32_BACKENDS_CFILES): Add elf-ifunc.c.
	Run "make dep-am".
This commit is contained in:
H.J. Lu
2009-06-16 13:41:10 +00:00
parent 671f4ed1aa
commit 6de2ae4a2a
10 changed files with 567 additions and 609 deletions

View File

@ -1,8 +1,55 @@
2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
* configure.in (elf): Add elf-ifunc.lo.
* configure: Regenerated.
* Makefile.in: Likewise.
* elf-bfd.h (elf_link_hash_table): Add sgot, sgotplt,
srelgot, splt, srelplt, igotplt, iplt, irelplt and irelifunc.
* elf32-i386.c (elf_i386_link_hash_table): Remove sgot,
sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and
irelifunc.
(elf_i386_link_hash_table_create): Likewise.
(elf_i386_create_dynamic_sections): Likewise.
(elf_i386_check_relocs): Likewise.
(elf_i386_allocate_dynrelocs): Likewise.
(elf_i386_size_dynamic_sections): Likewise.
(elf_i386_relocate_section): Likewise.
(elf_i386_finish_dynamic_symbol): Likewise.
(elf_i386_finish_dynamic_sections): Likewise.
(elf_i386_create_got_section): Removed.
* elf64-x86-64.c (elf64_x86_64_link_hash_table): Remove sgot,
sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and
irelifunc.
(elf64_x86_64_compute_jump_table_size): Updated.
(elf64_x86_64_link_hash_table_create): Likewise.
(elf64_x86_64_create_dynamic_sections): Likewise.
(elf64_x86_64_check_relocs): Likewise.
(elf64_x86_64_allocate_dynrelocs): Likewise.
(elf64_x86_64_size_dynamic_sections): Likewise.
(elf64_x86_64_relocate_section): Likewise.
(elf64_x86_64_finish_dynamic_symbol): Likewise.
(elf64_x86_64_finish_dynamic_sections): Likewise.
(elf64_x86_64_create_got_section): Removed.
* elflink.c (_bfd_elf_create_got_section): Use log_file_align
for pointer alignment. Set up section pointers.
(_bfd_elf_create_dynamic_sections): Likewise.
(_bfd_elf_create_ifunc_sections): Moved to ...
* elf-ifunc.c: Here. New.
* Makefile.am (BFD32_BACKENDS): Add elf-ifunc.lo.
(BFD32_BACKENDS_CFILES): Add elf-ifunc.c.
Run "make dep-am".
2009-06-16 Doug Kwan <dougkwan@google.com> 2009-06-16 Doug Kwan <dougkwan@google.com>
* elf32-arm.c (cortex_a8_erratum_scan): Change type of offset * elf32-arm.c (cortex_a8_erratum_scan): Change type of offset
to bfd_signed_vma. Cast constant operands which are used in to bfd_signed_vma. Cast constant operands which are used in
offset related expressions to bfd_signed_vma type as appropriate. offset related expressions to bfd_signed_vma type as appropriate.
2009-06-16 Maciej W. Rozycki <macro@linux-mips.org> 2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>

View File

@ -250,6 +250,7 @@ BFD32_BACKENDS = \
ecofflink.lo \ ecofflink.lo \
elf-attrs.lo \ elf-attrs.lo \
elf-eh-frame.lo \ elf-eh-frame.lo \
elf-ifunc.lo \
elf-m10200.lo \ elf-m10200.lo \
elf-m10300.lo \ elf-m10300.lo \
elf-strtab.lo \ elf-strtab.lo \
@ -432,6 +433,7 @@ BFD32_BACKENDS_CFILES = \
ecofflink.c \ ecofflink.c \
elf-attrs.c \ elf-attrs.c \
elf-eh-frame.c \ elf-eh-frame.c \
elf-ifunc.c \
elf-m10200.c \ elf-m10200.c \
elf-m10300.c \ elf-m10300.c \
elf-strtab.c \ elf-strtab.c \
@ -2046,6 +2048,18 @@ elf-eh-frame.lo: \
$(INCDIR)/filenames.h \ $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h \ $(INCDIR)/hashtab.h \
elf-bfd.h elf-bfd.h
elf-ifunc.lo: \
elf-ifunc.c \
$(INCDIR)/bfdlink.h \
$(INCDIR)/elf/common.h \
$(INCDIR)/elf/external.h \
$(INCDIR)/elf/internal.h \
$(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h \
$(INCDIR)/libiberty.h \
$(INCDIR)/objalloc.h \
$(INCDIR)/safe-ctype.h \
elf-bfd.h
elf-m10200.lo: \ elf-m10200.lo: \
elf-m10200.c \ elf-m10200.c \
$(INCDIR)/bfdlink.h \ $(INCDIR)/bfdlink.h \

View File

@ -521,6 +521,7 @@ BFD32_BACKENDS = \
ecofflink.lo \ ecofflink.lo \
elf-attrs.lo \ elf-attrs.lo \
elf-eh-frame.lo \ elf-eh-frame.lo \
elf-ifunc.lo \
elf-m10200.lo \ elf-m10200.lo \
elf-m10300.lo \ elf-m10300.lo \
elf-strtab.lo \ elf-strtab.lo \
@ -703,6 +704,7 @@ BFD32_BACKENDS_CFILES = \
ecofflink.c \ ecofflink.c \
elf-attrs.c \ elf-attrs.c \
elf-eh-frame.c \ elf-eh-frame.c \
elf-ifunc.c \
elf-m10200.c \ elf-m10200.c \
elf-m10300.c \ elf-m10300.c \
elf-strtab.c \ elf-strtab.c \
@ -2647,6 +2649,18 @@ elf-eh-frame.lo: \
$(INCDIR)/filenames.h \ $(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h \ $(INCDIR)/hashtab.h \
elf-bfd.h elf-bfd.h
elf-ifunc.lo: \
elf-ifunc.c \
$(INCDIR)/bfdlink.h \
$(INCDIR)/elf/common.h \
$(INCDIR)/elf/external.h \
$(INCDIR)/elf/internal.h \
$(INCDIR)/filenames.h \
$(INCDIR)/hashtab.h \
$(INCDIR)/libiberty.h \
$(INCDIR)/objalloc.h \
$(INCDIR)/safe-ctype.h \
elf-bfd.h
elf-m10200.lo: \ elf-m10200.lo: \
elf-m10200.c \ elf-m10200.c \
$(INCDIR)/bfdlink.h \ $(INCDIR)/bfdlink.h \

3
bfd/configure vendored
View File

@ -20942,7 +20942,8 @@ selarchs="$f"
# Target backend .o files. # Target backend .o files.
tb= tb=
elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo dwarf1.lo" elf="elf.lo elflink.lo elf-attrs.lo elf-ifunc.lo elf-strtab.lo
elf-eh-frame.lo dwarf1.lo"
for vec in $selvecs for vec in $selvecs
do do

View File

@ -639,7 +639,8 @@ selarchs="$f"
# Target backend .o files. # Target backend .o files.
tb= tb=
elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo dwarf1.lo" elf="elf.lo elflink.lo elf-attrs.lo elf-ifunc.lo elf-strtab.lo
elf-eh-frame.lo dwarf1.lo"
for vec in $selvecs for vec in $selvecs
do do

View File

@ -457,6 +457,17 @@ struct elf_link_hash_table
/* A linked list of BFD's loaded in the link. */ /* A linked list of BFD's loaded in the link. */
struct elf_link_loaded_list *loaded; struct elf_link_loaded_list *loaded;
/* Short-cuts to get to dynamic linker sections. */
asection *sgot;
asection *sgotplt;
asection *srelgot;
asection *splt;
asection *srelplt;
asection *igotplt;
asection *iplt;
asection *irelplt;
asection *irelifunc;
}; };
/* Look up an entry in an ELF linker hash table. */ /* Look up an entry in an ELF linker hash table. */

105
bfd/elf-ifunc.c Normal file
View File

@ -0,0 +1,105 @@
/* ELF STT_GNU_IFUNC support.
Copyright 2009
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 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.
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 "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#define ARCH_SIZE 0
#include "elf-bfd.h"
#include "safe-ctype.h"
#include "libiberty.h"
#include "objalloc.h"
/* Create sections needed by STT_GNU_IFUNC symbol. */
bfd_boolean
_bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
{
flagword flags, pltflags;
asection *s;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
struct elf_link_hash_table *htab = elf_hash_table (info);
if (htab->irelifunc != NULL || htab->iplt != NULL)
return TRUE;
flags = bed->dynamic_sec_flags;
pltflags = flags;
if (bed->plt_not_loaded)
/* We do not clear SEC_ALLOC here because we still want the OS to
allocate space for the section; it's just that there's nothing
to read in from the object file. */
pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
else
pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD;
if (bed->plt_readonly)
pltflags |= SEC_READONLY;
if (info->shared)
{
/* We need to create .rel[a].ifunc for shared objects. */
const char *rel_sec = (bed->rela_plts_and_copies_p
? ".rela.ifunc" : ".rel.ifunc");
s = bfd_make_section_with_flags (abfd, rel_sec,
flags | SEC_READONLY);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s,
bed->s->log_file_align))
return FALSE;
htab->irelifunc = s;
}
else
{
/* We need to create .iplt, .rel[a].iplt, .igot and .igot.plt
for static executables. */
s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
return FALSE;
htab->iplt = s;
s = bfd_make_section_with_flags (abfd,
(bed->rela_plts_and_copies_p
? ".rela.iplt" : ".rel.iplt"),
flags | SEC_READONLY);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s,
bed->s->log_file_align))
return FALSE;
htab->irelplt = s;
/* We don't need the .igot section if we have the .igot.plt
section. */
if (bed->want_got_plt)
s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
else
s = bfd_make_section_with_flags (abfd, ".igot", flags);
if (s == NULL
|| !bfd_set_section_alignment (abfd, s,
bed->s->log_file_align))
return FALSE;
htab->igotplt = s;
}
return TRUE;
}

View File

@ -670,17 +670,8 @@ struct elf_i386_link_hash_table
struct elf_link_hash_table elf; struct elf_link_hash_table elf;
/* Short-cuts to get to dynamic linker sections. */ /* Short-cuts to get to dynamic linker sections. */
asection *sgot;
asection *sgotplt;
asection *srelgot;
asection *splt;
asection *srelplt;
asection *sdynbss; asection *sdynbss;
asection *srelbss; asection *srelbss;
asection *igotplt;
asection *iplt;
asection *irelplt;
asection *irelifunc;
/* The (unloaded but important) .rel.plt.unloaded section on VxWorks. */ /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. */
asection *srelplt2; asection *srelplt2;
@ -850,17 +841,8 @@ elf_i386_link_hash_table_create (bfd *abfd)
return NULL; return NULL;
} }
ret->sgot = NULL;
ret->sgotplt = NULL;
ret->srelgot = NULL;
ret->splt = NULL;
ret->srelplt = NULL;
ret->sdynbss = NULL; ret->sdynbss = NULL;
ret->srelbss = NULL; ret->srelbss = NULL;
ret->igotplt= NULL;
ret->iplt = NULL;
ret->irelplt= NULL;
ret->irelifunc = NULL;
ret->tls_ldm_got.refcount = 0; ret->tls_ldm_got.refcount = 0;
ret->next_tls_desc_index = 0; ret->next_tls_desc_index = 0;
ret->sgotplt_jump_table_size = 0; ret->sgotplt_jump_table_size = 0;
@ -899,35 +881,6 @@ elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash)
_bfd_generic_link_hash_table_free (hash); _bfd_generic_link_hash_table_free (hash);
} }
/* Create .got, .gotplt, and .rel.got sections in DYNOBJ, and set up
shortcuts to them in our hash table. */
static bfd_boolean
elf_i386_create_got_section (bfd *dynobj, struct bfd_link_info *info)
{
struct elf_i386_link_hash_table *htab;
if (! _bfd_elf_create_got_section (dynobj, info))
return FALSE;
htab = elf_i386_hash_table (info);
htab->sgot = bfd_get_section_by_name (dynobj, ".got");
htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
if (!htab->sgot || !htab->sgotplt)
abort ();
htab->srelgot = bfd_make_section_with_flags (dynobj, ".rel.got",
(SEC_ALLOC | SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY));
if (htab->srelgot == NULL
|| ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
return FALSE;
return TRUE;
}
/* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and
.rel.bss sections in DYNOBJ, and set up shortcuts to them in our .rel.bss sections in DYNOBJ, and set up shortcuts to them in our
hash table. */ hash table. */
@ -937,25 +890,21 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
{ {
struct elf_i386_link_hash_table *htab; struct elf_i386_link_hash_table *htab;
htab = elf_i386_hash_table (info);
if (!htab->sgot && !elf_i386_create_got_section (dynobj, info))
return FALSE;
if (!_bfd_elf_create_dynamic_sections (dynobj, info)) if (!_bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE; return FALSE;
htab->splt = bfd_get_section_by_name (dynobj, ".plt"); htab = elf_i386_hash_table (info);
htab->srelplt = bfd_get_section_by_name (dynobj, ".rel.plt");
htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
if (!info->shared) if (!info->shared)
htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss"); htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");
if (!htab->splt || !htab->srelplt || !htab->sdynbss if (!htab->sdynbss
|| (!info->shared && !htab->srelbss)) || (!info->shared && !htab->srelbss))
abort (); abort ();
if (htab->is_vxworks if (htab->is_vxworks
&& !elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2)) && !elf_vxworks_create_dynamic_sections (dynobj, info,
&htab->srelplt2))
return FALSE; return FALSE;
return TRUE; return TRUE;
@ -1427,31 +1376,8 @@ elf_i386_check_relocs (bfd *abfd,
case R_386_PLT32: case R_386_PLT32:
case R_386_GOT32: case R_386_GOT32:
case R_386_GOTOFF: case R_386_GOTOFF:
if (htab->irelifunc == NULL && htab->iplt == NULL) if (!_bfd_elf_create_ifunc_sections (abfd, info))
{ return FALSE;
if (!_bfd_elf_create_ifunc_sections (abfd, info))
return FALSE;
if (info->shared)
{
htab->irelifunc = bfd_get_section_by_name (abfd,
".rel.ifunc");
if (!htab->irelifunc)
abort ();
}
else
{
htab->iplt = bfd_get_section_by_name (abfd, ".iplt");
htab->irelplt = bfd_get_section_by_name (abfd,
".rel.iplt");
htab->igotplt = bfd_get_section_by_name (abfd,
".igot.plt");
if (!htab->iplt
|| !htab->irelplt
|| !htab->igotplt)
abort ();
}
}
break; break;
} }
@ -1534,8 +1460,8 @@ elf_i386_check_relocs (bfd *abfd,
case R_386_GOT32: case R_386_GOT32:
case R_386_GOTOFF: case R_386_GOTOFF:
h->got.refcount += 1; h->got.refcount += 1;
if (htab->sgot == NULL if (htab->elf.sgot == NULL
&& !elf_i386_create_got_section (htab->elf.dynobj, && !_bfd_elf_create_got_section (htab->elf.dynobj,
info)) info))
return FALSE; return FALSE;
break; break;
@ -1678,11 +1604,11 @@ elf_i386_check_relocs (bfd *abfd,
case R_386_GOTOFF: case R_386_GOTOFF:
case R_386_GOTPC: case R_386_GOTPC:
create_got: create_got:
if (htab->sgot == NULL) if (htab->elf.sgot == NULL)
{ {
if (htab->elf.dynobj == NULL) if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd; htab->elf.dynobj = abfd;
if (!elf_i386_create_got_section (htab->elf.dynobj, info)) if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
return FALSE; return FALSE;
} }
if (r_type != R_386_TLS_IE) if (r_type != R_386_TLS_IE)
@ -2175,11 +2101,11 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
/* When building a static executable, use .iplt, .igot.plt and /* When building a static executable, use .iplt, .igot.plt and
.rel.iplt sections for STT_GNU_IFUNC symbols. */ .rel.iplt sections for STT_GNU_IFUNC symbols. */
if (htab->splt != NULL) if (htab->elf.splt != NULL)
{ {
plt = htab->splt; plt = htab->elf.splt;
gotplt = htab->sgotplt; gotplt = htab->elf.sgotplt;
relplt = htab->srelplt; relplt = htab->elf.srelplt;
/* If this is the first .plt entry, make room for the special /* If this is the first .plt entry, make room for the special
first entry. */ first entry. */
@ -2188,9 +2114,9 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
} }
else else
{ {
plt = htab->iplt; plt = htab->elf.iplt;
gotplt = htab->igotplt; gotplt = htab->elf.igotplt;
relplt = htab->irelplt; relplt = htab->elf.irelplt;
} }
/* Don't update value of STT_GNU_IFUNC symbol to PLT. We need /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
@ -2218,7 +2144,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
/* Finally, allocate space. */ /* Finally, allocate space. */
for (p = eh->dyn_relocs; p != NULL; p = p->next) for (p = eh->dyn_relocs; p != NULL; p = p->next)
htab->irelifunc->size += p->count * sizeof (Elf32_External_Rel); htab->elf.irelifunc->size += p->count * sizeof (Elf32_External_Rel);
/* For STT_GNU_IFUNC symbol, .got.plt has the real function /* For STT_GNU_IFUNC symbol, .got.plt has the real function
addres and .got has the PLT entry adddress. We will load addres and .got has the PLT entry adddress. We will load
@ -2239,17 +2165,17 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|| (!info->shared || (!info->shared
&& !h->pointer_equality_needed) && !h->pointer_equality_needed)
|| (info->executable && info->shared) || (info->executable && info->shared)
|| htab->sgot == NULL) || htab->elf.sgot == NULL)
{ {
/* Use .got.plt. */ /* Use .got.plt. */
h->got.offset = (bfd_vma) -1; h->got.offset = (bfd_vma) -1;
} }
else else
{ {
h->got.offset = htab->sgot->size; h->got.offset = htab->elf.sgot->size;
htab->sgot->size += 4; htab->elf.sgot->size += 4;
if (info->shared) if (info->shared)
htab->srelgot->size += sizeof (Elf32_External_Rel); htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
} }
return TRUE; return TRUE;
@ -2269,7 +2195,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (info->shared if (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
{ {
asection *s = htab->splt; asection *s = htab->elf.splt;
/* If this is the first .plt entry, make room for the special /* If this is the first .plt entry, make room for the special
first entry. */ first entry. */
@ -2295,10 +2221,10 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
/* We also need to make an entry in the .got.plt section, which /* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */ will be placed in the .got section by the linker script. */
htab->sgotplt->size += 4; htab->elf.sgotplt->size += 4;
/* We also need to make an entry in the .rel.plt section. */ /* We also need to make an entry in the .rel.plt section. */
htab->srelplt->size += sizeof (Elf32_External_Rel); htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
htab->next_tls_desc_index++; htab->next_tls_desc_index++;
if (htab->is_vxworks && !info->shared) if (htab->is_vxworks && !info->shared)
@ -2357,12 +2283,12 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
return FALSE; return FALSE;
} }
s = htab->sgot; s = htab->elf.sgot;
if (GOT_TLS_GDESC_P (tls_type)) if (GOT_TLS_GDESC_P (tls_type))
{ {
eh->tlsdesc_got = htab->sgotplt->size eh->tlsdesc_got = htab->elf.sgotplt->size
- elf_i386_compute_jump_table_size (htab); - elf_i386_compute_jump_table_size (htab);
htab->sgotplt->size += 8; htab->elf.sgotplt->size += 8;
h->got.offset = (bfd_vma) -2; h->got.offset = (bfd_vma) -2;
} }
if (! GOT_TLS_GDESC_P (tls_type) if (! GOT_TLS_GDESC_P (tls_type)
@ -2381,20 +2307,20 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
need two), R_386_TLS_GD needs one if local symbol and two if need two), R_386_TLS_GD needs one if local symbol and two if
global. */ global. */
if (tls_type == GOT_TLS_IE_BOTH) if (tls_type == GOT_TLS_IE_BOTH)
htab->srelgot->size += 2 * sizeof (Elf32_External_Rel); htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1) else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
|| (tls_type & GOT_TLS_IE)) || (tls_type & GOT_TLS_IE))
htab->srelgot->size += sizeof (Elf32_External_Rel); htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
else if (GOT_TLS_GD_P (tls_type)) else if (GOT_TLS_GD_P (tls_type))
htab->srelgot->size += 2 * sizeof (Elf32_External_Rel); htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
else if (! GOT_TLS_GDESC_P (tls_type) else if (! GOT_TLS_GDESC_P (tls_type)
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak) || h->root.type != bfd_link_hash_undefweak)
&& (info->shared && (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
htab->srelgot->size += sizeof (Elf32_External_Rel); htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
if (GOT_TLS_GDESC_P (tls_type)) if (GOT_TLS_GDESC_P (tls_type))
htab->srelplt->size += sizeof (Elf32_External_Rel); htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
} }
else else
h->got.offset = (bfd_vma) -1; h->got.offset = (bfd_vma) -1;
@ -2644,8 +2570,8 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
end_local_got = local_got + locsymcount; end_local_got = local_got + locsymcount;
local_tls_type = elf_i386_local_got_tls_type (ibfd); local_tls_type = elf_i386_local_got_tls_type (ibfd);
local_tlsdesc_gotent = elf_i386_local_tlsdesc_gotent (ibfd); local_tlsdesc_gotent = elf_i386_local_tlsdesc_gotent (ibfd);
s = htab->sgot; s = htab->elf.sgot;
srel = htab->srelgot; srel = htab->elf.srelgot;
for (; local_got < end_local_got; for (; local_got < end_local_got;
++local_got, ++local_tls_type, ++local_tlsdesc_gotent) ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
{ {
@ -2654,9 +2580,9 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
{ {
if (GOT_TLS_GDESC_P (*local_tls_type)) if (GOT_TLS_GDESC_P (*local_tls_type))
{ {
*local_tlsdesc_gotent = htab->sgotplt->size *local_tlsdesc_gotent = htab->elf.sgotplt->size
- elf_i386_compute_jump_table_size (htab); - elf_i386_compute_jump_table_size (htab);
htab->sgotplt->size += 8; htab->elf.sgotplt->size += 8;
*local_got = (bfd_vma) -2; *local_got = (bfd_vma) -2;
} }
if (! GOT_TLS_GDESC_P (*local_tls_type) if (! GOT_TLS_GDESC_P (*local_tls_type)
@ -2678,7 +2604,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|| ! GOT_TLS_GDESC_P (*local_tls_type)) || ! GOT_TLS_GDESC_P (*local_tls_type))
srel->size += sizeof (Elf32_External_Rel); srel->size += sizeof (Elf32_External_Rel);
if (GOT_TLS_GDESC_P (*local_tls_type)) if (GOT_TLS_GDESC_P (*local_tls_type))
htab->srelplt->size += sizeof (Elf32_External_Rel); htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
} }
} }
else else
@ -2690,9 +2616,9 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
{ {
/* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
relocs. */ relocs. */
htab->tls_ldm_got.offset = htab->sgot->size; htab->tls_ldm_got.offset = htab->elf.sgot->size;
htab->sgot->size += 8; htab->elf.sgot->size += 8;
htab->srelgot->size += sizeof (Elf32_External_Rel); htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
} }
else else
htab->tls_ldm_got.offset = -1; htab->tls_ldm_got.offset = -1;
@ -2711,7 +2637,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
it's not incremented, so in order to compute the space reserved it's not incremented, so in order to compute the space reserved
for them, it suffices to multiply the reloc count by the jump for them, it suffices to multiply the reloc count by the jump
slot size. */ slot size. */
if (htab->srelplt) if (htab->elf.srelplt)
htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4; htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4;
/* We now have determined the sizes of the various dynamic sections. /* We now have determined the sizes of the various dynamic sections.
@ -2724,11 +2650,11 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if ((s->flags & SEC_LINKER_CREATED) == 0) if ((s->flags & SEC_LINKER_CREATED) == 0)
continue; continue;
if (s == htab->splt if (s == htab->elf.splt
|| s == htab->sgot || s == htab->elf.sgot
|| s == htab->sgotplt || s == htab->elf.sgotplt
|| s == htab->iplt || s == htab->elf.iplt
|| s == htab->igotplt || s == htab->elf.igotplt
|| s == htab->sdynbss) || s == htab->sdynbss)
{ {
/* Strip this section if we don't need it; see the /* Strip this section if we don't need it; see the
@ -2742,7 +2668,9 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
} }
else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel")) else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel"))
{ {
if (s->size != 0 && s != htab->srelplt && s != htab->srelplt2) if (s->size != 0
&& s != htab->elf.srelplt
&& s != htab->srelplt2)
relocs = TRUE; relocs = TRUE;
/* We use the reloc_count field as a counter if we need /* We use the reloc_count field as a counter if we need
@ -2800,7 +2728,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
return FALSE; return FALSE;
} }
if (htab->splt->size != 0) if (htab->elf.splt->size != 0)
{ {
if (!add_dynamic_entry (DT_PLTGOT, 0) if (!add_dynamic_entry (DT_PLTGOT, 0)
|| !add_dynamic_entry (DT_PLTRELSZ, 0) || !add_dynamic_entry (DT_PLTRELSZ, 0)
@ -3162,15 +3090,15 @@ elf_i386_relocate_section (bfd *output_bfd,
abort (); abort ();
/* STT_GNU_IFUNC symbol must go through PLT. */ /* STT_GNU_IFUNC symbol must go through PLT. */
if (htab->splt != NULL) if (htab->elf.splt != NULL)
{ {
plt = htab->splt; plt = htab->elf.splt;
gotplt = htab->sgotplt; gotplt = htab->elf.sgotplt;
} }
else else
{ {
plt = htab->iplt; plt = htab->elf.iplt;
gotplt = htab->igotplt; gotplt = htab->elf.igotplt;
} }
relocation = (plt->output_section->vma relocation = (plt->output_section->vma
@ -3228,7 +3156,7 @@ elf_i386_relocate_section (bfd *output_bfd,
else else
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
sreloc = htab->irelifunc; sreloc = htab->elf.irelifunc;
loc = sreloc->contents; loc = sreloc->contents;
loc += (sreloc->reloc_count++ loc += (sreloc->reloc_count++
* sizeof (Elf32_External_Rel)); * sizeof (Elf32_External_Rel));
@ -3247,7 +3175,7 @@ elf_i386_relocate_section (bfd *output_bfd,
goto do_relocation; goto do_relocation;
case R_386_GOT32: case R_386_GOT32:
base_got = htab->sgot; base_got = htab->elf.sgot;
off = h->got.offset; off = h->got.offset;
if (base_got == NULL) if (base_got == NULL)
@ -3259,17 +3187,17 @@ elf_i386_relocate_section (bfd *output_bfd,
even just remember the offset, as finish_dynamic_symbol even just remember the offset, as finish_dynamic_symbol
would use that as offset into .got. */ would use that as offset into .got. */
if (htab->splt != NULL) if (htab->elf.splt != NULL)
{ {
plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
off = (plt_index + 3) * 4; off = (plt_index + 3) * 4;
base_got = htab->sgotplt; base_got = htab->elf.sgotplt;
} }
else else
{ {
plt_index = h->plt.offset / PLT_ENTRY_SIZE; plt_index = h->plt.offset / PLT_ENTRY_SIZE;
off = plt_index * 4; off = plt_index * 4;
base_got = htab->igotplt; base_got = htab->elf.igotplt;
} }
if (h->dynindx == -1 if (h->dynindx == -1
@ -3298,7 +3226,7 @@ elf_i386_relocate_section (bfd *output_bfd,
relocation = off; relocation = off;
/* Adjust for static executables. */ /* Adjust for static executables. */
if (htab->splt == NULL) if (htab->elf.splt == NULL)
relocation += gotplt->output_offset; relocation += gotplt->output_offset;
} }
else else
@ -3308,7 +3236,7 @@ elf_i386_relocate_section (bfd *output_bfd,
- gotplt->output_section->vma - gotplt->output_section->vma
- gotplt->output_offset); - gotplt->output_offset);
/* Adjust for static executables. */ /* Adjust for static executables. */
if (htab->splt == NULL) if (htab->elf.splt == NULL)
relocation += gotplt->output_offset; relocation += gotplt->output_offset;
} }
@ -3326,7 +3254,7 @@ elf_i386_relocate_section (bfd *output_bfd,
case R_386_GOT32: case R_386_GOT32:
/* Relocation is to the entry for this symbol in the global /* Relocation is to the entry for this symbol in the global
offset table. */ offset table. */
if (htab->sgot == NULL) if (htab->elf.sgot == NULL)
abort (); abort ();
if (h != NULL) if (h != NULL)
@ -3358,7 +3286,7 @@ elf_i386_relocate_section (bfd *output_bfd,
else else
{ {
bfd_put_32 (output_bfd, relocation, bfd_put_32 (output_bfd, relocation,
htab->sgot->contents + off); htab->elf.sgot->contents + off);
h->got.offset |= 1; h->got.offset |= 1;
} }
} }
@ -3380,7 +3308,7 @@ elf_i386_relocate_section (bfd *output_bfd,
else else
{ {
bfd_put_32 (output_bfd, relocation, bfd_put_32 (output_bfd, relocation,
htab->sgot->contents + off); htab->elf.sgot->contents + off);
if (info->shared) if (info->shared)
{ {
@ -3388,12 +3316,12 @@ elf_i386_relocate_section (bfd *output_bfd,
Elf_Internal_Rela outrel; Elf_Internal_Rela outrel;
bfd_byte *loc; bfd_byte *loc;
s = htab->srelgot; s = htab->elf.srelgot;
if (s == NULL) if (s == NULL)
abort (); abort ();
outrel.r_offset = (htab->sgot->output_section->vma outrel.r_offset = (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + htab->elf.sgot->output_offset
+ off); + off);
outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
loc = s->contents; loc = s->contents;
@ -3408,10 +3336,10 @@ elf_i386_relocate_section (bfd *output_bfd,
if (off >= (bfd_vma) -2) if (off >= (bfd_vma) -2)
abort (); abort ();
relocation = htab->sgot->output_section->vma relocation = htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off + htab->elf.sgot->output_offset + off
- htab->sgotplt->output_section->vma - htab->elf.sgotplt->output_section->vma
- htab->sgotplt->output_offset; - htab->elf.sgotplt->output_offset;
break; break;
case R_386_GOTOFF: case R_386_GOTOFF:
@ -3467,14 +3395,14 @@ elf_i386_relocate_section (bfd *output_bfd,
defined _GLOBAL_OFFSET_TABLE_ in a different way, as is defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
permitted by the ABI, we might have to change this permitted by the ABI, we might have to change this
calculation. */ calculation. */
relocation -= htab->sgotplt->output_section->vma relocation -= htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset; + htab->elf.sgotplt->output_offset;
break; break;
case R_386_GOTPC: case R_386_GOTPC:
/* Use global offset table as symbol value. */ /* Use global offset table as symbol value. */
relocation = htab->sgotplt->output_section->vma relocation = htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset; + htab->elf.sgotplt->output_offset;
unresolved_reloc = FALSE; unresolved_reloc = FALSE;
break; break;
@ -3488,7 +3416,7 @@ elf_i386_relocate_section (bfd *output_bfd,
break; break;
if (h->plt.offset == (bfd_vma) -1 if (h->plt.offset == (bfd_vma) -1
|| htab->splt == NULL) || htab->elf.splt == NULL)
{ {
/* We didn't make a PLT entry for this symbol. This /* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when happens when statically linking PIC code, or when
@ -3496,8 +3424,8 @@ elf_i386_relocate_section (bfd *output_bfd,
break; break;
} }
relocation = (htab->splt->output_section->vma relocation = (htab->elf.splt->output_section->vma
+ htab->splt->output_offset + htab->elf.splt->output_offset
+ h->plt.offset); + h->plt.offset);
unresolved_reloc = FALSE; unresolved_reloc = FALSE;
break; break;
@ -3800,7 +3728,7 @@ elf_i386_relocate_section (bfd *output_bfd,
} }
} }
if (htab->sgot == NULL) if (htab->elf.sgot == NULL)
abort (); abort ();
if (h != NULL) if (h != NULL)
@ -3826,7 +3754,7 @@ elf_i386_relocate_section (bfd *output_bfd,
int dr_type, indx; int dr_type, indx;
asection *sreloc; asection *sreloc;
if (htab->srelgot == NULL) if (htab->elf.srelgot == NULL)
abort (); abort ();
indx = h && h->dynindx != -1 ? h->dynindx : 0; indx = h && h->dynindx != -1 ? h->dynindx : 0;
@ -3835,12 +3763,12 @@ elf_i386_relocate_section (bfd *output_bfd,
{ {
outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC); outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC);
BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8 BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8
<= htab->sgotplt->size); <= htab->elf.sgotplt->size);
outrel.r_offset = (htab->sgotplt->output_section->vma outrel.r_offset = (htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ offplt + offplt
+ htab->sgotplt_jump_table_size); + htab->sgotplt_jump_table_size);
sreloc = htab->srelplt; sreloc = htab->elf.srelplt;
loc = sreloc->contents; loc = sreloc->contents;
loc += (htab->next_tls_desc_index++ loc += (htab->next_tls_desc_index++
* sizeof (Elf32_External_Rel)); * sizeof (Elf32_External_Rel));
@ -3852,21 +3780,21 @@ elf_i386_relocate_section (bfd *output_bfd,
BFD_ASSERT (! unresolved_reloc); BFD_ASSERT (! unresolved_reloc);
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
relocation - elf_i386_dtpoff_base (info), relocation - elf_i386_dtpoff_base (info),
htab->sgotplt->contents + offplt htab->elf.sgotplt->contents + offplt
+ htab->sgotplt_jump_table_size + 4); + htab->sgotplt_jump_table_size + 4);
} }
else else
{ {
bfd_put_32 (output_bfd, 0, bfd_put_32 (output_bfd, 0,
htab->sgotplt->contents + offplt htab->elf.sgotplt->contents + offplt
+ htab->sgotplt_jump_table_size + 4); + htab->sgotplt_jump_table_size + 4);
} }
} }
sreloc = htab->srelgot; sreloc = htab->elf.srelgot;
outrel.r_offset = (htab->sgot->output_section->vma outrel.r_offset = (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off); + htab->elf.sgot->output_offset + off);
if (GOT_TLS_GD_P (tls_type)) if (GOT_TLS_GD_P (tls_type))
dr_type = R_386_TLS_DTPMOD32; dr_type = R_386_TLS_DTPMOD32;
@ -3880,14 +3808,14 @@ elf_i386_relocate_section (bfd *output_bfd,
if (dr_type == R_386_TLS_TPOFF && indx == 0) if (dr_type == R_386_TLS_TPOFF && indx == 0)
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
relocation - elf_i386_dtpoff_base (info), relocation - elf_i386_dtpoff_base (info),
htab->sgot->contents + off); htab->elf.sgot->contents + off);
else if (dr_type == R_386_TLS_TPOFF32 && indx == 0) else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
elf_i386_dtpoff_base (info) - relocation, elf_i386_dtpoff_base (info) - relocation,
htab->sgot->contents + off); htab->elf.sgot->contents + off);
else if (dr_type != R_386_TLS_DESC) else if (dr_type != R_386_TLS_DESC)
bfd_put_32 (output_bfd, 0, bfd_put_32 (output_bfd, 0,
htab->sgot->contents + off); htab->elf.sgot->contents + off);
outrel.r_info = ELF32_R_INFO (indx, dr_type); outrel.r_info = ELF32_R_INFO (indx, dr_type);
loc = sreloc->contents; loc = sreloc->contents;
@ -3903,12 +3831,12 @@ elf_i386_relocate_section (bfd *output_bfd,
BFD_ASSERT (! unresolved_reloc); BFD_ASSERT (! unresolved_reloc);
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
relocation - elf_i386_dtpoff_base (info), relocation - elf_i386_dtpoff_base (info),
htab->sgot->contents + off + 4); htab->elf.sgot->contents + off + 4);
} }
else else
{ {
bfd_put_32 (output_bfd, 0, bfd_put_32 (output_bfd, 0,
htab->sgot->contents + off + 4); htab->elf.sgot->contents + off + 4);
outrel.r_info = ELF32_R_INFO (indx, outrel.r_info = ELF32_R_INFO (indx,
R_386_TLS_DTPOFF32); R_386_TLS_DTPOFF32);
outrel.r_offset += 4; outrel.r_offset += 4;
@ -3925,7 +3853,7 @@ elf_i386_relocate_section (bfd *output_bfd,
(indx == 0 (indx == 0
? relocation - elf_i386_dtpoff_base (info) ? relocation - elf_i386_dtpoff_base (info)
: 0), : 0),
htab->sgot->contents + off + 4); htab->elf.sgot->contents + off + 4);
outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF); outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
outrel.r_offset += 4; outrel.r_offset += 4;
sreloc->reloc_count++; sreloc->reloc_count++;
@ -3951,10 +3879,10 @@ elf_i386_relocate_section (bfd *output_bfd,
} }
else if (r_type == ELF32_R_TYPE (rel->r_info)) else if (r_type == ELF32_R_TYPE (rel->r_info))
{ {
bfd_vma g_o_t = htab->sgotplt->output_section->vma bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset; + htab->elf.sgotplt->output_offset;
relocation = htab->sgot->output_section->vma relocation = htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off - g_o_t; + htab->elf.sgot->output_offset + off - g_o_t;
if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE) if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
&& tls_type == GOT_TLS_IE_BOTH) && tls_type == GOT_TLS_IE_BOTH)
relocation += 4; relocation += 4;
@ -3996,10 +3924,10 @@ elf_i386_relocate_section (bfd *output_bfd,
if (tls_type == GOT_TLS_IE_POS) if (tls_type == GOT_TLS_IE_POS)
contents[roff + 6] = 0x03; contents[roff + 6] = 0x03;
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
htab->sgot->output_section->vma htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off + htab->elf.sgot->output_offset + off
- htab->sgotplt->output_section->vma - htab->elf.sgotplt->output_section->vma
- htab->sgotplt->output_offset, - htab->elf.sgotplt->output_offset,
contents + roff + 8); contents + roff + 8);
/* Skip R_386_PLT32. */ /* Skip R_386_PLT32. */
rel++; rel++;
@ -4037,10 +3965,10 @@ elf_i386_relocate_section (bfd *output_bfd,
off += 4; off += 4;
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
htab->sgot->output_section->vma htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off + htab->elf.sgot->output_offset + off
- htab->sgotplt->output_section->vma - htab->elf.sgotplt->output_section->vma
- htab->sgotplt->output_offset, - htab->elf.sgotplt->output_offset,
contents + roff); contents + roff);
continue; continue;
} }
@ -4103,7 +4031,7 @@ elf_i386_relocate_section (bfd *output_bfd,
continue; continue;
} }
if (htab->sgot == NULL) if (htab->elf.sgot == NULL)
abort (); abort ();
off = htab->tls_ldm_got.offset; off = htab->tls_ldm_got.offset;
@ -4114,26 +4042,26 @@ elf_i386_relocate_section (bfd *output_bfd,
Elf_Internal_Rela outrel; Elf_Internal_Rela outrel;
bfd_byte *loc; bfd_byte *loc;
if (htab->srelgot == NULL) if (htab->elf.srelgot == NULL)
abort (); abort ();
outrel.r_offset = (htab->sgot->output_section->vma outrel.r_offset = (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off); + htab->elf.sgot->output_offset + off);
bfd_put_32 (output_bfd, 0, bfd_put_32 (output_bfd, 0,
htab->sgot->contents + off); htab->elf.sgot->contents + off);
bfd_put_32 (output_bfd, 0, bfd_put_32 (output_bfd, 0,
htab->sgot->contents + off + 4); htab->elf.sgot->contents + off + 4);
outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32); outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32);
loc = htab->srelgot->contents; loc = htab->elf.srelgot->contents;
loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rel); loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
htab->tls_ldm_got.offset |= 1; htab->tls_ldm_got.offset |= 1;
} }
relocation = htab->sgot->output_section->vma relocation = htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off + htab->elf.sgot->output_offset + off
- htab->sgotplt->output_section->vma - htab->elf.sgotplt->output_section->vma
- htab->sgotplt->output_offset; - htab->elf.sgotplt->output_offset;
unresolved_reloc = FALSE; unresolved_reloc = FALSE;
break; break;
@ -4272,17 +4200,17 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
/* When building a static executable, use .iplt, .igot.plt and /* When building a static executable, use .iplt, .igot.plt and
.rel.iplt sections for STT_GNU_IFUNC symbols. */ .rel.iplt sections for STT_GNU_IFUNC symbols. */
if (htab->splt != NULL) if (htab->elf.splt != NULL)
{ {
plt = htab->splt; plt = htab->elf.splt;
gotplt = htab->sgotplt; gotplt = htab->elf.sgotplt;
relplt = htab->srelplt; relplt = htab->elf.srelplt;
} }
else else
{ {
plt = htab->iplt; plt = htab->elf.iplt;
gotplt = htab->igotplt; gotplt = htab->elf.igotplt;
relplt = htab->irelplt; relplt = htab->elf.irelplt;
} }
/* This symbol has an entry in the procedure linkage table. Set /* This symbol has an entry in the procedure linkage table. Set
@ -4308,7 +4236,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
For static executables, we don't reserve anything. */ For static executables, we don't reserve anything. */
if (plt == htab->splt) if (plt == htab->elf.splt)
{ {
plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
got_offset = (plt_index + 3) * 4; got_offset = (plt_index + 3) * 4;
@ -4350,16 +4278,16 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
loc = (htab->srelplt2->contents + reloc_index loc = (htab->srelplt2->contents + reloc_index
* sizeof (Elf32_External_Rel)); * sizeof (Elf32_External_Rel));
rel.r_offset = (htab->splt->output_section->vma rel.r_offset = (htab->elf.splt->output_section->vma
+ htab->splt->output_offset + htab->elf.splt->output_offset
+ h->plt.offset + 2), + h->plt.offset + 2),
rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
/* Create the R_386_32 relocation referencing the beginning of /* Create the R_386_32 relocation referencing the beginning of
the PLT for this GOT entry. */ the PLT for this GOT entry. */
rel.r_offset = (htab->sgotplt->output_section->vma rel.r_offset = (htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ got_offset); + got_offset);
rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32); rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
bfd_elf32_swap_reloc_out (output_bfd, &rel, bfd_elf32_swap_reloc_out (output_bfd, &rel,
@ -4375,7 +4303,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
} }
/* Don't fill PLT entry for static executables. */ /* Don't fill PLT entry for static executables. */
if (plt == htab->splt) if (plt == htab->elf.splt)
{ {
bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
plt->contents + h->plt.offset + 7); plt->contents + h->plt.offset + 7);
@ -4442,11 +4370,11 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
/* This symbol has an entry in the global offset table. Set it /* This symbol has an entry in the global offset table. Set it
up. */ up. */
if (htab->sgot == NULL || htab->srelgot == NULL) if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
abort (); abort ();
rel.r_offset = (htab->sgot->output_section->vma rel.r_offset = (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + htab->elf.sgot->output_offset
+ (h->got.offset & ~(bfd_vma) 1)); + (h->got.offset & ~(bfd_vma) 1));
/* If this is a static link, or it is a -Bsymbolic link and the /* If this is a static link, or it is a -Bsymbolic link and the
@ -4470,11 +4398,11 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
/* For non-shared object, we can't use .got.plt, which /* For non-shared object, we can't use .got.plt, which
contains the real function addres if we need pointer contains the real function addres if we need pointer
equality. We load the GOT entry with the PLT entry. */ equality. We load the GOT entry with the PLT entry. */
asection *plt = htab->splt ? htab->splt : htab->iplt; asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
(plt->output_section->vma (plt->output_section->vma
+ plt->output_offset + h->plt.offset), + plt->output_offset + h->plt.offset),
htab->sgot->contents + h->got.offset); htab->elf.sgot->contents + h->got.offset);
return TRUE; return TRUE;
} }
} }
@ -4489,12 +4417,12 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
BFD_ASSERT((h->got.offset & 1) == 0); BFD_ASSERT((h->got.offset & 1) == 0);
do_glob_dat: do_glob_dat:
bfd_put_32 (output_bfd, (bfd_vma) 0, bfd_put_32 (output_bfd, (bfd_vma) 0,
htab->sgot->contents + h->got.offset); htab->elf.sgot->contents + h->got.offset);
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT); rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
} }
loc = htab->srelgot->contents; loc = htab->elf.srelgot->contents;
loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rel); loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
} }
@ -4585,7 +4513,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
{ {
Elf32_External_Dyn *dyncon, *dynconend; Elf32_External_Dyn *dyncon, *dynconend;
if (sdyn == NULL || htab->sgot == NULL) if (sdyn == NULL || htab->elf.sgot == NULL)
abort (); abort ();
dyncon = (Elf32_External_Dyn *) sdyn->contents; dyncon = (Elf32_External_Dyn *) sdyn->contents;
@ -4606,17 +4534,17 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
continue; continue;
case DT_PLTGOT: case DT_PLTGOT:
s = htab->sgotplt; s = htab->elf.sgotplt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
break; break;
case DT_JMPREL: case DT_JMPREL:
s = htab->srelplt; s = htab->elf.srelplt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
break; break;
case DT_PLTRELSZ: case DT_PLTRELSZ:
s = htab->srelplt; s = htab->elf.srelplt;
dyn.d_un.d_val = s->size; dyn.d_un.d_val = s->size;
break; break;
@ -4627,7 +4555,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
what Solaris does. However, UnixWare can not handle what Solaris does. However, UnixWare can not handle
that case. Therefore, we override the DT_RELSZ entry that case. Therefore, we override the DT_RELSZ entry
here to make it not include the JMPREL relocs. */ here to make it not include the JMPREL relocs. */
s = htab->srelplt; s = htab->elf.srelplt;
if (s == NULL) if (s == NULL)
continue; continue;
dyn.d_un.d_val -= s->size; dyn.d_un.d_val -= s->size;
@ -4637,7 +4565,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
/* We may not be using the standard ELF linker script. /* We may not be using the standard ELF linker script.
If .rel.plt is the first .rel section, we adjust If .rel.plt is the first .rel section, we adjust
DT_REL to not include it. */ DT_REL to not include it. */
s = htab->srelplt; s = htab->elf.srelplt;
if (s == NULL) if (s == NULL)
continue; continue;
if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset) if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
@ -4650,33 +4578,33 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
} }
/* Fill in the first entry in the procedure linkage table. */ /* Fill in the first entry in the procedure linkage table. */
if (htab->splt && htab->splt->size > 0) if (htab->elf.splt && htab->elf.splt->size > 0)
{ {
if (info->shared) if (info->shared)
{ {
memcpy (htab->splt->contents, elf_i386_pic_plt0_entry, memcpy (htab->elf.splt->contents, elf_i386_pic_plt0_entry,
sizeof (elf_i386_pic_plt0_entry)); sizeof (elf_i386_pic_plt0_entry));
memset (htab->splt->contents + sizeof (elf_i386_pic_plt0_entry), memset (htab->elf.splt->contents + sizeof (elf_i386_pic_plt0_entry),
htab->plt0_pad_byte, htab->plt0_pad_byte,
PLT_ENTRY_SIZE - sizeof (elf_i386_pic_plt0_entry)); PLT_ENTRY_SIZE - sizeof (elf_i386_pic_plt0_entry));
} }
else else
{ {
memcpy (htab->splt->contents, elf_i386_plt0_entry, memcpy (htab->elf.splt->contents, elf_i386_plt0_entry,
sizeof(elf_i386_plt0_entry)); sizeof(elf_i386_plt0_entry));
memset (htab->splt->contents + sizeof (elf_i386_plt0_entry), memset (htab->elf.splt->contents + sizeof (elf_i386_plt0_entry),
htab->plt0_pad_byte, htab->plt0_pad_byte,
PLT_ENTRY_SIZE - sizeof (elf_i386_plt0_entry)); PLT_ENTRY_SIZE - sizeof (elf_i386_plt0_entry));
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
(htab->sgotplt->output_section->vma (htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ 4), + 4),
htab->splt->contents + 2); htab->elf.splt->contents + 2);
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
(htab->sgotplt->output_section->vma (htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ 8), + 8),
htab->splt->contents + 8); htab->elf.splt->contents + 8);
if (htab->is_vxworks) if (htab->is_vxworks)
{ {
@ -4685,15 +4613,15 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
/* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4. /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.
On IA32 we use REL relocations so the addend goes in On IA32 we use REL relocations so the addend goes in
the PLT directly. */ the PLT directly. */
rel.r_offset = (htab->splt->output_section->vma rel.r_offset = (htab->elf.splt->output_section->vma
+ htab->splt->output_offset + htab->elf.splt->output_offset
+ 2); + 2);
rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
bfd_elf32_swap_reloc_out (output_bfd, &rel, bfd_elf32_swap_reloc_out (output_bfd, &rel,
htab->srelplt2->contents); htab->srelplt2->contents);
/* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8. */ /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8. */
rel.r_offset = (htab->splt->output_section->vma rel.r_offset = (htab->elf.splt->output_section->vma
+ htab->splt->output_offset + htab->elf.splt->output_offset
+ 8); + 8);
rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
bfd_elf32_swap_reloc_out (output_bfd, &rel, bfd_elf32_swap_reloc_out (output_bfd, &rel,
@ -4704,13 +4632,13 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
/* UnixWare sets the entsize of .plt to 4, although that doesn't /* UnixWare sets the entsize of .plt to 4, although that doesn't
really seem like the right value. */ really seem like the right value. */
elf_section_data (htab->splt->output_section) elf_section_data (htab->elf.splt->output_section)
->this_hdr.sh_entsize = 4; ->this_hdr.sh_entsize = 4;
/* Correct the .rel.plt.unloaded relocations. */ /* Correct the .rel.plt.unloaded relocations. */
if (htab->is_vxworks && !info->shared) if (htab->is_vxworks && !info->shared)
{ {
int num_plts = (htab->splt->size / PLT_ENTRY_SIZE) - 1; int num_plts = (htab->elf.splt->size / PLT_ENTRY_SIZE) - 1;
unsigned char *p; unsigned char *p;
p = htab->srelplt2->contents; p = htab->srelplt2->contents;
@ -4736,24 +4664,24 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
} }
} }
if (htab->sgotplt) if (htab->elf.sgotplt)
{ {
/* Fill in the first three entries in the global offset table. */ /* Fill in the first three entries in the global offset table. */
if (htab->sgotplt->size > 0) if (htab->elf.sgotplt->size > 0)
{ {
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
(sdyn == NULL ? 0 (sdyn == NULL ? 0
: sdyn->output_section->vma + sdyn->output_offset), : sdyn->output_section->vma + sdyn->output_offset),
htab->sgotplt->contents); htab->elf.sgotplt->contents);
bfd_put_32 (output_bfd, 0, htab->sgotplt->contents + 4); bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 4);
bfd_put_32 (output_bfd, 0, htab->sgotplt->contents + 8); bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 8);
} }
elf_section_data (htab->sgotplt->output_section)->this_hdr.sh_entsize = 4; elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = 4;
} }
if (htab->sgot && htab->sgot->size > 0) if (htab->elf.sgot && htab->elf.sgot->size > 0)
elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4; elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
/* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
htab_traverse (htab->loc_hash_table, htab_traverse (htab->loc_hash_table,

View File

@ -488,17 +488,8 @@ struct elf64_x86_64_link_hash_table
struct elf_link_hash_table elf; struct elf_link_hash_table elf;
/* Short-cuts to get to dynamic linker sections. */ /* Short-cuts to get to dynamic linker sections. */
asection *sgot;
asection *sgotplt;
asection *srelgot;
asection *splt;
asection *srelplt;
asection *sdynbss; asection *sdynbss;
asection *srelbss; asection *srelbss;
asection *igotplt;
asection *iplt;
asection *irelplt;
asection *irelifunc;
/* The offset into splt of the PLT entry for the TLS descriptor /* The offset into splt of the PLT entry for the TLS descriptor
resolver. Special values are 0, if not necessary (or not found resolver. Special values are 0, if not necessary (or not found
@ -534,7 +525,7 @@ struct elf64_x86_64_link_hash_table
((struct elf64_x86_64_link_hash_table *) ((p)->hash)) ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
#define elf64_x86_64_compute_jump_table_size(htab) \ #define elf64_x86_64_compute_jump_table_size(htab) \
((htab)->srelplt->reloc_count * GOT_ENTRY_SIZE) ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
/* Create an entry in an x86-64 ELF linker hash table. */ /* Create an entry in an x86-64 ELF linker hash table. */
@ -664,17 +655,8 @@ elf64_x86_64_link_hash_table_create (bfd *abfd)
return NULL; return NULL;
} }
ret->sgot = NULL;
ret->sgotplt = NULL;
ret->srelgot = NULL;
ret->splt = NULL;
ret->srelplt = NULL;
ret->sdynbss = NULL; ret->sdynbss = NULL;
ret->srelbss = NULL; ret->srelbss = NULL;
ret->igotplt= NULL;
ret->iplt = NULL;
ret->irelplt= NULL;
ret->irelifunc = NULL;
ret->sym_sec.abfd = NULL; ret->sym_sec.abfd = NULL;
ret->tlsdesc_plt = 0; ret->tlsdesc_plt = 0;
ret->tlsdesc_got = 0; ret->tlsdesc_got = 0;
@ -711,35 +693,6 @@ elf64_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash)
_bfd_generic_link_hash_table_free (hash); _bfd_generic_link_hash_table_free (hash);
} }
/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
shortcuts to them in our hash table. */
static bfd_boolean
elf64_x86_64_create_got_section (bfd *dynobj, struct bfd_link_info *info)
{
struct elf64_x86_64_link_hash_table *htab;
if (! _bfd_elf_create_got_section (dynobj, info))
return FALSE;
htab = elf64_x86_64_hash_table (info);
htab->sgot = bfd_get_section_by_name (dynobj, ".got");
htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
if (!htab->sgot || !htab->sgotplt)
abort ();
htab->srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
(SEC_ALLOC | SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY));
if (htab->srelgot == NULL
|| ! bfd_set_section_alignment (dynobj, htab->srelgot, 3))
return FALSE;
return TRUE;
}
/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
.rela.bss sections in DYNOBJ, and set up shortcuts to them in our .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
hash table. */ hash table. */
@ -749,20 +702,15 @@ elf64_x86_64_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
{ {
struct elf64_x86_64_link_hash_table *htab; struct elf64_x86_64_link_hash_table *htab;
htab = elf64_x86_64_hash_table (info);
if (!htab->sgot && !elf64_x86_64_create_got_section (dynobj, info))
return FALSE;
if (!_bfd_elf_create_dynamic_sections (dynobj, info)) if (!_bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE; return FALSE;
htab->splt = bfd_get_section_by_name (dynobj, ".plt"); htab = elf64_x86_64_hash_table (info);
htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
if (!info->shared) if (!info->shared)
htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss"); htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
if (!htab->splt || !htab->srelplt || !htab->sdynbss if (!htab->sdynbss
|| (!info->shared && !htab->srelbss)) || (!info->shared && !htab->srelbss))
abort (); abort ();
@ -1213,31 +1161,8 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_X86_64_PLT32: case R_X86_64_PLT32:
case R_X86_64_GOTPCREL: case R_X86_64_GOTPCREL:
case R_X86_64_GOTPCREL64: case R_X86_64_GOTPCREL64:
if (htab->irelifunc == NULL && htab->iplt == NULL) if (!_bfd_elf_create_ifunc_sections (abfd, info))
{ return FALSE;
if (!_bfd_elf_create_ifunc_sections (abfd, info))
return FALSE;
if (info->shared)
{
htab->irelifunc = bfd_get_section_by_name (abfd,
".rela.ifunc");
if (!htab->irelifunc)
abort ();
}
else
{
htab->iplt = bfd_get_section_by_name (abfd, ".iplt");
htab->irelplt = bfd_get_section_by_name (abfd,
".rela.iplt");
htab->igotplt = bfd_get_section_by_name (abfd,
".igot.plt");
if (!htab->iplt
|| !htab->irelplt
|| !htab->igotplt)
abort ();
}
}
break; break;
} }
@ -1328,9 +1253,9 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_X86_64_GOTPCREL: case R_X86_64_GOTPCREL:
case R_X86_64_GOTPCREL64: case R_X86_64_GOTPCREL64:
h->got.refcount += 1; h->got.refcount += 1;
if (htab->sgot == NULL if (htab->elf.sgot == NULL
&& !elf64_x86_64_create_got_section (htab->elf.dynobj, && !_bfd_elf_create_got_section (htab->elf.dynobj,
info)) info))
return FALSE; return FALSE;
break; break;
} }
@ -1466,12 +1391,12 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_X86_64_GOTPC32: case R_X86_64_GOTPC32:
case R_X86_64_GOTPC64: case R_X86_64_GOTPC64:
create_got: create_got:
if (htab->sgot == NULL) if (htab->elf.sgot == NULL)
{ {
if (htab->elf.dynobj == NULL) if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd; htab->elf.dynobj = abfd;
if (!elf64_x86_64_create_got_section (htab->elf.dynobj, if (!_bfd_elf_create_got_section (htab->elf.dynobj,
info)) info))
return FALSE; return FALSE;
} }
break; break;
@ -2017,11 +1942,11 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
/* When building a static executable, use .iplt, .igot.plt and /* When building a static executable, use .iplt, .igot.plt and
.rela.iplt sections for STT_GNU_IFUNC symbols. */ .rela.iplt sections for STT_GNU_IFUNC symbols. */
if (htab->splt != NULL) if (htab->elf.splt != NULL)
{ {
plt = htab->splt; plt = htab->elf.splt;
gotplt = htab->sgotplt; gotplt = htab->elf.sgotplt;
relplt = htab->srelplt; relplt = htab->elf.srelplt;
/* If this is the first .plt entry, make room for the special /* If this is the first .plt entry, make room for the special
first entry. */ first entry. */
@ -2030,9 +1955,9 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
} }
else else
{ {
plt = htab->iplt; plt = htab->elf.iplt;
gotplt = htab->igotplt; gotplt = htab->elf.igotplt;
relplt = htab->irelplt; relplt = htab->elf.irelplt;
} }
/* Don't update value of STT_GNU_IFUNC symbol to PLT. We need /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
@ -2060,7 +1985,8 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
/* Finally, allocate space. */ /* Finally, allocate space. */
for (p = eh->dyn_relocs; p != NULL; p = p->next) for (p = eh->dyn_relocs; p != NULL; p = p->next)
htab->irelifunc->size += p->count * sizeof (Elf64_External_Rela); htab->elf.irelifunc->size
+= p->count * sizeof (Elf64_External_Rela);
/* For STT_GNU_IFUNC symbol, .got.plt has the real function /* For STT_GNU_IFUNC symbol, .got.plt has the real function
addres and .got has the PLT entry adddress. We will load addres and .got has the PLT entry adddress. We will load
@ -2081,17 +2007,17 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|| (!info->shared || (!info->shared
&& !h->pointer_equality_needed) && !h->pointer_equality_needed)
|| (info->executable && info->shared) || (info->executable && info->shared)
|| htab->sgot == NULL) || htab->elf.sgot == NULL)
{ {
/* Use .got.plt. */ /* Use .got.plt. */
h->got.offset = (bfd_vma) -1; h->got.offset = (bfd_vma) -1;
} }
else else
{ {
h->got.offset = htab->sgot->size; h->got.offset = htab->elf.sgot->size;
htab->sgot->size += GOT_ENTRY_SIZE; htab->elf.sgot->size += GOT_ENTRY_SIZE;
if (info->shared) if (info->shared)
htab->srelgot->size += sizeof (Elf64_External_Rela); htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
} }
return TRUE; return TRUE;
@ -2111,7 +2037,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
if (info->shared if (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
{ {
asection *s = htab->splt; asection *s = htab->elf.splt;
/* If this is the first .plt entry, make room for the special /* If this is the first .plt entry, make room for the special
first entry. */ first entry. */
@ -2137,11 +2063,11 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
/* We also need to make an entry in the .got.plt section, which /* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */ will be placed in the .got section by the linker script. */
htab->sgotplt->size += GOT_ENTRY_SIZE; htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
/* We also need to make an entry in the .rela.plt section. */ /* We also need to make an entry in the .rela.plt section. */
htab->srelplt->size += sizeof (Elf64_External_Rela); htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
htab->srelplt->reloc_count++; htab->elf.srelplt->reloc_count++;
} }
else else
{ {
@ -2183,15 +2109,15 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
if (GOT_TLS_GDESC_P (tls_type)) if (GOT_TLS_GDESC_P (tls_type))
{ {
eh->tlsdesc_got = htab->sgotplt->size eh->tlsdesc_got = htab->elf.sgotplt->size
- elf64_x86_64_compute_jump_table_size (htab); - elf64_x86_64_compute_jump_table_size (htab);
htab->sgotplt->size += 2 * GOT_ENTRY_SIZE; htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
h->got.offset = (bfd_vma) -2; h->got.offset = (bfd_vma) -2;
} }
if (! GOT_TLS_GDESC_P (tls_type) if (! GOT_TLS_GDESC_P (tls_type)
|| GOT_TLS_GD_P (tls_type)) || GOT_TLS_GD_P (tls_type))
{ {
s = htab->sgot; s = htab->elf.sgot;
h->got.offset = s->size; h->got.offset = s->size;
s->size += GOT_ENTRY_SIZE; s->size += GOT_ENTRY_SIZE;
if (GOT_TLS_GD_P (tls_type)) if (GOT_TLS_GD_P (tls_type))
@ -2203,18 +2129,18 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
R_X86_64_GOTTPOFF needs one dynamic relocation. */ R_X86_64_GOTTPOFF needs one dynamic relocation. */
if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1) if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
|| tls_type == GOT_TLS_IE) || tls_type == GOT_TLS_IE)
htab->srelgot->size += sizeof (Elf64_External_Rela); htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
else if (GOT_TLS_GD_P (tls_type)) else if (GOT_TLS_GD_P (tls_type))
htab->srelgot->size += 2 * sizeof (Elf64_External_Rela); htab->elf.srelgot->size += 2 * sizeof (Elf64_External_Rela);
else if (! GOT_TLS_GDESC_P (tls_type) else if (! GOT_TLS_GDESC_P (tls_type)
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak) || h->root.type != bfd_link_hash_undefweak)
&& (info->shared && (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
htab->srelgot->size += sizeof (Elf64_External_Rela); htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
if (GOT_TLS_GDESC_P (tls_type)) if (GOT_TLS_GDESC_P (tls_type))
{ {
htab->srelplt->size += sizeof (Elf64_External_Rela); htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
htab->tlsdesc_plt = (bfd_vma) -1; htab->tlsdesc_plt = (bfd_vma) -1;
} }
} }
@ -2445,8 +2371,8 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
end_local_got = local_got + locsymcount; end_local_got = local_got + locsymcount;
local_tls_type = elf64_x86_64_local_got_tls_type (ibfd); local_tls_type = elf64_x86_64_local_got_tls_type (ibfd);
local_tlsdesc_gotent = elf64_x86_64_local_tlsdesc_gotent (ibfd); local_tlsdesc_gotent = elf64_x86_64_local_tlsdesc_gotent (ibfd);
s = htab->sgot; s = htab->elf.sgot;
srel = htab->srelgot; srel = htab->elf.srelgot;
for (; local_got < end_local_got; for (; local_got < end_local_got;
++local_got, ++local_tls_type, ++local_tlsdesc_gotent) ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
{ {
@ -2455,9 +2381,9 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
{ {
if (GOT_TLS_GDESC_P (*local_tls_type)) if (GOT_TLS_GDESC_P (*local_tls_type))
{ {
*local_tlsdesc_gotent = htab->sgotplt->size *local_tlsdesc_gotent = htab->elf.sgotplt->size
- elf64_x86_64_compute_jump_table_size (htab); - elf64_x86_64_compute_jump_table_size (htab);
htab->sgotplt->size += 2 * GOT_ENTRY_SIZE; htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
*local_got = (bfd_vma) -2; *local_got = (bfd_vma) -2;
} }
if (! GOT_TLS_GDESC_P (*local_tls_type) if (! GOT_TLS_GDESC_P (*local_tls_type)
@ -2474,7 +2400,8 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
{ {
if (GOT_TLS_GDESC_P (*local_tls_type)) if (GOT_TLS_GDESC_P (*local_tls_type))
{ {
htab->srelplt->size += sizeof (Elf64_External_Rela); htab->elf.srelplt->size
+= sizeof (Elf64_External_Rela);
htab->tlsdesc_plt = (bfd_vma) -1; htab->tlsdesc_plt = (bfd_vma) -1;
} }
if (! GOT_TLS_GDESC_P (*local_tls_type) if (! GOT_TLS_GDESC_P (*local_tls_type)
@ -2491,9 +2418,9 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
{ {
/* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
relocs. */ relocs. */
htab->tls_ld_got.offset = htab->sgot->size; htab->tls_ld_got.offset = htab->elf.sgot->size;
htab->sgot->size += 2 * GOT_ENTRY_SIZE; htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
htab->srelgot->size += sizeof (Elf64_External_Rela); htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
} }
else else
htab->tls_ld_got.offset = -1; htab->tls_ld_got.offset = -1;
@ -2513,7 +2440,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
it's not incremented, so in order to compute the space reserved it's not incremented, so in order to compute the space reserved
for them, it suffices to multiply the reloc count by the jump for them, it suffices to multiply the reloc count by the jump
slot size. */ slot size. */
if (htab->srelplt) if (htab->elf.srelplt)
htab->sgotplt_jump_table_size htab->sgotplt_jump_table_size
= elf64_x86_64_compute_jump_table_size (htab); = elf64_x86_64_compute_jump_table_size (htab);
@ -2525,14 +2452,14 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
htab->tlsdesc_plt = 0; htab->tlsdesc_plt = 0;
else else
{ {
htab->tlsdesc_got = htab->sgot->size; htab->tlsdesc_got = htab->elf.sgot->size;
htab->sgot->size += GOT_ENTRY_SIZE; htab->elf.sgot->size += GOT_ENTRY_SIZE;
/* Reserve room for the initial entry. /* Reserve room for the initial entry.
FIXME: we could probably do away with it in this case. */ FIXME: we could probably do away with it in this case. */
if (htab->splt->size == 0) if (htab->elf.splt->size == 0)
htab->splt->size += PLT_ENTRY_SIZE; htab->elf.splt->size += PLT_ENTRY_SIZE;
htab->tlsdesc_plt = htab->splt->size; htab->tlsdesc_plt = htab->elf.splt->size;
htab->splt->size += PLT_ENTRY_SIZE; htab->elf.splt->size += PLT_ENTRY_SIZE;
} }
} }
@ -2544,11 +2471,11 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if ((s->flags & SEC_LINKER_CREATED) == 0) if ((s->flags & SEC_LINKER_CREATED) == 0)
continue; continue;
if (s == htab->splt if (s == htab->elf.splt
|| s == htab->sgot || s == htab->elf.sgot
|| s == htab->sgotplt || s == htab->elf.sgotplt
|| s == htab->iplt || s == htab->elf.iplt
|| s == htab->igotplt || s == htab->elf.igotplt
|| s == htab->sdynbss) || s == htab->sdynbss)
{ {
/* Strip this section if we don't need it; see the /* Strip this section if we don't need it; see the
@ -2556,12 +2483,12 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
} }
else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela")) else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
{ {
if (s->size != 0 && s != htab->srelplt) if (s->size != 0 && s != htab->elf.srelplt)
relocs = TRUE; relocs = TRUE;
/* We use the reloc_count field as a counter if we need /* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */ to copy relocs into the output file. */
if (s != htab->srelplt) if (s != htab->elf.srelplt)
s->reloc_count = 0; s->reloc_count = 0;
} }
else else
@ -2615,7 +2542,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
return FALSE; return FALSE;
} }
if (htab->splt->size != 0) if (htab->elf.splt->size != 0)
{ {
if (!add_dynamic_entry (DT_PLTGOT, 0) if (!add_dynamic_entry (DT_PLTGOT, 0)
|| !add_dynamic_entry (DT_PLTRELSZ, 0) || !add_dynamic_entry (DT_PLTRELSZ, 0)
@ -2879,7 +2806,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
abort (); abort ();
/* STT_GNU_IFUNC symbol must go through PLT. */ /* STT_GNU_IFUNC symbol must go through PLT. */
plt = htab->splt ? htab->splt : htab->iplt; plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
relocation = (plt->output_section->vma relocation = (plt->output_section->vma
+ plt->output_offset + h->plt.offset); + plt->output_offset + h->plt.offset);
@ -2952,7 +2879,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
outrel.r_addend = 0; outrel.r_addend = 0;
} }
sreloc = htab->irelifunc; sreloc = htab->elf.irelifunc;
loc = sreloc->contents; loc = sreloc->contents;
loc += (sreloc->reloc_count++ loc += (sreloc->reloc_count++
* sizeof (Elf64_External_Rela)); * sizeof (Elf64_External_Rela));
@ -2974,7 +2901,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_X86_64_GOTPCREL: case R_X86_64_GOTPCREL:
case R_X86_64_GOTPCREL64: case R_X86_64_GOTPCREL64:
base_got = htab->sgot; base_got = htab->elf.sgot;
off = h->got.offset; off = h->got.offset;
if (base_got == NULL) if (base_got == NULL)
@ -2986,17 +2913,17 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
even just remember the offset, as finish_dynamic_symbol even just remember the offset, as finish_dynamic_symbol
would use that as offset into .got. */ would use that as offset into .got. */
if (htab->splt != NULL) if (htab->elf.splt != NULL)
{ {
plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
off = (plt_index + 3) * GOT_ENTRY_SIZE; off = (plt_index + 3) * GOT_ENTRY_SIZE;
base_got = htab->sgotplt; base_got = htab->elf.sgotplt;
} }
else else
{ {
plt_index = h->plt.offset / PLT_ENTRY_SIZE; plt_index = h->plt.offset / PLT_ENTRY_SIZE;
off = plt_index * GOT_ENTRY_SIZE; off = plt_index * GOT_ENTRY_SIZE;
base_got = htab->igotplt; base_got = htab->elf.igotplt;
} }
if (h->dynindx == -1 if (h->dynindx == -1
@ -3032,10 +2959,10 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
&& r_type != R_X86_64_GOTPCREL64) && r_type != R_X86_64_GOTPCREL64)
{ {
asection *gotplt; asection *gotplt;
if (htab->splt != NULL) if (htab->elf.splt != NULL)
gotplt = htab->sgotplt; gotplt = htab->elf.sgotplt;
else else
gotplt = htab->igotplt; gotplt = htab->elf.igotplt;
relocation -= (gotplt->output_section->vma relocation -= (gotplt->output_section->vma
- gotplt->output_offset); - gotplt->output_offset);
} }
@ -3062,9 +2989,9 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
offset, if this symbol got a PLT entry (it was global). offset, if this symbol got a PLT entry (it was global).
Additionally if it's computed from the PLT entry, then that Additionally if it's computed from the PLT entry, then that
GOT offset is relative to .got.plt, not to .got. */ GOT offset is relative to .got.plt, not to .got. */
base_got = htab->sgot; base_got = htab->elf.sgot;
if (htab->sgot == NULL) if (htab->elf.sgot == NULL)
abort (); abort ();
if (h != NULL) if (h != NULL)
@ -3082,7 +3009,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
.got. */ .got. */
bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
off = (plt_index + 3) * GOT_ENTRY_SIZE; off = (plt_index + 3) * GOT_ENTRY_SIZE;
base_got = htab->sgotplt; base_got = htab->elf.sgotplt;
} }
dyn = htab->elf.dynamic_sections_created; dyn = htab->elf.dynamic_sections_created;
@ -3143,7 +3070,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* We need to generate a R_X86_64_RELATIVE reloc /* We need to generate a R_X86_64_RELATIVE reloc
for the dynamic linker. */ for the dynamic linker. */
s = htab->srelgot; s = htab->elf.srelgot;
if (s == NULL) if (s == NULL)
abort (); abort ();
@ -3167,8 +3094,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
relocation = base_got->output_section->vma relocation = base_got->output_section->vma
+ base_got->output_offset + off; + base_got->output_offset + off;
if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64) if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64)
relocation -= htab->sgotplt->output_section->vma relocation -= htab->elf.sgotplt->output_section->vma
- htab->sgotplt->output_offset; - htab->elf.sgotplt->output_offset;
break; break;
@ -3197,15 +3124,15 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
defined _GLOBAL_OFFSET_TABLE_ in a different way, as is defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
permitted by the ABI, we might have to change this permitted by the ABI, we might have to change this
calculation. */ calculation. */
relocation -= htab->sgotplt->output_section->vma relocation -= htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset; + htab->elf.sgotplt->output_offset;
break; break;
case R_X86_64_GOTPC32: case R_X86_64_GOTPC32:
case R_X86_64_GOTPC64: case R_X86_64_GOTPC64:
/* Use global offset table as symbol value. */ /* Use global offset table as symbol value. */
relocation = htab->sgotplt->output_section->vma relocation = htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset; + htab->elf.sgotplt->output_offset;
unresolved_reloc = FALSE; unresolved_reloc = FALSE;
break; break;
@ -3215,16 +3142,16 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (h != NULL if (h != NULL
/* See PLT32 handling. */ /* See PLT32 handling. */
&& h->plt.offset != (bfd_vma) -1 && h->plt.offset != (bfd_vma) -1
&& htab->splt != NULL) && htab->elf.splt != NULL)
{ {
relocation = (htab->splt->output_section->vma relocation = (htab->elf.splt->output_section->vma
+ htab->splt->output_offset + htab->elf.splt->output_offset
+ h->plt.offset); + h->plt.offset);
unresolved_reloc = FALSE; unresolved_reloc = FALSE;
} }
relocation -= htab->sgotplt->output_section->vma relocation -= htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset; + htab->elf.sgotplt->output_offset;
break; break;
case R_X86_64_PLT32: case R_X86_64_PLT32:
@ -3237,7 +3164,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
break; break;
if (h->plt.offset == (bfd_vma) -1 if (h->plt.offset == (bfd_vma) -1
|| htab->splt == NULL) || htab->elf.splt == NULL)
{ {
/* We didn't make a PLT entry for this symbol. This /* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when happens when statically linking PIC code, or when
@ -3245,8 +3172,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
break; break;
} }
relocation = (htab->splt->output_section->vma relocation = (htab->elf.splt->output_section->vma
+ htab->splt->output_offset + htab->elf.splt->output_offset
+ h->plt.offset); + h->plt.offset);
unresolved_reloc = FALSE; unresolved_reloc = FALSE;
break; break;
@ -3578,7 +3505,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (FALSE); BFD_ASSERT (FALSE);
} }
if (htab->sgot == NULL) if (htab->elf.sgot == NULL)
abort (); abort ();
if (h != NULL) if (h != NULL)
@ -3604,7 +3531,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
int dr_type, indx; int dr_type, indx;
asection *sreloc; asection *sreloc;
if (htab->srelgot == NULL) if (htab->elf.srelgot == NULL)
abort (); abort ();
indx = h && h->dynindx != -1 ? h->dynindx : 0; indx = h && h->dynindx != -1 ? h->dynindx : 0;
@ -3613,12 +3540,12 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{ {
outrel.r_info = ELF64_R_INFO (indx, R_X86_64_TLSDESC); outrel.r_info = ELF64_R_INFO (indx, R_X86_64_TLSDESC);
BFD_ASSERT (htab->sgotplt_jump_table_size + offplt BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
+ 2 * GOT_ENTRY_SIZE <= htab->sgotplt->size); + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
outrel.r_offset = (htab->sgotplt->output_section->vma outrel.r_offset = (htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ offplt + offplt
+ htab->sgotplt_jump_table_size); + htab->sgotplt_jump_table_size);
sreloc = htab->srelplt; sreloc = htab->elf.srelplt;
loc = sreloc->contents; loc = sreloc->contents;
loc += sreloc->reloc_count++ loc += sreloc->reloc_count++
* sizeof (Elf64_External_Rela); * sizeof (Elf64_External_Rela);
@ -3631,10 +3558,10 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
} }
sreloc = htab->srelgot; sreloc = htab->elf.srelgot;
outrel.r_offset = (htab->sgot->output_section->vma outrel.r_offset = (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off); + htab->elf.sgot->output_offset + off);
if (GOT_TLS_GD_P (tls_type)) if (GOT_TLS_GD_P (tls_type))
dr_type = R_X86_64_DTPMOD64; dr_type = R_X86_64_DTPMOD64;
@ -3643,7 +3570,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
else else
dr_type = R_X86_64_TPOFF64; dr_type = R_X86_64_TPOFF64;
bfd_put_64 (output_bfd, 0, htab->sgot->contents + off); bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off);
outrel.r_addend = 0; outrel.r_addend = 0;
if ((dr_type == R_X86_64_TPOFF64 if ((dr_type == R_X86_64_TPOFF64
|| dr_type == R_X86_64_TLSDESC) && indx == 0) || dr_type == R_X86_64_TLSDESC) && indx == 0)
@ -3663,12 +3590,12 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (! unresolved_reloc); BFD_ASSERT (! unresolved_reloc);
bfd_put_64 (output_bfd, bfd_put_64 (output_bfd,
relocation - elf64_x86_64_dtpoff_base (info), relocation - elf64_x86_64_dtpoff_base (info),
htab->sgot->contents + off + GOT_ENTRY_SIZE); htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
} }
else else
{ {
bfd_put_64 (output_bfd, 0, bfd_put_64 (output_bfd, 0,
htab->sgot->contents + off + GOT_ENTRY_SIZE); htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
outrel.r_info = ELF64_R_INFO (indx, outrel.r_info = ELF64_R_INFO (indx,
R_X86_64_DTPOFF64); R_X86_64_DTPOFF64);
outrel.r_offset += GOT_ENTRY_SIZE; outrel.r_offset += GOT_ENTRY_SIZE;
@ -3694,12 +3621,12 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{ {
if (r_type == R_X86_64_GOTPC32_TLSDESC if (r_type == R_X86_64_GOTPC32_TLSDESC
|| r_type == R_X86_64_TLSDESC_CALL) || r_type == R_X86_64_TLSDESC_CALL)
relocation = htab->sgotplt->output_section->vma relocation = htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ offplt + htab->sgotplt_jump_table_size; + offplt + htab->sgotplt_jump_table_size;
else else
relocation = htab->sgot->output_section->vma relocation = htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off; + htab->elf.sgot->output_offset + off;
unresolved_reloc = FALSE; unresolved_reloc = FALSE;
} }
else else
@ -3718,8 +3645,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0", "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
16); 16);
relocation = (htab->sgot->output_section->vma relocation = (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off + htab->elf.sgot->output_offset + off
- roff - roff
- input_section->output_section->vma - input_section->output_section->vma
- input_section->output_offset - input_section->output_offset
@ -3753,8 +3680,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_put_8 (output_bfd, 0x8b, contents + roff - 2); bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
htab->sgot->output_section->vma htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off + htab->elf.sgot->output_offset + off
- rel->r_offset - rel->r_offset
- input_section->output_section->vma - input_section->output_section->vma
- input_section->output_offset - input_section->output_offset
@ -3807,7 +3734,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
continue; continue;
} }
if (htab->sgot == NULL) if (htab->elf.sgot == NULL)
abort (); abort ();
off = htab->tls_ld_got.offset; off = htab->tls_ld_got.offset;
@ -3818,25 +3745,25 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
Elf_Internal_Rela outrel; Elf_Internal_Rela outrel;
bfd_byte *loc; bfd_byte *loc;
if (htab->srelgot == NULL) if (htab->elf.srelgot == NULL)
abort (); abort ();
outrel.r_offset = (htab->sgot->output_section->vma outrel.r_offset = (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off); + htab->elf.sgot->output_offset + off);
bfd_put_64 (output_bfd, 0, bfd_put_64 (output_bfd, 0,
htab->sgot->contents + off); htab->elf.sgot->contents + off);
bfd_put_64 (output_bfd, 0, bfd_put_64 (output_bfd, 0,
htab->sgot->contents + off + GOT_ENTRY_SIZE); htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64); outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
outrel.r_addend = 0; outrel.r_addend = 0;
loc = htab->srelgot->contents; loc = htab->elf.srelgot->contents;
loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela); loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
htab->tls_ld_got.offset |= 1; htab->tls_ld_got.offset |= 1;
} }
relocation = htab->sgot->output_section->vma relocation = htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + off; + htab->elf.sgot->output_offset + off;
unresolved_reloc = FALSE; unresolved_reloc = FALSE;
break; break;
@ -3937,17 +3864,17 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
/* When building a static executable, use .iplt, .igot.plt and /* When building a static executable, use .iplt, .igot.plt and
.rela.iplt sections for STT_GNU_IFUNC symbols. */ .rela.iplt sections for STT_GNU_IFUNC symbols. */
if (htab->splt != NULL) if (htab->elf.splt != NULL)
{ {
plt = htab->splt; plt = htab->elf.splt;
gotplt = htab->sgotplt; gotplt = htab->elf.sgotplt;
relplt = htab->srelplt; relplt = htab->elf.srelplt;
} }
else else
{ {
plt = htab->iplt; plt = htab->elf.iplt;
gotplt = htab->igotplt; gotplt = htab->elf.igotplt;
relplt = htab->irelplt; relplt = htab->elf.irelplt;
} }
/* This symbol has an entry in the procedure linkage table. Set /* This symbol has an entry in the procedure linkage table. Set
@ -3972,7 +3899,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
For static executables, we don't reserve anything. */ For static executables, we don't reserve anything. */
if (plt == htab->splt) if (plt == htab->elf.splt)
{ {
plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
@ -4003,7 +3930,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
plt->contents + h->plt.offset + 2); plt->contents + h->plt.offset + 2);
/* Don't fill PLT entry for static executables. */ /* Don't fill PLT entry for static executables. */
if (plt == htab->splt) if (plt == htab->elf.splt)
{ {
/* Put relocation index. */ /* Put relocation index. */
bfd_put_32 (output_bfd, plt_index, bfd_put_32 (output_bfd, plt_index,
@ -4070,11 +3997,11 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
/* This symbol has an entry in the global offset table. Set it /* This symbol has an entry in the global offset table. Set it
up. */ up. */
if (htab->sgot == NULL || htab->srelgot == NULL) if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
abort (); abort ();
rela.r_offset = (htab->sgot->output_section->vma rela.r_offset = (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + htab->elf.sgot->output_offset
+ (h->got.offset &~ (bfd_vma) 1)); + (h->got.offset &~ (bfd_vma) 1));
/* If this is a static link, or it is a -Bsymbolic link and the /* If this is a static link, or it is a -Bsymbolic link and the
@ -4098,11 +4025,11 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
/* For non-shared object, we can't use .got.plt, which /* For non-shared object, we can't use .got.plt, which
contains the real function addres if we need pointer contains the real function addres if we need pointer
equality. We load the GOT entry with the PLT entry. */ equality. We load the GOT entry with the PLT entry. */
asection *plt = htab->splt ? htab->splt : htab->iplt; asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
bfd_put_64 (output_bfd, (plt->output_section->vma bfd_put_64 (output_bfd, (plt->output_section->vma
+ plt->output_offset + plt->output_offset
+ h->plt.offset), + h->plt.offset),
htab->sgot->contents + h->got.offset); htab->elf.sgot->contents + h->got.offset);
return TRUE; return TRUE;
} }
} }
@ -4122,13 +4049,13 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
BFD_ASSERT((h->got.offset & 1) == 0); BFD_ASSERT((h->got.offset & 1) == 0);
do_glob_dat: do_glob_dat:
bfd_put_64 (output_bfd, (bfd_vma) 0, bfd_put_64 (output_bfd, (bfd_vma) 0,
htab->sgot->contents + h->got.offset); htab->elf.sgot->contents + h->got.offset);
rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT); rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT);
rela.r_addend = 0; rela.r_addend = 0;
} }
loc = htab->srelgot->contents; loc = htab->elf.srelgot->contents;
loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela); loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
} }
@ -4216,7 +4143,7 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
{ {
Elf64_External_Dyn *dyncon, *dynconend; Elf64_External_Dyn *dyncon, *dynconend;
if (sdyn == NULL || htab->sgot == NULL) if (sdyn == NULL || htab->elf.sgot == NULL)
abort (); abort ();
dyncon = (Elf64_External_Dyn *) sdyn->contents; dyncon = (Elf64_External_Dyn *) sdyn->contents;
@ -4234,16 +4161,16 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
continue; continue;
case DT_PLTGOT: case DT_PLTGOT:
s = htab->sgotplt; s = htab->elf.sgotplt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
break; break;
case DT_JMPREL: case DT_JMPREL:
dyn.d_un.d_ptr = htab->srelplt->output_section->vma; dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
break; break;
case DT_PLTRELSZ: case DT_PLTRELSZ:
s = htab->srelplt->output_section; s = htab->elf.srelplt->output_section;
dyn.d_un.d_val = s->size; dyn.d_un.d_val = s->size;
break; break;
@ -4255,21 +4182,21 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
linker script arranges for .rela.plt to follow all linker script arranges for .rela.plt to follow all
other relocation sections, we don't have to worry other relocation sections, we don't have to worry
about changing the DT_RELA entry. */ about changing the DT_RELA entry. */
if (htab->srelplt != NULL) if (htab->elf.srelplt != NULL)
{ {
s = htab->srelplt->output_section; s = htab->elf.srelplt->output_section;
dyn.d_un.d_val -= s->size; dyn.d_un.d_val -= s->size;
} }
break; break;
case DT_TLSDESC_PLT: case DT_TLSDESC_PLT:
s = htab->splt; s = htab->elf.splt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
+ htab->tlsdesc_plt; + htab->tlsdesc_plt;
break; break;
case DT_TLSDESC_GOT: case DT_TLSDESC_GOT:
s = htab->sgot; s = htab->elf.sgot;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
+ htab->tlsdesc_got; + htab->tlsdesc_got;
break; break;
@ -4279,95 +4206,95 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
} }
/* Fill in the special first entry in the procedure linkage table. */ /* Fill in the special first entry in the procedure linkage table. */
if (htab->splt && htab->splt->size > 0) if (htab->elf.splt && htab->elf.splt->size > 0)
{ {
/* Fill in the first entry in the procedure linkage table. */ /* Fill in the first entry in the procedure linkage table. */
memcpy (htab->splt->contents, elf64_x86_64_plt0_entry, memcpy (htab->elf.splt->contents, elf64_x86_64_plt0_entry,
PLT_ENTRY_SIZE); PLT_ENTRY_SIZE);
/* Add offset for pushq GOT+8(%rip), since the instruction /* Add offset for pushq GOT+8(%rip), since the instruction
uses 6 bytes subtract this value. */ uses 6 bytes subtract this value. */
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
(htab->sgotplt->output_section->vma (htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ 8 + 8
- htab->splt->output_section->vma - htab->elf.splt->output_section->vma
- htab->splt->output_offset - htab->elf.splt->output_offset
- 6), - 6),
htab->splt->contents + 2); htab->elf.splt->contents + 2);
/* Add offset for jmp *GOT+16(%rip). The 12 is the offset to /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to
the end of the instruction. */ the end of the instruction. */
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
(htab->sgotplt->output_section->vma (htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ 16 + 16
- htab->splt->output_section->vma - htab->elf.splt->output_section->vma
- htab->splt->output_offset - htab->elf.splt->output_offset
- 12), - 12),
htab->splt->contents + 8); htab->elf.splt->contents + 8);
elf_section_data (htab->splt->output_section)->this_hdr.sh_entsize = elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize =
PLT_ENTRY_SIZE; PLT_ENTRY_SIZE;
if (htab->tlsdesc_plt) if (htab->tlsdesc_plt)
{ {
bfd_put_64 (output_bfd, (bfd_vma) 0, bfd_put_64 (output_bfd, (bfd_vma) 0,
htab->sgot->contents + htab->tlsdesc_got); htab->elf.sgot->contents + htab->tlsdesc_got);
memcpy (htab->splt->contents + htab->tlsdesc_plt, memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
elf64_x86_64_plt0_entry, elf64_x86_64_plt0_entry,
PLT_ENTRY_SIZE); PLT_ENTRY_SIZE);
/* Add offset for pushq GOT+8(%rip), since the /* Add offset for pushq GOT+8(%rip), since the
instruction uses 6 bytes subtract this value. */ instruction uses 6 bytes subtract this value. */
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
(htab->sgotplt->output_section->vma (htab->elf.sgotplt->output_section->vma
+ htab->sgotplt->output_offset + htab->elf.sgotplt->output_offset
+ 8 + 8
- htab->splt->output_section->vma - htab->elf.splt->output_section->vma
- htab->splt->output_offset - htab->elf.splt->output_offset
- htab->tlsdesc_plt - htab->tlsdesc_plt
- 6), - 6),
htab->splt->contents + htab->tlsdesc_plt + 2); htab->elf.splt->contents + htab->tlsdesc_plt + 2);
/* Add offset for jmp *GOT+TDG(%rip), where TGD stands for /* Add offset for jmp *GOT+TDG(%rip), where TGD stands for
htab->tlsdesc_got. The 12 is the offset to the end of htab->tlsdesc_got. The 12 is the offset to the end of
the instruction. */ the instruction. */
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd,
(htab->sgot->output_section->vma (htab->elf.sgot->output_section->vma
+ htab->sgot->output_offset + htab->elf.sgot->output_offset
+ htab->tlsdesc_got + htab->tlsdesc_got
- htab->splt->output_section->vma - htab->elf.splt->output_section->vma
- htab->splt->output_offset - htab->elf.splt->output_offset
- htab->tlsdesc_plt - htab->tlsdesc_plt
- 12), - 12),
htab->splt->contents + htab->tlsdesc_plt + 8); htab->elf.splt->contents + htab->tlsdesc_plt + 8);
} }
} }
} }
if (htab->sgotplt) if (htab->elf.sgotplt)
{ {
/* Fill in the first three entries in the global offset table. */ /* Fill in the first three entries in the global offset table. */
if (htab->sgotplt->size > 0) if (htab->elf.sgotplt->size > 0)
{ {
/* Set the first entry in the global offset table to the address of /* Set the first entry in the global offset table to the address of
the dynamic section. */ the dynamic section. */
if (sdyn == NULL) if (sdyn == NULL)
bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents); bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents);
else else
bfd_put_64 (output_bfd, bfd_put_64 (output_bfd,
sdyn->output_section->vma + sdyn->output_offset, sdyn->output_section->vma + sdyn->output_offset,
htab->sgotplt->contents); htab->elf.sgotplt->contents);
/* Write GOT[1] and GOT[2], needed for the dynamic linker. */ /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + GOT_ENTRY_SIZE); bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + GOT_ENTRY_SIZE*2); bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE*2);
} }
elf_section_data (htab->sgotplt->output_section)->this_hdr.sh_entsize = elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
GOT_ENTRY_SIZE; GOT_ENTRY_SIZE;
} }
if (htab->sgot && htab->sgot->size > 0) if (htab->elf.sgot && htab->elf.sgot->size > 0)
elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
= GOT_ENTRY_SIZE; = GOT_ENTRY_SIZE;
/* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */

View File

@ -101,41 +101,39 @@ _bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
asection *s; asection *s;
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
const struct elf_backend_data *bed = get_elf_backend_data (abfd); const struct elf_backend_data *bed = get_elf_backend_data (abfd);
int ptralign; struct elf_link_hash_table *htab = elf_hash_table (info);
/* This function may be called more than once. */ /* This function may be called more than once. */
s = bfd_get_section_by_name (abfd, ".got"); s = bfd_get_section_by_name (abfd, ".got");
if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0) if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
return TRUE; return TRUE;
switch (bed->s->arch_size)
{
case 32:
ptralign = 2;
break;
case 64:
ptralign = 3;
break;
default:
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
flags = bed->dynamic_sec_flags; flags = bed->dynamic_sec_flags;
s = bfd_make_section_with_flags (abfd, ".got", flags); s = bfd_make_section_with_flags (abfd, ".got", flags);
if (s == NULL if (s == NULL
|| !bfd_set_section_alignment (abfd, s, ptralign)) || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE; return FALSE;
htab->sgot = s;
s = bfd_make_section_with_flags (abfd,
(bed->rela_plts_and_copies_p
? ".rela.got" : ".rel.got"),
(bed->dynamic_sec_flags
| SEC_READONLY));
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
htab->srelgot = s;
if (bed->want_got_plt) if (bed->want_got_plt)
{ {
s = bfd_make_section_with_flags (abfd, ".got.plt", flags); s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
if (s == NULL if (s == NULL
|| !bfd_set_section_alignment (abfd, s, ptralign)) || !bfd_set_section_alignment (abfd, s,
bed->s->log_file_align))
return FALSE; return FALSE;
htab->sgotplt = s;
} }
if (bed->want_got_sym) if (bed->want_got_sym)
@ -144,7 +142,8 @@ _bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
(or .got.plt) section. We don't do this in the linker script (or .got.plt) section. We don't do this in the linker script
because we don't want to define the symbol if we are not creating because we don't want to define the symbol if we are not creating
a global offset table. */ a global offset table. */
h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_"); h = _bfd_elf_define_linkage_sym (abfd, info, s,
"_GLOBAL_OFFSET_TABLE_");
elf_hash_table (info)->hgot = h; elf_hash_table (info)->hgot = h;
if (h == NULL) if (h == NULL)
return FALSE; return FALSE;
@ -303,6 +302,7 @@ _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
asection *s; asection *s;
const struct elf_backend_data *bed = get_elf_backend_data (abfd); const struct elf_backend_data *bed = get_elf_backend_data (abfd);
struct elf_link_hash_table *htab = elf_hash_table (info);
/* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
.rel[a].bss sections. */ .rel[a].bss sections. */
@ -323,6 +323,7 @@ _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
if (s == NULL if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
return FALSE; return FALSE;
htab->splt = s;
/* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
.plt section. */ .plt section. */
@ -342,6 +343,7 @@ _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
if (s == NULL if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE; return FALSE;
htab->srelplt = s;
if (! _bfd_elf_create_got_section (abfd, info)) if (! _bfd_elf_create_got_section (abfd, info))
return FALSE; return FALSE;
@ -12491,95 +12493,3 @@ _bfd_elf_make_dynamic_reloc_section (asection * sec,
return reloc_sec; return reloc_sec;
} }
/* Create sections needed by STT_GNU_IFUNC symbol. */
bfd_boolean
_bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
{
flagword flags, pltflags;
int ptralign;
asection *s;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
flags = bed->dynamic_sec_flags;
pltflags = flags;
if (bed->plt_not_loaded)
/* We do not clear SEC_ALLOC here because we still want the OS to
allocate space for the section; it's just that there's nothing
to read in from the object file. */
pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
else
pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD;
if (bed->plt_readonly)
pltflags |= SEC_READONLY;
if (info->shared)
{
/* We need to create .rel[a].ifunc for shared objects. */
const char *rel_sec = (bed->rela_plts_and_copies_p
? ".rela.ifunc" : ".rel.ifunc");
/* This function should be called only once. */
s = bfd_get_section_by_name (abfd, rel_sec);
if (s != NULL)
abort ();
s = bfd_make_section_with_flags (abfd, rel_sec,
flags | SEC_READONLY);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s,
bed->s->log_file_align))
return FALSE;
}
else
{
/* This function should be called only once. */
s = bfd_get_section_by_name (abfd, ".iplt");
if (s != NULL)
abort ();
/* We need to create .iplt, .rel[a].iplt, .igot and .igot.plt
for static executables. */
s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
return FALSE;
s = bfd_make_section_with_flags (abfd,
(bed->rela_plts_and_copies_p
? ".rela.iplt" : ".rel.iplt"),
flags | SEC_READONLY);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s,
bed->s->log_file_align))
return FALSE;
switch (bed->s->arch_size)
{
case 32:
ptralign = 2;
break;
case 64:
ptralign = 3;
break;
default:
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
/* We don't need the .igot section if we have the .igot.plt
section. */
if (bed->want_got_plt)
s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
else
s = bfd_make_section_with_flags (abfd, ".igot", flags);
if (s == NULL
|| !bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
}
return TRUE;
}