SectionRenameMap sectionRenameMap;
SegmentRenameMap segmentRenameMap;
+ bool hasExplicitExports = false;
SymbolPatterns exportedSymbols;
SymbolPatterns unexportedSymbols;
SymbolPatterns whyLive;
config->segmentProtections.push_back({segName, maxProt, initProt});
}
+ config->hasExplicitExports =
+ args.hasArg(OPT_no_exported_symbols) ||
+ args.hasArgNoClaim(OPT_exported_symbol, OPT_exported_symbols_list);
handleSymbolPatterns(args, config->exportedSymbols, OPT_exported_symbol,
OPT_exported_symbols_list);
handleSymbolPatterns(args, config->unexportedSymbols, OPT_unexported_symbol,
OPT_unexported_symbols_list);
- if (!config->exportedSymbols.empty() && !config->unexportedSymbols.empty()) {
- error("cannot use both -exported_symbol* and -unexported_symbol* options\n"
- ">>> ignoring unexports");
- config->unexportedSymbols.clear();
- }
+ if (config->hasExplicitExports && !config->unexportedSymbols.empty())
+ error("cannot use both -exported_symbol* and -unexported_symbol* options");
+
+ if (args.hasArg(OPT_no_exported_symbols) && !config->exportedSymbols.empty())
+ error("cannot use both -exported_symbol* and -no_exported_symbols options");
// Imitating LD64's:
// -non_global_symbols_no_strip_list and -non_global_symbols_strip_list can't
createSyntheticSections();
createSyntheticSymbols();
- if (!config->exportedSymbols.empty()) {
+ if (config->hasExplicitExports) {
parallelForEach(symtab->getSymbols(), [](Symbol *sym) {
if (auto *defined = dyn_cast<Defined>(sym)) {
StringRef symbolName = defined->getName();
MetaVarName<"<file>">,
HelpText<"Symbols specified in <file> remain global, while others become private externs">,
Group<grp_resolve>;
+def no_exported_symbols : Flag<["-"], "no_exported_symbols">,
+ HelpText<"Don't export any symbols from the binary, useful for main executables that don't have plugins">,
+ Group<grp_resolve>;
def unexported_symbol : Separate<["-"], "unexported_symbol">,
MetaVarName<"<symbol>">,
HelpText<"Global <symbol> becomes private extern">,
# RUN: not %lld -dylib %t/default.o -o /dev/null \
# RUN: -exported_symbol a -unexported_symbol b 2>&1 | \
# RUN: FileCheck --check-prefix=CONFLICT %s
+#
+# RUN: not %lld -dylib %t/default.o -o /dev/null \
+# RUN: -exported_symbols_list /dev/null -unexported_symbol b 2>&1 | \
+# RUN: FileCheck --check-prefix=CONFLICT %s
+#
+# RUN: not %lld -dylib %t/default.o -o /dev/null \
+# RUN: -no_exported_symbols -unexported_symbol b 2>&1 | \
+# RUN: FileCheck --check-prefix=CONFLICT %s
+#
+# RUN: not %lld -dylib %t/default.o -o /dev/null \
+# RUN: -no_exported_symbols -exported_symbol b 2>&1 | \
+# RUN: FileCheck --check-prefix=CONFLICT-NO-EXPORTS %s
+#
+# RUN: not %lld -dylib %t/default.o -o /dev/null \
+# RUN: -no_exported_symbols -exported_symbols_list %t/literals.txt 2>&1 | \
+# RUN: FileCheck --check-prefix=CONFLICT-NO-EXPORTS %s
# CONFLICT: error: cannot use both -exported_symbol* and -unexported_symbol* options
-# CONFLICT-NEXT: >>> ignoring unexports
+
+# CONFLICT-NO-EXPORTS: error: cannot use both -exported_symbol* and -no_exported_symbols options
## Check that an exported literal name with no symbol definition yields an error
## but that an exported glob-pattern with no matching symbol definition is OK
# AUTOHIDE-PRIVATE: error: cannot export hidden symbol _foo
# AUTOHIDE-PRIVATE-DEAD-STRIP: (__TEXT,__text) non-external (was a private external) _foo
+## Test not exporting any symbols
+# RUN: %lld -dylib %t/symdefs.o -o %t/noexports -exported_symbols_list /dev/null
+# RUN: llvm-objdump --macho --exports-trie %t/noexports | FileCheck --check-prefix=NOEXPORTS %s
+# RUN: %lld -dylib %t/symdefs.o -o %t/noexports -no_exported_symbols
+# RUN: llvm-objdump --macho --exports-trie %t/noexports | FileCheck --check-prefix=NOEXPORTS %s
+
+# NOEXPORTS-NOT: globby_also
+# NOEXPORTS-NOT: globby_only
+# NOEXPORTS-NOT: literal_also
+# NOEXPORTS-NOT: literal_only
+
#--- default.s
.globl _keep_globl, _hide_globl