llvm-project/lld/COFF/COFFLinkerContext.h
Jacek Caban 5b0572875c
[LLD][COFF] Add support for including native ARM64 objects in ARM64EC images (#137653)
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.
2025-05-15 11:38:24 +02:00

123 lines
3.5 KiB
C++

//===- COFFLinkerContext.h --------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLD_COFF_COFFLINKERCONTEXT_H
#define LLD_COFF_COFFLINKERCONTEXT_H
#include "Chunks.h"
#include "Config.h"
#include "DebugTypes.h"
#include "Driver.h"
#include "InputFiles.h"
#include "SymbolTable.h"
#include "Writer.h"
#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/Timer.h"
namespace lld::coff {
class COFFLinkerContext : public CommonLinkerContext {
public:
COFFLinkerContext();
COFFLinkerContext(const COFFLinkerContext &) = delete;
COFFLinkerContext &operator=(const COFFLinkerContext &) = delete;
~COFFLinkerContext() = default;
LinkerDriver driver;
SymbolTable symtab;
COFFOptTable optTable;
// A native ARM64 symbol table on ARM64X target.
std::optional<SymbolTable> hybridSymtab;
// Returns the appropriate symbol table for the specified machine type.
SymbolTable &getSymtab(llvm::COFF::MachineTypes machine) {
if (hybridSymtab && machine == ARM64)
return *hybridSymtab;
return symtab;
}
// Invoke the specified callback for each symbol table.
void forEachSymtab(std::function<void(SymbolTable &symtab)> f) {
// If present, process the native symbol table first.
if (hybridSymtab)
f(*hybridSymtab);
f(symtab);
}
// Invoke the specified callback for each active symbol table,
// skipping the native symbol table on pure ARM64EC targets.
void forEachActiveSymtab(std::function<void(SymbolTable &symtab)> f) {
if (symtab.ctx.config.machine == ARM64X)
f(*hybridSymtab);
f(symtab);
}
std::vector<ObjFile *> objFileInstances;
std::map<std::string, PDBInputFile *> pdbInputFileInstances;
std::vector<ImportFile *> importFileInstances;
MergeChunk *mergeChunkInstances[Log2MaxSectionAlignment + 1] = {};
/// All sources of type information in the program.
std::vector<TpiSource *> tpiSourceList;
void addTpiSource(TpiSource *tpi) { tpiSourceList.push_back(tpi); }
std::map<llvm::codeview::GUID, TpiSource *> typeServerSourceMappings;
std::map<uint32_t, TpiSource *> precompSourceMappings;
/// List of all output sections. After output sections are finalized, this
/// can be indexed by getOutputSection.
std::vector<OutputSection *> outputSections;
OutputSection *getOutputSection(const Chunk *c) const {
return c->osidx == 0 ? nullptr : outputSections[c->osidx - 1];
}
// Fake sections for parsing bitcode files.
FakeSection ltoTextSection;
FakeSection ltoDataSection;
FakeSectionChunk ltoTextSectionChunk;
FakeSectionChunk ltoDataSectionChunk;
// All timers used in the COFF linker.
Timer rootTimer;
Timer inputFileTimer;
Timer ltoTimer;
Timer gcTimer;
Timer icfTimer;
// Writer timers.
Timer codeLayoutTimer;
Timer outputCommitTimer;
Timer totalMapTimer;
Timer symbolGatherTimer;
Timer symbolStringsTimer;
Timer writeTimer;
// PDB timers.
Timer totalPdbLinkTimer;
Timer addObjectsTimer;
Timer typeMergingTimer;
Timer loadGHashTimer;
Timer mergeGHashTimer;
Timer symbolMergingTimer;
Timer publicsLayoutTimer;
Timer tpiStreamLayoutTimer;
Timer diskCommitTimer;
Configuration config;
DynamicRelocsChunk *dynamicRelocs = nullptr;
};
} // namespace lld::coff
#endif