This patch adds full support for linking SystemZ (ELF s390x) object
files. Support should be generally complete:
- All relocation types are supported.
- Full shared library support (DYNAMIC, GOT, PLT, ifunc).
- Relaxation of TLS and GOT relocations where appropriate.
- Platform-specific test cases.
In addition to new platform code and the obvious changes, there were a
few additional changes to common code:
- Add three new RelExpr members (R_GOTPLT_OFF, R_GOTPLT_PC, and
R_PLT_GOTREL) needed to support certain s390x relocations. I chose not
to use a platform-specific name since nothing in the definition of these
relocs is actually platform-specific; it is well possible that other
platforms will need the same.
- A couple of tweaks to TLS relocation handling, as the particular
semantics of the s390x versions differ slightly. See comments in the
code.
This was tested by building and testing >1500 Fedora packages, with only
a handful of failures; as these also have issues when building with LLD
on other architectures, they seem unrelated.
Co-authored-by: Tulio Magno Quites Machado Filho <tuliom@redhat.com>
The undefined symbol message suggests the source line when line number
information is available (see https://reviews.llvm.org/D31481).
When the undefined symbol is from a global variable, we won't get the
line information.
```
extern int undef;
namespace ns {
int *var[] = {
&undef
};
// DW_TAG_variable(DW_AT_decl_file/DW_AT_decl_line) is available while
// line number information is unavailable.
}
ld.lld: error: undefined symbol: undef
>>> referenced by undef-debug2.cc
>>> undef-debug2.o:(ns::var)
```
This patch utilizes `getEnclosingSymbol` to locate `var` and find
DW_TAG_variable for `var`:
```
ld.lld: error: undefined symbol: undef
>>> referenced by undef-debug2.cc:3 (/tmp/c/undef-debug2.cc:3)
>>> undef-debug2.o:(ns::var)
```
Integrating MTE globals on Android revealed a lot of cases where
libraries are built as both archives and DSOs, and they're linked into
fully static and dynamic executables respectively.
MTE globals doesn't work for fully static executables. They need a
dynamic loader to process the special R_AARCH64_RELATIVE relocation
semantics with the encoded offset. Fully static executables that had
out-of-bounds derived symbols (like 'int* foo_end = foo[16]') crash
under MTE globals w/ static executables. So, LLD in its current form
simply errors out when you try and compile a fully static executable
that has a single MTE global variable in it.
It seems like a much better idea to simply have LLD not do the special
work for MTE globals in fully static contexts, and to drop any
unnecessary metadata. This means that you can build archives with MTE
globals and link them into both fully-static and dynamic executables.
Code Object V2 has been deprecated for more than a year now. We can
safely remove it from LLVM.
- [clang] Remove support for the `-mcode-object-version=2` option.
- [lld] Remove/refactor tests that were still using COV2
- [llvm] Update AMDGPUUsage.rst
- Code Object V2 docs are left for informational purposes because those
code objects may still be supported by the runtime/loaders for a while.
- [AMDGPU] Remove COV2 emission capabilities.
- [AMDGPU] Remove `MetadataStreamerYamlV2` which was only used by COV2
- [AMDGPU] Update all tests that were still using COV2 - They are either
deleted or ported directly to code object v4 (as v3 is also planned to
be removed soon).
As per the ABI at
https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst,
this patch interprets the SHT_AARCH64_MEMTAG_GLOBALS_STATIC section,
which contains R_NONE relocations to tagged globals, and emits a
SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section, with the correct
DT_AARCH64_MEMTAG_GLOBALS and DT_AARCH64_MEMTAG_GLOBALSSZ dynamic
entries. This section describes, in a uleb-encoded stream, global memory
ranges that should be tagged with MTE.
We are also out of bits to spare in the LLD Symbol class. As a result,
I've reused the 'needsTocRestore' bit, which is a PPC64 only feature.
Now, it's also used for 'isTagged' on AArch64.
An entry in SHT_AARCH64_MEMTAG_GLOBALS_STATIC is practically a guarantee
from an objfile that all references to the linked symbol are through the
GOT, and meet correct alignment requirements. As a result, we go through
all symbols and make sure that, for all symbols $SYM, all object files
that reference $SYM also have a SHT_AARCH64_MEMTAG_GLOBALS_STATIC entry
for $SYM. If this isn't the case, we demote the symbol to being
untagged. Symbols that are imported from other DSOs should always be
fine, as they're GOT-referenced (and thus the GOT entry either has the
correct tag or not, depending on whether it's tagged in the defining DSO
or not).
Additionally hand-tested by building {libc, libm, libc++, libm, and libnetd}
on Android with some experimental MTE globals support in the
linker/libc.
Reviewed By: MaskRay, peter.smith
Differential Revision: https://reviews.llvm.org/D152921
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
This reverts commit c4fea39056.
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]
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
https://discourse.llvm.org/t/parallel-input-file-parsing/60164
initializeSymbols currently sets Defined::section and handles non-prevailing
COMDAT groups. Move the code to the parallel postParse to reduce work from the
single-threading code path and make parallel section initialization infeasible.
Postpone reporting duplicate symbol errors so that the messages have the
section information. (`Defined::section` is assigned in postParse and another
thread may not have the information).
* duplicated-synthetic-sym.s: BinaryFile duplicate definition (very rare) now
has no section information
* comdat-binding: `%t/w.o %t/g.o` leads to an undesired undefined symbol. This
is not ideal but we report a diagnostic to inform that this is unsupported.
(See release note)
* comdat-discarded-lazy.s: %tdef.o is unextracted. The new behavior (discarded
section error) makes more sense
* i386-comdat.s: switched to a better approach working around
.gnu.linkonce.t.__x86.get_pc_thunk.bx in glibc<2.32 for x86-32.
Drop the ancient no-longer-relevant workaround for __i686.get_pc_thunk.bx
Depends on D120640
Differential Revision: https://reviews.llvm.org/D120626
Fix a regression after aabe901d57 (`[ELF] Remove
one redundant computeBinding`): isLocal() does not indicate that the symbol is
originally local. For simplicity, just drop this optimization.
This reverts commit 640beb38e7.
That commit caused performance degradtion in Quicksilver test QS:sGPU and a functional test failure in (rocPRIM rocprim.device_segmented_radix_sort).
Reverting until we have a better solution to s_cselect_b64 codegen cleanup
Change-Id: Ibf8e397df94001f248fba609f072088a46abae08
Reviewed By: kzhuravl
Differential Revision: https://reviews.llvm.org/D115960
Change-Id: Id169459ce4dfffa857d5645a0af50b0063ce1105
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
(As I mentioned in https://reviews.llvm.org/D62609#1534158 ,
the condition for using bti c for executable can be loosened.)
In two cases the address of a PLT may escape:
* canonical PLT entry for a STT_FUNC
* non-preemptible STT_GNU_IFUNC which is converted to STT_FUNC
The first case can be detected with `needsPltAddr`.
The second case is not straightforward to detect because for the Relocations.cpp
created `directSym`, it's difficult to know whether the associated `sym` has
exercised the `!needsPlt(expr)` code path. Just use the conservative `isInIplt`
condition. A non-preemptible ifunc not referenced by non-GOT-generating
non-PLT-generating relocations will have an unneeded `bti c`, but the cost is acceptable.
The second case fixes a bug as well: a -shared link may have non-preemptible ifunc.
Before the patch we did not emit `bti c` and could be wrong if the PLT address escaped.
GNU ld doesn't handle the case: `relocation R_AARCH64_ADR_PREL_PG_HI21 against STT_GNU_IFUNC symbol 'ifunc2' isn't handled by elf64_aarch64_final_link_relocate` (https://sourceware.org/bugzilla/show_bug.cgi?id=28370)
For -shared, if BTI is enabled but PAC is disabled, the PLT entry size increases
from 16 to 24 because we have to select the PLT scheme early, but the cost is
acceptable.
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D110217
Copy relocation on a non-default version symbol is unsupported and can crash at
runtime. Fortunately there is a one-line fix which works for most cases:
ensure `getSymbolsAt` unconditionally returns `ss`.
If two non-default version symbols are defined at the same place and both
are copy relocated, our implementation will copy relocated them into different
addresses. The pointer inequality is very unlikely an issue. In GNU ld, copy
relocating version aliases seems to create more pointer inequality problems than
us.
(
In glibc, sys_errlist@GLIBC_2.2.5 sys_errlist@GLIBC_2.3 sys_errlist@GLIBC_2.4
are defined at the same place, but it is unlikely they are all copy relocated in
one executable. Even if so, the variables are read-only and pointer inequality
should not be a problem.
)
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D107535
After D77330, the comments are inconsistent with the disassembled code.
As the value of `far` has been changed, a thunk to reach it is now
generated, and target addresses of branch instructions are different
from what was initially expected.
The patch fixes that and makes the test closer to what it was originally.
Differential Revision: https://reviews.llvm.org/D104286
If we support local signature symbols (PR43094), these tests would fail.
When the support is added, new tests (local signature symbol specific) should be developed.
Fix PR49897: if `__real_foo` has the isUsedInRegularObj bit set, we need to
retain `foo` in .symtab, even if `foo` is undefined. The new behavior will match
GNU ld.
Before the patch, we produced an R_X86_64_JUMP_SLOT relocation referencing the
index 0 undefined symbol, which would be erroed by glibc
(see f96ff3c0f8).
While here, fix another bug: if `__wrap_foo` does not exist, its initial binding
should be `foo`'s.
For x86-64, D33100 added a diagnostic for local-exec TLS relocations referencing a preemptible symbol.
This patch generalizes it to non-preemptible symbols (see `-Bsymbolic` in `tls.s`)
on all targets.
Local-exec TLS relocations resolve to offsets relative to a fixed point within
the static TLS block, which are only meaningful for the executable.
With this change, `clang -fpic -shared -fuse-ld=bfd a.c` on the following example will be flagged for AArch64/ARM/i386/x86-64/RISC-V
```
static __attribute__((tls_model("local-exec"))) __thread long TlsVar = 42;
long bump() { return ++TlsVar; }
```
Note, in GNU ld, at least arm, riscv and x86's ports have the similar
diagnostics, but aarch64 and ppc64 do not error.
Differential Revision: https://reviews.llvm.org/D93331
The original tests have unneeded symbols and copy-relocation-zero-abs-addr.s
does not actually test anything.
Rewrite them and add copy-relocation-zero-addr.s instead.
Add --soname=b so that the address 0x203400 will be stable. (When linking an
executable with %t.so, the path %t.so will be recorded in the DT_NEEDED entry if
%t.so doesn't have DT_SONAME. .dynstr will have varying lengths on different
systems.)
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
It turns that gnu-ifunc-plt-i386.s and gnu-ifunc-plt.s tests are broken.
Initially they were implemented in D27581 and tested that `IRELATIVE` relocations
are placed after other relocations in `.rel.plt`.
Later, we started to place `IRELATIVE` relocations to `.rela.dyn` (D65651).
Also, at some point `.plt` was renamed to `.iplt` (D71520).
Now, `gnu-ifunc*` tests mentioned do not test what they intended to test initially:
they should test that `IRELATIVE` relocations are placed after other ones in
`.rela.dyn`. Also, comments needs to be updated accordingly after changes performed.
This patch updates them.
Differential revision: https://reviews.llvm.org/D85642
The PC Relative code allows for calls that are marked with the relocation
R_PPC64_REL24_NOTOC. This indicates that the caller does not have a valid TOC
pointer in R2 and does not require R2 to be restored after the call.
This patch is added to support local calls to callees tha also do not have a TOC.
Reviewed By: sfertile, MaskRay, stefanp
Differential Revision: https://reviews.llvm.org/D82816
The patch adds checking for various potential issues in parsing name
lookup tables and reporting them as recoverable errors, similarly as we
do for other tables.
Differential Revision: https://reviews.llvm.org/D83050
If there is no SHF_TLS section, there will be no PT_TLS and Out::tlsPhdr may be a nullptr.
If the symbol referenced by an R_TLS is lazy, we should treat the symbol as undefined.
Also reorganize tls-in-archive.s and tls-weak-undef.s . They do not test what they intended to test.
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
The test had a few style issues, and I noticed a hole in the coverage
(namely that the search order wasn't tested). Adding cases for the hole
in turn meant other cases weren't important.
The .so test case isn't important, since the code is shared code, so
I've removed it. Additionally, I've modified the usage of the "bar"
directive to show that an unneeded library must still be present, or the
link will fail, even though it isn't linked in.
Reviewed by: MaskRay, grimar
Differential Revision: https://reviews.llvm.org/D76851
Currently `yaml2obj` require `Offset` field in a relocation description.
There are many cases when `Offset` is insignificant in a context of a test case.
Making `Offset` optional allows to simplify our test cases.
This is what this patch does.
Also, with this patch `obj2yaml` does not dump a zero offset of a relocation.
Differential revision: https://reviews.llvm.org/D75608
Many of the debug line prologue errors are not inherently fatal. In most
cases, we can make reasonable assumptions and carry on. This patch does
exactly that. In the case of length problems, the approach of "assume
stated length is correct" is taken which means the offset might need
adjusting.
This is a relanding of b94191fe, fixing an LLD test and the LLDB build.
Reviewed by: dblaikie, labath
Differential Revision: https://reviews.llvm.org/D72158
LLD warns if it encounters malformed debug data when parsing line
information for an undefined reference. We only want to warn once.
This patch adds additional checking to make sure the warnings are
printed only once, both for variables within the same program and
variables in later line programs.
Reviewed by: grimar, MaskRay
Differential Revision: https://reviews.llvm.org/D71759