forked from OSchip/llvm-project
parent
e735b2bae3
commit
4e0b17dd3c
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "lld/Core/File.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace lld {
|
||||
|
||||
///
|
||||
|
@ -36,6 +38,10 @@ public:
|
|||
virtual error_code
|
||||
parseAllMembers(std::vector<std::unique_ptr<File>> &result) const = 0;
|
||||
|
||||
virtual std::set<StringRef> getDefinedSymbols() const {
|
||||
return std::set<StringRef>();
|
||||
}
|
||||
|
||||
protected:
|
||||
/// only subclasses of ArchiveLibraryFile can be instantiated
|
||||
ArchiveLibraryFile(StringRef path) : File(path, kindArchiveLibrary) {}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
@ -67,6 +68,11 @@ public:
|
|||
/// whether it should iterate over again or terminate or not.
|
||||
void notifyProgress();
|
||||
|
||||
/// Adds an observer of getNextFile(). Each time a new file is about to be
|
||||
/// returned from getNextFile(), registered observers are called with the file
|
||||
/// being returned.
|
||||
void registerObserver(std::function<void(File*)> &fn);
|
||||
|
||||
/// \brief Adds a node into the InputGraph
|
||||
void addInputElement(std::unique_ptr<InputElement>);
|
||||
|
||||
|
@ -93,6 +99,7 @@ protected:
|
|||
// Index of the next element to be processed
|
||||
uint32_t _nextElementIndex;
|
||||
InputElement *_currentInputElement;
|
||||
std::vector<std::function<void(File *)>> _observers;
|
||||
|
||||
private:
|
||||
ErrorOr<InputElement *> getNextInputElement();
|
||||
|
|
|
@ -21,9 +21,12 @@ ErrorOr<File &> InputGraph::getNextFile() {
|
|||
// it will succeed. If not, try to get the next file in the input graph.
|
||||
for (;;) {
|
||||
if (_currentInputElement) {
|
||||
ErrorOr<File &> nextFile = _currentInputElement->getNextFile();
|
||||
if (nextFile.getError() != InputGraphError::no_more_files)
|
||||
return std::move(nextFile);
|
||||
ErrorOr<File &> next = _currentInputElement->getNextFile();
|
||||
if (next.getError() != InputGraphError::no_more_files) {
|
||||
for (std::function<void(File*)> &observer : _observers)
|
||||
observer(&next.get());
|
||||
return std::move(next);
|
||||
}
|
||||
}
|
||||
|
||||
ErrorOr<InputElement *> elt = getNextInputElement();
|
||||
|
@ -35,6 +38,10 @@ ErrorOr<File &> InputGraph::getNextFile() {
|
|||
|
||||
void InputGraph::notifyProgress() { _currentInputElement->notifyProgress(); }
|
||||
|
||||
void InputGraph::registerObserver(std::function<void(File*)> &fn) {
|
||||
_observers.push_back(fn);
|
||||
}
|
||||
|
||||
void InputGraph::addInputElement(std::unique_ptr<InputElement> ie) {
|
||||
_inputArgs.push_back(std::move(ie));
|
||||
}
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lld/Core/ArchiveLibraryFile.h"
|
||||
#include "lld/Driver/Driver.h"
|
||||
#include "lld/Driver/WinLinkInputGraph.h"
|
||||
#include "lld/Driver/WinLinkModuleDef.h"
|
||||
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
|
||||
#include "../ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
@ -34,6 +36,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
@ -1293,6 +1296,19 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
|
|||
}
|
||||
}
|
||||
|
||||
if (!isReadingDirectiveSection) {
|
||||
std::unique_ptr<SimpleFileNode> node(new SimpleFileNode("<export>"));
|
||||
pecoff::ExportedSymbolRenameFile *renameFile =
|
||||
new pecoff::ExportedSymbolRenameFile(ctx);
|
||||
node->appendInputFile(std::unique_ptr<File>(renameFile));
|
||||
ctx.getLibraryGroup()->addFile(std::move(node));
|
||||
std::function<void(File *)> observer = [=](File *file) {
|
||||
if (auto *archive = dyn_cast<ArchiveLibraryFile>(file))
|
||||
renameFile->addResolvableSymbols(archive);
|
||||
};
|
||||
ctx.getInputGraph().registerObserver(observer);
|
||||
}
|
||||
|
||||
// Validate the combination of options used.
|
||||
return ctx.validate(diag);
|
||||
}
|
||||
|
|
|
@ -97,6 +97,16 @@ public:
|
|||
return _absoluteAtoms;
|
||||
}
|
||||
|
||||
/// Returns a set of all defined symbols in the archive.
|
||||
std::set<StringRef> getDefinedSymbols() const override {
|
||||
std::set<StringRef> ret;
|
||||
for (const auto &e : _symbolMemberMap) {
|
||||
StringRef sym = e.first;
|
||||
ret.insert(sym);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
error_code
|
||||
instantiateMember(Archive::child_iterator member,
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
|
||||
#include "lld/ReaderWriter/Simple.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace lld {
|
||||
namespace pecoff {
|
||||
|
@ -86,6 +89,18 @@ private:
|
|||
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
|
||||
};
|
||||
|
||||
class SymbolRenameFile : public SimpleFile {
|
||||
public:
|
||||
SymbolRenameFile(StringRef from, StringRef to)
|
||||
: SimpleFile("<symbol-rename>"), _to(*this, to), _from(*this, from, &_to) {
|
||||
addAtom(_from);
|
||||
};
|
||||
|
||||
private:
|
||||
COFFUndefinedAtom _to;
|
||||
COFFUndefinedAtom _from;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// A virtual file containing absolute symbol __ImageBase. __ImageBase (or
|
||||
|
@ -141,5 +156,51 @@ private:
|
|||
mutable llvm::BumpPtrAllocator _alloc;
|
||||
};
|
||||
|
||||
class ExportedSymbolRenameFile : public VirtualArchiveLibraryFile {
|
||||
public:
|
||||
ExportedSymbolRenameFile(const PECOFFLinkingContext &ctx)
|
||||
: VirtualArchiveLibraryFile("<export>") {
|
||||
for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports())
|
||||
_exportedSyms.insert(desc.name);
|
||||
}
|
||||
|
||||
void addResolvableSymbols(ArchiveLibraryFile *archive) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
if (_seen.count(archive) > 0)
|
||||
return;
|
||||
_seen.insert(archive);
|
||||
for (const std::string &sym : archive->getDefinedSymbols())
|
||||
_resolvableSyms.insert(sym);
|
||||
}
|
||||
|
||||
const File *find(StringRef sym, bool dataSymbolOnly) const override {
|
||||
if (_exportedSyms.count(sym) == 0)
|
||||
return nullptr;
|
||||
std::string expsym = sym;
|
||||
expsym.append("@");
|
||||
auto it = _resolvableSyms.lower_bound(expsym);
|
||||
for (auto e = _resolvableSyms.end(); it != e; ++it) {
|
||||
if (!StringRef(*it).startswith(expsym))
|
||||
return nullptr;
|
||||
if (it->size() == expsym.size())
|
||||
continue;
|
||||
StringRef suffix = it->substr(expsym.size());
|
||||
bool digitSuffix =
|
||||
suffix.find_first_not_of("0123456789") == StringRef::npos;
|
||||
if (digitSuffix) {
|
||||
return new (_alloc) SymbolRenameFile(sym, *it);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::string> _exportedSyms;
|
||||
std::set<std::string> _resolvableSyms;
|
||||
std::set<ArchiveLibraryFile *> _seen;
|
||||
mutable std::mutex _mutex;
|
||||
mutable llvm::BumpPtrAllocator _alloc;
|
||||
};
|
||||
|
||||
} // end namespace pecoff
|
||||
} // end namespace lld
|
||||
|
|
Loading…
Reference in New Issue