[PATCH 0/4] ld: Add "-z separate-code" option to ELF linker

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

[PATCH 0/4] ld: Add "-z separate-code" option to ELF linker

H.J. Lu-30
The new "-z separate-code" option will generate separate code LOAD
segment which must be in wholly disjoint pages from any other data.

When generating separate code LOAD segment, create a new LOAD segment
if the previous section contains text and the current section doesn't
or vice versa:

Elf file type is DYN (Shared object file)
Entry point 0x200020
There are 7 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x00200 0x00200 R   0x200000
  LOAD           0x200000 0x00200000 0x00200000 0x00036 0x00036 R E 0x200000
  LOAD           0x400000 0x00400000 0x00400000 0x00064 0x00064 R   0x200000
  LOAD           0x400f80 0x00600f80 0x00600f80 0x000a0 0x000a0 RW  0x200000
  DYNAMIC        0x400f80 0x00600f80 0x00600f80 0x00080 0x00080 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x400f80 0x00600f80 0x00600f80 0x00080 0x00080 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .hash .gnu.hash .dynsym .dynstr .rela.plt
   01     .plt .text
   02     .rodata .eh_frame
   03     .dynamic .got.plt
   04     .dynamic
   05
   06     .dynamic

to prevent fetching or executing data in code pages as instructions.

Also don't put a writable section in a read-only segment if there is a
RELRO segment.

Since code segment is aligned and padded to the maximum page size on
disk, the minimum file size is bigger than the maximum page size which
is 2MB (0x200000):

-rwxr-xr-x 1 hjl hjl 4201932 Jan 10 10:41 libfoo.so

"-z max-page-size=0x1000" can be used to reduce the maximum page size to
4KB (0x1000):

-rwxr-xr-x 1 hjl hjl   15820 Jan 10 10:44 libfoo.so

H.J. Lu (4):
  ld: Add "-z separate-code" option to ELF linker
  ld: Create a new LOAD segment for separate code segment
  ld: Add tests for -z separate-code and -z noseparate-code
  x86-64: Add tests for -z separate-code -z max-page-size=0x1000

 bfd/elf.c                            |  32 ++++++++---
 include/bfdlink.h                    |   3 ++
 ld/NEWS                              |   2 +
 ld/emultempl/elf32.em                | 100 +++++++++++++++++++++++++++++++----
 ld/genscripts.sh                     |  76 +++++++++++++++++++++++---
 ld/ld.texinfo                        |   7 +++
 ld/lexsup.c                          |   4 ++
 ld/scripttempl/elf.sc                |  22 ++++++--
 ld/testsuite/ld-elf/pr16322.d        |   2 +-
 ld/testsuite/ld-elf/pr22393-1.s      |  21 ++++++++
 ld/testsuite/ld-elf/pr22393-1a.d     |   9 ++++
 ld/testsuite/ld-elf/pr22393-1b.d     |   9 ++++
 ld/testsuite/ld-elf/pr22393-1c.d     |   9 ++++
 ld/testsuite/ld-elf/pr22393-1d.d     |   9 ++++
 ld/testsuite/ld-elf/pr22393-1e.d     |   9 ++++
 ld/testsuite/ld-elf/pr22393-1f.d     |   9 ++++
 ld/testsuite/ld-elf/pr22393-2a.c     |   7 +++
 ld/testsuite/ld-elf/pr22393-2a.rd    |   9 ++++
 ld/testsuite/ld-elf/pr22393-2b.c     |   7 +++
 ld/testsuite/ld-elf/pr22393-2b.rd    |   9 ++++
 ld/testsuite/ld-elf/shared.exp       |  71 +++++++++++++++++++++++++
 ld/testsuite/ld-x86-64/pr22393-3a.c  |   7 +++
 ld/testsuite/ld-x86-64/pr22393-3a.rd |   9 ++++
 ld/testsuite/ld-x86-64/pr22393-3b.c  |   7 +++
 ld/testsuite/ld-x86-64/pr22393-3b.rd |   9 ++++
 ld/testsuite/ld-x86-64/x86-64.exp    |  71 +++++++++++++++++++++++++
 26 files changed, 501 insertions(+), 28 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr22393-1.s
 create mode 100644 ld/testsuite/ld-elf/pr22393-1a.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1b.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1c.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1d.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1e.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1f.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-2a.c
 create mode 100644 ld/testsuite/ld-elf/pr22393-2a.rd
 create mode 100644 ld/testsuite/ld-elf/pr22393-2b.c
 create mode 100644 ld/testsuite/ld-elf/pr22393-2b.rd
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-3a.c
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-3a.rd
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-3b.c
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-3b.rd

--
2.14.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 1/4] ld: Add "-z separate-code" option to ELF linker

H.J. Lu-30
The new "-z separate-code" option will generate separate code LOAD
segment which must be in wholly disjoint pages from any other data.

include/

        PR ld/22393
        * bfdlink.h (bfd_link_info): Add separate_code.

ld/

        PR ld/22393
        * NEWS: Mention "-z separate-code".
        * emultempl/elf32.em (gld${EMULATION_NAME}_get_script): Get
        builtin linker scripts and return linker scripts from disk for
        "-z separate-code".
        (gld${EMULATION_NAME}_handle_option): Handle "-z separate-code"
        and "-z noseparate-code".
        * genscripts.sh: Generate linker scripts for "-z separate-code".
        (LD_FLAG): Set to *textonly for "-z separate-code".
        * ld.texinfo: Document "-z separate-code".
        * lexsup.c (elf_shlib_list_options): Add linker help messsages
        for "-z separate-code" and "-z noseparate-code".
        * scripttempl/elf.sc (SEPARATE_TEXT): New
        (TEXT_SEGMENT_ALIGN): Likewise.
        Use ${TEXT_SEGMENT_ALIGN} to align and pad text segment to
        ${MAXPAGESIZE}.
---
 include/bfdlink.h     |   3 ++
 ld/NEWS               |   2 +
 ld/emultempl/elf32.em | 100 +++++++++++++++++++++++++++++++++++++++++++++-----
 ld/genscripts.sh      |  76 ++++++++++++++++++++++++++++++++++----
 ld/ld.texinfo         |   7 ++++
 ld/lexsup.c           |   4 ++
 ld/scripttempl/elf.sc |  22 +++++++++--
 7 files changed, 194 insertions(+), 20 deletions(-)

diff --git a/include/bfdlink.h b/include/bfdlink.h
index f5c23de0da..5d637acbab 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -386,6 +386,9 @@ struct bfd_link_info
   /* TRUE if PT_GNU_RELRO segment should be created.  */
   unsigned int relro: 1;
 
+  /* TRUE if separate code segment should be created.  */
+  unsigned int separate_code: 1;
+
   /* Nonzero if .eh_frame_hdr section and PT_GNU_EH_FRAME ELF segment
      should be created.  1 for DWARF2 tables, 2 for compact tables.  */
   unsigned int eh_frame_hdr_type: 2;
diff --git a/ld/NEWS b/ld/NEWS
index 8326088b25..0d40ccd494 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,4 +1,6 @@
 -*- text -*-
+* Add -z separate-code to generate separate code PT_LOAD segment.
+
 * Add -z globalaudit command line option to force audit libraries to be run
   for every dynamic object loaded by an executable - provided that the loader
   supports this functionality.
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index a12aefa9cb..8ff19bf883 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -2367,13 +2367,25 @@ if test -n "$GENERATE_PIE_SCRIPT" ; then
 if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
 echo '  ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
 echo '             && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdwe >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc' >> e${EMULATION_NAME}.c
 echo '             && link_info.relro' >> e${EMULATION_NAME}.c
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xdw >> e${EMULATION_NAME}.c
 echo '  ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdce >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
 echo '             && link_info.combreloc) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c
 fi
+echo '  ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xde >> e${EMULATION_NAME}.c
 echo '  ; else if (bfd_link_pie (&link_info)) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c
 fi
@@ -2381,24 +2393,45 @@ if test -n "$GENERATE_SHLIB_SCRIPT" ; then
 if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
 echo '  ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
 echo '             && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xswe >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc' >> e${EMULATION_NAME}.c
 echo '             && link_info.relro' >> e${EMULATION_NAME}.c
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xsw >> e${EMULATION_NAME}.c
 echo '  ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsce >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
 echo '             && link_info.combreloc) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c
 fi
+echo '  ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xse >> e${EMULATION_NAME}.c
 echo '  ; else if (bfd_link_dll (&link_info)) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c
 fi
 if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
 echo '  ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xwe >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
 echo '             && link_info.relro' >> e${EMULATION_NAME}.c
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xw >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xce >> e${EMULATION_NAME}.c
 echo '  ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c
 fi
+echo '  ; else if (link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xe >> e${EMULATION_NAME}.c
 echo '  ; else return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
 echo '; }' >> e${EMULATION_NAME}.c
@@ -2431,15 +2464,30 @@ fragment <<EOF
    && link_info.combreloc
    && link_info.relro
    && (link_info.flags & DF_BIND_NOW))
-    return "ldscripts/${EMULATION_NAME}.xdw";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xdwe";
+      else
+ return "ldscripts/${EMULATION_NAME}.xdw";
+    }
   else if (bfd_link_pie (&link_info)
    && link_info.combreloc)
-    return "ldscripts/${EMULATION_NAME}.xdc";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xdce";
+      else
+ return "ldscripts/${EMULATION_NAME}.xdc";
+    }
 EOF
 fi
 fragment <<EOF
   else if (bfd_link_pie (&link_info))
-    return "ldscripts/${EMULATION_NAME}.xd";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xde";
+      else
+ return "ldscripts/${EMULATION_NAME}.xd";
+    }
 EOF
 fi
 if test -n "$GENERATE_SHLIB_SCRIPT" ; then
@@ -2447,28 +2495,58 @@ if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
 fragment <<EOF
   else if (bfd_link_dll (&link_info) && link_info.combreloc
    && link_info.relro && (link_info.flags & DF_BIND_NOW))
-    return "ldscripts/${EMULATION_NAME}.xsw";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xswe";
+      else
+ return "ldscripts/${EMULATION_NAME}.xsw";
+    }
   else if (bfd_link_dll (&link_info) && link_info.combreloc)
-    return "ldscripts/${EMULATION_NAME}.xsc";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xsce";
+      else
+ return "ldscripts/${EMULATION_NAME}.xsc";
+    }
 EOF
 fi
 fragment <<EOF
   else if (bfd_link_dll (&link_info))
-    return "ldscripts/${EMULATION_NAME}.xs";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xse";
+      else
+ return "ldscripts/${EMULATION_NAME}.xs";
+    }
 EOF
 fi
 if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
 fragment <<EOF
   else if (link_info.combreloc && link_info.relro
    && (link_info.flags & DF_BIND_NOW))
-    return "ldscripts/${EMULATION_NAME}.xw";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xwe";
+      else
+ return "ldscripts/${EMULATION_NAME}.xw";
+    }
   else if (link_info.combreloc)
-    return "ldscripts/${EMULATION_NAME}.xc";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xce";
+      else
+ return "ldscripts/${EMULATION_NAME}.xc";
+    }
 EOF
 fi
 fragment <<EOF
   else
-    return "ldscripts/${EMULATION_NAME}.x";
+    {
+      if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xe";
+      else
+ return "ldscripts/${EMULATION_NAME}.x";
+    }
 }
 
 EOF
@@ -2738,6 +2816,10 @@ fragment <<EOF
  link_info.relro = TRUE;
       else if (strcmp (optarg, "norelro") == 0)
  link_info.relro = FALSE;
+      else if (strcmp (optarg, "separate-code") == 0)
+ link_info.separate_code = TRUE;
+      else if (strcmp (optarg, "noseparate-code") == 0)
+ link_info.separate_code = FALSE;
       else if (strcmp (optarg, "common") == 0)
  link_info.elf_stt_common = elf_stt_common;
       else if (strcmp (optarg, "nocommon") == 0)
diff --git a/ld/genscripts.sh b/ld/genscripts.sh
index 43ccf5eda4..8732422b3a 100755
--- a/ld/genscripts.sh
+++ b/ld/genscripts.sh
@@ -290,14 +290,20 @@ CONSTRUCTING=" "
   . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
 ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xu
 
-LD_FLAG=
 DATA_ALIGNMENT=${DATA_ALIGNMENT_}
 RELOCATING=" "
+LD_FLAG=
 ( echo "/* Default linker script, for normal executables */"
   . ${CUSTOMIZER_SCRIPT}
   . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
 ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.x
 
+LD_FLAG=textonly
+( echo "/* Script for -z separate-code: generate normal executables with separate code segment */"
+  . ${CUSTOMIZER_SCRIPT}
+  . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xe
+
 LD_FLAG=n
 DATA_ALIGNMENT=${DATA_ALIGNMENT_n}
 ( echo "/* Script for -n: mix text and data on same page */"
@@ -321,44 +327,78 @@ if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
     . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
   ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xc
   rm -f ${COMBRELOC}
-  LD_FLAG=w
+  LD_FLAG=ctextonly
+  COMBRELOC=ldscripts/${EMULATION_NAME}.xce.tmp
+  ( echo "/* Script for -z combreloc -z separate-code: combine and sort reloc sections with separate code segment */"
+    . ${CUSTOMIZER_SCRIPT}
+    . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+  ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xce
+  rm -f ${COMBRELOC}
   RELRO_NOW=" "
+  LD_FLAG=w
   COMBRELOC=ldscripts/${EMULATION_NAME}.xw.tmp
   ( echo "/* Script for -z combreloc -z now -z relro: combine and sort reloc sections */"
     . ${CUSTOMIZER_SCRIPT}
     . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
   ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xw
   rm -f ${COMBRELOC}
+  LD_FLAG=wtextonly
+  COMBRELOC=ldscripts/${EMULATION_NAME}.xwe.tmp
+  ( echo "/* Script for -z combreloc -z now -z relro -z separate-code: combine and sort reloc sections with separate code segment */"
+    . ${CUSTOMIZER_SCRIPT}
+    . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+  ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xwe
+  rm -f ${COMBRELOC}
   COMBRELOC=
   unset RELRO_NOW
 fi
 
 if test -n "$GENERATE_SHLIB_SCRIPT"; then
-  LD_FLAG=shared
   DATA_ALIGNMENT=${DATA_ALIGNMENT_s-${DATA_ALIGNMENT_}}
   CREATE_SHLIB=" "
+  LD_FLAG=shared
   (
     echo "/* Script for ld --shared: link shared library */"
     . ${CUSTOMIZER_SCRIPT}
     . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
   ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xs
+  LD_FLAG=sharedtextonly
+  (
+    echo "/* Script for ld --shared -z separate-code: link shared library with separate code segment */"
+    . ${CUSTOMIZER_SCRIPT}
+    . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+  ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xse
   if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
-    LD_FLAG=cshared
     DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
+    LD_FLAG=cshared
     COMBRELOC=ldscripts/${EMULATION_NAME}.xsc.tmp
     ( echo "/* Script for --shared -z combreloc: shared library, combine & sort relocs */"
       . ${CUSTOMIZER_SCRIPT}
       . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
     ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xsc
     rm -f ${COMBRELOC}
-    LD_FLAG=wshared
+    LD_FLAG=csharedtextonly
+    COMBRELOC=ldscripts/${EMULATION_NAME}.xsce.tmp
+    ( echo "/* Script for --shared -z combreloc -z separate-code: shared library, combine & sort relocs with separate code segment */"
+      . ${CUSTOMIZER_SCRIPT}
+      . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+    ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xsce
+    rm -f ${COMBRELOC}
     RELRO_NOW=" "
+    LD_FLAG=wshared
     COMBRELOC=ldscripts/${EMULATION_NAME}.xsw.tmp
     ( echo "/* Script for --shared -z combreloc -z now -z relro: shared library, combine & sort relocs */"
       . ${CUSTOMIZER_SCRIPT}
       . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
     ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xsw
     rm -f ${COMBRELOC}
+    LD_FLAG=wsharedtextonly
+    COMBRELOC=ldscripts/${EMULATION_NAME}.xswe.tmp
+    ( echo "/* Script for --shared -z combreloc -z now -z relro -z separate-code: shared library, combine & sort relocs with separate code segment */"
+      . ${CUSTOMIZER_SCRIPT}
+      . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+    ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xswe
+    rm -f ${COMBRELOC}
     COMBRELOC=
     unset RELRO_NOW
   fi
@@ -366,31 +406,51 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; then
 fi
 
 if test -n "$GENERATE_PIE_SCRIPT"; then
-  LD_FLAG=pie
   DATA_ALIGNMENT=${DATA_ALIGNMENT_s-${DATA_ALIGNMENT_}}
   CREATE_PIE=" "
+  LD_FLAG=pie
   (
     echo "/* Script for ld -pie: link position independent executable */"
     . ${CUSTOMIZER_SCRIPT}
     . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
   ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xd
+  LD_FLAG=pietextonly
+  (
+    echo "/* Script for ld -pie -z separate-code: link position independent executable with separate code segment */"
+    . ${CUSTOMIZER_SCRIPT}
+    . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+  ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xde
   if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
-    LD_FLAG=cpie
     DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
     COMBRELOC=ldscripts/${EMULATION_NAME}.xdc.tmp
+    LD_FLAG=cpie
     ( echo "/* Script for -pie -z combreloc: position independent executable, combine & sort relocs */"
       . ${CUSTOMIZER_SCRIPT}
       . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
     ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdc
     rm -f ${COMBRELOC}
-    LD_FLAG=wpie
+    LD_FLAG=cpietextonly
+    COMBRELOC=ldscripts/${EMULATION_NAME}.xdce.tmp
+    ( echo "/* Script for -pie -z combreloc -z separate-code: position independent executable, combine & sort relocs with separate code segment */"
+      . ${CUSTOMIZER_SCRIPT}
+      . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+    ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdce
+    rm -f ${COMBRELOC}
     RELRO_NOW=" "
+    LD_FLAG=wpie
     COMBRELOC=ldscripts/${EMULATION_NAME}.xdw.tmp
     ( echo "/* Script for -pie -z combreloc -z now -z relro: position independent executable, combine & sort relocs */"
       . ${CUSTOMIZER_SCRIPT}
       . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
     ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdw
     rm -f ${COMBRELOC}
+    LD_FLAG=wpietextonly
+    COMBRELOC=ldscripts/${EMULATION_NAME}.xdwe.tmp
+    ( echo "/* Script for -pie -z combreloc -z now -z relro -z separate-code: position independent executable, combine & sort relocs with separate code segment */"
+      . ${CUSTOMIZER_SCRIPT}
+      . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+    ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdwe
+    rm -f ${COMBRELOC}
     COMBRELOC=
     unset RELRO_NOW
   fi
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 4fd12bb213..8cd2bed340 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -1264,6 +1264,13 @@ relocation, if supported.  Specifying @samp{common-page-size} smaller
 than the system page size will render this protection ineffective.
 Don't create an ELF @code{PT_GNU_RELRO} segment if @samp{norelro}.
 
+@item separate-code
+@itemx noseparate-code
+Create separate code @code{PT_LOAD} segment header in the object.  This
+specifies a memory segment that should contain only instructions and must
+be in wholly disjoint pages from any other data.  Don't create separate
+code @code{PT_LOAD} segment if @samp{noseparate-code} is used.
+
 @item shstk
 Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK in .note.gnu.property section
 to indicate compatibility with Intel Shadow Stack.  Supported for
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 8ed7070c4a..f2191602d4 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1787,6 +1787,10 @@ elf_shlib_list_options (FILE *file)
   fprintf (file, _("\
   -z norelro                  Don't create RELRO program header (default)\n"));
 #endif
+  fprintf (file, _("\
+  -z separate-code            Create separate code program header\n"));
+  fprintf (file, _("\
+  -z noseparate-code          Don't create separate code program header (default)\n"));
   fprintf (file, _("\
   -z common                   Generate common symbols with STT_COMMON type\n"));
   fprintf (file, _("\
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 841a831437..136288ccb9 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -316,6 +316,17 @@ STACK=".stack        ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} :
 TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${TEXT_START_ADDR})"
 SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${SHLIB_TEXT_START_ADDR:-0})"
 
+# Don't bother with separate code segment when there are data sections
+# between .plt and .text.
+if test -z "$TINY_READONLY_SECTION"; then
+  case "$LD_FLAG" in
+    *textonly*)
+      SEPARATE_TEXT=yes
+      TEXT_SEGMENT_ALIGN=". = ALIGN(${MAXPAGESIZE});"
+      ;;
+  esac
+fi
+
 if [ -z "$SEPARATE_CODE" ]; then
   SIZEOF_HEADERS_CODE=" + SIZEOF_HEADERS"
 else
@@ -478,6 +489,8 @@ emit_dyn()
 test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
 
 cat <<EOF
+  ${RELOCATING+${TEXT_SEGMENT_ALIGN}}
+
   .init         ${RELOCATING-0}${RELOCATING+${INIT_ADDR}} :
   {
     ${RELOCATING+${INIT_START}}
@@ -508,9 +521,10 @@ cat <<EOF
   ${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
   ${RELOCATING+PROVIDE (_${ETEXT_NAME} = .);}
   ${RELOCATING+PROVIDE (${ETEXT_NAME} = .);}
+  ${RELOCATING+${TEXT_SEGMENT_ALIGN}}
 EOF
 
-if test -n "${SEPARATE_CODE}"; then
+if test -n "${SEPARATE_CODE}${SEPARATE_TEXT}"; then
   if test -n "${RODATA_ADDR}"; then
     RODATA_ADDR="\
 SEGMENT_START(\"rodata-segment\", ${RODATA_ADDR}) + SIZEOF_HEADERS"
@@ -532,8 +546,10 @@ SEGMENT_START(\"rodata-segment\", ${SHLIB_RODATA_ADDR}) + SIZEOF_HEADERS"
   ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_RODATA_ADDR};}}
   ${CREATE_PIE+${RELOCATING+. = ${SHLIB_RODATA_ADDR};}}
 EOF
-  emit_early_ro
-  emit_dyn
+  if test -n "${SEPARATE_CODE}"; then
+    emit_early_ro
+    emit_dyn
+  fi
 fi
 
 cat <<EOF
--
2.14.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 2/4] ld: Create a new LOAD segment for separate code segment

H.J. Lu-30
In reply to this post by H.J. Lu-30
When generating separate code LOAD segment, create a new LOAD segment
if the previous section contains text and the current section doesn't
or vice versa:

Elf file type is DYN (Shared object file)
Entry point 0x200020
There are 7 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x00200 0x00200 R   0x200000
  LOAD           0x200000 0x00200000 0x00200000 0x00036 0x00036 R E 0x200000
  LOAD           0x400000 0x00400000 0x00400000 0x00064 0x00064 R   0x200000
  LOAD           0x400f80 0x00600f80 0x00600f80 0x000a0 0x000a0 RW  0x200000
  DYNAMIC        0x400f80 0x00600f80 0x00600f80 0x00080 0x00080 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x400f80 0x00600f80 0x00600f80 0x00080 0x00080 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .hash .gnu.hash .dynsym .dynstr .rela.plt
   01     .plt .text
   02     .rodata .eh_frame
   03     .dynamic .got.plt
   04     .dynamic
   05
   06     .dynamic

to prevent fetching or executing data in code pages as instructions.

Also don't put a writable section in a read-only segment if there is a
RELRO segment.

Since code segment is aligned and padded to the maximum page size on
disk, the minimum file size is bigger than the maximum page size which
is 2MB (0x200000):

-rwxr-xr-x 1 hjl hjl 4201932 Jan 10 10:41 libfoo.so

"-z max-page-size=0x1000" can be used to reduce the maximum page size to
4KB (0x1000):

-rwxr-xr-x 1 hjl hjl   15820 Jan 10 10:44 libfoo.so

        PR ld/22393
        * elf.c (_bfd_elf_map_sections_to_segments): When generating
        separate code and read-only data LOAD segments, create a new
        LOAD segment if the previous section contains text and the
        current section doesn't or vice versa.  Don't put a writable
        section in a read-only segment if there is a RELRO segment.
---
 bfd/elf.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/bfd/elf.c b/bfd/elf.c
index 9f44ff978a..1d0eefd053 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4566,6 +4566,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       asection **hdrpp;
       bfd_boolean phdr_in_segment = TRUE;
       bfd_boolean writable;
+      bfd_boolean executable;
       int tls_count = 0;
       asection *first_tls = NULL;
       asection *first_mbind = NULL;
@@ -4654,6 +4655,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       if (maxpagesize == 0)
  maxpagesize = 1;
       writable = FALSE;
+      executable = FALSE;
       dynsec = bfd_get_section_by_name (abfd, ".dynamic");
       if (dynsec != NULL
   && (dynsec->flags & SEC_LOAD) == 0)
@@ -4756,18 +4758,27 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
  file, then there is no other reason for a new segment.  */
       new_segment = FALSE;
     }
+  else if (info != NULL
+   && info->separate_code
+   && executable != ((hdr->flags & SEC_CODE) != 0))
+    {
+      new_segment = TRUE;
+    }
   else if (! writable
    && (hdr->flags & SEC_READONLY) == 0
-   && (((last_hdr->lma + last_size - 1) & -maxpagesize)
-       != (hdr->lma & -maxpagesize)))
+   && ((info != NULL
+ && info->relro_end > info->relro_start)
+       || (((last_hdr->lma + last_size - 1) & -maxpagesize)
+   != (hdr->lma & -maxpagesize))))
     {
       /* We don't want to put a writable section in a read only
  segment, unless they are on the same page in memory
- anyhow.  We already know that the last section does not
- bring us past the current section on the page, so the
- only case in which the new section is not on the same
- page as the previous section is when the previous section
- ends precisely on a page boundary.  */
+ anyhow and there is no RELRO segment.  We already
+ know that the last section does not bring us past the
+ current section on the page, so the only case in which
+ the new section is not on the same page as the previous
+ section is when the previous section ends precisely on
+ a page boundary.  */
       new_segment = TRUE;
     }
   else
@@ -4789,6 +4800,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
     {
       if ((hdr->flags & SEC_READONLY) == 0)
  writable = TRUE;
+      if ((hdr->flags & SEC_CODE) != 0)
+ executable = TRUE;
       last_hdr = hdr;
       /* .tbss sections effectively have zero size.  */
       if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
@@ -4814,6 +4827,11 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
   else
     writable = FALSE;
 
+  if ((hdr->flags & SEC_CODE) == 0)
+    executable = FALSE;
+  else
+    executable = TRUE;
+
   last_hdr = hdr;
   /* .tbss sections effectively have zero size.  */
   if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
--
2.14.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 3/4] ld: Add tests for -z separate-code and -z noseparate-code

H.J. Lu-30
In reply to this post by H.J. Lu-30
Verify that -z separate-code works and -z noseparate-code doesn't disable
-z relro.

        PR ld/22393
        * testsuite/ld-elf/pr16322.d: Add -z noseparate-code.
        * testsuite/ld-elf/pr22393-1.s: New file.
        * testsuite/ld-elf/pr22393-1a.d: Likewise.
        * testsuite/ld-elf/pr22393-1b.d: Likewise.
        * testsuite/ld-elf/pr22393-1c.d: Likewise.
        * testsuite/ld-elf/pr22393-1d.d: Likewise.
        * testsuite/ld-elf/pr22393-1e.d: Likewise.
        * testsuite/ld-elf/pr22393-1f.d: Likewise.
        * testsuite/ld-elf/pr22393-2a.c: Likewise.
        * testsuite/ld-elf/pr22393-2a.rd: Likewise.
        * testsuite/ld-elf/pr22393-2b.c: Likewise.
        * testsuite/ld-elf/pr22393-2b.rd: Likewise.
        * testsuite/ld-elf/shared.exp: Run tests for -z separate-code.
---
 ld/testsuite/ld-elf/pr16322.d     |  2 +-
 ld/testsuite/ld-elf/pr22393-1.s   | 21 ++++++++++++
 ld/testsuite/ld-elf/pr22393-1a.d  |  9 +++++
 ld/testsuite/ld-elf/pr22393-1b.d  |  9 +++++
 ld/testsuite/ld-elf/pr22393-1c.d  |  9 +++++
 ld/testsuite/ld-elf/pr22393-1d.d  |  9 +++++
 ld/testsuite/ld-elf/pr22393-1e.d  |  9 +++++
 ld/testsuite/ld-elf/pr22393-1f.d  |  9 +++++
 ld/testsuite/ld-elf/pr22393-2a.c  |  7 ++++
 ld/testsuite/ld-elf/pr22393-2a.rd |  9 +++++
 ld/testsuite/ld-elf/pr22393-2b.c  |  7 ++++
 ld/testsuite/ld-elf/pr22393-2b.rd |  9 +++++
 ld/testsuite/ld-elf/shared.exp    | 71 +++++++++++++++++++++++++++++++++++++++
 13 files changed, 179 insertions(+), 1 deletion(-)
 create mode 100644 ld/testsuite/ld-elf/pr22393-1.s
 create mode 100644 ld/testsuite/ld-elf/pr22393-1a.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1b.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1c.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1d.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1e.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-1f.d
 create mode 100644 ld/testsuite/ld-elf/pr22393-2a.c
 create mode 100644 ld/testsuite/ld-elf/pr22393-2a.rd
 create mode 100644 ld/testsuite/ld-elf/pr22393-2b.c
 create mode 100644 ld/testsuite/ld-elf/pr22393-2b.rd

diff --git a/ld/testsuite/ld-elf/pr16322.d b/ld/testsuite/ld-elf/pr16322.d
index 40a7975cb0..348927b384 100644
--- a/ld/testsuite/ld-elf/pr16322.d
+++ b/ld/testsuite/ld-elf/pr16322.d
@@ -1,4 +1,4 @@
-#ld: -shared -z relro
+#ld: -shared -z relro -z noseparate-code
 #readelf: -l --wide
 #target: *-*-linux-gnu *-*-gnu* *-*-nacl*
 
diff --git a/ld/testsuite/ld-elf/pr22393-1.s b/ld/testsuite/ld-elf/pr22393-1.s
new file mode 100644
index 0000000000..ffdb620915
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-1.s
@@ -0,0 +1,21 @@
+ .section .rodata,"a",%progbits
+ .globl fx1
+ .type fx1, %object
+fx1:
+ .zero 20
+ .section .data.rel.ro,"aw",%progbits
+ .globl px1
+ .type px1, %object
+px1:
+ .dc.a fx1
+
+ .text
+ .global start /* Used by SH targets.  */
+start:
+ .global _start
+_start:
+ .global __start
+__start:
+ .global main /* Used by HPPA targets.  */
+main:
+ .dc.a 0
diff --git a/ld/testsuite/ld-elf/pr22393-1a.d b/ld/testsuite/ld-elf/pr22393-1a.d
new file mode 100644
index 0000000000..f8dc0cc8f2
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-1a.d
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -shared -z separate-code -z relro
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
+#...
diff --git a/ld/testsuite/ld-elf/pr22393-1b.d b/ld/testsuite/ld-elf/pr22393-1b.d
new file mode 100644
index 0000000000..089d779591
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-1b.d
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -shared -z relro -z separate-code
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*.text.*(.eh_frame|\.rodata).*
+#...
diff --git a/ld/testsuite/ld-elf/pr22393-1c.d b/ld/testsuite/ld-elf/pr22393-1c.d
new file mode 100644
index 0000000000..3476be30a5
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-1c.d
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -pie -z separate-code
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
+#...
diff --git a/ld/testsuite/ld-elf/pr22393-1d.d b/ld/testsuite/ld-elf/pr22393-1d.d
new file mode 100644
index 0000000000..c0d1051f55
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-1d.d
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -pie -z separate-code
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*.text.*(.eh_frame|\.rodata).*
+#...
diff --git a/ld/testsuite/ld-elf/pr22393-1e.d b/ld/testsuite/ld-elf/pr22393-1e.d
new file mode 100644
index 0000000000..673d3f76b5
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-1e.d
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -z separate-code
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
+#...
diff --git a/ld/testsuite/ld-elf/pr22393-1f.d b/ld/testsuite/ld-elf/pr22393-1f.d
new file mode 100644
index 0000000000..4c5de439ff
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-1f.d
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -z separate-code
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*.text.*(.eh_frame|\.rodata).*
+#...
diff --git a/ld/testsuite/ld-elf/pr22393-2a.c b/ld/testsuite/ld-elf/pr22393-2a.c
new file mode 100644
index 0000000000..68fa4a0dd0
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2a.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+test()
+{
+  printf ("PASS\n");
+}
diff --git a/ld/testsuite/ld-elf/pr22393-2a.rd b/ld/testsuite/ld-elf/pr22393-2a.rd
new file mode 100644
index 0000000000..b7ba110095
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2a.rd
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -shared -z textonly
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
+#...
diff --git a/ld/testsuite/ld-elf/pr22393-2b.c b/ld/testsuite/ld-elf/pr22393-2b.c
new file mode 100644
index 0000000000..3033809b02
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2b.c
@@ -0,0 +1,7 @@
+void test(void);
+
+int main()
+{
+  test();
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/pr22393-2b.rd b/ld/testsuite/ld-elf/pr22393-2b.rd
new file mode 100644
index 0000000000..b7ba110095
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2b.rd
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -shared -z textonly
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
+#...
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index 0c54568879..b9e5d403cd 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -819,6 +819,51 @@ if { [istarget *-*-linux*]
     {} \
     "libpr19579.so" \
  ] \
+ [list \
+    "Build pr22393-2a.so" \
+    "-shared -Wl,-z,separate-code" \
+    "-fPIC" \
+    {pr22393-2a.c} \
+    {{readelf -lW pr22393-2a.rd} \
+     {readelf -lW pr22393-2b.rd}} \
+    "pr22393-2a.so" \
+ ] \
+ [list \
+    "Build pr22393-2a-now.so" \
+    "-shared -Wl,-z,separate-code,-z,now" \
+    "-fPIC" \
+    {pr22393-2a.c} \
+    {{readelf -lW pr22393-2a.rd} \
+     {readelf -lW pr22393-2b.rd}} \
+    "pr22393-2a-now.so" \
+ ] \
+ [list \
+    "Build pr22393-2" \
+    "$NOPIE_LDFLAGS -Wl,-z,separate-code,--no-as-needed tmpdir/pr22393-2a.so" \
+    "$NOPIE_CFLAGS" \
+    {pr22393-2b.c} \
+    {{readelf -lW pr22393-2a.rd} \
+     {readelf -lW pr22393-2b.rd}} \
+    "pr22393-2" \
+ ] \
+ [list \
+    "Build pr22393-2 (PIE)" \
+    "-pie -Wl,-z,separate-code,--no-as-needed tmpdir/pr22393-2a-now.so" \
+    "-fPIE" \
+    {pr22393-2b.c} \
+    {{readelf -lW pr22393-2a.rd} \
+     {readelf -lW pr22393-2b.rd}} \
+    "pr22393-2-pie" \
+ ] \
+ [list \
+    "Build pr22393-2 (static)" \
+    "-static -Wl,-z,separate-code" \
+    "" \
+    {pr22393-2a.c pr22393-2b.c} \
+    {{readelf -lW pr22393-2a.rd} \
+     {readelf -lW pr22393-2b.rd}} \
+    "pr22393-2-static" \
+ ] \
     ]
     run_ld_link_exec_tests [list \
  [list \
@@ -956,6 +1001,32 @@ if { [istarget *-*-linux*]
     "pass.out" \
     "-fPIE" \
  ] \
+ [list \
+    "Run pr22393-2" \
+    "$NOPIE_LDFLAGS -Wl,-z,separate-code,--no-as-needed tmpdir/pr22393-2a.so" \
+    "" \
+    {pr22393-2b.c} \
+    "pr22393-2" \
+    "pass.out" \
+    "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+    "Run pr22393-2 (PIE)" \
+    "-pie -Wl,-z,separate-code,--no-as-needed tmpdir/pr22393-2a-now.so" \
+    "" \
+    {pr22393-2b.c} \
+    "pr22393-2-pie" \
+    "pass.out" \
+    "-fPIE" \
+ ] \
+ [list \
+    "Run pr22393-2 (static)" \
+    "-static -Wl,-z,separate-code" \
+    "" \
+    {pr22393-2a.c pr22393-2b.c} \
+    "pr22393-2-static" \
+    "pass.out" \
+ ] \
     ]
 }
 
--
2.14.3

Reply | Threaded
Open this post in threaded view
|

[PATCH 4/4] x86-64: Add tests for -z separate-code -z max-page-size=0x1000

H.J. Lu-30
In reply to this post by H.J. Lu-30
        PR ld/22393
        * testsuite/ld-x86-64/pr22393-3a.c: New file.
        * testsuite/ld-x86-64/pr22393-3a.rd: Likewise.
        * testsuite/ld-x86-64/pr22393-3b.c: Likewise.
        * testsuite/ld-x86-64/pr22393-3b.rd: Likewise.
        * testsuite/ld-x86-64/x86-64.exp: Run tests for -z separate-code
        -z max-page-size=0x1000.
---
 ld/testsuite/ld-x86-64/pr22393-3a.c  |  7 ++++
 ld/testsuite/ld-x86-64/pr22393-3a.rd |  9 +++++
 ld/testsuite/ld-x86-64/pr22393-3b.c  |  7 ++++
 ld/testsuite/ld-x86-64/pr22393-3b.rd |  9 +++++
 ld/testsuite/ld-x86-64/x86-64.exp    | 71 ++++++++++++++++++++++++++++++++++++
 5 files changed, 103 insertions(+)
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-3a.c
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-3a.rd
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-3b.c
 create mode 100644 ld/testsuite/ld-x86-64/pr22393-3b.rd

diff --git a/ld/testsuite/ld-x86-64/pr22393-3a.c b/ld/testsuite/ld-x86-64/pr22393-3a.c
new file mode 100644
index 0000000000..68fa4a0dd0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr22393-3a.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+test()
+{
+  printf ("PASS\n");
+}
diff --git a/ld/testsuite/ld-x86-64/pr22393-3a.rd b/ld/testsuite/ld-x86-64/pr22393-3a.rd
new file mode 100644
index 0000000000..b7ba110095
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr22393-3a.rd
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -shared -z textonly
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
+#...
diff --git a/ld/testsuite/ld-x86-64/pr22393-3b.c b/ld/testsuite/ld-x86-64/pr22393-3b.c
new file mode 100644
index 0000000000..3033809b02
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr22393-3b.c
@@ -0,0 +1,7 @@
+void test(void);
+
+int main()
+{
+  test();
+  return 0;
+}
diff --git a/ld/testsuite/ld-x86-64/pr22393-3b.rd b/ld/testsuite/ld-x86-64/pr22393-3b.rd
new file mode 100644
index 0000000000..b7ba110095
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr22393-3b.rd
@@ -0,0 +1,9 @@
+#source: pr22393-1.s
+#ld: -shared -z textonly
+#readelf: -l --wide
+#target: *-*-linux-gnu *-*-gnu* *-*-nacl*
+
+#failif
+#...
+ +[0-9]+  +.*(\.note|\.gnu|\.hash|\.dyn|\.rel).*\.text.*
+#...
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 1f32b2331d..e7f338ee11 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -1105,6 +1105,51 @@ if { [isnative] && [which $CC] != 0 } {
     {} \
     "pr22064.so" \
  ] \
+ [list \
+    "Build pr22393-3a.so" \
+    "-shared -Wl,-z,separate-code,-z,max-page-size=0x1000" \
+    "-fPIC" \
+    {pr22393-3a.c} \
+    {{readelf -lW pr22393-3a.rd} \
+     {readelf -lW pr22393-3b.rd}} \
+    "pr22393-3a.so" \
+ ] \
+ [list \
+    "Build pr22393-3a-now.so" \
+    "-shared -Wl,-z,separate-code,-z,now,-z,max-page-size=0x1000" \
+    "-fPIC" \
+    {pr22393-3a.c} \
+    {{readelf -lW pr22393-3a.rd} \
+     {readelf -lW pr22393-3b.rd}} \
+    "pr22393-3a-now.so" \
+ ] \
+ [list \
+    "Build pr22393-3" \
+    "$NOPIE_LDFLAGS -Wl,-z,separate-code,-z,max-page-size=0x1000,--no-as-needed tmpdir/pr22393-2a.so" \
+    "$NOPIE_CFLAGS" \
+    {pr22393-3b.c} \
+    {{readelf -lW pr22393-3a.rd} \
+     {readelf -lW pr22393-3b.rd}} \
+    "pr22393-3" \
+ ] \
+ [list \
+    "Build pr22393-3 (PIE)" \
+    "-pie -Wl,-z,separate-code,-z,max-page-size=0x1000,--no-as-needed tmpdir/pr22393-2a-now.so" \
+    "-fPIE" \
+    {pr22393-3b.c} \
+    {{readelf -lW pr22393-3a.rd} \
+     {readelf -lW pr22393-3b.rd}} \
+    "pr22393-3-pie" \
+ ] \
+ [list \
+    "Build pr22393-3 (static)" \
+    "-static -Wl,-z,separate-code,-z,max-page-size=0x1000" \
+    "" \
+    {pr22393-3a.c pr22393-3b.c} \
+    {{readelf -lW pr22393-3a.rd} \
+     {readelf -lW pr22393-3b.rd}} \
+    "pr22393-3-static" \
+ ] \
     ]
 
     if  {[istarget "x86_64-*-linux*-gnux32"]} {
@@ -1404,6 +1449,32 @@ if { [isnative] && [which $CC] != 0 } {
     "pass.out" \
     "-fPIE" \
  ] \
+ [list \
+    "Run pr22393-3" \
+    "$NOPIE_LDFLAGS -Wl,-z,separate-code,-z,max-page-size=0x1000,--no-as-needed tmpdir/pr22393-3a.so" \
+    "" \
+    {pr22393-3b.c} \
+    "pr22393-3" \
+    "pass.out" \
+    "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+    "Run pr22393-3 (PIE)" \
+    "-pie -Wl,-z,separate-code,-z,max-page-size=0x1000,--no-as-needed tmpdir/pr22393-3a-now.so" \
+    "" \
+    {pr22393-3b.c} \
+    "pr22393-3-pie" \
+    "pass.out" \
+    "-fPIE" \
+ ] \
+ [list \
+    "Run pr22393-3 (static)" \
+    "-static -Wl,-z,separate-code,-z,max-page-size=0x1000" \
+    "" \
+    {pr22393-3a.c pr22393-3b.c} \
+    "pr22393-3-static" \
+    "pass.out" \
+ ] \
     ]
 
     # Run-time tests which require working ifunc attribute support.
--
2.14.3