MSVC linker accepts native ARM64 object files as input with
`-machine:arm64ec`, similar to `-machine:arm64x`. Its usefulness is very
limited; for example, both exports and imports are not reflected in the
PE structures and can't work. However, their symbol tables are otherwise
functional.
Since we already have handling of multiple symbol tables implemented for
ARM64X, the required changes are mostly about adjusting relevant checks
to account for them on the ARM64EC target.
Delay-load helper handling is a bit of a shortcut. The patch never pulls
it for native object files and just ensures that the code is fine with
that. In general, I think it would be nice to adjust the driver to pull
it only when it's actually referenced, which would allow applying the
same logic to the native symbol table on ARM64EC without worrying about
pulling too much.
Cygwin requires these symbols for its fork emulation to know what data
to copy into the child. GNU ld defines these symbols for MinGW targets
also, so do the same here.
Cygwin also has the `.data_cygwin_nocopy` section, which is merged into
`.data` outside the `__data_start__` to `__data_end__` range. This
excludes it from fork's copying. AFAIK it's only used by the Cygwin DLL
itself (which requires a custom linker script to link, that's not
supported by LLD), but the section is included in GNU ld's default
linker script so handle it here too.
Signed-off-by: Jeremy Drake <github@jdrake.com>
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.
This reverts commit 6a1bdd9 and re-instate behavior that matches what
MSVC link.exe does, that is, error out when trying to dllimport a symbol
from a static library.
A hint is now displayed in stdout, mentioning that we should rather dllimport the symbol
from a import library.
Fixes https://github.com/llvm/llvm-project/issues/131807
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.
This refactor prepares for further ARM64X hybrid support, where these
helpers will need to work with either the native or EC symbol table
based on context.
Move `LinkerDriver::addUndefined` to` SymbolTable` to allow its use with
both symbol tables on ARM64X and rename it to `addGCRoot` to clarify its
distinct role compared to the existing `SymbolTable::addUndefined`.
Command-line `-include` arguments now apply to the EC symbol table, with
`mainSymtab` introduced in `linkerMain`. There will be more similar
cases. For `.drectve` sections, the corresponding symbol table is used
based on the context.
cg_profile in object is from CGProfilePass and it is often inaccurate.
While call-graph-ordering-file is provided by user. It is weird to
aggregate them together especially when call-graph-ordering-file is
accurate enough.
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.
Previously, we'd collect all input files in Driver::filePaths, and then
write filePaths after all other flags in
createResponseFile(). This meant that `-start-lib foo.obj -end-lib`
would be written as `-start-lib -end-lib foo.obj`, changing semantics.
Instead, remove Driver::filePaths, and handle things that fed into it
directly:
* OPT_INPUT is now handled in the same way as other flags, so that we
now get `-start-lib foo.obj -end-lib` in response.txt as desired. Add a
test for -start-lib / -end-lib and /reproduce:.
* OPT_wholearchive_file needs explicit handling now -- but before, this
was buggy as well: We'd put the flag without a rewritten path in
response.txt, but also the rewritten input file without wholearchive
semantics via filePaths. So this commit makes --whole-archive work with
/reproduce: too, and adds test coverage.
* /defaultlib:foo is now written as /defaultlib:foo into response.txt,
instead of writing the resolved path previously. While response.txt
looks slightly differently, both should have the same semantics, and
this should be mostly a no-op. (It does require updating a test.)
* /defaultlib: from .drectve sections are no longer recorded in
response.txt. This seems like a progression -- in the non-repro case
they come from .obj files, so they should come (only) from there in the
repro case too. This adds test coverage for this case.
Makes createResponseFile() look more like the versions in the ELF and
MachO ports too.
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.
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.
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.
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.