Move more self-contained functionality away from tools/opt/opt.cpp
[oota-llvm.git] / tools / llvm-lto / llvm-lto.cpp
index 1d03fa62a870986191b9069162f1ec1e358c5dc9..4a421f9e76611c64b9e3154f8f7a7b691316698f 100644 (file)
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/StringSet.h"
 #include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/LTO/LTOCodeGenerator.h"
 #include "llvm/LTO/LTOModule.h"
@@ -19,8 +20,8 @@
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Signals.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
@@ -55,6 +56,12 @@ DSOSymbols("dso-symbol",
   cl::desc("Symbol to put in the symtab in the resulting dso"),
   cl::ZeroOrMore);
 
+namespace {
+struct ModuleInfo {
+  std::vector<bool> CanBeHidden;
+};
+}
+
 int main(int argc, char **argv) {
   // Print a stack trace if we signal out.
   sys::PrintStackTraceOnErrorSignal();
@@ -99,6 +106,12 @@ int main(int argc, char **argv) {
   CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF);
   CodeGen.setTargetOptions(Options);
 
+  llvm::StringSet<llvm::MallocAllocator> DSOSymbolsSet;
+  for (unsigned i = 0; i < DSOSymbols.size(); ++i)
+    DSOSymbolsSet.insert(DSOSymbols[i]);
+
+  std::vector<std::string> KeptDSOSyms;
+
   for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) {
     std::string error;
     OwningPtr<LTOModule> Module(LTOModule::makeLTOModule(InputFilenames[i].c_str(),
@@ -115,6 +128,17 @@ int main(int argc, char **argv) {
              << "': " << error << "\n";
       return 1;
     }
+
+    unsigned NumSyms = Module->getSymbolCount();
+    for (unsigned I = 0; I < NumSyms; ++I) {
+      StringRef Name = Module->getSymbolName(I);
+      if (!DSOSymbolsSet.count(Name))
+        continue;
+      lto_symbol_attributes Attrs = Module->getSymbolAttributes(I);
+      unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK;
+      if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN)
+        KeptDSOSyms.push_back(Name);
+    }
   }
 
   // Add all the exported symbols to the table of symbols to preserve.
@@ -122,8 +146,8 @@ int main(int argc, char **argv) {
     CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str());
 
   // Add all the dso symbols to the table of symbols to expose.
-  for (unsigned i = 0; i < DSOSymbols.size(); ++i)
-    CodeGen.addDSOSymbol(DSOSymbols[i].c_str());
+  for (unsigned i = 0; i < KeptDSOSyms.size(); ++i)
+    CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str());
 
   if (!OutputFilename.empty()) {
     size_t len = 0;
@@ -136,7 +160,8 @@ int main(int argc, char **argv) {
       return 1;
     }
 
-    raw_fd_ostream FileStream(OutputFilename.c_str(), ErrorInfo);
+    raw_fd_ostream FileStream(OutputFilename.c_str(), ErrorInfo,
+                              sys::fs::F_Binary);
     if (!ErrorInfo.empty()) {
       errs() << argv[0] << ": error opening the file '" << OutputFilename
              << "': " << ErrorInfo << "\n";