diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 135ca2d14524d9..6ce261cf7a544b 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1196,6 +1196,27 @@ bool macho::link(ArrayRef argsArr, bool canExitEarly, createSyntheticSections(); createSyntheticSymbols(); + if (!config->exportedSymbols.empty()) { + for (Symbol *sym : symtab->getSymbols()) { + if (auto *defined = dyn_cast(sym)) { + StringRef symbolName = defined->getName(); + if (config->exportedSymbols.match(symbolName)) { + if (defined->privateExtern) { + error("cannot export hidden symbol " + symbolName + + "\n>>> defined in " + toString(defined->getFile())); + } + } else { + defined->privateExtern = true; + } + } + } + } else if (!config->unexportedSymbols.empty()) { + for (Symbol *sym : symtab->getSymbols()) + if (auto *defined = dyn_cast(sym)) + if (config->unexportedSymbols.match(defined->getName())) + defined->privateExtern = true; + } + for (const Arg *arg : args.filtered(OPT_sectcreate)) { StringRef segName = arg->getValue(0); StringRef sectName = arg->getValue(1); diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index f1afbc723bb557..38c93e1f8f96c1 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -566,40 +566,11 @@ uint32_t LazyBindingSection::encode(const DylibSymbol &sym) { ExportSection::ExportSection() : LinkEditSection(segment_names::linkEdit, section_names::export_) {} -static void validateExportSymbol(const Defined *defined) { - StringRef symbolName = defined->getName(); - if (defined->privateExtern && config->exportedSymbols.match(symbolName)) - error("cannot export hidden symbol " + symbolName + "\n>>> defined in " + - toString(defined->getFile())); -} - -static bool shouldExportSymbol(const Defined *defined) { - if (defined->privateExtern) { - assert(defined->isExternal() && "invalid input file"); - return false; - } - // TODO: Is this a performance bottleneck? If a build has mostly - // global symbols in the input but uses -exported_symbols to filter - // out most of them, then it would be better to set the value of - // privateExtern at parse time instead of calling - // exportedSymbols.match() more than once. - // - // Measurements show that symbol ordering (which again looks up - // every symbol in a hashmap) is the biggest bottleneck when linking - // chromium_framework, so this will likely be worth optimizing. - if (!config->exportedSymbols.empty()) - return config->exportedSymbols.match(defined->getName()); - if (!config->unexportedSymbols.empty()) - return !config->unexportedSymbols.match(defined->getName()); - return true; -} - void ExportSection::finalizeContents() { trieBuilder.setImageBase(in.header->addr); for (const Symbol *sym : symtab->getSymbols()) { if (const auto *defined = dyn_cast(sym)) { - validateExportSymbol(defined); - if (!shouldExportSymbol(defined)) + if (defined->privateExtern) continue; trieBuilder.addSymbol(*defined); hasWeakSymbol = hasWeakSymbol || sym->isWeakDef(); @@ -834,7 +805,7 @@ template void SymtabSectionImpl::writeTo(uint8_t *buf) const { // TODO populate n_desc with more flags if (auto *defined = dyn_cast(entry.sym)) { uint8_t scope = 0; - if (!shouldExportSymbol(defined)) { + if (defined->privateExtern) { // Private external -- dylib scoped symbol. // Promote to non-external at link time. scope = N_PEXT;