Commit Graph

69 Commits

Author SHA1 Message Date
Steven Wu 091e364866 [JITLink][ELF] Support duplicated section names from object file
ELF object files can contain duplicated sections (thus section symbols
as well), espeically when comdats/section groups are present. This patch
adds support for generating LinkGraph from object files that have
duplicated section names. This is the first step to properly model
comdats/section groups.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D114753
2022-01-18 08:38:28 -08:00
Lang Hames 118e953b18 Re-apply "[JITLink] Update JITLink to use ExecutorAddr rather... " with fixes.
This re-applies 133f86e954, which was reverted in
c5965a411c while I investigated bot failures.

The original failure contained an arithmetic conversion think-o (on line 419 of
EHFrameSupport.cpp) that could cause failures on 32-bit platforms. The issue
should be fixed in this patch.
2022-01-06 17:22:21 +11:00
Lang Hames c5965a411c Revert "[JITLink] Update JITLink to use ExecutorAddr rather than..."
This reverts commit 133f86e954 while I investigate
the bot failures at https://lab.llvm.org/buildbot#builders/186/builds/3370.
2022-01-06 15:20:21 +11:00
Lang Hames 133f86e954 [JITLink] Update JITLink to use ExecutorAddr rather than JITTargetAddress.
ExecutorAddr is the preferred representation for executor process addresses now.
2022-01-06 13:48:12 +11:00
Lang Hames 21562c03ed [JITLink][ELF][x86-64] Adjust addends for R_X86_64_PLT32 relocations.
R_X86_64_PLT32 explicitly represents the '-4' PC-adjustment in the relocation's
addend, but JITLink's x86_64::Branch32PCRel includes the PC-adjustment
implicitly. We have been zeroing the addend to account for the difference, but
this breaks for branches to non-zero offsets past labels. This patch updates the
relocation parsing code to unconditionally adjust the offset by '+4' instead.
For branches directly to labels the result is still 0, for branches to offsets
past labels the result is the correct addend for x86_64::Branch32PCRel.
2021-12-05 20:37:55 +11:00
Lang Hames c22b110612 [JITLink][ELF][x86-64] Use the right edge-naming function for debugging output.
Graph edges use the generic x86-64 edge set (the ELF specific edges are only
used during parsing).
2021-12-05 17:12:39 +11:00
Zarko Todorovski 59c84774d2 [NFC][llvm] Inclusive language: remove uses of sanity in llvm/lib/ExecutionEngine/
Reworded and removed code comments to avoid using `sanity check` and `sanity
test`.
2021-11-17 22:17:54 -05:00
Lang Hames cc3115cd1d [JITLink][x86-64] Lift GOT, PLT table managers into x86_64.h; reuse for MachO.
This lifts the global offset table and procedure linkage table builders out of
ELF_x86_64.h and into x86_64.h, renaming them with generic names
x86_64::GOTTableBuilder and x86_64::PLTTableBuilder. MachO_x86_64.cpp is updated
to use these classes instead of the older PerGraphGOTAndStubsBuilder tool.
2021-10-18 21:47:24 -07:00
Lang Hames bc03a9c066 Simplify the TableManager class and move it into a public header.
Moves visitEdge into the TableManager derivatives, replacing the fixEdgeKind
methods in those classes. The visitEdge method takes on responsibility for
updating the edge target, as well as its kind.
2021-10-18 18:20:33 -07:00
luxufan 849b36bf6f [JITLink][NFC] Add TableManager to replace PerGraph...Builder pass
This patch add a TableManager which reponsible for fixing edges that need entries to reference the target symbol and constructing such entries.

In the past, the PerGraphGOTAndPLTStubsBuilder pass was used to build GOT and PLT entry, and the PerGraphTLSInfoEntryBuilder pass was used to build TLSInfo entry. By generalizing the behavior of building entry, I added a TableManager which could be reused when built GOT, PLT and TLSInfo entries.

If this patch makes sense and can be accepted, I will apply the TableManager to other targets(MachO_x86_64, MachO_arm64, ELF_riscv), and delete the file PerGraphGOTAndPLTStubsBuilder.h

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D110383
2021-10-14 23:09:53 +08:00
Lang Hames 962a2479b5 Re-apply e50aea58d5, "Major JITLinkMemoryManager refactor". with fixes.
Adds explicit narrowing casts to JITLinkMemoryManager.cpp.

Honors -slab-address option in llvm-jitlink.cpp, which was accidentally
dropped in the refactor.

This effectively reverts commit 6641d29b70.
2021-10-11 21:39:00 -07:00
Lang Hames 6641d29b70 Revert "[JITLink][ORC] Major JITLinkMemoryManager refactor."
This reverts commit e50aea58d5 while I
investigate bot failures.
2021-10-11 19:23:41 -07:00
Lang Hames e50aea58d5 [JITLink][ORC] Major JITLinkMemoryManager refactor.
This commit substantially refactors the JITLinkMemoryManager API to: (1) add
asynchronous versions of key operations, (2) give memory manager implementations
full control over link graph address layout, (3) enable more efficient tracking
of allocated memory, and (4) support "allocation actions" and finalize-lifetime
memory.

Together these changes provide a more usable API, and enable more powerful and
efficient memory manager implementations.

To support these changes the JITLinkMemoryManager::Allocation inner class has
been split into two new classes: InFlightAllocation, and FinalizedAllocation.
The allocate method returns an InFlightAllocation that tracks memory (both
working and executor memory) prior to finalization. The finalize method returns
a FinalizedAllocation object, and the InFlightAllocation is discarded. Breaking
Allocation into InFlightAllocation and FinalizedAllocation allows
InFlightAllocation subclassses to be written more naturally, and FinalizedAlloc
to be implemented and used efficiently (see (3) below).

In addition to the memory manager changes this commit also introduces a new
MemProt type to represent memory protections (MemProt replaces use of
sys::Memory::ProtectionFlags in JITLink), and a new MemDeallocPolicy type that
can be used to indicate when a section should be deallocated (see (4) below).

Plugin/pass writers who were using sys::Memory::ProtectionFlags will have to
switch to MemProt -- this should be straightworward. Clients with out-of-tree
memory managers will need to update their implementations. Clients using
in-tree memory managers should mostly be able to ignore it.

Major features:

(1) More asynchrony:

The allocate and deallocate methods are now asynchronous by default, with
synchronous convenience wrappers supplied. The asynchronous versions allow
clients (including JITLink) to request and deallocate memory without blocking.

(2) Improved control over graph address layout:

Instead of a SegmentRequestMap, JITLinkMemoryManager::allocate now takes a
reference to the LinkGraph to be allocated. The memory manager is responsible
for calculating the memory requirements for the graph, and laying out the graph
(setting working and executor memory addresses) within the allocated memory.
This gives memory managers full control over JIT'd memory layout. For clients
that don't need or want this degree of control the new "BasicLayout" utility can
be used to get a segment-based view of the graph, similar to the one provided by
SegmentRequestMap. Once segment addresses are assigned the BasicLayout::apply
method can be used to automatically lay out the graph.

(3) Efficient tracking of allocated memory.

The FinalizedAlloc type is a wrapper for an ExecutorAddr and requires only
64-bits to store in the controller. The meaning of the address held by the
FinalizedAlloc is left up to the memory manager implementation, but the
FinalizedAlloc type enforces a requirement that deallocate be called on any
non-default values prior to destruction. The deallocate method takes a
vector<FinalizedAlloc>, allowing for bulk deallocation of many allocations in a
single call.

Memory manager implementations will typically store the address of some
allocation metadata in the executor in the FinalizedAlloc, as holding this
metadata in the executor is often cheaper and may allow for clean deallocation
even in failure cases where the connection with the controller is lost.

(4) Support for "allocation actions" and finalize-lifetime memory.

Allocation actions are pairs (finalize_act, deallocate_act) of JITTargetAddress
triples (fn, arg_buffer_addr, arg_buffer_size), that can be attached to a
finalize request. At finalization time, after memory protections have been
applied, each of the "finalize_act" elements will be called in order (skipping
any elements whose fn value is zero) as

((char*(*)(const char *, size_t))fn)((const char *)arg_buffer_addr,
                                     (size_t)arg_buffer_size);

At deallocation time the deallocate elements will be run in reverse order (again
skipping any elements where fn is zero).

The returned char * should be null to indicate success, or a non-null
heap-allocated string error message to indicate failure.

These actions allow finalization and deallocation to be extended to include
operations like registering and deregistering eh-frames, TLS sections,
initializer and deinitializers, and language metadata sections. Previously these
operations required separate callWrapper invocations. Compared to callWrapper
invocations, actions require no extra IPC/RPC, reducing costs and eliminating
a potential source of errors.

Finalize lifetime memory can be used to support finalize actions: Sections with
finalize lifetime should be destroyed by memory managers immediately after
finalization actions have been run. Finalize memory can be used to support
finalize actions (e.g. with extra-metadata, or synthesized finalize actions)
without incurring permanent memory overhead.
2021-10-11 19:12:42 -07:00
luxufan b384736b20 Revert "[JITLink][NFC] Add TableManager to replace PerGraph...Builder pass"
This reverts commit 50a278c2ae.
2021-10-06 21:34:18 +08:00
luxufan 50a278c2ae [JITLink][NFC] Add TableManager to replace PerGraph...Builder pass
This patch add a TableManager which reponsible for fixing edges that need entries to reference the target symbol and constructing such entries.

In the past, the PerGraphGOTAndPLTStubsBuilder pass was used to build GOT and PLT entry, and the PerGraphTLSInfoEntryBuilder pass was used to build TLSInfo entry. By generalizing the behavior of building entry, I added a TableManager which could be reused when built GOT, PLT and TLSInfo entries.

If this patch makes sense and can be accepted, I will apply the TableManager to other targets(MachO_x86_64, MachO_arm64, ELF_riscv), and delete the file PerGraphGOTAndPLTStubsBuilder.h

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D110383
2021-10-06 21:24:34 +08:00
Geoffrey Martin-Noble 01b097afd0
Fix bad merge the removed switch case
When https://reviews.llvm.org/D109520 was landed, it reverted the addition of this switch
case added in https://reviews.llvm.org/D109293. This caused `-Wswitch` failures (and
presumably broke the functionality added in the latter patch).
2021-09-20 10:58:58 -07:00
Stefan Gränitz 68914dc990 [JITLink] Adopt forEachRelocation() helper in ELF x86-64 backend (NFC)
Following D109516, this patch re-uses the new helper function for ELF relocation traversal in the x86-64 backend.

Reviewed By: StephenFan

Differential Revision: https://reviews.llvm.org/D109520
2021-09-20 15:46:41 +02:00
luxufan ff6069b891 [JITLink] Add initial native TLS support to ELFNix platform
This patch use the same way as the https://reviews.llvm.org/rGfe1fa43f16beac1506a2e73a9f7b3c81179744eb to handle the thread local variable.

It allocates 2 * pointerSize space in GOT to represent the thread key and data address. Instead of using the _tls_get_addr function, I customed a function __orc_rt_elfnix_tls_get_addr to get the address of thread local varible. Currently, this is a wip patch, only one TLS relocation R_X86_64_TLSGD is supported and I need to add the corresponding test cases.

To allocate the TLS  descriptor in GOT, I need to get the edge kind information in PerGraphGOTAndPLTStubBuilder, So I add a `Edge::Kind K` argument in some functions in PerGraphGOTAndPLTStubBuilder.h. If it is not suitable, I can think further to solve this problem.

Differential Revision: https://reviews.llvm.org/D109293
2021-09-13 14:35:49 +08:00
luxufan dda116bc3d [JITLink] Add support of R_X86_64_32S relocation
This patch supported the R_X86_64_32S relocation and add the Pointer32Signed generic edge kind.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D108446
2021-08-22 16:45:25 +08:00
luxufan a9095f005f [JITLink] Optimize GOTPCRELX Relocations
This patch optimize the GOTPCRELX Reloations, which is described in X86-64 psabi chapter B.2. And Not all optimization of this chapter is implemented.

1. Convert call and jmp has been implemented
2. Convert mov, but the optimization that when the symbol is defined in the lower 32-bit address space, memory operand in `mov` can be convertted into immediate operand has not been implemented.
3. Conver Test and Binop has not been implemented.

The new test file named ELF_got_plt_optimizations.s has been added, and I moved some test cases about optimization of got/plt from ELF_x86_64_small_pic_relocations.s to the new test file.

By referencing the lld, so, the optimization `Convert call and jmp` is not same as what psabi says, and I have explained it in the comment.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D108280
2021-08-19 10:30:22 +08:00
luxufan 4ec32375bc [JITLink] Unify x86-64 MachO and ELF 's optimize GOT/Stub function
This patch  unify optimizeELF_x86_64_GOTAndStubs and optimizeMachO_x86_64_GOTAndStubs into a pure optimize_x86_64_GOTAndStubs

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D108025
2021-08-15 00:33:09 +08:00
Lang Hames 27ea3f1607 [JITLink][x86-64] Rename *Relaxable edges to *REXRelaxable.
The existing relaxable edges all assume a REX prefix. ELF includes non-REX
relaxations, so rename these edges to make room for the new kinds.
2021-08-14 18:28:49 +10:00
Lang Hames 632135acae [JITLink][x86-64] Rename BranchPCRel32ToPtrJumpStub(Relaxable -> Bypassable).
ELF allows for branch optimizations other than bypass, so rename this edge kind
to avoid any confusion.
2021-08-14 17:49:31 +10:00
luxufan ee65938357 [JITLink] Update ELF_x86_64 's edge kind to generic edge kind
This patch uses a switch statement to map the ELF_x86_64's edge kind to generic edge kind, and merge the ELF_x86_64 's applyFixup function to the x86_64 's applyFixup function. Some edge kinds were not have corresponding generic edge kinds, so I added three generic edge kinds asa follows:
1. RequestGOTAndTransformToDelta64, which is similar to RequestGOTAndTransformToDelta32.

2. GOTDelta64. This generic kind is similar to Delta64, except the GOTDelta64 computes the delta relative to GOTSymbol

3. RequestGOTAndTransformToGOTDelta64. This edge kind was used to deal with ELF_x86_64's GOT64 edge kind, it request the fixGOTEdge function to change the target to GOT entry, and set the edge kind to generic edge kind GOTDelta64.

These added generic edge kinds may named haphazardly, or can't express its meaning well.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D107967
2021-08-13 12:53:54 +08:00
Lang Hames 8a241cd9c2 [JITLink][ELF][x86-64] Include relocation name in missing relocation errors.
This saves a level of manual table lookup for those of us who don't remember
ELF relocation numbers off the top of our heads.
2021-07-30 15:19:11 +10:00
Lang Hames 8e66fc4384 [JITLink][ELF] Move ELF section and symbol parsing into ELFLinkGraphBuilder.
Move architecture independent ELF parsing/graph-building code from
ELFLinkGraphBuilder_x86_64 to the ELFLinkGraphBuilder base class template.
2021-06-29 09:59:49 +10:00
Lang Hames aff57ff24a [JITLink][ELF] Add generic ELFLinkGraphBuilder template.
ELFLinkGraphBuilder<ELFT> will hold generic parsing and LinkGraph-building code
that can be shared between JITLink ELF backends for different architectures.

For now it's just a stub. The plan is to incrementally move functionality down
from ELFLinkGraphBuilder_x86_64 into the new template.
2021-06-26 21:37:33 +10:00
Lang Hames 82ad2b6e94 [JITLink] Enable creation and management of mutable block content.
This patch introduces new operations on jitlink::Blocks: setMutableContent,
getMutableContent and getAlreadyMutableContent. The setMutableContent method
will set the block content data and size members and flag the content as
mutable. The getMutableContent method will return a mutable copy of the existing
content value, auto-allocating and populating a new mutable copy if the existing
content is marked immutable. The getAlreadyMutableMethod asserts that the
existing content is already mutable and returns it.

setMutableContent should be used when updating the block with totally new
content backed by mutable memory. It can be used to change the size of the
block. The argument value should *not* be shared with any other block.

getMutableContent should be used when clients want to modify the existing
content and are unsure whether it is mutable yet.

getAlreadyMutableContent should be used when clients want to modify the existing
content and know from context that it must already be immutable.

These operations reduce copy-modify-update boilerplate and unnecessary copies
introduced when clients couldn't me sure whether the existing content was
mutable or not.
2021-05-24 22:09:36 -07:00
Lang Hames 0269a407f3 [JITLink] Switch from StringRef to ArrayRef<char>, add some generic x86-64 utils
Adds utilities for creating anonymous pointers and jump stubs to x86_64.h. These
are used by the GOT and Stubs builder, but may also be used by pass writers who
want to create pointer stubs for indirection.

This patch also switches the underlying type for LinkGraph content from
StringRef to ArrayRef<char>. This avoids any confusion when working with buffers
that contain null bytes in the middle like, for example, a newly added null
pointer content array. ;)
2021-03-30 21:07:24 -07:00
Lang Hames cc4ad2c540 [JITLink][ELF/x86-64] Add support for GOTOFF64 relocation. 2021-03-22 10:40:50 -07:00
Lang Hames fc36a511c6 [JITLink][ELF/x86-64] Add support for R_X86_64_GOTPC64 and R_X86_64_GOT64.
Start adding support for ELF x86-64 large code model, PIC relocations.
2021-03-21 21:52:54 -07:00
Lang Hames 0a74ec3299 [JITLink] Start laying the groundwork for ELF x86-64 large code model support.
Introduces DefineExternalSectionStartAndEndSymbols.h, which defines a template
for a JITLink pass that transforms external symbols meeting a user-supplied
predicate into defined symbols pointing at the start and end of a Section
identified by the predicate. JITLink.h is updated with a new makeAbsolute
function to support this pass.

Also renames BasicGOTAndStubsBuilder to PerGraphGOTAndPLTStubsBuilder -- the new
name better describes the intent of this GOT and PLT stubs builder, and will
help to distinguish it from future GOT and PLT stub builders that build entries
that may be shared between multiple graphs.
2021-03-21 20:56:47 -07:00
Lang Hames 209ceed745 [JITLink][ELF/x86-64] Add Delta32, NegDelta32, NegDelta64 support.
These were missing, but are used in eh-frame section support.
2021-03-21 20:15:40 -07:00
Lang Hames 86ec3fd9d9 [JITLink] Improve out-of-range error messages.
Switches all backends to use the makeTargetOutOfRangeError function from
JITLink.h.
2021-03-17 21:35:24 -07:00
Lang Hames ecf6466f01 [JITLink][MachO][x86-64] Introduce generic x86-64 support.
This patch introduces generic x86-64 edge kinds, and refactors the MachO/x86-64
backend to use these edge kinds. This simplifies the implementation of the
MachO/x86-64 backend and makes it possible to write generic x86-64 passes and
utilities.

The new edge kinds are different from the original set used in the MachO/x86-64
backend. Several edge kinds that were not meaningfully distinguished in that
backend (e.g. the PCRelMinusN edges) have been merged into single edge kinds in
the new scheme (these edge kinds can be reintroduced later if we find a use for
them). At the same time, new edge kinds have been introduced to convey extra
information about the state of the graph. E.g. The Request*AndTransformTo**
edges represent GOT/TLVP relocations prior to synthesis of the GOT/TLVP
entries, and the 'Relaxable' suffix distinguishes edges that are candidates for
optimization from edges which should be left as-is (e.g. to enable runtime
redirection).

ELF/x86-64 will be refactored to use these generic edges at some point in the
future, and I anticipate a similar refactor to create a generic arm64 support
header too.

Differential Revision: https://reviews.llvm.org/D98305
2021-03-15 15:43:07 -07:00
Lang Hames 4e30b20bdb [JITLink][ORC] Make the LinkGraph available to modifyPassConfig.
This makes the target triple, graph name, and full graph content available
when making decisions about how to populate the linker pass pipeline.

Also updates the LLJITWithObjectLinkingLayerPlugin example to show more
API use, including use of the API changes in this patch.
2021-03-12 18:42:51 -08:00
Lang Hames bcb53999a4 [JITLink] Add a null-terminator to eh-frame sections on ELF/x86-64.
__register_ehframes on Linux requires a null terminator to identify the end of
this section.
2021-03-09 22:16:11 -08:00
Lang Hames 1237d94871 [JITLink] Add support for STT_NOTYPE symbols to ELF/x86-64. 2021-03-09 20:40:24 -08:00
Kazu Hirata 910e2d1e57 [llvm] Use llvm::is_contained (NFC) 2021-02-14 08:36:20 -08:00
Lang Hames b3e0135a6f [JITLink][ELF/x86-64] When building PLT stub, use -4 offset for PCRel32.
This is required for ELF where PCRel32 doesn't implicitly subtract 4.

No test case yet: I haven't figured out a good way to test stub
generation -- this may required extensions to jitlink-check.
2021-01-26 23:51:58 +11:00
Lang Hames cda4d3d37f [JITLink] Re-apply 6884fbc2c4 (ELF eh support) with fix for broken test case. 2021-01-26 11:55:41 +11:00
Nico Weber f80782590c Revert "[JITLink] Enable exception handling for ELF."
This reverts commit 6884fbc2c4.
Breaks tests on Windows: http://45.33.8.238/win/31981/step_11.txt
2021-01-25 11:00:38 -05:00
Lang Hames 6884fbc2c4 [JITLink] Enable exception handling for ELF.
Adds the EHFrameSplitter and EHFrameEdgeFixer passes to the default JITLink
pass pipeline for ELF/x86-64, and teaches EHFrameEdgeFixer to handle some
new pointer encodings.

Together these changes enable exception handling (at least for the basic
cases that I've tested so far) for ELF/x86-64 objects loaded via JITLink.
2021-01-25 15:31:27 +11:00
Lang Hames 3b1f17ca54 [JITLink][ELF/x86-64] Add support for weak and hidden symbols. 2021-01-22 20:51:11 +11:00
Lang Hames f9b5f6937e [JITLink][ELF/x86-64] Range check 32-bit relocs.
Also switch to using little_<b> / ulittle_<b> types to write results for
consistency with MachO.
2021-01-22 15:59:19 +11:00
Lang Hames a817f46d50 [JITLink][ELF] Skip DWARF sections in ELF objects.
This matches current JITLink/MachO behavior and avoids processing currently
unsupported relocations.
2021-01-18 12:42:48 +11:00
Lang Hames 7b11f564dc [JITLink] Rename PostAllocationPasses to PreFixupPasses.
PreFixupPasses better reflects when these passes will run.

A future patch will (re)introduce a PostAllocationPasses list that will run
after allocation, but before JITLinkContext::notifyResolved is called to notify
the rest of the JIT about the resolved symbol addresses.
2021-01-11 18:33:50 +11:00
Lang Hames ec6b71df70 [JITLink][ORC] Enable creation / linking of raw jitlink::LinkGraphs.
Separates link graph creation from linking. This allows raw LinkGraphs to be
created and passed to a link. ObjectLinkingLayer is updated to support emission
of raw LinkGraphs in addition to object buffers.

Raw LinkGraphs can be created by in-memory compilers to bypass object encoding /
decoding (though this prevents caching, as LinkGraphs have do not have an
on-disk representation), and by utility code to add programatically generated
data structures to the JIT target process.
2020-12-16 14:01:50 +11:00
Lang Hames 5bb28fa0f5 [JITLink][ELF] Reformat/add debug logging in ELF_x86_64.cpp.
Moves symbol name to the end of the output and makes other columns fixed width
so that they line up.
2020-12-10 18:46:44 +11:00
Georgii Rymar ffbce65f95 [lib/Object, tools] - Make ELFObjectFile::getELFFile return reference.
We always have an object, so we don't have to return a pointer.

Differential revision: https://reviews.llvm.org/D92560
2020-12-04 16:02:29 +03:00