290 Commits

Author SHA1 Message Date
Jacek Caban
9b88792291
[LLD][COFF] Allow overriding EC alias symbols with lazy archive symbols (#113283)
On ARM64EC, external function calls emit a pair of weak-dependency
aliases: `func` to `#func` and `#func` to the `func` guess exit thunk
(instead of a single undefined `func` symbol, which would be emitted on
other targets). Allow such aliases to be overridden by lazy archive
symbols, just as we would for undefined symbols.
2024-10-23 12:43:38 +02:00
Jacek Caban
f1ba8943c8
[LLD][COFF] Support anti-dependency symbols (#112542)
Co-authored-by: Billy Laws <blaws05@gmail.com>

Anti-dependency symbols are allowed to be duplicated, with the first
definition taking precedence. If a regular weak alias is present, it is
preferred over an anti-dependency definition. Chaining anti-dependencies
is not allowed.
2024-10-21 11:44:31 +02:00
Jacek Caban
486f790d29
[LLD][COFF] Process all ARM64EC import symbols in MapFile's getSymbols (#109118) 2024-09-19 13:47:22 +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
7e0008d5ad
[LLD][COFF][NFC] Create import thunks in ImportFile::parse. (#107929) 2024-09-11 12:22:36 +02:00
Jacek Caban
3d53212f61
[LLD][COFF] Initial support for ARM64EC importlibs. (#107164)
Use demangled symbol name for __imp_ symbols and define demangled thunk
symbol as AMD64 thunk.
2024-09-04 15:03:36 +02:00
Jacek Caban
519b36925c
[LLD][COFF][NFC] Store impSym as DefinedImportData in ImportFile. (#107162) 2024-09-04 11:49:50 +02:00
Jacek Caban
ecc9aece72
[LLD][COFF] Use archive's ECSYMBOLS on ARM64EC target when available. (#106904) 2024-09-02 23:14:55 +02:00
Jacek Caban
e1cf849e82
[LLD][COFF] Use parentName for import files in toString. (#106104)
Improves diagnostic messages.
2024-08-26 22:08:33 +02:00
Jacek Caban
846dccce9c
[LLD][COFF] Validate import library machine type. (#102738) 2024-08-11 19:03:09 +02:00
Jacek Caban
2849ebb19c
[LLD][NFC] Make InputFile::getMachineType const. (#102737) 2024-08-10 15:03:23 +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
GkvJwa
c11677eedb
[LLD][COFF] Support finding pdb files from outputpath (#94153)
In addition to looking for dependent (input) PDB files next to the associated .OBJ file, we now also look into the output folder as well. This mimics MSVC link.exe behavior.

Fixes #94152
2024-06-17 11:20:06 -04:00
Jacek Caban
7b275aa243
[LLD][COFF] Add support for IMPORT_NAME_EXPORTAS import library names. (#83211)
This allows handling importlibs produced by llvm-dlltool in #78772.
ARM64EC import libraries use it by default, but it's supported by MSVC
link.exe on other platforms too.

This also avoids assuming null-terminated input, like in #78769.
2024-03-11 00:13:04 +01:00
Kazu Hirata
21730eb49b [lld] Use SmallString::operator std::string (NFC) 2024-01-22 00:13:23 -08:00
Martin Storsjö
d0986519d5
[LLD] [COFF] Preserve directives and export names from LTO objects (#78802)
The export names are saved as StringRefs pointing into the COFF
directives. In the case of LTO objects, this can be memory allocated
that is owned by the LTO InputFile, which gets destructed when doing the
compilation.

In the case of LTO objects from an older version of LLVM, which require
being upgraded when loaded, the directives string gets destructed, while
when using LTO objects of a matching version (the common case), the
directives string points into memory that doesn't get destructed on LTO
compilation.

Test this by linking a bundled binary LTO object file, from an older
version of LLVM.

This fixes issue #78591, and downstream issue
https://github.com/mstorsjo/llvm-mingw/issues/392.
2024-01-20 16:15:44 +02: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
Martin Storsjö
143133fe68
[LLD] [COFF] Don't preserve unnecessary __imp_ prefixed symbols (#72989)
This redoes the fix from 3ab6209a3f93bdbeec8e9b9fcc00a9a4980915ff
differently, without the unwanted effect of preserving unnecessary
`__imp_` prefixed symbols.

If the referencing object is a regular object, the `__imp_` symbol will
have `isUsedInRegularObj` set on it from that already. If the
referencing object is an LTO object, we set `isUsedInRegularObj` for any
symbol starting with `__imp_`.

If the object file defining the `__imp_` symbol is a regular object, the
`isUsedInRegularObj` flag has no effect. If it is an LTO object, it
causes the symbol to be preserved.
2023-12-04 23:38:46 +02:00
Martin Storsjö
e8961969ec
[LLD] [COFF] Fix deducing the machine type from LTO objects for ARM/Thumb (#71335)
In practice, all the Windows ARMNT IR objects show the architecture type
Thumb, not ARM.

Most other switch cases for architecture in lld/COFF check for and treat
`arm` and `thumb` equally.
2023-11-07 12:00:31 +02:00
Martin Storsjö
1d95a071d6
[LLD] [COFF] Handle undefined weak symbols in LTO (#70430)
When reading the bitcode input, undefined weak symbols will show up as
undefined symbols - which fails the early pass of checking for missing
symbols in symtab.reportUnresolvable(), before doing the actual LTO
compilation.

Mark such symbols as deferUndefined (added in
3785a413feef896e8a022731cc6ed405d5ebe81b /
https://reviews.llvm.org/D89004 for the -wrap option), to let them pass
through this LTO precheck. After the LTO compilation, the weak undefined
symbols will point towards an absolute null symbol as default.

Such weak undefined symbols are used for the TLS init function in the
Itanium C++ ABI, for TLS variables that potentially need to run a
constructor, when accessed across translation units.

This fixes https://github.com/llvm/llvm-project/issues/64513.
2023-11-06 00:00:24 +02:00
Martin Storsjö
3ab6209a3f
[LLD] [COFF] Handle manually defined __imp_ pointers in LTO (#70777)
Such pointers are often used by the core parts of mingw-w64, to locally
define a function that might have been referred to with dllimport.

(MSVC style linkers can automatically provide such pointers, if there
are undefined references to `__imp_<func>` left but a definition of
`<func>` is available - although this prints the warning LNK4217. GNU ld
doesn't do this, so in mingw-w64, such things are generally handled by
manually providing the relevant `__imp_` pointers.)

Make sure that a full LTO build, that does LTO of both the `__imp_`
pointer and the object file referencing it, successfully resolves such
symbols.

This solution admittedly probably reduces the effect of the LTO
compilation if there would happen to be `__imp_` prefixed symbols
included, in LTO objects, that aren't actually used. Such symbols are
mostly used in the base toolchain, not often in user code, and usually
only the relevant object files are linked in anyway.

This fixes https://github.com/llvm/llvm-project/issues/57982.
2023-11-04 23:49:38 +02:00
Martin Storsjö
a67ae8c0fd
[LLD] [COFF] Add a separate option for allowing duplicate weak symbols (#68077)
The MinGW mode (enabled with the flag -lldmingw) does allow duplicate
weak symbols. A test in
compiler-rt/test/profile/Windows/coverage-weak-lld.cpp does currently
enable the -lldmingw flag in an MSVC context, in order to deal with
duplicate weak symbols.

Add a new, separate, lld specific flag for enabling this. In MinGW mode,
this is enabled by default, otherwise it is disabled.

This allows making the MinGW mode more restrictive in adding libpaths
from the surrounding environment; in MinGW mode, all libpaths are passed
explicitly by the compiler driver to the linker, which is attempted in
https://reviews.llvm.org/D144084.
2023-10-20 23:44:44 +03:00
Kazu Hirata
4a0ccfa865 Use llvm::endianness::{big,little,native} (NFC)
Note that llvm::support::endianness has been renamed to
llvm::endianness while becoming an enum class as opposed to an
enum. This patch replaces support::{big,little,native} with
llvm::endianness::{big,little,native}.
2023-10-12 21:21:45 -07:00
Martin Storsjö
503bc5f661
[LLD] [COFF] Fix handling of comdat .drectve sections (#68116)
This can happen when manually emitting strings into .drectve sections
with `__attribute__((section(".drectve")))`, which is a way to emulate
`#pragma comment(linker, "...")` for mingw compilers, without requiring
building with -fms-extensions.

Normally, this doesn't generate any comdat, but if compiled with
-fsanitize=address, this section does get turned into a comdat section.

This fixes #67261. This issue can be seen as a regression; a change in
the "lli" tool in 17.x triggers this case, if compiled with ASAN
enabled, triggering this unsupported corner case in LLD. With this
change, LLD can handle it.
2023-10-04 10:54:50 +03: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
Archibald Elliott
62c7f035b4 [NFC][TargetParser] Remove llvm/ADT/Triple.h
I also ran `git clang-format` to get the headers in the right order for
the new location, which has changed the order of other headers in two
files.
2023-02-07 12:39:46 +00: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
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
Sylvain Audi
84038cf914 [lld][COFF] Fix lld-link crash when several .obj files built with /Zi refer to a .pdb file that failed to load
This patch relaxes the constraints on the error message saved in PDBInputFile when failing to load a pdb file.

Storing an `Error` member infers that it must be accessed exactly once, which doesn't fit in several scenarios:
- If an invalid PDB file is provided as input file but never used, a loading error is created but never handled, causing an assert at shutdown.
- PDB file created using MSVC's `/Zi` option : The loading error message must be displayed once per obj file.

Also, the state of `PDBInputFile` was altered when reading (taking) the `Error` member, causing issues:
 - accessing it (taking the `Error`) makes the object look valid whereas it's not properly initialized
 - read vs write concurrency on a same `PDBInputFile` in the ghash parallel algorithm

The solution adopted here was to instead store an optional error string, and generate Error objects from it on demand.

Differential Revision: https://reviews.llvm.org/D140333
2022-12-21 16:13:46 -05:00
Kazu Hirata
d6684f2cb2 [lld] Use std::optional instead of None in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-10 17:04:56 -08:00
Fangrui Song
c33511c8df [lld] Change Optional to std::optional
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-11-27 17:25:34 -08:00
Fangrui Song
9da7aee7c9 [COFF] Change most Optional to std::optional 2022-11-27 16:39:40 -08:00
Kazu Hirata
ef70f9f12e [COFF] Use std::optional in InputFiles.cpp (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-11-26 20:54:36 -08:00
Alexandre Ganea
242a9cf7e6 [LLD][COFF] Survive empty and invalid PCH signature
Solve two issues that showed up when using LLD with Unreal Engine & FASTBuild:
1. It seems the S_OBJNAME record doesn't always record the "precomp signature". We were relying on that to match the PCH.OBJ with their dependent-OBJ.
2. MSVC link.exe is able to link a PCH.OBJ when the "precomp signatureÈ doesn't match, but LLD was failing. This was occuring since the Unreal Engine Build Tool was compiling the PCH.OBJ, but the dependent-OBJ were compiled & cached through FASTBuild. Upon a clean rebuild, the PCH.OBJs were recompiled by the Unreal Build Tool, thus the "precomp signatures" were changing; however the OBJs were already cached by FASTBuild, thus having an old "precomp signatures".

We now ignore "precomp signatures" and properly fallback to cmd-line name lookup, like MSVC link.exe does, and only fail if the PCH.OBJ type stream doesn't match the count expected by the dependent-OBJ.

Differential Revision: https://reviews.llvm.org/D136762
2022-11-20 10:40:50 -05:00
Alan Zhao
b34006dd0a [lld][COFF] Add support for overriding weak symbols in LLVM bitcode input
LLVM bitcode contains support for weak symbols, so we can add support
for overriding weak symbols in the output COFF even though COFF doesn't
have inherent support for weak symbols.

The motivation for this patch is that Chromium is trying to use libc++'s
assertion handler mechanism, which relies on weak symbols [0], but we're
unable to perform a ThinLTO build on Windows due to this problem [1].

[0]: https://reviews.llvm.org/D121478
[1]: https://crrev.com/c/3863576

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D133165
2022-09-08 13:17:02 -04: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
Fangrui Song
292395329c [lld-link] Remove unneeded lto::InputFile::create after D116434 2022-01-04 19:38:32 -08:00
Fangrui Song
d496abbe2a [lld-link] Replace LazyObjFile with lazy ObjFile/BitcodeFile
Similar to ELF 3a5fb57393c3bc77be9e7afc2ec9d4ec3c9bbf70.

* previously when a LazyObjFile was extracted, a new ObjFile/BitcodeFile was created; now the file is reused, just with `lazy` cleared
* avoid the confusing transfer of `symbols` from LazyObjFile to the new file
* simpler code, smaller executable (5200+ bytes smaller on x86-64)
* make eager parsing feasible (for parallel section/symbol table initialization)

Reviewed By: aganea, rnk

Differential Revision: https://reviews.llvm.org/D116434
2022-01-04 15:11:44 -08: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
Amy Huang
a2fd05ada9 Temporarily revert "[LLD] Remove global state in lld/COFF" and "[lld] Add test to
check for timer output"

Seems to be causing a number of asan test failures.

This reverts commit b4fa71eed34d967195514fe9b0a5211fca2bc5bc
and e03c7e367adb8f228332e3c2ef8f45484597b719.
2021-09-16 11:58:11 -07:00
Amy Huang
b4fa71eed3 [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
2021-09-16 11:00:23 -07:00
Fangrui Song
db5e078690 [LTO] Add SelectionKind to IRSymtab and use it in ld.lld/LLVMgold
In PGO, a C++ external linkage function `foo` has a private counter
`__profc_foo` and a private `__profd_foo` in a `comdat nodeduplicate`.

A `__attribute__((weak))` function `foo` has a weak hidden counter `__profc_foo`
and a private `__profd_foo` in a `comdat nodeduplicate`.

In `ld.lld a.o b.o`, say a.o defines an external linkage `foo` and b.o
defines a weak `foo`. Currently we treat `comdat nodeduplicate` as `comdat any`,
ld.lld will incorrectly consider `b.o:__profc_foo` non-prevailing.  In the worst
case when `b.o:__profd_foo` is retained and `b.o:__profc_foo` isn't, there will
be dangling reference causing an `undefined hidden symbol` error.

Add SelectionKind to `Comdat` in IRSymtab and let linkers ignore nodeduplicate comdat.

Differential Revision: https://reviews.llvm.org/D106228
2021-07-20 13:22:00 -07:00
Martin Storsjö
ce211c505b [LLD] [COFF] Fix up missing stdcall decorations in MinGW mode
If linking directly against a DLL without an import library, the
DLL export symbols might not contain stdcall decorations.

If we have an undefined symbol with decoration, and we happen to have
a matching undecorated symbol (which either is lazy and can be loaded,
or already defined), then alias it against that instead.

This matches what's done in reverse, when we have a def file
declaring to export a symbol without decoration, but we only have
a defined decorated symbol. In that case we do a fuzzy match
(SymbolTable::findMangle). This case is more straightforward; if we
have a decorated undefined symbol, just strip the decoration and look
for the corresponding undecorated symbol name.

Add warnings and options for either silencing the warning or disabling
the whole feature, corresponding to how ld.bfd does it.

(This feature works for any symbol decoration mismatch, not only when
linking against a DLL directly; ld.bfd also tolerates it anywhere,
and also fixes up mismatches in the other direction, like
SymbolTable::findMangle, for any symbol, not only exports. But in
practice, at least for lld, it would primarily end up used for linking
against DLLs.)

Differential Revision: https://reviews.llvm.org/D104532
2021-07-02 09:49:14 +03:00