diff options
author | Nick Kledzik <kledzik@apple.com> | 2014-09-03 19:52:50 +0000 |
---|---|---|
committer | Nick Kledzik <kledzik@apple.com> | 2014-09-03 19:52:50 +0000 |
commit | 141330aef62f4a753622441d11a756cfc72bde94 (patch) | |
tree | 151ebf036f9dcb9928fd0af08167f4a6fbb4b92f /lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp | |
parent | ed9709d928ff3684bc1d646badcf068689ce232d (diff) | |
download | bcm5719-llvm-141330aef62f4a753622441d11a756cfc72bde94.tar.gz bcm5719-llvm-141330aef62f4a753622441d11a756cfc72bde94.zip |
[mach-o] Add support for using export tries
On Darwin at runtime, dyld will prefer to use the export trie of a dylib instead
of the traditional symbol table (which is large and requires a binary search).
This change enables the linker to generate an export trie and to prefer it if
found in a dylib being linked against. This also simples the yaml for dylibs
because the yaml form of the trie can be reduced to just a sequence of names.
llvm-svn: 217066
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp')
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp index fc43141ca24..6fcee3bf059 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp @@ -33,6 +33,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" +#include "llvm/Object/MachO.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Errc.h" #include "llvm/Support/ErrorHandling.h" @@ -45,6 +46,8 @@ #include <system_error> using namespace llvm::MachO; +using llvm::object::ExportEntry; +using llvm::object::MachOObjectFile; namespace lld { namespace mach_o { @@ -231,6 +234,7 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, // Walk load commands looking for segments/sections and the symbol table. const data_in_code_entry *dataInCode = nullptr; + const dyld_info_command *dyldInfo = nullptr; uint32_t dataInCodeSize = 0; ec = forEachLoadCommand(lcRange, lcCount, swap, is64, [&] (uint32_t cmd, uint32_t size, const char* lc) -> bool { @@ -406,6 +410,7 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, start + read32(swap, ldc->dataoff)); dataInCodeSize = read32(swap, ldc->datasize); } + break; case LC_LOAD_DYLIB: case LC_LOAD_WEAK_DYLIB: case LC_REEXPORT_DYLIB: @@ -417,6 +422,10 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, f->dependentDylibs.push_back(entry); } break; + case LC_DYLD_INFO: + case LC_DYLD_INFO_ONLY: + dyldInfo = reinterpret_cast<const dyld_info_command*>(lc); + break; } return false; }); @@ -434,11 +443,30 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, } } + if (dyldInfo) { + // If any exports, extract and add to normalized exportInfo vector. + if (dyldInfo->export_size) { + const uint8_t *trieStart = reinterpret_cast<const uint8_t*>(start + + dyldInfo->export_off); + ArrayRef<uint8_t> trie(trieStart, dyldInfo->export_size); + for (const ExportEntry &trieExport : MachOObjectFile::exports(trie)) { + Export normExport; + normExport.name = trieExport.name().copy(f->ownedAllocations); + normExport.offset = trieExport.address(); + normExport.kind = ExportSymbolKind(trieExport.flags() & EXPORT_SYMBOL_FLAGS_KIND_MASK); + normExport.flags = trieExport.flags() & ~EXPORT_SYMBOL_FLAGS_KIND_MASK; + normExport.otherOffset = trieExport.other(); + if (!trieExport.otherName().empty()) + normExport.otherName = trieExport.otherName().copy(f->ownedAllocations); + f->exportInfo.push_back(normExport); + } + } + } + return std::move(f); } - class MachOReader : public Reader { public: MachOReader(MachOLinkingContext &ctx) : _ctx(ctx) {} |