elf: Place code after read-only data for --rosegment

Message ID 20260318192429.1160977-1-hjl.tools@gmail.com
State New
Headers
Series elf: Place code after read-only data for --rosegment |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

H.J. Lu March 18, 2026, 7:24 p.m. UTC
  commit e8e10743f7b207b21a1efb0cc9e42487080db013
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Jun 13 15:10:15 2024 +0100

    Add --rosegment option to BFD linker to stop the '-z separate-code' from gen erating two read-only segments.

added --rosegment option to generate one read-only segment with
-z separate-code.  But it puts the read-only data in the executable
segment:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x00185 0x00185 R E 0x1000
  LOAD           0x001000 0x00001000 0x00001000 0x000d0 0x000d0 R   0x1000
  LOAD           0x001f78 0x00002f78 0x00002f78 0x0008c 0x0008c RW  0x1000
  DYNAMIC        0x001f78 0x00002f78 0x00002f78 0x00070 0x00070 RW  0x4
  NOTE           0x000154 0x00000154 0x00000154 0x00024 0x00024 R   0x4
  NOTE           0x00109c 0x0000109c 0x0000109c 0x00034 0x00034 R   0x4
  GNU_PROPERTY   0x00109c 0x0000109c 0x0000109c 0x00034 0x00034 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x001f78 0x00002f78 0x00002f78 0x00088 0x00088 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.build-id .text
   01     .gnu.hash .dynsym .dynstr .rela.dyn .rodata .eh_frame .note.gnu.property
   02     .dynamic .got.plt .data
   03     .dynamic
   04     .note.gnu.build-id
   05     .note.gnu.property
   06     .note.gnu.property
   07
   08     .dynamic .got.plt

which defeats the purpose of -z separate-code.  Update --rosegment to
place code after read-only data:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x00248 0x00248 R   0x1000
  LOAD           0x001000 0x00001000 0x00001000 0x00005 0x00005 R E 0x1000
  LOAD           0x001f78 0x00002f78 0x00002f78 0x0008c 0x0008c RW  0x1000
  DYNAMIC        0x001f78 0x00002f78 0x00002f78 0x00070 0x00070 RW  0x4
  NOTE           0x000154 0x00000154 0x00000154 0x00024 0x00024 R   0x4
  NOTE           0x000214 0x00000214 0x00000214 0x00034 0x00034 R   0x4
  GNU_PROPERTY   0x000214 0x00000214 0x00000214 0x00034 0x00034 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x001f78 0x00002f78 0x00002f78 0x00088 0x00088 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.build-id .gnu.hash .dynsym .dynstr .rela.dyn .rodata .eh_frame .note.gnu.property
   01     .text
   02     .dynamic .got.plt .data
   03     .dynamic
   04     .note.gnu.build-id
   05     .note.gnu.property
   06     .note.gnu.property
   07
   08     .dynamic .got.plt

	PR ld/30907
	PR ld/32191
	PR ld/34003
	* scripttempl/elf.sc (ALL_TEXT_BEFORE_RO): Removed.
	(ALL_TEXT_AFTER_RO): New.  Set for -z separate-code --rosegment.
	Place code after read-only data for -z separate-code --rosegment.
	* testsuite/ld-elf/pr30907-2.d: Updated.
	* testsuite/ld-i386/pr32191.d: Likewise.
	* testsuite/ld-x86-64/pr32191-x32.d: Likewise.
	* testsuite/ld-x86-64/pr32191.d: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 ld/scripttempl/elf.sc                | 65 +++++++++++++---------------
 ld/testsuite/ld-elf/pr30907-2.d      |  4 +-
 ld/testsuite/ld-i386/pr32191.d       |  4 +-
 ld/testsuite/ld-x86-64/pr32191-x32.d |  4 +-
 ld/testsuite/ld-x86-64/pr32191.d     |  4 +-
 5 files changed, 42 insertions(+), 39 deletions(-)
  

Comments

H.J. Lu March 24, 2026, 8:26 p.m. UTC | #1
On Wed, Mar 18, 2026 at 12:24 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> commit e8e10743f7b207b21a1efb0cc9e42487080db013
> Author: Nick Clifton <nickc@redhat.com>
> Date:   Thu Jun 13 15:10:15 2024 +0100
>
>     Add --rosegment option to BFD linker to stop the '-z separate-code' from gen erating two read-only segments.
>
> added --rosegment option to generate one read-only segment with
> -z separate-code.  But it puts the read-only data in the executable
> segment:
>
> Program Headers:
>   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>   LOAD           0x000000 0x00000000 0x00000000 0x00185 0x00185 R E 0x1000
>   LOAD           0x001000 0x00001000 0x00001000 0x000d0 0x000d0 R   0x1000
>   LOAD           0x001f78 0x00002f78 0x00002f78 0x0008c 0x0008c RW  0x1000
>   DYNAMIC        0x001f78 0x00002f78 0x00002f78 0x00070 0x00070 RW  0x4
>   NOTE           0x000154 0x00000154 0x00000154 0x00024 0x00024 R   0x4
>   NOTE           0x00109c 0x0000109c 0x0000109c 0x00034 0x00034 R   0x4
>   GNU_PROPERTY   0x00109c 0x0000109c 0x0000109c 0x00034 0x00034 R   0x4
>   GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
>   GNU_RELRO      0x001f78 0x00002f78 0x00002f78 0x00088 0x00088 R   0x1
>
>  Section to Segment mapping:
>   Segment Sections...
>    00     .note.gnu.build-id .text
>    01     .gnu.hash .dynsym .dynstr .rela.dyn .rodata .eh_frame .note.gnu.property
>    02     .dynamic .got.plt .data
>    03     .dynamic
>    04     .note.gnu.build-id
>    05     .note.gnu.property
>    06     .note.gnu.property
>    07
>    08     .dynamic .got.plt
>
> which defeats the purpose of -z separate-code.  Update --rosegment to
> place code after read-only data:
>
> Program Headers:
>   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>   LOAD           0x000000 0x00000000 0x00000000 0x00248 0x00248 R   0x1000
>   LOAD           0x001000 0x00001000 0x00001000 0x00005 0x00005 R E 0x1000
>   LOAD           0x001f78 0x00002f78 0x00002f78 0x0008c 0x0008c RW  0x1000
>   DYNAMIC        0x001f78 0x00002f78 0x00002f78 0x00070 0x00070 RW  0x4
>   NOTE           0x000154 0x00000154 0x00000154 0x00024 0x00024 R   0x4
>   NOTE           0x000214 0x00000214 0x00000214 0x00034 0x00034 R   0x4
>   GNU_PROPERTY   0x000214 0x00000214 0x00000214 0x00034 0x00034 R   0x4
>   GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
>   GNU_RELRO      0x001f78 0x00002f78 0x00002f78 0x00088 0x00088 R   0x1
>
>  Section to Segment mapping:
>   Segment Sections...
>    00     .note.gnu.build-id .gnu.hash .dynsym .dynstr .rela.dyn .rodata .eh_frame .note.gnu.property
>    01     .text
>    02     .dynamic .got.plt .data
>    03     .dynamic
>    04     .note.gnu.build-id
>    05     .note.gnu.property
>    06     .note.gnu.property
>    07
>    08     .dynamic .got.plt

Any feedback on this patch?

>         PR ld/30907
>         PR ld/32191
>         PR ld/34003
>         * scripttempl/elf.sc (ALL_TEXT_BEFORE_RO): Removed.
>         (ALL_TEXT_AFTER_RO): New.  Set for -z separate-code --rosegment.
>         Place code after read-only data for -z separate-code --rosegment.
>         * testsuite/ld-elf/pr30907-2.d: Updated.
>         * testsuite/ld-i386/pr32191.d: Likewise.
>         * testsuite/ld-x86-64/pr32191-x32.d: Likewise.
>         * testsuite/ld-x86-64/pr32191.d: Likewise.
>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> ---
>  ld/scripttempl/elf.sc                | 65 +++++++++++++---------------
>  ld/testsuite/ld-elf/pr30907-2.d      |  4 +-
>  ld/testsuite/ld-i386/pr32191.d       |  4 +-
>  ld/testsuite/ld-x86-64/pr32191-x32.d |  4 +-
>  ld/testsuite/ld-x86-64/pr32191.d     |  4 +-
>  5 files changed, 42 insertions(+), 39 deletions(-)
>
> diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
> index 8a0efc02c86..f992dac2ccb 100644
> --- a/ld/scripttempl/elf.sc
> +++ b/ld/scripttempl/elf.sc
> @@ -80,7 +80,7 @@
>  #              for standard sections, without initial "." or suffixes.
>  #       SYMBOL_ABI_ALIGNMENT - minimum alignment in bytes which needs to be
>  #               applied to every symbol definition
> -#       ALL_TEXT_BEFORE_RO - put all code sections before read-only
> +#       ALL_TEXT_AFTER_RO - put all code sections after read-only
>  #               sections
>  #
>  # When adding sections, do note that the names of some sections are used
> @@ -360,7 +360,7 @@ SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${SHLIB_TEXT_START_ADDR:-
>  if test -z "$TINY_READONLY_SECTION"; then
>    case "$LD_FLAG" in
>      *ro*textonly*)
> -      ALL_TEXT_BEFORE_RO=" "
> +      ALL_TEXT_AFTER_RO=" "
>        SEPARATE_TEXT=" "
>        TEXT_SEGMENT_ALIGN=". = ALIGN(${MAXPAGESIZE});"
>        ;;
> @@ -1021,25 +1021,24 @@ EOF
>
>    #------Early Read Only Data -----------------------------------------------
>
> -  if test -z "${ALL_TEXT_BEFORE_RO}"; then
> -    # We are allowed to put R/O sections before code sections.
> -    # Doing so either puts read only data into the code segment, if the data
> -    # and code sections are contiguous, or creates a data segment followed by
> -    # a code segment, followed by another data segment (for read/write data).
> -    # Having three segments like this makes the binary bigger, which is a
> -    # problem for some scenarios, eg containers.  On the other hand, having
> -    # data in an executable code segment means that it might provide an
> -    # avenue of attack for bad actors, which is a security risk.
> -
> -    test -n "${SEPARATE_CODE}" || emit_early_ro
> -    test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
> -
> -    # We only need the alignment if we have emitted some sections.
> -    if test -z "${SEPARATE_CODE}"; then
> -      align_text
> -    elif test -z "${NON_ALLOC_DYN}${SEPARATE_CODE}"; then
> -      align_text
> -    fi
> +  # We are allowed to put R/O sections before code sections.
> +  # Doing so either puts read only data into the code segment, if the data
> +  # and code sections are contiguous, or creates a data segment followed by
> +  # a code segment, followed by another data segment (for read/write data).
> +  # Having three segments like this makes the binary bigger, which is a
> +  # problem for some scenarios, eg containers.  On the other hand, having
> +  # data in an executable code segment means that it might provide an
> +  # avenue of attack for bad actors, which is a security risk.
> +
> +  test -n "${SEPARATE_CODE}" || emit_early_ro
> +  test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
> +  test -z "${ALL_TEXT_AFTER_RO}" || emit_rodata
> +
> +  # We only need the alignment if we have emitted some sections.
> +  if test -z "${SEPARATE_CODE}"; then
> +    align_text
> +  elif test -z "${NON_ALLOC_DYN}${SEPARATE_CODE}"; then
> +    align_text
>    fi
>
>    #------Executable Code ----------------------------------------------------
> @@ -1058,24 +1057,22 @@ EOF
>
>    align_text
>
> -  #------Read Only Data -----------------------------------------------------
> +  if test -z "${ALL_TEXT_AFTER_RO}"; then
> +    #------Read Only Data ------------------------------------------------
>
> -  align_rodata
> +    align_rodata
>
> -  # If we have not already emitted the early read only data sections then do
> -  # so now.  Also if the dynamic section has not already been emitted and we
> -  # can put it into the data segment, then do that here as well.
> +    # If we have not already emitted the early read only data sections then do
> +    # so now.  Also if the dynamic section has not already been emitted and we
> +    # can put it into the data segment, then do that here as well.
>
> -  if test -n "${ALL_TEXT_BEFORE_RO}"; then
> -    test -n "${SEPARATE_CODE}" || emit_early_ro
> -    test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
> -  fi
> -  test -z "${SEPARATE_CODE}" || emit_early_ro
> -  test -z "${SEPARATE_CODE}" || emit_dyn
> +    test -z "${SEPARATE_CODE}" || emit_early_ro
> +    test -z "${SEPARATE_CODE}" || emit_dyn
>
> -  # Now emit the rest of the read only data.
> +    # Now emit the rest of the read only data.
>
> -  emit_rodata
> +    emit_rodata
> +  fi
>
>    #------Read Write Data ----------------------------------------------------
>
> diff --git a/ld/testsuite/ld-elf/pr30907-2.d b/ld/testsuite/ld-elf/pr30907-2.d
> index fed957e760e..1ac8d4951da 100644
> --- a/ld/testsuite/ld-elf/pr30907-2.d
> +++ b/ld/testsuite/ld-elf/pr30907-2.d
> @@ -6,10 +6,10 @@
>  #xfail: ![check_shared_lib_support]
>  #xfail: ![check_relro_support]
>
> -#...
> -[ ]+LOAD[      ]+0x[0-9a-f x]+R E[ ]+0x.*
>  #...
>  [ ]+LOAD[      ]+0x[0-9a-f x]+R[ ]+0x.*
>  #...
> +[ ]+LOAD[      ]+0x[0-9a-f x]+R E[ ]+0x.*
> +#...
>  [ ]+LOAD[      ]+0x[0-9a-f x]+RW[ ]+0x.*
>  #...
> diff --git a/ld/testsuite/ld-i386/pr32191.d b/ld/testsuite/ld-i386/pr32191.d
> index 8d7838a1311..5558da1b0b8 100644
> --- a/ld/testsuite/ld-i386/pr32191.d
> +++ b/ld/testsuite/ld-i386/pr32191.d
> @@ -4,6 +4,8 @@
>  #readelf: -lW
>
>  #...
> - +[0-9]+ +\.note\.gnu\.build-id \.text
> + +[0-9]+ +\.note\.gnu\.build-id .*
> + +[0-9]+ +\.text
> +#...
>   +[0-9]+ +\..* \.note\.gnu\.property .*
>  #pass
> diff --git a/ld/testsuite/ld-x86-64/pr32191-x32.d b/ld/testsuite/ld-x86-64/pr32191-x32.d
> index 19e06a26c11..b574e05f6c9 100644
> --- a/ld/testsuite/ld-x86-64/pr32191-x32.d
> +++ b/ld/testsuite/ld-x86-64/pr32191-x32.d
> @@ -4,6 +4,8 @@
>  #readelf: -lW
>
>  #...
> - +[0-9]+ +\.note\.gnu\.build-id \.text
> + +[0-9]+ +\.note\.gnu\.build-id .*
> + +[0-9]+ +\.text
> +#...
>   +[0-9]+ +\..* \.note\.gnu\.property .*
>  #pass
> diff --git a/ld/testsuite/ld-x86-64/pr32191.d b/ld/testsuite/ld-x86-64/pr32191.d
> index 9038ccd9b35..2a0c0339165 100644
> --- a/ld/testsuite/ld-x86-64/pr32191.d
> +++ b/ld/testsuite/ld-x86-64/pr32191.d
> @@ -4,6 +4,8 @@
>  #readelf: -lW
>
>  #...
> - +[0-9]+ +\.note\.gnu\.build-id \.text
> + +[0-9]+ +\.note\.gnu\.build-id .*
> + +[0-9]+ +\.text
> +#...
>   +[0-9]+ +\..* \.note\.gnu\.property .*
>  #pass
> --
> 2.53.0
>
  

Patch

diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 8a0efc02c86..f992dac2ccb 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -80,7 +80,7 @@ 
 #		for standard sections, without initial "." or suffixes.
 #       SYMBOL_ABI_ALIGNMENT - minimum alignment in bytes which needs to be
 #               applied to every symbol definition
-#       ALL_TEXT_BEFORE_RO - put all code sections before read-only
+#       ALL_TEXT_AFTER_RO - put all code sections after read-only
 #               sections
 #
 # When adding sections, do note that the names of some sections are used
@@ -360,7 +360,7 @@  SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${SHLIB_TEXT_START_ADDR:-
 if test -z "$TINY_READONLY_SECTION"; then
   case "$LD_FLAG" in
     *ro*textonly*)
-      ALL_TEXT_BEFORE_RO=" "
+      ALL_TEXT_AFTER_RO=" "
       SEPARATE_TEXT=" "
       TEXT_SEGMENT_ALIGN=". = ALIGN(${MAXPAGESIZE});"
       ;;
@@ -1021,25 +1021,24 @@  EOF
 
   #------Early Read Only Data -----------------------------------------------
 
-  if test -z "${ALL_TEXT_BEFORE_RO}"; then
-    # We are allowed to put R/O sections before code sections.
-    # Doing so either puts read only data into the code segment, if the data
-    # and code sections are contiguous, or creates a data segment followed by
-    # a code segment, followed by another data segment (for read/write data).
-    # Having three segments like this makes the binary bigger, which is a
-    # problem for some scenarios, eg containers.  On the other hand, having
-    # data in an executable code segment means that it might provide an
-    # avenue of attack for bad actors, which is a security risk.
-
-    test -n "${SEPARATE_CODE}" || emit_early_ro
-    test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
-
-    # We only need the alignment if we have emitted some sections.
-    if test -z "${SEPARATE_CODE}"; then
-      align_text
-    elif test -z "${NON_ALLOC_DYN}${SEPARATE_CODE}"; then
-      align_text
-    fi
+  # We are allowed to put R/O sections before code sections.
+  # Doing so either puts read only data into the code segment, if the data
+  # and code sections are contiguous, or creates a data segment followed by
+  # a code segment, followed by another data segment (for read/write data).
+  # Having three segments like this makes the binary bigger, which is a
+  # problem for some scenarios, eg containers.  On the other hand, having
+  # data in an executable code segment means that it might provide an
+  # avenue of attack for bad actors, which is a security risk.
+
+  test -n "${SEPARATE_CODE}" || emit_early_ro
+  test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
+  test -z "${ALL_TEXT_AFTER_RO}" || emit_rodata
+
+  # We only need the alignment if we have emitted some sections.
+  if test -z "${SEPARATE_CODE}"; then
+    align_text
+  elif test -z "${NON_ALLOC_DYN}${SEPARATE_CODE}"; then
+    align_text
   fi
   
   #------Executable Code ----------------------------------------------------
@@ -1058,24 +1057,22 @@  EOF
 
   align_text
 
-  #------Read Only Data -----------------------------------------------------
+  if test -z "${ALL_TEXT_AFTER_RO}"; then
+    #------Read Only Data ------------------------------------------------
 
-  align_rodata
+    align_rodata
 
-  # If we have not already emitted the early read only data sections then do
-  # so now.  Also if the dynamic section has not already been emitted and we
-  # can put it into the data segment, then do that here as well.
+    # If we have not already emitted the early read only data sections then do
+    # so now.  Also if the dynamic section has not already been emitted and we
+    # can put it into the data segment, then do that here as well.
 
-  if test -n "${ALL_TEXT_BEFORE_RO}"; then
-    test -n "${SEPARATE_CODE}" || emit_early_ro
-    test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn
-  fi
-  test -z "${SEPARATE_CODE}" || emit_early_ro
-  test -z "${SEPARATE_CODE}" || emit_dyn
+    test -z "${SEPARATE_CODE}" || emit_early_ro
+    test -z "${SEPARATE_CODE}" || emit_dyn
 
-  # Now emit the rest of the read only data.
+    # Now emit the rest of the read only data.
 
-  emit_rodata
+    emit_rodata
+  fi
 
   #------Read Write Data ----------------------------------------------------
 
diff --git a/ld/testsuite/ld-elf/pr30907-2.d b/ld/testsuite/ld-elf/pr30907-2.d
index fed957e760e..1ac8d4951da 100644
--- a/ld/testsuite/ld-elf/pr30907-2.d
+++ b/ld/testsuite/ld-elf/pr30907-2.d
@@ -6,10 +6,10 @@ 
 #xfail: ![check_shared_lib_support] 
 #xfail: ![check_relro_support]
 
-#...
-[ ]+LOAD[ 	]+0x[0-9a-f x]+R E[ ]+0x.*
 #...
 [ ]+LOAD[ 	]+0x[0-9a-f x]+R[ ]+0x.*
 #...
+[ ]+LOAD[ 	]+0x[0-9a-f x]+R E[ ]+0x.*
+#...
 [ ]+LOAD[ 	]+0x[0-9a-f x]+RW[ ]+0x.*
 #...
diff --git a/ld/testsuite/ld-i386/pr32191.d b/ld/testsuite/ld-i386/pr32191.d
index 8d7838a1311..5558da1b0b8 100644
--- a/ld/testsuite/ld-i386/pr32191.d
+++ b/ld/testsuite/ld-i386/pr32191.d
@@ -4,6 +4,8 @@ 
 #readelf: -lW
 
 #...
- +[0-9]+ +\.note\.gnu\.build-id \.text 
+ +[0-9]+ +\.note\.gnu\.build-id .*
+ +[0-9]+ +\.text 
+#...
  +[0-9]+ +\..* \.note\.gnu\.property .*
 #pass
diff --git a/ld/testsuite/ld-x86-64/pr32191-x32.d b/ld/testsuite/ld-x86-64/pr32191-x32.d
index 19e06a26c11..b574e05f6c9 100644
--- a/ld/testsuite/ld-x86-64/pr32191-x32.d
+++ b/ld/testsuite/ld-x86-64/pr32191-x32.d
@@ -4,6 +4,8 @@ 
 #readelf: -lW
 
 #...
- +[0-9]+ +\.note\.gnu\.build-id \.text 
+ +[0-9]+ +\.note\.gnu\.build-id .*
+ +[0-9]+ +\.text 
+#...
  +[0-9]+ +\..* \.note\.gnu\.property .*
 #pass
diff --git a/ld/testsuite/ld-x86-64/pr32191.d b/ld/testsuite/ld-x86-64/pr32191.d
index 9038ccd9b35..2a0c0339165 100644
--- a/ld/testsuite/ld-x86-64/pr32191.d
+++ b/ld/testsuite/ld-x86-64/pr32191.d
@@ -4,6 +4,8 @@ 
 #readelf: -lW
 
 #...
- +[0-9]+ +\.note\.gnu\.build-id \.text 
+ +[0-9]+ +\.note\.gnu\.build-id .*
+ +[0-9]+ +\.text 
+#...
  +[0-9]+ +\..* \.note\.gnu\.property .*
 #pass