aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJozef Lawrynowicz <jozef.l@mittosystems.com>2020-11-18 11:51:13 +0000
committerJozef Lawrynowicz <jozef.l@mittosystems.com>2020-11-18 11:51:13 +0000
commit99fabbc9739a87ba3433e66792e93b773896790e (patch)
tree6a52b12cc648532f3b38fd102cec221a207188ba /gas
parent40d9d2fd796a184f04a83ca4442fd78034b5e00b (diff)
downloadbinutils-99fabbc9739a87ba3433e66792e93b773896790e.zip
binutils-99fabbc9739a87ba3433e66792e93b773896790e.tar.gz
binutils-99fabbc9739a87ba3433e66792e93b773896790e.tar.bz2
Support SHF_GNU_RETAIN ELF section flag
The SHF_GNU_RETAIN section flag is an extension to the GNU ELF OSABI. It is defined as follows: ========================================================= Section Attribute Flags +-------------------------------------+ | Name | Value | +-------------------------------------+ | SHF_GNU_RETAIN | 0x200000 (1 << 21) | +-------------------------------------+ SHF_GNU_RETAIN The link editor should not garbage collect the section. ========================================================= The .section directive accepts the "R" flag, which indicates SHF_GNU_RETAIN should be applied to the section. There is not a direct mapping of SHF_GNU_RETAIN to the BFD section flag SEC_KEEP. Keeping these flags distinct allows SHF_GNU_RETAIN sections to be explicitly removed by placing them in /DISCARD/. bfd/ChangeLog: * elf-bfd.h (enum elf_gnu_osabi): Add elf_gnu_osabi_retain. (struct elf_obj_tdata): Increase has_gnu_osabi to 4 bits. * elf.c (_bfd_elf_make_section_from_shdr): Set elf_gnu_osabi_retain for SHF_GNU_RETAIN. (_bfd_elf_final_write_processing): Report if SHF_GNU_RETAIN is not supported by the OSABI. Adjust error messages. * elflink.c (elf_link_input_bfd): Copy enabled has_gnu_osabi bits from input BFD to output BFD. (bfd_elf_gc_sections): gc_mark the section if SHF_GNU_RETAIN is set. binutils/ChangeLog: * NEWS: Announce SHF_GNU_RETAIN support. * readelf.c (get_elf_section_flags): Handle SHF_GNU_RETAIN. Recognize SHF_GNU_RETAIN and SHF_GNU_MBIND only for supported OSABIs. * testsuite/binutils-all/readelf.exp: Run new tests. Don't run run_dump_test when there isn't an assembler available. * testsuite/lib/binutils-common.exp (supports_gnu_osabi): Adjust comment. * testsuite/binutils-all/readelf-maskos-1a.d: New test. * testsuite/binutils-all/readelf-maskos-1b.d: New test. * testsuite/binutils-all/readelf-maskos.s: New test. * testsuite/binutils-all/retain1.s: New test. * testsuite/binutils-all/retain1a.d: New test. * testsuite/binutils-all/retain1b.d: New test. gas/ChangeLog: * NEWS: Announce SHF_GNU_RETAIN support. * config/obj-elf.c (obj_elf_change_section): Merge SHF_GNU_RETAIN bit between section declarations. (obj_elf_parse_section_letters): Handle 'R' flag. Handle numeric flag values within the SHF_MASKOS range. (obj_elf_section): Validate SHF_GNU_RETAIN usage. * doc/as.texi: Document 'R' flag to .section directive. * testsuite/gas/elf/elf.exp: Run new tests. * testsuite/gas/elf/section10.d: Unset SHF_GNU_RETAIN bit. * testsuite/gas/elf/section10.s: Likewise. * testsuite/gas/elf/section22.d: New test. * testsuite/gas/elf/section22.s: New test. * testsuite/gas/elf/section23.s: New test. * testsuite/gas/elf/section23a.d: New test. * testsuite/gas/elf/section23b.d: New test. * testsuite/gas/elf/section23b.err: New test. * testsuite/gas/elf/section24.l: New test. * testsuite/gas/elf/section24.s: New test. * testsuite/gas/elf/section24a.d: New test. * testsuite/gas/elf/section24b.d: New test. include/ChangeLog: * elf/common.h (SHF_GNU_RETAIN): Define. ld/ChangeLog: * NEWS: Announce support for SHF_GNU_RETAIN. * ld.texi (garbage collection): Document SHF_GNU_RETAIN. (Output Section Discarding): Likewise. * testsuite/ld-elf/elf.exp: Run new tests. * testsuite/ld-elf/retain1.s: New test. * testsuite/ld-elf/retain1a.d: New test. * testsuite/ld-elf/retain1b.d: New test. * testsuite/ld-elf/retain2.d: New test. * testsuite/ld-elf/retain2.ld: New test. * testsuite/ld-elf/retain2.map: New test. * testsuite/ld-elf/retain3.d: New test. * testsuite/ld-elf/retain3.s: New test. * testsuite/ld-elf/retain4.d: New test. * testsuite/ld-elf/retain4.s: New test. * testsuite/ld-elf/retain5.d: New test. * testsuite/ld-elf/retain5.map: New test. * testsuite/ld-elf/retain5lib.s: New test. * testsuite/ld-elf/retain5main.s: New test. * testsuite/ld-elf/retain6a.d: New test. * testsuite/ld-elf/retain6b.d: New test. * testsuite/ld-elf/retain6lib.s: New test. * testsuite/ld-elf/retain6main.s: New test.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog23
-rw-r--r--gas/NEWS5
-rw-r--r--gas/config/obj-elf.c80
-rw-r--r--gas/doc/as.texi3
-rw-r--r--gas/testsuite/gas/elf/elf.exp6
-rw-r--r--gas/testsuite/gas/elf/section10.d4
-rw-r--r--gas/testsuite/gas/elf/section10.s4
-rw-r--r--gas/testsuite/gas/elf/section22.d19
-rw-r--r--gas/testsuite/gas/elf/section22.s34
-rw-r--r--gas/testsuite/gas/elf/section23.s11
-rw-r--r--gas/testsuite/gas/elf/section23a.d10
-rw-r--r--gas/testsuite/gas/elf/section23b.d6
-rw-r--r--gas/testsuite/gas/elf/section23b.err2
-rw-r--r--gas/testsuite/gas/elf/section24.s38
-rw-r--r--gas/testsuite/gas/elf/section24a.d17
-rw-r--r--gas/testsuite/gas/elf/section24b.d10
16 files changed, 250 insertions, 22 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index cdbc1ca..fcfce70 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,26 @@
+2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * NEWS: Announce SHF_GNU_RETAIN support.
+ * config/obj-elf.c (obj_elf_change_section): Merge SHF_GNU_RETAIN bit
+ between section declarations.
+ (obj_elf_parse_section_letters): Handle 'R' flag.
+ Handle numeric flag values within the SHF_MASKOS range.
+ (obj_elf_section): Validate SHF_GNU_RETAIN usage.
+ * doc/as.texi: Document 'R' flag to .section directive.
+ * testsuite/gas/elf/elf.exp: Run new tests.
+ * testsuite/gas/elf/section10.d: Unset SHF_GNU_RETAIN bit.
+ * testsuite/gas/elf/section10.s: Likewise.
+ * testsuite/gas/elf/section22.d: New test.
+ * testsuite/gas/elf/section22.s: New test.
+ * testsuite/gas/elf/section23.s: New test.
+ * testsuite/gas/elf/section23a.d: New test.
+ * testsuite/gas/elf/section23b.d: New test.
+ * testsuite/gas/elf/section23b.err: New test.
+ * testsuite/gas/elf/section24.s: New test.
+ * testsuite/gas/elf/section24a.d: New test.
+ * testsuite/gas/elf/section24b.d: New test.
+
2020-11-13 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com>
* NEWS: Update news.
diff --git a/gas/NEWS b/gas/NEWS
index 6969d1c..f44861c 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -52,6 +52,11 @@
* Configure with --enable-x86-used-note by default for Linux/x86.
+* Add support for the SHF_GNU_RETAIN flag, which can be applied to
+ sections using the 'R' flag in the .section directive.
+ SHF_GNU_RETAIN specifies that the section should not be garbage
+ collected by the linker. It requires the GNU or FreeBSD ELF OSABIs.
+
Changes in 2.35:
* X86 NaCl target support is removed.
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 7aed812..54d42d9 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -806,9 +806,17 @@ obj_elf_change_section (const char *name,
as_bad (_("changed section attributes for %s"), name);
}
else
- /* FIXME: Maybe we should consider removing a previously set
- processor or application specific attribute as suspicious ? */
- elf_section_flags (sec) = attr;
+ {
+ /* Don't overwrite a previously set SHF_GNU_RETAIN flag for the
+ section. The entire section must be marked retained. */
+ if ((elf_tdata (stdoutput)->has_gnu_osabi & elf_gnu_osabi_retain)
+ && ((elf_section_flags (old_sec) & SHF_GNU_RETAIN)))
+ attr |= SHF_GNU_RETAIN;
+
+ /* FIXME: Maybe we should consider removing a previously set
+ processor or application specific attribute as suspicious ? */
+ elf_section_flags (sec) = attr;
+ }
if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
as_bad (_("changed section entity size for %s"), name);
@@ -861,6 +869,9 @@ obj_elf_parse_section_letters (char *str, size_t len,
case 'd':
*gnu_attr |= SHF_GNU_MBIND;
break;
+ case 'R':
+ *gnu_attr |= SHF_GNU_RETAIN;
+ break;
case '?':
*is_clone = TRUE;
break;
@@ -890,8 +901,32 @@ obj_elf_parse_section_letters (char *str, size_t len,
if (ISDIGIT (*str))
{
char * end;
+ struct elf_backend_data *bed;
+ bfd_vma numeric_flags = strtoul (str, &end, 0);
+
+ attr |= numeric_flags;
+
+ bed = (struct elf_backend_data *)
+ get_elf_backend_data (stdoutput);
+
+ if (bed->elf_osabi == ELFOSABI_NONE
+ || bed->elf_osabi == ELFOSABI_STANDALONE
+ || bed->elf_osabi == ELFOSABI_GNU
+ || bed->elf_osabi == ELFOSABI_FREEBSD)
+ {
+ /* Add flags in the SHF_MASKOS range to gnu_attr for
+ OSABIs that support those flags.
+ Also adding the flags for ELFOSABI_{NONE,STANDALONE}
+ allows them to be validated later in obj_elf_section.
+ We can't just always set these bits in gnu_attr for
+ all OSABIs, since Binutils does not recognize all
+ SHF_MASKOS bits for non-GNU OSABIs. It's therefore
+ possible that numeric flags are being used to set bits
+ in the SHF_MASKOS range for those targets, and we
+ don't want assembly to fail in those situations. */
+ *gnu_attr |= (numeric_flags & SHF_MASKOS);
+ }
- attr |= strtoul (str, & end, 0);
/* Update str and len, allowing for the fact that
we will execute str++ and len-- below. */
end --;
@@ -1387,26 +1422,37 @@ obj_elf_section (int push)
done:
demand_empty_rest_of_line ();
- obj_elf_change_section (name, type, attr, entsize, &match, linkonce,
- push);
-
- if ((gnu_attr & SHF_GNU_MBIND) != 0)
+ if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
{
struct elf_backend_data *bed;
+ bfd_boolean mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
- if ((attr & SHF_ALLOC) == 0)
+ if (mbind_p && (attr & SHF_ALLOC) == 0)
as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
- if (bed->elf_osabi == ELFOSABI_NONE)
- bed->elf_osabi = ELFOSABI_GNU;
- else if (bed->elf_osabi != ELFOSABI_GNU
- && bed->elf_osabi != ELFOSABI_FREEBSD)
- as_bad (_("GNU_MBIND section is supported only by GNU "
- "and FreeBSD targets"));
- elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
+
+ if (bed->elf_osabi != ELFOSABI_GNU
+ && bed->elf_osabi != ELFOSABI_FREEBSD
+ && bed->elf_osabi != ELFOSABI_NONE)
+ as_bad (_("%s section is supported only by GNU and FreeBSD targets"),
+ mbind_p ? "GNU_MBIND" : "GNU_RETAIN");
+ else
+ {
+ if (bed->elf_osabi == ELFOSABI_NONE)
+ bed->elf_osabi = ELFOSABI_GNU;
+
+ if (mbind_p)
+ elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
+ if ((gnu_attr & SHF_GNU_RETAIN) != 0)
+ elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
+
+ attr |= gnu_attr;
+ }
}
- elf_section_flags (now_seg) |= gnu_attr;
+
+ obj_elf_change_section (name, type, attr, entsize, &match, linkonce,
+ push);
if (linked_to_section_index != -1UL)
{
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 278de41..84a7e61 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -6659,6 +6659,9 @@ section is a member of a section group
section is used for thread-local-storage
@item ?
section is a member of the previously-current section's group, if any
+@item R
+retained section (apply SHF_GNU_RETAIN to prevent linker garbage
+collection, GNU ELF extension)
@item @code{<number>}
a numeric value indicating the bits to be set in the ELF section header's flags
field. Note - if one or more of the alphabetic characters described above is
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index edacf27..0ba32c7 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -261,8 +261,12 @@ if { [is_elf_format] } then {
run_dump_test "section19"
run_dump_test "section20"
run_dump_test "section21"
+ run_dump_test "section22"
+ run_dump_test "section23a"
+ run_dump_test "section23b"
+ run_dump_test "section24a"
+ run_dump_test "section24b"
run_dump_test "sh-link-zero"
-
run_dump_test "dwarf2-1" $dump_opts
run_dump_test "dwarf2-2" $dump_opts
run_dump_test "dwarf2-3" $dump_opts
diff --git a/gas/testsuite/gas/elf/section10.d b/gas/testsuite/gas/elf/section10.d
index 554a791..6aa7b08 100644
--- a/gas/testsuite/gas/elf/section10.d
+++ b/gas/testsuite/gas/elf/section10.d
@@ -18,7 +18,7 @@
#...
[ ]*\[.*\][ ]+sec3
[ ]*PROGBITS.*
-[ ]*\[.*fefff030\]: MERGE, STRINGS,.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[3467]0000000\), UNKNOWN \(0+0ff000\)
+[ ]*\[.*fedff030\]: MERGE, STRINGS,.* EXCLUDE, OS \(.*ed00000\), PROC \(.*[3467]0000000\), UNKNOWN \(0+0ff000\)
#...
[ ]*\[.*\][ ]+sec4
[ ]*LOOS\+0x11[ ].*
@@ -26,7 +26,7 @@
#...
[ ]*\[.*\][ ]+sec5
[ ]*LOUSER\+0x9[ ].*
-[ ]*\[.*feff0000\]:.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\)
+[ ]*\[.*fedf0000\]:.* EXCLUDE, OS \(.*ed00000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\)
[ ]*\[.*\][ ]+.data.foo
[ ]*LOUSER\+0x7f000000[ ].*
[ ]*\[0+003\]: WRITE, ALLOC
diff --git a/gas/testsuite/gas/elf/section10.s b/gas/testsuite/gas/elf/section10.s
index 29f1184..d52b345 100644
--- a/gas/testsuite/gas/elf/section10.s
+++ b/gas/testsuite/gas/elf/section10.s
@@ -7,7 +7,7 @@
.word 2
# Make sure that specifying further arguments to .sections is still supported
- .section sec3, "0xfefff000MS", %progbits, 32
+ .section sec3, "0xfedff000MS", %progbits, 32
.word 3
# Make sure that extra flags can be set for well known sections as well.
@@ -19,7 +19,7 @@
.word 5
# Test both together, with a quoted type value.
- .section sec5, "0xfeff0000", "0x80000009"
+ .section sec5, "0xfedf0000", "0x80000009"
.word 6
# Test that declaring an extended version of a known special section works.
diff --git a/gas/testsuite/gas/elf/section22.d b/gas/testsuite/gas/elf/section22.d
new file mode 100644
index 0000000..8aa7fcf
--- /dev/null
+++ b/gas/testsuite/gas/elf/section22.d
@@ -0,0 +1,19 @@
+#readelf: -h -S --wide
+#name: SHF_GNU_RETAIN sections 22
+#notarget: ![supports_gnu_osabi]
+
+#...
+ +OS/ABI: +UNIX - GNU
+#...
+ \[..\] .text.discard0[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX.*
+#...
+ \[..\] .data.discard1[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WA.*
+#...
+ \[..\] .bss.discard2[ ]+NOBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WA.*
+#...
+ \[..\] .bss.retain0[ ]+NOBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR.*
+#...
+ \[..\] .data.retain1[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR.*
+#...
+ \[..\] .text.retain2[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AXR.*
+#pass
diff --git a/gas/testsuite/gas/elf/section22.s b/gas/testsuite/gas/elf/section22.s
new file mode 100644
index 0000000..66ed990
--- /dev/null
+++ b/gas/testsuite/gas/elf/section22.s
@@ -0,0 +1,34 @@
+ .section .text.discard0,"ax",%progbits
+ .global discard0
+ .type discard0, %function
+discard0:
+ .word 0
+
+ .section .data.discard1,"aw"
+ .global discard1
+ .type discard1, %object
+discard1:
+ .word 1
+
+ .section .bss.discard2,"aw"
+ .global discard2
+ .type discard2, %object
+discard2:
+ .zero 2
+
+ .section .bss.retain0,"awR",%nobits
+ .global retain0
+ .type retain0, %object
+retain0:
+ .zero 2
+
+ .section .data.retain1,"awR",%progbits
+ .type retain1, %object
+retain1:
+ .word 1
+
+ .section .text.retain2,"axR",%progbits
+ .global retain2
+ .type retain2, %function
+retain2:
+ .word 0
diff --git a/gas/testsuite/gas/elf/section23.s b/gas/testsuite/gas/elf/section23.s
new file mode 100644
index 0000000..d671119
--- /dev/null
+++ b/gas/testsuite/gas/elf/section23.s
@@ -0,0 +1,11 @@
+ .section .data.retain_var,"0x200003"
+ .global retain_var
+ .type retain_var, %object
+retain_var:
+ .long 2
+
+ .section .text._start,"ax"
+ .global _start
+ .type _start, %function
+_start:
+ .word 0
diff --git a/gas/testsuite/gas/elf/section23a.d b/gas/testsuite/gas/elf/section23a.d
new file mode 100644
index 0000000..2e413e1
--- /dev/null
+++ b/gas/testsuite/gas/elf/section23a.d
@@ -0,0 +1,10 @@
+#name: SHF_GNU_RETAIN set with numeric flag value in .section
+#source: section23.s
+#target: [supports_gnu_osabi]
+#readelf: -h -S --wide
+
+#...
+ +OS/ABI: +UNIX - GNU
+#...
+ \[..\] .data.retain_var[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR.*
+#pass
diff --git a/gas/testsuite/gas/elf/section23b.d b/gas/testsuite/gas/elf/section23b.d
new file mode 100644
index 0000000..c85200e
--- /dev/null
+++ b/gas/testsuite/gas/elf/section23b.d
@@ -0,0 +1,6 @@
+#name: SHF_GNU_RETAIN set with numeric flag value in .section for non-GNU OSABI target
+#source: section23.s
+#error_output: section23b.err
+#target: msp430-*-elf visium-*-elf
+
+# This test only runs for targets which set ELFOSABI_STANDALONE.
diff --git a/gas/testsuite/gas/elf/section23b.err b/gas/testsuite/gas/elf/section23b.err
new file mode 100644
index 0000000..83de60c
--- /dev/null
+++ b/gas/testsuite/gas/elf/section23b.err
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:1: Error: GNU_RETAIN section is supported only by GNU and FreeBSD targets
diff --git a/gas/testsuite/gas/elf/section24.s b/gas/testsuite/gas/elf/section24.s
new file mode 100644
index 0000000..adcff4a
--- /dev/null
+++ b/gas/testsuite/gas/elf/section24.s
@@ -0,0 +1,38 @@
+ .section .text,"ax",%progbits
+ .word 0
+ .section .data,"aw"
+ .word 0
+ .section .bss,"aw",%nobits
+ .word 0
+ .section .rodata,"a"
+ .word 0
+
+/* Test that we can set the 'R' flag on an existing section. */
+ .section .text,"axR",%progbits
+ .word 0
+ .section .data,"awR"
+ .word 0
+ .section .bss,"awR",%nobits
+ .word 0
+ .section .rodata,"aR"
+ .word 0
+
+/* Test that the 'R' flag does not get clobbered when the section is switched
+ back to. */
+ .section .text,"ax",%progbits
+ .word 0
+ .section .data,"aw"
+ .word 0
+ .section .bss,"aw",%nobits
+ .word 0
+ .section .rodata,"a"
+ .word 0
+
+ .section .text
+ .word 0
+ .section .data
+ .word 0
+ .section .bss
+ .word 0
+ .section .rodata
+ .word 0
diff --git a/gas/testsuite/gas/elf/section24a.d b/gas/testsuite/gas/elf/section24a.d
new file mode 100644
index 0000000..8f316d3
--- /dev/null
+++ b/gas/testsuite/gas/elf/section24a.d
@@ -0,0 +1,17 @@
+#name: Merge SHF_GNU_RETAIN for non-unique sections
+#notarget: ![supports_gnu_osabi]
+#source: section24.s
+#readelf: -h -S --wide
+
+#...
+ +OS/ABI: +UNIX - GNU
+#...
+ \[..\] .text[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AXR .*
+#...
+ \[..\] .data[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR .*
+#...
+ \[..\] .bss[ ]+NOBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR .*
+#...
+ \[..\] .rodata[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AR .*
+#pass
+
diff --git a/gas/testsuite/gas/elf/section24b.d b/gas/testsuite/gas/elf/section24b.d
new file mode 100644
index 0000000..451ec21
--- /dev/null
+++ b/gas/testsuite/gas/elf/section24b.d
@@ -0,0 +1,10 @@
+#name: Merge SHF_GNU_RETAIN for non-unique sections (check no unmerged)
+#notarget: ![supports_gnu_osabi]
+#source: section24.s
+#readelf: -S --wide
+
+#failif
+#...
+ \[..\] .(text|data|bss|rodata)[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 [^R] .*
+#pass
+