* 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:
Bob Wilson 2007-02-03 06:25:00 +00:00
parent b3d2152a31
commit f0e6fdb270
2 changed files with 195 additions and 137 deletions

View file

@ -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 *.

View file

@ -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