Commit Graph

391 Commits

Author SHA1 Message Date
Jacek Caban
18fa9fa043 [LLD][COFF] Add support for ARM64EC delay-load imports (#110042)
Fill the regular delay-load IAT with x86_64 delay-load thunks. Similarly
to regular imports, create an auxiliary IAT and its copy for ARM64EC
calls. These are filled with the same `__impchk_` thunks used for
regular imports, which perform an indirect call with
`__icall_helper_arm64ec` on the regular delay-load IAT. These auxiliary
IATs are exposed via CHPE metadata starting from version 2.

The MSVC linker creates one more copy of the auxiliary IAT. `__imp_func`
symbols refer to that hidden IAT, while the `#func` thunk performs a
call with the public auxiliary IAT. If the public auxiliary IAT is fine
for `#func`, it should be fine for calls using the `__imp_func` symbol
as well. Therefore, I made `__imp_func` refer to that IAT too.
2024-09-30 20:26:55 +02:00
Jacek Caban
f661e695a6 [LLD][COFF] Add support for ARM64EC import call thunks with extended range (#109703)
The MSVC linker generates range extensions for these thunks when needed.
This commit inlines the range extension into the thunk, making it both
slightly more optimal and easier to implement in LLD.
2024-09-26 10:44:40 +02:00
Jacek Caban
fc661df41a [LLD][COFF][NFC] Use dyn_cast on section chunks (#109701)
Instead of dyn_cast_or_null, chunk pointers are never null.
2024-09-24 12:04:04 +02:00
Jacek Caban
a17a2451db [LLD][COFF] Add Support for auxiliary IAT copy (#108610)
In addition to the auxiliary IAT, ARM64EC modules also contain a copy of
it. At runtime, the auxiliary IAT is filled with the addresses of actual
ARM64EC functions when possible. If patching is detected, the OS may use
the IAT copy to revert the auxiliary IAT, ensuring that the call checker
is used for calls to imported functions.
2024-09-17 14:40:24 +02:00
Jacek Caban
ea5d37f4c1 [LLD][COFF] Add Support for ARM64EC Import Thunks (#108460)
ARM64EC import thunks function similarly to regular ARM64 thunks but use
a mangled name and perform the call through the auxiliary IAT.
2024-09-13 17:05:02 +02:00
Jacek Caban
6be9be5e0b [LLD][COFF][NFC] Store live flag in ImportThunkChunk. (#108459)
Instead of ImportFile. This is a preparation for ARM64EC support, which
has both x86 and ARM64EC thunks and each of them needs a separate flag.
2024-09-13 15:42:05 +02:00
Jacek Caban
82a36468c7 [LLD][COFF] Add support for ARM64EC auxiliary IAT (#108304)
In addition to the regular IAT, ARM64EC also includes an auxiliary IAT.
At runtime, the regular IAT is populated with the addresses of imported
functions, which may be x86_64 functions or the export thunks of ARM64EC
functions. The auxiliary IAT contains versions of functions that are
guaranteed to be directly callable by ARM64 code.

The linker fills the auxiliary IAT with the addresses of `__impchk_`
thunks. These thunks perform a call on the IAT address using
`__icall_helper_arm64ec` with the target address from the IAT. If the
imported function is an ARM64EC function, the OS may replace the address
in the auxiliary IAT with the address of the ARM64EC version of the
function (not its export thunk), avoiding the runtime call checker for
better performance.
2024-09-12 22:20:50 +02:00
Jacek Caban
99a2354993 [LLD][COFF] Add support for ARM64EC import call thunks. (#107931)
These thunks can be accessed using `__impchk_*` symbols, though they
are typically not called directly. Instead, they are used to populate the
auxiliary IAT. When the imported function is x86_64 (or an ARM64EC
function with a patched export thunk), the thunk is used to call it.
Otherwise, the OS may replace the thunk at runtime with a direct
pointer to the ARM64EC function to avoid the overhead.
2024-09-11 14:46:40 +02:00
Jacek Caban
dec0781c8b [LLD][COFF] Always locate the IAT at the beginning of the .rdata section and align its size to 4KB on ARM64EC. (#107588)
This mimics the behavior of MSVC's link.exe. My guess is that the reason
for this approach is to facilitate tracking runtime IAT modifications.
An auxiliary IAT allows bypassing the call checker for imported function
calls. It's the OS's responsibility to ensure that, if runtime patching
occurs, the auxiliary IAT is reverted to enable call checking. Modifying
the IAT is a form of runtime patching, and ensuring that it doesn’t
share pages with other data likely helps with tracking accuracy.

Although alignment alone should ensure that the IAT occupies its own
pages, placing it at the beginning of the .rdata section might be an
optimization. This way, padding is only needed after the IAT, not
before. The auxiliary IAT seems to follow a similar idea but is
positioned at the end of the .rdata section.
2024-09-08 15:36:24 +02:00
Jacek Caban
efad561890 [LLD][COFF] Add support for range extension thunks for ARM64EC targets. (#106289)
Thunks themselves are the same as regular ARM64 thunks; they just need
to report the correct machine type. When processing the code, we also
need to use the current chunk's machine type instead of the global one:
we don't want to treat x86_64 thunks as ARM64EC, and we need to report
the correct machine type in hybrid binaries.
2024-08-29 10:19:32 +02:00
Jacek Caban
a35398d1bb [LLD][COFF] Generate redirection metadata for custom ARM64EC export thunks. (#105901)
This allows using custom export thunks instead of default generated
ones. This is useful for performance in cases where transferring between
JIT and ARM64EC code is more expensive than just emulating the whole
function (but it's still useful to have ARM64EC version so that ARM64EC
callers don't call into the emulator). It's also useful for compatibility,
where applications have specific expectations about function contents
(like syscall functions).
2024-08-26 21:03:12 +02:00
Jacek Caban
52a7116f5c [LLD][COFF] Add support for CHPE code ranges metadata. (#105741)
This is part of CHPE metadata containing a sorted list of x86_64 export
thunks RVAs and sizes.
2024-08-23 21:17:38 +02:00
Jacek Caban
caa844e67c [LLD][COFF] Add support for CHPE redirection metadata. (#105739)
This is part of CHPE metadata containing a sorted list of x86_64 export
thunks RVAs and RVAs of ARM64EC functions associated with them. It's
stored in a dedicated .a64xrm section.
2024-08-23 20:29:19 +02:00
Jacek Caban
a2d8743cc8 [LLD][COFF] Generate X64 thunks for ARM64EC entry points and patchable functions. (#105499)
This implements Fast-Forward Sequences documented in ARM64EC
ABI https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi.

There are two conditions when linker should generate such thunks:

- For each exported ARM64EC functions.
It applies only to ARM64EC functions (we may also have pure x64
functions, for which no thunk is needed). MSVC linker creates
`EXP+<mangled export name>` symbol in those cases that points to the
thunk and uses that symbol for the export. It's observable from the
module: it's possible to reference such symbols as I did in the test.
Note that it uses export name, not name of the symbol that's exported
(as in `foo` in `/EXPORT:foo=bar`). This implies that if the same
function is exported multiple times, it will have multiple thunks. I
followed this MSVC behavior.

- For hybrid_patchable functions.
The linker tries to generate a thunk for each undefined `EXP+*` symbol
(and such symbols are created by the compiler as a target of weak alias
from the demangled name). MSVC linker tries to find corresponding
`*$hp_target` symbol and if fails to do so, it outputs a cryptic error
like `LINK : fatal error LNK1000: Internal error during
IMAGE::BuildImage`. I just skip generating the thunk in such case (which
causes undefined reference error). MSVC linker additionally checks that
the symbol complex type is a function (see also #102898). We generally
don't do such checks in LLD, so I made it less strict. It should be
fine: if it's some data symbol, it will not have `$hp_target` symbol, so
we will skip it anyway.
2024-08-22 22:03:05 +02:00
Jacek Caban
fed8e38c19 [LLD][COFF] Add support for ARM64EC entry thunks. (#88132)
For x86_64 callable functions, ARM64EC requires an entry thunk generated
by the compiler. The linker interprets .hybmp sections to associate
function chunks with their entry points and writes an offset to thunks
preceding function section contents.

Additionally, ICF needs to be aware of entry thunks to not consider
chunks to be equal when they have different entry thunks, and GC needs
to mark entry thunks together with function chunks.

I used a new SectionChunkEC class instead of storing entry thunks in
SectionChunk, following the guideline to keep SectionChunk as compact as
possible. This way, there is no memory usage increase on non-EC targets.
2024-06-18 11:14:01 +02:00
Martin Storsjö
d17db6066d [LLD] [COFF] Don't create pseudo relocations for discardable sections (#89043)
This extends on the case from 9c970d5ecd6a85188cd2b0a941fcd4d60063ef81;
if a section is marked discardable, it won't be mapped into memory at
runtime, so there's no point in creating runtime pseudo relocations for
such sections.
2024-04-18 13:30:29 +03:00
Martin Storsjö
a169d4c2e9 [LLD] [COFF] Error out if the runtime pseudo relocation function is missing (#88573)
When then linker creates runtime pseudo relocations, it places them in a
list with the assumption that the runtime will fix these relocations
later, when the image gets loaded. If the relevant runtime function
doesn't seem to be present in the linked image, error out.

Normally when linking the mingw-w64 runtime libraries, this function
always is available. However, if linking without including the mingw-w64
CRT startup files, and the image needs runtime pseudo relocations, make
it clear that this won't work as expected at runtime.

With ld.bfd, this situation is a hard error too; ld.bfd adds an
undefined reference to this symbol if runtime pseudo relocations are
needed.

A later alternative would be to actually try to pull in the symbol (if
seen in a static library, but not included yet). This would allow
decoupling the function from the main mingw-w64 CRT startup code (making
it optional, only running if the linker actually produced runtime pseudo
relocations).

Doing that would require restructuring the lld code (gathering pseudo
relocations earlier, then loading the relocator function, then pulling in
more object files to satisfy the dependencies of the relocator) though.

Also, ld.bfd doesn't currently successfully pull in more object files to
satisfy the dependency on _pei386_runtime_relocator, so with that in
mind, there's not much extra value in making LLD do it currently either;
we can't make such a change in mingw-w64's CRT until both linkers
handle it.

This fixes one issue brought up in
https://github.com/llvm/llvm-project/issues/84424.
2024-04-16 10:37:15 +03:00
Martin Storsjö
50d33c62ad [LLD] [COFF] Fix crashes for cfguard with undefined weak symbols (#79063)
When marking symbols as having their address taken, we can have the
sitaution where we have the address taken of a weak symbol. If there's
no strong definition of the symbol, the symbol ends up as an absolute
symbol with the value null. In those cases, we don't have any Chunk.
Skip such symbols from the cfguard tables.

This fixes https://github.com/llvm/llvm-project/issues/78619.
2024-01-23 20:37:03 +02:00
Jacek Caban
dc5fb32547 [lld][NFC] Revert commit ccec22b675. (#76398)
This reverts commit ccec22b675 (#75183).
It's no longer needed with #76251.
2023-12-26 18:17:35 +01:00
Martin Storsjö
23e6e88187 [LLD] [COFF] Rewrite the config flags for dwarf debug info or symtab. NFC. (#75172)
This shouldn't have any user visible effect, but makes the logic within
the linker implementation more explicit.

Note how DWARF debug info sections were retained even if enabling a link
with PDB info only; that behaviour is preserved.
2023-12-15 20:01:13 +02:00
Zequan Wu
47b4bbfe52 [LLD][COFF] add __buildid symbol. (#74652)
After #71433, lld-link is able to always generate build id even when PDB
is not generated.

This adds the `__buildid` symbol to points to the start of 16 bytes guid
(which is after `RSDS`) and allows profile runtime to access it and dump
it to raw profile.
2023-12-14 17:43:10 -05:00
Jacek Caban
b1cc6f778d [LLD][COFF] Fix ARM64 EC chunks comparator. (#75495)
Spotted by Alexandre Ganea in #75407.
2023-12-14 23:05:29 +01:00
Jacek Caban
ccec22b675 [lld][NFC] Silence -Wuninitialized GCC 11 warnings. (#75183)
Use of those variables is guarded by lastType, so they are not actually used uninitialized.
2023-12-12 14:45:42 +01:00
Zequan Wu
aaf3a8ded4 [LLD][COFF] Add -build-id flag to generate .buildid section. (#71433)
[RFC](https://discourse.llvm.org/t/rfc-add-build-id-flag-to-lld-link/74661)

Before, lld-link only generate the debug directory containing guid when
generating PDB with the hash of PDB content.

With this change, lld-link can generate the debug directory when only
`/build-id` is given:
1. If generating PDB, `/build-id` is ignored. Same behaviour as before.
2. Not generating PDB, using hash of the binary.
   - Not under MinGW, the debug directory is still in `.rdata` section.
   - Under MinGW, place the debug directory into new `.buildid` section.
2023-12-05 14:57:45 -05:00
Jacek Caban
72c6ca6943 [lld][COFF] Support .pdata section on ARM64EC targets. (#72521)
ARM64EC needs to handle both ARM and x86_64 exception tables. This is
achieved by separating their chunks and sorting them separately.
EXCEPTION_TABLE directory references x86_64 variant, while ARM variant
is exposed using CHPE metadata, which references
__arm64x_extra_rfe_table and __arm64x_extra_rfe_table_size symbols.
2023-12-05 11:59:43 +01:00
Jacek Caban
708158529b [lld][COFF][NFC] Store pdata range as ChunkRange. (#74024) 2023-12-02 13:09:51 +01:00
Jacek Caban
ec42d547eb [lld][COFF][NFC] Factor out exception table sorting. (#72518)
This is a preparation for ARM64EC support, which needs to sort both ARM
and x86_64 tables separately.
2023-11-17 12:42:32 +01:00
Jacek Caban
fe2bd12396 [lld] Add support for EC code map. (#69101) 2023-11-15 12:35:45 +01:00
Jacek Caban
c425db2eb5 [lld] Mark target section as code section when merging code sections into a data section. (#72030) 2023-11-14 23:01:59 +01:00
Jacek Caban
54f83e6de6 [lld][COFF] Fill only gaps in code sections. (#72138)
Filling entire buffer would require all chunks to overwrite it later,
which is not the case for uninitialized chunks merged into code
sections.
2023-11-14 20:48:40 +01:00
Aleksei Nurmukhametov
76947e0405 [LLD][COFF] Support /DEPENDENTLOADFLAG[:flags] (#71537)
This should fix https://github.com/llvm/llvm-project/issues/43935
2023-11-08 15:21:05 -05:00
Jacek Caban
d61ab5e858 [lld] Align EC code region boundaries. (#69100)
Boundaries between code chunks of different architecture are always
aligned. 0x1000 seems to be a constant, this does not seem to be
affected by any command line alignment argument.
2023-11-02 12:16:02 +01:00
Jacek Caban
c605431a40 [lld] Sort data chunks before code chunks on ARM64EC. (#70722) 2023-11-01 16:47:43 +01:00
Jacek Caban
cbbb545c46 [lld] Sort code section chunks by range types on Arm64EC targets. (#69099) 2023-10-18 13:57:42 +02:00
Jacek Caban
f6f944e77f [lld][NFC] Factor out isCodeSection helper. (#69193) 2023-10-16 21:00:13 +02:00
Alexandre Ganea
356139bd02 [LLD][COFF] Add support for --time-trace (#68236)
This adds support for generating Chrome-tracing .json profile traces in
the LLD COFF driver.

Also add the necessary time scopes, so that the profile trace shows in
great detail which tasks are executed.

As an example, this is what we see when linking a Unreal Engine
executable:

![image](https://github.com/llvm/llvm-project/assets/37383324/b2e26eb4-9d37-4cf9-b002-48b604e7dcb7)
2023-10-05 22:33:58 -04:00
namazso
e335c78ec2 [lld][COFF] Remove incorrect flag from EHcont table
Fixes EHCont implementation in LLD. Closes #64570

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D157623
2023-08-10 16:17:38 -04:00
Fangrui Song
1d1f245270 [COFF] Switch to xxh3_64bits
Similar to recent changes to ELF (e.g., commit
f4b4bc2f18) and Mach-O to improve hashing
performance.
2023-07-19 14:08:14 -07:00
Fangrui Song
8d85c96e0e [lld] StringRef::{starts,ends}with => {starts,ends}_with. NFC
The latter form is now preferred to be similar to C++20 starts_with.
This replacement also removes one function call when startswith is not inlined.
2023-06-05 14:36:19 -07:00
Jacek Caban
482ee33a63 [lld] Use correct machine type in ARM64EC COFF headers.
This adds very minimal support for ARM64EC/ARM64X targets,
just enough for interesting test cases. Next patches in the
series extend llvm-objdump and llvm-readobj to provide
better tests. Those will also be useful for testing further
ARM64EC LLD support.

Differential Revision: https://reviews.llvm.org/D149086
2023-05-29 19:42:24 +02:00
Haohai Wen
c384fcd3ea [lld] Partially revert "Always emit symbol table when dwarf section exists in COFF"
This reverts part of commit 44363f2ff2.

Fixup for NO symbol table test has been reserved.

Reviewed By: wxiao3

Differential Revision: https://reviews.llvm.org/D151417
2023-05-29 09:23:51 +08:00
Phoebe Wang
360d0cd0a2 [LLD] Do not assume /guard:cf always set together with /guard:ehcont
MS link accepts *.obj with ehcont bit set only. LLD should match this
behavoir too.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D150508
2023-05-16 23:12:03 +08:00
Haohai Wen
44363f2ff2 Always emit symbol table when dwarf section exists in COFF
This also fixes check prefix NO which is pointless in symtab.test

Reviewed By: mstorsjo

Differential Revision: https://reviews.llvm.org/D149235
2023-04-27 09:42:47 +08:00
Jacek Caban
a5988034a4 [lld] Fill .text section gaps with INT3 only on x86 targets.
It doesn't make sense on ARM and using default 0 fill is compatible
with MSVC.

(It's more noticeable ARM64EC targets, where additional padding mixed
with alignment is used for entry thunk association, so there are more
gaps).

Reviewed By: mstorsjo

Differential Revision: https://reviews.llvm.org/D145962
2023-03-23 13:43:21 +02:00
Jez Ng
3df4c5a92f [NFC] Optimize vector usage in lld
By using emplace_back, as well as converting some loops to for-each, we can do more efficient vectorization.

Make copy constructor for TemporaryFile noexcept.

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D139552
2023-01-26 20:31:42 -05:00
Joe Loser
a288d7f937 [llvm][ADT] Replace uses of makeMutableArrayRef with deduction guides
Similar to how `makeArrayRef` is deprecated in favor of deduction guides, do the
same for `makeMutableArrayRef`.

Once all of the places in-tree are using the deduction guides for
`MutableArrayRef`, we can mark `makeMutableArrayRef` as deprecated.

Differential Revision: https://reviews.llvm.org/D141814
2023-01-16 14:49:37 -07:00
serge-sans-paille
c512eda38e [lld][COFF] Provide unwinding information for Chunk injected by /delayloaded
For each symbol in a /delayloaded library, lld injects a small piece of
code to handle the symbol lazy loading. This code doesn't have unwind
information, which may be troublesome.

Provide these information for AMD64.

Thanks to Yannis Juglaret <yjuglaret@mozilla.com> for contributing the
unwinding info and for his support while crafting this patch.

Fix #59639

Differential Revision: https://reviews.llvm.org/D141691
2023-01-16 18:39:21 +01:00
Benjamin Kramer
931d04be2f [ADT] Make StringRef::compare like std::string_view::compare
string_view has a slightly weaker contract, which only specifies whether
the value is bigger or smaller than 0. Adapt users accordingly and just
forward to the standard function (that also compiles down to memcmp)
2023-01-15 20:59:21 +01:00
Amy Huang
5a58b19f9c [LLD] Remove global state in lld/COFF
Remove globals from the lldCOFF library, by moving globals into a context class.
This patch mostly moves the config object into COFFLinkerContext.

See https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html for
context about removing globals from LLD.

Reviewed By: aganea

Differential Revision: https://reviews.llvm.org/D110450
2023-01-09 23:39:30 -05:00
Martin Storsjö
398c2ad6f6 Revert "[LLD] Remove global state in lld/COFF"
This reverts commit 7370ff624d.
(and 47fb8ae2f9).

This commit broke the symbol type in import libraries generated
for mingw autoexported symbols, when the source files were built
with LTO. I'll commit a testcase that showcases this issue after
the revert.
2023-01-09 16:04:44 +02:00