Commit Graph

307 Commits

Author SHA1 Message Date
Nico Weber
6cd171dc33 [lld/COFF] Support thin archives in /reproduce: files (#121512)
This already worked without /wholearchive; now it works with it too.
(Only for thin archives containing relative file names, matching the ELF
and Mach-O ports.)
2025-01-03 08:20:06 -05:00
Jacek Caban
8435225374 [LLD][COFF] Move addFile implementation to LinkerDriver (NFC) (#121342)
The addFile implementation does not rely on the SymbolTable object. With
#119294, the symbol table for input files is determined during the
construction of the objects representing them. To clarify that
relationship, this change moves the implementation from the SymbolTable
class to the LinkerDriver class.
2025-01-01 19:42:49 +01:00
Nico Weber
2b6713d3b8 [lld/coff] Fix assert on /start-lib foo.obj /end-lib during eager loads (#120292)
If foo.obj is eagerly loaded (due to a prior undef referencing one if
its symbols) and has more than one symbol, we used to assert:
SymbolTable::addLazyObject() for the first symbol would set `lazy` to
false and load all symbols from the file, but the outer
ObjFile::parseLazy() loop would continue to run and call addLazyObject()
for the second symbol, which would assert.

Instead, just stop adding lazy symbols if the file got loaded for real
while adding a symbol.

(The ELF port has a similar early exit in `ObjFile<ELFT>::parseLazy()`.)
2024-12-19 11:22:29 -05:00
Jacek Caban
16ef239520 [LLD][COFF] Introduce hybrid symbol table for EC input files on ARM64X (#119294) 2024-12-17 21:19:01 +01:00
Jacek Caban
9c8214ff31 [LLD][COFF] Create COFFObjectFile instance when constructing ObjFile (NFC) (#120144)
This change moves the creation of COFFObjectFile to the construction of
ObjFile, instead of delaying it until parsing.
2024-12-17 19:26:13 +01:00
Jacek Caban
7168de5ca7 Revert "[LLD][COFF] Introduce hybrid symbol table for EC input files on ARM64X (#119294)"
This reverts commit a8206e7b37 due to sanitizer failures.
2024-12-15 22:31:28 +01:00
Jacek Caban
a8206e7b37 [LLD][COFF] Introduce hybrid symbol table for EC input files on ARM64X (#119294)
On hybrid ARM64X targets, ARM64 and ARM64EC input files operate in
separate namespaces and cannot reference each other. This change
introduces separate `SymbolTable` instances and associates each
`InputFile` with the appropriate table to reflect this behavior.
2024-12-15 18:49:32 +01:00
Jacek Caban
d3c4857179 [LLD][COFF] Store machine type in SymbolTable (NFC) (#119298)
This change prepares for hybrid ARM64X support, which requires two
`SymbolTable` instances: one for native symbols and one for EC symbols.
In such cases, `config.machine` will remain ARM64X, while the
`SymbolTable` instances will store ARM64 and ARM64EC machine types.
2024-12-15 18:43:09 +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
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
8d225f10ef [lld-link] Replace error(...) with Err 2024-12-05 19:44:26 -08:00
Fangrui Song
4639a9a063 [lld-link] Replace log(...) with Log 2024-12-04 09:04:40 -08:00
Fangrui Song
1534f45694 [lld-link] Replace warn(...) with Warn(ctx) 2024-12-03 22:19:30 -08:00
Fangrui Song
982575fd06 [lld-link] Add context-aware diagnostic functions (#118430)
Similar to #112319 for ELF. While there is some initial boilerplate, it
can simplify some call sites that use Twine, especially when a printed
element uses `ctx` or toString.
2024-12-03 20:51:50 -08:00
Jacek Caban
581106759a [LLD][COFF] Support ARM64EC in BitcodeFile::getMachineType (#115474) 2024-11-09 13:21:58 +01:00
Jacek Caban
5d7afd324a [LLD][COFF] Add EC alias symbols for undefined x86_64 symbols on ARM64EC target (#114466) 2024-11-04 16:26:33 +01:00
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 3ab6209a3f
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
3785a413fe /
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 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
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