PR 33917 Internal error in S_SET_SEGMENT
Alan Modra
amodra@gmail.com
Sat Feb 21 01:24:23 GMT 2026
Commit d4d05d13eba6 attempted to fix a similar error to that uncovered
by the testcase in pr33917, but did so in a way that was wrong.
Modifying an undefined_section symbol that is an equate breaks prior
use of that symbol, as shown in the rewrite of the
section-symbol-redef test.
Another oddity found when poking at pr33917 is that gas allows
x=0
.sect x
x=u
while
.sect x
x=u
fails with "Error: symbol `x' is already defined".
Fix all of this by rewriting section_symbol to properly check for the
only case where we want to redefine an existing symbol, a truly
undefined symbol, and always use section_symbol in obj-elf rather than
trying to handle undefined symbols there too.
PR 33917
* config/obj-elf.c (change_section): Always call section_symbol
to set up sym.
* subsegs.c (section_symbol): Rewrite.
* testsuite/gas/elf/section-symbol-redef.d
* testsuite/gas/elf/section-symbol-redef.s: Rewrite.
* testsuite/gas/elf/section-symbol-redef-2.d,
* testsuite/gas/elf/section-symbol-redef-2.s: New test.
* testsuite/gas/elf/elf.exp: Run new test.
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 3c617bc36a3..e09be292cd1 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -774,8 +774,6 @@ change_section (const char *name,
if (old_sec == NULL)
{
- symbolS *secsym;
-
if (type == SHT_NULL)
type = bfd_elf_get_default_section_type (flags);
elf_section_type (sec) = type;
@@ -800,18 +798,7 @@ change_section (const char *name,
elf_group_name (sec) = match_p->group_name;
/* Add a symbol for this section to the symbol table. */
- secsym = symbol_find (name);
- if (secsym != NULL)
- {
- /* We could be repurposing an undefined symbol here: make sure we
- reset sy_value to look like other section symbols in order to avoid
- trying to incorrectly resolve this section symbol later on. */
- static const expressionS exp = { .X_op = O_constant };
- symbol_set_value_expression (secsym, &exp);
- symbol_set_bfdsym (secsym, sec->symbol);
- }
- else
- symbol_table_insert (section_symbol (sec));
+ symbol_table_insert (section_symbol (sec));
}
else
{
diff --git a/gas/subsegs.c b/gas/subsegs.c
index 2f830327dc6..199fd869f21 100644
--- a/gas/subsegs.c
+++ b/gas/subsegs.c
@@ -247,27 +247,23 @@ section_symbol (segT sec)
#define EMIT_SECTION_SYMBOLS 1
#endif
- if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen)
+ /* A reference to the section (ie. an undefined symbol)
+ should now become defined, but any other symbol that happens to
+ have the same name as the section should not be modified. Make
+ sure an undefined_section symbol isn't equated to some other
+ undefined symbol. */
+ s = symbol_find (sec->symbol->name);
+ if (s == NULL
+ || S_GET_SEGMENT (s) != undefined_section
+ || !symbol_constant_p (s))
{
- /* Here we know it won't be going into the symbol table. */
- s = symbol_create (sec->symbol->name, sec, &zero_address_frag, 0);
- }
- else
- {
- segT seg;
- s = symbol_find (sec->symbol->name);
- /* We have to make sure it is the right symbol when we
- have multiple sections with the same section name. */
- if (s == NULL
- || ((seg = S_GET_SEGMENT (s)) != sec
- && seg != undefined_section))
+ if (!EMIT_SECTION_SYMBOLS || symbol_table_frozen)
+ s = symbol_create (sec->symbol->name, sec, &zero_address_frag, 0);
+ else
s = symbol_new (sec->symbol->name, sec, &zero_address_frag, 0);
- else if (seg == undefined_section)
- {
- S_SET_SEGMENT (s, sec);
- symbol_set_frag (s, &zero_address_frag);
- }
}
+ else
+ S_SET_SEGMENT (s, sec);
S_CLEAR_EXTERNAL (s);
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index b4b4272ab9f..07acb4ad514 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -408,5 +408,6 @@ if { [is_elf_format] } then {
run_dump_test "bignums" $dump_opts
run_dump_test "section-symbol-redef"
+ run_dump_test "section-symbol-redef-2"
run_dump_test "pr27228"
}
diff --git a/gas/testsuite/gas/elf/section-symbol-redef-2.d b/gas/testsuite/gas/elf/section-symbol-redef-2.d
new file mode 100644
index 00000000000..10141c51d4d
--- /dev/null
+++ b/gas/testsuite/gas/elf/section-symbol-redef-2.d
@@ -0,0 +1,2 @@
+#error: 4: Error: symbol `x' is already defined
+#xfail: bfin-*-*
diff --git a/gas/testsuite/gas/elf/section-symbol-redef-2.s b/gas/testsuite/gas/elf/section-symbol-redef-2.s
new file mode 100644
index 00000000000..56c25bb3672
--- /dev/null
+++ b/gas/testsuite/gas/elf/section-symbol-redef-2.s
@@ -0,0 +1,6 @@
+#pr33917
+ x=0
+ .sect x
+ x=u
+ .reloc 0,BFD_RELOC_NONE,0
+ y=x
diff --git a/gas/testsuite/gas/elf/section-symbol-redef.d b/gas/testsuite/gas/elf/section-symbol-redef.d
index 149e8f9de64..1daa20bd175 100644
--- a/gas/testsuite/gas/elf/section-symbol-redef.d
+++ b/gas/testsuite/gas/elf/section-symbol-redef.d
@@ -1,5 +1,8 @@
-#readelf: -x myseg
+#objdump: -r
#xfail: bfin-*-* h8300-*
-Hex dump of section .*:
- 0x0+ 2a\s+\*
+#...
+0+ .* u
+#...
+0+ .* x
+#pass
diff --git a/gas/testsuite/gas/elf/section-symbol-redef.s b/gas/testsuite/gas/elf/section-symbol-redef.s
index 87e65699b48..55b34ea37d6 100644
--- a/gas/testsuite/gas/elf/section-symbol-redef.s
+++ b/gas/testsuite/gas/elf/section-symbol-redef.s
@@ -1,3 +1,4 @@
- myseg=not_defined_here
- .section myseg
- .byte 42
+ x=u
+ .dc.a x
+ .section x
+ .dc.a x
--
Alan Modra
More information about the Binutils
mailing list