[BFD][PR21703]Override the new defined symbol with the old normal symbol when --allow...
authorRenlin Li <renlin.li@arm.com>
Tue, 24 Oct 2017 11:42:30 +0000 (12:42 +0100)
committerRenlin Li <renlin.li@arm.com>
Tue, 24 Oct 2017 12:01:48 +0000 (13:01 +0100)
The behavior of _bfd_elf_merge_symbol and _bfd_generic_link_add_one_symbol is
inconsistent.

In multiple definition case, _bfd_elf_merge_symbol decided to override the old
symbol definition with the new defintion, (size, type, target data)
In _bfd_generic_link_add_one_symbol, it simply return without doing anything
because of allow-multiple-definition is provided.
This leaves the symbol in a wrong state.

Here, following the documentation, I made this patch to force the old definition
override the new definition if the old symbol is not dynamic or weak.
Because, in those two cases, it's expected to do some merge. I have checked
that, those two cases are properly handled.

bfd/
PR ld/21703
* elflink.c (_bfd_elf_merge_symbol): Handle multiple definition case.

ld/

PR ld/21703
* testsuite/ld-elf/elf.exp: Run new tests.
* testsuite/ld-elf/pr21703-1.s: New.
* testsuite/ld-elf/pr21703-2.s: New.
* testsuite/ld-elf/pr21703-3.s: New.
* testsuite/ld-elf/pr21703-4.s: New.
* testsuite/ld-elf/pr21703-r.sd: New.
* testsuite/ld-elf/pr21703-shared.sd: New.
* testsuite/ld-elf/pr21703.sd: New.
* testsuite/ld-elf/pr21703.ver: New.

12 files changed:
bfd/ChangeLog
bfd/elflink.c
ld/ChangeLog
ld/testsuite/ld-elf/elf.exp
ld/testsuite/ld-elf/pr21703-1.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr21703-2.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr21703-3.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr21703-4.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr21703-r.sd [new file with mode: 0644]
ld/testsuite/ld-elf/pr21703-shared.sd [new file with mode: 0644]
ld/testsuite/ld-elf/pr21703.sd [new file with mode: 0644]
ld/testsuite/ld-elf/pr21703.ver [new file with mode: 0644]

index 73d1f4b145c6debd7fa15d36ad2e39f50559e4e0..a534b216af1aea5dc248bd3373419441a4ac9a79 100644 (file)
@@ -1,3 +1,8 @@
+2017-10-24  Renlin Li  <renlin.li@arm.com>
+
+       PR ld/21703
+       * elflink.c (_bfd_elf_merge_symbol): Handle multiple definition case.
+
 2017-10-23  Nick Clifton  <nickc@redhat.com>
 
        PR 22319
index de13d04c8924ac6ad7f9b8d52eb731bad7b773c2..20057f55f1678c4a75e8cfb3e6e2940337b52a37 100644 (file)
@@ -1036,6 +1036,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
   bfd_boolean newweak, oldweak, newfunc, oldfunc;
   const struct elf_backend_data *bed;
   char *new_version;
+  bfd_boolean default_sym = *matched;
 
   *skip = FALSE;
   *override = FALSE;
@@ -1557,6 +1558,18 @@ _bfd_elf_merge_symbol (bfd *abfd,
       sec = *psec;
     }
 
+  /* There are multiple definitions of a normal symbol.
+     Skip the default symbol as well.  */
+  if (olddef && !olddyn && !oldweak && newdef && !newdyn && !newweak
+      && !default_sym && h->def_regular)
+    {
+      /* Handle a multiple definition.  */
+      (*info->callbacks->multiple_definition) (info, &h->root,
+                                              abfd, sec, *pvalue);
+      *skip = TRUE;
+      return TRUE;
+    }
+
   /* If both the old and the new symbols look like common symbols in a
      dynamic object, set the size of the symbol to the larger of the
      two.  */
index ac96579e44263b4e22d99b729d3c2b1205d27166..7319d72ef8f7d7ce84b586d7fbe8a8428a6ec3b2 100644 (file)
@@ -1,3 +1,16 @@
+2017-10-24  Renlin Li  <renlin.li@arm.com>
+
+       PR ld/21703
+       * testsuite/ld-elf/elf.exp: Run new tests.
+       * testsuite/ld-elf/pr21703-1.s: New.
+       * testsuite/ld-elf/pr21703-2.s: New.
+       * testsuite/ld-elf/pr21703-3.s: New.
+       * testsuite/ld-elf/pr21703-4.s: New.
+       * testsuite/ld-elf/pr21703-r.sd: New.
+       * testsuite/ld-elf/pr21703-shared.sd: New.
+       * testsuite/ld-elf/pr21703.sd: New.
+       * testsuite/ld-elf/pr21703.ver: New.
+
 2017-10-23  H.J. Lu  <hongjiu.lu@intel.com>
 
        * configure.tgt (i[3-7]86-*-linux-*): Move elf32_x86_64 from
index 655f0daf230d54d9cff35acb5c975ce45cadc681..eac29e0390241a56c28ab97deb80cd01d9915d64 100644 (file)
@@ -70,6 +70,18 @@ run_ld_link_tests [list \
        {symbol3w.s} {} "symbol3w.a" ] \
 ]
 
+run_ld_link_tests [list \
+    [list "PR ld/21703" \
+       "--allow-multiple-definition tmpdir/pr21703-1.o tmpdir/pr21703-2.o" "" "" \
+       {pr21703-1.s pr21703-2.s} {{readelf {-s} pr21703.sd}} "pr21703" ] \
+    [list "PR ld/21703 -r" \
+       "-r --allow-multiple-definition tmpdir/pr21703-3.o tmpdir/pr21703-4.o" "" "" \
+       {pr21703-3.s pr21703-4.s} {{readelf {-s} pr21703-r.sd}} "pr21703.o" ] \
+    [list "PR ld/21703 shared" \
+       "-shared --allow-multiple-definition --version-script pr21703.ver tmpdir/pr21703-3.o tmpdir/pr21703-4.o" "" "" \
+       {pr21703-3.s pr21703-4.s} {{readelf {--dyn-syms} pr21703-shared.sd}} "pr21703.so" ] \
+]
+
 if { [check_shared_lib_support] } then {
     run_ld_link_tests {
        {"Build pr14170a.o" "" "" "" {pr14170a.s} {} "pr14170.a" }
diff --git a/ld/testsuite/ld-elf/pr21703-1.s b/ld/testsuite/ld-elf/pr21703-1.s
new file mode 100644 (file)
index 0000000..92a4718
--- /dev/null
@@ -0,0 +1,6 @@
+       .text
+       .globl  foo
+       .type   foo, %function
+foo:
+       .space  4
+       .size   foo, 4
diff --git a/ld/testsuite/ld-elf/pr21703-2.s b/ld/testsuite/ld-elf/pr21703-2.s
new file mode 100644 (file)
index 0000000..1d65304
--- /dev/null
@@ -0,0 +1,6 @@
+       .text
+       .globl  foo
+       .type   foo, %function
+foo:
+       .space  16
+       .size   foo, 16
diff --git a/ld/testsuite/ld-elf/pr21703-3.s b/ld/testsuite/ld-elf/pr21703-3.s
new file mode 100644 (file)
index 0000000..6da6de8
--- /dev/null
@@ -0,0 +1,15 @@
+       .text
+       .global foo
+       .type   foo, %function
+foo:
+       .space  4
+       .size   foo, 4
+
+       .global foo1
+       .type   foo1, %function
+foo1:
+       .space  32
+       .size   foo1, 32
+
+       .symver foo, foo@FOO
+       .symver foo1, foo@@FOO1
diff --git a/ld/testsuite/ld-elf/pr21703-4.s b/ld/testsuite/ld-elf/pr21703-4.s
new file mode 100644 (file)
index 0000000..9390e94
--- /dev/null
@@ -0,0 +1,15 @@
+       .text
+       .global bar
+       .type   bar, %function
+bar:
+       .space  16
+       .size   bar, 16
+
+       .global bar1
+       .type   bar1, %function
+bar1:
+       .space  8
+       .size   bar1, 8
+
+       .symver bar, foo@FOO
+       .symver bar1, foo@@FOO1
diff --git a/ld/testsuite/ld-elf/pr21703-r.sd b/ld/testsuite/ld-elf/pr21703-r.sd
new file mode 100644 (file)
index 0000000..6758088
--- /dev/null
@@ -0,0 +1,9 @@
+Symbol table '.symtab' contains .* entries:
+#...
+.*: [0-9a-fA-F]* +4 +FUNC +GLOBAL +DEFAULT +. foo@FOO
+.*: [0-9a-fA-F]* +32 +FUNC +GLOBAL +DEFAULT +. foo1
+.*: [0-9a-fA-F]* +32 +FUNC +GLOBAL +DEFAULT +. foo@@FOO1
+.*: [0-9a-fA-F]* +8 +FUNC +GLOBAL +DEFAULT +. bar1
+.*: [0-9a-fA-F]* +4 +FUNC +GLOBAL +DEFAULT +. foo
+.*: [0-9a-fA-F]* +16 +FUNC +GLOBAL +DEFAULT +. bar
+#pass
diff --git a/ld/testsuite/ld-elf/pr21703-shared.sd b/ld/testsuite/ld-elf/pr21703-shared.sd
new file mode 100644 (file)
index 0000000..9b6b1b9
--- /dev/null
@@ -0,0 +1,8 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +4 +FUNC +GLOBAL +DEFAULT +[0-9] +foo@FOO
+ +[0-9]+: +[0-9a-f]+ +0 +OBJECT +GLOBAL +DEFAULT +ABS +FOO1
+ +[0-9]+: +[0-9a-f]+ +32 +FUNC +GLOBAL +DEFAULT +[0-9] +foo@@FOO1
+ +[0-9]+: +[0-9a-f]+ +0 +OBJECT +GLOBAL +DEFAULT +ABS +FOO
+#...
diff --git a/ld/testsuite/ld-elf/pr21703.sd b/ld/testsuite/ld-elf/pr21703.sd
new file mode 100644 (file)
index 0000000..955cf17
--- /dev/null
@@ -0,0 +1,4 @@
+Symbol table '.symtab' contains .* entries:
+#...
+.*: [0-9a-fA-F]* +4 +FUNC +GLOBAL +DEFAULT +. foo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21703.ver b/ld/testsuite/ld-elf/pr21703.ver
new file mode 100644 (file)
index 0000000..c36f292
--- /dev/null
@@ -0,0 +1,4 @@
+FOO
+{ global: foo; local: *; };
+FOO1
+{ global: foo; local: *; };