diff options
author | Renlin Li <renlin.li@arm.com> | 2017-10-24 12:42:30 +0100 |
---|---|---|
committer | Renlin Li <renlin.li@arm.com> | 2017-10-24 13:01:48 +0100 |
commit | 93f4de3929aeb3e21d57950bfa96539599a92f2a (patch) | |
tree | 0ff309d325abe18c23c96887731b1b0b5a2463e6 /bfd/elflink.c | |
parent | eb2bfbadc159ff1463e58daf24c4ad5d1a23796d (diff) | |
download | gdb-93f4de3929aeb3e21d57950bfa96539599a92f2a.zip gdb-93f4de3929aeb3e21d57950bfa96539599a92f2a.tar.gz gdb-93f4de3929aeb3e21d57950bfa96539599a92f2a.tar.bz2 |
[BFD][PR21703]Override the new defined symbol with the old normal symbol when --allow-multiple-definition is provided.
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.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index de13d04..20057f5 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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. */ |