jhuber6 created this revision.
jhuber6 added reviewers: jdoerfert, tianshilei1992, tra, JonChesterfield.
Herald added a project: All.
jhuber6 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The linker wrapper does its own library searching for static archives
that can contain device code. The device linking phases happen before
the host linking phases so that we can generate the necessary
registration code and link it in with the rest of the code. Previously,
If a library containing needed device code was not found the execution
would continue silently until it failed with undefined symbols. This
patch allows the linker wrapper to perform its own check beforehand to
catch these errors.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137180

Files:
  clang/test/Driver/linker-wrapper.c
  clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp


Index: clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
===================================================================
--- clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -1219,7 +1219,7 @@
                                             ArrayRef<StringRef> SearchPaths) {
   for (StringRef Dir : SearchPaths) {
     if (Optional<std::string> File = findFile(Dir, Root, "lib" + Name + ".so"))
-      return None;
+      return File;
     if (Optional<std::string> File = findFile(Dir, Root, "lib" + Name + ".a"))
       return File;
   }
@@ -1266,7 +1266,7 @@
       return std::move(Err);
   }
 
-  // Try to extract input from input libraries.
+  // Try to extract input from input archive libraries.
   for (const opt::Arg *Arg : Args.filtered(OPT_library)) {
     if (auto Library = searchLibrary(Arg->getValue(), Root, LibraryPaths)) {
       ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
@@ -1274,8 +1274,15 @@
       if (std::error_code EC = BufferOrErr.getError())
         reportError(createFileError(*Library, EC));
 
+      if (identify_magic((*BufferOrErr)->getBuffer()) != file_magic::archive)
+        continue;
+
       if (Error Err = extractOffloadBinaries(**BufferOrErr, LazyInputFiles))
         return std::move(Err);
+    } else {
+      reportError(createStringError(inconvertibleErrorCode(),
+                                    "unable to find library -l%s",
+                                    Arg->getValue()));
     }
   }
 
Index: clang/test/Driver/linker-wrapper.c
===================================================================
--- clang/test/Driver/linker-wrapper.c
+++ clang/test/Driver/linker-wrapper.c
@@ -115,8 +115,8 @@
 // RUN:   
--image=file=%S/Inputs/dummy-elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
 // RUN:   -fembed-offload-object=%t.out
-// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu 
-linker-path \
-// RUN:   /usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP
+// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \
+// RUN:   --linker-path=/usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s 
--check-prefix=HIP
 
 // HIP: lld{{.*}}-flavor gnu --no-undefined -shared 
-plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx908 -o {{.*}}.out 
{{.*}}.o
 // HIP: lld{{.*}}-flavor gnu --no-undefined -shared 
-plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx90a -o {{.*}}.out 
{{.*}}.o
@@ -134,6 +134,12 @@
 // LINKER_ARGS: lld{{.*}}-flavor gnu --no-undefined -shared 
-plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx908 -o {{.*}}.out 
{{.*}}.o a
 // LINKER_ARGS: nvlink{{.*}}-m64 -o {{.*}}.out -arch sm_70 {{.*}}.o a b
 
+// RUN: not clang-linker-wrapper --dry-run 
--host-triple=x86_64-unknown-linux-gnu -ldummy \
+// RUN:   --linker-path=/usr/bin/ld --device-linker=a 
--device-linker=nvptx64-nvidia-cuda=b -- \
+// RUN:   -o a.out 2>&1 | FileCheck %s --check-prefix=MISSING-LIBRARY
+
+// MISSING-LIBRARY: error: unable to find library -ldummy
+
 /// Ensure that temp files aren't leftoever from static libraries.
 // RUN: clang-offload-packager -o %t-lib.out \
 // RUN:   
--image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 \


Index: clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
===================================================================
--- clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -1219,7 +1219,7 @@
                                             ArrayRef<StringRef> SearchPaths) {
   for (StringRef Dir : SearchPaths) {
     if (Optional<std::string> File = findFile(Dir, Root, "lib" + Name + ".so"))
-      return None;
+      return File;
     if (Optional<std::string> File = findFile(Dir, Root, "lib" + Name + ".a"))
       return File;
   }
@@ -1266,7 +1266,7 @@
       return std::move(Err);
   }
 
-  // Try to extract input from input libraries.
+  // Try to extract input from input archive libraries.
   for (const opt::Arg *Arg : Args.filtered(OPT_library)) {
     if (auto Library = searchLibrary(Arg->getValue(), Root, LibraryPaths)) {
       ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
@@ -1274,8 +1274,15 @@
       if (std::error_code EC = BufferOrErr.getError())
         reportError(createFileError(*Library, EC));
 
+      if (identify_magic((*BufferOrErr)->getBuffer()) != file_magic::archive)
+        continue;
+
       if (Error Err = extractOffloadBinaries(**BufferOrErr, LazyInputFiles))
         return std::move(Err);
+    } else {
+      reportError(createStringError(inconvertibleErrorCode(),
+                                    "unable to find library -l%s",
+                                    Arg->getValue()));
     }
   }
 
Index: clang/test/Driver/linker-wrapper.c
===================================================================
--- clang/test/Driver/linker-wrapper.c
+++ clang/test/Driver/linker-wrapper.c
@@ -115,8 +115,8 @@
 // RUN:   --image=file=%S/Inputs/dummy-elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
 // RUN:   -fembed-offload-object=%t.out
-// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -linker-path \
-// RUN:   /usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP
+// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \
+// RUN:   --linker-path=/usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP
 
 // HIP: lld{{.*}}-flavor gnu --no-undefined -shared -plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx908 -o {{.*}}.out {{.*}}.o
 // HIP: lld{{.*}}-flavor gnu --no-undefined -shared -plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx90a -o {{.*}}.out {{.*}}.o
@@ -134,6 +134,12 @@
 // LINKER_ARGS: lld{{.*}}-flavor gnu --no-undefined -shared -plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx908 -o {{.*}}.out {{.*}}.o a
 // LINKER_ARGS: nvlink{{.*}}-m64 -o {{.*}}.out -arch sm_70 {{.*}}.o a b
 
+// RUN: not clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -ldummy \
+// RUN:   --linker-path=/usr/bin/ld --device-linker=a --device-linker=nvptx64-nvidia-cuda=b -- \
+// RUN:   -o a.out 2>&1 | FileCheck %s --check-prefix=MISSING-LIBRARY
+
+// MISSING-LIBRARY: error: unable to find library -ldummy
+
 /// Ensure that temp files aren't leftoever from static libraries.
 // RUN: clang-offload-packager -o %t-lib.out \
 // RUN:   --image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to