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