[binutils-gdb] gas/ELF: restrict visibility changes
Jan Beulich
jbeulich@sourceware.org
Fri May 8 09:47:11 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=695e1cb7f1e6158e113f6022a57083b82ff5ef54
commit 695e1cb7f1e6158e113f6022a57083b82ff5ef54
Author: Jan Beulich <jbeulich@suse.com>
Date: Fri May 8 11:44:09 2026 +0200
gas/ELF: restrict visibility changes
Since the spec mandates that the most restricting visibility ought to
propagate when linking, the same rule should apply when assembling.
Diff:
---
gas/config/obj-elf.c | 21 ++++++++++++---------
gas/testsuite/gas/elf/elf.exp | 1 +
gas/testsuite/gas/elf/pseudo.l | 1 +
gas/testsuite/gas/elf/visibility.d | 12 ++++++++++++
gas/testsuite/gas/elf/visibility.l | 5 +++++
gas/testsuite/gas/elf/visibility.s | 28 ++++++++++++++++++++++++++++
6 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index f884e577554..06216906420 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -404,21 +404,24 @@ static void
obj_elf_visibility (int visibility)
{
int c;
- symbolS *symbolP;
- asymbol *bfdsym;
- elf_symbol_type *elfsym;
do
{
- symbolP = get_sym_from_input_line_and_check ();
-
- bfdsym = symbol_get_bfdsym (symbolP);
- elfsym = elf_symbol_from (bfdsym);
+ symbolS *symbolP = get_sym_from_input_line_and_check ();
+ const asymbol *bfdsym = symbol_get_bfdsym (symbolP);
+ elf_symbol_type *elfsym = elf_symbol_from (bfdsym);
+ int current = ELF_ST_VISIBILITY (elfsym->internal_elf_sym.st_other);
gas_assert (elfsym);
- elfsym->internal_elf_sym.st_other &= ~3;
- elfsym->internal_elf_sym.st_other |= visibility;
+ if (!current || visibility <= current)
+ {
+ elfsym->internal_elf_sym.st_other &= ~ELF_ST_VISIBILITY (~0);
+ elfsym->internal_elf_sym.st_other |= visibility;
+ }
+ else
+ as_warn (_("visibility of `%s' is already `%s'"), S_GET_NAME (symbolP),
+ current == STV_HIDDEN ? "hidden" : "internal");
c = *input_line_pointer;
if (c == ',')
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index cf983057bf6..2232e2d58d9 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -237,6 +237,7 @@ if { [is_elf_format] } then {
# The alpha port uses .set for state, e.g. nomacro.
run_dump_test "symtab"
}
+ run_dump_test "visibility"
run_dump_test "symver"
run_dump_test "pr21661"
run_dump_test "pr14891"
diff --git a/gas/testsuite/gas/elf/pseudo.l b/gas/testsuite/gas/elf/pseudo.l
index 605f5b889b5..667d6205d49 100644
--- a/gas/testsuite/gas/elf/pseudo.l
+++ b/gas/testsuite/gas/elf/pseudo.l
@@ -4,6 +4,7 @@
[^:]*:6: Error: Missing symbol name in directive
[^:]*:8: Error: Missing symbol name in directive
[^:]*:10: Error: Missing symbol name in directive
+[^:]*:10: Warning: visibility of .* is already .internal.
[^:]*:12: Error: Missing symbol name in directive
[^:]*:14: Error: Missing symbol name in directive
[^:]*:14: Error: expected comma after name in .symver
diff --git a/gas/testsuite/gas/elf/visibility.d b/gas/testsuite/gas/elf/visibility.d
new file mode 100644
index 00000000000..89c977dd9ec
--- /dev/null
+++ b/gas/testsuite/gas/elf/visibility.d
@@ -0,0 +1,12 @@
+#name: diagnostics for visibility directives
+#readelf: -s -W
+#warning_output: visibility.l
+#target: [supports_gnu_unique]
+
+#...
+ +[0-9]+: +0+ +0 +(NOTYPE|OBJECT) +GLOBAL +INTERNAL +[1-9] +gd
+ +[0-9]+: +0+1 +0 +(NOTYPE|OBJECT) +WEAK +INTERNAL +[1-9] +wd
+ +[0-9]+: +0+2 +0 +OBJECT +UNIQUE +HIDDEN +[1-9] +gu
+ +[0-9]+: +0+ +0 +(NOTYPE|OBJECT) +GLOBAL +INTERNAL +UND +ge
+ +[0-9]+: +0+ +0 +(NOTYPE|OBJECT) +WEAK +HIDDEN +UND +we
+#pass
diff --git a/gas/testsuite/gas/elf/visibility.l b/gas/testsuite/gas/elf/visibility.l
new file mode 100644
index 00000000000..db2f858e8f4
--- /dev/null
+++ b/gas/testsuite/gas/elf/visibility.l
@@ -0,0 +1,5 @@
+[^:]*: Assembler messages:
+[^:]*:4: Warning: visibility of .gd. is already .internal.
+[^:]*:5: Warning: visibility of .gd. is already .internal.
+[^:]*:21: Warning: visibility of .ge. is already .hidden.
+[^:]*:26: Warning: visibility of .we. is already .hidden.
diff --git a/gas/testsuite/gas/elf/visibility.s b/gas/testsuite/gas/elf/visibility.s
new file mode 100644
index 00000000000..01ced4a5888
--- /dev/null
+++ b/gas/testsuite/gas/elf/visibility.s
@@ -0,0 +1,28 @@
+ .data
+ .global gd
+ .internal gd
+ .hidden gd
+ .protected gd
+gd: .dc.b 0
+
+ .weak wd
+ .protected wd
+ .hidden wd
+ .internal wd
+wd: .dc.b 0
+
+ .type gu, %gnu_unique_object
+ .hidden gu
+ .hidden gu
+gu: .dc.b 0
+
+ .global ge
+ .hidden ge
+ .protected ge
+ .internal ge
+
+ .weak we
+ .hidden we
+ .protected we
+ .p2align 3
+ .dc.a we
More information about the Binutils-cvs
mailing list