Skip to content

Commit 05fef6b

Browse files
committed
Fix minor issues
1 parent d5ab06c commit 05fef6b

File tree

9 files changed

+448
-203
lines changed

9 files changed

+448
-203
lines changed

llvm/include/llvm/ExecutionEngine/Orc/Shared/AutoLoadDylibUtils.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,27 @@ constexpr uint32_t log2u(std::uint32_t n) {
2929
return (n > 1) ? 1 + log2u(n >> 1) : 0;
3030
}
3131

32+
extern const char *const kEnvDelim;
33+
34+
enum class SplitMode {
35+
PruneNonExistant, ///< Don't add non-existant paths into output
36+
FailNonExistant, ///< Fail on any non-existant paths
37+
AllowNonExistant ///< Add all paths whether they exist or not
38+
};
39+
40+
/// Collect the constituant paths from a PATH string.
41+
/// /bin:/usr/bin:/usr/local/bin -> {/bin, /usr/bin, /usr/local/bin}
42+
bool SplitPaths(llvm::StringRef PathStr,
43+
llvm::SmallVectorImpl<llvm::StringRef> &Paths,
44+
SplitMode Mode = SplitMode::PruneNonExistant,
45+
llvm::StringRef Delim = kEnvDelim, bool Verbose = false);
46+
47+
///
48+
bool GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string> &Paths);
49+
50+
/// Returns a normalized version of the given Path
51+
std::string NormalizePath(const std::string &Path);
52+
3253
class BloomFilter {
3354
private:
3455
static constexpr int Bits = 8 * sizeof(uint64_t);

llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/AutoLoadDylibLookup.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,6 @@ namespace llvm {
2222
namespace orc {
2323
class DynamicLoader;
2424

25-
#if defined(LLVM_ON_UNIX)
26-
const char *const kEnvDelim = ":";
27-
#elif defined(_WIN32)
28-
const char *const kEnvDelim = ";";
29-
#else
30-
#error "Unknown platform (environmental delimiter)"
31-
#endif
32-
3325
class AutoLoadDynamicLibraryLookup {
3426
public:
3527
/// Describes the library search paths.
@@ -140,15 +132,6 @@ class AutoLoadDynamicLibraryLookup {
140132
void BuildGlobalBloomFilter(BloomFilter &Filter) const;
141133
};
142134

143-
enum class SplitMode {
144-
PruneNonExistant, ///< Don't add non-existant paths into output
145-
FailNonExistant, ///< Fail on any non-existant paths
146-
AllowNonExistant ///< Add all paths whether they exist or not
147-
};
148-
149-
bool SplitPaths(StringRef PathStr, SmallVectorImpl<StringRef> &Paths,
150-
SplitMode Mode, StringRef Delim, bool Verbose = false);
151-
152135
} // end namespace orc
153136
} // end namespace llvm
154137

llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ Error AutoLoadDynamicLibrarySearchGenerator::tryToGenerate(
109109

110110
SymbolNameSet CandidateSyms;
111111
for (auto &KV : Symbols) {
112-
if (GlobalFilter.IsInitialized() && !GlobalFilter.MayContain(*KV.first) &&
113-
!ExcludedSymbols.count(*KV.first))
112+
if (GlobalFilter.IsInitialized() && (!GlobalFilter.MayContain(*KV.first) ||
113+
ExcludedSymbols.count(*KV.first)))
114114
continue;
115115

116116
CandidateSyms.insert(KV.first);
@@ -121,12 +121,6 @@ Error AutoLoadDynamicLibrarySearchGenerator::tryToGenerate(
121121

122122
auto Err = tryToResolve(CandidateSyms, [this, &JD, LS = std::move(LS),
123123
CandidateSyms](auto Result) mutable {
124-
auto &ResolveRes = Result->front();
125-
bool IsFilter = GlobalFilter.IsInitialized();
126-
if (!IsFilter && ResolveRes.Filter.has_value()) {
127-
GlobalFilter = std::move(ResolveRes.Filter.value());
128-
}
129-
130124
if (!Result) {
131125
LLVM_DEBUG({
132126
dbgs() << "AutoLoadDynamicLibrarySearchGenerator resolve failed due to "
@@ -135,6 +129,12 @@ Error AutoLoadDynamicLibrarySearchGenerator::tryToGenerate(
135129
return LS.continueLookup(Result.takeError());
136130
}
137131

132+
auto &ResolveRes = Result->front();
133+
bool IsFilter = GlobalFilter.IsInitialized();
134+
if (!IsFilter && ResolveRes.Filter.has_value()) {
135+
GlobalFilter = std::move(ResolveRes.Filter.value());
136+
}
137+
138138
auto &Symbols = ResolveRes.SymbolDef;
139139
assert(Result->size() == 1 && "Results for more than one library returned");
140140
assert(Symbols.size() == CandidateSyms.size() &&
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
//===---------------- AutoLoadDylibUtils.cpp ----------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/ExecutionEngine/Orc/Shared/AutoLoadDylibUtils.h"
10+
11+
#include "llvm/Support/Debug.h"
12+
#include "llvm/Support/DynamicLibrary.h"
13+
#include "llvm/Support/ErrorHandling.h"
14+
#include "llvm/Support/FileSystem.h"
15+
#include "llvm/Support/Path.h"
16+
17+
namespace llvm {
18+
namespace orc {
19+
20+
#if defined(LLVM_ON_UNIX)
21+
const char *const kEnvDelim = ":";
22+
#elif defined(_WIN32)
23+
const char *const kEnvDelim = ";";
24+
#else
25+
#error "Unknown platform (environmental delimiter)"
26+
#endif
27+
28+
#if defined(LLVM_ON_UNIX)
29+
bool Popen(const std::string &Cmd, llvm::SmallVectorImpl<char> &Buf, bool RdE) {
30+
if (FILE *PF = ::popen(RdE ? (Cmd + " 2>&1").c_str() : Cmd.c_str(), "r")) {
31+
Buf.resize(0);
32+
const size_t Chunk = Buf.capacity_in_bytes();
33+
while (true) {
34+
const size_t Len = Buf.size();
35+
Buf.resize(Len + Chunk);
36+
const size_t R = ::fread(&Buf[Len], sizeof(char), Chunk, PF);
37+
if (R < Chunk) {
38+
Buf.resize(Len + R);
39+
break;
40+
}
41+
}
42+
::pclose(PF);
43+
return !Buf.empty();
44+
}
45+
return false;
46+
}
47+
#endif
48+
49+
std::string NormalizePath(const std::string &Path) {
50+
51+
llvm::SmallString<256> Buffer;
52+
std::error_code EC = llvm::sys::fs::real_path(Path, Buffer, true);
53+
if (EC)
54+
return std::string();
55+
return std::string(Buffer.str());
56+
}
57+
58+
static void LogNonExistantDirectory(StringRef Path) {
59+
#define DEBUG_TYPE "LogNonExistantDirectory"
60+
LLVM_DEBUG(dbgs() << " ignoring nonexistent directory \"" << Path << "\"\n");
61+
#undef DEBUG_TYPE
62+
}
63+
64+
bool SplitPaths(StringRef PathStr, SmallVectorImpl<StringRef> &Paths,
65+
SplitMode Mode, StringRef Delim, bool Verbose) {
66+
#define DEBUG_TYPE "SplitPths"
67+
68+
assert(Delim.size() && "Splitting without a delimiter");
69+
70+
#if defined(_WIN32)
71+
// Support using a ':' delimiter on Windows.
72+
const bool WindowsColon = Delim.equals(":");
73+
#endif
74+
75+
bool AllExisted = true;
76+
for (std::pair<StringRef, StringRef> Split = PathStr.split(Delim);
77+
!Split.second.empty(); Split = PathStr.split(Delim)) {
78+
79+
if (!Split.first.empty()) {
80+
bool Exists = sys::fs::is_directory(Split.first);
81+
82+
#if defined(_WIN32)
83+
// Because drive letters will have a colon we have to make sure the split
84+
// occurs at a colon not followed by a path separator.
85+
if (!Exists && WindowsColon && Split.first.size() == 1) {
86+
// Both clang and cl.exe support '\' and '/' path separators.
87+
if (Split.second.front() == '\\' || Split.second.front() == '/') {
88+
const std::pair<StringRef, StringRef> Tmp = Split.second.split(Delim);
89+
// Split.first = 'C', but we want 'C:', so Tmp.first.size()+2
90+
Split.first = StringRef(Split.first.data(), Tmp.first.size() + 2);
91+
Split.second = Tmp.second;
92+
Exists = sys::fs::is_directory(Split.first);
93+
}
94+
}
95+
#endif
96+
97+
AllExisted = AllExisted && Exists;
98+
99+
if (!Exists) {
100+
if (Mode == SplitMode::FailNonExistant) {
101+
if (Verbose) {
102+
// Exiting early, but still log all non-existant paths that we have
103+
LogNonExistantDirectory(Split.first);
104+
while (!Split.second.empty()) {
105+
Split = PathStr.split(Delim);
106+
if (sys::fs::is_directory(Split.first)) {
107+
LLVM_DEBUG(dbgs() << " ignoring directory that exists \""
108+
<< Split.first << "\"\n");
109+
} else
110+
LogNonExistantDirectory(Split.first);
111+
Split = Split.second.split(Delim);
112+
}
113+
if (!sys::fs::is_directory(Split.first))
114+
LogNonExistantDirectory(Split.first);
115+
}
116+
return false;
117+
} else if (Mode == SplitMode::AllowNonExistant)
118+
Paths.push_back(Split.first);
119+
else if (Verbose)
120+
LogNonExistantDirectory(Split.first);
121+
} else
122+
Paths.push_back(Split.first);
123+
}
124+
125+
PathStr = Split.second;
126+
}
127+
128+
// Trim trailing sep in case of A:B:C:D:
129+
if (!PathStr.empty() && PathStr.ends_with(Delim))
130+
PathStr = PathStr.substr(0, PathStr.size() - Delim.size());
131+
132+
if (!PathStr.empty()) {
133+
if (!sys::fs::is_directory(PathStr)) {
134+
AllExisted = false;
135+
if (Mode == SplitMode::AllowNonExistant)
136+
Paths.push_back(PathStr);
137+
else if (Verbose)
138+
LogNonExistantDirectory(PathStr);
139+
} else
140+
Paths.push_back(PathStr);
141+
}
142+
143+
return AllExisted;
144+
145+
#undef DEBUG_TYPE
146+
}
147+
148+
bool GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string> &Paths) {
149+
#if defined(__APPLE__) || defined(__CYGWIN__)
150+
Paths.push_back("/usr/local/lib/");
151+
Paths.push_back("/usr/X11R6/lib/");
152+
Paths.push_back("/usr/lib/");
153+
Paths.push_back("/lib/");
154+
155+
#ifndef __APPLE__
156+
Paths.push_back("/lib/x86_64-linux-gnu/");
157+
Paths.push_back("/usr/local/lib64/");
158+
Paths.push_back("/usr/lib64/");
159+
Paths.push_back("/lib64/");
160+
#endif
161+
#elif defined(LLVM_ON_UNIX)
162+
llvm::SmallString<1024> Buf;
163+
Popen("LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls", Buf, true);
164+
const llvm::StringRef Result = Buf.str();
165+
166+
const std::size_t NPos = std::string::npos;
167+
const std::size_t LD = Result.find("(LD_LIBRARY_PATH)");
168+
std::size_t From = Result.find("search path=", LD == NPos ? 0 : LD);
169+
if (From != NPos) {
170+
std::size_t To = Result.find("(system search path)", From);
171+
if (To != NPos) {
172+
From += 12;
173+
while (To > From && isspace(Result[To - 1]))
174+
--To;
175+
std::string SysPath = Result.substr(From, To - From).str();
176+
SysPath.erase(std::remove_if(SysPath.begin(), SysPath.end(), ::isspace),
177+
SysPath.end());
178+
179+
llvm::SmallVector<llvm::StringRef, 10> CurPaths;
180+
SplitPaths(SysPath, CurPaths);
181+
for (const auto &Path : CurPaths)
182+
Paths.push_back(Path.str());
183+
}
184+
}
185+
#endif
186+
return true;
187+
}
188+
189+
} // namespace orc
190+
} // namespace llvm

llvm/lib/ExecutionEngine/Orc/Shared/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_llvm_component_library(LLVMOrcShared
22
AllocationActions.cpp
3+
AutoLoadDylibUtils.cpp
34
MachOObjectFormat.cpp
45
ObjectFormats.cpp
56
OrcError.cpp

0 commit comments

Comments
 (0)