summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h75
1 files changed, 44 insertions, 31 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h b/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
index 931b1e4a6c6..131d55d18d9 100644
--- a/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
+++ b/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
@@ -161,6 +161,45 @@ private:
mutable llvm::BumpPtrAllocator _alloc;
};
+class ResolvableSymbols {
+public:
+ void add(File *file) {
+ std::lock_guard<std::mutex> lock(_mutex);
+ if (_seen.count(file) > 0)
+ return;
+ _seen.insert(file);
+ _queue.insert(file);
+ }
+
+ const std::set<std::string> &defined() {
+ readAllSymbols();
+ return _defined;
+ }
+
+private:
+ // Files are read lazily, so that it has no runtime overhead if
+ // no one accesses this class.
+ void readAllSymbols() {
+ std::lock_guard<std::mutex> lock(_mutex);
+ for (File *file : _queue) {
+ if (auto *archive = dyn_cast<ArchiveLibraryFile>(file)) {
+ for (const std::string &sym : archive->getDefinedSymbols())
+ _defined.insert(sym);
+ continue;
+ }
+ for (const DefinedAtom *atom : file->defined())
+ if (!atom->name().empty())
+ _defined.insert(atom->name());
+ }
+ _queue.clear();
+ }
+
+ std::set<std::string> _defined;
+ std::set<File *> _seen;
+ std::set<File *> _queue;
+ std::mutex _mutex;
+};
+
// A ExportedSymbolRenameFile is a virtual archive file for dllexported symbols.
//
// One usually has to specify the exact symbol name to resolve it. That's true
@@ -199,18 +238,11 @@ public:
_exportedSyms.insert(desc.name);
}
- void addResolvableSymbols(File *file) {
- std::lock_guard<std::mutex> lock(_mutex);
- if (_seen.count(file) > 0)
- return;
- _seen.insert(file);
- _queue.insert(file);
- }
+ void addResolvableSymbols(File *file) { _syms.add(file); }
const File *find(StringRef sym, bool dataSymbolOnly) const override {
if (_exportedSyms.count(sym) == 0)
return nullptr;
- readAllSymbols();
std::string replace;
if (!findSymbolWithAtsignSuffix(sym.str(), replace))
return nullptr;
@@ -218,29 +250,13 @@ public:
}
private:
- // Files are read lazily, so that it has no runtime overhead if
- // there's no dllexported stdcall functions.
- void readAllSymbols() const {
- std::lock_guard<std::mutex> lock(_mutex);
- for (File *file : _queue) {
- if (auto *archive = dyn_cast<ArchiveLibraryFile>(file)) {
- for (const std::string &sym : archive->getDefinedSymbols())
- _defined.insert(sym);
- continue;
- }
- for (const DefinedAtom *atom : file->defined())
- if (!atom->name().empty())
- _defined.insert(atom->name());
- }
- _queue.clear();
- }
-
// Find a symbol that starts with a given symbol name followed
// by @number suffix.
bool findSymbolWithAtsignSuffix(std::string sym, std::string &res) const {
sym.append("@");
- auto it = _defined.lower_bound(sym);
- for (auto e = _defined.end(); it != e; ++it) {
+ const std::set<std::string> &defined = _syms.defined();
+ auto it = defined.lower_bound(sym);
+ for (auto e = defined.end(); it != e; ++it) {
if (!StringRef(*it).startswith(sym))
return false;
if (it->size() == sym.size())
@@ -255,10 +271,7 @@ private:
}
std::set<std::string> _exportedSyms;
- std::set<File *> _seen;
- mutable std::set<std::string> _defined;
- mutable std::set<File *> _queue;
- mutable std::mutex _mutex;
+ mutable ResolvableSymbols _syms;
mutable llvm::BumpPtrAllocator _alloc;
};
OpenPOWER on IntegriCloud