powerpc common-page-size
authorAlan Modra <amodra@gmail.com>
Sat, 14 Apr 2018 06:53:56 +0000 (16:23 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 14 Apr 2018 08:26:40 +0000 (17:56 +0930)
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.

12 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/bfd.c
bfd/elf-bfd.h
bfd/elf32-ppc.c
bfd/elf64-ppc.c
bfd/elfxx-target.h
ld/ChangeLog
ld/ldemul.c
ld/ldmain.c
ld/testsuite/ld-powerpc/ppc476-shared.d
ld/testsuite/ld-powerpc/ppc476-shared2.d

index c34cff6844f661787ede5f43ad548e2d6d873949..c8ee895988fe9e4f606864d483f6e9c4ce3fa380 100644 (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>
 
        * elf32-ppc.c (ELF_MAXPAGESIZE, ELF_COMMONPAGESIZE): Don't depend
index 3f5d38bedfded8e0d05caba933ffabce7b2683b2..fc07ded0c4a49a04f0c90d76756a7f6ea07577e0 100644 (file)
@@ -7251,7 +7251,7 @@ bfd_vma bfd_emul_get_maxpagesize (const char *);
 
 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);
 
index a1b6bf10b20c751b17aca0b94e81c532d6088392..31bcc34cc3b84f6b1912dfd63655273a8b06c6f8 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2137,7 +2137,7 @@ FUNCTION
        bfd_emul_get_commonpagesize
 
 SYNOPSIS
-       bfd_vma bfd_emul_get_commonpagesize (const char *);
+       bfd_vma bfd_emul_get_commonpagesize (const char *, bfd_boolean);
 
 DESCRIPTION
        Returns the common page size, in bytes, as determined by
@@ -2148,15 +2148,22 @@ RETURNS
 */
 
 bfd_vma
-bfd_emul_get_commonpagesize (const char *emul)
+bfd_emul_get_commonpagesize (const char *emul, bfd_boolean relro)
 {
   const bfd_target *target;
 
   target = bfd_find_target (emul, NULL);
   if (target != NULL
       && 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;
 }
 
index afd6982a92b07e8895b83e53c64b845669faab93..9c900b7656c8e68e9adcdd01a3f627f81c168d97 100644 (file)
@@ -864,6 +864,9 @@ struct elf_backend_data
   /* The common page size for this backend.  */
   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.  */
   flagword dynamic_sec_flags;
 
index 8629380dd85f635d5fad1a458d1276af89c9dd57..0438af4e2a741bd151b3c8c541c14a11215b838c 100644 (file)
@@ -11390,8 +11390,8 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
 #define ELF_TARGET_ID          PPC32_ELF_DATA
 #define ELF_MACHINE_CODE       EM_PPC
 #define ELF_MAXPAGESIZE                0x10000
-#define ELF_COMMONPAGESIZE     0x10000
-#define ELF_MINPAGESIZE                0x1000
+#define ELF_COMMONPAGESIZE     0x1000
+#define ELF_RELROPAGESIZE      ELF_MAXPAGESIZE
 #define elf_info_to_howto      ppc_elf_info_to_howto
 
 #ifdef  EM_CYGNUS_POWERPC
index 59c29226662e827da21b588706df75a8fb231c1f..971adc4960cf4a5ad707233b342a047a995d401f 100644 (file)
@@ -64,7 +64,8 @@ static bfd_vma opd_entry_value
 #define ELF_TARGET_ID          PPC64_ELF_DATA
 #define ELF_MACHINE_CODE       EM_PPC64
 #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_backend_want_got_sym 0
index ccab02d39d7ea6a23600d33ee205ee79c0779dde..89efed3a5e4d5d0950ec8054091dd55e1db8ad16 100644 (file)
 #define ELF_COMMONPAGESIZE ELF_MAXPAGESIZE
 #endif
 
+#ifndef ELF_RELROPAGESIZE
+#define ELF_RELROPAGESIZE ELF_COMMONPAGESIZE
+#endif
+
 #ifndef ELF_MINPAGESIZE
 #define ELF_MINPAGESIZE ELF_COMMONPAGESIZE
 #endif
 #if ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
 # error ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
 #endif
+#if ELF_RELROPAGESIZE > ELF_MAXPAGESIZE
+# error ELF_RELROPAGESIZE > ELF_MAXPAGESIZE
+#endif
 #if ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
 # error ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
 #endif
+#if ELF_MINPAGESIZE > ELF_RELROPAGESIZE
+# error ELF_MINPAGESIZE > ELF_RELROPAGESIZE
+#endif
 
 #ifndef ELF_DYNAMIC_SEC_FLAGS
 /* 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_MINPAGESIZE,             /* minpagesize */
   ELF_COMMONPAGESIZE,          /* commonpagesize */
+  ELF_RELROPAGESIZE,           /* commonpagesize to use with -z relro */
   ELF_DYNAMIC_SEC_FLAGS,       /* dynamic_sec_flags */
   elf_backend_arch_data,
   elf_info_to_howto,
index 9d5bc2d8dd34317cfff4ce8ae2f39c4fe2f08124..d7f3e181ee95ab987d73d676fd01472783fb037b 100644 (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>
 
        * emulparams/elf32ppcwindiss.sh: Rewrite to use elf32ppc.sh.
index 6e5b0dee5da72cd347495e1a8d783492ec3d0785..cd6743dad4562853e8ca5fc6b00b5cb295504b14 100644 (file)
@@ -225,6 +225,11 @@ after_parse_default (void)
       if (!is_vma)
        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
index 6527613c983a1c33152090eb26579832424dcd68..43602fe85a46a12aa491c7db8f5b7deb5f39daf1 100644 (file)
@@ -305,8 +305,6 @@ main (int argc, char **argv)
   emulation = get_emulation (argc, argv);
   ldemul_choose_mode (emulation);
   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 ();
   ldexp_init ();
   ldemul_before_parse ();
index 72f8a3d3beb810e49c2a064f182bf0d2a6e21a75..7953cb44e25a6d7254d677cc5c57e98c1e645bae 100644 (file)
@@ -1,6 +1,6 @@
 #source: ppc476-shared.s
 #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
 #target: powerpc*-*-*
 
index 5bf0a035cfd39aac47a59322fc2612b96fc7633a..26a5c41f9887ca2e4f68de2da868bf6f462e3f22 100644 (file)
@@ -1,6 +1,6 @@
 #source: ppc476-shared.s
 #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
 #target: powerpc*-*-*