543 Commits

Author SHA1 Message Date
Fangrui Song 0334578edc [ELF] --wrap: don't leave the original symbol as SHN_UNDEF in .symtab or .dynsym 2020-08-08 18:18:20 -07:00
William S. Moses dc6b3f03a8 [ELF] Drop an unneeded reference to symtab from SymbolTable::addSymbol
The Symbol Table in LLD references the global object to add a symbol rather than adding it to itself.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D83184
2020-07-06 12:05:54 -07:00
Fangrui Song a6ae333a0c [ELF] --wrap: don't error undefined reference to __real_foo (--no-allow-shlib-undefined) if foo is a wrapped definition
This is a regression after D51283.

Also, export `foo` if `__real_foo` is referenced by a shared object.
2020-06-01 23:00:51 -07:00
Rui Ueyama 54d2896852 [ELF] --wrap: Drop __real_ symbol from the symbol table
In D34993, we discussed and concluded that we should drop `__real_
symbol from the symbol table, but I did the opposite in D50569.
This patch is to drop `__real_` symbol.

MaskRay's note: omitting `__real_` is important if it is undefined:
otherwise a subsequent link may error due to the undefined `__real_` in .dynsym

Differential Revision: https://reviews.llvm.org/D51283
2020-05-27 16:58:00 -07:00
Fangrui Song 07837b8f49 [ELF] Use namespace qualifiers (lld:: or elf::) instead of namespace lld { namespace elf {
Similar to D74882. This reverts much code from commit
bd8cfe65f5 (D68323) and fixes some
problems before D68323.

Sorry for the churn but D68323 was a mistake. Namespace qualifiers avoid
bugs where the definition does not match the declaration from the
header. See
https://llvm.org/docs/CodingStandards.html#use-namespace-qualifiers-to-implement-previously-declared-functions (D74515)

Differential Revision: https://reviews.llvm.org/D79982
2020-05-15 08:49:53 -07:00
Fangrui Song c1c679e2d2 [ELF] Make --version-script/--dynamic-list work for lazy symbols fetched by LTO libcalls
Fixes https://bugs.llvm.org/show_bug.cgi?id=45391

The LTO code generator happens after version script scanning and may
create references which will fetch some lazy symbols.

Currently a version script does not assign VER_NDX_LOCAL to lazy symbols
and such symbols will be made global after they are fetched.

Change findByVersion and findAllByVersion to work on lazy symbols.
For unfetched lazy symbols, we should keep them non-local (D35263).
Check isDefined() in computeBinding() as a compensation.

This patch fixes a companion bug that --dynamic-list does not export
libcall fetched symbols.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D77280
2020-04-06 09:47:06 -07:00
Thomas Preud'homme c42fe24754 [lld/ELF] PR44498: Support input filename in double quote
Summary:
Linker scripts allow filenames to be put in double quotes to prevent
characters in filenames that are part of the linker script syntax from
having their special meaning. Case in point the * wildcard character.

Availability of double quoting filenames also allows to fix a failure in
ELF/linkerscript/filename-spec.s when the path contain a @ which the
lexer consider as a special characters and thus break up a filename
containing it. This may happens under Jenkins which createspath such as
pipeline@2.

To avoid the need for escaping GlobPattern metacharacters in filename
in double quotes, GlobPattern::create is augmented with a new parameter
to request literal matching instead of relying on the presence of a
wildcard character in the pattern.

Reviewers: jhenderson, MaskRay, evgeny777, espindola, alexshap

Reviewed By: MaskRay

Subscribers: peter.smith, grimar, ruiu, emaste, arichardson, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72517
2020-01-22 12:03:10 +00:00
Nico Weber 5976a3f5aa Fix a few typos in lld/ELF to cycle bots 2019-10-28 21:41:47 -04:00
Fangrui Song bd8cfe65f5 [ELF] Wrap things in namespace lld { namespace elf {, NFC
This makes it clear `ELF/**/*.cpp` files define things in the `lld::elf`
namespace and simplifies `elf::foo` to `foo`.

Reviewed By: atanasyan, grimar, ruiu

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

llvm-svn: 373885
2019-10-07 08:31:18 +00:00
Martin Storsjo 5ebab1f8f9 [LLD] Simplify the demangleItanium function. NFC.
Instead of returning an optional, just return the input string if
demangling fails, as that's what all callers use anyway.

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

llvm-svn: 373077
2019-09-27 12:24:18 +00:00
Fangrui Song f1d538cce5 [ELF] Initialize 2 fields of Symbol in SymbolTable::insert
A new symbol is added to elf::symtab in 3 steps:

1) SymbolTable::insert creates a placeholder.
2) Symbol::mergeProperties
3) Symbol::replace

Fields referenced by steps 2) and 3) should be initialized in
SymbolTable::insert.  `traced` and `referenced` were missed previously.
This did not cause problems because compilers generated code that
initialized them (bit fields) to 0.

Reviewed By: grimar

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

llvm-svn: 368784
2019-08-14 01:52:47 +00:00
Fangrui Song c6cd62352c [ELF] Simplify handling of exportDynamic and isPreemptible
In Writer::includeInDynSym(), exportDynamic is used by a Defined with
protected or default visibility, to record whether it is required to be
exported into .dynsym. It is set when any of the following conditions
hold:

1) There is an interposable symbol from a DSO (Undefined or SharedSymbol with default visibility)
2) If -shared or --export-dynamic is specified, any symbol in an object file/bitcode sets this property, unless suppressed by canBeOmittedFromSymbolTable().
3) --dynamic-list when producing an executable

4) protected symbol from a DSO preempted by copy relocation/canonical PLT when
  --ignore-{data,function}-address-equality is specified
5) ifunc is exported when -z ifunc-noplt is specified

Bullet points 4) and 5) are irrelevant in this patch.

Bullet 3) does not play well with 1) and 2). When -shared is specified,
exportDynamic of most symbols is true. This makes it incapable to record
--dynamic-list marked symbols. We thus have obscure:

    if (!config->shared)
      b->exportDynamic = true;
    else if (b->includeInDynsym())
      b->isPreemptible = true;

This patch adds another bit `Symbol::inDynamicList` to record
3). We can thus simplify handleDynamicList() by unifying the DSO and
  executable cases. It also allows us to simplify isPreemptible - now
the field is only used in finalizeSections() and later stages.

Reviewed By: peter.smith

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

llvm-svn: 368659
2019-08-13 09:12:52 +00:00
Fangrui Song ab04ad6af7 [ELF] Rename odd variable names "New" after r365730. NFC
New -> newSym or newFlags

Reviewed By: atanasyan

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

llvm-svn: 368651
2019-08-13 06:19:39 +00:00
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 47cfe8f321 [ELF] Fix variable names in comments after VariableName -> variableName change
Also fix some typos.

llvm-svn: 366181
2019-07-16 05:50:45 +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
Rui Ueyama 3837f4273f [Coding style change] Rename variables so that they start with a lowercase letter
This patch is mechanically generated by clang-llvm-rename tool that I wrote
using Clang Refactoring Engine just for creating this patch. You can see the
source code of the tool at https://reviews.llvm.org/D64123. There's no manual
post-processing; you can generate the same patch by re-running the tool against
lld's code base.

Here is the main discussion thread to change the LLVM coding style:
https://lists.llvm.org/pipermail/llvm-dev/2019-February/130083.html
In the discussion thread, I proposed we use lld as a testbed for variable
naming scheme change, and this patch does that.

I chose to rename variables so that they are in camelCase, just because that
is a minimal change to make variables to start with a lowercase letter.

Note to downstream patch maintainers: if you are maintaining a downstream lld
repo, just rebasing ahead of this commit would cause massive merge conflicts
because this patch essentially changes every line in the lld subdirectory. But
there's a remedy.

clang-llvm-rename tool is a batch tool, so you can rename variables in your
downstream repo with the tool. Given that, here is how to rebase your repo to
a commit after the mass renaming:

1. rebase to the commit just before the mass variable renaming,
2. apply the tool to your downstream repo to mass-rename variables locally, and
3. rebase again to the head.

Most changes made by the tool should be identical for a downstream repo and
for the head, so at the step 3, almost all changes should be merged and
disappear. I'd expect that there would be some lines that you need to merge by
hand, but that shouldn't be too many.

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

llvm-svn: 365595
2019-07-10 05:00:37 +00:00
Peter Collingbourne ba2816be82 ELF: Add basic partition data structures and behaviours.
This change causes us to read partition specifications from partition
specification sections and split output sections into partitions according
to their reachability from partition entry points.

This is only the first step towards a full implementation of partitions. Later
changes will add additional synthetic sections to each partition so that
they can be loaded independently.

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

llvm-svn: 361925
2019-05-29 03:55:20 +00:00
Rui Ueyama d8f8abbd4a Use SymbolTable::insert() to implement --trace.
Differential Revision: https://reviews.llvm.org/D62381

llvm-svn: 361791
2019-05-28 06:33:06 +00:00
Rui Ueyama 7f7d2b2e62 Move code for symbol resolution from SymbolTable.cpp to Symbols.cpp.
My recent commits separated symbol resolution from the symbol table,
so the functions to resolve symbols are now in a somewhat wrong file.
This patch moves it to Symbols.cpp.

The functions are now member functions of the symbol.

This is code move change. I modified function names so that they are
appropriate as member functions, though. No functionality change
intended.

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

llvm-svn: 361474
2019-05-23 09:58:08 +00:00
Rui Ueyama 4254840313 Speed up --start-lib and --end-lib.
--{start,end}-lib give files grouped by the options the archive file
semantics. That is, each object file between them acts as if it were
in an archive file whose sole member is the file.

Therefore, files between --{start,end}-lib are linked to the final
output only if they are needed to resolve some undefined symbols.

Previously, the feature was implemented this way:

 1. We read a symbol table and insert defined symbols to the symbol
    table as lazy symbols.

 2. If an undefind symbol is resolved to a lazy symbol, that lazy
    symbol instantiate ObjFile class for that symbol, which re-insert
    all defined symbols to the symbol table.

So, if an ObjFile is instantiated, defined symbols are inserted to the
symbol table twice. Since inserting long symbol names is not cheap,
there's a room to optimize here.

This patch optimzies it. Now, LazyObjFile remembers symbol handles and
passed them over to a new ObjFile instance, so that the ObjFile
doesn't insert the same strings.

Here is a quick benchmark to link clang. "Original" is the original
lld with unmodified command line options. For "Case 1" and "Case 2", I
extracted all files from archive files and replace .a's in a command
line with .o's wrapped with --{start,end}-lib. I used the original lld
for Case 1" and use this patch for Case 2.

  Original: 5.892
    Case 1: 6.001 (+1.8%)
    Case 2: 5.701 (-3.2%)

So, interestingly, --{start,end}-lib are now faster than the regular
linking scheme with archive files. That's perhaps not too surprising,
though, because for regular archive files, we look up the symbol table
with the same string twice.

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

llvm-svn: 361473
2019-05-23 09:53:30 +00:00
Rui Ueyama 0baaf45be7 Move SymbolTable::addCombinedLTOObject() to LinkerDriver.
Also renames it LinkerDriver::compileBitcodeFiles.

The function doesn't logically belong to SymbolTable. We added this
function to the symbol table because symbol table used to be a
container of input files. This is no longer the case.

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

llvm-svn: 361469
2019-05-23 09:26:27 +00:00
Fangrui Song b72b091389 [ELF] Improve error message for relocations to symbols defined in discarded sections
Rather than report "undefined symbol: ", give more informative message
about the object file that defines the discarded section.

In particular, PR41133, if the section is a discarded COMDAT, print the
section group signature and the object file with the prevailing
definition. This is useful to track down some ODR issues.

We need to
* add `uint32_t DiscardedSecIdx` to Undefined for this feature.
* make ComdatGroups public and change its type to DenseMap<CachedHashStringRef, const InputFile *>

Reviewed By: ruiu

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

llvm-svn: 361359
2019-05-22 09:06:42 +00:00
Rui Ueyama faf541e1e1 Make replaceSymbol a member function of Symbol.
This is a mechanical rewrite of replaceSymbol(A, B) to A->replace(B).
I also added a comment to Symbol::replace().

Technically this change is not necessary, but this change makes code a
bit more concise.

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

llvm-svn: 361123
2019-05-20 03:36:33 +00:00