This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH RFC] 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.

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]