gas/ELF: don't accumulate .type settings
authorJan Beulich <jbeulich@suse.com>
Thu, 4 Jul 2019 08:35:47 +0000 (10:35 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 4 Jul 2019 08:35:47 +0000 (10:35 +0200)
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
gas/config/obj-elf.c
gas/config/tc-hppa.h
gas/doc/as.texi
gas/testsuite/gas/elf/elf.exp
gas/testsuite/gas/elf/type-2.e [new file with mode: 0644]
gas/testsuite/gas/elf/type-2.l [new file with mode: 0644]
gas/testsuite/gas/elf/type-2.s [new file with mode: 0644]
ld/ChangeLog
ld/testsuite/ld-elf/group9.s

index 1356aabbebb2d40a942ee631c7d6a6893ca33341..ab00f146db5723cd3551e6225a153fd7d3daf4b8 100644 (file)
@@ -1,3 +1,14 @@
+2019-07-04  Jan Beulich  <jbeulich@suse.com>
+
+       * 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  <nickc@redhat.com>
 
        * testsuite/gas/aarch64/codealign.d: Update to work with a
index 318e27d67c1c3e58f1a1b7d89f75537822dadd9c..224d4c29e6cf919c27f9c519a813e5cf485fe4a1 100644 (file)
@@ -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 ();
 }
index 42fd5d2a932d91fa8653915c906a51f3cc4d8d78..ab54b4d095197f70441761c8ad5a582c82d29fa6 100644 (file)
@@ -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 \
index b177daa73713a5b2d3bb445e743ddf2e39b21c73..b4598e86dc6e188aa04d46252391c3cdc3354475 100644 (file)
@@ -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
index eb9bd9c5de8619f517f3ae5d58152b40649c7d10..b27a7ecabb208641c23234cc39b941197ddfc0ed 100644 (file)
@@ -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 (file)
index 0000000..684727c
--- /dev/null
@@ -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 (file)
index 0000000..f4c626e
--- /dev/null
@@ -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 (file)
index 0000000..c0a28eb
--- /dev/null
@@ -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
index d4916f4b698cc6216b1d49ce2e0e74100bfc8c26..dbf2d2e4b5ce1bf60e91d5b71726e78a638ed0c5 100644 (file)
@@ -1,3 +1,7 @@
+2019-07-04  Jan Beulich  <jbeulich@suse.com>
+
+       * testsuite/ld-elf/group9.s: Correct argument of .type.
+
 2019-07-02  Nick Clifton  <nickc@redhat.com>
 
        PR 24753
index 933c9f9e8ac8c0acde40a7c225b45eec34971399..9f0bccbdd2f5c3c0b3911dbddc484021ad255411 100644 (file)
@@ -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