PR 19264 looping in ppc64_elf_size_stubs

b399102 fixed the testcase in this PR but it may be possible to
trigger the problem in other ways.

	PR ld/19264
	* elf64-ppc.c (STUB_SHRINK_ITER): Define.
	(ppc64_elf_size_stubs): Exit stub sizing loop past STUB_SHRINK_ITER
	if shrinking stubs.
	(ppc64_elf_size_stubs): Adjust to suit.
This commit is contained in:
Alan Modra 2016-06-27 20:00:09 +09:30
parent f495252396
commit c9301e3181
2 changed files with 21 additions and 7 deletions

View file

@ -1,3 +1,11 @@
2016-06-27 Alan Modra <amodra@gmail.com>
PR ld/19264
* elf64-ppc.c (STUB_SHRINK_ITER): Define.
(ppc64_elf_size_stubs): Exit stub sizing loop past STUB_SHRINK_ITER
if shrinking stubs.
(ppc64_elf_size_stubs): Adjust to suit.
2016-06-27 Trevor Saunders <tbsaunde+binutils@tbsaunde.org> 2016-06-27 Trevor Saunders <tbsaunde+binutils@tbsaunde.org>
* elf32-dlx.h: New file. * elf32-dlx.h: New file.

View file

@ -12185,6 +12185,13 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
if (!group_sections (info, stub_group_size, stubs_always_before_branch)) if (!group_sections (info, stub_group_size, stubs_always_before_branch))
return FALSE; return FALSE;
#define STUB_SHRINK_ITER 20
/* Loop until no stubs added. After iteration 20 of this loop we may
exit on a stub section shrinking. This is to break out of a
pathological case where adding stubs on one iteration decreases
section gaps (perhaps due to alignment), which then requires
fewer or smaller stubs on the next iteration. */
while (1) while (1)
{ {
bfd *input_bfd; bfd *input_bfd;
@ -12566,11 +12573,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
stub_sec != NULL; stub_sec != NULL;
stub_sec = stub_sec->next) stub_sec = stub_sec->next)
if ((stub_sec->flags & SEC_LINKER_CREATED) == 0 if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
&& stub_sec->rawsize != stub_sec->size) && stub_sec->rawsize != stub_sec->size
&& (htab->stub_iteration <= STUB_SHRINK_ITER
|| stub_sec->rawsize < stub_sec->size))
break; break;
/* Exit from this loop when no stubs have been added, and no stubs
have changed size. */
if (stub_sec == NULL if (stub_sec == NULL
&& (htab->glink_eh_frame == NULL && (htab->glink_eh_frame == NULL
|| htab->glink_eh_frame->rawsize == htab->glink_eh_frame->size)) || htab->glink_eh_frame->rawsize == htab->glink_eh_frame->size))
@ -12901,9 +12908,6 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
stub_sec->contents = bfd_zalloc (htab->params->stub_bfd, stub_sec->size); stub_sec->contents = bfd_zalloc (htab->params->stub_bfd, stub_sec->size);
if (stub_sec->contents == NULL) if (stub_sec->contents == NULL)
return FALSE; return FALSE;
/* We want to check that built size is the same as calculated
size. rawsize is a convenient location to use. */
stub_sec->rawsize = stub_sec->size;
stub_sec->size = 0; stub_sec->size = 0;
} }
@ -13092,7 +13096,9 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
if ((stub_sec->flags & SEC_LINKER_CREATED) == 0) if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
{ {
stub_sec_count += 1; stub_sec_count += 1;
if (stub_sec->rawsize != stub_sec->size) if (stub_sec->rawsize != stub_sec->size
&& (htab->stub_iteration <= STUB_SHRINK_ITER
|| stub_sec->rawsize < stub_sec->size))
break; break;
} }