[PATCH RFC] gas/ELF: don't accumulate .type settings
Jan Beulich
JBeulich@suse.com
Fri Jun 28 13:17:00 GMT 2019
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.
Questions:
Is a diagnostic needed (perhaps unless changing to @notype)?
What to do with @common? It getting set involves more than just setting
STT_OBJECT. Should type changes on common symbols be disallowed?
Is anyone aware of any other caveats here?
[1] https://lists.xenproject.org/archives/html/xen-devel/2019-05/msg01980.html
gas/
2019-06-28 Jan Beulich <jbeulich@suse.com>
* config/obj-elf.c (obj_elf_type): New local variable "mask".
Change "type" to flagword. Determine what flags to remove before
setting the new ones.
* testsuite/gas/elf/type-2.e,
testsuite/gas/elf/type-2.s: New.
* testsuite/gas/elf/elf.exp: Run new test.
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -1962,7 +1962,7 @@ static void
obj_elf_type (int ignore ATTRIBUTE_UNUSED)
{
char c;
- int type;
+ flagword type, mask;
const char *type_name;
symbolS *sym;
elf_symbol_type *elfsym;
@@ -2069,6 +2069,12 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSE
if (*input_line_pointer == '"')
++input_line_pointer;
+ 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;
+ elfsym->symbol.flags &= ~mask;
elfsym->symbol.flags |= type;
demand_empty_rest_of_line ();
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -230,6 +230,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" "" "" "-s" "| grep \"0 *\\\[FIONT\\\]\""
}
run_dump_test "section6"
--- /dev/null
+++ b/gas/testsuite/gas/elf/type-2.e
@@ -0,0 +1,9 @@
+ +.+: 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 +TLS +LOCAL +DEFAULT +. test7
+ +.+: 0+7 +0 +IFUNC +LOCAL +DEFAULT +. test8
--- /dev/null
+++ b/gas/testsuite/gas/elf/type-2.s
@@ -0,0 +1,41 @@
+ .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,%tls_object
+ .type test7,%object
+test7:
+ .byte 0x0
+
+ .type test8,%gnu_indirect_function
+ .type test8,%function
+test8:
+ .byte 0x0
More information about the Binutils
mailing list