235 Commits

Author SHA1 Message Date
Jacek Caban
f8f01b5eeb
[LLD][COFF] Support marking sections as x86_64 code in ARM64EC object files (#135280)
On ARM64EC, the `IMAGE_SCN_GPREL` flag is repurposed to indicate that
section code is x86_64. This enables embedding x86_64 code within
ARM64EC object files. MSVC uses this for export thunks in .exp files.
2025-04-11 16:13:46 +02:00
Jacek Caban
1c05c6183d
[LLD][COFF] Swap the meaning of symtab and hybridSymtab in hybrid images (#135093)
Originally, the intent behind symtab was to represent the symbol table
seen in the PE header (without applying ARM64X relocations). However, in
most cases outside of `writeHeader()`, the code references either both
symbol tables or only the EC one, for example, `mainSymtab` in
`linkerMain()` maps to `hybridSymtab` on ARM64X.

MSVC's link.exe allows pure ARM64EC images to include native ARM64
files. This patch prepares LLD to support the same, which will require
`hybridSymtab` to be available even for ARM64EC. At that point,
`writeHeader()` will need to use the EC symbol table, and the original
reasoning for keeping it in `hybridSymtab` no longer applies.

Given this, it seems cleaner to treat the EC symbol table as the “main”
one, assigning it to `symtab`, and use `hybridSymtab` for the native
symbol table instead. Since `writeHeader()` will need to be conditional
anyway, this change simplifies the rest of the code by allowing other
parts to consistently treat `ctx.symtab` as the main symbol table.

As a further simplification, this also allows us to eliminate `symtabEC`
and use `symtab` directly; I’ll submit that as a separate PR.

The map file now uses the EC symbol table for printed entry points and
exports, matching MSVC behavior.
2025-04-11 15:53:25 +02:00
Jacek Caban
a92bfaa7d9
[LLD][COFF] Support MinGW constructor and destructor lists on ARM64X (#127205)
Split the chunks for EC and native views, inserting headers and tails for both.
2025-02-17 21:34:12 +01:00
Jacek Caban
fb01a28903
[LLD][COFF] Implement support for hybrid IAT on ARM64X (#124189)
In hybrid images, the PE header references a single IAT for both native
and EC views, merging entries where possible. When merging isn't
feasible, different imports are grouped together, and ARM64X relocations
are emitted as needed.
2025-01-26 22:11:40 +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
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
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
799e9883ea
[LLD][COFF] Silence GCC warning in Arm64XDynamicRelocEntry::getSize (NFC) (#122382)
Fixes 71bbafba31699bdabe289654d157ae961432e52a.
2025-01-10 14:38:22 +01:00
Jacek Caban
84087226fa
[LLD][COFF] Emit base relocation for native CHPE metadata pointer on ARM64X (#121500) 2025-01-09 21:48:16 +01:00
Jacek Caban
6b493baec1
[LLD][COFF] Store reference to SymbolTable instead of COFFLinkerContext in InputFile (NFC) (#119296)
This change prepares for the introduction of separate hybrid namespaces.
Hybrid images will require two `SymbolTable` instances, making it
necessary to associate `InputFile` objects with the relevant one.
2024-12-15 12:45:34 +01:00
Nico Weber
d73ef9749e
[lld/COFF] Demangle symbol name in discarded section relocation error message (#119726) 2024-12-13 19:35:51 -05: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
Jacek Caban
dafbc97594
[LLD][COFF] Append a terminator entry to redirection metadata (#115202)
For MSVC compatibility.
2024-11-07 12:44:45 +01:00
Jacek Caban
31a6dbe941
[LLD][COFF] Add Support for ARM64EC pseudo relocations (#113832) 2024-10-28 18:44:23 +01: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
JOE1994
4b27b5800f [lld] Nits on uses of raw_string_ostream (NFC)
* Don't call raw_string_ostream::flush(), which is essentially a no-op.
* Strip calls to raw_string_ostream::str(), to avoid excess layer of indirection.
2024-09-15 04:23:11 -04: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
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
233ed51cf5
[LLD][COFF][NFC] Use is64Bit in Baserel::getDefaultType. (#107378)
In preparation for ARM64EC support. Also make it static.
2024-09-05 15:57:20 +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
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ö
9c970d5ecd
[LLD] [COFF] Don't add pseudo relocs for dangling references (#88487)
When doing GC, we normally won't have dangling references, because such
a reference would keep the other section alive, keeping it from being
eliminated.

However, references within DWARF sections are ignored for the purposes
of GC (because otherwise, they would essentially keep everything alive,
defeating the point of the GC), see
c579a5b1d92a9bc2046d00ee2d427832e0f5ddec for more context.

Therefore, dangling relocations against discarded symbols are ignored
within DWARF sections (see maybeReportRelocationToDiscarded in
Chunks.cpp). Consequently, we also shouldn't create any pseudo
relocations for these cases, as we run into a null pointer dereference
when trying to generate the pseudo relocation info for it.

This fixes the downstream bug
https://github.com/mstorsjo/llvm-mingw/issues/418, fixing crashes on
combinations with -ffunction-sections, -fdata-sections,
-Wl,--gc-sections and debug info.
2024-04-15 20:14:07 +03:00
Jacek Caban
8f9903db8a
[LLD][COFF][NFC] Use getMachineArchType helper. (#87495)
It's similar to #87370, but for lld-link.
2024-04-04 14:41:50 +02:00
Jacek Caban
fe2bd12396
[lld] Add support for EC code map. (#69101) 2023-11-15 12:35:45 +01:00
Jacek Caban
47401b6173
[lld] Add support for relocations in x86_64 objects on Arm64EC targets. (#69098)
Since EC targets may combine various object types, we need to pick
relocation format based on chunk type instead of global config.
2023-10-16 20:50:15 +02:00
Martin Storsjö
6daa4b90e2 [LLD] [COFF] Warn about pseudo relocations that are too narrow
In 64 bit mode, any references to symbols that might end up autoimported
must be made via full 64 bit pointers (usually in .refptr stubs
generated by the compiler).

If referenced via e.g. a 32 bit rip relative offset, it might work
as long as DLLs are loaded close together in the 64 bit address
space, but will fail surprisingly later if they happen to be loaded
further apart. Any cases of that happening is usually a toolchain
error, and the sooner we can warn about it, the easier it is to diagnose.

Differential Revision: https://reviews.llvm.org/D154777
2023-07-11 23:43:34 +03:00
Elliot Goodrich
b0abd4893f [llvm] Add missing StringExtras.h includes
In preparation for removing the `#include "llvm/ADT/StringExtras.h"`
from the header to source file of `llvm/Support/Error.h`, first add in
all the missing includes that were previously included transitively
through this header.
2023-06-25 15:42:22 +01: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
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
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 7370ff624d217b0f8f7512ca5b651a9b8095a411.
(and 47fb8ae2f9a4075de05433ef24f459b6befd1730).

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
NAKAMURA Takumi
47fb8ae2f9 lldCOFF: Fix warnings for D110450 [-Wunused-private-field] 2023-01-09 13:05:34 +09:00
Amy Huang
7370ff624d [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-08 18:43:13 -05:00
Guillaume Chatelet
173f62d98f [Alignment][NFC] Use Align in StringTableBuilder ctor 2022-12-02 12:43:01 +00:00
Joe Loser
1173ecf9fb [lld] Use std::size instead of llvm::array_lengthof
LLVM contains a helpful function for getting the size of a C-style
array: `llvm::array_lengthof`. This is useful prior to C++17, but not as
helpful for C++17 or later: `std::size` already has support for C-style
arrays.

Differential Revision: https://reviews.llvm.org/D133598
2022-09-09 15:28:30 -06:00
Nico Weber
7c26641d9d [lld/win] Use C++17 nested namespace syntax in most places
Like D131354, but for COFF.

No behavior change.

Differential Revision: https://reviews.llvm.org/D131405
2022-08-08 11:48:12 -04:00
Dmitri Gribenko
aba43035bd Use llvm::sort instead of std::sort where possible
llvm::sort is beneficial even when we use the iterator-based overload,
since it can optionally shuffle the elements (to detect
non-determinism). However llvm::sort is not usable everywhere, for
example, in compiler-rt.

Reviewed By: nhaehnle

Differential Revision: https://reviews.llvm.org/D130406
2022-07-23 15:19:05 +02:00
Benjamin Kramer
f15014ff54 Revert "Rename llvm::array_lengthof into llvm::size to match std::size from C++17"
This reverts commit ef8206320769ad31422a803a0d6de6077fd231d2.

- It conflicts with the existing llvm::size in STLExtras, which will now
  never be called.
- Calling it without llvm:: breaks C++17 compat
2022-01-26 16:55:53 +01:00
serge-sans-paille
ef82063207 Rename llvm::array_lengthof into llvm::size to match std::size from C++17
As a conquence move llvm::array_lengthof from STLExtras.h to
STLForwardCompat.h (which is included by STLExtras.h so no build
breakage expected).
2022-01-26 16:17:45 +01:00
Alexandre Ganea
83d59e05b2 Re-land [LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.

See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html

The previous land f860fe362282ed69b9d4503a20e5d20b9a041189 caused issues in https://lab.llvm.org/buildbot/#/builders/123/builds/8383, fixed by 22ee510dac9440a74b2e5b3fe3ff13ccdbf55af3.

Differential Revision: https://reviews.llvm.org/D108850
2022-01-20 14:53:26 -05:00
Alexandre Ganea
e6b153947d Revert [LLD] Remove global state in lldCommon
It seems to be causing issues on https://lab.llvm.org/buildbot/#/builders/123/builds/8383
2022-01-16 11:03:06 -05:00
Alexandre Ganea
f860fe3622 [LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.

See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html

Differential Revision: https://reviews.llvm.org/D108850
2022-01-16 08:57:57 -05:00
Nico Weber
5730d11c2b [lld-link] Consistently print all /verbose output to stderr
lld-link used to consistently print all /verbose output to stdout, and that was
an intentional decision: https://reviews.llvm.org/rG4bce7bcc88f3

https://reviews.llvm.org/rGe6e206d4b4814 added message() and log(),
and back then `log()` morally was just `if (verbose) message(...)`
and message() wrote to stdout.

So that change moved most /verbose-induced writes to outs() to
log(). Except for the one in printDiscardedMessage(), since
the check for `verbose` for that one is in the caller, in
Writer::createSections():

    if (config->verbose)
      sc->printDiscardedMessage();

Later, https://reviews.llvm.org/D41033 changed log() to write to
stderr. That moved lld-link from writing all its /verbose output
to stdout to writing almost all of its /verbose output to stderr --
except for printDiscardedMessage() output.

This change moves printDiscardedMessage() to call log() as well,
so that all /verbose output once again consistently goes to the same
stream.

Differential Revision: https://reviews.llvm.org/D116667
2022-01-05 11:52:04 -05:00
Martin Storsjö
7c15da6761 [LLD] [COFF] Interpret the immediate in ARM64 adr/adrp relocations as signed 21 bit
This matches how MS link.exe interprets this relocation.

Differential Revision: https://reviews.llvm.org/D114347
2021-11-23 10:13:01 +02:00
Amy Huang
6f7483b1ec Reland "[LLD] Remove global state in lld/COFF" after fixing asan and msan test failures
Original commit description:

  [LLD] Remove global state in lld/COFF

  This patch removes globals from the lldCOFF library, by moving globals
  into a context class (COFFLinkingContext) and passing it around wherever
  it's needed.

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

  I also haven't moved the `driver` or `config` variables yet.

  Differential Revision: https://reviews.llvm.org/D109634

This reverts commit a2fd05ada9030eab2258fff25e77a05adccae128.

Original commits were b4fa71eed34d967195514fe9b0a5211fca2bc5bc
and e03c7e367adb8f228332e3c2ef8f45484597b719.
2021-09-17 17:18:42 -07:00