755 Commits

Author SHA1 Message Date
Fangrui Song
8565a87fd4 [ELF] Simplify MergeInputSection::getParentOffset. NFC
and remove overly verbose comments.
2022-03-28 10:02:35 -07:00
Fangrui Song
72bedf46c7 [ELF] Inline InputSection::getParent. NFC
Combined with the previous change, lld executable is ~2K smaller and some code
paths using InputSection::getParent are more efficient.

The fragmented headers lead to a design limitation that OutputSection has to be
incomplete, so we cannot use static_cast.
2022-03-08 11:26:12 -08:00
Fangrui Song
a815424cc5 Reland D119909 [ELF] Parallelize initializeLocalSymbols
ObjFile::parse combines symbol initialization and resolution. Many tasks
unrelated to symbol resolution can be postponed and parallelized. This patch
extracts local symbol initialization and parallelizes it.

Technically the new function initializeLocalSymbols can be merged into
ObjFile::postParse, but functions like getSrcMsg may access the
uninitialized (all nullptr) local part of InputFile::symbols.

Linking chrome: 1.02x as fast with glibc malloc, 1.04x as fast with mimalloc

Depends on f456c3ae3f4182b23673929e8fe0aa18bcec4289 and D119908

Reviewed By: ikudrin

Differential Revision: https://reviews.llvm.org/D119909
2022-03-04 19:00:10 -08:00
Jorge Gorbe Moya
449b649fec Revert "[ELF] Parallelize initializeLocalSymbols"
This reverts commit 09602d3b47ec83abb2c26efa5a199c13b72c7abf.
2022-03-04 15:01:17 -08:00
Fangrui Song
bb3eeac773 [ELF] Make InputSection::classof inline. NFC 2022-02-28 00:16:45 -08:00
Fangrui Song
4976d1fe58 [ELF] Move SyntheticSection check from InputSection::writeTo to OutputSection::writeTo. NFC
Simplify code and make the heavyweight operation to the call site so that it is
clearer how to improve the inefficient scheduling in the future.
2022-02-27 23:28:52 -08:00
Fangrui Song
09602d3b47 [ELF] Parallelize initializeLocalSymbols
ObjFile::parse combines symbol initialization and resolution. Many tasks
unrelated to symbol resolution can be postponed and parallelized. This patch
extracts local symbol initialization and parallelizes it.

Technically the new function initializeLocalSymbols can be merged into
ObjFile::postParse, but functions like getSrcMsg may access the
uninitialized (all nullptr) local part of InputFile::symbols.

Linking chrome: 1.02x as fast with glibc malloc, 1.04x as fast with mimalloc

Reviewed By: ikudrin

Differential Revision: https://reviews.llvm.org/D119909
2022-02-24 20:05:59 -08:00
Fangrui Song
ae1ba6194f [ELF] Replace uncompressed InputSectionBase::data() with rawData. NFC
In many call sites we know uncompression cannot happen (non-SHF_ALLOC, or the
data (even if compressed) must have been uncompressed by a previous pass).
Prefer rawData in these cases. data() increases code size and prevents
optimization on rawData.
2022-02-21 00:39:26 -08:00
Fangrui Song
27bb799095 [ELF] Clean up headers. NFC 2022-02-07 21:53:34 -08:00
Alexander Shaposhnikov
4450a2a23d [lld][ELF] Add support for ADRP+ADD optimization for AArch64
This diff adds support for ADRP+ADD optimization for AArch64 described in
d2ca58c54b
i.e. under appropriate constraints

ADRP  x0, symbol
ADD   x0, x0, :lo12: symbol

can be turned into

NOP
ADR   x0, symbol

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D117614
2022-02-02 06:09:55 +00:00
Fangrui Song
17a39aecd1 [ELF] Simplify code with invokeELFT. NFC 2022-02-01 09:53:29 -08:00
Fangrui Song
d97749fabc [ELF] Switch split-stack to use SmallVector. NFC
My x86-64 lld executable is 1.1KiB smaller.
2022-02-01 00:09:30 -08:00
Fangrui Song
457273fda5 [ELF] splitStrings: replace entSize==1 special case with manual loop unswitch. NFC
My x86-64 lld executable is actually smaller.
2022-01-30 17:15:45 -08:00
Fangrui Song
5a2020d069 [ELF] copyShtGroup: replace unordered_set<uint32_t> with DenseSet<uint32_t>. NFC
We don't need to support the empty/tombstone key section index.
2022-01-30 01:18:41 -08:00
Fangrui Song
bc1369fae3 [ELF] Optimize MergeInputSection::splitNonStrings with resize_for_overwrite. NFC 2022-01-30 00:10:52 -08:00
Fangrui Song
14b7785c09 [ELF] Simplify InputSection::writeTo. NFC 2022-01-26 22:03:26 -08:00
Alexandre Ganea
83d59e05b2 Re-land [LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.

See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html

The previous land f860fe362282ed69b9d4503a20e5d20b9a041189 caused issues in https://lab.llvm.org/buildbot/#/builders/123/builds/8383, fixed by 22ee510dac9440a74b2e5b3fe3ff13ccdbf55af3.

Differential Revision: https://reviews.llvm.org/D108850
2022-01-20 14:53:26 -05:00
Fangrui Song
a7a4115bf3 [ELF] Replace .zdebug string comparison with SHF_COMPRESSED check. NFC 2022-01-19 22:33:32 -08:00
Fangrui Song
5bd38a2826 [ELF] Fix split-stack caller with hidden non-split-stack callee
Fix a regression after aabe901d57d6df4cd2786163359a7b2a7aae8c32 (`[ELF] Remove
one redundant computeBinding`): isLocal() does not indicate that the symbol is
originally local. For simplicity, just drop this optimization.
2022-01-19 12:25:01 -08:00
Fangrui Song
5f404a749a [ELF] De-template InputSectionBase::getLocation. NFC 2022-01-18 17:33:58 -08:00
Fangrui Song
eafd34581f [ELF] Simplify/optimize EhInputSection::split
and change some `fatal` to `errorOrWarn`.

EhFrame.cpp is a helper file. We don't place all .eh_frame implementation there,
so the code move is fine.
2022-01-18 17:03:23 -08:00
Fangrui Song
83c7f5d3fb [ELF] EhInputSection::split: remove unneeded check 2022-01-17 13:59:52 -08:00
Alexandre Ganea
e6b153947d Revert [LLD] Remove global state in lldCommon
It seems to be causing issues on https://lab.llvm.org/buildbot/#/builders/123/builds/8383
2022-01-16 11:03:06 -05:00
Alexandre Ganea
f860fe3622 [LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.

See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html

Differential Revision: https://reviews.llvm.org/D108850
2022-01-16 08:57:57 -05:00
Fangrui Song
8b2f33231c [ELF] Make some diagnostics follow the convention 2022-01-15 10:46:25 -08:00
Igor Kudrin
e00ac48df3 [ELF] Use tombstone values for discarded symbols in relocatable output
This extends D81784. Sections can be discarded when linking a
relocatable output. Before the patch, LLD did not update the content
of debug sections and only replaced the corresponding relocations with
R_*_NONE, which could break the debug information.

Differential Revision: https://reviews.llvm.org/D116946
2022-01-13 11:38:26 +07:00
Fangrui Song
7f1955dc96 [ELF] Support mixed TLSDESC and TLS GD
We only support both TLSDESC and TLS GD for x86 so this is an x86-specific
problem. If both are used, only one R_X86_64_TLSDESC is produced and TLS GD
accesses will incorrectly reference R_X86_64_TLSDESC. Fix this by introducing
SymbolAux::tlsDescIdx.

Reviewed By: ikudrin

Differential Revision: https://reviews.llvm.org/D116900
2022-01-10 10:03:21 -08:00
Alexander Shaposhnikov
8acc3b4ab0 [lld][ELF] Support adrp+ldr GOT optimization for AArch64
This diff adds first bits to support relocation relaxations for AArch64
discussed on https://github.com/ARM-software/abi-aa/pull/106.
In particular, the case of

adrp x0, :got: symbol
ldr x0, [x0, :got_lo12: symbol]

is handled.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D112063
2022-01-10 05:20:37 +00:00
Fangrui Song
e90c8c0422 [ELF] Optimize basic block section bytesDropped/jumpInstrMods
and make them more space efficient. This decreases sizeof(InputSection) from 176
to 160, and decreases peak memory usage by 0.3% when linking Chrome.
2021-12-26 22:17:30 -08:00
Fangrui Song
469144ffa3 [ELF] De-template InputSectionBase::getEnclosingFunction 2021-12-26 15:21:22 -08:00
Fangrui Song
213896bc5a [ELF] Remove unused InputSection::getOffsetInFile 2021-12-26 15:18:56 -08:00
Fangrui Song
bf7f3dd74e [ELF] Move outSecOff addition from InputSection::writeTo to the caller
Simplify the code a bit and improve consistency with SyntheticSection::writeTo.
2021-12-26 12:11:41 -08:00
Fangrui Song
745420d3f4 [ELF] Cache global variable target in relocate*
This avoid repeated load of the unique_ptr in hot paths.
2021-12-24 17:54:12 -08:00
Fangrui Song
b5a0f0f397 [ELF] Add ELFFileBase::{elfShdrs,numELFShdrs} to avoid duplicate llvm::object::ELFFile::sections()
This mainly avoid `relsOrRelas` cost in `InputSectionBase::relocate`.
`llvm::object::ELFFile::sections()` has redundant and expensive checks.
2021-12-24 17:10:38 -08:00
Fangrui Song
e1b6b5be46 [ELF] Avoid referencing SectionBase::repl after ICF
It is fairly easy to forget SectionBase::repl after ICF.
Let ICF rewrite a Defined symbol's `section` field to avoid references to
SectionBase::repl in subsequent passes. This slightly improves the --icf=none
performance due to less indirection (maybe for --icf={safe,all} as well if most
symbols are Defined).

With this change, there is only one reference to `repl` (--gdb-index D89751).
We can undo f4fb5fd7523f8e3c3b3966d43c0a28457b59d1d8 (`Move Repl to SectionBase.`)
but move `repl` to `InputSection` instead.

Reviewed By: ikudrin

Differential Revision: https://reviews.llvm.org/D116093
2021-12-24 12:09:48 -08:00
Fangrui Song
bf45624ba0 [ELF][PPC32] Support .got2 in an output section description
I added `PPC32Got2Section` D62464 to support .got2 but did not implement .got2
in another output section.

PR52799 has a linker script placing .got2 in .rodata, which causes a null
pointer dereference because a MergeSyntheticSection's file is nullptr.
Add the support.
2021-12-23 11:32:44 -08:00
Fangrui Song
ba948c5a9c [ELF] Use SmallVector for some global variables (*Files and *Sections). NFC
My lld executable is 26+KiB smaller.
2021-12-22 22:30:08 -08:00
Fangrui Song
aa27bab5a1 [ELF] InputSection::writeTo: reorder type checks and add LLVM_UNLIKELY 2021-12-16 23:42:50 -08:00
Fangrui Song
054cdb34a2 [ELF] Optimize MergeInputSection::splitNonStrings. NFC 2021-12-16 21:23:00 -08:00
Fangrui Song
4c98d08841 [ELF] Speed up MergeInputSection::split*. NFC 2021-12-16 21:17:02 -08:00
Fangrui Song
1ff1d50d9f [ELF] Make InputFile smaller
sizeof(ObjFile<ELF64LE>) is decreased from 344 to 272 on an ELF64 system.
In a large link with 30000 ObjFiles, this may be 2+MiB saving.

Change std::vector members to SmallVector, and std::string members to
SmallString<0> (these members typically don't benefit from small string optimization).
On Linux x86-64 the lld executable is ~6k smaller.
2021-12-14 20:55:32 -08:00
Fangrui Song
d29766bb48 [ELF] relocateAlloc: remove variables type and expr. NFC 2021-12-12 19:31:30 -08:00
Fangrui Song
4cfff19b88 [ELF] Move adjustSplitStackFunctionPrologues's splitStack check to the caller. NFC
Avoid a function call in the majority of cases and make the output smaller.
2021-12-12 19:26:03 -08:00
Fangrui Song
85e50c1080 [ELF] Inline InputSection::getOffset into callers and remove it. NFC
This is an unneeded abstraction which may cause confusion:
SectionBase::getOffset has the same name but hard codes -1 as the size of OutputSection.
2021-11-28 16:09:04 -08:00
Petr Hosek
d56b171ee9 [lld][ELF] Support for R_ARM_THM_JUMP8
This change implements support for R_ARM_THM_JUMP8 relocation in
addition to R_ARM_THM_JUMP11 which is already supported by LLD.

Differential Revision: https://reviews.llvm.org/D21225
2021-11-11 09:06:52 -08:00
Fangrui Song
6fcc19afb9 [ELF] Simplify R_TPREL formula after D111365 2021-10-28 21:03:53 -07:00
Fangrui Song
e39c138f45 [ELF] Implement TLSDESC for x86-32
`-z rela` is also supported.

Tested with:

```
cat > ./a.c <<eof
#include <assert.h>
int foo();
int bar();
int main() {
  assert(foo() == 2);
  assert(foo() == 4);
  assert(bar() == 2);
  assert(bar() == 4);
}
eof

cat > ./b.c <<eof
#include <stdio.h>
__thread int tls0;
extern __thread int tls1;
int foo() { return ++tls0 + ++tls1; }
static __thread int tls2, tls3;
int bar() { return ++tls2 + ++tls3; }
eof

echo '__thread int tls1;' > ./c.c

sed 's/        /\t/' > ./Makefile <<'eof'
.MAKE.MODE = meta curDirOk=true

CC := gcc -m32 -g -fpic -mtls-dialect=gnu2
LDFLAGS := -m32 -Wl,-rpath=.

all: a0 a1 a2

run: all
        ./a0 && ./a1 && ./a2

c.so: c.o; ${LINK.c} -shared $> -o $@
bc.so: b.o c.o; ${LINK.c} -shared $> -o $@
b.so: b.o c.so; ${LINK.c} -shared $> -o $@

a0: a.o b.o c.o; ${LINK.c} $> -o $@
a1: a.o b.so; ${LINK.c} $> -o $@
a2: a.o bc.so; ${LINK.c} $> -o $@
eof
```
and glibc `elf/tst-gnu2-tls1`.

`/usr/local/bin/ld` points to the freshly built `lld`.

`bmake run && bmake CFLAGS=-O1 run` => ok.

Differential Revision: https://reviews.llvm.org/D112582
2021-10-28 17:52:03 -07:00
Fangrui Song
2b1e32410c [ELF] Change common diagnostics to report both object file location and source file location
Many diagnostics use `getErrorPlace` or `getErrorLocation` to report a location.
In the presence of line table debug information, `getErrorPlace` uses a source
file location and ignores the object file location. However, the object file
location is sometimes more useful.

This patch changes "undefined symbol" and "out of range" diagnostics to report
both object/source file locations. Other diagnostics can use similar format if
needed.

The key idea is to let `InputSectionBase::getLocation` report the object file
location and use `getSrcMsg` for source file/line information. `getSrcMsg`
doesn't leverage `STT_FILE` information yet, but I think the temporary lack of
the functionality is ok.

For the ARM "branch and link relocation" diagnostic, I arbitrarily place the
source file location at the end of the line. The diagnostic is not very common
so its formatting doesn't need to be pretty.

Differential Revision: https://reviews.llvm.org/D112518
2021-10-28 09:38:45 -07:00
Fangrui Song
ecc93ed2d7 [ELF] Replace InputBaseSection::{areRelocsRela,firstRelocation,numRelocation} with relSecIdx
For `InputSection` `.foo`, its `InputBaseSection::{areRelocsRela,firstRelocation,numRelocation}` basically
encode the information of `.rel[a].foo`. However, one uint32_t (the relocation section index)
suffices. See the implementation of `relsOrRelas`.

This change decreases sizeof(InputSection) from 184 to 176 on 64-bit Linux.

The maximum resident set size linking a large application (1.2G output) decreases by 0.39%.

Differential Revision: https://reviews.llvm.org/D112513
2021-10-27 09:51:07 -07:00
Fangrui Song
43753f8f9d [ELF] Remove irrelevant SHT_INIT_ARRAY/SHT_FINI_ARRAY hack
The hack is irrelevant for two reasons:

* binutils 2.24 is quite old and cannot handle R_X86_64_REX_GOTPCRELX from 2016 onwards anyway
* `canMergeToProgbits` allows combining SHT_INIT_ARRAY/SHT_FINI_ARRAY into SHT_PROGBITS
2021-10-25 14:23:05 -07:00