Skip to content

[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

Merged
merged 1 commit into from
Aug 11, 2024

Conversation

cjacek
Copy link
Contributor

@cjacek cjacek commented Aug 10, 2024

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

@llvmbot
Copy link
Member

llvmbot commented Aug 10, 2024

@llvm/pr-subscribers-lld
@llvm/pr-subscribers-lld-coff

@llvm/pr-subscribers-platform-windows

Author: Jacek Caban (cjacek)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/102738.diff

5 Files Affected:

  • (modified) lld/COFF/InputFiles.cpp (+10-3)
  • (modified) lld/COFF/InputFiles.h (+7-4)
  • (removed) lld/test/COFF/Inputs/except_handler3.lib ()
  • (added) lld/test/COFF/implib-machine.s (+32)
  • (modified) lld/test/COFF/safeseh-md.s (+10-2)
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

@tru tru requested a review from aganea August 10, 2024 10:36
Copy link
Member

@aganea aganea left a 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?

@cjacek
Copy link
Contributor Author

cjacek commented Aug 10, 2024

Rebased, thanks for reviews.

Copy link
Member

@aganea aganea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@cjacek cjacek merged commit 846dccc into llvm:main Aug 11, 2024
8 checks passed
@cjacek cjacek deleted the implib-machine branch August 11, 2024 17:03
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 11, 2024

LLVM Buildbot has detected a new failure on builder openmp-offload-amdgpu-runtime running on omp-vega20-0 while building lld at step 7 "Add check check-offload".

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:

Step 7 (Add check check-offload) failure: test (failure)
...
PASS: libomptarget :: x86_64-pc-linux-gnu-LTO :: offloading/test_libc.cpp (828 of 837)
PASS: libomptarget :: x86_64-pc-linux-gnu-LTO :: offloading/bug47654.cpp (829 of 837)
PASS: libomptarget :: x86_64-pc-linux-gnu-LTO :: offloading/bug50022.cpp (830 of 837)
PASS: libomptarget :: x86_64-pc-linux-gnu-LTO :: offloading/wtime.c (831 of 837)
PASS: libomptarget :: x86_64-pc-linux-gnu :: offloading/bug49021.cpp (832 of 837)
PASS: libomptarget :: x86_64-pc-linux-gnu :: offloading/std_complex_arithmetic.cpp (833 of 837)
PASS: libomptarget :: x86_64-pc-linux-gnu-LTO :: offloading/complex_reduction.cpp (834 of 837)
PASS: libomptarget :: x86_64-pc-linux-gnu-LTO :: offloading/bug49021.cpp (835 of 837)
PASS: libomptarget :: x86_64-pc-linux-gnu-LTO :: offloading/std_complex_arithmetic.cpp (836 of 837)
TIMEOUT: libomptarget :: amdgcn-amd-amdhsa :: offloading/default_thread_limit.c (837 of 837)
******************** TEST 'libomptarget :: amdgcn-amd-amdhsa :: offloading/default_thread_limit.c' FAILED ********************
Exit Code: -9
Timeout: Reached timeout of 100 seconds

Command Output (stdout):
--
# RUN: at line 2
/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/clang -fopenmp    -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src  -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib  -fopenmp-targets=amdgcn-amd-amdhsa /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/offloading/default_thread_limit.c -o /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/offloading/Output/default_thread_limit.c.tmp /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/clang -fopenmp -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -fopenmp-targets=amdgcn-amd-amdhsa /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/offloading/default_thread_limit.c -o /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/offloading/Output/default_thread_limit.c.tmp /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a
# note: command had no output on stdout or stderr
# RUN: at line 3
env LIBOMPTARGET_INFO=16    /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/offloading/Output/default_thread_limit.c.tmp 2>&1 | /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/offloading/default_thread_limit.c --check-prefix=DEFAULT
# executed command: env LIBOMPTARGET_INFO=16 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/offloading/Output/default_thread_limit.c.tmp
# note: command had no output on stdout or stderr
# error: command failed with exit status: -9
# error: command reached timeout: True
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/offloading/default_thread_limit.c --check-prefix=DEFAULT
# note: command had no output on stdout or stderr
# error: command failed with exit status: -9
# error: command reached timeout: True

--

********************
Slowest Tests:
--------------------------------------------------------------------------
100.05s: libomptarget :: amdgcn-amd-amdhsa :: offloading/default_thread_limit.c
16.41s: libomptarget :: amdgcn-amd-amdhsa :: offloading/bug49021.cpp
12.82s: libomptarget :: amdgcn-amd-amdhsa :: offloading/parallel_target_teams_reduction_max.cpp
12.68s: libomptarget :: amdgcn-amd-amdhsa :: offloading/parallel_target_teams_reduction_min.cpp
11.09s: libomptarget :: amdgcn-amd-amdhsa :: offloading/complex_reduction.cpp
10.24s: libomptarget :: amdgcn-amd-amdhsa :: jit/empty_kernel_lvl2.c
9.14s: libomptarget :: x86_64-pc-linux-gnu :: offloading/bug49021.cpp
8.31s: libomptarget :: amdgcn-amd-amdhsa :: offloading/ompx_saxpy_mixed.c
7.46s: libomptarget :: x86_64-pc-linux-gnu :: offloading/std_complex_arithmetic.cpp
7.17s: libomptarget :: x86_64-pc-linux-gnu :: offloading/complex_reduction.cpp
6.94s: libomptarget :: amdgcn-amd-amdhsa :: offloading/barrier_fence.c
6.64s: libomptarget :: x86_64-pc-linux-gnu-LTO :: offloading/bug49021.cpp
6.09s: libomptarget :: amdgcn-amd-amdhsa :: offloading/parallel_target_teams_reduction.cpp

@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 11, 2024

LLVM Buildbot has detected a new failure on builder lldb-aarch64-ubuntu running on linaro-lldb-aarch64-ubuntu while building lld at step 6 "test".

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:

Step 6 (test) failure: build (failure)
...
PASS: lldb-unit :: ValueObject/./LLDBValueObjectTests/2/3 (1993 of 2002)
PASS: lldb-unit :: Utility/./UtilityTests/0/8 (1994 of 2002)
PASS: lldb-unit :: tools/lldb-server/tests/./LLDBServerTests/0/2 (1995 of 2002)
PASS: lldb-unit :: tools/lldb-server/tests/./LLDBServerTests/1/2 (1996 of 2002)
PASS: lldb-unit :: Utility/./UtilityTests/5/8 (1997 of 2002)
PASS: lldb-unit :: Utility/./UtilityTests/6/8 (1998 of 2002)
PASS: lldb-unit :: Host/./HostTests/2/11 (1999 of 2002)
PASS: lldb-unit :: Process/gdb-remote/./ProcessGdbRemoteTests/8/10 (2000 of 2002)
PASS: lldb-api :: tools/lldb-server/TestLldbGdbServer.py (2001 of 2002)
TIMEOUT: lldb-api :: functionalities/single-thread-step/TestSingleThreadStepTimeout.py (2002 of 2002)
******************** TEST 'lldb-api :: functionalities/single-thread-step/TestSingleThreadStepTimeout.py' FAILED ********************
Script:
--
/usr/bin/python3.8 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env ARCHIVER=/usr/local/bin/llvm-ar --env OBJCOPY=/usr/bin/llvm-objcopy --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --arch aarch64 --build-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/dsymutil --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/single-thread-step -p TestSingleThreadStepTimeout.py
--
Exit Code: -9
Timeout: Reached timeout of 600 seconds

Command Output (stdout):
--
lldb version 20.0.0git (https://github.com/llvm/llvm-project.git revision 846dccce9cd030a1984a4d4336267cd2850e6bd8)
  clang revision 846dccce9cd030a1984a4d4336267cd2850e6bd8
  llvm revision 846dccce9cd030a1984a4d4336267cd2850e6bd8

--

********************
********************
Timed Out Tests (1):
  lldb-api :: functionalities/single-thread-step/TestSingleThreadStepTimeout.py


Testing Time: 686.79s

Total Discovered Tests: 3006
  Unsupported      :  490 (16.30%)
  Passed           : 2492 (82.90%)
  Expectedly Failed:   23 (0.77%)
  Timed Out        :    1 (0.03%)
FAILED: tools/lldb/test/CMakeFiles/check-lldb /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/CMakeFiles/check-lldb 
cd /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test && /usr/bin/python3.8 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/llvm-lit -v /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test
ninja: build stopped: subcommand failed.

# 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
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants