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