Commit Graph

367 Commits

Author SHA1 Message Date
Fangrui Song 0526c0cd8e [ELF] Implement Local Dynamic style TLSDESC for x86-64
For the Local Dynamic case of TLSDESC, _TLS_MODULE_BASE_ is defined as a
special TLS symbol that makes:

1) Without relaxation: it produces a dynamic TLSDESC relocation that
computes 0. Adding @dtpoff to access a TLS symbol.
2) With LD->LE relaxation: _TLS_MODULE_BASE_@tpoff = 0 (lowest address in
the TLS block). Adding @tpoff to access a TLS symbol.

For 1), this saves dynamic relocations and GOT slots as otherwise
(General Dynamic) we would create an R_X86_64_TLSDESC and reserve two
GOT slots for each symbol.

Add ElfSym::TlsModuleBase and change the signature of getTlsTpOffset()
to special case _TLS_MODULE_BASE_.

Reviewed By: ruiu

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

llvm-svn: 362078
2019-05-30 10:00:20 +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
Sam Clegg 7991b68284 [lld] Trace all references with lld --trace-symbol
Previously undefined symbol references were only traced if they were
seen before that definition.

Fixes https://bugs.llvm.org/show_bug.cgi?id=41878

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

llvm-svn: 361636
2019-05-24 13:29:17 +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 ecf6eb515f Copy symbol length when we replace a symbol.
Symbol's NameSize is computed lazily. Currently, when we replace a symbol,
a cached length value can be discarded. This patch propagates that value.

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

llvm-svn: 361364
2019-05-22 09:19:30 +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
Fangrui Song a6720e7407 [ELF] Copy IsPreemptible in replaceSymbol()
Otherwise, we may set IsPreemptible (e.g. --dynamic-list) then clear it
(in replaceCommonSymbols()).

Reviewed By: ruiu

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

llvm-svn: 361122
2019-05-20 02:07:03 +00:00
Michael Liao 63621832da Suppress false-positive GCC -Wreturn-type warning.
llvm-svn: 361094
2019-05-18 06:35:47 +00:00
Rui Ueyama bbf154cf9c Move symbol resolution code out of SymbolTable class.
This is the last patch of the series of patches to make it possible to
resolve symbols without asking SymbolTable to do so.

The main point of this patch is the introduction of
`elf::resolveSymbol(Symbol *Old, Symbol *New)`. That function resolves
or merges given symbols by examining symbol types and call
replaceSymbol (which memcpy's New to Old) if necessary.

With the new function, we have now separated symbol resolution from
symbol lookup. If you already have a Symbol pointer, you can directly
resolve the symbol without asking SymbolTable to do that.

Now that the nice abstraction become available, I can start working on
performance improvement of the linker. As a starter, I'm thinking of
making --{start,end}-lib faster.

--{start,end}-lib is currently unnecessarily slow because it looks up
the symbol table twice for each symbol.

 - The first hash table lookup/insertion occurs when we instantiate a
   LazyObject file to insert LazyObject symbols.

 - The second hash table lookup/insertion occurs when we create an
   ObjFile from LazyObject file. That overwrites LazyObject symbols
   with Defined symbols.

I think it is not too hard to see how we can now eliminate the second
hash table lookup. We can keep LazyObject symbols in Step 1, and then
call elf::resolveSymbol() to do Step 2.

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

llvm-svn: 360975
2019-05-17 01:55:20 +00:00
Rui Ueyama 5c073a94f9 Introduce CommonSymbol.
Previously, we handled common symbols as a kind of Defined symbol,
but what we were doing for common symbols is pretty different from
regular defined symbols.

Common symbol and defined symbol are probably as different as shared
symbol and defined symbols are different.

This patch introduces CommonSymbol to represent common symbols.
After symbols are resolved, they are converted to Defined symbols
residing in a .bss section.

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

llvm-svn: 360841
2019-05-16 03:29:03 +00:00
Rui Ueyama 7d4761928e Simplify SymbolTable::add{Defined,Undefined,...} functions.
SymbolTable's add-family functions have lots of parameters because
when they have to create a new symbol, they forward given arguments
to Symbol's constructors. Therefore, the functions take at least as
many arguments as their corresponding constructors.

This patch simplifies the add-family functions. Now, the functions
take a symbol instead of arguments to construct a symbol. If there's
no existing symbol, a given symbol is memcpy'ed to the symbol table.
Otherwise, the functions attempt to merge the existing and a given
new symbol.

I also eliminated `CanOmitFromDynSym` parameter, so that the functions
take really one argument.

Symbol classes are trivially constructible, so looks like constructing
them to pass to add-family functions is as cheap as passing a lot of
arguments to the functions. A quick benchmark showed that this patch
seems performance-neutral.

This is a preparation for
http://lists.llvm.org/pipermail/llvm-dev/2019-April/131902.html

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

llvm-svn: 360838
2019-05-16 02:14:00 +00:00
Peter Collingbourne cc1618e668 ELF: De-template SharedFile. NFCI.
Differential Revision: https://reviews.llvm.org/D60305

llvm-svn: 357925
2019-04-08 17:35:55 +00:00
Fangrui Song f9695e166b [ELF] Delete unused forward declarations and unused DynamicReloc::getInputSec(). NFC
llvm-svn: 356239
2019-03-15 07:16:39 +00:00
Sam Clegg d15a4154a8 [WebAssembly] Don't mark lazy symbols as `IsUsedInRegularObj`
This matches the ELF does.  Update the comment in ELF/Symbols.h and
duplicate it in wasm/Symbols.h

This a followup on rL355580 and rL355577.

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

llvm-svn: 355737
2019-03-08 21:10:48 +00:00
Peter Collingbourne 8331f61a51 ELF: Allow GOT relocs pointing to non-preemptable ifunc to resolve to an IRELATIVE where possible.
Non-GOT non-PLT relocations to non-preemptible ifuncs result in the
creation of a canonical PLT, which now takes the identity of the IFUNC
in the symbol table. This (a) ensures address consistency inside and
outside the module, and (b) fixes a bug where some of these relocations
end up pointing to the resolver.

Fixes (at least) PR40474 and PR40501.

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

llvm-svn: 353981
2019-02-13 21:49:55 +00:00
Chandler Carruth 2946cd7010 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00
Rui Ueyama 6f9d49cdde Do not emit a corrupt symbol table entry for .rela_iplt_{start,end}.
If .rela.iplt does not exist, we used to emit a corrupt symbol table
that contains two symbols, .rela_iplt_{start,end}, pointing to a
nonexisting section.

This patch fixes the issue by setting section index 0 to the symbols
if .rel.iplt section does not exist.

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

llvm-svn: 351218
2019-01-15 18:30:23 +00:00
Rui Ueyama 63d397ea6e Simplify Symbol::getPltVA.
This patch also makes getPltEntryOffset a non-member function because
it doesn't depend on any private members of the TargetInfo class.

I tried a few different ideas, and it seems this change fits in best to me.

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

llvm-svn: 347781
2018-11-28 17:42:59 +00:00
Sean Fertile 614dc11ca8 [PPC64] Long branch thunks.
On PowerPC64, when a function call offset is too large to encode in a call
instruction the address is stored in a table in the data segment. A thunk is
used to load the branch target address from the table relative to the
TOC-pointer and indirectly branch to the callee. When linking position-dependent
code the addresses are stored directly in the table, for position-independent
code the table is allocated and filled in at load time by the dynamic linker.

For position-independent code the branch targets could have gone in the .got.plt
but using the .branch_lt section for both position dependent and position
independent binaries keeps it consitent and helps keep this PPC64 specific logic
seperated from the target-independent code handling the .got.plt.

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

llvm-svn: 346877
2018-11-14 17:56:43 +00:00
Rui Ueyama 4c06a6cc90 Rename warnUnorderableSymbol maybeWarnUnorderableSymbol because the function doesn't always emit a warning.
llvm-svn: 345393
2018-10-26 15:07:12 +00:00
Rui Ueyama 660e8721a9 Remove a global variable that is set but not used.
llvm-svn: 345080
2018-10-23 21:00:28 +00:00
Rui Ueyama f3fad55787 Remove `Type` parameter from SymbolTable::insert(). NFC.
`Type` parameter was used only to check for TLS attribute mismatch,
but we can do that when we actually replace symbols, so we don't need
to type as an argument. This change should simplify the interface of
the symbol table a bit.

llvm-svn: 344394
2018-10-12 18:29:18 +00:00
Rui Ueyama 714abece2b Simplify. NFC.
llvm-svn: 344074
2018-10-09 20:16:16 +00:00
Chih-Hung Hsieh 73e04847bf [ELF] Revert "Also demote lazy symbols."
This reverts commit https://reviews.llvm.org/rL330869
for a regression to link Android dex2oatds.

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

llvm-svn: 342007
2018-09-11 23:00:36 +00:00
Peter Collingbourne 6556e6b929 ELF: Don't examine values of linker script symbols during ICF.
These symbols are declared early with the same value, so they otherwise
appear identical to ICF.

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

llvm-svn: 340998
2018-08-29 23:43:38 +00:00
Rui Ueyama 07b4536bb7 Change how we handle -wrap.
We have an issue with -wrap that the option doesn't work well when
renamed symbols get PLT entries. I'll explain what is the issue and
how this patch solves it.

For one -wrap option, we have three symbols: foo, wrap_foo and real_foo.
Currently, we use memcpy to overwrite wrapped symbols so that they get
the same contents. This works in most cases but doesn't when the relocation
processor sets some flags in the symbol. memcpy'ed symbols are just
aliases, so they always have to have the same contents, but the
relocation processor breaks that assumption.

r336609 is an attempt to fix the issue by memcpy'ing again after
processing relocations, so that symbols that are out of sync get the
same contents again. That works in most cases as well, but it breaks
ASan build in a mysterious way.

We could probably fix the issue by choosing symbol attributes that need
to be copied after they are updated. But it feels too complicated to me.

So, in this patch, I fixed it once and for all. With this patch, we no
longer memcpy symbols. All references to renamed symbols point to new
symbols after wrapSymbols() is done.

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

llvm-svn: 340387
2018-08-22 07:02:26 +00:00
Rui Ueyama 5cd9c6bcd8 Support RISC-V
Patch by PkmX.

This patch makes lld recognize RISC-V target and implements basic
relocation for RV32/RV64 (and RVC). This should be necessary for static
linking ELF applications.

The ABI documentation for RISC-V can be found at:
https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md.
Note that the documentation is far from complete so we had to figure out
some details from bfd.

The patch should be pretty straightforward. Some highlights:

 - A new relocation Expr R_RISCV_PC_INDIRECT is added. This is needed as
   the low part of a PC-relative relocation is linked to the corresponding
   high part (auipc), see:
   https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#pc-relative-symbol-addresses

 - LLVM's MC support for RISC-V is very incomplete (we are working on
   this), so tests are given in objectyaml format with the original
   assembly included in the comments. Once we have complete support for
   RISC-V in MC, we can switch to llvm-as/llvm-objdump.

 - We don't support linker relaxation for now as it requires greater
   changes to lld that is beyond the scope of this patch. Once this is
   accepted we can start to work on adding relaxation to lld.

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

llvm-svn: 339364
2018-08-09 17:59:56 +00:00
Peter Collingbourne 98930115ea ELF: Only add libcall symbols to the link if defined in bitcode.
Adding all libcall symbols to the link can have undesired consequences.
For example, the libgcc implementation of __sync_val_compare_and_swap_8
on 32-bit ARM pulls in an .init_array entry that aborts the program if
the Linux kernel does not support 64-bit atomics, which would prevent
the program from running even if it does not use 64-bit atomics.

This change makes it so that we only add libcall symbols to the
link before LTO if we have to, i.e. if the symbol's definition is in
bitcode. Any other required libcall symbols will be added to the link
after LTO when we add the LTO object file to the link.

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

llvm-svn: 339301
2018-08-08 23:48:12 +00:00
Simon Atanasyan ed9ee69ccf [ELF][MIPS] Multi-GOT implementation
Almost all entries inside MIPS GOT are referenced by signed 16-bit
index. Zero entry lies approximately in the middle of the GOT. So the
total number of GOT entries cannot exceed ~16384 for 32-bit architecture
and ~8192 for 64-bit architecture. This limitation makes impossible to
link rather large application like for example LLVM+Clang. There are two
workaround for this problem. The first one is using the -mxgot
compiler's flag. It enables using a 32-bit index to access GOT entries.
But each access requires two assembly instructions two load GOT entry
index to a register. Another workaround is multi-GOT. This patch
implements it.

Here is a brief description of multi-GOT for detailed one see the
following link https://dmz-portal.mips.com/wiki/MIPS_Multi_GOT.

If the sum of local, global and tls entries is less than 64K only single
got is enough. Otherwise, multi-got is created. Series of primary and
multiple secondary GOTs have the following layout:
```
- Primary GOT
    Header
    Local entries
    Global entries
    Relocation only entries
    TLS entries

- Secondary GOT
    Local entries
    Global entries
    TLS entries
...
```

All GOT entries required by relocations from a single input file
entirely belong to either primary or one of secondary GOTs. To reference
GOT entries each GOT has its own _gp value points to the "middle" of the
GOT. In the code this value loaded to the register which is used for GOT
access.

MIPS 32 function's prologue:
```
lui     v0,0x0
0: R_MIPS_HI16  _gp_disp
addiu   v0,v0,0
4: R_MIPS_LO16  _gp_disp
```

MIPS 64 function's prologue:
```
lui     at,0x0
14: R_MIPS_GPREL16  main
```

Dynamic linker does not know anything about secondary GOTs and cannot
use a regular MIPS mechanism for GOT entries initialization. So we have
to use an approach accepted by other architectures and create dynamic
relocations R_MIPS_REL32 to initialize global entries (and local in case
of PIC code) in secondary GOTs. But ironically MIPS dynamic linker
requires GOT entries and correspondingly ordered dynamic symbol table
entries to deal with dynamic relocations. To handle this problem
relocation-only section in the primary GOT contains entries for all
symbols referenced in global parts of secondary GOTs. Although the sum
of local and normal global entries of the primary got should be less
than 64K, the size of the primary got (including relocation-only entries
can be greater than 64K, because parts of the primary got that overflow
the 64K limit are used only by the dynamic linker at dynamic link-time
and not by 16-bit gp-relative addressing at run-time.

The patch affects common LLD code in the following places:

- Added new hidden -mips-got-size flag. This flag required to set low
maximum size of a single GOT to be able to test the implementation using
small test cases.

- Added InputFile argument to the getRelocTargetVA function. The same
symbol referenced by GOT relocation from different input file might be
allocated in different GOT. So result of relocation depends on the file.

- Added new ctor to the DynamicReloc class. This constructor records
settings of dynamic relocation which used to adjust address of 64kb page
lies inside a specific output section.

With the patch LLD is able to link all LLVM+Clang+LLD applications and
libraries for MIPS 32/64 targets.

Differential revision: https://reviews.llvm.org/D31528

llvm-svn: 334390
2018-06-11 07:24:31 +00:00
Sean Fertile d2e887d2f6 [PPC64] Emit plt call stubs to the text section rather then the plt section.
On PowerPC calls to functions through the plt must be done through a call stub
that is responsible for:
1) Saving the toc pointer to the stack.
2) Loading the target functions address from the plt into both r12 and the
   count register.
3) Indirectly branching to the target function.

Previously we have been emitting these call stubs to the .plt section, however
the .plt section should be reserved for the lazy symbol resolution stubs. This
patch moves the call stubs to the text section by moving the implementation from
writePlt to the thunk framework.

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

llvm-svn: 331607
2018-05-06 19:13:29 +00:00
Rafael Espindola ab0cce5f1f Replace SharedSymbols with Defined when creating copy relocations.
This is slightly simpler to read IMHO. Now if a symbol has a position
in the file, it is Defined.

The main motivation is that with this a SharedSymbol doesn't need a
section, which reduces the size of SymbolUnion.

With this the peak allocation when linking chromium goes from 568.1 to
564.2 MB.

llvm-svn: 330966
2018-04-26 17:58:58 +00:00
Rafael Espindola f4a9d56a9a Delete GotPltIndex.
It was always an offset of PltIndex.

This doesn't reduce the size of the structures, but makes it easier to
do so in a followup patch.

llvm-svn: 330953
2018-04-26 16:09:30 +00:00
Rui Ueyama 5fcebff485 Remove unused features from StringRefZ and move it to Symbols.h.
Differential Revision: https://reviews.llvm.org/D46087

llvm-svn: 330879
2018-04-25 22:34:21 +00:00
Rafael Espindola 1eeb26293d Pack symbols a bit more.
Before this patch:

Symbol 56
Defined 80
Undefined 56
SharedSymbol 88
LazyArchive 72
LazyObject 56

With this patch

Symbol 48
Defined 72
Undefined 48
SharedSymbol 80
LazyArchive 64
LazyObject 48

The result is that peak allocation when linking chromium (according to
heaptrack) goes from 578 to 568 MB.

llvm-svn: 330874
2018-04-25 21:44:37 +00:00
Rafael Espindola 047f857642 Also demote lazy symbols.
This is not a big simplification right now, but the special cases for
lazy symbols have been a common source of bugs in the past.

llvm-svn: 330869
2018-04-25 20:46:08 +00:00
George Rimar 19f9b814dd [ELF] - Refactor lazy symbol duplicated code.
Our code for LazyObject and LazyArchive duplicates.

This patch extracts the common part to remove
the duplication.

Differential revision: https://reviews.llvm.org/D45516

llvm-svn: 330701
2018-04-24 09:41:56 +00:00
Rafael Espindola aded409325 Simplify getOffset for synthetic sections.
We had a single symbol using -1 with a synthetic section. It is
simpler to just update its value.

This is not a big will by itself, but will allow having a simple
getOffset for InputSeciton.

llvm-svn: 330340
2018-04-19 16:54:30 +00:00
Michael J. Spencer b842725c1d [ELF] Add profile guided section layout
This adds profile guided layout using the Call-Chain Clustering (C³) heuristic
from https://research.fb.com/wp-content/uploads/2017/01/cgo2017-hfsort-final1.pdf .

RFC: [llvm-dev] [RFC] Profile guided section layout
     http://lists.llvm.org/pipermail/llvm-dev/2017-June/114178.html

Pass `--call-graph-ordering-file <file>` to read a call graph profile where each
line has the format:

    <from symbol> <to symbol> <call count>

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

llvm-svn: 330234
2018-04-17 23:30:05 +00:00
Sam Clegg d11b6edfc8 Remove references to old SymbolBody class
Differential Revision: https://reviews.llvm.org/D45400

llvm-svn: 329846
2018-04-11 19:52:53 +00:00
George Rimar 1ef746ba21 [ELF] - Eliminate Lazy class.
Patch removes Lazy class which
is just an excessive layer.

Differential revision: https://reviews.llvm.org/D45083

llvm-svn: 329086
2018-04-03 17:16:52 +00:00
George Rimar 624e163f53 [ELF] - Remove dead declaration. NFC.
llvm-svn: 329058
2018-04-03 10:40:39 +00:00
Rui Ueyama 7d6131a898 Inline two trivial functions that are called only once. NFC.
llvm-svn: 329034
2018-04-02 23:58:50 +00:00
Rafael Espindola e3a6062844 Simplify. NFC.
Since r321982 we don't set VersionId in scanShlibUndefined, which
makes InVersionScript redundant.

llvm-svn: 326641
2018-03-03 02:13:50 +00:00
Rui Ueyama ee17371897 Merge {COFF,ELF}/Strings.cpp to Common/Strings.cpp.
This should resolve the issue that lld build fails in some hosts
that uses case-insensitive file system.

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

llvm-svn: 326339
2018-02-28 17:38:19 +00:00
Fangrui Song ffac3ed341 [ELF] Fix IsPreemptible comment and typo. NFC
llvm-svn: 325963
2018-02-23 21:57:49 +00:00
Fangrui Song 9cd5df0e15 [ELF] Add comment for preemptible and fix typo. NFC
Subscribers: emaste, arichardson, llvm-commits

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

llvm-svn: 325855
2018-02-23 02:05:48 +00:00
Sam Clegg 3141ddc58d Consistent (non) use of empty lines in include blocks
The profailing style in lld seem to be to not include such empty lines.
Clang-tidy/clang-format seem to handle this just fine.

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

llvm-svn: 325629
2018-02-20 21:53:18 +00:00
Rui Ueyama 38781a59f6 Revert r325158: Convert an assert to a static_assert. NFC.
This reverts commit r325158 because it broke GCC builds.

llvm-svn: 325183
2018-02-14 22:43:43 +00:00
Sam Clegg ab31b7759d Convert an assert to a static_assert. NFC.
Differential Revision: https://reviews.llvm.org/D43305

llvm-svn: 325158
2018-02-14 19:28:46 +00:00