Skip to content

Commit b9ee2ac

Browse files
committed
[LinkerWrapper] report on missing libraries
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. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D137180
1 parent 9b3834e commit b9ee2ac

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

clang/test/Driver/linker-wrapper-image.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
116116
// RUN: -fembed-offload-object=%t.out
117117
// RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu \
118-
// RUN: -linker-path /usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP
118+
// RUN: --linker-path=/usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP
119119

120120
// HIP: @.fatbin_image = internal constant [0 x i8] zeroinitializer, section ".hip_fatbin"
121121
// HIP-NEXT: @.fatbin_wrapper = internal constant %fatbin_wrapper { i32 1212764230, i32 1, ptr @.fatbin_image, ptr null }, section ".hipFatBinSegment", align 8

clang/test/Driver/linker-wrapper.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@
115115
// RUN: --image=file=%S/Inputs/dummy-elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx908
116116
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
117117
// RUN: -fembed-offload-object=%t.out
118-
// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -linker-path \
119-
// RUN: /usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP
118+
// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \
119+
// RUN: --linker-path=/usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP
120120

121121
// HIP: lld{{.*}}-flavor gnu --no-undefined -shared -plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx908 -o {{.*}}.out {{.*}}.o
122122
// HIP: lld{{.*}}-flavor gnu --no-undefined -shared -plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx90a -o {{.*}}.out {{.*}}.o
@@ -134,6 +134,12 @@
134134
// LINKER_ARGS: lld{{.*}}-flavor gnu --no-undefined -shared -plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx908 -o {{.*}}.out {{.*}}.o a
135135
// LINKER_ARGS: nvlink{{.*}}-m64 -o {{.*}}.out -arch sm_70 {{.*}}.o a b
136136

137+
// RUN: not clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -ldummy \
138+
// RUN: --linker-path=/usr/bin/ld --device-linker=a --device-linker=nvptx64-nvidia-cuda=b -- \
139+
// RUN: -o a.out 2>&1 | FileCheck %s --check-prefix=MISSING-LIBRARY
140+
141+
// MISSING-LIBRARY: error: unable to find library -ldummy
142+
137143
/// Ensure that temp files aren't leftoever from static libraries.
138144
// RUN: clang-offload-packager -o %t-lib.out \
139145
// RUN: --image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \

clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,7 @@ Optional<std::string> searchLibraryBaseName(StringRef Name, StringRef Root,
12191219
ArrayRef<StringRef> SearchPaths) {
12201220
for (StringRef Dir : SearchPaths) {
12211221
if (Optional<std::string> File = findFile(Dir, Root, "lib" + Name + ".so"))
1222-
return None;
1222+
return File;
12231223
if (Optional<std::string> File = findFile(Dir, Root, "lib" + Name + ".a"))
12241224
return File;
12251225
}
@@ -1266,16 +1266,23 @@ Expected<SmallVector<OffloadFile>> getDeviceInput(const ArgList &Args) {
12661266
return std::move(Err);
12671267
}
12681268

1269-
// Try to extract input from input libraries.
1269+
// Try to extract input from input archive libraries.
12701270
for (const opt::Arg *Arg : Args.filtered(OPT_library)) {
12711271
if (auto Library = searchLibrary(Arg->getValue(), Root, LibraryPaths)) {
12721272
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
12731273
MemoryBuffer::getFileOrSTDIN(*Library);
12741274
if (std::error_code EC = BufferOrErr.getError())
12751275
reportError(createFileError(*Library, EC));
12761276

1277+
if (identify_magic((*BufferOrErr)->getBuffer()) != file_magic::archive)
1278+
continue;
1279+
12771280
if (Error Err = extractOffloadBinaries(**BufferOrErr, LazyInputFiles))
12781281
return std::move(Err);
1282+
} else {
1283+
reportError(createStringError(inconvertibleErrorCode(),
1284+
"unable to find library -l%s",
1285+
Arg->getValue()));
12791286
}
12801287
}
12811288

0 commit comments

Comments
 (0)