aboutsummaryrefslogtreecommitdiff
path: root/lld/MachO/InputFiles.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/MachO/InputFiles.cpp')
-rw-r--r--lld/MachO/InputFiles.cpp77
1 files changed, 45 insertions, 32 deletions
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index c53874133a78..fda6900edabe 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -347,7 +347,7 @@ void ObjFile::parseSections(ArrayRef<SectionHeader> sectionHeaders) {
section.subsections.push_back({0, isec});
} else if (auto recordSize = getRecordSize(segname, name)) {
splitRecords(*recordSize);
- } else if (config->parseEhFrames && name == section_names::ehFrame &&
+ } else if (name == section_names::ehFrame &&
segname == segment_names::text) {
splitEhFrames(data, *sections.back());
} else if (segname == segment_names::llvm) {
@@ -1117,7 +1117,7 @@ template <class LP> void ObjFile::parse() {
}
if (compactUnwindSection)
registerCompactUnwind(*compactUnwindSection);
- if (config->parseEhFrames && ehFrameSection)
+ if (ehFrameSection)
registerEhFrames(*ehFrameSection);
}
@@ -1687,7 +1687,6 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
umbrella = this;
this->umbrella = umbrella;
- auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
auto *hdr = reinterpret_cast<const mach_header *>(mb.getBufferStart());
// Initialize installName.
@@ -1722,39 +1721,53 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
// Initialize symbols.
exportingFile = isImplicitlyLinked(installName) ? this : this->umbrella;
- if (const load_command *cmd = findCommand(hdr, LC_DYLD_INFO_ONLY)) {
- auto *c = reinterpret_cast<const dyld_info_command *>(cmd);
- struct TrieEntry {
- StringRef name;
- uint64_t flags;
- };
- std::vector<TrieEntry> entries;
- // Find all the $ld$* symbols to process first.
- parseTrie(buf + c->export_off, c->export_size,
- [&](const Twine &name, uint64_t flags) {
- StringRef savedName = saver().save(name);
- if (handleLDSymbol(savedName))
- return;
- entries.push_back({savedName, flags});
- });
-
- // Process the "normal" symbols.
- for (TrieEntry &entry : entries) {
- if (exportingFile->hiddenSymbols.contains(
- CachedHashStringRef(entry.name)))
- continue;
+ const auto *dyldInfo = findCommand<dyld_info_command>(hdr, LC_DYLD_INFO_ONLY);
+ const auto *exportsTrie =
+ findCommand<linkedit_data_command>(hdr, LC_DYLD_EXPORTS_TRIE);
+ if (dyldInfo && exportsTrie) {
+ // It's unclear what should happen in this case. Maybe we should only error
+ // out if the two load commands refer to different data?
+ error("dylib " + toString(this) +
+ " has both LC_DYLD_INFO_ONLY and LC_DYLD_EXPORTS_TRIE");
+ return;
+ } else if (dyldInfo) {
+ parseExportedSymbols(dyldInfo->export_off, dyldInfo->export_size);
+ } else if (exportsTrie) {
+ parseExportedSymbols(exportsTrie->dataoff, exportsTrie->datasize);
+ } else {
+ error("No LC_DYLD_INFO_ONLY or LC_DYLD_EXPORTS_TRIE found in " +
+ toString(this));
+ return;
+ }
+}
- bool isWeakDef = entry.flags & EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
- bool isTlv = entry.flags & EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL;
+void DylibFile::parseExportedSymbols(uint32_t offset, uint32_t size) {
+ struct TrieEntry {
+ StringRef name;
+ uint64_t flags;
+ };
- symbols.push_back(
- symtab->addDylib(entry.name, exportingFile, isWeakDef, isTlv));
- }
+ auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
+ std::vector<TrieEntry> entries;
+ // Find all the $ld$* symbols to process first.
+ parseTrie(buf + offset, size, [&](const Twine &name, uint64_t flags) {
+ StringRef savedName = saver().save(name);
+ if (handleLDSymbol(savedName))
+ return;
+ entries.push_back({savedName, flags});
+ });
- } else {
- error("LC_DYLD_INFO_ONLY not found in " + toString(this));
- return;
+ // Process the "normal" symbols.
+ for (TrieEntry &entry : entries) {
+ if (exportingFile->hiddenSymbols.contains(CachedHashStringRef(entry.name)))
+ continue;
+
+ bool isWeakDef = entry.flags & EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
+ bool isTlv = entry.flags & EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL;
+
+ symbols.push_back(
+ symtab->addDylib(entry.name, exportingFile, isWeakDef, isTlv));
}
}