[PATCH] gas/ELF: Assume merge entity size of 1 if it's missing
Thiago Jung Bauermann
thiago.bauermann@linaro.org
Fri Jan 3 03:28:31 GMT 2025
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
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.
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
PR gas/32491
* gas/config/obj-elf.c (obj_elf_section): Assume entsize of 1 if
not specified.
* gas/read.c (get_absolute_expression_kind): New function.
* gas/read.h (get_absolute_expression_kind): Declare.
---
gas/config/obj-elf.c | 15 +++++++++++----
gas/read.c | 21 +++++++++++++++++++++
gas/read.h | 1 +
3 files changed, 33 insertions(+), 4 deletions(-)
Also, note that I posted a patch to fix GCC's configure script here:
https://inbox.sourceware.org/gcc-patches/20241227214756.1059146-1-thiago.bauermann@linaro.org/
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index c4af01808b6a..d5b558210919 100644
--- 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;
}
if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && type == SHT_NOBITS)
diff --git a/gas/read.c b/gas/read.c
index 6d0d4b5e31a1..9468277bc609 100644
--- 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;
+}
+
static int pop_override_ok;
static const char *pop_table_name;
diff --git a/gas/read.h b/gas/read.h
index d11daf13034f..bc236523a89e 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -117,6 +117,7 @@ extern char *demand_copy_string (int *lenP);
extern char *demand_copy_C_string (int *len_pointer);
extern char get_absolute_expression_and_terminator (long *val_pointer);
extern offsetT get_absolute_expression (void);
+extern offsetT get_absolute_expression_kind (operatorT *kind);
extern unsigned int next_char_of_string (void);
extern void s_mri_sect (char *);
extern char *mri_comment_field (char *);
base-commit: f087e2e3f6dece21c5cb6049b4531bf762a3068f
More information about the Binutils
mailing list