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