From f2d4ba38f5723a207c40a288036af2f38b70e837 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 4 Jul 2019 10:35:47 +0200 Subject: [PATCH] gas/ELF: don't accumulate .type settings Recently a patch was submitted for a Xen Project test harness binary to override the compiler specified @object to @func (see [1]). In a reply I suggested we shouldn't make ourselves dependent on currently unspecified behavior of gas here: It accumulates all requests, and then bfd/elf.c:swap_out_syms(), in an apparently ad hoc manner, prioritizes certain flags over others. Make the behavior predictable: Generally the last .type is what counts. Exceptions are directives which set multiple bits (TLS, IFUNC, and UNIQUE): Subsequent directives requesting just the more generic bit (i.e. FUNC following IFUNC) won't clear the more specific one. Warn about incompatible changes, except from/to STT_NOTYPE. Also add a new target hook, which hppa wants to use right away afaict. In the course of adding the warning I ran into two ld testsuite failures. I can only assume that it was a copy-and-paste mistake that lead to the same symbol having its type set twice. [1] https://lists.xenproject.org/archives/html/xen-devel/2019-05/msg01980.html --- gas/ChangeLog | 11 ++++++++++ gas/config/obj-elf.c | 33 +++++++++++++++++++++++++++- gas/config/tc-hppa.h | 8 +++++++ gas/doc/as.texi | 4 ++++ gas/testsuite/gas/elf/elf.exp | 1 + gas/testsuite/gas/elf/type-2.e | 10 +++++++++ gas/testsuite/gas/elf/type-2.l | 3 +++ gas/testsuite/gas/elf/type-2.s | 49 ++++++++++++++++++++++++++++++++++++++++++ ld/ChangeLog | 4 ++++ ld/testsuite/ld-elf/group9.s | 2 +- 10 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 gas/testsuite/gas/elf/type-2.e create mode 100644 gas/testsuite/gas/elf/type-2.l create mode 100644 gas/testsuite/gas/elf/type-2.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 1356aab..ab00f14 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2019-07-04 Jan Beulich + + * config/obj-elf.c (obj_elf_type): Check for conflicts between + old and new types. + * config/tc-hppa.h (md_elf_symbol_type_change): New. + * doc/as.texi: Mention warning behavior for the ELF flavor of + .type. + * testsuite/gas/elf/type-2.e, testsuite/gas/elf/type-2.l, + testsuite/gas/elf/type-2.s: New. + * testsuite/gas/elf/elf.exp: Run new test. + 2019-07-03 Nick Clifton * testsuite/gas/aarch64/codealign.d: Update to work with a diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 318e27d..224d4c2 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -2069,7 +2069,38 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED) if (*input_line_pointer == '"') ++input_line_pointer; - elfsym->symbol.flags |= type; +#ifdef md_elf_symbol_type_change + if (!md_elf_symbol_type_change (sym, elfsym, type)) +#endif + { + flagword mask = BSF_FUNCTION | BSF_OBJECT; + + if (type != BSF_FUNCTION) + mask |= BSF_GNU_INDIRECT_FUNCTION; + if (type != BSF_OBJECT) + { + mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL; + + if (S_IS_COMMON (sym)) + { + as_bad (_("cannot change type of common symbol '%s'"), + S_GET_NAME (sym)); + mask = type = 0; + } + } + + /* Don't warn when changing to STT_NOTYPE. */ + if (type) + { + flagword new = (elfsym->symbol.flags & ~mask) | type; + + if (new != (elfsym->symbol.flags | type)) + as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym)); + elfsym->symbol.flags = new; + } + else + elfsym->symbol.flags &= ~mask; + } demand_empty_rest_of_line (); } diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h index 42fd5d2..ab54b4d 100644 --- a/gas/config/tc-hppa.h +++ b/gas/config/tc-hppa.h @@ -177,6 +177,14 @@ int hppa_fix_adjustable (struct fix *); ), BSF_FUNCTION) \ : -1) +/* Handle type change from .type pseudo: Zap STT_PARISC_MILLI when + switching to a non-function type. */ +#define md_elf_symbol_type_change(sym, elf, type) \ + ((type) != BSF_FUNCTION \ + && (((elf)->internal_elf_sym.st_info = \ + ELF_ST_INFO (ELF_ST_BIND ((elf)->internal_elf_sym.st_info), \ + STT_NOTYPE)), 0)) + #define tc_frob_symbol(sym,punt) \ { \ if ((S_GET_SEGMENT (sym) == bfd_und_section_ptr \ diff --git a/gas/doc/as.texi b/gas/doc/as.texi index b177daa..b4598e8 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -7215,6 +7215,10 @@ systems). @end table +Changing between incompatible types other than from/to STT_NOTYPE will +result in a diagnostic. An intermediate change to STT_NOTYPE will silence +this. + Note: Some targets support extra types in addition to those listed above. @end ifset diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index eb9bd9c..b27a7ec 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -229,6 +229,7 @@ if { [is_elf_format] } then { } else { run_dump_test ifunc-1 run_elf_list_test "type" "" "" "-s" "| grep \"1 *\\\[FIONTCU\\\]\"" + run_elf_list_test "type-2" "" "--warn" "-s" "| grep \"0 *\\\[FIONT\\\]\"" } run_dump_test "section6" diff --git a/gas/testsuite/gas/elf/type-2.e b/gas/testsuite/gas/elf/type-2.e new file mode 100644 index 0000000..684727c --- /dev/null +++ b/gas/testsuite/gas/elf/type-2.e @@ -0,0 +1,10 @@ + +.+: 0+0 +0 +NOTYPE +LOCAL +DEFAULT +UND * + +.+: 0+0 +0 +OBJECT +LOCAL +DEFAULT +. test1 + +.+: 0+1 +0 +FUNC +LOCAL +DEFAULT +. test2 + +.+: 0+2 +0 +NOTYPE +LOCAL +DEFAULT +. test3 + +.+: 0+3 +0 +NOTYPE +LOCAL +DEFAULT +. test4 + +.+: 0+4 +0 +NOTYPE +LOCAL +DEFAULT +. test5 + +.+: 0+5 +0 +NOTYPE +LOCAL +DEFAULT +. test6 + +.+: 0+6 +0 +OBJECT +LOCAL +DEFAULT +. test7 + +.+: 0+7 +0 +TLS +LOCAL +DEFAULT +. test8 + +.+: 0+8 +0 +IFUNC +LOCAL +DEFAULT +. test9 diff --git a/gas/testsuite/gas/elf/type-2.l b/gas/testsuite/gas/elf/type-2.l new file mode 100644 index 0000000..f4c626e --- /dev/null +++ b/gas/testsuite/gas/elf/type-2.l @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:4: Warning: .* +.*:9: Warning: .* diff --git a/gas/testsuite/gas/elf/type-2.s b/gas/testsuite/gas/elf/type-2.s new file mode 100644 index 0000000..c0a28eb --- /dev/null +++ b/gas/testsuite/gas/elf/type-2.s @@ -0,0 +1,49 @@ + .text + + .type test1,%function + .type test1,%object +test1: + .byte 0x0 + + .type test2,%object + .type test2,%function +test2: + .byte 0x0 + + .type test3,%object + .type test3,%notype +test3: + .byte 0x0 + + .type test4,%function + .type test4,%notype +test4: + .byte 0x0 + + .type test5,%tls_object + .type test5,%notype +test5: + .byte 0x0 + + .type test6,%gnu_indirect_function + .type test6,%notype +test6: + .byte 0x0 + + .type test7,%function + .type test7,%notype + .type test7,%object +test7: + .byte 0x0 + + .type test8,%object + .type test8,%tls_object + .type test8,%object +test8: + .byte 0x0 + + .type test9,%function + .type test9,%gnu_indirect_function + .type test9,%function +test9: + .byte 0x0 diff --git a/ld/ChangeLog b/ld/ChangeLog index d4916f4..dbf2d2e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,7 @@ +2019-07-04 Jan Beulich + + * testsuite/ld-elf/group9.s: Correct argument of .type. + 2019-07-02 Nick Clifton PR 24753 diff --git a/ld/testsuite/ld-elf/group9.s b/ld/testsuite/ld-elf/group9.s index 933c9f9..9f0bccb 100644 --- a/ld/testsuite/ld-elf/group9.s +++ b/ld/testsuite/ld-elf/group9.s @@ -5,7 +5,7 @@ foo: .byte 0 .section .data.foo,"axG",%progbits,foo,comdat .globl foo.data - .type foo,%object + .type foo.data,%object foo.data: .byte 0 .section .text.bar,"axG",%progbits,bar,comdat -- 2.7.4