From 04601fb1cd19a358d6abdfd41190b7a6a788f9c6 Mon Sep 17 00:00:00 2001 From: gnezdo Date: Fri, 4 Mar 2022 16:46:23 +0000 Subject: [PATCH] Report versioned lib.so in cc --print-file-name given short name E.g. `cc --print-file-name libc.so` reports /usr/lib/libc.so.96.1 This is a complement of the major.minor finding logic in DriverUtils. `ld -lc -L/usr/lib` currently find the libraries with this logic. To make things more obviously related the code was extracted into a function which was copied over verbatim. fine with mortimer@ ok patrick@ --- gnu/llvm/clang/lib/Driver/Driver.cpp | 54 +++++++++++++++++++++++-- gnu/llvm/lld/ELF/DriverUtils.cpp | 60 ++++++++++++++++------------ 2 files changed, 85 insertions(+), 29 deletions(-) diff --git a/gnu/llvm/clang/lib/Driver/Driver.cpp b/gnu/llvm/clang/lib/Driver/Driver.cpp index 94a7553e273..399c37d15ab 100644 --- a/gnu/llvm/clang/lib/Driver/Driver.cpp +++ b/gnu/llvm/clang/lib/Driver/Driver.cpp @@ -5089,7 +5089,50 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, } } + +namespace { +static Optional findFile(StringRef path1, const Twine &path2) { + SmallString<128> s; + llvm::sys::path::append(s, path1, path2); + + if (llvm::sys::fs::exists(s)) + return std::string(s); + return None; +} + +// Must be in sync with findMajMinShlib in lld/ELF/DriverUtils.cpp. +llvm::Optional findMajMinShlib(StringRef dir, const Twine& libNameSo) { + // Handle OpenBSD-style maj/min shlib scheme + llvm::SmallString<128> Scratch; + const StringRef LibName = (libNameSo + ".").toStringRef(Scratch); + int MaxMaj = -1, MaxMin = -1; + std::error_code EC; + for (llvm::sys::fs::directory_iterator LI(dir, EC), LE; + LI != LE; LI = LI.increment(EC)) { + StringRef FilePath = LI->path(); + StringRef FileName = llvm::sys::path::filename(FilePath); + if (!(FileName.startswith(LibName))) + continue; + std::pair MajMin = + FileName.substr(LibName.size()).split('.'); + int Maj, Min; + if (MajMin.first.getAsInteger(10, Maj) || Maj < 0) + continue; + if (MajMin.second.getAsInteger(10, Min) || Min < 0) + continue; + if (Maj > MaxMaj) + MaxMaj = Maj, MaxMin = Min; + if (MaxMaj == Maj && Min > MaxMin) + MaxMin = Min; + } + if (MaxMaj >= 0) + return findFile(dir, LibName + Twine(MaxMaj) + "." + Twine(MaxMin)); + return None; +} +} // namespace + std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const { + const bool lookForLibDotSo = Name.startswith("lib") && Name.endswith(".so"); // Search for Name in a list of paths. auto SearchPaths = [&](const llvm::SmallVectorImpl &P) -> llvm::Optional { @@ -5099,9 +5142,14 @@ std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const { if (Dir.empty()) continue; SmallString<128> P(Dir[0] == '=' ? SysRoot + Dir.substr(1) : Dir); - llvm::sys::path::append(P, Name); - if (llvm::sys::fs::exists(Twine(P))) - return std::string(P); + if (!lookForLibDotSo) { + llvm::sys::path::append(P, Name); + if (llvm::sys::fs::exists(Twine(P))) + return std::string(P); + } else { + if (auto s = findMajMinShlib(P, Name)) + return std::string(*s); + } } return None; }; diff --git a/gnu/llvm/lld/ELF/DriverUtils.cpp b/gnu/llvm/lld/ELF/DriverUtils.cpp index 6b164e30677..2fee8538913 100644 --- a/gnu/llvm/lld/ELF/DriverUtils.cpp +++ b/gnu/llvm/lld/ELF/DriverUtils.cpp @@ -230,6 +230,38 @@ Optional elf::findFromSearchPaths(StringRef path) { return None; } +namespace { +// Must be in sync with findMajMinShlib in clang/lib/Driver/Driver.cpp. +llvm::Optional findMajMinShlib(StringRef dir, const Twine& libNameSo) { + // Handle OpenBSD-style maj/min shlib scheme + llvm::SmallString<128> Scratch; + const StringRef LibName = (libNameSo + ".").toStringRef(Scratch); + int MaxMaj = -1, MaxMin = -1; + std::error_code EC; + for (llvm::sys::fs::directory_iterator LI(dir, EC), LE; + LI != LE; LI = LI.increment(EC)) { + StringRef FilePath = LI->path(); + StringRef FileName = llvm::sys::path::filename(FilePath); + if (!(FileName.startswith(LibName))) + continue; + std::pair MajMin = + FileName.substr(LibName.size()).split('.'); + int Maj, Min; + if (MajMin.first.getAsInteger(10, Maj) || Maj < 0) + continue; + if (MajMin.second.getAsInteger(10, Min) || Min < 0) + continue; + if (Maj > MaxMaj) + MaxMaj = Maj, MaxMin = Min; + if (MaxMaj == Maj && Min > MaxMin) + MaxMin = Min; + } + if (MaxMaj >= 0) + return findFile(dir, LibName + Twine(MaxMaj) + "." + Twine(MaxMin)); + return None; +} +} // namespace + // This is for -l. We'll look for lib.so or lib.a from // search paths. Optional elf::searchLibraryBaseName(StringRef name) { @@ -237,32 +269,8 @@ Optional elf::searchLibraryBaseName(StringRef name) { if (!config->isStatic) { if (Optional s = findFile(dir, "lib" + name + ".so")) return s; - - // Handle OpenBSD-style maj/min shlib scheme - llvm::SmallString<128> Scratch; - const StringRef LibName = ("lib" + name + ".so.").toStringRef(Scratch); - int MaxMaj = -1, MaxMin = -1; - std::error_code EC; - for (fs::directory_iterator LI(dir, EC), LE; - LI != LE; LI = LI.increment(EC)) { - StringRef FilePath = LI->path(); - StringRef FileName = path::filename(FilePath); - if (!(FileName.startswith(LibName))) - continue; - std::pair MajMin = - FileName.substr(LibName.size()).split('.'); - int Maj, Min; - if (MajMin.first.getAsInteger(10, Maj) || Maj < 0) - continue; - if (MajMin.second.getAsInteger(10, Min) || Min < 0) - continue; - if (Maj > MaxMaj) - MaxMaj = Maj, MaxMin = Min; - if (MaxMaj == Maj && Min > MaxMin) - MaxMin = Min; - } - if (MaxMaj >= 0) - return findFile(dir, LibName + Twine(MaxMaj) + "." + Twine(MaxMin)); + if (Optional s = findMajMinShlib(dir, "lib" + name + ".so")) + return s; } if (Optional s = findFile(dir, "lib" + name + ".a")) return s; -- 2.20.1