aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog11
-rw-r--r--gas/config/obj-elf.c18
-rw-r--r--gas/testsuite/gas/elf/elf.exp2
-rw-r--r--gas/testsuite/gas/elf/section28.d15
-rw-r--r--gas/testsuite/gas/elf/section28.s11
-rw-r--r--gas/testsuite/gas/elf/section29.d11
-rw-r--r--gas/testsuite/gas/elf/section29.s4
7 files changed, 66 insertions, 6 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7978254..87fa8e7 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,14 @@
+2021-02-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR gas/27412
+ * config/obj-elf.c (obj_elf_change_section): Strip SHF_GNU_RETAIN
+ when checking incorrect section attributes.
+ * testsuite/gas/elf/elf.exp: Run section28 and section29.
+ * testsuite/gas/elf/section28.d: New file.
+ * testsuite/gas/elf/section28.s: Likewise.
+ * testsuite/gas/elf/section29.d: Likewise.
+ * testsuite/gas/elf/section29.s: Likewise.
+
2021-02-16 Jan Beulich <jbeulich@suse.com>
* testsuite/gas/i386/sse-check.s,
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index f52dc69..2fb8ccd 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -667,39 +667,45 @@ obj_elf_change_section (const char *name,
| SHF_MASKPROC))
& ~ssect->attr) != 0)
{
+ /* Strip SHF_GNU_RETAIN. */
+ bfd_vma generic_attr = attr;
+ if (elf_tdata (stdoutput)->has_gnu_osabi)
+ generic_attr &= ~SHF_GNU_RETAIN;
+
/* As a GNU extension, we permit a .note section to be
allocatable. If the linker sees an allocatable .note
section, it will create a PT_NOTE segment in the output
file. We also allow "x" for .note.GNU-stack. */
if (ssect->type == SHT_NOTE
- && (attr == SHF_ALLOC || attr == SHF_EXECINSTR))
+ && (generic_attr == SHF_ALLOC
+ || generic_attr == SHF_EXECINSTR))
;
/* Allow different SHF_MERGE and SHF_STRINGS if we have
something like .rodata.str. */
else if (ssect->suffix_length == -2
&& name[ssect->prefix_length] == '.'
- && (attr
+ && (generic_attr
& ~ssect->attr
& ~SHF_MERGE
& ~SHF_STRINGS) == 0)
;
/* .interp, .strtab and .symtab can have SHF_ALLOC. */
- else if (attr == SHF_ALLOC
+ else if (generic_attr == SHF_ALLOC
&& (strcmp (name, ".interp") == 0
|| strcmp (name, ".strtab") == 0
|| strcmp (name, ".symtab") == 0))
override = TRUE;
/* .note.GNU-stack can have SHF_EXECINSTR. */
- else if (attr == SHF_EXECINSTR
+ else if (generic_attr == SHF_EXECINSTR
&& strcmp (name, ".note.GNU-stack") == 0)
override = TRUE;
#ifdef TC_ALPHA
/* A section on Alpha may have SHF_ALPHA_GPREL. */
- else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
+ else if ((generic_attr & ~ssect->attr) == SHF_ALPHA_GPREL)
override = TRUE;
#endif
#ifdef TC_RX
- else if (attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
+ else if (generic_attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
&& (ssect->type == SHT_INIT_ARRAY
|| ssect->type == SHT_FINI_ARRAY
|| ssect->type == SHT_PREINIT_ARRAY))
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 2917ea9..525f47c 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -273,6 +273,8 @@ if { [is_elf_format] } then {
run_dump_test "section25"
run_dump_test "section26"
run_dump_test "section27"
+ run_dump_test "section28"
+ run_dump_test "section29"
run_dump_test "sh-link-zero"
run_dump_test "dwarf2-1" $dump_opts
run_dump_test "dwarf2-2" $dump_opts
diff --git a/gas/testsuite/gas/elf/section28.d b/gas/testsuite/gas/elf/section28.d
new file mode 100644
index 0000000..a1fd65b
--- /dev/null
+++ b/gas/testsuite/gas/elf/section28.d
@@ -0,0 +1,15 @@
+#readelf: -h -S --wide
+#name: SHF_GNU_RETAIN sections 28
+#notarget: ![supports_gnu_osabi]
+
+#...
+ +OS/ABI: +UNIX - (GNU|FreeBSD)
+#...
+ \[..\] \.note\.Linux +NOTE +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +A +0.*
+#...
+ \[..\] \.note\.Linux +NOTE +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +AR +0.*
+#...
+ \[..\] \.note\.foo +NOTE +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +0 +.*
+#...
+ \[..\] \.note\.foo +NOTE +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +R +0 +.*
+#pass
diff --git a/gas/testsuite/gas/elf/section28.s b/gas/testsuite/gas/elf/section28.s
new file mode 100644
index 0000000..ebcf42c
--- /dev/null
+++ b/gas/testsuite/gas/elf/section28.s
@@ -0,0 +1,11 @@
+ .section .note.Linux,"a"
+ .word 1
+
+ .section .note.Linux,"aR"
+ .word 1
+
+ .section .note.foo
+ .word 1
+
+ .section .note.foo,"R"
+ .word 1
diff --git a/gas/testsuite/gas/elf/section29.d b/gas/testsuite/gas/elf/section29.d
new file mode 100644
index 0000000..7e1b482
--- /dev/null
+++ b/gas/testsuite/gas/elf/section29.d
@@ -0,0 +1,11 @@
+#readelf: -h -S --wide
+#name: SHF_GNU_RETAIN sections 29
+#notarget: ![supports_gnu_osabi]
+
+#...
+ +OS/ABI: +UNIX - (GNU|FreeBSD)
+#...
+ \[..\] \.rodata\.str1\.1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+4 +01 +AMS +0 +0 +1
+#...
+ \[..\] \.rodata\.str1\.1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+4 +01 +AMSR +0 +0 +1
+#pass
diff --git a/gas/testsuite/gas/elf/section29.s b/gas/testsuite/gas/elf/section29.s
new file mode 100644
index 0000000..772031e
--- /dev/null
+++ b/gas/testsuite/gas/elf/section29.s
@@ -0,0 +1,4 @@
+ .section .rodata.str1.1,"aMS",%progbits,1
+ .asciz "foo"
+ .section .rodata.str1.1,"aMSR",%progbits,1
+ .asciz "bar"