diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2025-01-17 15:03:47 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@arm.com> | 2025-01-20 10:07:15 +0000 |
commit | c3190b22b03ab147a048395546a8abfa7a4c47de (patch) | |
tree | e8665d8f704a0f5fc9d8daf6ce7a1715ef9bdc6b | |
parent | bf2da5d57d7532855e56538a4a7242c705b1d27d (diff) | |
download | binutils-c3190b22b03ab147a048395546a8abfa7a4c47de.zip binutils-c3190b22b03ab147a048395546a8abfa7a4c47de.tar.gz binutils-c3190b22b03ab147a048395546a8abfa7a4c47de.tar.bz2 |
gas: elf: Relax rules for SHF_STRING sections
Commit af3394d97a8c5187085c0eec5fb03e8da88db5fb allowed sections
declared with "S" (SHF_STRING) to specify the entity size, but then
would warn if the entity size was omitted, as with the old syntax.
Unfortunately, since specifying the entity size is incompatible with
binutils 2.43 or earlier, this makes it impossible to specify a
strings section in source code without generating an assembly warning
(the new syntax isn't supported in older assemblers and the old syntax
generates warnings).
Nevertheless, the old code was wrong in that it did not set the entity
size at all, in contravention of the ELF specification (though to date
there are no known cases where this mattered outside of mergeable
sections).
Fix this by permitting the original syntax without a warning again,
but by defaulting the entity size to 1. This is compatible with the
most common case of strings being byte-based.
Added some tests for the various flavours of declaration that we
support.
-rw-r--r-- | gas/config/obj-elf.c | 14 | ||||
-rw-r--r-- | gas/doc/as.texi | 28 | ||||
-rw-r--r-- | gas/testsuite/gas/elf/elf.exp | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/elf/string.d | 9 | ||||
-rw-r--r-- | gas/testsuite/gas/elf/string.s | 10 |
5 files changed, 50 insertions, 12 deletions
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 52080cb..6670b9a 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -1340,11 +1340,21 @@ obj_elf_section (int push) fetch_entsize: entsize = now_seg->entsize; } - else if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0) + else if ((attr & SHF_MERGE) != 0) { - as_warn (_("entity size for SHF_MERGE / SHF_STRINGS not specified")); + /* ??? Perhaps we should error here. The manual says that + entsize must be specified if SHF_MERGE is set. */ + as_warn (_("entity size for SHF_MERGE not specified")); attr &= ~(SHF_MERGE | SHF_STRINGS); } + else if ((attr & SHF_STRINGS) != 0) + { + /* Ideally we would warn about this, but older versions + of gas did not permit an entity size to be specified, + so we have to default this silently for + compatibility. */ + entsize = 1; + } if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && type == SHT_NOBITS) as_warn (_("bogus SHF_MERGE / SHF_STRINGS for SHT_NOBITS section")); diff --git a/gas/doc/as.texi b/gas/doc/as.texi index c9f65a4..d95ce9c 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -7011,7 +7011,16 @@ Note - some sections, eg @code{.text} and @code{.data} are considered to be special and have fixed types. Any attempt to declare them with a different type will generate an error from the assembler. -If @var{flags} contains the @code{M} and/or @code{S} symbol then the @var{type} +If @var{flags} contains the @code{S} flag then the section contains +zero-terminated strings. The size of each character in the string is specified +in octets by the entity size, @var{entsize}, which defaults to @code{1}, but +can be set using the syntax + +@smallexample +.section @var{name}, "@var{flags}"S[, @@@var{type}] [, @var{entsize}] +@end smallexample + +If @var{flags} contains the @code{M} flag then the @var{type} argument must be specified as well as an extra argument---@var{entsize}---like this: @@ -7019,15 +7028,14 @@ this: .section @var{name} , "@var{flags}"M, @@@var{type}, @var{entsize} @end smallexample -Sections with the @code{M} flag but not @code{S} flag must contain fixed size -constants, each @var{entsize} octets long. Sections with @code{S} must contain -zero terminated strings where each character is @var{entsize} bytes long. For -@code{M} sections the linker may remove duplicates within sections with -the same name, same entity size and same flags. @var{entsize} must be an -absolute expression. For sections with both @code{M} and @code{S}, a string -which is a suffix of a larger string is considered a duplicate. Thus -@code{"def"} will be merged with @code{"abcdef"}; A reference to the first -@code{"def"} will be changed to a reference to @code{"abcdef"+3}. +Sections with the @code{M} flag but not the @code{S} flag must contain fixed +size constants, each @var{entsize} octets long. For @code{M} sections the +linker may remove duplicates within sections with the same name, same entity +size and same flags. @var{entsize} must be an absolute expression. For +sections with both @code{M} and @code{S}, a string which is a suffix of a +larger string is considered a duplicate. Thus @code{"def"} will be merged with +@code{"abcdef"}; A reference to the first @code{"def"} will be changed to a +reference to @code{"abcdef"+3}. If @var{flags} contains the @code{o} flag, then the @var{type} argument must be present along with an additional field like this: diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index 5103880..1f42c3f 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -292,6 +292,7 @@ if { [is_elf_format] } then { run_dump_test "section29" run_dump_test "section30" $dump_opts run_dump_test "sh-link-zero" + run_dump_test "string" run_dump_test "size" run_dump_test "dwarf2-1" $dump_opts run_dump_test "dwarf2-2" $dump_opts diff --git a/gas/testsuite/gas/elf/string.d b/gas/testsuite/gas/elf/string.d new file mode 100644 index 0000000..6fcfe46 --- /dev/null +++ b/gas/testsuite/gas/elf/string.d @@ -0,0 +1,9 @@ +#readelf: -SW +#name: string sections + +#... +[ ]*\[.*\][ ]+\.str1[ ]+PROGBITS[ ]+0+[ ]+[0-9a-f]+[ ]+[0-9a-f]+[ ]+01[ ]+S[ ]+.* +[ ]*\[.*\][ ]+\.str2[ ]+PROGBITS[ ]+0+[ ]+[0-9a-f]+[ ]+[0-9a-f]+[ ]+01[ ]+S[ ]+.* +[ ]*\[.*\][ ]+\.str3[ ]+PROGBITS[ ]+0+[ ]+[0-9a-f]+[ ]+[0-9a-f]+[ ]+01[ ]+S[ ]+.* +[ ]*\[.*\][ ]+\.str4[ ]+PROGBITS[ ]+0+[ ]+[0-9a-f]+[ ]+[0-9a-f]+[ ]+02[ ]+S[ ]+.* +#pass diff --git a/gas/testsuite/gas/elf/string.s b/gas/testsuite/gas/elf/string.s new file mode 100644 index 0000000..78c22f7 --- /dev/null +++ b/gas/testsuite/gas/elf/string.s @@ -0,0 +1,10 @@ +# Test extended forms of string section. Only the first of these was supported +# in binutils 2.43 and earlier, but it failed to set the entity size. + .section .str1,"S" + .asciz "abc" + .section .str2,"S",1 + .asciz "def" + .section .str3,"S",%progbits + .asciz "ghi" + .section .str4,"S",%progbits,2 + .short 32, 0 |