summaryrefslogtreecommitdiff
path: root/lld/lib/ReaderWriter/MachO/File.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /lld/lib/ReaderWriter/MachO/File.h
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/File.h')
-rw-r--r--lld/lib/ReaderWriter/MachO/File.h72
1 files changed, 70 insertions, 2 deletions
diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h
index 072702973f81..8d59656beab5 100644
--- a/lld/lib/ReaderWriter/MachO/File.h
+++ b/lld/lib/ReaderWriter/MachO/File.h
@@ -17,6 +17,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Format.h"
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+#include "llvm/TextAPI/MachO/TextAPIReader.h"
#include <unordered_map>
namespace lld {
@@ -322,7 +324,8 @@ public:
void loadReExportedDylibs(FindDylib find) {
for (ReExportedDylib &entry : _reExportedDylibs) {
- entry.file = find(entry.path);
+ if (!entry.file)
+ entry.file = find(entry.path);
}
}
@@ -339,7 +342,7 @@ public:
return std::error_code();
}
-private:
+protected:
OwningAtomPtr<SharedLibraryAtom> exports(StringRef name,
StringRef installName) const {
// First, check if requested symbol is directly implemented by this dylib.
@@ -373,6 +376,7 @@ private:
struct ReExportedDylib {
ReExportedDylib(StringRef p) : path(p), file(nullptr) { }
+ ReExportedDylib(StringRef p, MachODylibFile *file) : path(p), file(file) { }
StringRef path;
MachODylibFile *file;
};
@@ -393,6 +397,70 @@ private:
mutable std::unordered_map<StringRef, AtomAndFlags> _nameToAtom;
};
+class TAPIFile : public MachODylibFile {
+public:
+
+ TAPIFile(std::unique_ptr<MemoryBuffer> mb, MachOLinkingContext *ctx)
+ : MachODylibFile(std::move(mb), ctx) {}
+
+ std::error_code doParse() override {
+
+ llvm::Expected<std::unique_ptr<llvm::MachO::InterfaceFile>> result =
+ llvm::MachO::TextAPIReader::get(*_mb);
+ if (!result)
+ return std::make_error_code(std::errc::invalid_argument);
+
+ std::unique_ptr<llvm::MachO::InterfaceFile> interface{std::move(*result)};
+ return loadFromInterface(*interface);
+ }
+
+private:
+ std::error_code loadFromInterface(llvm::MachO::InterfaceFile &interface) {
+ llvm::MachO::Architecture arch;
+ switch(_ctx->arch()) {
+ case MachOLinkingContext::arch_x86:
+ arch = llvm::MachO::AK_i386;
+ break;
+ case MachOLinkingContext::arch_x86_64:
+ arch = llvm::MachO::AK_x86_64;
+ break;
+ case MachOLinkingContext::arch_arm64:
+ arch = llvm::MachO::AK_arm64;
+ break;
+ default:
+ return std::make_error_code(std::errc::invalid_argument);
+ }
+
+ setInstallName(interface.getInstallName().copy(allocator()));
+ // TODO(compnerd) filter out symbols based on the target platform
+ for (const auto symbol : interface.symbols())
+ if (symbol->getArchitectures().has(arch))
+ addExportedSymbol(symbol->getName(), symbol->isWeakDefined(), true);
+
+ for (const llvm::MachO::InterfaceFileRef &reexport :
+ interface.reexportedLibraries())
+ addReExportedDylib(reexport.getInstallName().copy(allocator()));
+
+ for (const auto& document : interface.documents()) {
+ for (auto& reexport : _reExportedDylibs) {
+ if (reexport.path != document->getInstallName())
+ continue;
+ assert(!reexport.file);
+ _ownedFiles.push_back(std::make_unique<TAPIFile>(
+ MemoryBuffer::getMemBuffer("", _mb->getBufferIdentifier()), _ctx));
+ reexport.file = _ownedFiles.back().get();
+ std::error_code err = _ownedFiles.back()->loadFromInterface(*document);
+ if (err)
+ return err;
+ }
+ }
+
+ return std::error_code();
+ }
+
+ std::vector<std::unique_ptr<TAPIFile>> _ownedFiles;
+};
+
} // end namespace mach_o
} // end namespace lld