* elf32-ppc.c (allocate_dynrelocs): Correct plt offset assigned

for second and subsequent list entries.  Only allocate multiple
	glink stubs when shared or pie.
	(ppc_elf_finish_dynamic_symbol): Break out early when only one
	glink stub is needed.
This commit is contained in:
Alan Modra
2005-05-20 02:37:21 +00:00
parent f53fee9196
commit 28e99bb619
2 changed files with 57 additions and 33 deletions

View File

@ -1,3 +1,11 @@
2005-05-20 Alan Modra <amodra@bigpond.net.au>
* elf32-ppc.c (allocate_dynrelocs): Correct plt offset assigned
for second and subsequent list entries. Only allocate multiple
glink stubs when shared or pie.
(ppc_elf_finish_dynamic_symbol): Break out early when only one
glink stub is needed.
2005-05-19 Zack Weinberg <zack@codesourcery.com> 2005-05-19 Zack Weinberg <zack@codesourcery.com>
* Makefile.am: Have 'all' depend on 'info'. * Makefile.am: Have 'all' depend on 'info'.

View File

@ -4058,6 +4058,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{ {
struct plt_entry *ent; struct plt_entry *ent;
bfd_boolean doneone = FALSE; bfd_boolean doneone = FALSE;
bfd_vma plt_offset = 0, glink_offset = 0;
for (ent = h->plt.plist; ent != NULL; ent = ent->next) for (ent = h->plt.plist; ent != NULL; ent = ent->next)
if (ent->plt.refcount > 0) if (ent->plt.refcount > 0)
{ {
@ -4076,56 +4078,67 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (!htab->old_plt) if (!htab->old_plt)
{ {
ent->plt.offset = s->size;
if (!doneone) if (!doneone)
{
plt_offset = s->size;
s->size += 4; s->size += 4;
}
ent->plt.offset = plt_offset;
s = htab->glink; s = htab->glink;
if (!info->shared if (!doneone || info->shared || info->pie)
{
glink_offset = s->size;
s->size += GLINK_ENTRY_SIZE;
}
if (!doneone
&& !info->shared
&& !h->def_regular) && !h->def_regular)
{ {
h->root.u.def.section = s; h->root.u.def.section = s;
h->root.u.def.value = s->size; h->root.u.def.value = glink_offset;
} }
ent->glink_offset = s->size; ent->glink_offset = glink_offset;
s->size += GLINK_ENTRY_SIZE;
} }
else else
{ {
/* If this is the first .plt entry, make room for the if (!doneone)
special first entry. */ {
/* If this is the first .plt entry, make room
for the special first entry. */
if (s->size == 0) if (s->size == 0)
s->size += PLT_INITIAL_ENTRY_SIZE; s->size += PLT_INITIAL_ENTRY_SIZE;
/* The PowerPC PLT is actually composed of two parts, the /* The PowerPC PLT is actually composed of two
first part is 2 words (for a load and a jump), and then parts, the first part is 2 words (for a load
there is a remaining word available at the end. */ and a jump), and then there is a remaining
ent->plt.offset = (PLT_INITIAL_ENTRY_SIZE word available at the end. */
plt_offset = (PLT_INITIAL_ENTRY_SIZE
+ (PLT_SLOT_SIZE + (PLT_SLOT_SIZE
* ((s->size - PLT_INITIAL_ENTRY_SIZE) * ((s->size - PLT_INITIAL_ENTRY_SIZE)
/ PLT_ENTRY_SIZE))); / PLT_ENTRY_SIZE)));
/* If this symbol is not defined in a regular file, and we /* If this symbol is not defined in a regular
are not generating a shared library, then set the symbol file, and we are not generating a shared
to this location in the .plt. This is required to make library, then set the symbol to this location
function pointers compare as equal between the normal in the .plt. This is required to make
executable and the shared library. */ function pointers compare as equal between
the normal executable and the shared library. */
if (! info->shared if (! info->shared
&& !h->def_regular) && !h->def_regular)
{ {
h->root.u.def.section = s; h->root.u.def.section = s;
h->root.u.def.value = ent->plt.offset; h->root.u.def.value = plt_offset;
} }
/* Make room for this entry. After the 8192nd entry, room /* Make room for this entry. After the 8192nd
for two entries is allocated. */ entry, room for two entries is allocated. */
if (!doneone)
{
s->size += PLT_ENTRY_SIZE; s->size += PLT_ENTRY_SIZE;
if ((s->size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE if ((s->size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
> PLT_NUM_SINGLE_ENTRIES) > PLT_NUM_SINGLE_ENTRIES)
s->size += PLT_ENTRY_SIZE; s->size += PLT_ENTRY_SIZE;
} }
ent->plt.offset = plt_offset;
} }
/* We also need to make an entry in the .rela.plt section. */ /* We also need to make an entry in the .rela.plt section. */
@ -6508,6 +6521,9 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
p += 4; p += 4;
bfd_put_32 (output_bfd, BCTR, p); bfd_put_32 (output_bfd, BCTR, p);
p += 4; p += 4;
/* We only need one non-PIC glink stub. */
break;
} }
} }
else else