Enable ppc476 workaround for ld -r.

The Linux kernel builds modules using ld -r.  These might need the
ppc476 workaround, so enable it for ld -r if sections have sufficient
alignment to tell location within a page.

bfd/
	* elf32-ppc.c (ppc_elf_relax_section): Enable ppc476 workaround
	for ld -r, when code sections are sufficiently aligned.
	* elf32-ppc.h (struct ppc_elf_params): Delete pagesize.  Add
	pagesize_p2.
ld/
	* emultempl/ppc32elf.em (pagesize): New static var.
	(ppc_after_open_output): Set params.pagesize_p2 from pagesize.
	(PARSE_AND_LIST_ARGS_CASES): Adjust to use pagesize.
This commit is contained in:
Alan Modra
2014-02-12 16:44:36 +10:30
parent b407645f7e
commit 795bc6b3ea
5 changed files with 33 additions and 12 deletions

View File

@ -1,3 +1,10 @@
2014-02-12 Alan Modra <amodra@gmail.com>
* elf32-ppc.c (ppc_elf_relax_section): Enable ppc476 workaround
for ld -r, when code sections are sufficiently aligned.
* elf32-ppc.h (struct ppc_elf_params): Delete pagesize. Add
pagesize_p2.
2014-02-12 Alan Modra <amodra@gmail.com> 2014-02-12 Alan Modra <amodra@gmail.com>
PR gold/15530 PR gold/15530

View File

@ -7060,16 +7060,18 @@ ppc_elf_relax_section (bfd *abfd,
workaround_change = FALSE; workaround_change = FALSE;
newsize = trampoff; newsize = trampoff;
if (htab->params->ppc476_workaround) if (htab->params->ppc476_workaround
&& (!link_info->relocatable
|| isec->output_section->alignment_power >= htab->params->pagesize_p2))
{ {
bfd_vma addr, end_addr; bfd_vma addr, end_addr;
unsigned int crossings; unsigned int crossings;
unsigned int pagesize = htab->params->pagesize; bfd_vma pagesize = (bfd_vma) 1 << htab->params->pagesize_p2;
addr = isec->output_section->vma + isec->output_offset; addr = isec->output_section->vma + isec->output_offset;
end_addr = addr + trampoff - 1; end_addr = addr + trampoff - 1;
addr &= -pagesize; addr &= -pagesize;
crossings = ((end_addr & -pagesize) - addr) / pagesize; crossings = ((end_addr & -pagesize) - addr) >> htab->params->pagesize_p2;
if (crossings != 0) if (crossings != 0)
{ {
/* Keep space aligned, to ensure the patch code itself does /* Keep space aligned, to ensure the patch code itself does
@ -9134,11 +9136,14 @@ ppc_elf_relocate_section (bfd *output_bfd,
} }
if (htab->params->ppc476_workaround if (htab->params->ppc476_workaround
&& input_section->sec_info_type == SEC_INFO_TYPE_TARGET) && input_section->sec_info_type == SEC_INFO_TYPE_TARGET
&& (!info->relocatable
|| (input_section->output_section->alignment_power
>= htab->params->pagesize_p2)))
{ {
struct ppc_elf_relax_info *relax_info; struct ppc_elf_relax_info *relax_info;
bfd_vma start_addr, end_addr, addr; bfd_vma start_addr, end_addr, addr;
unsigned int pagesize = htab->params->pagesize; bfd_vma pagesize = (bfd_vma) 1 << htab->params->pagesize_p2;
relax_info = elf_section_data (input_section)->sec_info; relax_info = elf_section_data (input_section)->sec_info;
if (relax_info->workaround_size != 0) if (relax_info->workaround_size != 0)

View File

@ -43,7 +43,7 @@ struct ppc_elf_params
/* Avoid execution falling into new page. */ /* Avoid execution falling into new page. */
int ppc476_workaround; int ppc476_workaround;
int pagesize; unsigned int pagesize_p2;
}; };
void ppc_elf_link_params (struct bfd_link_info *, struct ppc_elf_params *); void ppc_elf_link_params (struct bfd_link_info *, struct ppc_elf_params *);

View File

@ -1,3 +1,9 @@
2014-02-12 Alan Modra <amodra@gmail.com>
* emultempl/ppc32elf.em (pagesize): New static var.
(ppc_after_open_output): Set params.pagesize_p2 from pagesize.
(PARSE_AND_LIST_ARGS_CASES): Adjust to use pagesize.
2014-02-11 Andrew Pinski <apinski@cavium.com> 2014-02-11 Andrew Pinski <apinski@cavium.com>
* emulparams/aarch64linux32.sh (LIBPATH_SUFFIX): Change to ilp32. * emulparams/aarch64linux32.sh (LIBPATH_SUFFIX): Change to ilp32.

View File

@ -39,6 +39,8 @@ static int notlsopt = 0;
/* Choose the correct place for .got. */ /* Choose the correct place for .got. */
static int old_got = 0; static int old_got = 0;
static bfd_vma pagesize = 0;
static struct ppc_elf_params params = { PLT_UNSET, -1, 0, 0, 0, 0 }; static struct ppc_elf_params params = { PLT_UNSET, -1, 0, 0, 0, 0 };
static void static void
@ -46,8 +48,9 @@ ppc_after_open_output (void)
{ {
if (params.emit_stub_syms < 0) if (params.emit_stub_syms < 0)
params.emit_stub_syms = link_info.emitrelocations || link_info.shared; params.emit_stub_syms = link_info.emitrelocations || link_info.shared;
if (params.pagesize == 0) if (pagesize == 0)
params.pagesize = config.commonpagesize; pagesize = config.commonpagesize;
params.pagesize_p2 = bfd_log2 (pagesize);
if (link_info.relocatable) if (link_info.relocatable)
params.ppc476_workaround = 0; params.ppc476_workaround = 0;
ppc_elf_link_params (&link_info, &params); ppc_elf_link_params (&link_info, &params);
@ -267,10 +270,10 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
if (optarg != NULL) if (optarg != NULL)
{ {
char *end; char *end;
params.pagesize = strtoul (optarg, &end, 0); pagesize = strtoul (optarg, &end, 0);
if (*end if (*end
|| (params.pagesize < 4096 && params.pagesize != 0) || (pagesize < 4096 && pagesize != 0)
|| params.pagesize != (params.pagesize & -params.pagesize)) || pagesize != (pagesize & -pagesize))
einfo (_("%P%F: invalid pagesize `%s'\''\n"), optarg); einfo (_("%P%F: invalid pagesize `%s'\''\n"), optarg);
} }
break; break;