Commit Graph

420 Commits

Author SHA1 Message Date
Jacek Caban
8cb3d7b418 [LLD][COFF] Emit locally imported EC symbols for ARM64X (#125527) 2025-02-05 10:30:13 +01:00
Jacek Caban
97aa56ada5 [LLD][COFF] Move delayLoadHelper and tailMergeUnwindInfoChunk to SymbolTable (NFC) (#124729)
In preparation for ARM64X delay-load import support (#124600).
2025-01-28 12:07:35 +01:00
Jacek Caban
671ec34fb2 [LLD][COFF] Add support for hybrid exports on ARM64X (#123724) 2025-01-21 22:55:58 +01:00
Jacek Caban
659e66e2b3 [LLD][COFF] Implement ARM64X relocations for the exception table (#123723) 2025-01-21 22:24:00 +01:00
Jacek Caban
455b3d6df2 [LLD][COFF] Separate EC and native exports for ARM64X (#123652)
Store exports in SymbolTable instead of Configuration.
2025-01-21 10:41:15 +01:00
Jacek Caban
2cfddda1f5 [LLD][COFF] Simplify creation of .edata chunks (NFC) (#123651)
Since commit dadc6f2488, only the constructor of the `EdataContents`
class is used. Replace it with a function and skip the call when using a
custom `.edata` section.
2025-01-20 23:02:26 +01:00
kkent030315
fb974e8909 [LLD][COFF] Add support for custom DOS stub (#122561)
This change implements support for the /stub flag to align with MS
link.exe. This option is useful when a program needs to optimize the DOS
program that executes when the PE runs on DOS, avoiding the traditional
hardcoded DOS program in LLD.
2025-01-20 23:38:59 +02:00
Jacek Caban
a16adafd47 [LLD][COFF] Add support for alternate entry point in CHPE metadata on ARM64X (#123346)
Includes handling for ARM64X relocations relative to a symbol.
2025-01-20 11:38:54 +01:00
Jacek Caban
1bd5f34d76 [LLD][COFF] Move getChunk to LinkerDriver (NFC) (#123103)
The `getChunk` function returns all chunks, not just those specific to a
symbol table. Move it out of the `SymbolTable` class to clarify its
scope.
2025-01-16 12:55:12 +01:00
Jacek Caban
d004947ac5 [LLD][COFF] Add support for hybrid ARM64X entry points (#123096)
Store the entry symbol in SymbolTable instead of Configuration, as it
differs between symbol tables.
2025-01-16 12:53:48 +01:00
Jacek Caban
3b0dafff87 [LLD][COFF] Use EC load config for ARM64X relocations of load config directory (#121337)
This change ensures the load config in the hybrid image view is handled
correctly. It introduces a new Arm64XRelocVal class to abstract
relocation values, allowing them to be relative to a symbol. This class
will also be useful for managing ARM64X relocation offsets in the
future.
2025-01-10 21:50:07 +01:00
Jacek Caban
c57810a00a [LLD][COFF] Sort base relocations (#121699)
This change ensures that base relocations are sorted in the output,
aligning with MSVC linker behavior. While input files typically provide
sorted relocations, this update guarantees correct sorting even if the
input relocations are unordered.
2025-01-09 15:40:49 +01:00
Nico Weber
4b22ef7d6b [lld/COFF] Fix comment typo to cycle bots 2025-01-02 08:24:50 -05:00
Jacek Caban
db7123fbbc [LLD][COFF] Use EC symbol table for CHPE metadata (#120328)
Copy CHPE metadata pointer from EC load config to native configuration.
2024-12-29 14:04:00 +01:00
Jacek Caban
7144325109 [LLD][COFF] Prepare both load configs on ARM64X (#120326) 2024-12-29 12:55:10 +01:00
Jacek Caban
ff29f38c02 [LLD][COFF] Store and validate load config in SymbolTable (#120324)
Improve diagnostics for invalid load configurations.
2024-12-29 11:43:45 +01:00
Fangrui Song
1865f0e203 [lld-link] Replace warn(...) with Warn(ctx) 2024-12-12 22:27:45 -08:00
Fangrui Song
c7caab2238 [lld-link] Simplify some << toString 2024-12-05 20:56:19 -08:00
Fangrui Song
8b844de3c9 [lld-link] Replace fatal(...) with Fatal 2024-12-05 20:18:01 -08:00
Fangrui Song
36c294013c [lld-link] Remove unneeded Twine when using COFFSyncStream 2024-12-05 19:49:53 -08:00
Fangrui Song
8d225f10ef [lld-link] Replace error(...) with Err 2024-12-05 19:44:26 -08:00
Mateusz Mikuła
8a6f1abe16 [LLD] [COFF] Print a warning when using /dependentloadflag without load config (#117400)
As per request in https://github.com/llvm/llvm-project/pull/113814.
2024-12-05 22:28:38 +02:00
Jacek Caban
71bbafba31 [LLD][COFF] Add basic ARM64X dynamic relocations support (#118035)
This modifies the machine field in the hybrid view to be AMD64, aligning
it with expectations from ARM64EC modules. While this provides initial
support, additional relocations will be necessary for full
functionality. Many of these cases depend on implementing separate
namespace support first.

Move clearing of the .reloc section from addBaserels to assignAddresses
to ensure it is always cleared, regardless of the relocatable
configuration. This change also clarifies the reasoning for adding the
dynamic relocations chunk in that location.
2024-12-05 13:07:41 +01:00
Fangrui Song
4639a9a063 [lld-link] Replace log(...) with Log 2024-12-04 09:04:40 -08:00
Jacek Caban
7235ac9051 [LLD][COFF] Check load config size before setting its DependentLoadFlags (#118535)
Merge prepareLoadConfig and checkLoadConfigGuardData to share helper
macros.
2024-12-04 15:36:41 +01:00
Fangrui Song
1534f45694 [lld-link] Replace warn(...) with Warn(ctx) 2024-12-03 22:19:30 -08:00
Fangrui Song
8c7c8eaa19 [lld-link] Replace global lld::errs() with ctx.e.errs() 2024-11-16 18:45:47 -08:00
Fangrui Song
1bfe55aff5 [lld-link] Replace errorHandler() with ctx.e
errorHandler() uses the global state, which should be avoided in
lld/COFF code.
2024-11-16 18:31:58 -08:00
Jacek Caban
5fbe9b958d [LLD][COFF] Set __guard_flags to CF_INSTRUMENTED if any object is instrumented (#115374) 2024-11-08 14:01:25 +01:00
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