[lld] f942949 - [LLD][COFF] Require explicit specification of ARM64EC target (#116281)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 24 05:33:17 PST 2024
Author: Jacek Caban
Date: 2024-11-24T14:33:14+01:00
New Revision: f942949a7cf16a082eb43943b2a4f93f9180556f
URL: https://github.com/llvm/llvm-project/commit/f942949a7cf16a082eb43943b2a4f93f9180556f
DIFF: https://github.com/llvm/llvm-project/commit/f942949a7cf16a082eb43943b2a4f93f9180556f.diff
LOG: [LLD][COFF] Require explicit specification of ARM64EC target (#116281)
Inferring the ARM64EC target can lead to errors. The `-machine:arm64ec`
option may include x86_64 input files, and any valid ARM64EC input is
also valid for `-machine:arm64x`. MSVC requires an explicit `-machine`
argument with informative diagnostics; this patch adopts the same
behavior.
Added:
Modified:
lld/COFF/Config.h
lld/COFF/SymbolTable.cpp
lld/test/COFF/arm64ec.test
Removed:
################################################################################
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 3d416e6985d02c..57cb443798cd8f 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -114,6 +114,7 @@ struct Configuration {
bool is64() const { return llvm::COFF::is64Bit(machine); }
llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
+ bool machineInferred = false;
size_t wordsize;
bool verbose = false;
WindowsSubsystem subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index df3c5a176b52e0..0c6df701284b7d 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -46,6 +46,8 @@ static bool compatibleMachineType(COFFLinkerContext &ctx, MachineTypes mt) {
return COFF::isArm64EC(mt) || mt == AMD64;
case ARM64X:
return COFF::isAnyArm64(mt) || mt == AMD64;
+ case IMAGE_FILE_MACHINE_UNKNOWN:
+ return true;
default:
return ctx.config.machine == mt;
}
@@ -74,14 +76,26 @@ void SymbolTable::addFile(InputFile *file) {
}
MachineTypes mt = file->getMachineType();
- if (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN) {
- ctx.config.machine = mt;
- ctx.driver.addWinSysRootLibSearchPaths();
- } else if (!compatibleMachineType(ctx, mt)) {
+ // The ARM64EC target must be explicitly specified and cannot be inferred.
+ if (mt == ARM64EC &&
+ (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN ||
+ (ctx.config.machineInferred &&
+ (ctx.config.machine == ARM64 || ctx.config.machine == AMD64)))) {
+ error(toString(file) + ": machine type arm64ec is ambiguous and cannot be "
+ "inferred, use /machine:arm64ec or /machine:arm64x");
+ return;
+ }
+ if (!compatibleMachineType(ctx, mt)) {
error(toString(file) + ": machine type " + machineToStr(mt) +
" conflicts with " + machineToStr(ctx.config.machine));
return;
}
+ if (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN &&
+ mt != IMAGE_FILE_MACHINE_UNKNOWN) {
+ ctx.config.machineInferred = true;
+ ctx.config.machine = mt;
+ ctx.driver.addWinSysRootLibSearchPaths();
+ }
ctx.driver.parseDirectives(file);
}
diff --git a/lld/test/COFF/arm64ec.test b/lld/test/COFF/arm64ec.test
index e50b14ce0184c8..75288e97e598dd 100644
--- a/lld/test/COFF/arm64ec.test
+++ b/lld/test/COFF/arm64ec.test
@@ -4,6 +4,7 @@ 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: llvm-mc -filetype=obj -triple=x86_64-windows x86_64-data-sym.s -o x86_64-data-sym.obj
+RUN: llvm-mc -filetype=obj -triple=i686-windows x86_64-data-sym.s -o i686-data-sym.obj
RUN: llvm-cvtres -machine:arm64x -out:arm64x-resource.obj %S/Inputs/resource.res
RUN: lld-link -out:test.dll -machine:arm64ec arm64ec-data-sym.obj -dll -noentry
@@ -46,6 +47,26 @@ RUN: not lld-link -out:test.dll -machine:arm64 arm64-data-sym.obj x86_64-data-sy
RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT3 %s
INCOMPAT3: lld-link: error: x86_64-data-sym.obj: machine type x64 conflicts with arm64
+arm64ec machine type can't be inferred, it must be specified explicitly.
+RUN: not lld-link -out:test.dll arm64ec-data-sym.obj \
+RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT4 %s
+INCOMPAT4: lld-link: error: arm64ec-data-sym.obj: machine type arm64ec is ambiguous and cannot be inferred, use /machine:arm64ec or /machine:arm64x
+
+RUN: not lld-link -out:test.dll x86_64-data-sym.obj arm64ec-data-sym.obj \
+RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT4 %s
+
+RUN: not lld-link -out:test.dll arm64-data-sym.obj arm64ec-data-sym.obj \
+RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT4 %s
+
+RUN: not lld-link -out:test.dll i686-data-sym.obj arm64ec-data-sym.obj \
+RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT5 %s
+INCOMPAT5: lld-link: error: arm64ec-data-sym.obj: machine type arm64ec conflicts with x86
+
+arm64x can be inferred and when mixed with ARM64, the first one wins
+RUN: lld-link -out:test.dll -dll -noentry arm64x-resource.obj arm64-data-sym.obj x86_64-data-sym.obj arm64ec-data-sym.obj
+RUN: not lld-link -out:test.dll -dll -noentry arm64-data-sym.obj arm64x-resource.obj x86_64-data-sym.obj 2>&1 | FileCheck -check-prefix=INCOMPAT3 %s
+RUN: not lld-link -out:test.dll -dll -noentry arm64-data-sym.obj arm64x-resource.obj arm64ec-data-sym.obj 2>&1 | FileCheck -check-prefix=INCOMPAT4 %s
+
#--- arm64ec-data-sym.s
.data
.globl arm64ec_data_sym
More information about the llvm-commits
mailing list