[lld] r216146 - [mach-o] Add support for -exported_symbols_list and -keep_private_externs

Nick Kledzik kledzik at apple.com
Wed Aug 20 18:59:11 PDT 2014


Author: kledzik
Date: Wed Aug 20 20:59:11 2014
New Revision: 216146

URL: http://llvm.org/viewvc/llvm-project?rev=216146&view=rev
Log:
[mach-o] Add support for -exported_symbols_list and -keep_private_externs

Both options control the final scope of atoms.

When -exported_symbols_list <file> is used, the file is parsed into one
symbol per line in the file.  Only those symbols will be exported (global)
in the final linked image.

The -keep_private_externs option is only used with -r mode. Normally, -r
mode reduces private extern (scopeLinkageUnit) symbols to non-external. But
add the -keep_private_externs option keeps them private external.

Added:
    lld/trunk/test/mach-o/Inputs/exported_symbols_list.exp
    lld/trunk/test/mach-o/exported_symbols_list-dylib.yaml
    lld/trunk/test/mach-o/exported_symbols_list-obj.yaml
    lld/trunk/test/mach-o/exported_symbols_list-undef.yaml
    lld/trunk/test/mach-o/keep_private_externs.yaml
Modified:
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/Driver/DarwinLdOptions.td
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=216146&r1=216145&r2=216146&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Wed Aug 20 20:59:11 2014
@@ -15,6 +15,7 @@
 #include "lld/ReaderWriter/Writer.h"
 
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MachO.h"
 
@@ -25,7 +26,7 @@ using llvm::MachO::HeaderFileType;
 namespace lld {
 
 namespace mach_o {
-class ArchHandler; 
+class ArchHandler;
 class MachODylibFile;
 }
 
@@ -51,6 +52,12 @@ public:
     iOS_simulator
   };
 
+  enum class ExportMode {
+    globals,    // Default, all global symbols exported.
+    whiteList,  // -exported_symbol[s_list], only listed symbols exported.
+    blackList   // -unexported_symbol[s_list], no listed symbol exported.
+  };
+
   /// Initializes the context to sane default values given the specified output
   /// file type, arch, os, and minimum os version.  This should be called before
   /// other setXXX() methods.
@@ -79,6 +86,15 @@ public:
   StringRef archName() const { return nameFromArch(_arch); }
   OS os() const { return _os; }
 
+  ExportMode exportMode() const { return _exportMode; }
+  void setExportMode(ExportMode mode) { _exportMode = mode; }
+  void addExportSymbol(StringRef sym);
+  bool exportRestrictMode() const { return _exportMode != ExportMode::globals; }
+  bool exportSymbolNamed(StringRef sym) const;
+
+  bool keepPrivateExterns() const { return _keepPrivateExterns; }
+  void setKeepPrivateExterns(bool v) { _keepPrivateExterns = v; }
+
   bool minOS(StringRef mac, StringRef iOS) const;
   void setDoNothing(bool value) { _doNothing = value; }
   bool doNothing() const { return _doNothing; }
@@ -222,6 +238,8 @@ public:
 private:
   Writer &writer() const override;
   mach_o::MachODylibFile* loadIndirectDylib(StringRef path) const;
+  void checkExportWhiteList(const DefinedAtom *atom) const;
+  void checkExportBlackList(const DefinedAtom *atom) const;
 
 
   struct ArchInfo {
@@ -258,6 +276,7 @@ private:
   bool _deadStrippableDylib;
   bool _printAtoms;
   bool _testingFileUsage;
+  bool _keepPrivateExterns;
   StringRef _bundleLoader;
   mutable std::unique_ptr<mach_o::ArchHandler> _archHandler;
   mutable std::unique_ptr<Writer> _writer;
@@ -265,6 +284,8 @@ private:
   llvm::StringMap<mach_o::MachODylibFile*> _pathToDylibMap;
   std::set<mach_o::MachODylibFile*> _allDylibs;
   mutable std::vector<std::unique_ptr<class MachOFileNode>> _indirectDylibs;
+  ExportMode _exportMode;
+  llvm::StringSet<> _exportedSymbols;
 };
 
 } // end namespace lld

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=216146&r1=216145&r2=216146&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Wed Aug 20 20:59:11 2014
@@ -88,6 +88,31 @@ void addFile(StringRef path, std::unique
                                           new MachOFileNode(path, forceLoad)));
 }
 
+// Export lists are one symbol per line.  Blank lines are ignored.
+// Trailing comments start with #.
+std::error_code parseExportsList(StringRef exportFilePath,
+                                 MachOLinkingContext &ctx,
+                                 raw_ostream &diagnostics) {
+  // Map in export list file.
+  ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
+                                   MemoryBuffer::getFileOrSTDIN(exportFilePath);
+  if (std::error_code ec = mb.getError())
+    return ec;
+  StringRef buffer = mb->get()->getBuffer();
+  while (!buffer.empty()) {
+    // Split off each line in the file.
+    std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
+    StringRef line = lineAndRest.first;
+    // Ignore trailing # comments.
+    std::pair<StringRef, StringRef> symAndComment = line.split('#');
+    StringRef sym = symAndComment.first.trim();
+    if (!sym.empty())
+      ctx.addExportSymbol(sym);
+    buffer = lineAndRest.second;
+  }
+  return std::error_code();
+}
+
 //
 // There are two variants of the  -filelist option:
 //
@@ -349,7 +374,7 @@ bool DarwinLdDriver::parse(int argc, con
     ctx.appendLLVMOption(llvmArg->getValue());
   }
 
-  // Handle -print_atoms a
+  // Handle -print_atoms
   if (parsedArgs->getLastArg(OPT_print_atoms))
     ctx.setPrintAtoms();
 
@@ -357,6 +382,13 @@ bool DarwinLdDriver::parse(int argc, con
   if (parsedArgs->getLastArg(OPT_t))
     ctx.setLogInputFiles(true);
 
+  // Handle -keep_private_externs
+  if (parsedArgs->getLastArg(OPT_keep_private_externs)) {
+    ctx.setKeepPrivateExterns(true);
+    if (ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
+      diagnostics << "warning: -keep_private_externs only used in -r mode\n";
+  }
+
   // In -test_file_usage mode, we'll be given an explicit list of paths that
   // exist. We'll also be expected to print out information about how we located
   // libraries and so on that the user specified, but not to actually do any
@@ -427,6 +459,64 @@ bool DarwinLdDriver::parse(int argc, con
     }
   }
 
+  // Handle -exported_symbols_list <file>
+  for (auto expFile : parsedArgs->filtered(OPT_exported_symbols_list)) {
+    if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) {
+      diagnostics << "error: -exported_symbols_list cannot be combined "
+                  << "with -unexported_symbol[s_list]\n";
+       return false;
+    }
+    ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList);
+    if (std::error_code ec = parseExportsList(expFile->getValue(), ctx,
+                                              diagnostics)) {
+      diagnostics << "error: " << ec.message()
+                  << ", processing '-exported_symbols_list "
+                  << expFile->getValue()
+                  << "'\n";
+      return false;
+    }
+  }
+
+  // Handle -exported_symbol <symbol>
+  for (auto symbol : parsedArgs->filtered(OPT_exported_symbol)) {
+    if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) {
+      diagnostics << "error: -exported_symbol cannot be combined "
+                  << "with -unexported_symbol[s_list]\n";
+       return false;
+    }
+    ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList);
+    ctx.addExportSymbol(symbol->getValue());
+  }
+
+  // Handle -unexported_symbols_list <file>
+  for (auto expFile : parsedArgs->filtered(OPT_unexported_symbols_list)) {
+    if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) {
+      diagnostics << "error: -unexported_symbols_list cannot be combined "
+                  << "with -exported_symbol[s_list]\n";
+       return false;
+    }
+    ctx.setExportMode(MachOLinkingContext::ExportMode::blackList);
+    if (std::error_code ec = parseExportsList(expFile->getValue(), ctx,
+                                              diagnostics)) {
+      diagnostics << "error: " << ec.message()
+                  << ", processing '-unexported_symbols_list "
+                  << expFile->getValue()
+                  << "'\n";
+      return false;
+    }
+  }
+
+  // Handle -unexported_symbol <symbol>
+  for (auto symbol : parsedArgs->filtered(OPT_unexported_symbol)) {
+    if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) {
+      diagnostics << "error: -unexported_symbol cannot be combined "
+                  << "with -exported_symbol[s_list]\n";
+       return false;
+    }
+    ctx.setExportMode(MachOLinkingContext::ExportMode::blackList);
+    ctx.addExportSymbol(symbol->getValue());
+  }
+
   // Handle input files
   for (auto &arg : *parsedArgs) {
     ErrorOr<StringRef> resolvedPath = StringRef();
@@ -442,7 +532,8 @@ bool DarwinLdDriver::parse(int argc, con
         diagnostics << "Unable to find library -l" << arg->getValue() << "\n";
         return false;
       } else if (ctx.testingFileUsage()) {
-       diagnostics << "Found library " << canonicalizePath(resolvedPath.get()) << '\n';
+       diagnostics << "Found library "
+                   << canonicalizePath(resolvedPath.get()) << '\n';
       }
       addFile(resolvedPath.get(), inputGraph, globalWholeArchive);
       break;
@@ -452,7 +543,8 @@ bool DarwinLdDriver::parse(int argc, con
         diagnostics << "Unable to find -framework " << arg->getValue() << "\n";
         return false;
       } else if (ctx.testingFileUsage()) {
-        diagnostics << "Found framework " << canonicalizePath(resolvedPath.get()) << '\n';
+        diagnostics << "Found framework "
+                    << canonicalizePath(resolvedPath.get()) << '\n';
       }
       addFile(resolvedPath.get(), inputGraph, globalWholeArchive);
       break;

Modified: lld/trunk/lib/Driver/DarwinLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdOptions.td?rev=216146&r1=216145&r2=216146&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdOptions.td (original)
+++ lld/trunk/lib/Driver/DarwinLdOptions.td Wed Aug 20 20:59:11 2014
@@ -34,6 +34,21 @@ def ios_simulator_version_min : Separate
 def mllvm : Separate<["-"], "mllvm">,
      MetaVarName<"<option>">,
      HelpText<"Options to pass to LLVM during LTO">, Group<grp_opts>;
+def exported_symbols_list : Separate<["-"], "exported_symbols_list">,
+     MetaVarName<"<file-path>">,
+     HelpText<"Restricts which symbols will be exported">, Group<grp_opts>;
+def exported_symbol : Separate<["-"], "exported_symbol">,
+     MetaVarName<"<symbol>">,
+     HelpText<"Restricts which symbols will be exported">, Group<grp_opts>;
+def unexported_symbols_list : Separate<["-"], "unexported_symbols_list">,
+     MetaVarName<"<file-path>">,
+     HelpText<"Lists symbols that should not be exported">, Group<grp_opts>;
+def unexported_symbol : Separate<["-"], "unexported_symbol">,
+     MetaVarName<"<symbol>">,
+     HelpText<"A symbol which should not be exported">, Group<grp_opts>;
+def keep_private_externs : Flag<["-"], "keep_private_externs">,
+     HelpText<"Private extern (hidden) symbols should not be transformed "
+              "into local symbols">, Group<grp_opts>;
 
 // main executable options
 def grp_main : OptionGroup<"opts">, HelpText<"MAIN EXECUTABLE OPTIONS">;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=216146&r1=216145&r2=216146&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Wed Aug 20 20:59:11 2014
@@ -130,7 +130,8 @@ MachOLinkingContext::MachOLinkingContext
       _doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
       _pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
       _currentVersion(0), _deadStrippableDylib(false), _printAtoms(false),
-      _testingFileUsage(false), _archHandler(nullptr) {}
+      _testingFileUsage(false), _keepPrivateExterns(false),
+      _archHandler(nullptr), _exportMode(ExportMode::globals) {}
 
 MachOLinkingContext::~MachOLinkingContext() {}
 
@@ -448,6 +449,12 @@ bool MachOLinkingContext::validateImpl(r
     return false;
   }
 
+  // If -exported_symbols_list used, all exported symbols must be defined.
+  if (_exportMode == ExportMode::whiteList) {
+    for (const auto &symbol : _exportedSymbols)
+      addInitialUndefinedSymbol(symbol.getKey());
+  }
+
   return true;
 }
 
@@ -572,4 +579,23 @@ bool MachOLinkingContext::sectionAligned
   return false;
 }
 
+
+void MachOLinkingContext::addExportSymbol(StringRef sym) {
+  // FIXME: Support wildcards.
+  _exportedSymbols.insert(sym);
+}
+
+bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
+  switch (_exportMode) {
+  case ExportMode::globals:
+    llvm_unreachable("exportSymbolNamed() should not be called in this mode");
+    break;
+  case ExportMode::whiteList:
+    return _exportedSymbols.count(sym);
+  case ExportMode::blackList:
+    return !_exportedSymbols.count(sym);
+  }
+}
+
+
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=216146&r1=216145&r2=216146&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Wed Aug 20 20:59:11 2014
@@ -106,7 +106,7 @@ public:
   void      copySectionInfo(NormalizedFile &file);
   void      updateSectionInfo(NormalizedFile &file);
   void      buildAtomToAddressMap();
-  void      addSymbols(const lld::File &atomFile, NormalizedFile &file);
+  std::error_code addSymbols(const lld::File &atomFile, NormalizedFile &file);
   void      addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file);
   void      addRebaseAndBindingInfo(const lld::File &, NormalizedFile &file);
   void      addSectionRelocs(const lld::File &, NormalizedFile &file);
@@ -130,20 +130,21 @@ private:
   void         layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr);
   void         layoutSectionsInTextSegment(size_t, SegmentInfo *, uint64_t &);
   void         copySectionContent(SectionInfo *si, ContentBytes &content);
-  uint8_t      scopeBits(const DefinedAtom* atom);
   uint16_t     descBits(const DefinedAtom* atom);
   int          dylibOrdinal(const SharedLibraryAtom *sa);
   void         segIndexForSection(const SectionInfo *sect,
                              uint8_t &segmentIndex, uint64_t &segmentStartAddr);
   const Atom  *targetOfLazyPointer(const DefinedAtom *lpAtom);
   const Atom  *targetOfStub(const DefinedAtom *stubAtom);
-  bool         belongsInGlobalSymbolsSection(const DefinedAtom* atom);
+  std::error_code getSymbolTableRegion(const DefinedAtom* atom,
+                                       bool &inGlobalsRegion,
+                                       SymbolScope &symbolScope);
   void         appendSection(SectionInfo *si, NormalizedFile &file);
   uint32_t     sectionIndexForAtom(const Atom *atom);
 
   static uint64_t alignTo(uint64_t value, uint8_t align2);
   typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
-  struct AtomAndIndex { const Atom *atom; uint32_t index; };
+  struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
   struct AtomSorter {
     bool operator()(const AtomAndIndex &left, const AtomAndIndex &right);
   };
@@ -635,18 +636,6 @@ void Util::buildAtomToAddressMap() {
   }
 }
 
-uint8_t Util::scopeBits(const DefinedAtom* atom) {
-  switch (atom->scope()) {
-  case Atom::scopeTranslationUnit:
-    return 0;
-  case Atom::scopeLinkageUnit:
-    return N_PEXT | N_EXT;
-  case Atom::scopeGlobal:
-    return N_EXT;
-  }
-  llvm_unreachable("Unknown scope");
-}
-
 uint16_t Util::descBits(const DefinedAtom* atom) {
   uint16_t desc = 0;
   switch (atom->merge()) {
@@ -677,16 +666,55 @@ bool Util::AtomSorter::operator()(const
 }
 
 
-bool Util::belongsInGlobalSymbolsSection(const DefinedAtom* atom) {
-  // ScopeLinkageUnit symbols are in globals area of symbol table
-  // in object files, but in locals area for final linked images. 
-  if (_context.outputMachOType() == llvm::MachO::MH_OBJECT)
-    return (atom->scope() != Atom::scopeTranslationUnit);
-  else
-    return (atom->scope() == Atom::scopeGlobal);
+std::error_code Util::getSymbolTableRegion(const DefinedAtom* atom,
+                                           bool &inGlobalsRegion,
+                                           SymbolScope &scope) {
+  bool rMode = (_context.outputMachOType() == llvm::MachO::MH_OBJECT);
+  switch (atom->scope()) {
+  case Atom::scopeTranslationUnit:
+    scope = 0;
+    inGlobalsRegion = false;
+    return std::error_code();
+  case Atom::scopeLinkageUnit:
+    if ((_context.exportMode() == MachOLinkingContext::ExportMode::whiteList)
+        && _context.exportSymbolNamed(atom->name())) {
+      return make_dynamic_error_code(Twine("cannot export hidden symbol ")
+                                    + atom->name());
+    }
+    if (rMode) {
+      if (_context.keepPrivateExterns()) {
+        // -keep_private_externs means keep in globals region as N_PEXT.
+        scope = N_PEXT | N_EXT;
+        inGlobalsRegion = true;
+        return std::error_code();
+      }
+    }
+    // scopeLinkageUnit symbols are no longer global once linked.
+    scope = N_PEXT;
+    inGlobalsRegion = false;
+    return std::error_code();
+  case Atom::scopeGlobal:
+    if (_context.exportRestrictMode()) {
+      if (_context.exportSymbolNamed(atom->name())) {
+        scope = N_EXT;
+        inGlobalsRegion = true;
+        return std::error_code();
+      } else {
+        scope = N_PEXT;
+        inGlobalsRegion = false;
+        return std::error_code();
+      }
+    } else {
+      scope = N_EXT;
+      inGlobalsRegion = true;
+      return std::error_code();
+    }
+    break;
+  }
 }
 
-void Util::addSymbols(const lld::File &atomFile, NormalizedFile &file) {
+std::error_code Util::addSymbols(const lld::File &atomFile,
+                                 NormalizedFile &file) {
   bool rMode = (_context.outputMachOType() == llvm::MachO::MH_OBJECT);
   // Mach-O symbol table has three regions: locals, globals, undefs.
 
@@ -697,14 +725,19 @@ void Util::addSymbols(const lld::File &a
     for (const AtomInfo &info : sect->atomsAndOffsets) {
       const DefinedAtom *atom = info.atom;
       if (!atom->name().empty()) {
-        if (belongsInGlobalSymbolsSection(atom)) {
-          AtomAndIndex ai = { atom, sect->finalSectionIndex };
+        SymbolScope symbolScope;
+        bool inGlobalsRegion;
+        if (auto ec = getSymbolTableRegion(atom, inGlobalsRegion, symbolScope)){
+          return ec;
+        }
+        if (inGlobalsRegion) {
+          AtomAndIndex ai = { atom, sect->finalSectionIndex, symbolScope };
           globals.push_back(ai);
         } else {
           Symbol sym;
           sym.name  = atom->name();
           sym.type  = N_SECT;
-          sym.scope = scopeBits(atom);
+          sym.scope = symbolScope;
           sym.sect  = sect->finalSectionIndex;
           sym.desc  = descBits(atom);
           sym.value = _atomToAddress[atom];
@@ -737,7 +770,7 @@ void Util::addSymbols(const lld::File &a
     Symbol sym;
     sym.name  = ai.atom->name();
     sym.type  = N_SECT;
-    sym.scope = scopeBits(static_cast<const DefinedAtom*>(ai.atom));
+    sym.scope = ai.scope;
     sym.sect  = ai.index;
     sym.desc  = descBits(static_cast<const DefinedAtom*>(ai.atom));
     sym.value = _atomToAddress[ai.atom];
@@ -750,11 +783,11 @@ void Util::addSymbols(const lld::File &a
   std::vector<AtomAndIndex> undefs;
   undefs.reserve(128);
   for (const UndefinedAtom *atom : atomFile.undefined()) {
-    AtomAndIndex ai = { atom, 0 };
+    AtomAndIndex ai = { atom, 0, N_EXT };
     undefs.push_back(ai);
   }
   for (const SharedLibraryAtom *atom : atomFile.sharedLibrary()) {
-    AtomAndIndex ai = { atom, 0 };
+    AtomAndIndex ai = { atom, 0, N_EXT };
     undefs.push_back(ai);
   }
   std::sort(undefs.begin(), undefs.end(), AtomSorter());
@@ -768,13 +801,15 @@ void Util::addSymbols(const lld::File &a
     }
     sym.name  = ai.atom->name();
     sym.type  = N_UNDF;
-    sym.scope = N_EXT;
+    sym.scope = ai.scope;
     sym.sect  = 0;
     sym.desc  = desc;
     sym.value = 0;
     _atomToSymbolIndex[ai.atom] = file.undefinedSymbols.size() + start;
     file.undefinedSymbols.push_back(sym);
   }
+
+  return std::error_code();
 }
 
 const Atom *Util::targetOfLazyPointer(const DefinedAtom *lpAtom) {
@@ -1083,7 +1118,9 @@ normalizedFromAtoms(const lld::File &ato
   util.buildAtomToAddressMap();
   util.updateSectionInfo(normFile);
   util.copySectionContent(normFile);
-  util.addSymbols(atomFile, normFile);
+  if (auto ec = util.addSymbols(atomFile, normFile)) {
+    return ec;
+  }
   util.addIndirectSymbols(atomFile, normFile);
   util.addRebaseAndBindingInfo(atomFile, normFile);
   util.addSectionRelocs(atomFile, normFile);

Added: lld/trunk/test/mach-o/Inputs/exported_symbols_list.exp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/Inputs/exported_symbols_list.exp?rev=216146&view=auto
==============================================================================
--- lld/trunk/test/mach-o/Inputs/exported_symbols_list.exp (added)
+++ lld/trunk/test/mach-o/Inputs/exported_symbols_list.exp Wed Aug 20 20:59:11 2014
@@ -0,0 +1,6 @@
+#
+# For use with exported_symbols_list.yaml
+#
+_foo
+_b
+

Added: lld/trunk/test/mach-o/exported_symbols_list-dylib.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exported_symbols_list-dylib.yaml?rev=216146&view=auto
==============================================================================
--- lld/trunk/test/mach-o/exported_symbols_list-dylib.yaml (added)
+++ lld/trunk/test/mach-o/exported_symbols_list-dylib.yaml Wed Aug 20 20:59:11 2014
@@ -0,0 +1,67 @@
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
+# RUN:      %s %p/Inputs/libSystem.yaml -o %t \
+# RUN:      -exported_symbols_list %p/Inputs/exported_symbols_list.exp && \
+# RUN: llvm-nm -m %t | FileCheck %s
+#
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
+# RUN:      %s %p/Inputs/libSystem.yaml -o %t2 \
+# RUN:      -exported_symbol _foo -exported_symbol _b  && \
+# RUN: llvm-nm -m %t2 | FileCheck %s
+#
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
+# RUN:      %s %p/Inputs/libSystem.yaml -o %t3 \
+# RUN:      -unexported_symbol _bar -unexported_symbol _a  && \
+# RUN: llvm-nm -m %t3 | FileCheck %s
+#
+# Test -exported_symbols_list and -exported_symbol properly changes visibility.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48, 
+                       0x89, 0xE5, 0x5D, 0xC3 ]
+  - segment:         __DATA
+    section:         __data
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       2
+    address:         0x000000000000000C
+    content:         [ 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 ]
+
+global-symbols:
+  - name:            _a
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            2
+    value:           0x000000000000000C
+  - name:            _b
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            2
+    value:           0x0000000000000010
+  - name:            _bar
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000006
+  - name:            _foo
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+
+
+...
+
+# CHECK: (__DATA,__data) non-external (was a private external) _a
+# CHECK: (__DATA,__data) external _b
+# CHECK: (__TEXT,__text) non-external (was a private external) _bar
+# CHECK: (__TEXT,__text) external _foo

Added: lld/trunk/test/mach-o/exported_symbols_list-obj.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exported_symbols_list-obj.yaml?rev=216146&view=auto
==============================================================================
--- lld/trunk/test/mach-o/exported_symbols_list-obj.yaml (added)
+++ lld/trunk/test/mach-o/exported_symbols_list-obj.yaml Wed Aug 20 20:59:11 2014
@@ -0,0 +1,67 @@
+# RUN: lld -flavor darwin -arch x86_64 -r  %s -o %t -exported_symbol _bar \
+# RUN:    && llvm-nm -m %t | FileCheck %s
+#
+# RUN: lld -flavor darwin -arch x86_64 -r  %s -o %t2 -keep_private_externs \
+# RUN:      -exported_symbol _bar && \
+# RUN: llvm-nm -m %t2 | FileCheck -check-prefix=CHECK_KPE %s
+#
+# RUN: not lld -flavor darwin -arch x86_64 -r  %s -o %t3  \
+# RUN:      -exported_symbol _foo 2> %t4
+
+# Test -exported_symbols_list properly changes visibility in -r mode.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48, 
+                       0x89, 0xE5, 0x5D, 0xC3 ]
+  - segment:         __DATA
+    section:         __data
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       2
+    address:         0x000000000000000C
+    content:         [ 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 ]
+
+global-symbols:
+  - name:            _a
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            2
+    value:           0x000000000000000C
+  - name:            _b
+    type:            N_SECT
+    scope:           [ N_EXT, N_PEXT ]
+    sect:            2
+    value:           0x0000000000000010
+  - name:            _bar
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000006
+  - name:            _foo
+    type:            N_SECT
+    scope:           [ N_EXT, N_PEXT  ]
+    sect:            1
+    value:           0x0000000000000000
+
+
+...
+
+# CHECK: (__DATA,__data) non-external (was a private external) _a
+# CHECK: (__DATA,__data) non-external (was a private external) _b
+# CHECK: (__TEXT,__text) external _bar
+# CHECK: (__TEXT,__text) non-external (was a private external) _foo
+
+# CHECK_KPE: (__DATA,__data) non-external (was a private external) _a
+# CHECK_KPE: (__DATA,__data) private external _b
+# CHECK_KPE: (__TEXT,__text) external _bar
+# CHECK_KPE: (__TEXT,__text) private external _foo

Added: lld/trunk/test/mach-o/exported_symbols_list-undef.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exported_symbols_list-undef.yaml?rev=216146&view=auto
==============================================================================
--- lld/trunk/test/mach-o/exported_symbols_list-undef.yaml (added)
+++ lld/trunk/test/mach-o/exported_symbols_list-undef.yaml Wed Aug 20 20:59:11 2014
@@ -0,0 +1,55 @@
+# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
+# RUN:      %s %p/Inputs/libSystem.yaml -o %t -exported_symbol _foobar 2> %t2
+#
+# Test -exported_symbol fails if exported symbol not found.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48, 
+                       0x89, 0xE5, 0x5D, 0xC3 ]
+  - segment:         __DATA
+    section:         __data
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       2
+    address:         0x000000000000000C
+    content:         [ 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 ]
+
+global-symbols:
+  - name:            _a
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            2
+    value:           0x000000000000000C
+  - name:            _b
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            2
+    value:           0x0000000000000010
+  - name:            _bar
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000006
+  - name:            _foo
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+
+
+...
+
+# CHECK: (__DATA,__data) private external _a
+# CHECK: (__DATA,__data) external _b
+# CHECK: (__TEXT,__text) private external _bar
+# CHECK: (__TEXT,__text) external _foo

Added: lld/trunk/test/mach-o/keep_private_externs.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/keep_private_externs.yaml?rev=216146&view=auto
==============================================================================
--- lld/trunk/test/mach-o/keep_private_externs.yaml (added)
+++ lld/trunk/test/mach-o/keep_private_externs.yaml Wed Aug 20 20:59:11 2014
@@ -0,0 +1,63 @@
+# RUN: lld -flavor darwin -arch x86_64 -r  %s -o %t \
+# RUN:    && llvm-nm -m %t | FileCheck %s
+#
+# RUN: lld -flavor darwin -arch x86_64 -r  %s -o %t2 -keep_private_externs \
+# RUN:    && llvm-nm -m %t2 | FileCheck -check-prefix=CHECK_KPE %s
+#
+# Test -keep_private_externs in -r mode.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48, 
+                       0x89, 0xE5, 0x5D, 0xC3 ]
+  - segment:         __DATA
+    section:         __data
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       2
+    address:         0x000000000000000C
+    content:         [ 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 ]
+
+global-symbols:
+  - name:            _a
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            2
+    value:           0x000000000000000C
+  - name:            _b
+    type:            N_SECT
+    scope:           [ N_EXT, N_PEXT ]
+    sect:            2
+    value:           0x0000000000000010
+  - name:            _bar
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000006
+  - name:            _foo
+    type:            N_SECT
+    scope:           [ N_EXT, N_PEXT  ]
+    sect:            1
+    value:           0x0000000000000000
+
+
+...
+
+# CHECK: (__DATA,__data) external _a
+# CHECK: (__DATA,__data) non-external (was a private external) _b
+# CHECK: (__TEXT,__text) external _bar
+# CHECK: (__TEXT,__text) non-external (was a private external) _foo
+
+# CHECK_KPE: (__DATA,__data) external _a
+# CHECK_KPE: (__DATA,__data) private external _b
+# CHECK_KPE: (__TEXT,__text) external _bar
+# CHECK_KPE: (__TEXT,__text) private external _foo





More information about the llvm-commits mailing list