84 Commits

Author SHA1 Message Date
Kazu Hirata
732bccb8c1 Use StringRef::{starts,ends}_with (NFC)
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
2023-12-14 07:53:20 -08:00
Amilendra Kodithuwakku
9acbab60e5 [LLD][ELF] Cortex-M Security Extensions (CMSE) Support
This commit provides linker support for Cortex-M Security Extensions (CMSE).
The specification for this feature can be found in ARM v8-M Security Extensions:
Requirements on Development Tools.

The linker synthesizes a security gateway veneer in a special section;
`.gnu.sgstubs`, when it finds non-local symbols `__acle_se_<entry>` and `<entry>`,
defined relative to the same text section and having the same address. The
address of `<entry>` is retargeted to the starting address of the
linker-synthesized security gateway veneer in section `.gnu.sgstubs`.

In summary, the linker translates input:

```
    .text
  entry:
  __acle_se_entry:
    [entry_code]

```
into:

```
    .section .gnu.sgstubs
  entry:
    SG
    B.W __acle_se_entry

    .text
  __acle_se_entry:
    [entry_code]
```

If addresses of `__acle_se_<entry>` and `<entry>` are not equal, the linker
considers that `<entry>` already defines a secure gateway veneer so does not
synthesize one.

If `--out-implib=<out.lib>` is specified, the linker writes the list of secure
gateway veneers into a CMSE import library `<out.lib>`. The CMSE import library
will have 3 sections: `.symtab`, `.strtab`, `.shstrtab`. For every secure gateway
veneer <entry> at address `<addr>`, `.symtab` contains a `SHN_ABS` symbol `<entry>` with
value `<addr>`.

If `--in-implib=<in.lib>` is specified, the linker reads the existing CMSE import
library `<in.lib>` and preserves the entry function addresses in the resulting
executable and new import library.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D139092
2023-07-06 11:34:07 +01:00
John Brawn
5421ab4625 [lld][ARM] Add support for 16-bit thumb group relocations
This adds support for the following relocations:
 * R_ARM_THM_ALU_ABS_G0_NC
 * R_ARM_THM_ALU_ABS_G1_NC
 * R_ARM_THM_ALU_ABS_G2_NC
 * R_ARM_THM_ALU_ABS_G3
as defined in:
https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#5615static-thumb16-relocations

Differential Revision: https://reviews.llvm.org/D153407
2023-06-23 13:43:04 +01:00
Simi Pallipurath
f146763e07 Revert "Revert "[lld][Arm] Big Endian - Byte invariant support.""
This reverts commit d8851384c6ac2a1cea15e05228dbde5f13654e23.

Reason: Applied the fix for the Asan buildbot failures.
2023-06-22 16:10:18 +01:00
Mitch Phillips
cd116e0460 Revert "Revert "Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support"""
This reverts commit 9246df7049b0bb83743f860caff4221413c63de2.

Reason: This patch broke the UBSan buildbots. See more information in
the original phabricator review: https://reviews.llvm.org/D139092
2023-06-22 14:33:57 +02:00
Amilendra Kodithuwakku
9246df7049 Revert "Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support""
This reverts commit a685ddf1d104b3ce9d53cf420521f5aaff429630.

This relands Arm CMSE support (D139092) and fixes the GCC build bot errors.
2023-06-21 22:27:13 +01:00
Amilendra Kodithuwakku
a685ddf1d1 Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support"
This reverts commit c4fea3905617af89d1ad87319893e250f5b72dd6.

I am reverting this for now until I figure out how to fix
the build bot errors and warnings.

Errors:
llvm-project/lld/ELF/Arch/ARM.cpp:1300:29: error: expected primary-expression before ‘>’ token
 osec->writeHeaderTo<ELFT>(++sHdrs);

Warnings:
llvm-project/lld/ELF/Arch/ARM.cpp:1306:31: warning: left operand of comma operator has no effect [-Wunused-value]
2023-06-21 16:13:44 +01:00
Amilendra Kodithuwakku
c4fea39056 [LLD][ELF] Cortex-M Security Extensions (CMSE) Support
This commit provides linker support for Cortex-M Security Extensions (CMSE).
The specification for this feature can be found in ARM v8-M Security Extensions:
Requirements on Development Tools.

The linker synthesizes a security gateway veneer in a special section;
`.gnu.sgstubs`, when it finds non-local symbols `__acle_se_<entry>` and `<entry>`,
defined relative to the same text section and having the same address. The
address of `<entry>` is retargeted to the starting address of the
linker-synthesized security gateway veneer in section `.gnu.sgstubs`.

In summary, the linker translates input:

```
    .text
  entry:
  __acle_se_entry:
    [entry_code]

```
into:

```
    .section .gnu.sgstubs
  entry:
    SG
    B.W __acle_se_entry

    .text
  __acle_se_entry:
    [entry_code]
```

If addresses of `__acle_se_<entry>` and `<entry>` are not equal, the linker
considers that `<entry>` already defines a secure gateway veneer so does not
synthesize one.

If `--out-implib=<out.lib>` is specified, the linker writes the list of secure
gateway veneers into a CMSE import library `<out.lib>`. The CMSE import library
will have 3 sections: `.symtab`, `.strtab`, `.shstrtab`. For every secure gateway
veneer <entry> at address `<addr>`, `.symtab` contains a `SHN_ABS` symbol `<entry>` with
value `<addr>`.

If `--in-implib=<in.lib>` is specified, the linker reads the existing CMSE import
library `<in.lib>` and preserves the entry function addresses in the resulting
executable and new import library.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D139092
2023-06-21 14:47:34 +01:00
Simi Pallipurath
d8851384c6 Revert "[lld][Arm] Big Endian - Byte invariant support."
This reverts commit 8cf8956897ce9bca3176c6339077b1ca17b27abc.
2023-06-20 17:27:44 +01:00
Simi Pallipurath
8cf8956897 [lld][Arm] Big Endian - Byte invariant support.
Arm has BE8 big endian configuration called a byte-invariant(every byte has the same address on little and big-endian systems).

When in BE8 mode:
  1. Instructions are big-endian in relocatable objects but
     little-endian in executables and shared objects.
  2. Data is big-endian.
  3. The data encoding of the ELF file is ELFDATA2MSB.

To support BE8 without an ABI break for relocatable objects,the linker takes on the responsibility of changing the endianness of instructions. At a high level the only difference between BE32 and BE8 in the linker is that for BE8:
  1. The linker sets the flag EF_ARM_BE8 in the ELF header.
  2. The linker endian reverses the instructions, but not data.

This patch adds BE8 big endian support for Arm. To endian reverse the instructions we'll need access to the mapping symbols. Code sections can contain a mix of Arm, Thumb and literal data. We need to endian reverse Arm instructions as words, Thumb instructions
as half-words and ignore literal data.The only way to find these transitions precisely is by using mapping symbols. The instruction reversal will need to take place after relocation. For Arm BE8 code sections (Section has SHF_EXECINSTR flag ) we inserted a step after relocation to endian reverse the instructions. The implementation strategy i have used here is to write all sections BE32  including SyntheticSections then endian reverse all code in InputSections via mapping symbols.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D150870
2023-06-20 14:08:21 +01:00
Simi Pallipurath
2f68ddc604 [lld][ARM][2/3]Big Endian support - Word invariant support
Changes:
 - Adding BE32 big endian Support for Arm.
 - Replace the writele and readle with their endian-aware versions.
 - Adding test cases for the big-endian be32 arm configuration.

     Patch by: Milosz Plichta. This patch merges all the changes from
     this patch https://reviews.llvm.org/D140203 as well.

Reviewed By: peter.smith, MaskRay

Differential Revision: https://reviews.llvm.org/D140202
2023-03-29 10:21:00 +01:00
Simi Pallipurath
674f094d85 [lld][ARM][NFCI][1/3]Big Endian support - Removing assumptions
Change:
 - Replacing the memcpy that assume little endian with the endian-aware write.

Shouldn't affect the output for now, just a prerequisite for the next patches.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D140201
2023-02-15 11:42:49 +00:00
Kazu Hirata
55e2cd1609 Use llvm::count{lr}_{zero,one} (NFC) 2023-01-28 12:41:20 -08:00
Ties Stuij
62c605771a [lld][ARM] support absolute thunks for Armv4T Thumb and interworking
changes:
- BLX: The Arm architecture versions that support the branch and link
  instruction (BLX), can rewrite BLs in place when a state change from Arm<->Thumb
  is required. Armv4T does not have BLX and so needs thunks for state changes.
- v4T Thumb long branches needed their own thunk. We could have used the v6M
  implementation, but v6M doesn't have Arm state and must resolve to rather
  inefficient stack reshuffling. We also can't reuse v7 thumb thunks as they use
  MOVV/MOVT, which wasn't available yet for v4T.
- Remove the `lack of BLX' warning. LLVM only supports Arm Architecture versions
  upwards of v4, which we now all support in LLD.
- renamed existing thunks to better reflect their use:
  ARMV5ABSLongThunk -> ARMV5LongLdrPcThunk,
  ARMV5PILongThunk -> ARMV4PILongThunk
- removed isCompatibleWith method from ARMV5ABSLongThunk and ARMV5PILongThunk,
  as they were identical to the ARMThunk parent class implementation.

Support for (efficient) position independent thunks for v4T will be added in a
follow-up patch, including possible related thunk renaming and code comment
cleanup.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D139888
2022-12-21 11:04:32 +00:00
Fangrui Song
4c244b2833 [ELF] Fix .plt.got comments. NFC 2022-08-16 23:29:01 -07: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
b483ce1228 [ELF][ARM] Fix unneeded thunk for branches to hidden undefined weak
Similar to D123750 for AArch64.
2022-04-14 23:58:13 -07:00
Fangrui Song
27bb799095 [ELF] Clean up headers. NFC 2022-02-07 21:53:34 -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
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
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
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
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
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
Alex Richardson
35c5e564e6 [ELF] Check the Elf_Rel addends for dynamic relocations
There used to be many cases where addends for Elf_Rel were not emitted in
the final object file (mostly when building for MIPS64 since the input .o
files use RELA but the output uses REL). These cases have been fixed since,
but this patch adds a check to ensure that the written values are correct.
It is based on a previous patch that I added to the CHERI fork of LLD since
we were using MIPS64 as a baseline. The work has now almost entirely
shifted to RISC-V and Arm Morello (which use Elf_Rela), but I thought
it would be useful to upstream our local changes anyway.

This patch adds a (hidden) command line flag --check-dynamic-relocations
that can be used to enable these checks. It is also on by default in
assertions builds for targets that handle all dynamic relocations kinds
that LLD can emit in Target::getImplicitAddend(). Currently this is
enabled for ARM, MIPS, and I386.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D101450
2021-07-09 10:41:40 +01:00
Peter Smith
e35929e026 [LLD][ELF][ARM] Refactor inBranchRange to use addend for PC Bias
In AArch32 ARM, the PC reads two instructions ahead of the currently
executiing instruction. This evaluates to 8 in ARM state and 4 in
Thumb state. Branch instructions on AArch32 compensate for this by
subtracting the PC bias from the addend. For a branch to symbol this
will result in an addend of -8 in ARM state and -4 in Thumb state.

The existing ARM Target::inBranchRange function accounted for this
implict addend within the function meaning that if the addend were
to be taken into account by the caller then it would be double
counted. This complicates the interface for all Targets as callers
wanting to account for addends had to account for the ARM PC-bias.

In certain situations such as:
https://github.com/ClangBuiltLinux/linux/issues/1305
the PC-bias compensation code didn't match up. In particular
normalizeExistingThunk() didn't put the PC-bias back in as Arm
thunks did not store the addend.

The simplest fix for the problem is to add the PC bias in
normalizeExistingThunk when restoring the addend. However I think
it is worth refactoring the Arm inBranchRange implementation so
that fewer calls to getPCBias are needed for other Targets. I
wasn't able to remove getPCBias completely but hopefully the
Relocations.cpp code is simpler now.

In principle a test could be written to replicate the linux kernel
build failure but I wasn't able to reproduce with a small example
that I could build up from scratch.

Fixes https://github.com/ClangBuiltLinux/linux/issues/1305

Differential Revision: https://reviews.llvm.org/D97550
2021-03-02 11:02:33 +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
Fangrui Song
c1a5f73a4a [ELF][ARM] Represent R_ARM_LDO32 as R_DTPREL instead of R_ABS
Follow-up to D82899. Note, we need to disable R_DTPREL relaxation
because ARM psABI does not define TLS relaxation.

Reviewed By: grimar, psmith

Differential Revision: https://reviews.llvm.org/D83138
2020-07-06 09:47:53 -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
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
Tobias Hieta
87383e408d [ELF][ARM] Increase default max-page-size from 4096 to 6536
See http://lists.llvm.org/pipermail/llvm-dev/2020-April/140549.html

For the record, GNU ld changed to 64k max page size in 2014
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=7572ca8989ead4c3425a1500bc241eaaeffa2c89
"[RFC] ld/ARM: Increase maximum page size to 64kB"

Android driver forced 4k page size in AArch64 (D55029) and ARM (D77746).

A binary linked with max-page-size=4096 does not run on a system with a
higher page size configured. There are some systems out there that do
this and it leads to the binary getting `Killed!` by the kernel.

In the non-linker-script cases, when linked with -z noseparate-code
(default), the max-page-size increase should not cause any size
difference. There may be some VMA usage differences, though.

Reviewed By: psmith, MaskRay

Differential Revision: https://reviews.llvm.org/D77330
2020-04-18 08:19:45 -07:00
Peter Smith
28b172e341 [LLD][ELF][ARM] Implement ARM pc-relative relocations for ADR and LDR
The R_ARM_ALU_PC_G0 and R_ARM_LDR_PC_G0 relocations are used by the
ADR and LDR pseudo instructions, and are the basis of the group
relocations that can load an arbitrary constant via a series of add, sub
and ldr instructions.

The relocations need to be obtained via the .reloc directive.

R_ARM_ALU_PC_G0 is much more complicated as the add/sub instruction uses
a modified immediate encoding of an 8-bit immediate rotated right by an
even 4-bit field. This means that the range of representable immediates
is sparse. We extract the encoding and decoding functions for the modified
immediate from llvm/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h as
this header file is not accessible from LLD. Duplication of code isn't
ideal, but as these are well-defined mathematical functions they are
unlikely to change.

Differential Revision: https://reviews.llvm.org/D75349
2020-04-08 12:43:44 +01:00
Peter Smith
6b035b607f [LLD][ELF][ARM] Implement Thumb pc-relative relocations for adr and ldr
MC will now output the R_ARM_THM_PC8, R_ARM_THM_PC12 and
R_ARM_THM_PREL_11_0 relocations. These are short-ranged relocations that
are used to implement the adr rd, literal and ldr rd, literal pseudo
instructions.

The instructions use a new RelExpr called R_ARM_PCA in order to calculate
the required S + A - Pa expression, where Pa is AlignDown(P, 4) as the
instructions add their immediate to AlignDown(PC, 4). We also do not want
these relocations to generate or resolve against a PLT entry as the range
of these relocations is so short they would never reach.

The R_ARM_THM_PC8 has a special encoding convention for the relocation
addend, the immediate field is unsigned, yet the addend must be -4 to
account for the Thumb PC bias. The ABI (not the architecture) uses the
convention that the 8-byte immediate of 0xff represents -4.

Differential Revision: https://reviews.llvm.org/D75042
2020-02-28 11:29:29 +00:00
Tamas Petz
6e326882da [LLD][ELF][ARM] Fix support for SBREL type relocations
With this patch lld recognizes ARM SBREL relocations.
R_ARM*_MOVW_BREL relocations are not tested because they are not used.

Patch by Tamas Petz

Differential Revision: https://reviews.llvm.org/D74604
2020-02-19 10:07:46 +00:00
Peter Smith
29c1361557 [LLD][ELF][ARM] Do not substitute BL/BLX for non STT_FUNC symbols.
Recommit of 0b4a047bfbd11fe1f5abda8da0e2391c1918162a
(reverted in c29003813ab9bd6ea7b6de40ea8f1fe21979f13f) to incorporate
subsequent fix and add a warning when LLD's interworking behavior has
changed.

D73474 disabled the generation of interworking thunks for branch
relocations to non STT_FUNC symbols. This patch handles the case of BL and
BLX instructions to non STT_FUNC symbols. LLD would normally look at the
state of the caller and the callee and write a BL if the states are the
same and a BLX if the states are different.

This patch disables BL/BLX substitution when the destination symbol does
not have type STT_FUNC. This brings our behavior in line with GNU ld which
may prevent difficult to diagnose runtime errors when switching to lld.

This change does change how LLD handles interworking of symbols that do not
have type STT_FUNC from previous versions including the 10.0 release. This
brings LLD in line with ld.bfd but there may be programs that have not been
linked with ld.bfd that depend on LLD's previous behavior. We emit a warning
when the behavior changes.

A summary of the difference between 10.0 and 11.0 is that for symbols
that do not have a type of STT_FUNC LLD will not change a BL to a BLX or
vice versa. The table below enumerates the changes
| relocation     | STT_FUNC | bit(0) | in  | 10.0- out | 11.0+ out |
| R_ARM_CALL     | no       | 1      | BL  | BLX       | BL        |
| R_ARM_CALL     | no       | 0      | BLX | BL        | BLX       |
| R_ARM_THM_CALL | no       | 1      | BLX | BL        | BLX       |
| R_ARM_THM_CALL | no       | 0      | BL  | BLX       | BL        |

Differential Revision: https://reviews.llvm.org/D73542
2020-02-13 09:40:21 +00:00
Nico Weber
c29003813a Revert "[LLD][ELF][ARM] Do not substitute BL/BLX for non STT_FUNC symbols."
There are still problems after the fix in
"[ELF][ARM] Fix regression of BL->BLX substitution after D73542"
so let's revert to get trunk back to green while we investigate.
See https://reviews.llvm.org/D73542

This reverts commit 5461fa2b1fcfcfcd8e28e3ac3383d2245d5d90bf.
This reverts commit 0b4a047bfbd11fe1f5abda8da0e2391c1918162a.
2020-02-07 08:55:52 -05:00
Fangrui Song
5461fa2b1f [ELF][ARM] Fix regression of BL->BLX substitution after D73542
D73542 made a typo (`rel.type == R_PLT_PC`; should be `rel.expr`) and introduced a regression:
BL->BLX substitution was disabled when the target symbol is preemptible
(expr is R_PLT_PC).

The two added bl instructions in arm-thumb-interwork-shared.s check that
we patch BL to BLX.

Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=1047531
2020-02-05 14:09:14 -08:00
Peter Smith
0b4a047bfb [LLD][ELF][ARM] Do not substitute BL/BLX for non STT_FUNC symbols.
D73474 disabled the generation of interworking thunks for branch
relocations to non STT_FUNC symbols. This patch handles the case of BL and
BLX instructions to non STT_FUNC symbols. LLD would normally look at the
state of the caller and the callee and write a BL if the states are the
same and a BLX if the states are different.

This patch disables BL/BLX substitution when the destination symbol does
not have type STT_FUNC. This brings our behavior in line with GNU ld which
may prevent difficult to diagnose runtime errors when switching to lld.

Differential Revision: https://reviews.llvm.org/D73542
2020-01-29 11:42:25 +00:00
Peter Smith
4f38ab250f [LLD][ELF][ARM] Do not insert interworking thunks for non STT_FUNC symbols
ELF for the ARM architecture requires linkers to provide
interworking for symbols that are of type STT_FUNC. Interworking for
other symbols must be encoded directly in the object file. LLD was always
providing interworking, regardless of the symbol type, this breaks some
programs that have branches from Thumb state targeting STT_NOTYPE symbols
that have bit 0 clear, but they are in fact internal labels in a Thumb
function. LLD treats these symbols as ARM and inserts a transition to Arm.

This fixes the problem for in range branches, R_ARM_JUMP24,
R_ARM_THM_JUMP24 and R_ARM_THM_JUMP19. This is expected to be the vast
majority of problem cases as branching to an internal label close to the
function.

There is at least one follow up patch required.
- R_ARM_CALL and R_ARM_THM_CALL may do interworking via BL/BLX
  substitution.

In theory range-extension thunks can be altered to not change state when
the symbol type is not STT_FUNC. I will need to check with ld.bfd to see if
this is the case in practice.

Fixes (part of) https://github.com/ClangBuiltLinux/linux/issues/773

Differential Revision: https://reviews.llvm.org/D73474
2020-01-28 11:54:18 +00:00
Peter Smith
3238b03c19 [LLD][ELF][ARM] clang-format function signature [NFC]
ARM::needsThunk had gone over 80 characters, run clang-format over it to
prevent it wrapping.
2020-01-28 11:54:18 +00: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
bec1b55c64 [ELF] Delete the RelExpr member R_HINT. NFC
R_HINT is ignored like R_NONE. There are no strong reasons to keep
R_HINT. The largest RelExpr member R_RISCV_PC_INDIRECT is 60 now.

Differential Revision: https://reviews.llvm.org/D71822
2020-01-14 10:56: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
47cfe8f321 [ELF] Fix variable names in comments after VariableName -> variableName change
Also fix some typos.

llvm-svn: 366181
2019-07-16 05:50:45 +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
Fangrui Song
ffed2c96d9 [ELF][ARM] Merge handleARMTlsRelocation() into handleTlsRelocation()
ARM and RISC-V do not support TLS relaxations. However, for General
Dynamic and Local Dynamic models, if we are producing an executable and
the symbol is non-preemptable, we know it must be defined and the
R_ARM_TLS_DTPMOD32/R_RISCV_TLS_DTPMOD{32,64} dynamic relocation can be
omitted because it is always 1. This may be necessary for static linking
as DTPMOD may not be expected at load time.

Merge handleARMTlsRelocation() into handleTlsRelocation(). This requires
more logic to R_TLSGD_PC and R_TLSLD_PC. Because we use SymbolicRel to
resolve the relocation at link time, R_ARM_TLS_DTPMOD32 can be deleted
from relocateOne(). It cannot be used as a static relocation type.

As a bonus, the additional logic in R_TLSGD_PC code can be shared by the
TLS support for RISC-V (D63220).

Reviewed By: ruiu

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

llvm-svn: 363927
2019-06-20 13:53:11 +00:00