-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[LLD][COFF] Validate import library machine type. #102738
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lld @llvm/pr-subscribers-platform-windows Author: Jacek Caban (cjacek) ChangesThis depends on #102737 and #102736. Check import library machine type instead of ignoring it. This matches MSVC link.exe's behavior. It will be also useful for ARM64EC, which needs to handle multiple machine types (ARM64EC and x86_64 for pure EC, additionally aarch64 for ARM64X) differently, depending on the type Full diff: https://github.com/llvm/llvm-project/pull/102738.diff 5 Files Affected:
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index fdbe90390f5cac..f9a22b0a7a5f0f 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -724,7 +724,7 @@ std::optional<Symbol *> ObjFile::createDefined(
return createRegular(sym);
}
-MachineTypes ObjFile::getMachineType() {
+MachineTypes ObjFile::getMachineType() const {
if (coffObj)
return static_cast<MachineTypes>(coffObj->getMachine());
return IMAGE_FILE_MACHINE_UNKNOWN;
@@ -987,6 +987,13 @@ void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)
: InputFile(ctx, ImportKind, m), live(!ctx.config.doGC), thunkLive(live) {}
+MachineTypes ImportFile::getMachineType() const {
+ uint16_t machine =
+ reinterpret_cast<const coff_import_header *>(mb.getBufferStart())
+ ->Machine;
+ return MachineTypes(machine);
+}
+
void ImportFile::parse() {
const auto *hdr =
reinterpret_cast<const coff_import_header *>(mb.getBufferStart());
@@ -1139,7 +1146,7 @@ void BitcodeFile::parseLazy() {
ctx.symtab.addLazyObject(this, sym.getName());
}
-MachineTypes BitcodeFile::getMachineType() {
+MachineTypes BitcodeFile::getMachineType() const {
switch (Triple(obj->getTargetTriple()).getArch()) {
case Triple::x86_64:
return AMD64;
@@ -1220,7 +1227,7 @@ void DLLFile::parse() {
}
}
-MachineTypes DLLFile::getMachineType() {
+MachineTypes DLLFile::getMachineType() const {
if (coffObj)
return static_cast<MachineTypes>(coffObj->getMachine());
return IMAGE_FILE_MACHINE_UNKNOWN;
diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h
index cabd87ba673e3c..a332ac87b265e6 100644
--- a/lld/COFF/InputFiles.h
+++ b/lld/COFF/InputFiles.h
@@ -82,7 +82,9 @@ class InputFile {
virtual void parse() = 0;
// Returns the CPU type this file was compiled to.
- virtual MachineTypes getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; }
+ virtual MachineTypes getMachineType() const {
+ return IMAGE_FILE_MACHINE_UNKNOWN;
+ }
MemoryBufferRef mb;
@@ -133,7 +135,7 @@ class ObjFile : public InputFile {
static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
void parse() override;
void parseLazy();
- MachineTypes getMachineType() override;
+ MachineTypes getMachineType() const override;
ArrayRef<Chunk *> getChunks() { return chunks; }
ArrayRef<SectionChunk *> getDebugChunks() { return debugChunks; }
ArrayRef<SectionChunk *> getSXDataChunks() { return sxDataChunks; }
@@ -342,6 +344,7 @@ class ImportFile : public InputFile {
explicit ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m);
static bool classof(const InputFile *f) { return f->kind() == ImportKind; }
+ MachineTypes getMachineType() const override;
Symbol *impSym = nullptr;
Symbol *thunkSym = nullptr;
@@ -376,7 +379,7 @@ class BitcodeFile : public InputFile {
~BitcodeFile();
static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
ArrayRef<Symbol *> getSymbols() { return symbols; }
- MachineTypes getMachineType() override;
+ MachineTypes getMachineType() const override;
void parseLazy();
std::unique_ptr<llvm::lto::InputFile> obj;
@@ -393,7 +396,7 @@ class DLLFile : public InputFile {
: InputFile(ctx, DLLKind, m) {}
static bool classof(const InputFile *f) { return f->kind() == DLLKind; }
void parse() override;
- MachineTypes getMachineType() override;
+ MachineTypes getMachineType() const override;
struct Symbol {
StringRef dllName;
diff --git a/lld/test/COFF/Inputs/except_handler3.lib b/lld/test/COFF/Inputs/except_handler3.lib
deleted file mode 100644
index fdc51ed7328555..00000000000000
Binary files a/lld/test/COFF/Inputs/except_handler3.lib and /dev/null differ
diff --git a/lld/test/COFF/implib-machine.s b/lld/test/COFF/implib-machine.s
new file mode 100644
index 00000000000000..32deff0fc25f89
--- /dev/null
+++ b/lld/test/COFF/implib-machine.s
@@ -0,0 +1,32 @@
+# REQUIRES: x86
+# RUN: split-file %s %t.dir
+# RUN: llvm-lib -machine:i386 -out:%t.dir/test32.lib -def:%t.dir/test32.def
+# RUN: llvm-lib -machine:amd64 -out:%t.dir/test64.lib -def:%t.dir/test64.def
+# RUN: llvm-mc -triple i686-windows-msvc %t.dir/test.s -filetype=obj -o %t.dir/test32.obj
+# RUN: llvm-mc -triple x86_64-windows-msvc %t.dir/test.s -filetype=obj -o %t.dir/test64.obj
+
+# RUN: not lld-link -dll -noentry -out:%t32.dll %t.dir/test32.obj %t.dir/test64.lib 2>&1 | FileCheck --check-prefix=ERR32 %s
+# ERR32: error: test.dll: machine type x64 conflicts with x86
+
+# RUN: not lld-link -dll -noentry -out:%t64.dll %t.dir/test64.obj %t.dir/test32.lib 2>&1 | FileCheck --check-prefix=ERR64 %s
+# ERR64: error: test.dll: machine type x86 conflicts with x64
+
+#--- test.s
+ .def @feat.00;
+ .scl 3;
+ .type 0;
+ .endef
+ .globl @feat.00
+@feat.00 = 1
+ .data
+ .rva __imp__test
+
+#--- test32.def
+NAME test.dll
+EXPORTS
+ test DATA
+
+#--- test64.def
+NAME test.dll
+EXPORTS
+ _test DATA
diff --git a/lld/test/COFF/safeseh-md.s b/lld/test/COFF/safeseh-md.s
index d065af872b8f90..fda09fda64ede4 100644
--- a/lld/test/COFF/safeseh-md.s
+++ b/lld/test/COFF/safeseh-md.s
@@ -1,12 +1,15 @@
# REQUIRES: x86
-# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
-# RUN: lld-link %t.obj %S/Inputs/except_handler3.lib -safeseh -out:%t.exe -opt:noref -entry:main
+# RUN: split-file %s %t.dir
+# RUN: llvm-mc -triple i686-windows-msvc %t.dir/safeseh-md.s -filetype=obj -o %t.obj
+# RUN: llvm-lib -machine:x86 -out:%t.dir/except_handler3.lib -def:%t.dir/except_handler3.def
+# RUN: lld-link %t.obj %t.dir/except_handler3.lib -safeseh -out:%t.exe -opt:noref -entry:main
# RUN: llvm-readobj --coff-load-config %t.exe | FileCheck %s
# CHECK: SEHTable [
# CHECK-NEXT: 0x
# CHECK-NEXT: ]
+#--- safeseh-md.s
.def @feat.00;
.scl 3;
.type 0;
@@ -33,3 +36,8 @@ __load_config_used:
.fill 60, 1, 0
.long ___safe_se_handler_table
.long ___safe_se_handler_count
+
+#--- except_handler3.def
+NAME except_handler3.dll
+EXPORTS
+ _except_handler3
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind rebasing please after landing the other two PRs?
Rebased, thanks for reviews. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/30/builds/3785 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/2999 Here is the relevant piece of the build log for the reference:
|
# RUN: llvm-mc -triple x86_64-windows-msvc %t.dir/test.s -filetype=obj -o %t.dir/test64.obj | ||
|
||
# RUN: not lld-link -dll -noentry -out:%t32.dll %t.dir/test32.obj %t.dir/test64.lib 2>&1 | FileCheck --check-prefix=ERR32 %s | ||
# ERR32: error: test.dll: machine type x64 conflicts with x86 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The machine type is on "test64.lib", so shouldn't that be used in the error message instead? Otherwise it can get pretty confusing for a user to track down where "test.dll" comes from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The machine type is a property of import file, which is what's printed here. Import file is a member or an archive ("test64.lib" in this case) and I agree that it would be more informative to print that information. That's what we do for other member types, import files are an exception in this case. It's easy to change, I will create a PR.
This depends on #102737 and #102736.
Check import library machine type instead of ignoring it. This matches MSVC link.exe's behavior. It will be also useful for ARM64EC, which needs to handle multiple machine types (ARM64EC and x86_64 for pure EC, additionally aarch64 for ARM64X) differently, depending on the type