summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2014-09-03 19:52:50 +0000
committerNick Kledzik <kledzik@apple.com>2014-09-03 19:52:50 +0000
commit141330aef62f4a753622441d11a756cfc72bde94 (patch)
tree151ebf036f9dcb9928fd0af08167f4a6fbb4b92f /lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
parented9709d928ff3684bc1d646badcf068689ce232d (diff)
downloadbcm5719-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.cpp30
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) {}
OpenPOWER on IntegriCloud