79 Commits

Author SHA1 Message Date
Fangrui Song
04996a28b7
[ELF] Rename target-specific RelExpr enumerators
RelExpr enumerators are named `R_*`, which can be confused with ELF
relocation type names. Rename the target-specific ones to `RE_*` to
avoid confusion.

For consistency, the target-independent ones can be renamed as well, but
that's not urgent. The relocation processing mechanism with RelExpr has
non-trivial overhead compared with mold's approach, and we might make
more code into Arch/*.cpp files and decrease the enumerators.

Pull Request: https://github.com/llvm/llvm-project/pull/118424
2024-12-03 09:17:17 -08:00
Fangrui Song
c1a6defd9f [ELF] Make RelType a struct type
otherwise operator<<(const ELFSyncStream &s, RelType type) applies to
non-reloc-type uint32_t, which can be confusing.
2024-11-16 20:26:34 -08:00
Fangrui Song
be5dad012e [ELF] Replace internalLinkerError(getErrorLoc(ctx, buf) + ...) with InternalErr(ctx, buf)
and simplify `+ toStr(ctx, x)` to `<< x`.
The trailing '\n' << llvm::getBugReportMsg() is not very useful and
therefore removed.
2024-11-16 13:07:17 -08:00
Fangrui Song
58a971f42f [ELF] Replace contex-less toString(x) with toStr(ctx, x)
so that we can remove the global `ctx` from toString implementations.
Rename lld::toString (to lld:🧝:toStr) to simplify name lookup (we
have many llvm::toString and another lld::toString(const llvm::opt::Arg
&)).
2024-11-16 11:58:10 -08:00
Fangrui Song
09c2c5e1e9 [ELF] Replace error(...) with ErrAlways or Err
Most are migrated to ErrAlways mechanically.
In the future we should change most to Err.
2024-11-06 22:04:52 -08:00
Fangrui Song
861bd36bce [ELF] Pass Ctx & to Symbol::getVA 2024-10-19 20:32:58 -07:00
Fangrui Song
2c5dd03f55 [ELF] Pass Ctx & to check* 2024-10-13 11:14:40 -07:00
Fangrui Song
002ca63b3f [ELF] Pass Ctx & to (read|write)(16|64) 2024-10-13 10:47:18 -07:00
Fangrui Song
38dfcd9ac9 [ELF] Pass Ctx & to read32/write32 2024-10-13 10:37:47 -07:00
Fangrui Song
e1a073c9d9 [ELF] Change Ctx::target to unique_ptr (#111260)
also rename `TargetInfo *getXXXTargetInfo` to `void setXXXTargetInfo`
and change it to set `ctx.target`. This ensures that when `ctx` becomes
a local variable, two lld invocations will not reuse the function-local
static variable.

---

Reland after commit c35214c131c0bc7f54dc18ceb75c75cba89f58ee
([ELF] Initialize TargetInfo members).
2024-10-07 23:14:02 -07:00
Paul Kirth
2ca850111f
Revert "[ELF] Change Ctx::target to unique_ptr (#111260)" (#111449)
This patch seems to be breaking the windows build bots.
https://lab.llvm.org/buildbot/#/builders/63/builds/1953

We also see this in Fuchsia's Linux CI:
https://fxbug.dev/372010530

This reverts commit 4ec06b17435e32ece5e1aa2bc8a6d26dbf0bb312.
2024-10-07 15:43:01 -07:00
Fangrui Song
4ec06b1743
[ELF] Change Ctx::target to unique_ptr (#111260)
also rename `TargetInfo *getXXXTargetInfo` to `void setXXXTargetInfo`
and change it to set `ctx.target`. This ensures that when `ctx` becomes
a local variable, two lld invocations will not reuse the function-local
static variable.
2024-10-06 21:47:13 -07:00
Fangrui Song
cfd3289a1f [ELF] Pass Ctx & to some free functions 2024-10-06 19:36:21 -07:00
Fangrui Song
acb2b1e779 [ELF] Pass Ctx & to Symbols 2024-10-06 16:59:04 -07:00
Fangrui Song
2b5cb1bf62 [ELF] getRelocTargetVA: pass Ctx and Relocation. NFC 2024-10-06 16:34:09 -07:00
Fangrui Song
6d03a69034 [ELF] Pass Ctx & to Arch/ 2024-10-06 00:14:12 -07:00
Fangrui Song
04e69ad727 [ELF] Pass Ctx & to Thunk 2024-09-29 15:20:01 -07:00
Fangrui Song
c3e4998c0b [ELF] Pass Ctx & to TargetInfo. NFC 2024-09-28 21:48:26 -07:00
Fangrui Song
1dd9a565ea [ELF] Replace config-> with ctx.arg. in Arch/ 2024-09-21 12:03:18 -07:00
Fangrui Song
e88b7ff016 [ELF] Move InStruct into Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons.

llvm/Support/thread.h includes <thread>, which transitively includes
sstream in libc++ and uses ios_base::in, so we cannot use `#define in ctx.sec`.

`symtab, config, ctx` are now the only variables using
LLVM_LIBRARY_VISIBILITY.
2024-09-15 22:15:02 -07:00
Fangrui Song
c62fa63ff1 [ELF] Move mainPart to Ctx. NFC
Ctx was introduced in March 2022 as a more suitable place for such
singletons.
2024-08-21 20:08:11 -07:00
Fangrui Song
0cbe49eade [ELF] Implement getImplicitAddend and enable checkDynamicRelocsDefault for PPC32 2023-09-15 22:49:18 -07:00
Amy Kwan
698b45aa90 [PowerPC][lld] Account for additional X-Forms -> D-Form/DS-Forms load/stores when relaxing initial-exec to local-exec
D153645 added additional X-Form load/stores that can be generated for TLS accesses.
However, these added instructions have not been accounted for in lld. As a result,
lld does not know how to handle them and cannot relax initial-exec to local-exec
when the initial-exec sequence contains these additional load/stores.

This patch aims to resolve https://github.com/llvm/llvm-project/issues/64424.

Differential Revision: https://reviews.llvm.org/D158197
2023-08-31 08:45:10 -05:00
Fangrui Song
c3c9e45312 [ELF] Add InputSectionBase::{addRelocs,relocs} and GotSection::addConstant to add/access relocations
to prepare for changing `relocations` from a SmallVector to a pointer.

Also change the `isec` parameter in `addAddendOnlyRelocIfNonPreemptible` to `GotSection &`.
2022-11-21 04:12:03 +00:00
Fangrui Song
685b212553 [ELF] Make relocateAlloc target specific. NFC
The target-specific code (AArch64, PPC64) does not fit into the generic code and
adds virtual function overhead. Move relocateAlloc into ELF/Arch/ instead. This
removes many virtual functions (relaxTls*). In addition, this helps get rid of
getRelocTargetVA dispatch and many RelExpr members in the future.
2022-10-17 11:01:11 -07:00
Fangrui Song
767e64fc11 [ELF] Support some absolute/PC-relative relocation types for REL format
ctfconvert seems to use REL-format `.rel.SUNW_dof` for 32-bit architectures.
```
Binary file usr/ports/lang/perl5.32/work/perl-5.32.1/dtrace_mini.o matches
[alfredo.junior@dell-a ~/tmp/llvm-bug]$ readelf -r dtrace_mini.o

Relocation section (.rel.SUNW_dof):
r_offset r_info   r_type              st_value st_name
00000184 0000281a R_PPC_REL32         00000000 $dtrace1772974259.Perl_dtrace_probe_load
```

Support R_PPC_REL32 to fix `ld.lld: error: drti.c:(.SUNW_dof+0x4E4): internal linker error: cannot read addend for relocation R_PPC_REL32`.
While here, add some common relocation types for AArch64, PPC, and PPC64.
We perform minimum tests.

Reviewed By: adalava, arichardson

Differential Revision: https://reviews.llvm.org/D120535
2022-02-25 19:25:18 +00:00
Fangrui Song
53fc5d9b9a [ELF] Support R_PPC_NONE/R_PPC64_NONE in getImplicitAddend
Similar to f457863ae345d2635026501f5383e0e625869639
2022-02-04 15:13:37 -08:00
Fangrui Song
5d3bd7f360 [ELF] Move gotIndex/pltIndex/globalDynIndex to SymbolAux
to decrease sizeof(SymbolUnion) by 8 on ELF64 platforms.

Symbols needing such information are typically 1% or fewer (5134 out of 560520
when linking clang, 19898 out of 5550705 when linking chrome). Storing them
elsewhere can decrease memory usage and symbol initialization time.
There is a ~0.8% saving on max RSS when linking a large program.

Future direction:

* Move some of dynsymIndex/verdefIndex/versionId to SymbolAux
* Support mixed TLSDESC and TLS GD without increasing sizeof(SymbolUnion)

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D116281
2022-01-09 13:43:27 -08:00
Fangrui Song
baa3eb0dd9 [ELF] Change some non-null pointer parameters to references. NFC 2021-12-22 20:51:11 -08:00
Fangrui Song
bee5bc9075 [ELF] #undef PPC to support GCC powerpc32 build
GCC's powerpc32 port predefines `PPC` as a macro in GNU C++ mode in some configurations (Linux,
FreeBSD, and some others. See `builtin_define_std ("PPC"); ` in gcc/config/rs6000).

```
% powerpc-linux-gnu-g++ -E -dM -xc++ /dev/null -o - | grep -w PPC
#define PPC 1
```

Fixes https://bugs.gentoo.org/829599

Reviewed By: thesamesam

Differential Revision: https://reviews.llvm.org/D116017
2021-12-20 10:12:51 -08:00
Fangrui Song
d23fd8ae89 [ELF] Replace noneRel = R_*_NONE with static constexpr. NFC
All architectures define R_*_NONE to 0.
2021-09-25 15:16:44 -07:00
Fangrui Song
40cd4db442 [ELF] Default gotBaseSymInGotPlt to false (NFC for most architectures)
Most architectures use .got instead of .got.plt, so switching the default can
minimize customization.

This fixes an issue for SPARC V9 which uses .got .
AVR, AMDGPU, and MSP430 don't seem to use _GLOBAL_OFFSET_TABLE_.
2021-09-25 15:06:09 -07:00
Fangrui Song
3809f4ebab [ELF] Support R_PPC_ADDR24 (ba foo; bla foo) 2021-01-17 00:02:13 -08: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
Fangrui Song
50564ca075 [ELF] Rename adjustRelaxExpr to adjustTlsExpr and delete the unused data parameter. NFC
Reviewed By: psmith

Differential Revision: https://reviews.llvm.org/D91995
2020-11-25 09:00:55 -08: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
bd8cfe65f5fee4ad573adc2172359c9552e8cdc0 (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
00925aadb3 [ELF][PPC32] Fix canonical PLTs when the order does not match the PLT order
Reviewed By: Bdragon28

Differential Revision: https://reviews.llvm.org/D75394
2020-02-28 22:23:14 -08:00
Fangrui Song
70389be7a0 [ELF][PPC32] Support range extension thunks with addends
* Generalize the code added in D70637 and D70937. We should eventually remove the EM_MIPS special case.
* Handle R_PPC_LOCAL24PC the same way as R_PPC_REL24.

Reviewed By: Bdragon28

Differential Revision: https://reviews.llvm.org/D73424
2020-01-25 22:32:42 -08:00
Fangrui Song
837e8a9c0c [ELF][PPC32] Support canonical PLT
-fno-pie produces a pair of non-GOT-non-PLT relocations R_PPC_ADDR16_{HA,LO} (R_ABS) referencing external
functions.

```
lis 3, func@ha
la 3, func@l(3)
```

In a -no-pie/-pie link, if func is not defined in the executable, a canonical PLT entry (st_value>0, st_shndx=0) will be needed.
References to func in shared objects will be resolved to this address.
-fno-pie -pie should fail with "can't create dynamic relocation ... against ...", so we just need to think about -no-pie.

On x86, the PLT entry passes the JMP_SLOT offset to the rtld PLT resolver.
On x86-64: the PLT entry passes the JUMP_SLOT index to the rtld PLT resolver.
On ARM/AArch64: the PLT entry passes &.got.plt[n]. The PLT header passes &.got.plt[fixed-index]. The rtld PLT resolver can compute the JUMP_SLOT index from the two addresses.

For these targets, the canonical PLT entry can just reuse the regular PLT entry (in PltSection).

On PPC32: PltSection (.glink) consists of `b PLTresolve` instructions and `PLTresolve`. The rtld PLT resolver depends on r11 having been set up to the .plt (GotPltSection) entry.
On PPC64 ELFv2: PltSection (.glink) consists of `__glink_PLTresolve` and `bl __glink_PLTresolve`. The rtld PLT resolver depends on r12 having been set up to the .plt (GotPltSection) entry.

We cannot reuse a `b PLTresolve`/`bl __glink_PLTresolve` in PltSection as a canonical PLT entry. PPC64 ELFv2 avoids the problem by using TOC for any external reference, even in non-pic code, so the canonical PLT entry scenario should not happen in the first place.
For PPC32, we have to create a PLT call stub as the canonical PLT entry. The code sequence sets up r11.

Reviewed By: Bdragon28

Differential Revision: https://reviews.llvm.org/D73399
2020-01-25 17:56:37 -08:00
Fangrui Song
deb5819d62 [ELF] Rename relocateOne() to relocate() and pass Relocation to it
Symbol information can be used to improve out-of-range/misalignment diagnostics.
It also helps R_ARM_CALL/R_ARM_THM_CALL which has different behaviors with different symbol types.

There are many (67) relocateOne() call sites used in thunks, {Arm,AArch64}errata, PLT, etc.
Rename them to `relocateNoSym()` to be clearer that there is no symbol information.

Reviewed By: grimar, peter.smith

Differential Revision: https://reviews.llvm.org/D73254
2020-01-25 12:00:18 -08:00
Fangrui Song
f1dab29908 [ELF][PowerPC] Support R_PPC_COPY and R_PPC64_COPY
Reviewed By: Bdragon28, jhenderson, grimar, sfertile

Differential Revision: https://reviews.llvm.org/D73255
2020-01-24 09:06:20 -08:00
Fangrui Song
1e57038bf2 [ELF] Pass Relocation to relaxGot and relaxTls{GdToIe,GdToLe,LdToLe,IeToLe}
These functions call relocateOne(). This patch is a prerequisite for
making relocateOne() aware of `Symbol` (D73254).

Reviewed By: grimar, nickdesaulniers

Differential Revision: https://reviews.llvm.org/D73250
2020-01-23 10:39:25 -08:00
Fangrui Song
fb2944bd7f [ELF][PPC32] Implement IPLT code sequence for non-preemptible IFUNC
Similar to D71509 (EM_PPC64), on EM_PPC, the IPLT code sequence should
be similar to a PLT call stub. Unlike EM_PPC64, EM_PPC -msecure-plt has
small/large PIC model differences.

* -fpic/-fpie: R_PPC_PLTREL24 r_addend=0.  The call stub loads an address relative to `_GLOBAL_OFFSET_TABLE_`.
* -fPIC/-fPIE: R_PPC_PLTREL24 r_addend=0x8000. (A partial linked object
  file may have an addend larger than 0x8000.) The call stub loads an address relative to .got2+0x8000.

Just assume large PIC model for now. This patch makes:

  // clang -fuse-ld=lld -msecure-plt -fno-pie -no-pie a.c
  // clang -fuse-ld=lld -msecure-plt -fPIE -pie a.c
  #include <stdio.h>
  static void impl(void) { puts("meow"); }
  void thefunc(void) __attribute__((ifunc("resolver")));
  void *resolver(void) { return &impl; }
  int main(void) {
    thefunc();
    void (*theptr)(void) = &thefunc;
    theptr();
  }

work on Linux glibc. -fpie will crash because the compiler and the
linker do not agree on the value which r30 stores (_GLOBAL_OFFSET_TABLE_
vs .got2+0x8000).

Differential Revision: https://reviews.llvm.org/D71621
2019-12-29 22:42:53 -08:00
Fangrui Song
37b2808059 [ELF] writePlt, writeIplt: replace parameters gotPltEntryAddr and index with const Symbol &. NFC
PPC::writeIplt (IPLT code sequence, D71621) needs to access `Symbol`.

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D71631
2019-12-18 00:14:03 -08:00
Fangrui Song
891a8655ab [ELF] Add IpltSection
PltSection is used by both PLT and IPLT. The PLT section may have a
header while the IPLT section does not. Split off IpltSection from
PltSection to be clearer.

Unlike other targets, PPC64 cannot use the same code sequence for PLT
and IPLT. This helps make a future PPC64 patch (D71509) more isolated.

On EM_386 and EM_X86_64, when PLT is empty while IPLT is not, currently
we are inconsistent whether the PLT header is conceptually attached to
in.plt or in.iplt .  Consistently attach the header to in.plt can make
the -z retpolineplt logic simpler. It also makes `jmp` point to an
aesthetically better place for non-retpolineplt cases.

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D71519
2019-12-17 00:06:04 -08:00
Fangrui Song
90d195d026 [ELF] Delete relOff from TargetInfo::writePLT
This change only affects EM_386. relOff can be computed from `index`
easily, so it is unnecessarily passed as a parameter.

Both in.plt and in.iplt entries are written by writePLT. For in.iplt,
the instruction `push reloc_offset` will change because `index` is now
different. Fortunately, this does not matter because `push; jmp` is only
used by PLT. IPLT does not need the code sequence.

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D71518
2019-12-16 11:10:02 -08:00
Fangrui Song
bf535ac4a2 [ELF][AArch64] Support R_AARCH64_{CALL26,JUMP26} range extension thunks with addends
Fixes AArch64 part of PR40438

The current range extension thunk framework does not handle a relocation
relative to a STT_SECTION symbol with a non-zero addend, which may be
used by jumps/calls to local functions on some RELA targets (AArch64,
powerpc ELFv1, powerpc64 ELFv2, etc).  See PR40438 and the following
code for examples:

  // clang -target $target a.cc
  // .text.cold may be placed in a separate output section.
  // The distance between bar in .text.cold and foo in .text may be larger than 128MiB.
  static void foo() {}
  __attribute__((section(".text.cold"))) static int bar() { foo(); return
  0; }
  __attribute__((used)) static int dummy = bar();

This patch makes such thunks with addends work for AArch64. The target
independent part can be reused by PPC in the future.

On REL targets (ARM, MIPS), jumps/calls are not represented as
STT_SECTION + non-zero addend (see
MCELFObjectTargetWriter::needsRelocateWithSymbol), so they don't need
this feature, but we need to make sure this patch does not affect them.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D70637
2019-12-02 10:07:24 -08:00
Fangrui Song
bd8cfe65f5 [ELF] Wrap things in namespace lld { namespace elf {, NFC
This makes it clear `ELF/**/*.cpp` files define things in the `lld::elf`
namespace and simplifies `elf::foo` to `foo`.

Reviewed By: atanasyan, grimar, ruiu

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

llvm-svn: 373885
2019-10-07 08:31:18 +00:00
Fangrui Song
1542ff5282 [ELF][PPC] Improve error message for unknown relocations
Like rLLD354040.

Previously, for unrecognized relocation types, in -no-pie mode:

  foo.o: unrecognized reloc 256

In -pie/-shared mode:

  error: can't create dynamic relocation R_PPC_xxx against symbol: yyy in readonly segment

llvm-svn: 368964
2019-08-15 05:22:23 +00:00
Rui Ueyama
3837f4273f [Coding style change] Rename variables so that they start with a lowercase letter
This patch is mechanically generated by clang-llvm-rename tool that I wrote
using Clang Refactoring Engine just for creating this patch. You can see the
source code of the tool at https://reviews.llvm.org/D64123. There's no manual
post-processing; you can generate the same patch by re-running the tool against
lld's code base.

Here is the main discussion thread to change the LLVM coding style:
https://lists.llvm.org/pipermail/llvm-dev/2019-February/130083.html
In the discussion thread, I proposed we use lld as a testbed for variable
naming scheme change, and this patch does that.

I chose to rename variables so that they are in camelCase, just because that
is a minimal change to make variables to start with a lowercase letter.

Note to downstream patch maintainers: if you are maintaining a downstream lld
repo, just rebasing ahead of this commit would cause massive merge conflicts
because this patch essentially changes every line in the lld subdirectory. But
there's a remedy.

clang-llvm-rename tool is a batch tool, so you can rename variables in your
downstream repo with the tool. Given that, here is how to rebase your repo to
a commit after the mass renaming:

1. rebase to the commit just before the mass variable renaming,
2. apply the tool to your downstream repo to mass-rename variables locally, and
3. rebase again to the head.

Most changes made by the tool should be identical for a downstream repo and
for the head, so at the step 3, almost all changes should be merged and
disappear. I'd expect that there would be some lines that you need to merge by
hand, but that shouldn't be too many.

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

llvm-svn: 365595
2019-07-10 05:00:37 +00:00