Commit Graph

6474 Commits

Author SHA1 Message Date
Fangrui Song e80a0b353c [ELF] Remove unneeded getOutputSectionVA. NFC
I attempted to remove it 1 or 2 year ago but kept it just to have a good
diagnostic in case the output section is nullptr (should be impossible).
It is long enough that we haven't seen such a case.
2021-11-28 16:17:10 -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
Fangrui Song 7ea662e2dd [ELF] Replace one make_unique from r316378 with a stack object. NFC 2021-11-28 15:32:29 -08:00
Fangrui Song 25c7ec4fc6 [ELF] Simplify OutputSection::sectionIndex assignment. NFC
And improve comments.
2021-11-28 14:56:29 -08:00
Fangrui Song d060cc1f98 [ELF] Fix out-of-bounds write in memset(&Out::first, ...)
Fix r285764: there is no guarantee that Out::first is placed before other
static data members of `struct Out`. After `bufferStart` was introduced, this
out-of-bounds write is destined in many compilers. It is likely benign, though.

And move `Out::elfHeader->size` assignment beside `Out::elfHeader->sectionIndex`
2021-11-28 14:47:57 -08:00
Fangrui Song cecc6893a0 [ELF] Simplify assignFileOffsets
There is a difference with non-SHF_ALLOC SHT_NOBITS when off%sh_addralign!=0
which doesn't happen/matter in practice.
2021-11-28 13:44:42 -08:00
Fangrui Song f9a4d9aa03 [ELF] -z separate-*: Use max-page-size instead of common-page-size for text/non-SHF_ALLOC transition and writeTrapInstr
For -z separate-code and -z separate-loadable-segments:

When RW is present, the RX to RW transition is aligned with max-page-size.
When RW is absent, the RX to non-SHF_ALLOC transition should use max-page-size as well.
2021-11-28 12:47:50 -08:00
Fangrui Song 6c1c2313d1 [ELF] Simplify assignFileOffsets. NFC 2021-11-28 11:43:59 -08:00
Ard Biesheuvel da66263b6e [ARM] implement support for ALU/LDR PC-relative group relocations
Currently, LLD does not support the complete set of ARM group relocations.
Given that I intend to start using these in the Linux kernel [0], let's add
support for these.

This implements the group processing as documented in the ELF psABI. Notably,
this means support is dropped for very far symbol references that also carry a
small component, where the immediate is rotated in such a way that only part of
it wraps to the other end of the 32-bit word. To me, it seems unlikely that
this is something anyone could be relying on, but of course I could be wrong.

[0] https://lore.kernel.org/r/20211122092816.2865873-8-ardb@kernel.org/

Reviewed By: peter.smith, MaskRay

Differential Revision: https://reviews.llvm.org/D114172
2021-11-27 10:26:37 +01:00
Fangrui Song f1ba48d508 [ELF] Simplify Symbol::extract. NFC 2021-11-26 14:10:55 -08:00
Fangrui Song 3b4dd68de5 [ELF][PPC64] Make --power10-stubs/--no-power10-stubs proper aliases for --power10-stubs={auto,no}
This allows --power10-stubs= and --[no-]power10-stubs to override each other
(they are position dependent in GNU ld).

Also improve --help messages and the manpage.

Note: GNU ld's default "auto" mode uses heuristics to decide whether Power10
instructions are used. Arguably it is a design mistake of R_PPC64_REL24_NOTOC
(acked by the relevant folks on a libc-alpha discussion). We don't implement
"auto", so the default --power10-stubs is the same as "yes".
2021-11-26 11:51:45 -08:00
Fangrui Song 09401dfcf1 [ELF] Rename fetch to extract
The canonical term is "extract" (GNU ld documentation, Solaris's `-z *extract`
options). Avoid inventing a term and match --why-extract. (ld64 prefers "load"
but the word is overloaded too much)

Mostly MFC, except for --help messages and the header row in
--print-archive-stats output.
2021-11-26 10:58:50 -08:00
Fangrui Song 7051aeef7a [ELF] Rename BaseCommand to SectionCommand. NFC
BaseCommand was picked when PHDRS/INSERT/etc were not implemented. Rename it to
SectionCommand to match `sectionCommands` and make it clear that the commands
are used in SECTIONS (except a special case for SymbolAssignment).

Also, improve naming of some BaseCommand variables (base -> cmd).
2021-11-25 20:24:23 -08:00
Fangrui Song e40e17fcaf [ELF] Make ExprValue smaller. NFC' 2021-11-25 16:55:06 -08:00
Fangrui Song 6188fd4957 [ELF] Rename OutputSection::sectionCommands to commands. NFC
This partially reverts r315409: the description applies to LinkerScript, but not
to OutputSection.

The name "sectionCommands" is used in both LinkerScript::sectionCommands and
OutputSection::sectionCommands, which may lead to confusion.
"commands" in OutputSection has no ambiguity because there are no other types
of commands.
2021-11-25 16:47:07 -08:00
Fangrui Song ff0d9e6cfa [ELF] Remove redundant part.dynSymTab creation. NFC 2021-11-25 14:42:22 -08:00
Fangrui Song 5ca54c6686 [ELF] Simplify GnuHashSection::write. NFC 2021-11-25 14:23:25 -08:00
Fangrui Song 55c14d6dbf [ELF] Simplify DynamicSection content computation. NFC
The new code computes the content twice, but avoides the tricky
std::function<uint64_t()>. Removed 13KiB code in a Release build.
2021-11-25 14:12:34 -08:00
Fangrui Song 6ca8fde226 [ELF] Emit DF_STATIC_TLS only for -shared
This matches GNU ld and saves 2 words for executables.
2021-11-24 23:17:13 -08:00
Fangrui Song 5922dd91f8 [ELF] Rename hasStaticTlsModel to hasTlsIe
and remove unneeded atomic.
2021-11-24 21:06:04 -08:00
Fangrui Song 371290dfd4 [ELF] Remove unneeded DF_STATIC_TLS for EM_386 local-exec TLS
which is also untested.
2021-11-24 20:43:58 -08:00
Igor Kudrin 8cdf1c1edb [ELF] Support the "read-only" memory region attribute
The attribute 'r' allows (or disallows for the negative case) read-only
sections, i.e. ones without the SHF_WRITE flag, to be assigned to the
memory region. Before the patch, lld could put a section in the wrong
region or fail with "error: no memory region specified for section".

Differential Revision: https://reviews.llvm.org/D113771
2021-11-24 12:17:09 +07:00
Fangrui Song 38ed1db7e8 [ELF] Support non-RAX/non-adjacent R_X86_64_GOTPC32_TLSDESC/R_X86_64_TLSDESC_CALL
The current TLSDESC optimization code assumes:
```
leaq x@tlsdesc(%rip), %rax
call *x@tlscall(%rax)       # adjacent
```

From https://gitlab.freedesktop.org/mesa/mesa/-/issues/5665 , it seems that the
two instructions may not be adjacent in GCC 10's output:
```
leaq x@tlsdesc(%rip), %rax
something else
call *x@tlscall(%rax)
```

This patch supports the case. While here, support non-RAX registers for
R_X86_64_GOTPC32_TLSDESC, in case the compiler generates inefficient:

```
leaq x@tlsdesc(%rip), %rcx  # or %rdx, %rbx, %rdi, ...
movq %rcx, %rax
call *x@tlscall(%rax)       # GNU ld/gold error for non-RAX
```

Differential Revision: https://reviews.llvm.org/D114416
2021-11-23 10:30:11 -08:00
Fangrui Song 7aafe467d2 [ELF] Simplify a condition with config->copyRelocs. NFC 2021-11-22 13:59:23 -08:00
Igor Kudrin a05b694b1e [ELF][NFC] Do not pass region name to expandMemoryRegion()
The name can be easily got on-site.

Differential Revision: https://reviews.llvm.org/D114228
2021-11-22 14:19:07 +07:00
Fangrui Song 648157b05a [ELF] Move getOutputSectionName from Writer.cpp to LinkerScript.cpp. NFC
and internalize it.
2021-11-20 22:18:09 -08:00
Fangrui Song 2997441b85 [ELF] Support discarding .got.plt
Fix a null pointer dereference when .got.plt is discarded.

This also adds a test for discarding `.plt`.

Reviewed By: ikudrin

Differential Revision: https://reviews.llvm.org/D114180
2021-11-19 10:50:53 -08:00
Andrew Ng 47eb3f155f [ELF] Ensure output section is not discarded in addStartEndSymbols()
Fixes https://bugs.llvm.org/show_bug.cgi?id=52534.

Differential Revision: https://reviews.llvm.org/D114179
2021-11-19 11:45:58 +00:00
Konstantin Schwarz 8c18719bae [ELF] Expand LMA region if output section alignment introduces padding
When aligning the start address of an output section introduces a gap between the current dot pointer
and the new aligned address, we were already properly expanding the memory region, if available.

D74286 introduced a new behavior to also align the LMA address if an LMA region is specified.
However, this did not expand the corresponding LMA region.
Now, we also expand the LMA region if it is set.

This fixes PR52510.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D114166
2021-11-19 11:27:21 +01:00
Igor Kudrin 66691de94c [ELF] Do not try to assign a memory region to a non-allocatable section
Non-allocatable sections are not part of the memory image of the
program, so there is no need to find memory regions for them either
matching properties or handling explicit assignments. The early test
and return help to simplify LinkerScript::findMemoryRegion() a bit.

Differential Revision: https://reviews.llvm.org/D113768
2021-11-15 15:59:39 +07:00
Fangrui Song a05384dc89 [ELF] Make --no-relax disable R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX GOT optimization
This brings back the original version of D81359.
I have found several use cases now.

* Unlike GNU ld, LLD's relocation processing is one pass. If we decide to
  optimize(relax) R_X86_64_{,REX_}GOTPCRELX, we will suppress GOT generation and
  cannot undo the decision later. Optimizing R_X86_64_REX_GOTPCRELX can usually
  make it easy to hit `relocation R_X86_64_REX_GOTPCRELX out of range` because
  the distance to GOT is usually shorter. Without --no-relax, the user has to
  recompile with `-Wa,-mrelax-relocations=no`.
* The option would help during my investigationg of the root cause of https://git.kernel.org/linus/09e43968db40c33a73e9ddbfd937f46d5c334924
* There is need for relaxation for AArch64 & RISC-V. Implementing this for
  x86-64 improves consistency with little target-specific cost (two-line
  X86_64.cpp change).

Reviewed By: alexander-shaposhnikov

Differential Revision: https://reviews.llvm.org/D113615
2021-11-12 09:47:31 -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
Igor Kudrin d2dd36bbbe [ELF] Better resemble GNU ld when placing orphan sections into memory regions
An orphan section should be placed in the same memory region as its
anchor section if the latter specifies the memory region explicitly.
If there is no explicit assignment for the anchor section in the linker
script, its memory region is selected by matching attributes, and the
same should be done for the orphan section.

Before the patch, some scripts that were handled smoothly in GNU ld
caused an "error: no memory region specified for section" in lld.

Differential Revision: https://reviews.llvm.org/D112925
2021-11-11 15:07:38 +07:00
Fangrui Song 51ee08c217 [ELF] Enforce double-dash form for --ignore-{data,function}-pointer-equality --reproduce --thread
They are LLD-specific options. We have enforced double-dash forms for
other options (reduce collision with short options) but missed them.
2021-11-10 01:17:08 -08:00
Fangrui Song d71bb6a409 [ELF] Inline isPPC64SmallCodeModelTocReloc which is only called once. NFC 2021-11-09 20:41:05 -08:00
Fangrui Song bec28ee1ea [ELF] Move isStaticLinkTimeConstant closer to the only caller processRelocAux. NFC 2021-11-09 20:37:46 -08:00
Fangrui Song 213d1849a4 [ELF] Improve sh_info=0 and sh_info>=num_sections diagnostic for SHT_REL/SHT_RELA
PR52408 reported an sh_info=0 instance. I have seen sh_info=0
independently before.

sh_info>=num_sections is probably very rare. Just use one diagnostic for
the two types of errors.

Delete invalid-relocations.test which is covered by invalid/bad-reloc-target.test

Differential Revision: https://reviews.llvm.org/D113466
2021-11-09 09:54:12 -08:00
Fangrui Song cebb0a64b4 [ELF][ARM] Improve error message for unknown relocation
Like rLLD354040.

Before: `error: unrecognized relocation Unknown (254)`
Now:    `error: unknown relocation (254) against symbol foo`
2021-11-08 12:39:08 -08:00
Noah Shutty d788c44f5c [Support] Improve Caching conformance with Support library behavior
This diff makes several amendments to the local file caching mechanism
which was migrated from ThinLTO to Support in
rGe678c51177102845c93529d457b020f969125373 in response to follow-up
discussion on that commit.

Patch By: noajshu

Differential Revision: https://reviews.llvm.org/D113080
2021-11-04 13:00:44 -07:00
Fangrui Song c977564fc2 Revert "[ELF] Try appeasing --target=armv7-linux-androideabi24 sanitizer symbolization tests"
This reverts commit 5cbec88cbf.

Vitaly said that 2faac77f26 actually works.

Sanitizer's armv7-linux-androideabi24 configuration has other issues which haven't been identified yet, but that's unrelated to the empty symbol name issue.
2021-11-03 00:56:09 -07:00
Fangrui Song 5cbec88cbf [ELF] Try appeasing --target=armv7-linux-androideabi24 sanitizer symbolization tests 2021-11-02 18:57:04 -07:00
Fangrui Song 2f7366c89d [ELF] Simplify R_DTPREL. NFC 2021-10-31 20:30:00 -07:00
Fangrui Song 9f8ffaaa0b [ELF] Replace "symbol '...' has no type" diagnostic with "relocation ... cannot be used against symbol '...'"
The "symbol 'foo' has no type" diagnostic tries to inform that copy
relocation/canonical PLT entry cannot be used, but the diagnostic is often
incorrect and confusing.
2021-10-31 13:12:26 -07:00
Fangrui Song 164194a5af [ELF] Untangle R_GOT style TLS IE and processRelocAux. NFC 2021-10-31 12:38:36 -07:00
Fangrui Song 55e69ece72 [ELF] Remove -Wl,-z,notext hint
The hint does not pull its weight:

* adding -Wl,-z,notext often won't work (relocation types other than `symbolRel`, e.g. `R_AARCH64_LDST32_ABS_LO12_NC`)
* for pure (no assembly) C/C++ projects, the "-fPIC" hint is sufficient
2021-10-31 12:10:43 -07:00
Fangrui Song b76aacef5f [ELF] Simplify isStaticLinkTimeConstant. NFC 2021-10-31 10:46:42 -07:00
Fangrui Song 3fe4b54915 [ELF] Make getImplicitAddend return 0 for R_ARM_V4BX. NFC
Will be useful if we move R_ARM_V4BX handling around.
2021-10-30 23:31:39 -07:00
Fangrui Song aa1d32f519 [ELF][Mips] Use R_DTPREL for R_MIPS_TLS_DTPREL* 2021-10-30 21:58:43 -07: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