[PATCH] gas/ELF: Assume merge entity size of 1 if it's missing
Jan Beulich
jbeulich@suse.com
Mon Jan 6 08:31:28 GMT 2025
On 03.01.2025 04:28, Thiago Jung Bauermann wrote:
> commit d5cbf916be4a ("gas/ELF: also reject merge entity size being zero")
> made gas stricter when an entity size isn't specified (and thus assumed to
> be zero).
>
> Unfortunately this mistake can happen in 32-bit Arm assembly, where the @
> character is the start of a comment. E.g.:
>
> .section .rodata.str, "aMS", @progbits, 1
And what if it's
.section .rodata.str, "aMS", @progbits, 4
? You just can't ...
> The aforementioned commit actually pointed out a binutils testcase with
> this problem, as well as a bug in GCC's configure script.
>
> Therefore, change the parser to accept the specific case of an absent
> entsize with "M" and assume 1, as suggested by Alan Modra.
... make such an assumption (but see below).
> With this change, a version of GCC's configure script with the bug
> recognizes support for section merging:
>
> configure:27013: checking assembler for section merging support
> configure:27022: /path/to/bin/as --fatal-warnings -o conftest.o conftest.s >&5
> conftest.s: Assembler messages:
> conftest.s:1: entity size for SHF_MERGE / SHF_STRINGS not specified. Assuming 1.
> configure:27025: $? = 0
> configure:27036: result: yes
Nor do I agree on this aspect. I'm sure --fatal-warnings is passed here
for a reason. Yet you make the diagnostics ...
> --- a/gas/config/obj-elf.c
> +++ b/gas/config/obj-elf.c
> @@ -1318,15 +1318,22 @@ obj_elf_section (int push)
> if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0
> && *input_line_pointer == ',')
> {
> + operatorT kind;
> +
> ++input_line_pointer;
> SKIP_WHITESPACE ();
> if (inherit && *input_line_pointer == ','
> && (bfd_section_flags (now_seg)
> & (SEC_MERGE | SEC_STRINGS)) != 0)
> goto fetch_entsize;
> - entsize = get_absolute_expression ();
> + entsize = get_absolute_expression_kind (&kind);
> SKIP_WHITESPACE ();
> - if (entsize <= 0)
> + if (kind == O_absent)
> + {
> + as_tsktsk (_("entity size for SHF_MERGE / SHF_STRINGS not specified. Assuming 1."));
> + entsize = 1;
> + }
> + else if (entsize <= 0)
> {
> as_warn (_("invalid merge / string entity size"));
> attr &= ~(SHF_MERGE | SHF_STRINGS);
> @@ -1342,8 +1349,8 @@ obj_elf_section (int push)
> }
> else if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0)
> {
> - as_warn (_("entity size for SHF_MERGE / SHF_STRINGS not specified"));
> - attr &= ~(SHF_MERGE | SHF_STRINGS);
> + as_tsktsk (_("entity size for SHF_MERGE / SHF_STRINGS not specified. Assuming 1."));
> + entsize = 1;
> }
... not be warnings anymore. With them being warnings, the defaulting may then
be acceptable (albeit still somewhat questionable).
> --- a/gas/read.c
> +++ b/gas/read.c
> @@ -45,6 +45,7 @@
> #include "ginsn.h"
>
> #include <limits.h>
> +#include <stdbool.h>
>
> #ifndef TC_START_LABEL
> #define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) (NEXT_CHAR == ':')
> @@ -569,6 +570,26 @@ get_absolute_expression (void)
> return get_absolute_expr (&exp);
> }
>
> +/* Return value of absolute expression starting at INPUT_LINE_POINTER and
> + set KIND to either O_constant, O_absent or O_illegal depending on
> + whether the expression was constant, absent or something else
> + entirely. */
> +
> +offsetT
> +get_absolute_expression_kind (operatorT *kind)
> +{
> + expressionS exp;
> + offsetT value;
> +
> + value = get_absolute_expr (&exp);
> + if (exp.X_op == O_absent || exp.X_op == O_constant)
> + *kind = exp.X_op;
> + else
> + *kind = O_illegal;
> +
> + return value;
> +}
Personally I question such oddly named, overly special purpose helpers.
Callers needing details on the expression simply should be using the
respective underlying functions.
Jan
More information about the Binutils
mailing list