Commit Graph

718 Commits

Author SHA1 Message Date
Fangrui Song e3fcf2e06f [ELF] Simplify llvm::enumerate with structured binding. NFC 2022-08-09 21:52:08 -07:00
Alex Brachet dbd04b853b [ELF] Support --package-metadata
This was recently introduced in GNU linkers and it makes sense for
ld.lld to have the same support. This implementation omits checking if
the input string is valid json to reduce size bloat.

Differential Revision: https://reviews.llvm.org/D131439
2022-08-08 21:31:58 +00:00
Fangrui Song ec04e45c03 [lld] LLVM_FALLTHROUGH => [[fallthrough]]. NFC
With C++17 there is no Clang pedantic warning or MSVC C5051.
2022-08-07 00:02:35 +00:00
Fangrui Song 28d05d6723 [ELF][PPC64] Fix potentially corrupted section content with empty .got
D91426 makes .got possibly empty while needed. If .got and .data have the same
address, and .got's content is written after .data, the first word of .data will
be corrupted.

The bug is not testable without D131247.
2022-08-05 15:22:57 -07:00
Fangrui Song b2559f2f5c [ELF] .eh_frame: remove config->wordsize padding
Linux Standard Base Core Specification says that CIE/FDE is padded to an
addressing unit size boundary, but in practice GNU assembler/LLVM integrated
assembler pad FDE/CIE to 4 and the last FDE to 8 on 64-bit systems.

In addition, GNU ld doesn't pad to 8, so let's drop excess padding, too.
If the assembler provides aligned pieces, the output will be aligned.

Noticed .eh_frame size reduction for 3 executables: 0.3% (chrome), 4.7% (clang),
7.6% (an internal program).
2022-07-31 23:35:44 -07:00
Fangrui Song 81ed005c4c [ELF] Remove EhFrameSection::addSection. NFC 2022-07-31 19:55:05 -07:00
Fangrui Song 3e9adff456 [ELF] Split EhInputSection::pieces into cies and fdes
This simplifies code, removes a read32 (for id==0 check), and makes it feasible
to combine some operations in EhInputSection::split and EhFrameSection::addRecords.

Mostly NFC, but fixes "Relocation not in any piece" assertion failure in an
erroneous case when a relocation offset precedes all CIE/FDE pices.
2022-07-31 16:16:10 -07:00
Fangrui Song c09d323599 [ELF] Move EhInputSection out of inputSections. NFC
inputSections temporarily contains EhInputSection objects mainly for
combineEhSections. Place EhInputSection objects into a new vector
ehInputSections instead of inputSections.
2022-07-31 11:58:08 -07:00
Fangrui Song 2e2d5304f0 [ELF] Move combineEhSections from Writer to SyntheticSections. NFC
This not only places the function in the right place, but also allows inlining addSection.
2022-07-29 00:47:30 -07:00
Fangrui Song 85cfd91723 [ELF] Optimize some non-constant alignTo with alignToPowerOf2. NFC
My x86-64 lld executable is 2KiB smaller. .eh_frame writing gets faster as there
were lots of divisions.
2022-07-24 11:20:49 -07:00
Kazu Hirata 1cc7f5bede Use static_assert instead of assert (NFC)
Identified with misc-static-assert.
2022-07-23 09:22:27 -07:00
Dmitri Gribenko aba43035bd Use llvm::sort instead of std::sort where possible
llvm::sort is beneficial even when we use the iterator-based overload,
since it can optionally shuffle the elements (to detect
non-determinism). However llvm::sort is not usable everywhere, for
example, in compiler-rt.

Reviewed By: nhaehnle

Differential Revision: https://reviews.llvm.org/D130406
2022-07-23 15:19:05 +02:00
Fangrui Song 9a572164d5 [ELF] Move InputFiles global variables (memoryBuffers, objectFiles, etc) into Ctx. NFC 2022-06-29 18:53:38 -07:00
Nico Weber 7effcbda49 Rename parallelForEachN to just parallelFor
Patch created by running:

  rg -l parallelForEachN | xargs sed -i '' -c 's/parallelForEachN/parallelFor/'

No behavior change.

Differential Revision: https://reviews.llvm.org/D128140
2022-06-19 17:49:00 -04:00
Martin Storsjö 9617ffce0d [LLD] [ELF] Add parentheses to silence a GCC warning. NFC.
This silences the following warning:

../tools/lld/ELF/SyntheticSections.cpp:1596:48: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
 1596 |   assert((index != 0 || type != target->gotRel && type != target->pltRel ||

Differential Revision: https://reviews.llvm.org/D127395
2022-06-09 22:26:37 +03:00
Fangrui Song f4a3569d0a [ELF] Fix spurious GOT/PLT assertion failure when .dynsym is discarded
Linux kernel arch/arm64/kernel/vmlinux.lds.S discards .dynsym . D123985 triggers
a spurious assertion failure. Detect the case with
`!mainPart->dynSymTab->getParent()`.
2022-04-20 22:49:49 -07:00
Shoaib Meenai 610a0e8b53 [ELF] Assert on invalid GOT or PLT relocations
Because of https://llvm.org/PR50675, we can end up producing a PLT
relocation referencing a symbol that's dropped from the dynamic symbol
table, which in turn causes a crash at runtime. We ran into this again
recently, resulting in crashes for our users. A subsequent diff will fix
that issue, but add an assert to catch it if it happens again.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D123985
2022-04-20 10:46:04 -07:00
Matt Arsenault 63fe6d7eae lld/AMDGPU: Fix asserts if no object files are involved in link
Fixes issue 47690. The reproduction steps produced a shared object
from clang directly, and then fed the shared object back into
lld. With no regular object files, this assert was hit. I'm not sure
if we need to or should be looking for equivalent fields in shared
objects.
2022-04-08 14:18:52 -04:00
Mitch Phillips 786c89fed3 [ELF][MTE] Add --android-memtag-* options to synthesize ELF notes
This ELF note is aarch64 and Android-specific. It specifies to the
dynamic loader that specific work should be scheduled to enable MTE
protection of stack and heap regions.

Current synthesis of the ".note.android.memtag" ELF note is done in the
Android build system. We'd like to move that to the compiler. This patch
adds the --memtag-stack, --memtag-heap, and --memtag-mode={async, sync,
none} flags to the linker, which synthesises the note for us.

Future changes will add -fsanitize=memtag* flags to clang which will
pass these through to lld.

Depends on D119381.

Differential Revision: https://reviews.llvm.org/D119384
2022-04-04 11:17:36 -07:00
Fangrui Song bdb98bd979 [ELF] Use endianness-aware read32 to avoid dispatch. NFC 2022-03-15 23:51:11 -07:00
Fangrui Song 385573e07b [ELF] Inline ARMExidxSyntheticSection::classof. NFC
To optimize the only call site `dyn_cast<ARMExidxSyntheticSection>(first)` and
decrease code size.
2022-03-15 23:41:30 -07:00
Fangrui Song 4a8de2832a [ELF] Add -z pack-relative-relocs
GNU ld 2.38 added -z pack-relative-relocs which is similar to
--pack-dyn-relocs=relr but synthesizes the `GLIBC_ABI_DT_RELR` version
dependency if a shared object named `libc.so.*` has a `GLIBC_2.*` version
dependency.

This is used to implement the (as some glibc folks call) version lockout
mechanism. Add this option, because glibc does not want to support
--pack-dyn-relocs=relr which does not add `GLIBC_ABI_DT_RELR`.
See https://maskray.me/blog/2021-10-31-relative-relocations-and-relr for
detail.

Close https://github.com/llvm/llvm-project/issues/53775

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D120701
2022-03-10 19:54:21 -08:00
Fangrui Song 6c814931bc [ELF] Don't use multiple inheritance for OutputSection. NFC
Add an OutputDesc class inheriting from SectionCommand. An OutputDesc wraps an
OutputSection. This change allows InputSection::getParent to be inlined.

Differential Revision: https://reviews.llvm.org/D120650
2022-03-08 11:23:42 -08:00
Joao Moreira 9d7001eba9 [ELF][X86] Don't create IBT .plt if there is no PLT entry
https://github.com/ClangBuiltLinux/linux/issues/1606
When GNU_PROPERTY_X86_FEATURE_1_IBT is enabled, ld.lld will create .plt output
section even if there is no PLT entry. Fix this by implementing
IBTPltSection::isNeeded instead of using the default code path (which always
returns true).

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D120600
2022-02-26 03:55:40 +00: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 c12d49c4e2 [ELF] Remove .strtab deduplication
D118577: the 0.1~1.1% .strtab size reduction does not justify the 3~6%
link time increase. Just remove it even for -O2. release/14.x
has D118577 and the release note mentioned that this may be removed.

Fix https://github.com/ClangBuiltLinux/linux/issues/1578
caused by D118577 (empty string not in stringMap).
2022-02-18 14:54:10 -08:00
Fangrui Song ce45c95694 [ELF] Remove obscure -dp and GNU ld incompatible --[no-]define-common, ignore -d/-dc
https://maskray.me/blog/2022-02-06-all-about-common-symbols#no-define-common

In GNU ld, -dc only affects -r links and causes COMMON symbols to be allocated.
--no-define-common is defined to make COMMON symbols undefined for -shared.
AIUI --no-define-common is a workaround around glibc 2.1 time and not really useful.

gold confuses --define-common with -d/FORCE_COMMON_ALLOCATION and implements
--define-common with -d semantics. Its --no-define-common is incompatible with
GNU ld.

In ld.lld, b2a23cf3c0 fixed the default -r
behavior for COMMON symbols but ported the incompatible gold
--[no-]define-common. To the best of my knowledge, no project uses -dp
--[no-]define-common. So just remove these options.

-d/-dc are used by the following projects:

* grub grub-core/genmod.sh.in uses -Wl,-r,-d (https://lists.gnu.org/archive/html/grub-devel/2022-02/msg00088.html)
* FreeBSD crunchgen uses -Wl,-dc (https://reviews.freebsd.org/D34215)

A no-op implementation works for them. Only when a program inspects relocatable
output by itself and does not recognize COMMON symbols, there may be a problem.
This is an extremely unlikely case.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D119108
2022-02-09 10:35:53 -08:00
Fangrui Song 27bb799095 [ELF] Clean up headers. NFC 2022-02-07 21:53:34 -08:00
Fangrui Song 0c3704fdbd [ELF] Deduplicate names of local symbols only with -O2
The deduplication requires a DenseMap of the same size of the local part of
.strtab . I optimized it in e205445434 but it is
still quite slow.

For Release build of clang, deduplication makes .strtab 1.1% smaller and makes the link 3% slower.
For chrome, deduplication makes .strtab 0.1% smaller and makes the link 6% slower.

I suggest that we only perform the optimization with -O2 (default is -O1).
Not deduplicating local symbol names will simplify parallel symbol table write.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D118577
2022-02-01 10:10:22 -08:00
Fangrui Song 196aedb843 [ELF] Change vector<InputSection *> to SmallVector. NFC
My x86-64 lld executable is 8KiB smaller.
2022-02-01 00:14:21 -08:00
Fangrui Song 73fd7d2304 [ELF] Change splitSections to objectFiles based parallelForEach. NFC
The work is more balanced.
2022-01-30 13:34:27 -08:00
Fangrui Song 988a03c585 [ELF] Add some Mips*Section to InStruct and change make<Mips*Section> to std::make_unique
Similar to D116143. My x86-64 lld executable is 20+KiB smaller.
2022-01-29 23:55:29 -08:00
Fangrui Song 469c4124ab [ELF] --gdb-index: switch to SmallVector. NFC 2022-01-29 15:24:56 -08:00
Fangrui Song da0e5b885b [ELF] Refactor -z combreloc
* `RelocationBaseSection::addReloc` increases `numRelativeRelocs`, which
  duplicates the work done by RelocationSection<ELFT>::writeTo.
* --pack-dyn-relocs=android has inappropropriate DT_RELACOUNT.
  AndroidPackedRelocationSection does not necessarily place relative relocations
  in the front and DT_RELACOUNT might cause semantics error (though our
  implementation doesn't and Android bionic doesn't use DT_RELACOUNT anyway.)

Move `llvm::partition` to a new function `partitionRels` and compute
`numRelativeRelocs` there. Now `RelocationBaseSection::addReloc` is trivial and
can be moved to the header to enable inlining.

The rest of DynamicReloc and `-z combreloc` handling is moved to the
non-template `RelocationBaseSection::computeRels` to decrease code size. My
x86-64 lld executable is 44+KiB smaller.

While here, rename `sort` to `combreloc`.
2022-01-29 14:45:58 -08:00
Fangrui Song 3704abaa16 [ELF] --gdb-index: replace vector<uint8_t> with unique_ptr<uint8_t[]>. NFC 2022-01-25 23:53:23 -08:00
Fangrui Song 571d6a7120 [ELF] Optimize .relr.dyn to not grow vector<uint64_t>. NFC 2022-01-25 23:33:40 -08:00
Fangrui Song 9fac78d0e1 [ELF] Simplify and optimize .relr.dyn NFC 2022-01-25 22:50:03 -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 f860fe3622 caused issues in https://lab.llvm.org/buildbot/#/builders/123/builds/8383, fixed by 22ee510dac.

Differential Revision: https://reviews.llvm.org/D108850
2022-01-20 14:53:26 -05:00
Fangrui Song ac0986f880 [ELF] Change std::vector<InputSectionBase *> to SmallVector
There is no remaining std::vector<InputSectionBase> now. My x86-64 lld
executable is 2KiB small.
2022-01-17 10:25:07 -08:00
Fangrui Song f855074ed1 [ELF] GnuHashTableSection: replace stable_sort with 2-key sort. NFC
strTabOffset stabilizes llvm::sort. My x86-64 executable is 5+KiB smaller.
2022-01-17 00:34:42 -08:00
Fangrui Song 9c4292a59d [ELF] Remove unneeded SyntheticSection memset(*, 0, *)
After the D33630 fallout was properly fixed by a4c5db30be.

Tested by D37462/D44986 tests, the new --no-rosegment test in build-id.s, and a few --rosegment/--no-rosegment programs.
2022-01-16 22:51:57 -08:00
Fangrui Song a4c5db30be [ELF] Remove redundant fillTrap and memset(*, 0, *). NFC
The new tests in build-id.s would catch problems if we made a mistake here.
2022-01-16 22:37:31 -08:00
Fangrui Song aad90763d9 [ELF] RelocationSection<ELFT>::writeTo: use unstable partition 2022-01-16 21:44:19 -08:00
Fangrui Song e205445434 [ELF] StringTableSection: Use DenseMap<CachedHashStringRef> to avoid redundant hash computation
5~6% speedup when linking clang and chrome.
2022-01-16 21:02:05 -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 3736d0854a [ELF] Optimize -z combreloc
Sorting dynamic relocations is a bottleneck. Simplifying the comparator improves
performance. Linking clang is 4~5% faster with --threads=8.

This change may shuffle R_MIPS_REL32 for Mips and is a NFC for non-Mips.
2022-01-15 22:33:51 -08:00
Fangrui Song 43d927984c [ELF] Refactor how .gnu.hash and .hash are discarded
Switch to the D114180 approach which is simpler and allows gnuHashTab/hashTab to
switch to unique_ptr.
2022-01-12 12:47:07 -08:00
Fangrui Song bf9c8636f2 [ELF] Support discarding .relr.dyn
db08df0570 does not work because part.relrDyn is
a unique_ptr and `reset` destroys the object which may still be referenced.

This commit uses the D114180 approach. Also improve the test to check that there
is no R_X86_64_RELATIVE.
2022-01-12 11:55:22 -08: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