aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2019-07-04 10:35:47 +0200
committerJan Beulich <jbeulich@suse.com>2019-07-04 10:35:47 +0200
commitf2d4ba38f5723a207c40a288036af2f38b70e837 (patch)
tree4f864465aad8dfadd14c3ee62cc9f0ca7c743045
parentdb7fbcbeb749c0d4ea19284438d62b253648c58a (diff)
downloadgdb-f2d4ba38f5723a207c40a288036af2f38b70e837.zip
gdb-f2d4ba38f5723a207c40a288036af2f38b70e837.tar.gz
gdb-f2d4ba38f5723a207c40a288036af2f38b70e837.tar.bz2
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
-rw-r--r--gas/ChangeLog11
-rw-r--r--gas/config/obj-elf.c33
-rw-r--r--gas/config/tc-hppa.h8
-rw-r--r--gas/doc/as.texi4
-rw-r--r--gas/testsuite/gas/elf/elf.exp1
-rw-r--r--gas/testsuite/gas/elf/type-2.e10
-rw-r--r--gas/testsuite/gas/elf/type-2.l3
-rw-r--r--gas/testsuite/gas/elf/type-2.s49
-rw-r--r--ld/ChangeLog4
-rw-r--r--ld/testsuite/ld-elf/group9.s2
10 files changed, 123 insertions, 2 deletions
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 <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
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 <jbeulich@suse.com>
+
+ * testsuite/ld-elf/group9.s: Correct argument of .type.
+
2019-07-02 Nick Clifton <nickc@redhat.com>
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