[binutils-gdb] gas/ELF: restrict visibility changes
Jan Beulich via Binutils-cvs <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=695e1cb7f1e6158e113f6022a57083b82ff5ef54 commit 695e1cb7f1e6158e113f6022a57083b82ff5ef54 Author: Jan Beulich <[email protected]> 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