[lld] [LLD][COFF] Remove no longer needed symtabEC from COFFLinkerContext (NFC) (PR #135094)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 9 16:36:49 PDT 2025
https://github.com/cjacek created https://github.com/llvm/llvm-project/pull/135094
With #135093, we may just use `symtab` instead.
>From a1555e776b5a3dea89763c0b93e7c63000396e69 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Mon, 7 Apr 2025 19:41:12 +0200
Subject: [PATCH 1/2] [LLD][COFF] Swap the meaning of symtab and hybridSymtab
in hybrid images
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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.
---
lld/COFF/COFFLinkerContext.h | 6 ++--
lld/COFF/Chunks.cpp | 10 +++---
lld/COFF/Driver.cpp | 35 +++++++++------------
lld/COFF/InputFiles.cpp | 1 +
lld/COFF/Writer.cpp | 54 ++++++++++++++++----------------
lld/test/COFF/arm64x-map.s | 60 ++++++++++++++++++++++++++++++++++++
6 files changed, 110 insertions(+), 56 deletions(-)
create mode 100644 lld/test/COFF/arm64x-map.s
diff --git a/lld/COFF/COFFLinkerContext.h b/lld/COFF/COFFLinkerContext.h
index 8322f829d4055..d01a34899c57d 100644
--- a/lld/COFF/COFFLinkerContext.h
+++ b/lld/COFF/COFFLinkerContext.h
@@ -32,7 +32,7 @@ class COFFLinkerContext : public CommonLinkerContext {
SymbolTable symtab;
COFFOptTable optTable;
- // A hybrid ARM64EC symbol table on ARM64X target.
+ // A native ARM64 symbol table on ARM64X target.
std::optional<SymbolTable> hybridSymtab;
// Pointer to the ARM64EC symbol table: either symtab for an ARM64EC target or
@@ -41,16 +41,16 @@ class COFFLinkerContext : public CommonLinkerContext {
// Returns the appropriate symbol table for the specified machine type.
SymbolTable &getSymtab(llvm::COFF::MachineTypes machine) {
- if (hybridSymtab && (machine == ARM64EC || machine == AMD64))
+ if (hybridSymtab && machine == ARM64)
return *hybridSymtab;
return symtab;
}
// Invoke the specified callback for each symbol table.
void forEachSymtab(std::function<void(SymbolTable &symtab)> f) {
- f(symtab);
if (hybridSymtab)
f(*hybridSymtab);
+ f(symtab);
}
std::vector<ObjFile *> objFileInstances;
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 3494d1ba0ac02..3920158923858 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -570,14 +570,14 @@ void SectionChunk::getBaserels(std::vector<Baserel> *res) {
// to match the value in the EC load config, which is expected to be
// a relocatable pointer to the __chpe_metadata symbol.
COFFLinkerContext &ctx = file->symtab.ctx;
- if (ctx.hybridSymtab && ctx.symtab.loadConfigSym &&
- ctx.symtab.loadConfigSym->getChunk() == this &&
- ctx.hybridSymtab->loadConfigSym &&
- ctx.symtab.loadConfigSize >=
+ if (ctx.hybridSymtab && ctx.hybridSymtab->loadConfigSym &&
+ ctx.hybridSymtab->loadConfigSym->getChunk() == this &&
+ ctx.symtab.loadConfigSym &&
+ ctx.hybridSymtab->loadConfigSize >=
offsetof(coff_load_configuration64, CHPEMetadataPointer) +
sizeof(coff_load_configuration64::CHPEMetadataPointer))
res->emplace_back(
- ctx.symtab.loadConfigSym->getRVA() +
+ ctx.hybridSymtab->loadConfigSym->getRVA() +
offsetof(coff_load_configuration64, CHPEMetadataPointer),
IMAGE_REL_BASED_DIR64);
}
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 7aa13bdce488e..d9e70a5be3261 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -662,9 +662,9 @@ void LinkerDriver::setMachine(MachineTypes machine) {
if (machine == ARM64EC)
ctx.symtabEC = &ctx.symtab;
} else {
- ctx.symtab.machine = ARM64;
- ctx.hybridSymtab.emplace(ctx, ARM64EC);
- ctx.symtabEC = &*ctx.hybridSymtab;
+ ctx.symtab.machine = ARM64EC;
+ ctx.hybridSymtab.emplace(ctx, ARM64);
+ ctx.symtabEC = &ctx.symtab;
}
addWinSysRootLibSearchPaths();
@@ -981,12 +981,9 @@ void LinkerDriver::createImportLibrary(bool asLib) {
}
};
- if (ctx.hybridSymtab) {
- getExports(ctx.symtab, nativeExports);
- getExports(*ctx.hybridSymtab, exports);
- } else {
- getExports(ctx.symtab, exports);
- }
+ getExports(ctx.symtab, exports);
+ if (ctx.hybridSymtab)
+ getExports(*ctx.hybridSymtab, nativeExports);
std::string libName = getImportName(asLib);
std::string path = getImplibPath();
@@ -1818,10 +1815,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
}
}
- // Most of main arguments apply either to both or only to EC symbol table on
- // ARM64X target.
- SymbolTable &mainSymtab = ctx.hybridSymtab ? *ctx.hybridSymtab : ctx.symtab;
-
// Handle /nodefaultlib:<filename>
{
llvm::TimeTraceScope timeScope2("Nodefaultlib");
@@ -1903,11 +1896,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Handle /alternatename
for (auto *arg : args.filtered(OPT_alternatename))
- mainSymtab.parseAlternateName(arg->getValue());
+ ctx.symtab.parseAlternateName(arg->getValue());
// Handle /include
for (auto *arg : args.filtered(OPT_incl))
- mainSymtab.addGCRoot(arg->getValue());
+ ctx.symtab.addGCRoot(arg->getValue());
// Handle /implib
if (auto *arg = args.getLastArg(OPT_implib))
@@ -2056,7 +2049,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Handle /aligncomm
for (auto *arg : args.filtered(OPT_aligncomm))
- mainSymtab.parseAligncomm(arg->getValue());
+ ctx.symtab.parseAligncomm(arg->getValue());
// Handle /manifestdependency.
for (auto *arg : args.filtered(OPT_manifestdependency))
@@ -2307,19 +2300,19 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (!e.extName.empty() && !isDecorated(e.extName))
e.extName = saver().save("_" + e.extName);
}
- mainSymtab.exports.push_back(e);
+ ctx.symtab.exports.push_back(e);
}
}
// Handle /def
if (auto *arg = args.getLastArg(OPT_deffile)) {
// parseModuleDefs mutates Config object.
- mainSymtab.parseModuleDefs(arg->getValue());
+ ctx.symtab.parseModuleDefs(arg->getValue());
if (ctx.hybridSymtab) {
// MSVC ignores the /defArm64Native argument on non-ARM64X targets.
// It is also ignored if the /def option is not specified.
if (auto *arg = args.getLastArg(OPT_defarm64native))
- ctx.symtab.parseModuleDefs(arg->getValue());
+ ctx.hybridSymtab->parseModuleDefs(arg->getValue());
}
}
@@ -2336,7 +2329,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// and after the early return when just writing an import library.
if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
llvm::TimeTraceScope timeScope("Infer subsystem");
- config->subsystem = mainSymtab.inferSubsystem();
+ config->subsystem = ctx.symtab.inferSubsystem();
if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
Fatal(ctx) << "subsystem must be defined";
}
@@ -2702,7 +2695,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Handle /output-def (MinGW specific).
if (auto *arg = args.getLastArg(OPT_output_def))
- writeDefFile(ctx, arg->getValue(), mainSymtab.exports);
+ writeDefFile(ctx, arg->getValue(), ctx.symtab.exports);
// Set extra alignment for .comm symbols
ctx.forEachSymtab([&](SymbolTable &symtab) {
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 256bec6bb636c..7916e3fd4ea1f 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -139,6 +139,7 @@ void ArchiveFile::parse() {
// Read both EC and native symbols on ARM64X.
if (!ctx.hybridSymtab)
return;
+ archiveSymtab = &*ctx.hybridSymtab;
} else if (ctx.hybridSymtab) {
// If the ECSYMBOLS section is missing in the archive, the archive could
// be either a native-only ARM64 or x86_64 archive. Check the machine type
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 6ed1f884a9636..31c686761d74f 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1359,14 +1359,14 @@ void Writer::createExportTable() {
for (auto chunk : edataSec->chunks) {
if (chunk->getMachine() != ARM64) {
- ctx.hybridSymtab->edataStart = chunk;
- ctx.hybridSymtab->edataEnd = edataSec->chunks.back();
+ ctx.symtab.edataStart = chunk;
+ ctx.symtab.edataEnd = edataSec->chunks.back();
break;
}
- if (!ctx.symtab.edataStart)
- ctx.symtab.edataStart = chunk;
- ctx.symtab.edataEnd = chunk;
+ if (!ctx.hybridSymtab->edataStart)
+ ctx.hybridSymtab->edataStart = chunk;
+ ctx.hybridSymtab->edataEnd = chunk;
}
}
}
@@ -1760,7 +1760,8 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
assert(coffHeaderOffset == buf - buffer->getBufferStart());
auto *coff = reinterpret_cast<coff_file_header *>(buf);
buf += sizeof(*coff);
- coff->Machine = ctx.symtab.isEC() ? AMD64 : ctx.symtab.machine;
+ SymbolTable &symtab = ctx.hybridSymtab ? *ctx.hybridSymtab : ctx.symtab;
+ coff->Machine = symtab.isEC() ? AMD64 : symtab.machine;
coff->NumberOfSections = ctx.outputSections.size();
coff->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
if (config->largeAddressAware)
@@ -1807,7 +1808,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
pe->SizeOfImage = sizeOfImage;
pe->SizeOfHeaders = sizeOfHeaders;
if (!config->noEntry) {
- Defined *entry = cast<Defined>(ctx.symtab.entry);
+ Defined *entry = cast<Defined>(symtab.entry);
pe->AddressOfEntryPoint = entry->getRVA();
// Pointer to thumb code must have the LSB set, so adjust it.
if (config->machine == ARMNT)
@@ -1851,11 +1852,11 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
dataDirOffset64 == buf - buffer->getBufferStart());
auto *dir = reinterpret_cast<data_directory *>(buf);
buf += sizeof(*dir) * numberOfDataDirectory;
- if (ctx.symtab.edataStart) {
- dir[EXPORT_TABLE].RelativeVirtualAddress = ctx.symtab.edataStart->getRVA();
- dir[EXPORT_TABLE].Size = ctx.symtab.edataEnd->getRVA() +
- ctx.symtab.edataEnd->getSize() -
- ctx.symtab.edataStart->getRVA();
+ if (symtab.edataStart) {
+ dir[EXPORT_TABLE].RelativeVirtualAddress = symtab.edataStart->getRVA();
+ dir[EXPORT_TABLE].Size = symtab.edataEnd->getRVA() +
+ symtab.edataEnd->getSize() -
+ symtab.edataStart->getRVA();
}
if (importTableStart) {
dir[IMPORT_TABLE].RelativeVirtualAddress = importTableStart->getRVA();
@@ -1886,7 +1887,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = relocSec->getRVA();
dir[BASE_RELOCATION_TABLE].Size = relocSize;
}
- if (Symbol *sym = ctx.symtab.findUnderscore("_tls_used")) {
+ if (Symbol *sym = symtab.findUnderscore("_tls_used")) {
if (Defined *b = dyn_cast<Defined>(sym)) {
dir[TLS_TABLE].RelativeVirtualAddress = b->getRVA();
dir[TLS_TABLE].Size = config->is64()
@@ -1898,10 +1899,10 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
dir[DEBUG_DIRECTORY].RelativeVirtualAddress = debugDirectory->getRVA();
dir[DEBUG_DIRECTORY].Size = debugDirectory->getSize();
}
- if (ctx.symtab.loadConfigSym) {
+ if (symtab.loadConfigSym) {
dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress =
- ctx.symtab.loadConfigSym->getRVA();
- dir[LOAD_CONFIG_TABLE].Size = ctx.symtab.loadConfigSize;
+ symtab.loadConfigSym->getRVA();
+ dir[LOAD_CONFIG_TABLE].Size = symtab.loadConfigSize;
}
if (!delayIdata.empty()) {
dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress =
@@ -2442,7 +2443,7 @@ void Writer::setECSymbols() {
// For the hybrid image, set the alternate entry point to the EC entry
// point. In the hybrid view, it is swapped to the native entry point
// using ARM64X relocations.
- if (auto altEntrySym = cast_or_null<Defined>(ctx.hybridSymtab->entry)) {
+ if (auto altEntrySym = cast_or_null<Defined>(ctx.symtab.entry)) {
// If the entry is an EC export thunk, use its target instead.
if (auto thunkChunk =
dyn_cast<ECExportThunkChunk>(altEntrySym->getChunk()))
@@ -2711,7 +2712,7 @@ void Writer::createDynamicRelocs() {
if (ctx.symtab.entry != ctx.hybridSymtab->entry ||
pdata.first != hybridPdata.first) {
chpeSym = cast_or_null<DefinedRegular>(
- ctx.hybridSymtab->findUnderscore("__chpe_metadata"));
+ ctx.symtab.findUnderscore("__chpe_metadata"));
if (!chpeSym)
Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
}
@@ -2720,14 +2721,14 @@ void Writer::createDynamicRelocs() {
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
peHeaderOffset +
offsetof(pe32plus_header, AddressOfEntryPoint),
- cast_or_null<Defined>(ctx.hybridSymtab->entry));
+ cast_or_null<Defined>(ctx.symtab.entry));
// Swap the alternate entry point in the CHPE metadata.
if (chpeSym)
ctx.dynamicRelocs->add(
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, AlternateEntryPoint)),
- cast_or_null<Defined>(ctx.symtab.entry));
+ cast_or_null<Defined>(ctx.hybridSymtab->entry));
}
if (ctx.symtab.edataStart != ctx.hybridSymtab->edataStart) {
@@ -2735,7 +2736,7 @@ void Writer::createDynamicRelocs() {
dataDirOffset64 +
EXPORT_TABLE * sizeof(data_directory) +
offsetof(data_directory, RelativeVirtualAddress),
- ctx.hybridSymtab->edataStart);
+ ctx.symtab.edataStart);
// The Size value is assigned after addresses are finalized.
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
dataDirOffset64 +
@@ -2773,12 +2774,12 @@ void Writer::createDynamicRelocs() {
dataDirOffset64 +
LOAD_CONFIG_TABLE * sizeof(data_directory) +
offsetof(data_directory, RelativeVirtualAddress),
- ctx.hybridSymtab->loadConfigSym);
+ ctx.symtab.loadConfigSym);
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
dataDirOffset64 +
LOAD_CONFIG_TABLE * sizeof(data_directory) +
offsetof(data_directory, Size),
- ctx.hybridSymtab->loadConfigSize);
+ ctx.symtab.loadConfigSize);
}
PartialSection *Writer::createPartialSection(StringRef name,
@@ -2889,15 +2890,14 @@ void Writer::prepareLoadConfig(SymbolTable &symtab, T *loadConfig) {
// On ARM64X, only the EC version of the load config contains
// CHPEMetadataPointer. Copy its value to the native load config.
if (ctx.hybridSymtab && !symtab.isEC() &&
- ctx.hybridSymtab->loadConfigSize >=
+ ctx.symtab.loadConfigSize >=
offsetof(T, CHPEMetadataPointer) + sizeof(T::CHPEMetadataPointer)) {
OutputSection *sec =
- ctx.getOutputSection(ctx.hybridSymtab->loadConfigSym->getChunk());
+ ctx.getOutputSection(ctx.symtab.loadConfigSym->getChunk());
uint8_t *secBuf = buffer->getBufferStart() + sec->getFileOff();
auto hybridLoadConfig =
reinterpret_cast<const coff_load_configuration64 *>(
- secBuf +
- (ctx.hybridSymtab->loadConfigSym->getRVA() - sec->getRVA()));
+ secBuf + (ctx.symtab.loadConfigSym->getRVA() - sec->getRVA()));
loadConfig->CHPEMetadataPointer = hybridLoadConfig->CHPEMetadataPointer;
}
}
diff --git a/lld/test/COFF/arm64x-map.s b/lld/test/COFF/arm64x-map.s
new file mode 100644
index 0000000000000..956c52a93b041
--- /dev/null
+++ b/lld/test/COFF/arm64x-map.s
@@ -0,0 +1,60 @@
+// REQUIRES: aarch64
+// RUN: split-file %s %t.dir && cd %t.dir
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows arm64-data-sym.s -o arm64-data-sym.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows arm64ec-data-sym.s -o arm64ec-data-sym.obj
+// RUN: lld-link -machine:arm64x -dll -out:out.dll -map -mapinfo:exports arm64-data-sym.obj arm64ec-data-sym.obj
+// RUN: FileCheck %s < out.map
+
+// CHECK: Start Length Name Class
+// CHECK-NEXT: 0001:00000000 00001004H .text CODE
+// CHECK-NEXT: 0004:00000000 00000008H .data DATA
+// CHECK-NEXT: 0004:00000008 00000000H .bss DATA
+// CHECK-EMPTY:
+// CHECK-NEXT: Address Publics by Value Rva+Base Lib:Object
+// CHECK-EMPTY:
+// CHECK-NEXT: 0001:00000000 _DllMainCRTStartup 0000000180001000 arm64-data-sym.obj
+// CHECK-NEXT: 0001:00001000 _DllMainCRTStartup 0000000180002000 arm64ec-data-sym.obj
+// CHECK-NEXT: 0004:00000000 arm64_data_sym 0000000180005000 arm64-data-sym.obj
+// CHECK-NEXT: 0004:00000004 arm64ec_data_sym 0000000180005004 arm64ec-data-sym.obj
+// CHECK-EMPTY:
+// CHECK-NEXT: entry point at 0002:00000000
+// CHECK-EMPTY:
+// CHECK-NEXT: Static symbols
+// CHECK-EMPTY:
+// CHECK-EMPTY:
+// CHECK-NEXT: Exports
+// CHECK-EMPTY:
+// CHECK-NEXT: ordinal name
+// CHECK-EMPTY:
+// CHECK-NEXT: 1 arm64ec_data_sym
+
+#--- arm64ec-data-sym.s
+ .text
+ .globl _DllMainCRTStartup
+_DllMainCRTStartup:
+ ret
+
+ .data
+ .globl arm64ec_data_sym
+ .p2align 2, 0x0
+arm64ec_data_sym:
+ .word 0x02020202
+
+ .section .drectve
+ .ascii "-export:arm64ec_data_sym,DATA"
+
+#--- arm64-data-sym.s
+ .text
+ .globl _DllMainCRTStartup
+_DllMainCRTStartup:
+ ret
+
+ .data
+ .globl arm64_data_sym
+ .p2align 2, 0x0
+arm64_data_sym:
+ .word 0x01010101
+
+ .section .drectve
+ .ascii "-export:arm64_data_sym,DATA"
>From 75cc8b141294ea4ac2db2ec11cc9e39bcb6ee503 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Mon, 7 Apr 2025 20:01:35 +0200
Subject: [PATCH 2/2] [LLD][COFF] Remove no longer needed symtabEC from
COFFLinkerContext (NFC)
With #135093, we may just use symtab instead.
---
lld/COFF/COFFLinkerContext.h | 4 ---
lld/COFF/DLL.cpp | 4 +--
lld/COFF/Driver.cpp | 22 +++++++----------
lld/COFF/InputFiles.cpp | 4 +--
lld/COFF/Writer.cpp | 47 +++++++++++++++++-------------------
5 files changed, 35 insertions(+), 46 deletions(-)
diff --git a/lld/COFF/COFFLinkerContext.h b/lld/COFF/COFFLinkerContext.h
index d01a34899c57d..053cd8739eb55 100644
--- a/lld/COFF/COFFLinkerContext.h
+++ b/lld/COFF/COFFLinkerContext.h
@@ -35,10 +35,6 @@ class COFFLinkerContext : public CommonLinkerContext {
// A native ARM64 symbol table on ARM64X target.
std::optional<SymbolTable> hybridSymtab;
- // Pointer to the ARM64EC symbol table: either symtab for an ARM64EC target or
- // hybridSymtab for an ARM64X target.
- SymbolTable *symtabEC = nullptr;
-
// Returns the appropriate symbol table for the specified machine type.
SymbolTable &getSymtab(llvm::COFF::MachineTypes machine) {
if (hybridSymtab && machine == ARM64)
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index 198b6e1cddd1e..0440507b71756 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -848,7 +848,7 @@ void IdataContents::create(COFFLinkerContext &ctx) {
: make<NullChunk>(ctx));
addresses.push_back(addressesTerminator ? addressesTerminator
: make<NullChunk>(ctx));
- if (ctx.symtabEC) {
+ if (ctx.symtab.isEC()) {
auxIat.push_back(make<NullChunk>(ctx));
auxIatCopy.push_back(make<NullChunk>(ctx));
}
@@ -998,7 +998,7 @@ void DelayLoadContents::create() {
// Terminate with null values.
addresses.push_back(make<NullChunk>(ctx, 8));
names.push_back(make<NullChunk>(ctx, 8));
- if (ctx.symtabEC) {
+ if (ctx.symtab.isEC()) {
auxIat.push_back(make<NullChunk>(ctx, 8));
auxIatCopy.push_back(make<NullChunk>(ctx, 8));
}
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index d9e70a5be3261..e3ff647209e72 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -659,12 +659,9 @@ void LinkerDriver::setMachine(MachineTypes machine) {
if (machine != ARM64X) {
ctx.symtab.machine = machine;
- if (machine == ARM64EC)
- ctx.symtabEC = &ctx.symtab;
} else {
ctx.symtab.machine = ARM64EC;
ctx.hybridSymtab.emplace(ctx, ARM64);
- ctx.symtabEC = &ctx.symtab;
}
addWinSysRootLibSearchPaths();
@@ -1320,7 +1317,7 @@ void LinkerDriver::maybeCreateECExportThunk(StringRef name, Symbol *&sym) {
expName = saver().save("EXP+" + *mangledName);
else
expName = saver().save("EXP+" + name);
- sym = ctx.symtabEC->addGCRoot(expName);
+ sym = ctx.symtab.addGCRoot(expName);
if (auto undef = dyn_cast<Undefined>(sym)) {
if (!undef->getWeakAlias()) {
auto thunk = make<ECExportThunkChunk>(def);
@@ -1332,13 +1329,13 @@ void LinkerDriver::maybeCreateECExportThunk(StringRef name, Symbol *&sym) {
void LinkerDriver::createECExportThunks() {
// Check if EXP+ symbols have corresponding $hp_target symbols and use them
// to create export thunks when available.
- for (Symbol *s : ctx.symtabEC->expSymbols) {
+ for (Symbol *s : ctx.symtab.expSymbols) {
if (!s->isUsedInRegularObj)
continue;
assert(s->getName().starts_with("EXP+"));
std::string targetName =
(s->getName().substr(strlen("EXP+")) + "$hp_target").str();
- Symbol *sym = ctx.symtabEC->find(targetName);
+ Symbol *sym = ctx.symtab.find(targetName);
if (!sym)
continue;
Defined *targetSym;
@@ -1360,10 +1357,9 @@ void LinkerDriver::createECExportThunks() {
}
}
- if (ctx.symtabEC->entry)
- maybeCreateECExportThunk(ctx.symtabEC->entry->getName(),
- ctx.symtabEC->entry);
- for (Export &e : ctx.symtabEC->exports) {
+ if (ctx.symtab.entry)
+ maybeCreateECExportThunk(ctx.symtab.entry->getName(), ctx.symtab.entry);
+ for (Export &e : ctx.symtab.exports) {
if (!e.data)
maybeCreateECExportThunk(e.extName.empty() ? e.name : e.extName, e.sym);
}
@@ -1372,7 +1368,7 @@ void LinkerDriver::createECExportThunks() {
void LinkerDriver::pullArm64ECIcallHelper() {
if (!ctx.config.arm64ECIcallHelper)
ctx.config.arm64ECIcallHelper =
- ctx.symtabEC->addGCRoot("__icall_helper_arm64ec");
+ ctx.symtab.addGCRoot("__icall_helper_arm64ec");
}
// In MinGW, if no symbols are chosen to be exported, then all symbols are
@@ -2753,8 +2749,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (auto *arg = args.getLastArg(OPT_print_symbol_order))
config->printSymbolOrder = arg->getValue();
- if (ctx.symtabEC)
- ctx.symtabEC->initializeECThunks();
+ if (ctx.symtab.isEC())
+ ctx.symtab.initializeECThunks();
ctx.forEachSymtab([](SymbolTable &symtab) { symtab.initializeLoadConfig(); });
// Identify unreferenced COMDAT sections.
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 7916e3fd4ea1f..7fb42bb681939 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -129,12 +129,12 @@ void ArchiveFile::parse() {
file = CHECK(Archive::create(mb), this);
// Try to read symbols from ECSYMBOLS section on ARM64EC.
- if (ctx.symtabEC) {
+ if (ctx.symtab.isEC()) {
iterator_range<Archive::symbol_iterator> symbols =
CHECK(file->ec_symbols(), this);
if (!symbols.empty()) {
for (const Archive::Symbol &sym : symbols)
- ctx.symtabEC->addLazyArchive(this, sym);
+ ctx.symtab.addLazyArchive(this, sym);
// Read both EC and native symbols on ARM64X.
if (!ctx.hybridSymtab)
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 31c686761d74f..a5582cc8074d1 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -581,7 +581,7 @@ bool Writer::createThunks(OutputSection *os, int margin) {
// Create a code map for CHPE metadata.
void Writer::createECCodeMap() {
- if (!ctx.symtabEC)
+ if (!ctx.symtab.isEC())
return;
// Clear the map in case we were're recomputing the map after adding
@@ -617,8 +617,7 @@ void Writer::createECCodeMap() {
closeRange();
- Symbol *tableCountSym =
- ctx.symtabEC->findUnderscore("__hybrid_code_map_count");
+ Symbol *tableCountSym = ctx.symtab.findUnderscore("__hybrid_code_map_count");
cast<DefinedAbsolute>(tableCountSym)->setVA(codeMap.size());
}
@@ -2234,11 +2233,10 @@ void Writer::maybeAddRVATable(SymbolRVASet tableSymbols, StringRef tableSym,
// Create CHPE metadata chunks.
void Writer::createECChunks() {
- SymbolTable *symtab = ctx.symtabEC;
- if (!symtab)
+ if (!ctx.symtab.isEC())
return;
- for (Symbol *s : symtab->expSymbols) {
+ for (Symbol *s : ctx.symtab.expSymbols) {
auto sym = dyn_cast<Defined>(s);
if (!sym || !sym->getChunk())
continue;
@@ -2257,9 +2255,9 @@ void Writer::createECChunks() {
// we should use the #foo$hp_target symbol as the redirection target.
// First, try to look up the $hp_target symbol. If it can't be found,
// assume it's a regular function and look for #foo instead.
- Symbol *targetSym = symtab->find((targetName + "$hp_target").str());
+ Symbol *targetSym = ctx.symtab.find((targetName + "$hp_target").str());
if (!targetSym)
- targetSym = symtab->find(targetName);
+ targetSym = ctx.symtab.find(targetName);
Defined *t = dyn_cast_or_null<Defined>(targetSym);
if (t && isArm64EC(t->getChunk()->getMachine()))
exportThunks.push_back({chunk, t});
@@ -2268,20 +2266,20 @@ void Writer::createECChunks() {
auto codeMapChunk = make<ECCodeMapChunk>(codeMap);
rdataSec->addChunk(codeMapChunk);
- Symbol *codeMapSym = symtab->findUnderscore("__hybrid_code_map");
+ Symbol *codeMapSym = ctx.symtab.findUnderscore("__hybrid_code_map");
replaceSymbol<DefinedSynthetic>(codeMapSym, codeMapSym->getName(),
codeMapChunk);
CHPECodeRangesChunk *ranges = make<CHPECodeRangesChunk>(exportThunks);
rdataSec->addChunk(ranges);
Symbol *rangesSym =
- symtab->findUnderscore("__x64_code_ranges_to_entry_points");
+ ctx.symtab.findUnderscore("__x64_code_ranges_to_entry_points");
replaceSymbol<DefinedSynthetic>(rangesSym, rangesSym->getName(), ranges);
CHPERedirectionChunk *entryPoints = make<CHPERedirectionChunk>(exportThunks);
a64xrmSec->addChunk(entryPoints);
Symbol *entryPointsSym =
- symtab->findUnderscore("__arm64x_redirection_metadata");
+ ctx.symtab.findUnderscore("__arm64x_redirection_metadata");
replaceSymbol<DefinedSynthetic>(entryPointsSym, entryPointsSym->getName(),
entryPoints);
}
@@ -2385,8 +2383,7 @@ void Writer::setSectionPermissions() {
// Set symbols used by ARM64EC metadata.
void Writer::setECSymbols() {
- SymbolTable *symtab = ctx.symtabEC;
- if (!symtab)
+ if (!ctx.symtab.isEC())
return;
llvm::stable_sort(exportThunks, [](const std::pair<Chunk *, Defined *> &a,
@@ -2395,45 +2392,45 @@ void Writer::setECSymbols() {
});
ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
- Symbol *rfeTableSym = symtab->findUnderscore("__arm64x_extra_rfe_table");
+ Symbol *rfeTableSym = ctx.symtab.findUnderscore("__arm64x_extra_rfe_table");
replaceSymbol<DefinedSynthetic>(rfeTableSym, "__arm64x_extra_rfe_table",
chpePdata.first);
if (chpePdata.first) {
Symbol *rfeSizeSym =
- symtab->findUnderscore("__arm64x_extra_rfe_table_size");
+ ctx.symtab.findUnderscore("__arm64x_extra_rfe_table_size");
cast<DefinedAbsolute>(rfeSizeSym)
->setVA(chpePdata.last->getRVA() + chpePdata.last->getSize() -
chpePdata.first->getRVA());
}
Symbol *rangesCountSym =
- symtab->findUnderscore("__x64_code_ranges_to_entry_points_count");
+ ctx.symtab.findUnderscore("__x64_code_ranges_to_entry_points_count");
cast<DefinedAbsolute>(rangesCountSym)->setVA(exportThunks.size());
Symbol *entryPointCountSym =
- symtab->findUnderscore("__arm64x_redirection_metadata_count");
+ ctx.symtab.findUnderscore("__arm64x_redirection_metadata_count");
cast<DefinedAbsolute>(entryPointCountSym)->setVA(exportThunks.size());
- Symbol *iatSym = symtab->findUnderscore("__hybrid_auxiliary_iat");
+ Symbol *iatSym = ctx.symtab.findUnderscore("__hybrid_auxiliary_iat");
replaceSymbol<DefinedSynthetic>(iatSym, "__hybrid_auxiliary_iat",
idata.auxIat.empty() ? nullptr
: idata.auxIat.front());
- Symbol *iatCopySym = symtab->findUnderscore("__hybrid_auxiliary_iat_copy");
+ Symbol *iatCopySym = ctx.symtab.findUnderscore("__hybrid_auxiliary_iat_copy");
replaceSymbol<DefinedSynthetic>(
iatCopySym, "__hybrid_auxiliary_iat_copy",
idata.auxIatCopy.empty() ? nullptr : idata.auxIatCopy.front());
Symbol *delayIatSym =
- symtab->findUnderscore("__hybrid_auxiliary_delayload_iat");
+ ctx.symtab.findUnderscore("__hybrid_auxiliary_delayload_iat");
replaceSymbol<DefinedSynthetic>(
delayIatSym, "__hybrid_auxiliary_delayload_iat",
delayIdata.getAuxIat().empty() ? nullptr
: delayIdata.getAuxIat().front());
Symbol *delayIatCopySym =
- symtab->findUnderscore("__hybrid_auxiliary_delayload_iat_copy");
+ ctx.symtab.findUnderscore("__hybrid_auxiliary_delayload_iat_copy");
replaceSymbol<DefinedSynthetic>(
delayIatCopySym, "__hybrid_auxiliary_delayload_iat_copy",
delayIdata.getAuxIatCopy().empty() ? nullptr
@@ -2448,16 +2445,16 @@ void Writer::setECSymbols() {
if (auto thunkChunk =
dyn_cast<ECExportThunkChunk>(altEntrySym->getChunk()))
altEntrySym = thunkChunk->target;
- symtab->findUnderscore("__arm64x_native_entrypoint")
+ ctx.symtab.findUnderscore("__arm64x_native_entrypoint")
->replaceKeepingName(altEntrySym, sizeof(SymbolUnion));
}
- if (symtab->edataStart)
+ if (ctx.symtab.edataStart)
ctx.dynamicRelocs->set(
dataDirOffset64 + EXPORT_TABLE * sizeof(data_directory) +
offsetof(data_directory, Size),
- symtab->edataEnd->getRVA() - symtab->edataStart->getRVA() +
- symtab->edataEnd->getSize());
+ ctx.symtab.edataEnd->getRVA() - ctx.symtab.edataStart->getRVA() +
+ ctx.symtab.edataEnd->getSize());
if (hybridPdata.first) {
ctx.dynamicRelocs->set(
dataDirOffset64 + EXCEPTION_TABLE * sizeof(data_directory) +
More information about the llvm-commits
mailing list