Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lld/COFF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 18 additions & 4 deletions lld/COFF/SymbolTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down
21 changes: 21 additions & 0 deletions lld/test/COFF/arm64ec.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading