Commit Graph

681 Commits

Author SHA1 Message Date
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 f4fb5fd752 (`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
Fangrui Song ca8105b76c [ELF][X86] Support R_X86_64_PLTOFF64
For a function call (using the default `-fplt`), GCC `-mcmodel=large` generates an assembly modifier which
leads to an R_X86_64_PLTOFF64 relocation. In real world,
http://git.ageinghacker.net/jitter (used by GNU poke) uses `-mcmodel=large`.

R_X86_64_PLTOFF64's formula is (if preemptible) `L - GOT + A` or (if non-preemptible) `S - GOT + A`
where `GOT` is (confusingly) the address of `.got.plt`

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D112386
2021-10-25 13:05:17 -07:00
Simon Atanasyan c6ebc651b6 [LLD] Support compressed input sections on big-endian targets
This patch enables compressed input sections on big-endian targets by
checking the target endianness and selecting an appropriate `Chdr`
structure.

Fixes PR51369

Differential Revision: https://reviews.llvm.org/D107635
2021-08-07 13:20:13 +03:00
Fangrui Song 0995bbdb66 [ELF] Simplify getAArch64UndefinedRelativeWeakVA. NFC 2021-06-10 13:30:16 -07:00
Fangrui Song c03b6305d8 [ELF][RISCV] Resolve branch relocations referencing undefined weak to current location if not using PLT
In a -no-pie link we optimize R_PLT_PC to R_PC. Currently we resolve a branch
relocation to the link-time zero address. However such a choice tends to cause
relocation overflow possibility for RISC architectures.

* aarch64: GNU ld: rewrite the instruction to a NOP; ld.lld: branch to the next instruction
* mips: GNU ld: branch to the start of the text segment (?); ld.lld: branch to zero
* ppc32: GNU ld: rewrite the instruction to a NOP; ld.lld: branch to the current instruction
* ppc64: GNU ld: rewrite the instruction to a NOP; ld.lld: branch to the current instruction
* riscv: GNU ld: branch to the absolute zero address (with instruction rewriting)
* i386/x86_64: GNU ld/ld.lld: branch to the link-time zero address

I think that resolving to the same location is a good choice. The instruction,
if triggered, is clearly an undefined behavior. Resolving to the same location
can cause an infinite loop (making the user aware of the issue) while ensuring
no overflow.

Reviewed By: jrtc27

Differential Revision: https://reviews.llvm.org/D103001
2021-06-10 13:25:16 -07:00
Fangrui Song c9b1bd1012 [ELF] Support .rela.eh_frame with unordered r_offset values
GNU ld -r can create .rela.eh_frame with unordered r_offset values.
(With LLD, we can craft such a case by reordering sections in .eh_frame.)
This is currently unsupported and will trigger
`assert(pieces[i].inputOff <= off ...` in `OffsetGetter::get`
(the content is corrupted in a -DLLVM_ENABLE_ASSERTIONS=off build).
This patch supports this case.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D101116
2021-04-29 08:51:09 -07:00
Fangrui Song b2a3d31eed [ELF] Simplify R_386_TLS_GD computation. NFC 2021-04-16 19:08:23 -07:00
Sam Clegg d49270b087 [lld][ELF] Removing redundant cast. NFC.
Also a couple of minor cleanups in merge-string.s:
- fix inconsistent use of tabs
- use `.p2align` rather than `.align` since `.p2align` works the
  same on all platforms (the meaning of align seems to differ
  between platforms according to `AlignmentIsInBytes`.

I noticed these potential cleanups while porting SHF_STRINGS support to
wasm-ld.

Differential Revision: https://reviews.llvm.org/D97647
2021-02-28 16:53:41 -08:00
Fangrui Song b3165a70ae [ELF] Allow R_386_GOTOFF from .debug_info
In GCC emitted .debug_info sections, R_386_GOTOFF may be used to
relocate DW_AT_GNU_call_site_value values
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98946).

R_386_GOTOFF (`S + A - GOT`) is one of the `isStaticLinkTimeConstant` relocation
type which is not PC-relative, so it can be used from non-SHF_ALLOC sections. We
current allow new relocation types as needs come. The diagnostic has caught some
bugs in the past.

Differential Revision: https://reviews.llvm.org/D95994
2021-02-04 09:17:47 -08:00
Adhemerval Zanella 988cc0a083 [LLD][ELF][AArch64] Add support for R_AARCH64_LD64_GOTPAGE_LO15 relocation
It is not used by LLVM, but GCC might generates it when compiling
with -fpie, as indicated by PR#40357 [1].

[1] https://bugs.llvm.org/show_bug.cgi?id=40357
2021-01-26 12:01:38 +00:00
Fangrui Song 22c1bd57bf [ELF] Rename R_TLS to R_TPREL and R_NEG_TLS to R_TPREL_NEG. NFC
The scope of R_TLS (TP offset relocation types (TPREL/TPOFF) used for the
local-exec TLS model) is actually narrower than its name may imply. R_TLS_NEG
is only used by Solaris R_386_TLS_LE_32.

Rename them so that they will be less confusing.

Reviewed By: grimar, psmith, rprichard

Differential Revision: https://reviews.llvm.org/D93467
2020-12-18 08:24:42 -08:00
Georgii Rymar 4845531fa8 [lib/Object] - Refine interface of ELFFile<ELFT>. NFCI.
`ELFFile<ELFT>` has many methods that take pointers,
though they assume that arguments are never null and
hence could take references instead.

This patch performs such clean-up.

Differential revision: https://reviews.llvm.org/D87385
2020-09-15 11:38:31 +03:00
Pavel Labath 3d1b0000f9 [lld] s/dyn_cast/isa in InputSection.cpp
Avoids a -Wunused-variable with gcc.
2020-08-24 11:45:30 +02:00
Nemanja Ivanovic cddb0dbcef [LLD][PowerPC] Implement GOT to PC-Rel relaxation
This patch implements the handling for the R_PPC64_PCREL_OPT relocation as well
as the GOT relocation for the associated R_PPC64_GOT_PCREL34 relocation.

On Power10 targets with PC-Relative addressing, the linker can relax
GOT-relative accesses to PC-Relative under some conditions. Since the sequence
consists of a prefixed load, followed by a non-prefixed access (load or store),
the linker needs to replace the first instruction (as the replacement
instruction will be prefixed). The compiler communicates to the linker that
this optimization is safe by placing the two aforementioned relocations on the
GOT load (of the address).
The linker then does two things:

- Convert the load from the got into a PC-Relative add to compute the address
  relative to the PC
- Find the instruction referred to by the second relocation (R_PPC64_PCREL_OPT)
  and replace the first with the PC-Relative version of it

It is important to synchronize the mapping from legacy memory instructions to
their PC-Relative form. Hence, this patch adds a file to be included by both
the compiler and the linker so they're always in agreement.

Differential revision: https://reviews.llvm.org/D84360
2020-08-17 09:36:09 -05:00
Fangrui Song e973c1375e [ELF] Move the outSecOff addend from relocAlloc/relocNonAlloc/... to InputSectionBase::relocate
For an InputSection, the `buf` argument of `InputSectionBase::relocate` points
to the content of the containing OutputSection, instead of the content of the
InputSection itself, so `outSecOff` needs to be added in its callees.  This is
counter-intuitive and leads to many `- outSecOff` and `+ outSecOff`.

This patch makes `InputSection::writeTo` call `InputSectionBase::relocate` with
`outSecOff` added. relocAlloc/relocNonAlloc/relocateNonAllocForRelocatable can
thus be simplified now.

Updated test:

* non-abs-reloc.s: A minor offset bug is fixed for a diagnostic in `relocateNonAlloc`

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D85618
2020-08-11 08:06:38 -07:00
Fangrui Song 004be4037e [ELF] Change tombstone values to (.debug_ranges/.debug_loc) 1 and (other .debug_*) 0
tl;dr See D81784 for the 'tombstone value' concept. This patch changes our behavior to be almost the same as GNU ld (except that we also use 1 for .debug_loc):

* .debug_ranges & .debug_loc: 1 (LLD<11: 0+addend; GNU ld uses 1 for .debug_ranges)
* .debug_*: 0 (LLD<11: 0+addend; GNU ld uses 0; future LLD: -1)

We make the tweaks because:

1) The new tombstone is novel and needs more time to be adopted by consumers before it's the default.
2) The old (gold) strategy had problems with zero-length functions - so rather than going back that, we're going to the GNU ld strategy which doesn't have that problem.
3) One slight tweak to (2) is to apply the .debug_ranges workaround to .debug_loc for the same reasons it applies to debug_ranges - to avoid terminating lists early.

-----

http://lists.llvm.org/pipermail/llvm-dev/2020-July/143482.html

The tombstone value -1 in .debug_line caused problems to lldb (fixed by D83957;
will be included in 11.0.0) and breakpad (fixed by
https://crrev.com/c/2321300). It may potentially affects other DWARF consumers.

For .debug_ranges & .debug_loc: 1, an argument preferring 1 (GNU ld for .debug_ranges) over -2 is that:
```
{-1, -2}    <<< base address selection entry
{0, length} <<< address range
```
may create a situation where low_pc is greater than high_pc. So we use
1, the GNU ld behavior for .debug_ranges

For other .debug_* sections, there haven't been many reports. One issue is that
bloaty (src/dwarf.cc) can incorrectly count address ranges in .debug_ranges . To
reduce similar disruption, this patch changes the tombstone values to be similar to GNU ld.

This does mean another behavior change to the default trunk behavior. Sorry
about it. The default trunk behavior will be similar to release/11.x while we work on a transition plan for LLD users.

Reviewed By: dblaikie, echristo

Differential Revision: https://reviews.llvm.org/D84825
2020-08-06 15:30:08 -07:00
Fangrui Song b216c80cc2 [ELF] Allow SHF_LINK_ORDER sections to have sh_link=0
Part of https://bugs.llvm.org/show_bug.cgi?id=41734

The semantics of SHF_LINK_ORDER have been extended to represent metadata
sections associated with some other sections (usually text).

The associated text section may be discarded (e.g. LTO) and we want the
metadata section to have sh_link=0 (D72899, D76802).

Normally the metadata section is only referenced by the associated text
section. sh_link=0 means the associated text section is discarded, and
the metadata section will be garbage collected. If there is another
section (.gc_root) referencing the metadata section, the metadata
section will be retained. It's the .gc_root consumer's job to validate
the metadata sections.

  # This creates a SHF_LINK_ORDER .meta with sh_link=0
  .section .meta,"awo",@progbits,0
  1:
  .section .meta,"awo",@progbits,foo
  2:

  .section .gc_root,"a",@progbits
  .quad 1b
  .quad 2b

Reviewed By: pcc, jhenderson

Differential Revision: https://reviews.llvm.org/D72904
2020-08-05 16:17:42 -07:00
Fangrui Song 86ab98b001 [ELF] -r: rewrite SHT_GROUP content if some members are combined or discarded
* If two group members are combined, we should leave just one index in the SHT_GROUP content.
* If a group member is discarded (/DISCARD/ or upcoming -r --gc-sections combination),
  we should drop its index in the SHT_GROUP content. LLD currently crashes (`getOutputSection()` is null).

Reviewed By: psmith

Differential Revision: https://reviews.llvm.org/D84129
2020-07-21 08:49:45 -07:00
Fangrui Song 4ce56b8122 [ELF] Add -z dead-reloc-in-nonalloc=<section_glob>=<value>
... to customize the tombstone value we use for an absolute relocation
referencing a discarded symbol. This can be used as a workaround when
some debug processing tool has trouble with current -1 tombstone value
(https://bugs.chromium.org/p/chromium/issues/detail?id=1102223#c11 )

For example, to get the current built-in rules (not considering the .debug_line special case for ICF):

```
-z dead-reloc-in-nonalloc='.debug_*=0xffffffffffffffff'
-z dead-reloc-in-nonalloc=.debug_loc=0xfffffffffffffffe
-z dead-reloc-in-nonalloc=.debug_ranges=0xfffffffffffffffe
```

To get GNU ld (as of binutils 2.35)'s behavior:

```
-z dead-reloc-in-nonalloc='*=0'
-z dead-reloc-in-nonalloc=.debug_ranges=1
```

This option has other use cases. For example, if we want to check
whether a non-SHF_ALLOC section has dead relocations.
With this patch, we can run a regular LLD and run another with a special
-z dead-reloc-in-nonalloc=, then compare their output.

Reviewed By: thakis

Differential Revision: https://reviews.llvm.org/D83264
2020-07-08 10:15:16 -07:00
Fangrui Song 6fa1343bb3 [ELF] Resolve R_DTPREL in .debug_* referencing discarded symbols to -1
The location of a TLS variable is encoded as a DW_OP_const4u/DW_OP_const8u
followed by a DW_OP_push_tls_address (or DW_OP_GNU_push_tls_address https://sourceware.org/bugzilla/show_bug.cgi?id=11616 ).

This change follows up to D81784 and makes relocations types generalized as
R_DTPREL (e.g. R_X86_64_DTPOFF{32,64}, R_PPC64_DTPREL64) use -1 as the
tombstone value as well. This works for both TLS Variant I and Variant II
architectures.

* arm: .long tls(tlsldo)   # not working currently (R_ARM_TLS_LDO32 is R_ABS)
* mips64: .dtpreldword tls+32768
* ppc64: .quad tls@DTPREL+0x8000
* riscv: neither GCC nor clang has implemented DW_AT_location. It is likely .long/.quad tls@dtprel+0x800
* x86-32: .long tls@DTPOFF
* x86-64: .long tls@DTPOFF; .quad tls@DTPOFF

tls has a non-negative st_value, so such relocations (st_value+addend)
never resolve to -1 in a normal (not discarded) case.

```
// clang -fuse-ld=lld -g -ffunction-sections a.c -Wl,--gc-sections
// foo and tls will be discarded by --gc-sections.
// DW_AT_location [DW_FORM_exprloc] (DW_OP_const8u 0xffffffffffffffff, DW_OP_GNU_push_tls_address)
thread_local int tls;
int foo() { return ++tls; }
int main() {}
```

Also, drop logic added in D26201 intended to address PR30793. It added a test
(gc-debuginfo-tls.s) using a non-SHF_ALLOC section and a local symbol, which
does not reflect the intended scenario: a relocation in a SHF_ALLOC section
referencing a discarded non-local symbol. For such a non .debug_* section, just
emit an error.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D82899
2020-07-03 09:50:30 -07:00
Fangrui Song e6ad78fe05 [ELF] Don't resolve a relocation in .debug_line referencing an ICF folded symbol to the tombstone value
After D81784, we resolve a relocation in .debug_* referencing an ICF folded
section symbol to a tombstone value.

Doing this for .debug_line has a problem (https://reviews.llvm.org/D81784#2116925 ):
.debug_line may describe folded lines as having addresses UINT64_MAX or
some wraparound small addresses.

```
int foo(int x) {
  return x; // line 2
}

int bar(int x) {
  return x; // line 6
}
```

```
Address            Line   Column File   ISA Discriminator Flags
------------------ ------ ------ ------ --- ------------- -------------
0x00000000002016c0      1      0      1   0             0  is_stmt
0x00000000002016c7      2      9      1   0             0  is_stmt
prologue_end
0x00000000002016ca      2      2      1   0             0
0x00000000002016cc      2      2      1   0             0  end_sequence
// UINT64_MAX and wraparound small addresses
0xffffffffffffffff      5      0      1   0             0  is_stmt
0x0000000000000006      6      9      1   0             0  is_stmt
prologue_end
0x0000000000000009      6      2      1   0             0
0x000000000000000b      6      2      1   0             0  end_sequence
0x00000000002016d0      9      0      1   0             0  is_stmt
0x00000000002016df     10      6      1   0             0  is_stmt prologue_end
0x00000000002016e6     11     11      1   0             0  is_stmt
...
```

These entries can confuse debuggers:

gdb before 2020-07-01 (binutils-gdb a8caed5d7faa639a1e6769eba551d15d8ddd9510 "Recognize -1 as a tombstone value in .debug_line")
(can't continue due to a breakpoint in an invalid region of memory):
```
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x6
```
lldb (breakpoint has no effect):
```
(lldb) b 6
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
```

This patch special cases .debug_line to not use the tombstone value,
restoring the previous behavior: .debug_line will have entries with the
same addresses (ICF) but different line numbers. A breakpoint on line 2
or 6 will trigger on both functions.

Reviewed By: dblaikie, jhenderson

Differential Revision: https://reviews.llvm.org/D82828
2020-07-01 13:38:16 -07:00
Leonard Chan 723b5a1785 [lld][ELF][AArch64] Handle R_AARCH64_PLT32 relocation
This is the followup to D77647 which implements handling for the new
R_AARCH64_PLT32 relocation type in lld. This relocation would benefit the
PIC-friendly vtables feature described in D72959.

Differential Revision: https://reviews.llvm.org/D81184
2020-06-23 16:10:07 -07:00
Fangrui Song e618ccbf43 [ELF] Resolve relocations in .debug_* referencing (discarded symbols or ICF folded section symbols) to tombstone values
See D59553, https://lists.llvm.org/pipermail/llvm-dev/2020-May/141885.html and
https://sourceware.org/pipermail/binutils/2020-May/111357.html for
extensive discussions on a tombstone value.
See http://www.dwarfstd.org/ShowIssue.php?issue=200609.1
(Reserve an address value for "not present") for a DWARF enhancement proposal.

We resolve such relocations to a tombstone value to indicate that the address is invalid.
This solves several problems (the normal behavior is to resolve the relocation to the addend):

* For an empty function in a collected section, a pair of (0,0) can
  terminate .debug_loc and .debug_ranges (as of binutils 2.34, GNU ld
  resolves such a relocation to 1 to avoid the .debug_ranges issue)
* If DW_AT_high_pc is sufficiently large, the address range can collide
  with a regular code range of low address (https://bugs.llvm.org/show_bug.cgi?id=41124 )
* If a text section is folded into another by ICF, we may leave entries
  in multiple CUs claiming ownership of the same range of code, which can
  confuse consumers.
* Debug information associated with COMDAT sections can have problems
  similar to ICF, but is more complex - thus not addressed by this patch.

For pre-DWARF-v5 .debug_loc and .debug_ranges, a pair of 0 can terminate
entries (invalidating subsequent ranges).
-1 is a reserved value with special meaning (base address selection entry) which can't be used either.
Use -2 instead.

For all other .debug_*, use UINT32_MAX for 32-bit targets and UINT64_MAX
for 64-bit targets. In the code, we intentionally use
`uint64_t tombstone = UINT64_MAX` for 32-bit targets as well: this matches
SignExtend64 as used in `relocateAlloc`. (Actually UINT32_MAX does not work for R_386_32)

Note 0, we only special case `target->symbolicRel` (R_X86_64_64, R_AARCH64_ABS64, R_PPC64_ADDR64), not
short-range absolute relocations (e.g. R_X86_64_32). Only forms like DW_FORM_addr need to be special cased.
They can hold an arbitrary address (must be 64-bit on a 64-bit target). (In theory,
producers can make use of small code model to emit 32-bit relocations. This doesn't seem to be leveraged.)

Note 1, we have to ignore the addend, because we don't want to resolve
DW_AT_low_pc (which may have a non-zero addend) to -1+addend (wrap
around to a low address):

  __attribute__((section(".text.x"))) void f1() { }
  __attribute__((section(".text.x"))) void f2() { } // DW_AT_low_pc has a non-zero addend

Note 2, if the prevailing copy does not have debugging information while
a non-prevailing copy has (partial debug build), we don't do extra work
to attach debugging information to the prevailing definition.  (clang
has a lot of debug info optimizations that are on-by-default that assume
the whole program is built with debug info).

  clang -c -ffunction-sections a.cc    # prevailing copy has no debug info
  clang -c -ffunction-sections -g b.cc

Reviewed By: dblaikie, avl, jhenderson

Differential Revision: https://reviews.llvm.org/D81784
2020-06-23 11:48:46 -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 b257d3c8a8 [ELF][PPC64] Suppress toc-indirect to toc-relative relaxation if R_PPC64_TOC16_LO is seen
The current implementation assumes that R_PPC64_TOC16_HA is always followed
by R_PPC64_TOC16_LO_DS. This can break with R_PPC64_TOC16_LO:

  // Load the address of the TOC entry, instead of the value stored at that address
  addis 3, 2, .LC0@tloc@ha  # R_PPC64_TOC16_HA
  addi  3, 3, .LC0@tloc@l   # R_PPC64_TOC16_LO
  blr

which is used by boringssl's util/fipstools/delocate/delocate.go
https://github.com/google/boringssl/blob/master/crypto/fipsmodule/FIPS.md has some documentation.
In short, this tool converts an assembly file to avoid any potential relocations.
The distance to an input .toc is not a constant after linking, so it cannot use an `addis;ld` pair.
Instead, it jumps to a stub which loads the TOC entry address with `addis;addi`.

This patch checks the presence of R_PPC64_TOC16_LO and suppresses
toc-indirect to toc-relative relaxation if R_PPC64_TOC16_LO is seen.
This approach is conservative and loses some relaxation opportunities but is easy to implement.

  addis 3, 2, .LC0@toc@ha  # no relaxation
  addi  3, 3, .LC0@toc@l   # no relaxation
  li    9, 0
  addis 4, 2, .LC0@toc@ha  # can relax but suppressed
  ld    4, .LC0@toc@l(4)   # can relax but suppressed

Also note that interleaved R_PPC64_TOC16_HA and R_PPC64_TOC16_LO_DS is
possible and this patch accounts for that.

  addis 3, 2, .LC1@toc@ha  # can relax
  addis 4, 2, .LC2@toc@ha  # can relax
  ld    3, .LC1@toc@l(3)   # can relax
  ld    4, .LC2@toc@l(4)   # can relax

Reviewed By: #powerpc, sfertile

Differential Revision: https://reviews.llvm.org/D78431
2020-04-30 09:16:51 -07:00