* elf32-spu.c (struct spu_link_hash_table): Add "stubs".
(spu_elf_link_hash_table_create): Init new field. (spu_elf_size_stubs): Store sorted stub syms in new htab field rather than local var. (spu_elf_build_stubs): Iterate over htab stubs rather than hash traversal. (struct stubarr): Delete. (allocate_spuear_stubs, populate_stubs, write_one_stub): Adjust.
This commit is contained in:
parent
82dcae9de0
commit
98e89a7d84
|
@ -1,3 +1,14 @@
|
||||||
|
2007-09-25 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf32-spu.c (struct spu_link_hash_table): Add "stubs".
|
||||||
|
(spu_elf_link_hash_table_create): Init new field.
|
||||||
|
(spu_elf_size_stubs): Store sorted stub syms in new htab field
|
||||||
|
rather than local var.
|
||||||
|
(spu_elf_build_stubs): Iterate over htab stubs rather than
|
||||||
|
hash traversal.
|
||||||
|
(struct stubarr): Delete.
|
||||||
|
(allocate_spuear_stubs, populate_stubs, write_one_stub): Adjust.
|
||||||
|
|
||||||
2007-09-24 Daniel Jacobowitz <dan@codesourcery.com>
|
2007-09-24 Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
* elf.c (assign_file_positions_for_load_sections): Trust
|
* elf.c (assign_file_positions_for_load_sections): Trust
|
||||||
|
|
|
@ -260,6 +260,13 @@ struct spu_link_hash_table
|
||||||
/* The stub hash table. */
|
/* The stub hash table. */
|
||||||
struct bfd_hash_table stub_hash_table;
|
struct bfd_hash_table stub_hash_table;
|
||||||
|
|
||||||
|
/* Sorted array of stubs. */
|
||||||
|
struct {
|
||||||
|
struct spu_stub_hash_entry **sh;
|
||||||
|
unsigned int count;
|
||||||
|
int err;
|
||||||
|
} stubs;
|
||||||
|
|
||||||
/* Shortcuts to overlay sections. */
|
/* Shortcuts to overlay sections. */
|
||||||
asection *stub;
|
asection *stub;
|
||||||
asection *ovtab;
|
asection *ovtab;
|
||||||
|
@ -370,8 +377,8 @@ spu_elf_link_hash_table_create (bfd *abfd)
|
||||||
sizeof (struct spu_stub_hash_entry)))
|
sizeof (struct spu_stub_hash_entry)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset (&htab->stub, 0,
|
memset (&htab->stubs, 0,
|
||||||
sizeof (*htab) - offsetof (struct spu_link_hash_table, stub));
|
sizeof (*htab) - offsetof (struct spu_link_hash_table, stubs));
|
||||||
|
|
||||||
return &htab->elf.root;
|
return &htab->elf.root;
|
||||||
}
|
}
|
||||||
|
@ -764,13 +771,6 @@ needs_ovl_stub (const char *sym_name,
|
||||||
return !is_branch;
|
return !is_branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stubarr {
|
|
||||||
struct bfd_hash_table *stub_hash_table;
|
|
||||||
struct spu_stub_hash_entry **sh;
|
|
||||||
unsigned int count;
|
|
||||||
int err;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Called via elf_link_hash_traverse to allocate stubs for any _SPUEAR_
|
/* Called via elf_link_hash_traverse to allocate stubs for any _SPUEAR_
|
||||||
symbols. */
|
symbols. */
|
||||||
|
|
||||||
|
@ -784,19 +784,19 @@ allocate_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
|
||||||
&& h->def_regular
|
&& h->def_regular
|
||||||
&& strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
|
&& strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
|
||||||
{
|
{
|
||||||
struct stubarr *stubs = inf;
|
struct spu_link_hash_table *htab = inf;
|
||||||
static Elf_Internal_Rela zero_rel;
|
static Elf_Internal_Rela zero_rel;
|
||||||
char *stub_name = spu_stub_name (h->root.u.def.section, h, &zero_rel);
|
char *stub_name = spu_stub_name (h->root.u.def.section, h, &zero_rel);
|
||||||
struct spu_stub_hash_entry *sh;
|
struct spu_stub_hash_entry *sh;
|
||||||
|
|
||||||
if (stub_name == NULL)
|
if (stub_name == NULL)
|
||||||
{
|
{
|
||||||
stubs->err = 1;
|
htab->stubs.err = 1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sh = (struct spu_stub_hash_entry *)
|
sh = (struct spu_stub_hash_entry *)
|
||||||
bfd_hash_lookup (stubs->stub_hash_table, stub_name, TRUE, FALSE);
|
bfd_hash_lookup (&htab->stub_hash_table, stub_name, TRUE, FALSE);
|
||||||
if (sh == NULL)
|
if (sh == NULL)
|
||||||
{
|
{
|
||||||
free (stub_name);
|
free (stub_name);
|
||||||
|
@ -812,7 +812,7 @@ allocate_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
|
||||||
|
|
||||||
sh->target_section = h->root.u.def.section;
|
sh->target_section = h->root.u.def.section;
|
||||||
sh->target_off = h->root.u.def.value;
|
sh->target_off = h->root.u.def.value;
|
||||||
stubs->count += 1;
|
htab->stubs.count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -824,9 +824,9 @@ allocate_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
populate_stubs (struct bfd_hash_entry *bh, void *inf)
|
populate_stubs (struct bfd_hash_entry *bh, void *inf)
|
||||||
{
|
{
|
||||||
struct stubarr *stubs = inf;
|
struct spu_link_hash_table *htab = inf;
|
||||||
|
|
||||||
stubs->sh[--stubs->count] = (struct spu_stub_hash_entry *) bh;
|
htab->stubs.sh[--htab->stubs.count] = (struct spu_stub_hash_entry *) bh;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,14 +873,10 @@ spu_elf_size_stubs (bfd *output_bfd,
|
||||||
{
|
{
|
||||||
struct spu_link_hash_table *htab = spu_hash_table (info);
|
struct spu_link_hash_table *htab = spu_hash_table (info);
|
||||||
bfd *ibfd;
|
bfd *ibfd;
|
||||||
struct stubarr stubs;
|
|
||||||
unsigned i, group;
|
unsigned i, group;
|
||||||
flagword flags;
|
flagword flags;
|
||||||
|
|
||||||
htab->non_overlay_stubs = non_overlay_stubs;
|
htab->non_overlay_stubs = non_overlay_stubs;
|
||||||
stubs.stub_hash_table = &htab->stub_hash_table;
|
|
||||||
stubs.count = 0;
|
|
||||||
stubs.err = 0;
|
|
||||||
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
||||||
{
|
{
|
||||||
extern const bfd_target bfd_elf32_spu_vec;
|
extern const bfd_target bfd_elf32_spu_vec;
|
||||||
|
@ -1054,7 +1050,7 @@ spu_elf_size_stubs (bfd *output_bfd,
|
||||||
sh->target_off = sym->st_value;
|
sh->target_off = sym->st_value;
|
||||||
sh->target_off += irela->r_addend;
|
sh->target_off += irela->r_addend;
|
||||||
|
|
||||||
stubs.count += 1;
|
htab->stubs.count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're done with the internal relocs, free them. */
|
/* We're done with the internal relocs, free them. */
|
||||||
|
@ -1072,12 +1068,12 @@ spu_elf_size_stubs (bfd *output_bfd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elf_link_hash_traverse (&htab->elf, allocate_spuear_stubs, &stubs);
|
elf_link_hash_traverse (&htab->elf, allocate_spuear_stubs, htab);
|
||||||
if (stubs.err)
|
if (htab->stubs.err)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
*stub = NULL;
|
*stub = NULL;
|
||||||
if (stubs.count == 0)
|
if (htab->stubs.count == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
ibfd = info->input_bfds;
|
ibfd = info->input_bfds;
|
||||||
|
@ -1104,15 +1100,16 @@ spu_elf_size_stubs (bfd *output_bfd,
|
||||||
(*toe)->size = 16;
|
(*toe)->size = 16;
|
||||||
|
|
||||||
/* Retrieve all the stubs and sort. */
|
/* Retrieve all the stubs and sort. */
|
||||||
stubs.sh = bfd_malloc (stubs.count * sizeof (*stubs.sh));
|
htab->stubs.sh = bfd_malloc (htab->stubs.count * sizeof (*htab->stubs.sh));
|
||||||
if (stubs.sh == NULL)
|
if (htab->stubs.sh == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
i = stubs.count;
|
i = htab->stubs.count;
|
||||||
bfd_hash_traverse (&htab->stub_hash_table, populate_stubs, &stubs);
|
bfd_hash_traverse (&htab->stub_hash_table, populate_stubs, htab);
|
||||||
BFD_ASSERT (stubs.count == 0);
|
BFD_ASSERT (htab->stubs.count == 0);
|
||||||
|
|
||||||
stubs.count = i;
|
htab->stubs.count = i;
|
||||||
qsort (stubs.sh, stubs.count, sizeof (*stubs.sh), sort_stubs);
|
qsort (htab->stubs.sh, htab->stubs.count, sizeof (*htab->stubs.sh),
|
||||||
|
sort_stubs);
|
||||||
|
|
||||||
/* Now that the stubs are sorted, place them in the stub section.
|
/* Now that the stubs are sorted, place them in the stub section.
|
||||||
Stubs are grouped per overlay
|
Stubs are grouped per overlay
|
||||||
|
@ -1129,36 +1126,37 @@ spu_elf_size_stubs (bfd *output_bfd,
|
||||||
. br __ovly_load */
|
. br __ovly_load */
|
||||||
|
|
||||||
group = 0;
|
group = 0;
|
||||||
for (i = 0; i < stubs.count; i++)
|
for (i = 0; i < htab->stubs.count; i++)
|
||||||
{
|
{
|
||||||
if (spu_elf_section_data (stubs.sh[group]->target_section
|
if (spu_elf_section_data (htab->stubs.sh[group]->target_section
|
||||||
->output_section)->ovl_index
|
->output_section)->ovl_index
|
||||||
!= spu_elf_section_data (stubs.sh[i]->target_section
|
!= spu_elf_section_data (htab->stubs.sh[i]->target_section
|
||||||
->output_section)->ovl_index)
|
->output_section)->ovl_index)
|
||||||
{
|
{
|
||||||
htab->stub->size += SIZEOF_STUB2;
|
htab->stub->size += SIZEOF_STUB2;
|
||||||
for (; group != i; group++)
|
for (; group != i; group++)
|
||||||
stubs.sh[group]->delta
|
htab->stubs.sh[group]->delta
|
||||||
= stubs.sh[i - 1]->off - stubs.sh[group]->off;
|
= htab->stubs.sh[i - 1]->off - htab->stubs.sh[group]->off;
|
||||||
}
|
}
|
||||||
if (group == i
|
if (group == i
|
||||||
|| ((stubs.sh[i - 1]->target_section->output_section->vma
|
|| ((htab->stubs.sh[i - 1]->target_section->output_section->vma
|
||||||
+ stubs.sh[i - 1]->target_section->output_offset
|
+ htab->stubs.sh[i - 1]->target_section->output_offset
|
||||||
+ stubs.sh[i - 1]->target_off)
|
+ htab->stubs.sh[i - 1]->target_off)
|
||||||
!= (stubs.sh[i]->target_section->output_section->vma
|
!= (htab->stubs.sh[i]->target_section->output_section->vma
|
||||||
+ stubs.sh[i]->target_section->output_offset
|
+ htab->stubs.sh[i]->target_section->output_offset
|
||||||
+ stubs.sh[i]->target_off)))
|
+ htab->stubs.sh[i]->target_off)))
|
||||||
{
|
{
|
||||||
stubs.sh[i]->off = htab->stub->size;
|
htab->stubs.sh[i]->off = htab->stub->size;
|
||||||
htab->stub->size += SIZEOF_STUB1;
|
htab->stub->size += SIZEOF_STUB1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
stubs.sh[i]->off = stubs.sh[i - 1]->off;
|
htab->stubs.sh[i]->off = htab->stubs.sh[i - 1]->off;
|
||||||
}
|
}
|
||||||
if (group != i)
|
if (group != i)
|
||||||
htab->stub->size += SIZEOF_STUB2;
|
htab->stub->size += SIZEOF_STUB2;
|
||||||
for (; group != i; group++)
|
for (; group != i; group++)
|
||||||
stubs.sh[group]->delta = stubs.sh[i - 1]->off - stubs.sh[group]->off;
|
htab->stubs.sh[group]->delta
|
||||||
|
= htab->stubs.sh[i - 1]->off - htab->stubs.sh[group]->off;
|
||||||
|
|
||||||
/* htab->ovtab consists of two arrays.
|
/* htab->ovtab consists of two arrays.
|
||||||
. struct {
|
. struct {
|
||||||
|
@ -1228,10 +1226,9 @@ spu_elf_open_builtin_lib (bfd **ovl_bfd, const struct _ovl_stream *stream)
|
||||||
write the stub that sets the overlay number too. */
|
write the stub that sets the overlay number too. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
write_one_stub (struct bfd_hash_entry *bh, void *inf)
|
write_one_stub (struct spu_stub_hash_entry *ent, struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
struct spu_stub_hash_entry *ent = (struct spu_stub_hash_entry *) bh;
|
struct spu_link_hash_table *htab = spu_hash_table (info);
|
||||||
struct spu_link_hash_table *htab = inf;
|
|
||||||
asection *sec = htab->stub;
|
asection *sec = htab->stub;
|
||||||
asection *s = ent->target_section;
|
asection *s = ent->target_section;
|
||||||
unsigned int ovl;
|
unsigned int ovl;
|
||||||
|
@ -1372,7 +1369,8 @@ spu_elf_build_stubs (struct bfd_link_info *info, int emit_syms, asection *toe)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out all the stubs. */
|
/* Write out all the stubs. */
|
||||||
bfd_hash_traverse (&htab->stub_hash_table, write_one_stub, htab);
|
for (i = 0; i < htab->stubs.count; i++)
|
||||||
|
write_one_stub (htab->stubs.sh[i], info);
|
||||||
|
|
||||||
if (htab->stub_overflow)
|
if (htab->stub_overflow)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue