bfd/
* elfxx-mips.c (mips_elf_count_got_entries): Delete. (mips_elf_check_recreate_got, mips_elf_recreate_got): Take a mips_elf_traverse_got_arg. Count GOT entries. (mips_elf_resolve_final_got_entries): Take the bfd_link_info as argument. Update after above changes. (mips_elf_merge_got, mips_elf_lay_out_got): Don't call mips_elf_count_got_entries. Update the calls to mips_elf_resolve_final_got_entries.
This commit is contained in:
parent
9ab066b4cf
commit
476366af69
|
@ -1,3 +1,14 @@
|
||||||
|
2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
|
* elfxx-mips.c (mips_elf_count_got_entries): Delete.
|
||||||
|
(mips_elf_check_recreate_got, mips_elf_recreate_got): Take a
|
||||||
|
mips_elf_traverse_got_arg. Count GOT entries.
|
||||||
|
(mips_elf_resolve_final_got_entries): Take the bfd_link_info
|
||||||
|
as argument. Update after above changes.
|
||||||
|
(mips_elf_merge_got, mips_elf_lay_out_got): Don't call
|
||||||
|
mips_elf_count_got_entries. Update the calls to
|
||||||
|
mips_elf_resolve_final_got_entries.
|
||||||
|
|
||||||
2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
|
2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
* elfxx-mips.c (mips_got_tls_type): New enum.
|
* elfxx-mips.c (mips_got_tls_type): New enum.
|
||||||
|
|
103
bfd/elfxx-mips.c
103
bfd/elfxx-mips.c
|
@ -2979,23 +2979,6 @@ mips_elf_count_got_entry (struct bfd_link_info *info,
|
||||||
g->global_gotno += 1;
|
g->global_gotno += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A htab_traverse callback. Count the number of GOT entries and
|
|
||||||
TLS relocations required for the GOT entry in *ENTRYP. DATA points
|
|
||||||
to a mips_elf_traverse_got_arg structure. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
mips_elf_count_got_entries (void **entryp, void *data)
|
|
||||||
{
|
|
||||||
struct mips_got_entry *entry;
|
|
||||||
struct mips_elf_traverse_got_arg *arg;
|
|
||||||
|
|
||||||
entry = (struct mips_got_entry *) *entryp;
|
|
||||||
arg = (struct mips_elf_traverse_got_arg *) data;
|
|
||||||
mips_elf_count_got_entry (arg->info, arg->g, entry);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output a simple dynamic relocation into SRELOC. */
|
/* Output a simple dynamic relocation into SRELOC. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3861,17 +3844,19 @@ mips_elf_allocate_dynamic_relocations (bfd *abfd, struct bfd_link_info *info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A htab_traverse callback for GOT entries. Set boolean *DATA to true
|
/* A htab_traverse callback for GOT entries, with DATA pointing to a
|
||||||
if the GOT entry is for an indirect or warning symbol. */
|
mips_elf_traverse_got_arg structure. Count the number of GOT
|
||||||
|
entries and TLS relocs. Set DATA->value to true if we need
|
||||||
|
to resolve indirect or warning symbols and then recreate the GOT. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mips_elf_check_recreate_got (void **entryp, void *data)
|
mips_elf_check_recreate_got (void **entryp, void *data)
|
||||||
{
|
{
|
||||||
struct mips_got_entry *entry;
|
struct mips_got_entry *entry;
|
||||||
bfd_boolean *must_recreate;
|
struct mips_elf_traverse_got_arg *arg;
|
||||||
|
|
||||||
entry = (struct mips_got_entry *) *entryp;
|
entry = (struct mips_got_entry *) *entryp;
|
||||||
must_recreate = (bfd_boolean *) data;
|
arg = (struct mips_elf_traverse_got_arg *) data;
|
||||||
if (entry->abfd != NULL && entry->symndx == -1)
|
if (entry->abfd != NULL && entry->symndx == -1)
|
||||||
{
|
{
|
||||||
struct mips_elf_link_hash_entry *h;
|
struct mips_elf_link_hash_entry *h;
|
||||||
|
@ -3880,27 +3865,28 @@ mips_elf_check_recreate_got (void **entryp, void *data)
|
||||||
if (h->root.root.type == bfd_link_hash_indirect
|
if (h->root.root.type == bfd_link_hash_indirect
|
||||||
|| h->root.root.type == bfd_link_hash_warning)
|
|| h->root.root.type == bfd_link_hash_warning)
|
||||||
{
|
{
|
||||||
*must_recreate = TRUE;
|
arg->value = TRUE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mips_elf_count_got_entry (arg->info, arg->g, entry);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A htab_traverse callback for GOT entries. Add all entries to
|
/* A htab_traverse callback for GOT entries, with DATA pointing to a
|
||||||
hash table *DATA, converting entries for indirect and warning
|
mips_elf_traverse_got_arg structure. Add all entries to DATA->g,
|
||||||
symbols into entries for the target symbol. Set *DATA to null
|
converting entries for indirect and warning symbols into entries
|
||||||
on error. */
|
for the target symbol. Set DATA->g to null on error. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mips_elf_recreate_got (void **entryp, void *data)
|
mips_elf_recreate_got (void **entryp, void *data)
|
||||||
{
|
{
|
||||||
htab_t *new_got;
|
|
||||||
struct mips_got_entry new_entry, *entry;
|
struct mips_got_entry new_entry, *entry;
|
||||||
|
struct mips_elf_traverse_got_arg *arg;
|
||||||
void **slot;
|
void **slot;
|
||||||
|
|
||||||
new_got = (htab_t *) data;
|
|
||||||
entry = (struct mips_got_entry *) *entryp;
|
entry = (struct mips_got_entry *) *entryp;
|
||||||
|
arg = (struct mips_elf_traverse_got_arg *) data;
|
||||||
if (entry->abfd != NULL
|
if (entry->abfd != NULL
|
||||||
&& entry->symndx == -1
|
&& entry->symndx == -1
|
||||||
&& (entry->d.h->root.root.type == bfd_link_hash_indirect
|
&& (entry->d.h->root.root.type == bfd_link_hash_indirect
|
||||||
|
@ -3920,10 +3906,10 @@ mips_elf_recreate_got (void **entryp, void *data)
|
||||||
|| h->root.root.type == bfd_link_hash_warning);
|
|| h->root.root.type == bfd_link_hash_warning);
|
||||||
entry->d.h = h;
|
entry->d.h = h;
|
||||||
}
|
}
|
||||||
slot = htab_find_slot (*new_got, entry, INSERT);
|
slot = htab_find_slot (arg->g->got_entries, entry, INSERT);
|
||||||
if (slot == NULL)
|
if (slot == NULL)
|
||||||
{
|
{
|
||||||
*new_got = NULL;
|
arg->g = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (*slot == NULL)
|
if (*slot == NULL)
|
||||||
|
@ -3933,12 +3919,13 @@ mips_elf_recreate_got (void **entryp, void *data)
|
||||||
entry = bfd_alloc (entry->abfd, sizeof (*entry));
|
entry = bfd_alloc (entry->abfd, sizeof (*entry));
|
||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
*new_got = NULL;
|
arg->g = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*entry = new_entry;
|
*entry = new_entry;
|
||||||
}
|
}
|
||||||
*slot = entry;
|
*slot = entry;
|
||||||
|
mips_elf_count_got_entry (arg->info, arg->g, entry);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -3947,24 +3934,32 @@ mips_elf_recreate_got (void **entryp, void *data)
|
||||||
replace them with entries for the target symbol. */
|
replace them with entries for the target symbol. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
mips_elf_resolve_final_got_entries (struct mips_got_info *g)
|
mips_elf_resolve_final_got_entries (struct bfd_link_info *info,
|
||||||
|
struct mips_got_info *g)
|
||||||
{
|
{
|
||||||
bfd_boolean must_recreate;
|
struct mips_elf_traverse_got_arg tga;
|
||||||
htab_t new_got;
|
struct mips_got_info oldg;
|
||||||
|
|
||||||
must_recreate = FALSE;
|
oldg = *g;
|
||||||
htab_traverse (g->got_entries, mips_elf_check_recreate_got, &must_recreate);
|
|
||||||
if (must_recreate)
|
tga.info = info;
|
||||||
|
tga.g = g;
|
||||||
|
tga.value = FALSE;
|
||||||
|
htab_traverse (g->got_entries, mips_elf_check_recreate_got, &tga);
|
||||||
|
if (tga.value)
|
||||||
{
|
{
|
||||||
new_got = htab_create (htab_size (g->got_entries),
|
*g = oldg;
|
||||||
mips_elf_got_entry_hash,
|
g->got_entries = htab_create (htab_size (oldg.got_entries),
|
||||||
mips_elf_got_entry_eq, NULL);
|
mips_elf_got_entry_hash,
|
||||||
htab_traverse (g->got_entries, mips_elf_recreate_got, &new_got);
|
mips_elf_got_entry_eq, NULL);
|
||||||
if (new_got == NULL)
|
if (!g->got_entries)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
htab_delete (g->got_entries);
|
htab_traverse (oldg.got_entries, mips_elf_recreate_got, &tga);
|
||||||
g->got_entries = new_got;
|
if (!tga.g)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
htab_delete (oldg.got_entries);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -4134,17 +4129,12 @@ static bfd_boolean
|
||||||
mips_elf_merge_got (bfd *abfd, struct mips_got_info *g,
|
mips_elf_merge_got (bfd *abfd, struct mips_got_info *g,
|
||||||
struct mips_elf_got_per_bfd_arg *arg)
|
struct mips_elf_got_per_bfd_arg *arg)
|
||||||
{
|
{
|
||||||
struct mips_elf_traverse_got_arg tga;
|
|
||||||
unsigned int estimate;
|
unsigned int estimate;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (!mips_elf_resolve_final_got_entries (g))
|
if (!mips_elf_resolve_final_got_entries (arg->info, g))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
tga.info = arg->info;
|
|
||||||
tga.g = g;
|
|
||||||
htab_traverse (g->got_entries, mips_elf_count_got_entries, &tga);
|
|
||||||
|
|
||||||
/* Work out the number of page, local and TLS entries. */
|
/* Work out the number of page, local and TLS entries. */
|
||||||
estimate = arg->max_pages;
|
estimate = arg->max_pages;
|
||||||
if (estimate > g->page_gotno)
|
if (estimate > g->page_gotno)
|
||||||
|
@ -8608,11 +8598,6 @@ mips_elf_lay_out_got (bfd *output_bfd, struct bfd_link_info *info)
|
||||||
g->local_gotno += htab->reserved_gotno;
|
g->local_gotno += htab->reserved_gotno;
|
||||||
g->assigned_gotno = htab->reserved_gotno;
|
g->assigned_gotno = htab->reserved_gotno;
|
||||||
|
|
||||||
/* Replace entries for indirect and warning symbols with entries for
|
|
||||||
the target symbol. */
|
|
||||||
if (!mips_elf_resolve_final_got_entries (g))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Decide which symbols need to go in the global part of the GOT and
|
/* Decide which symbols need to go in the global part of the GOT and
|
||||||
count the number of reloc-only GOT symbols. */
|
count the number of reloc-only GOT symbols. */
|
||||||
mips_elf_link_hash_traverse (htab, mips_elf_count_got_symbols, info);
|
mips_elf_link_hash_traverse (htab, mips_elf_count_got_symbols, info);
|
||||||
|
@ -8652,10 +8637,10 @@ mips_elf_lay_out_got (bfd *output_bfd, struct bfd_link_info *info)
|
||||||
|
|
||||||
g->local_gotno += page_gotno;
|
g->local_gotno += page_gotno;
|
||||||
|
|
||||||
/* Count the number of GOT entries and TLS relocs. */
|
/* Replace entries for indirect and warning symbols with entries for
|
||||||
tga.info = info;
|
the target symbol. Count the number of GOT entries and TLS relocs. */
|
||||||
tga.g = g;
|
if (!mips_elf_resolve_final_got_entries (info, g))
|
||||||
htab_traverse (g->got_entries, mips_elf_count_got_entries, &tga);
|
return FALSE;
|
||||||
|
|
||||||
s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
|
s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
|
||||||
s->size += g->global_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
|
s->size += g->global_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
|
||||||
|
|
Loading…
Reference in New Issue