Commit Graph

3 Commits

Author SHA1 Message Date
Fangrui Song e28a70daf4 [ELF] Consistently prioritize non-* wildcards overs "*" in version scripts
We prioritize non-* wildcards overs VER_NDX_LOCAL/VER_NDX_GLOBAL "*".
This patch generalizes the rule to "*" of other versions and thus fixes PR40176.
I don't feel strongly about this GNU linkers' behavior but the
generalization simplifies code.

Delete `config->defaultSymbolVersion` which was used to special case
VER_NDX_LOCAL/VER_NDX_GLOBAL "*".

In `SymbolTable::scanVersionScript`, custom versions are handled the same
way as VER_NDX_LOCAL/VER_NDX_GLOBAL. So merge
`config->versionScript{Locals,Globals}` into `config->versionDefinitions`.
Overall this seems to simplify the code.

In `SymbolTable::assign{Exact,Wildcard}Versions`,
`sym->verdefIndex == config->defaultSymbolVersion` is changed to
`verdefIndex == UINT32_C(-1)`.
This allows us to give duplicate assignment diagnostics for
`{ global: foo; };` `V1 { global: foo; };`

In test/linkerscript/version-script.s:
  vs_index of an undefined symbol changes from 0 to 1. This doesn't matter (arguably 1 is better because the binding is STB_GLOBAL) because vs_index of an undefined symbol is ignored.

Reviewed By: ruiu

Differential Revision: https://reviews.llvm.org/D65716

llvm-svn: 367869
2019-08-05 14:31:39 +00:00
Fangrui Song e1ee3837ac [ELF] Handle non-glob patterns before glob patterns in version scripts & fix a corner case of --dynamic-list
This fixes PR38549, which is silently accepted by ld.bfd.
This seems correct because it makes sense to let non-glob patterns take
precedence over glob patterns.

lld issues an error because
`assignWildcardVersion(ver, VER_NDX_LOCAL);` is processed before `assignExactVersion(ver, v.id, v.name);`.

Move all assignWildcardVersion() calls after assignExactVersion() calls
to fix this.

Also, move handleDynamicList() to the bottom. computeBinding() called by
includeInDynsym() has this cryptic rule:

    if (versionId == VER_NDX_LOCAL && isDefined() && !isPreemptible)
      return STB_LOCAL;

Before the change:

* foo's version is set to VER_NDX_LOCAL due to `local: *`
* handleDynamicList() is called
  - foo.computeBinding() is STB_LOCAL
  - foo.includeInDynsym() is false
  - foo.isPreemptible is not set (wrong)
* foo's version is set to V1

After the change:

* foo's version is set to VER_NDX_LOCAL due to `local: *`
* foo's version is set to V1
* handleDynamicList() is called
  - foo.computeBinding() is STB_GLOBAL
  - foo.includeInDynsym() is true
  - foo.isPreemptible is set (correct)

Reviewed By: ruiu

Differential Revision: https://reviews.llvm.org/D64550

llvm-svn: 365760
2019-07-11 11:16:51 +00:00
Fangrui Song be8275753f [ELF] Warn rather than error when duplicate version assignments occur
In lvm2, libdevmapper.so is linked with a version script with duplicate
version assignments:

    DM_1_02_138 { global: ... dm_bitset_parse_list; ... };
    DM_1_02_129 { global: ... dm_bitset_parse_list; ... };

ld.bfd silently accepts this while gold issues a warning. We currently
error, thus inhibit producing the executable. Change the error to
warning to allow this case, and improve the message.

There are some cases where ld.bfd error
`anonymous version tag cannot be combined with other version tags`
but we just warn. It is probably OK for now.

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D64549

llvm-svn: 365759
2019-07-11 11:16:44 +00:00