powerpc common-page-size

max-page-size only matters for demand paged executables or shared
libraries, and the ideal size is the largest value used by your
operating system.  Values larger than necessary just waste file space
and memory.  common-page-size also affects file and memory size,
trading a possible small increase in file size for a decrease in
memory size when the operating system is using a common-page-size
page.  With a powerpc max-page-size of 64k and common-page-size of 4k
many executables will use no more memory pages when the system page
size is 4k than an executable linked with -z max-page-size=0x1000,
yet will still run on a system using 64k pages.  However, when running
on a system using 64k pages relro protection will not be completely
effective.

Due to the relro problem, powerpc binutils has been using a default
common-page-size of 64k since 2014-12-18 (git commit 04c6a44c7),
leading to complaints about increased file and memory sizes.  People
not using relro do have a valid reason to complain..

So this patch introduces an extra back-end value to use as the default
for common-page-size when generating relro executables, and enables
the support for powerpc.  Non relro executables will now be generated
with a default common-page-size of 4k.

bfd/
	* elf-bfd.h (struct elf_backend_data): Add relropagesize.
	* elfxx-target.h (ELF_RELROPAGESIZE): Provide default and
	sanity test.
	(elfNN_bed): Init relropagesize.
	* bfd.c (bfd_emul_get_commonpagesize): Add boolean param to
	select relropagesize.
	* elf32-ppc.c (ELF_COMMONPAGESIZE): Define as 0x1000.
	(ELF_RELROPAGESIZE): Define as ELF_MAXPAGESIZE.
	(ELF_MINPAGESIZE): Don't define.
	* elf64-ppc.c (ELF_COMMONPAGESIZE): Define as 0x1000.
	(ELF_RELROPAGESIZE): Define as ELF_MAXPAGESIZE.
	* bfd-in2.h: Regenerate.
ld/
	* ldmain.c (main): Move config.maxpagesize and
	config.commonpagesize initialization to..
	* ldemul.c (after_parse_default): ..here.
	* testsuite/ld-powerpc/ppc476-shared.d: Pass -z common-page-size.
	* testsuite/ld-powerpc/ppc476-shared2.d: Likewise.
This commit is contained in:
Alan Modra 2018-04-14 16:23:56 +09:30
parent 03aa968462
commit 702d167134
12 changed files with 59 additions and 11 deletions

View File

@ -1,3 +1,18 @@
2018-04-14 Alan Modra <amodra@gmail.com>
* elf-bfd.h (struct elf_backend_data): Add relropagesize.
* elfxx-target.h (ELF_RELROPAGESIZE): Provide default and
sanity test.
(elfNN_bed): Init relropagesize.
* bfd.c (bfd_emul_get_commonpagesize): Add boolean param to
select relropagesize.
* elf32-ppc.c (ELF_COMMONPAGESIZE): Define as 0x1000.
(ELF_RELROPAGESIZE): Define as ELF_MAXPAGESIZE.
(ELF_MINPAGESIZE): Don't define.
* elf64-ppc.c (ELF_COMMONPAGESIZE): Define as 0x1000.
(ELF_RELROPAGESIZE): Define as ELF_MAXPAGESIZE.
* bfd-in2.h: Regenerate.
2018-04-14 Alan Modra <amodra@gmail.com> 2018-04-14 Alan Modra <amodra@gmail.com>
* elf32-ppc.c (ELF_MAXPAGESIZE, ELF_COMMONPAGESIZE): Don't depend * elf32-ppc.c (ELF_MAXPAGESIZE, ELF_COMMONPAGESIZE): Don't depend

View File

@ -7251,7 +7251,7 @@ bfd_vma bfd_emul_get_maxpagesize (const char *);
void bfd_emul_set_maxpagesize (const char *, bfd_vma); void bfd_emul_set_maxpagesize (const char *, bfd_vma);
bfd_vma bfd_emul_get_commonpagesize (const char *); bfd_vma bfd_emul_get_commonpagesize (const char *, bfd_boolean);
void bfd_emul_set_commonpagesize (const char *, bfd_vma); void bfd_emul_set_commonpagesize (const char *, bfd_vma);

View File

@ -2137,7 +2137,7 @@ FUNCTION
bfd_emul_get_commonpagesize bfd_emul_get_commonpagesize
SYNOPSIS SYNOPSIS
bfd_vma bfd_emul_get_commonpagesize (const char *); bfd_vma bfd_emul_get_commonpagesize (const char *, bfd_boolean);
DESCRIPTION DESCRIPTION
Returns the common page size, in bytes, as determined by Returns the common page size, in bytes, as determined by
@ -2148,15 +2148,22 @@ RETURNS
*/ */
bfd_vma bfd_vma
bfd_emul_get_commonpagesize (const char *emul) bfd_emul_get_commonpagesize (const char *emul, bfd_boolean relro)
{ {
const bfd_target *target; const bfd_target *target;
target = bfd_find_target (emul, NULL); target = bfd_find_target (emul, NULL);
if (target != NULL if (target != NULL
&& target->flavour == bfd_target_elf_flavour) && target->flavour == bfd_target_elf_flavour)
return xvec_get_elf_backend_data (target)->commonpagesize; {
const struct elf_backend_data *bed;
bed = xvec_get_elf_backend_data (target);
if (relro)
return bed->relropagesize;
else
return bed->commonpagesize;
}
return 0; return 0;
} }

View File

@ -864,6 +864,9 @@ struct elf_backend_data
/* The common page size for this backend. */ /* The common page size for this backend. */
bfd_vma commonpagesize; bfd_vma commonpagesize;
/* The value of commonpagesize to use when -z relro for this backend. */
bfd_vma relropagesize;
/* The BFD flags applied to sections created for dynamic linking. */ /* The BFD flags applied to sections created for dynamic linking. */
flagword dynamic_sec_flags; flagword dynamic_sec_flags;

View File

@ -11390,8 +11390,8 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
#define ELF_TARGET_ID PPC32_ELF_DATA #define ELF_TARGET_ID PPC32_ELF_DATA
#define ELF_MACHINE_CODE EM_PPC #define ELF_MACHINE_CODE EM_PPC
#define ELF_MAXPAGESIZE 0x10000 #define ELF_MAXPAGESIZE 0x10000
#define ELF_COMMONPAGESIZE 0x10000 #define ELF_COMMONPAGESIZE 0x1000
#define ELF_MINPAGESIZE 0x1000 #define ELF_RELROPAGESIZE ELF_MAXPAGESIZE
#define elf_info_to_howto ppc_elf_info_to_howto #define elf_info_to_howto ppc_elf_info_to_howto
#ifdef EM_CYGNUS_POWERPC #ifdef EM_CYGNUS_POWERPC

View File

@ -64,7 +64,8 @@ static bfd_vma opd_entry_value
#define ELF_TARGET_ID PPC64_ELF_DATA #define ELF_TARGET_ID PPC64_ELF_DATA
#define ELF_MACHINE_CODE EM_PPC64 #define ELF_MACHINE_CODE EM_PPC64
#define ELF_MAXPAGESIZE 0x10000 #define ELF_MAXPAGESIZE 0x10000
#define ELF_COMMONPAGESIZE 0x10000 #define ELF_COMMONPAGESIZE 0x1000
#define ELF_RELROPAGESIZE ELF_MAXPAGESIZE
#define elf_info_to_howto ppc64_elf_info_to_howto #define elf_info_to_howto ppc64_elf_info_to_howto
#define elf_backend_want_got_sym 0 #define elf_backend_want_got_sym 0

View File

@ -367,6 +367,10 @@
#define ELF_COMMONPAGESIZE ELF_MAXPAGESIZE #define ELF_COMMONPAGESIZE ELF_MAXPAGESIZE
#endif #endif
#ifndef ELF_RELROPAGESIZE
#define ELF_RELROPAGESIZE ELF_COMMONPAGESIZE
#endif
#ifndef ELF_MINPAGESIZE #ifndef ELF_MINPAGESIZE
#define ELF_MINPAGESIZE ELF_COMMONPAGESIZE #define ELF_MINPAGESIZE ELF_COMMONPAGESIZE
#endif #endif
@ -374,9 +378,15 @@
#if ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE #if ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
# error ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE # error ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
#endif #endif
#if ELF_RELROPAGESIZE > ELF_MAXPAGESIZE
# error ELF_RELROPAGESIZE > ELF_MAXPAGESIZE
#endif
#if ELF_MINPAGESIZE > ELF_COMMONPAGESIZE #if ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
# error ELF_MINPAGESIZE > ELF_COMMONPAGESIZE # error ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
#endif #endif
#if ELF_MINPAGESIZE > ELF_RELROPAGESIZE
# error ELF_MINPAGESIZE > ELF_RELROPAGESIZE
#endif
#ifndef ELF_DYNAMIC_SEC_FLAGS #ifndef ELF_DYNAMIC_SEC_FLAGS
/* Note that we set the SEC_IN_MEMORY flag for these sections. */ /* Note that we set the SEC_IN_MEMORY flag for these sections. */
@ -757,6 +767,7 @@ static struct elf_backend_data elfNN_bed =
ELF_MAXPAGESIZE, /* maxpagesize */ ELF_MAXPAGESIZE, /* maxpagesize */
ELF_MINPAGESIZE, /* minpagesize */ ELF_MINPAGESIZE, /* minpagesize */
ELF_COMMONPAGESIZE, /* commonpagesize */ ELF_COMMONPAGESIZE, /* commonpagesize */
ELF_RELROPAGESIZE, /* commonpagesize to use with -z relro */
ELF_DYNAMIC_SEC_FLAGS, /* dynamic_sec_flags */ ELF_DYNAMIC_SEC_FLAGS, /* dynamic_sec_flags */
elf_backend_arch_data, elf_backend_arch_data,
elf_info_to_howto, elf_info_to_howto,

View File

@ -1,3 +1,11 @@
2018-04-14 Alan Modra <amodra@gmail.com>
* ldmain.c (main): Move config.maxpagesize and
config.commonpagesize initialization to..
* ldemul.c (after_parse_default): ..here.
* testsuite/ld-powerpc/ppc476-shared.d: Pass -z common-page-size.
* testsuite/ld-powerpc/ppc476-shared2.d: Likewise.
2018-04-14 Alan Modra <amodra@gmail.com> 2018-04-14 Alan Modra <amodra@gmail.com>
* emulparams/elf32ppcwindiss.sh: Rewrite to use elf32ppc.sh. * emulparams/elf32ppcwindiss.sh: Rewrite to use elf32ppc.sh.

View File

@ -225,6 +225,11 @@ after_parse_default (void)
if (!is_vma) if (!is_vma)
ldlang_add_undef (entry_symbol.name, entry_from_cmdline); ldlang_add_undef (entry_symbol.name, entry_from_cmdline);
} }
if (config.maxpagesize == 0)
config.maxpagesize = bfd_emul_get_maxpagesize (default_target);
if (config.commonpagesize == 0)
config.commonpagesize = bfd_emul_get_commonpagesize (default_target,
link_info.relro);
} }
void void

View File

@ -305,8 +305,6 @@ main (int argc, char **argv)
emulation = get_emulation (argc, argv); emulation = get_emulation (argc, argv);
ldemul_choose_mode (emulation); ldemul_choose_mode (emulation);
default_target = ldemul_choose_target (argc, argv); default_target = ldemul_choose_target (argc, argv);
config.maxpagesize = bfd_emul_get_maxpagesize (default_target);
config.commonpagesize = bfd_emul_get_commonpagesize (default_target);
lang_init (); lang_init ();
ldexp_init (); ldexp_init ();
ldemul_before_parse (); ldemul_before_parse ();

View File

@ -1,6 +1,6 @@
#source: ppc476-shared.s #source: ppc476-shared.s
#as: -a32 #as: -a32
#ld: -melf32ppc -q -shared --ppc476-workaround -T ppc476-shared.lnk #ld: -melf32ppc -q -shared -z common-page-size=0x10000 --ppc476-workaround -T ppc476-shared.lnk
#objdump: -dr #objdump: -dr
#target: powerpc*-*-* #target: powerpc*-*-*

View File

@ -1,6 +1,6 @@
#source: ppc476-shared.s #source: ppc476-shared.s
#as: -a32 #as: -a32
#ld: -melf32ppc -shared --ppc476-workaround -T ppc476-shared.lnk #ld: -melf32ppc -shared -z common-page-size=0x10000 --ppc476-workaround -T ppc476-shared.lnk
#objdump: -R #objdump: -R
#target: powerpc*-*-* #target: powerpc*-*-*