Skip to content

Commit f942949

Browse files
authored
[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.
1 parent c4d656a commit f942949

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

lld/COFF/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ struct Configuration {
114114
bool is64() const { return llvm::COFF::is64Bit(machine); }
115115

116116
llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
117+
bool machineInferred = false;
117118
size_t wordsize;
118119
bool verbose = false;
119120
WindowsSubsystem subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;

lld/COFF/SymbolTable.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ static bool compatibleMachineType(COFFLinkerContext &ctx, MachineTypes mt) {
4646
return COFF::isArm64EC(mt) || mt == AMD64;
4747
case ARM64X:
4848
return COFF::isAnyArm64(mt) || mt == AMD64;
49+
case IMAGE_FILE_MACHINE_UNKNOWN:
50+
return true;
4951
default:
5052
return ctx.config.machine == mt;
5153
}
@@ -74,14 +76,26 @@ void SymbolTable::addFile(InputFile *file) {
7476
}
7577

7678
MachineTypes mt = file->getMachineType();
77-
if (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN) {
78-
ctx.config.machine = mt;
79-
ctx.driver.addWinSysRootLibSearchPaths();
80-
} else if (!compatibleMachineType(ctx, mt)) {
79+
// The ARM64EC target must be explicitly specified and cannot be inferred.
80+
if (mt == ARM64EC &&
81+
(ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN ||
82+
(ctx.config.machineInferred &&
83+
(ctx.config.machine == ARM64 || ctx.config.machine == AMD64)))) {
84+
error(toString(file) + ": machine type arm64ec is ambiguous and cannot be "
85+
"inferred, use /machine:arm64ec or /machine:arm64x");
86+
return;
87+
}
88+
if (!compatibleMachineType(ctx, mt)) {
8189
error(toString(file) + ": machine type " + machineToStr(mt) +
8290
" conflicts with " + machineToStr(ctx.config.machine));
8391
return;
8492
}
93+
if (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN &&
94+
mt != IMAGE_FILE_MACHINE_UNKNOWN) {
95+
ctx.config.machineInferred = true;
96+
ctx.config.machine = mt;
97+
ctx.driver.addWinSysRootLibSearchPaths();
98+
}
8599

86100
ctx.driver.parseDirectives(file);
87101
}

lld/test/COFF/arm64ec.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ RUN: split-file %s %t.dir && cd %t.dir
44
RUN: llvm-mc -filetype=obj -triple=aarch64-windows arm64-data-sym.s -o arm64-data-sym.obj
55
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows arm64ec-data-sym.s -o arm64ec-data-sym.obj
66
RUN: llvm-mc -filetype=obj -triple=x86_64-windows x86_64-data-sym.s -o x86_64-data-sym.obj
7+
RUN: llvm-mc -filetype=obj -triple=i686-windows x86_64-data-sym.s -o i686-data-sym.obj
78
RUN: llvm-cvtres -machine:arm64x -out:arm64x-resource.obj %S/Inputs/resource.res
89

910
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
4647
RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT3 %s
4748
INCOMPAT3: lld-link: error: x86_64-data-sym.obj: machine type x64 conflicts with arm64
4849

50+
arm64ec machine type can't be inferred, it must be specified explicitly.
51+
RUN: not lld-link -out:test.dll arm64ec-data-sym.obj \
52+
RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT4 %s
53+
INCOMPAT4: lld-link: error: arm64ec-data-sym.obj: machine type arm64ec is ambiguous and cannot be inferred, use /machine:arm64ec or /machine:arm64x
54+
55+
RUN: not lld-link -out:test.dll x86_64-data-sym.obj arm64ec-data-sym.obj \
56+
RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT4 %s
57+
58+
RUN: not lld-link -out:test.dll arm64-data-sym.obj arm64ec-data-sym.obj \
59+
RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT4 %s
60+
61+
RUN: not lld-link -out:test.dll i686-data-sym.obj arm64ec-data-sym.obj \
62+
RUN: -dll -noentry 2>&1 | FileCheck -check-prefix=INCOMPAT5 %s
63+
INCOMPAT5: lld-link: error: arm64ec-data-sym.obj: machine type arm64ec conflicts with x86
64+
65+
arm64x can be inferred and when mixed with ARM64, the first one wins
66+
RUN: lld-link -out:test.dll -dll -noentry arm64x-resource.obj arm64-data-sym.obj x86_64-data-sym.obj arm64ec-data-sym.obj
67+
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
68+
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
69+
4970
#--- arm64ec-data-sym.s
5071
.data
5172
.globl arm64ec_data_sym

0 commit comments

Comments
 (0)