[PATCH] ld: Default the maximum page size to the common page size for -z separate-code

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] ld: Default the maximum page size to the common page size for -z separate-code

H.J. Lu
When -z separate-code is used, code segment is aligned and padded to
the maximum page size on disk.  This patch defaults the maximum page
size to the common page size for -z separate-code to reduce file size.

OK for master?

H.J.
---
        * ld.h (ld_config_type): Add maxpagesize_specified.
        * ldmain.c (main): Set config.maxpagesize_specified to FALSE.
        * emultempl/elf32.em (gld${EMULATION_NAME}_after_parse): Default
        config.maxpagesize to config.commonpagesize for -z separate-code.
        (gld${EMULATION_NAME}_handle_option): Set
        config.maxpagesize_specified to TRUE for -z max-page-size.
        * testsuite/ld-elf/pr22393-1g.d: New file.
        * testsuite/ld-x86-64/pr22393-4.d: Likewise.
        * testsuite/ld-x86-64/pr22393-4.s: Likewise.
        * testsuite/ld-x86-64/x86-64.exp: Run pr22393-4.
---
 ld/emultempl/elf32.em              |  6 ++++++
 ld/ld.h                            |  3 +++
 ld/ldmain.c                        |  1 +
 ld/testsuite/ld-elf/pr22393-1g.d   |  9 +++++++++
 ld/testsuite/ld-x86-64/pr22393-4.d |  7 +++++++
 ld/testsuite/ld-x86-64/pr22393-4.s | 11 +++++++++++
 ld/testsuite/ld-x86-64/x86-64.exp  |  1 +
 7 files changed, 38 insertions(+)
 create mode 100644 ld/testsuite/ld-elf/pr22393-1g.d
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-4.d
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-4.s

diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 8ff19bf883..036fba5b6e 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -120,6 +120,11 @@ gld${EMULATION_NAME}_after_parse (void)
   if (bfd_link_pie (&link_info))
     link_info.flags_1 |= (bfd_vma) DF_1_PIE;
 
+  /* When -z separate-code is used, default the maximum page size to the
+     common page size.  */
+  if (link_info.separate_code && !config.maxpagesize_specified)
+    config.maxpagesize = config.commonpagesize;
+
   if (bfd_link_executable (&link_info)
       && link_info.nointerp)
     {
@@ -2732,6 +2737,7 @@ fragment <<EOF
  {
   char *end;
 
+  config.maxpagesize_specified = TRUE;
   config.maxpagesize = strtoul (optarg + 14, &end, 0);
   if (*end || (config.maxpagesize & (config.maxpagesize - 1)) != 0)
     einfo (_("%P%F: invalid maxium page size \`%s'\n"),
diff --git a/ld/ld.h b/ld/ld.h
index ba914b921e..27747162f9 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -318,6 +318,9 @@ typedef struct
 
   /* The common page size for ELF.  */
   bfd_vma commonpagesize;
+
+  /* The maximum page size for ELF is set from command-line.  */
+  bfd_boolean maxpagesize_specified;
 } ld_config_type;
 
 extern ld_config_type config;
diff --git a/ld/ldmain.c b/ld/ldmain.c
index c473ed24c3..7cca4fbf58 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -299,6 +299,7 @@ main (int argc, char **argv)
   ldemul_choose_mode (emulation);
   default_target = ldemul_choose_target (argc, argv);
   config.maxpagesize = bfd_emul_get_maxpagesize (default_target);
+  config.maxpagesize_specified = FALSE;
   config.commonpagesize = bfd_emul_get_commonpagesize (default_target);
   lang_init ();
   ldexp_init ();
diff --git a/ld/testsuite/ld-elf/pr22393-1g.d b/ld/testsuite/ld-elf/pr22393-1g.d
new file mode 100644
index 0000000000..2bff2542ed
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-1g.d
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -z separate-code -z max-page-size=0x400000
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#...
+  LOAD+.*0x400000
+  LOAD+.*0x400000
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr22393-4.d b/ld/testsuite/ld-x86-64/pr22393-4.d
new file mode 100644
index 0000000000..3a077e0efd
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr22393-4.d
@@ -0,0 +1,7 @@
+#ld: -z separate-code
+#readelf: -l --wide
+
+#...
+  LOAD+.*0x1000
+  LOAD+.*0x1000
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr22393-4.s b/ld/testsuite/ld-x86-64/pr22393-4.s
new file mode 100644
index 0000000000..f4dff5caa2
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr22393-4.s
@@ -0,0 +1,11 @@
+ .text
+ .globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .globl _start
+ .type _start, @function
+_start:
+ movl foo@GOTPCREL(%rip), %eax
+ .size _start, .-_start
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index e7f338ee11..d2bab67c6b 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -379,6 +379,7 @@ run_dump_test "pr22115-1c-x32"
 run_dump_test "pr22115-1d"
 run_dump_test "pr22115-1d-x32"
 run_dump_test "pr22135"
+run_dump_test "pr22393-4"
 
 if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
     return
--
2.14.3

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] ld: Default the maximum page size to the common page size for -z separate-code

Alan Modra-3
On Thu, Jan 11, 2018 at 09:13:19PM -0800, H.J. Lu wrote:
> When -z separate-code is used, code segment is aligned and padded to
> the maximum page size on disk.  This patch defaults the maximum page
> size to the common page size for -z separate-code to reduce file size.

I think this is a bad idea.  Options should have as few magical
side-effects as possible.  If you want -z separate-code to align to
common-page-size, then do that in the script (and document in
ld.texinfo that code separation is only effective for system page size
up to common-page-size, like -z relro).

--
Alan Modra
Australia Development Lab, IBM
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] ld: Default the maximum page size to the common page size for -z separate-code

H.J. Lu-30
On Thu, Jan 11, 2018 at 9:55 PM, Alan Modra <[hidden email]> wrote:

> On Thu, Jan 11, 2018 at 09:13:19PM -0800, H.J. Lu wrote:
>> When -z separate-code is used, code segment is aligned and padded to
>> the maximum page size on disk.  This patch defaults the maximum page
>> size to the common page size for -z separate-code to reduce file size.
>
> I think this is a bad idea.  Options should have as few magical
> side-effects as possible.  If you want -z separate-code to align to
> common-page-size, then do that in the script (and document in
> ld.texinfo that code separation is only effective for system page size
> up to common-page-size, like -z relro).
>

RELRO segment is optional.  Ignoring it at run-time won't crash
the program.

How about adding ELF_MAXCODEPAGESIZE which defaults to
ELF_COMMONPAGESIZE and -z max-code-page-size?


--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] ld: Default the maximum page size to the common page size for -z separate-code

H.J. Lu-30
On Fri, Jan 12, 2018 at 3:39 AM, H.J. Lu <[hidden email]> wrote:

> On Thu, Jan 11, 2018 at 9:55 PM, Alan Modra <[hidden email]> wrote:
>> On Thu, Jan 11, 2018 at 09:13:19PM -0800, H.J. Lu wrote:
>>> When -z separate-code is used, code segment is aligned and padded to
>>> the maximum page size on disk.  This patch defaults the maximum page
>>> size to the common page size for -z separate-code to reduce file size.
>>
>> I think this is a bad idea.  Options should have as few magical
>> side-effects as possible.  If you want -z separate-code to align to
>> common-page-size, then do that in the script (and document in
>> ld.texinfo that code separation is only effective for system page size
>> up to common-page-size, like -z relro).
>>
>
> RELRO segment is optional.  Ignoring it at run-time won't crash
> the program.
>
> How about adding ELF_MAXCODEPAGESIZE which defaults to
> ELF_COMMONPAGESIZE and -z max-code-page-size?
>

Never mind.  This is the same approach with a different implementation.
The problem with aligning code segment to common-page-size while
keeping the maximum page size is we don't get code separation with
the maximum page size is used:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x00200 0x00200 R   0x200000
  LOAD           0x001000 0x00001000 0x00001000 0x00036 0x00036 R E 0x200000
  LOAD           0x002000 0x00202000 0x00202000 0x00064 0x00064 R   0x200000
  LOAD           0x002f80 0x00402f80 0x00402f80 0x000a0 0x000a0 RW  0x200000

The program runs with 2MB page size.  But the 2MB code page contains
RO and RW data.

--
H.J.