This patch introduces a skeleton JITLink ppc64 support header and ELF/ppc64
backend. No relocations are supported in this initial version, but given a
program requiring no relocations (e.g. one that just returns a constant value
from main) the new backend is able to construct a LinkGraph from a ppc64 ELF
relocatable object, and the llvm-jitlink tool is able to execute it.
This commit should also serve as a good example of how to introduce a JITLink
backend for a new architecture.
Reviewed By: sgraenitz, v.g.vassilev, vchuravy, nemanjai, jain98, MaskRay
Differential Revision: https://reviews.llvm.org/D148192
For linker relaxation (D149526), a new edge kind (`CallRelaxable`) was
introduced. However, this new kind was not taken into account by
`PerGraphGOTAndPLTStubsBuilder_ELF_riscv`. This patch fixes this.
Reviewed By: StephenFan
Differential Revision: https://reviews.llvm.org/D150957
These were previously re-enabled in d771f54107c, but had to be disabled again
in 2060a72b4d7 due to test failures.
This is a next step to landing https://reviews.llvm.org/D148192, which adds
a skeleton JITLink backend for PowerPC.
The fixes for those failures were (1) to explicitly specify IsLittleEndian =
true for the MachO YAML testcases, (2) disable some example tests for examples
that aren't supported on PowerPC yet, and (3) fixing the endianness of a
relocation read/write (for ELF R_AARCH64_TSTBR14) in RuntimeDyldELF.
This relocation is used for the 14-bit immediate in test and branch
instructions.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D150778
This is a follow-up to b71edfaa4ec3c998aadb35255ce2f60bba2940b0
since I forgot the lit.local.cfg files in that one.
Reformatting is done with `black`.
If you end up having problems merging this commit because you
have made changes to a python file, the best way to handle that
is to run git checkout --ours <yourfile> and then reformat it
with black.
If you run into any problems, post to discourse about it and
we will try to help.
RFC Thread below:
https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style
Reviewed By: barannikov88, kwk
Differential Revision: https://reviews.llvm.org/D150762
This patch is essentially an adaption of LLD's algorithm to JITLink.
Currently, only relaxing R_RISCV_CALL(_PLT) and R_RISCV_ALIGN is
implemented, other relocations can follow later.
From a high level, the algorithm works as follows. In the first phase
(relaxBlock), we iteratively try to relax all instructions that have a
R_RISCV_RELAX relocation:
- If, based on the current symbol values, an instruction sequence can be
relaxed (i.e., replaced by a shorter instruction), we record how many
bytes would be removed, the new instruction (Writes), and the new
relocation type (EdgeKinds).
- We keep track of the total number of bytes that got removed up to each
relocation in the RelocDeltas array. This is the cumulative sum of the
number of bytes removed for each relocation.
- Symbol values and sizes are updated based on the number of removed
bytes.
- If for any relocation, the current RelocDeltas value doesn't match the
one from the previous iteration, something changed and we need to run
another iteration as some symbols might now have different values.
In the second phase (finalizeBlockRelax), all code is moved based on
RelocDeltas, the relaxed instructions are rewritten using Writes, and
R_RISCV_ALIGN is handled (moving instructions to ensure alignment and
inserting the correct NOP-sequence if needed). Finally, edge kinds and
offsets are updated and all R_RISCV_RELAX and R_RISCV_ALIGN edges are
removed (they are not needed anymore for the fixup linking stage).
Linker relaxation is implemented as a pass and added to PreFixupPasses
in the default configuration on RISC-V.
Since linker relaxation removes instructions, the memory for blocks
should ideally be reallocated. However, I believe this is currently not
possible in JITLink. Therefore, relaxation directly modifies the memory
of blocks, reducing the number of instructions but not the size of
blocks. I'm not very familiar with JITLink's memory allocators so I
might be overlooking something here, though.
Note on testing: some of the tests rely on the debug output of
llvm-jitlink. The main reason for this is the verification of symbol
sizes (which may change due to relaxation). I don't believe this can be
done using jitlink-check checks alone.
Note that there is a slightly unrelated change that makes
Symbol::setOffset public to be able to update symbol offsets during
relaxation.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D149526
This relocation is used for the 19-bit immediate in conditional branch
and compare and branch instructions.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D149138
This patch ports PerfJITEventListener to a JITLink plugin, but adds unwind record support and drops debuginfo support temporarily. Debuginfo can be enabled in the future by providing a way to obtain a DWARFContext from a LinkGraph.
See D146060 for an experimental implementation that adds debuginfo parsing.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D146169
Adds support for the R_X86_64_GOTPC32 relocation, which is a 32-bit delta to
the global offset table.
Since the delta to the GOT doesn't actually require any GOT entries to exist
this commit adds an extra fallback path to the getOrCreateGOTSymbol function:
If the symbol is in the extenal symbols list but no entry exists then the
symbol is turned into an absolute symbol pointing to an arbitrary address in
the current graph's allocation (accessing this address via the symbol would be
illegal, but any access should have triggered creation of a GOT entry which
would prevent this fallback path from being taken in the first place).
This commit also updates the llvm-jitlink tool to scrape the addresses of the
absolute symbols in the graph so that the testcase can see the now-absolute
_GLOBAL_OFFSET_TABLE_ symbol.
Tests in test/ExecutionEngine/JITLink/AArch64 are for aarch64 only, so we don't
need to repeat 'aarch64' / 'arm64' in the individual test names.
Commit 8ad75c10372 made a similar change for the x86-64 tests.
Tests in test/ExecutionEngine/JITLink/X86 were for x86-64 only (never i386) so
it makes sense to name the test directory x86-64, and drop x86-64 from the
individual test names.
The various ADD/SUB relocations work by reading the current value the
relocation points to, transforming it, and then writing it back to
memory. While the current implementation writes the value back to
working memory, it reads the current value from the execution address of
the relocation. This causes at least wrong results, but often crashes,
when the addresses of working memory are not equal to execution
addresses. This patch fixes this by reading the current value from
working memory.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D147693
The original -show-graph option dumped the LinkGraph for all graphs loaded into
the session, but can make it difficult to see small graphs (e.g. reduced test
cases) among the surrounding larger files (especially the ORC runtime).
The new -show-graphs option takes a regex and dumps only those graphs matching
the regex. This allows testcases to specify exactly which graphs to dump.
This first version lays the foundations for AArch32 support in JITLink. ELFLinkGraphBuilder_aarch32 processes REL-type relocations and populates LinkGraphs from ELF object files for both big- and little-endian systems. The ArmCfg member controls subarchitecture-specific details throughout the linking process (i.e. it's passed to ELFJITLinker_aarch32).
Relocation types follow the ABI documentation's division into classes: Data (endian-sensitive), Arm (32-bit little-endian) and Thumb (2x 16-bit little-endian, "Thumb32" in the docs). The implementation of instruction encoding/decoding for relocation resolution is implemented symmetrically and is testable in isolation (see AArch32 category in JITLinkTests).
Callable Thumb functions are marked with a ThumbSymbol target-flag and stored in the LinkGraph with their real addresses. The thumb-bit is added back in when the owning JITDylib requests the address for such a symbol.
The StubsManager can generate (absolute) Thumb-state stubs for branch range extensions on v7+ targets. Proper GOT/PLT handling is not yet implemented.
This patch is based on the backend implementation in ez-clang and has just enough functionality to model the infrastructure and link a Thumb function `main()` that calls `printf()` to dump "Hello Arm!" on Armv7a. It was tested on Raspberry Pi with 32-bit Raspbian OS.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D144083
This first version lays the foundations for AArch32 support in JITLink. ELFLinkGraphBuilder_aarch32 processes REL-type relocations and populates LinkGraphs from ELF object files for both big- and little-endian systems. The ArmCfg member controls subarchitecture-specific details throughout the linking process (i.e. it's passed to ELFJITLinker_aarch32).
Relocation types follow the ABI documentation's division into classes: Data (endian-sensitive), Arm (32-bit little-endian) and Thumb (2x 16-bit little-endian, "Thumb32" in the docs). The implementation of instruction encoding/decoding for relocation resolution is implemented symmetrically and is testable in isolation (see AArch32 category in JITLinkTests).
Callable Thumb functions are marked with a ThumbSymbol target-flag and stored in the LinkGraph with their real addresses. The thumb-bit is added back in when the owning JITDylib requests the address for such a symbol.
The StubsManager can generate (absolute) Thumb-state stubs for branch range extensions on v7+ targets. Proper GOT/PLT handling is not yet implemented.
This patch is based on the backend implementation in ez-clang and has just enough functionality to model the infrastructure and link a Thumb function `main()` that calls `printf()` to dump "Hello Arm!" on Armv7a. It was tested on Raspberry Pi with 32-bit Raspbian OS.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D144083
This reapplies 57aeb305460406f7b822cfe6ab9fb4d730fc3b38, which was reverted in
f721fcb6ed0a186b8f146282467dd8420a5a36d0 due to buildbot failures.
The cause of the failure was missing support for R_AARCH64_ABS32, which was
added in fb1b9945be7657a3a25b727eaf0eeb3f74525210.
This relocation is commonly used in debug sections. Failure to handle it caused
the test failure in https://lab.llvm.org/buildbot/#/builders/197/builds/4272,
which forced the reversion, in f721fcb6ed0, of 57aeb305460 ("[JITLink][ELF]
Don't skip debug info sections by default"). This fix should allow us to
re-land 57aeb305460.
By default ELFLinkGraphBuilder will now create LinkGraph sections with NoAlloc
lifetime for debug info sections in the original object. Debug sections are not
kept alive by default, and will be dead-stripped unless some plugin marks them
as live in the pre-prune phase.
This speeds up section lookup by name.
This change was motivated by poor performance of a testcase while trying to fix
the NoAlloc lifetime patch that was originally landed as 2cc64df0bd6. The
NoAlloc lifetime patch causes ELF non-SHF_ALLOC sections to be given a JITLink
Section (previously they were skipped), and the
llvm/test/ExecutionEngine/JITLink/X86/ELF_shndex.s testcase creates > 64k
non-SHF_ALLOC sections, each of which now needs to be checked to ensure that its
name does not clash. Moving to a DenseMap allows us to implement this check
efficiently.
Allocation actions may run JIT'd code, which isn't permitted in -noexec mode.
Testcases that depend on actions running should be moved to the ORC runtime.
This commit adds support for PLT based relocations. Specifically -
1. It adds logic to create a `PLTTableManager` in the `buildTables_ELF_i386`
function, which is called as part of the post-prune JITLink passes. The `PLTTableManager`
handles creating pointer jump stubs and related GOT entries for position independent
code.
2. It also adds a pre-fixup pass to optimize away PLT based calls in position independent
code, when possible.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D142846
Index 0 is reserved for anonymous symbols, which can't have the N_EXT bit
set (since N_EXT means non-local scope, and non-local scope requires a name).
This implementation supports basic relocation types and adds EHFrame,
Got/Plt handling passes.
This patch also enables JIT support for LoongArch64.
With this patch, I successfully run hello.ll and simple_throw.ll
(which is generated from test-suite/SingleSource/Regression/C++/EH/simple_throw.cpp)
using the `lli` command with options `--jit-kind=orc --jit-linker=jitlink`.
Note: `hasJIT` property of LoongArch32 remains false as there is no
validation environment.
New changes: Since LoongArch does not support RuntimeDyld, JITLink is set
by default. Add a null-terminator to eh-frame sections. This should fix
the test failure on LoongArch bot.
(https://lab.llvm.org/staging/#/builders/236/builds/896)
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D141036
This implementation supports basic relocation types and adds EHFrame,
Got/Plt handling passes.
This patch also enables JIT support for LoongArch64.
With this patch, I successfully run hello.ll and simple_throw.ll
(which is generated from test-suite/SingleSource/Regression/C++/EH/simple_throw.cpp)
using the `lli` command with options `--jit-kind=orc --jit-linker=jitlink`.
Note: `hasJIT` property of LoongArch32 remains false as there is no
validation environment.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D141036
These are the compressed equivalents of the relocations R_RISCV_BRANCH
and R_RISCV_JAL with slightly more complex immediate handling.
Differential Revision: https://reviews.llvm.org/D140827
This CR modifies the existing 32 bit pcrel relocation test to
include the case when the relocation target might be present at
a smaller address than the address of the location that needs to be
patched.
Additionally, it adds a test for 16 bit absolute relocation.
Reviewed By: sunho
Differential Revision: https://reviews.llvm.org/D138372
This test caught my attention because it's the only one in JITLink that XFAILs. Running it in isolation showed that the output doesn't meet the CHECK-LINES, i.e. the block address didn't match:
```
error: CHECK-NEXT: expected string not found in input
CHECK-NEXT: block 0xfff02000 size = 0x00000001, align = 16, alignment-offset = 0
<stdin>:22:2: note: possible intended match here
block 0xfff01000 size = 0x00000001, align = 16, alignment-offset = 0
```
Though, that doesn't appear to be the reason the test XFAILs. What we really want to check here is that llvm-jitlink doesn't fail with a duplicate section error yet.
In order to avoid issues like this in the future we can match a placeholder to check for some valid address within the slab (64Kb == last 4 digits).
The patch also drops the duplicate -noexec argument, removes an empty RUN-line, fixes indentation and adds a newline at EOF.
Reviewed By: sunho
Differential Revision: https://reviews.llvm.org/D137148
This commit adds support for 32 bit absolute and pc relative relocations in
ELF/i386 objects, along with simple regression tests.
Reviewed By: sgraenitz, lhames
Differential Revision: https://reviews.llvm.org/D135523
Previously we stripped Weak flags from JITDylib symbol table entries once they
were resolved (there was no particularly good reason for this). Now we want to
retain them and query them when setting the Linkage on external symbols in
LinkGraphs during symbol resolution (this was the motivation for 75404e9ef88).
Making weak linkage of external definitions discoverable in the LinkGraph will
in turn allow future plugins to implement correct handling for them (by
recording locations that depend on exported weak definitions and pointing all
of these at one chosen definition at runtime).
R_RISCV_CALL/R_RISCV_CALL_PLT distinction isn't necessary. R_RISCV_CALL has been
deprecated as a resolution to
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/98 .
ld.lld and mold treat the two relocation types the same. GNU ld has a custom
handling for undefined weak functions which is unnecessary: calling an
unresolved undefined weak function is UB and GNU ld can handle the case without
a relocation error (such a function call is usually guarded by a zero value
check and should be allowed).
This patch assembles `call foo` to use R_RISCV_CALL_PLT instead of the
deprecated R_RISCV_CALL.
Note: the code generator still differentiates `call foo` and (maybe preemptible)
`call foo@plt`, but the difference is purely aesthetic.
Note: D105429 does not support R_RISCV_CALL_PLT correctly. Changed the test to
force R_RISCV_CALL for now.
Reviewed By: kito-cheng
Differential Revision: https://reviews.llvm.org/D132530
This patch updates MachOLinkGraphBuilder to honor the MH_SUBSECTIONS_VIA_SYMBOLS
flag. Prior to this patch we assumed MH_SUBSECTIONS_VIA_SYMBOLS, but never
checked the flag.
If MH_SUBSECTIONS_VIA_SYMBOLS is set (the default for MachO output on modern
compilers) then MachOLinkGraphBuilder will break MachO section content into
jitlink::Blocks on symbol boundaries. (This is how JITLink has always handled
MachO sections previously).
If MH_SUBSECTIONS_VIA_SYMBOLS is not set then MachOLinkGraphBuilder will create
a single jitlink::Block for each MachO section.
Existing hand-written testcases that were _not_ using the
.subsections_via_symbols directive are updated to use it. A new testcase for
non-subsections-via-symbols behavior is included.
I (lhames) accidentally pushed 5f300397c6ae8fa7ca3547ec2b7a3cd844f3ed59 on
Kshitij Jain's behalf without updating the patch author first (my apologies
Kshitij!).
Re-applying with correct authorship.
https://reviews.llvm.org/D131347