Ejemplo n.º 1
0
// getArchive - Get the archive file name from the command line
void getArchive() {
    if(RestOfArgs.size() > 0) {
        ArchiveName = RestOfArgs[0];
        RestOfArgs.erase(RestOfArgs.begin());
    }
    else
        throw "An archive name must be specified.";
}
Ejemplo n.º 2
0
// getRelPos - Extract the member filename from the command line for
// the [relpos] argument associated with a, b, and i modifiers
void getRelPos() {
    if(RestOfArgs.size() > 0) {
        RelPos = RestOfArgs[0];
        RestOfArgs.erase(RestOfArgs.begin());
    }
    else
        throw "Expected [relpos] for a, b, or i modifier";
}
Ejemplo n.º 3
0
// getCount - Extract the [count] argument associated with the N modifier
// from the command line and check its value.
void getCount() {
  if(RestOfArgs.size() == 0)
    show_help("Expected [count] value with N modifier");

  Count = atoi(RestOfArgs[0].c_str());
  RestOfArgs.erase(RestOfArgs.begin());

  // Non-positive counts are not allowed
  if (Count < 1)
    show_help("Invalid [count] value (not a positive integer)");
}
Ejemplo n.º 4
0
// getCount - Extract the [count] argument associated with the N modifier
// from the command line and check its value.
void getCount() {
    if(RestOfArgs.size() > 0) {
        Count = atoi(RestOfArgs[0].c_str());
        RestOfArgs.erase(RestOfArgs.begin());
    }
    else
        throw "Expected [count] value with N modifier";

    // Non-positive counts are not allowed
    if (Count < 1)
        throw "Invalid [count] value (not a positive integer)";
}
/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM
/// bytecode file for the program.
static void EmitShellScript(char **argv) {
  if (Verbose)
    cout << "Emitting Shell Script\n";
#if defined(_WIN32) || defined(__CYGWIN__)
  // Windows doesn't support #!/bin/sh style shell scripts in .exe files.  To
  // support windows systems, we copy the llvm-stub.exe executable from the
  // build tree to the destination file.
  std::string ErrMsg;  
  sys::Path llvmstub = FindExecutable("llvm-stub.exe", argv[0]);
  if (llvmstub.isEmpty())
    PrintAndExit("Could not find llvm-stub.exe executable!");

  if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg))
    PrintAndExit(ErrMsg);

  return;
#endif

  // Output the script to start the program...
  std::ofstream Out2(OutputFilename.c_str());
  if (!Out2.good())
    PrintAndExit("error opening '" + OutputFilename + "' for writing!");

  Out2 << "#!/bin/sh\n";
  // Allow user to setenv LLVMINTERP if lli is not in their PATH.
  Out2 << "lli=${LLVMINTERP-lli}\n";
  Out2 << "exec $lli \\\n";
  // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib.
  LibPaths.push_back("/lib");
  LibPaths.push_back("/usr/lib");
  LibPaths.push_back("/usr/X11R6/lib");
  // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a
  // shared object at all! See RH 8: plain text.
  std::vector<std::string>::iterator libc =
    std::find(Libraries.begin(), Libraries.end(), "c");
  if (libc != Libraries.end()) Libraries.erase(libc);
  // List all the shared object (native) libraries this executable will need
  // on the command line, so that we don't have to do this manually!
  for (std::vector<std::string>::iterator i = Libraries.begin(),
         e = Libraries.end(); i != e; ++i) {
    sys::Path FullLibraryPath = sys::Path::FindLibrary(*i);
    if (!FullLibraryPath.isEmpty() && FullLibraryPath.isDynamicLibrary())
      Out2 << "    -load=" << FullLibraryPath.toString() << " \\\n";
  }
  Out2 << "    $0.bc ${1+\"$@\"}\n";
  Out2.close();
}
Ejemplo n.º 6
0
// Get the archive file name from the command line
static void getArchive() {
  if(RestOfArgs.size() == 0)
    show_help("An archive name must be specified");
  ArchiveName = RestOfArgs[0];
  RestOfArgs.erase(RestOfArgs.begin());
}
Ejemplo n.º 7
0
static void getOptions() {
  if(RestOfArgs.size() == 0)
    show_help("Expected options");
  Options = RestOfArgs[0];
  RestOfArgs.erase(RestOfArgs.begin());
}
Ejemplo n.º 8
0
// Extract the member filename from the command line for the [relpos] argument
// associated with a, b, and i modifiers
static void getRelPos() {
  if(RestOfArgs.size() == 0)
    show_help("Expected [relpos] for a, b, or i modifier");
  RelPos = RestOfArgs[0];
  RestOfArgs.erase(RestOfArgs.begin());
}
int main(int argc, char **argv, char **envp) {
  llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.
  try {
    // Initial global variable above for convenience printing of program name.
    progname = sys::Path(argv[0]).getBasename();

    // Parse the command line options
    cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
    sys::PrintStackTraceOnErrorSignal();

    // Construct a Linker (now that Verbose is set)
    Linker TheLinker(progname, OutputFilename, Verbose);

    // Keep track of the native link items (versus the bytecode items)
    Linker::ItemList NativeLinkItems;

    // Add library paths to the linker
    TheLinker.addPaths(LibPaths);
    TheLinker.addSystemPaths();

    // Remove any consecutive duplicates of the same library...
    Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
                    Libraries.end());

    if (LinkAsLibrary) {
      std::vector<sys::Path> Files;
      for (unsigned i = 0; i < InputFilenames.size(); ++i )
        Files.push_back(sys::Path(InputFilenames[i]));
      if (TheLinker.LinkInFiles(Files))
        return 1; // Error already printed

      // The libraries aren't linked in but are noted as "dependent" in the
      // module.
      for (cl::list<std::string>::const_iterator I = Libraries.begin(),
           E = Libraries.end(); I != E ; ++I) {
        TheLinker.getModule()->addLibrary(*I);
      }
    } else {
      // Build a list of the items from our command line
      Linker::ItemList Items;
      BuildLinkItems(Items, InputFilenames, Libraries);

      // Link all the items together
      if (TheLinker.LinkInItems(Items, NativeLinkItems) )
        return 1; // Error already printed
    }

    std::auto_ptr<Module> Composite(TheLinker.releaseModule());

    // Optimize the module
    Optimize(Composite.get());

    // Generate the bytecode for the optimized module.
    std::string RealBytecodeOutput = OutputFilename;
    if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
    GenerateBytecode(Composite.get(), RealBytecodeOutput);

    // If we are not linking a library, generate either a native executable
    // or a JIT shell script, depending upon what the user wants.
    if (!LinkAsLibrary) {
      // If the user wants to run a post-link optimization, run it now.
      if (!PostLinkOpts.empty()) {
        std::vector<std::string> opts = PostLinkOpts;
        for (std::vector<std::string>::iterator I = opts.begin(),
             E = opts.end(); I != E; ++I) {
          sys::Path prog(*I);
          if (!prog.canExecute()) {
            prog = sys::Program::FindProgramByName(*I);
            if (prog.isEmpty())
              PrintAndExit(std::string("Optimization program '") + *I +
                "' is not found or not executable.");
          }
          // Get the program arguments
          sys::Path tmp_output("opt_result");
          std::string ErrMsg;
          if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg))
            PrintAndExit(ErrMsg);

          const char* args[4];
          args[0] = I->c_str();
          args[1] = RealBytecodeOutput.c_str();
          args[2] = tmp_output.c_str();
          args[3] = 0;
          if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) {
            if (tmp_output.isBytecodeFile() || tmp_output.isBitcodeFile()) {
              sys::Path target(RealBytecodeOutput);
              target.eraseFromDisk();
              if (tmp_output.renamePathOnDisk(target, &ErrMsg))
                PrintAndExit(ErrMsg, 2);
            } else
              PrintAndExit("Post-link optimization output is not bytecode");
          } else {
            PrintAndExit(ErrMsg);
          }
        }
      }

      // If the user wants to generate a native executable, compile it from the
      // bytecode file.
      //
      // Otherwise, create a script that will run the bytecode through the JIT.
      if (Native) {
        // Name of the Assembly Language output file
        sys::Path AssemblyFile ( OutputFilename);
        AssemblyFile.appendSuffix("s");

        // Mark the output files for removal if we get an interrupt.
        sys::RemoveFileOnSignal(AssemblyFile);
        sys::RemoveFileOnSignal(sys::Path(OutputFilename));

        // Determine the locations of the llc and gcc programs.
        sys::Path llc = FindExecutable("llc", argv[0]);
        if (llc.isEmpty())
          PrintAndExit("Failed to find llc");

        sys::Path gcc = FindExecutable("gcc", argv[0]);
        if (gcc.isEmpty())
          PrintAndExit("Failed to find gcc");

        // Generate an assembly language file for the bytecode.
        std::string ErrMsg;
        if (0 != GenerateAssembly(AssemblyFile.toString(), RealBytecodeOutput,
            llc, ErrMsg))
          PrintAndExit(ErrMsg);

        if (0 != GenerateNative(OutputFilename, AssemblyFile.toString(),
                                NativeLinkItems, gcc, envp, ErrMsg))
          PrintAndExit(ErrMsg);

        // Remove the assembly language file.
        AssemblyFile.eraseFromDisk();
      } else if (NativeCBE) {
        sys::Path CFile (OutputFilename);
        CFile.appendSuffix("cbe.c");

        // Mark the output files for removal if we get an interrupt.
        sys::RemoveFileOnSignal(CFile);
        sys::RemoveFileOnSignal(sys::Path(OutputFilename));

        // Determine the locations of the llc and gcc programs.
        sys::Path llc = FindExecutable("llc", argv[0]);
        if (llc.isEmpty())
          PrintAndExit("Failed to find llc");

        sys::Path gcc = FindExecutable("gcc", argv[0]);
        if (gcc.isEmpty())
          PrintAndExit("Failed to find gcc");

        // Generate an assembly language file for the bytecode.
        std::string ErrMsg;
        if (0 != GenerateCFile(
            CFile.toString(), RealBytecodeOutput, llc, ErrMsg))
          PrintAndExit(ErrMsg);

        if (0 != GenerateNative(OutputFilename, CFile.toString(), 
                                NativeLinkItems, gcc, envp, ErrMsg))
          PrintAndExit(ErrMsg);

        // Remove the assembly language file.
        CFile.eraseFromDisk();

      } else {
        EmitShellScript(argv);
      }

      // Make the script executable...
      std::string ErrMsg;
      if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg))
        PrintAndExit(ErrMsg);

      // Make the bytecode file readable and directly executable in LLEE as well
      if (sys::Path(RealBytecodeOutput).makeExecutableOnDisk(&ErrMsg))
        PrintAndExit(ErrMsg);

      if (sys::Path(RealBytecodeOutput).makeReadableOnDisk(&ErrMsg))
        PrintAndExit(ErrMsg);
    }
  } catch (const std::string& msg) {
    PrintAndExit(msg,2);
  } catch (...) {
    PrintAndExit("Unexpected unknown exception occurred.", 2);
  }

  // Graceful exit
  return 0;
}
Ejemplo n.º 10
0
int main(int argc, char **argv, char **envp) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeTarget(Registry);

  // Initial global variable above for convenience printing of program name.
  progname = sys::path::stem(argv[0]);

  // Parse the command line options
  cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");

#if defined(_WIN32) || defined(__CYGWIN__)
  if (!LinkAsLibrary) {
    // Default to "a.exe" instead of "a.out".
    if (OutputFilename.getNumOccurrences() == 0)
      OutputFilename = "a.exe";

    // If there is no suffix add an "exe" one.
    if (sys::path::extension(OutputFilename).empty())
      OutputFilename.append(".exe");
  }
#endif

  // Generate the bitcode for the optimized module.
  // If -b wasn't specified, use the name specified
  // with -o to construct BitcodeOutputFilename.
  if (BitcodeOutputFilename.empty()) {
    BitcodeOutputFilename = OutputFilename;
    if (!LinkAsLibrary) BitcodeOutputFilename += ".bc";
  }

  // Arrange for the bitcode output file to be deleted on any errors.
  BitcodeOutputRemover.setFile(BitcodeOutputFilename);
  sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename));

  // Arrange for the output file to be deleted on any errors.
  if (!LinkAsLibrary) {
    OutputRemover.setFile(OutputFilename);
    sys::RemoveFileOnSignal(sys::Path(OutputFilename));
  }

  // Construct a Linker (now that Verbose is set)
  Linker TheLinker(progname, OutputFilename, Context, Verbose);

  // Keep track of the native link items (versus the bitcode items)
  Linker::ItemList NativeLinkItems;

  // Add library paths to the linker
  TheLinker.addPaths(LibPaths);
  TheLinker.addSystemPaths();

  // Remove any consecutive duplicates of the same library...
  Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
                  Libraries.end());

  if (LinkAsLibrary) {
    std::vector<sys::Path> Files;
    for (unsigned i = 0; i < InputFilenames.size(); ++i )
      Files.push_back(sys::Path(InputFilenames[i]));
    if (TheLinker.LinkInFiles(Files))
      return 1; // Error already printed

    // The libraries aren't linked in but are noted as "dependent" in the
    // module.
    for (cl::list<std::string>::const_iterator I = Libraries.begin(),
         E = Libraries.end(); I != E ; ++I) {
      TheLinker.getModule()->addLibrary(*I);
    }
  } else {
    // Build a list of the items from our command line
    Linker::ItemList Items;
    BuildLinkItems(Items, InputFilenames, Libraries);

    // Link all the items together
    if (TheLinker.LinkInItems(Items, NativeLinkItems) )
      return 1; // Error already printed
  }

  std::auto_ptr<Module> Composite(TheLinker.releaseModule());

  // Optimize the module
  Optimize(Composite.get());

  // Generate the bitcode output.
  GenerateBitcode(Composite.get(), BitcodeOutputFilename);

  // If we are not linking a library, generate either a native executable
  // or a JIT shell script, depending upon what the user wants.
  if (!LinkAsLibrary) {
    // If the user wants to run a post-link optimization, run it now.
    if (!PostLinkOpts.empty()) {
      std::vector<std::string> opts = PostLinkOpts;
      for (std::vector<std::string>::iterator I = opts.begin(),
           E = opts.end(); I != E; ++I) {
        sys::Path prog(*I);
        if (!prog.canExecute()) {
          prog = sys::Program::FindProgramByName(*I);
          if (prog.isEmpty())
            PrintAndExit(std::string("Optimization program '") + *I +
                         "' is not found or not executable.", Composite.get());
        }
        // Get the program arguments
        sys::Path tmp_output("opt_result");
        std::string ErrMsg;
        if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg))
          PrintAndExit(ErrMsg, Composite.get());

        const char* args[4];
        args[0] = I->c_str();
        args[1] = BitcodeOutputFilename.c_str();
        args[2] = tmp_output.c_str();
        args[3] = 0;
        if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) {
          if (tmp_output.isBitcodeFile()) {
            sys::Path target(BitcodeOutputFilename);
            target.eraseFromDisk();
            if (tmp_output.renamePathOnDisk(target, &ErrMsg))
              PrintAndExit(ErrMsg, Composite.get(), 2);
          } else
            PrintAndExit("Post-link optimization output is not bitcode",
                         Composite.get());
        } else {
          PrintAndExit(ErrMsg, Composite.get());
        }
      }
    }

    // If the user wants to generate a native executable, compile it from the
    // bitcode file.
    //
    // Otherwise, create a script that will run the bitcode through the JIT.
    if (Native) {
      // Name of the Assembly Language output file
      sys::Path AssemblyFile ( OutputFilename);
      AssemblyFile.appendSuffix("s");

      // Mark the output files for removal.
      FileRemover AssemblyFileRemover(AssemblyFile.str());
      sys::RemoveFileOnSignal(AssemblyFile);

      // Determine the locations of the llc and gcc programs.
      sys::Path llc = PrependMainExecutablePath("llc", argv[0],
                                                (void *)(intptr_t)&Optimize);
      if (llc.isEmpty())
        PrintAndExit("Failed to find llc", Composite.get());

      sys::Path gcc = sys::Program::FindProgramByName("gcc");
      if (gcc.isEmpty())
        PrintAndExit("Failed to find gcc", Composite.get());

      // Generate an assembly language file for the bitcode.
      std::string ErrMsg;
      if (0 != GenerateAssembly(AssemblyFile.str(), BitcodeOutputFilename,
          llc, ErrMsg))
        PrintAndExit(ErrMsg, Composite.get());

      if (0 != GenerateNative(OutputFilename, AssemblyFile.str(),
                              NativeLinkItems, gcc, envp, ErrMsg))
        PrintAndExit(ErrMsg, Composite.get());
    } else if (NativeCBE) {
      sys::Path CFile (OutputFilename);
      CFile.appendSuffix("cbe.c");

      // Mark the output files for removal.
      FileRemover CFileRemover(CFile.str());
      sys::RemoveFileOnSignal(CFile);

      // Determine the locations of the llc and gcc programs.
      sys::Path llc = PrependMainExecutablePath("llc", argv[0],
                                                (void *)(intptr_t)&Optimize);
      if (llc.isEmpty())
        PrintAndExit("Failed to find llc", Composite.get());

      sys::Path gcc = sys::Program::FindProgramByName("gcc");
      if (gcc.isEmpty())
        PrintAndExit("Failed to find gcc", Composite.get());

      // Generate an assembly language file for the bitcode.
      std::string ErrMsg;
      if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg))
        PrintAndExit(ErrMsg, Composite.get());

      if (GenerateNative(OutputFilename, CFile.str(),
                         NativeLinkItems, gcc, envp, ErrMsg))
        PrintAndExit(ErrMsg, Composite.get());
    } else {
      EmitShellScript(argv, Composite.get());
    }

    // Make the script executable...
    std::string ErrMsg;
    if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg))
      PrintAndExit(ErrMsg, Composite.get());

    // Make the bitcode file readable and directly executable in LLEE as well
    if (sys::Path(BitcodeOutputFilename).makeExecutableOnDisk(&ErrMsg))
      PrintAndExit(ErrMsg, Composite.get());

    if (sys::Path(BitcodeOutputFilename).makeReadableOnDisk(&ErrMsg))
      PrintAndExit(ErrMsg, Composite.get());
  }

  // Operations which may fail are now complete.
  BitcodeOutputRemover.releaseFile();
  if (!LinkAsLibrary)
    OutputRemover.releaseFile();

  // Graceful exit
  return 0;
}
Ejemplo n.º 11
0
/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM
/// bitcode file for the program.
static void EmitShellScript(char **argv, Module *M) {
  if (Verbose)
    errs() << "Emitting Shell Script\n";
#if defined(_WIN32)
  // Windows doesn't support #!/bin/sh style shell scripts in .exe files.  To
  // support windows systems, we copy the llvm-stub.exe executable from the
  // build tree to the destination file.
  std::string ErrMsg;
  sys::Path llvmstub = PrependMainExecutablePath("llvm-stub", argv[0],
                                                 (void *)(intptr_t)&Optimize);
  if (llvmstub.isEmpty())
    PrintAndExit("Could not find llvm-stub.exe executable!", M);

  if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg))
    PrintAndExit(ErrMsg, M);

  return;
#endif

  // Output the script to start the program...
  std::string ErrorInfo;
  tool_output_file Out2(OutputFilename.c_str(), ErrorInfo);
  if (!ErrorInfo.empty())
    PrintAndExit(ErrorInfo, M);

  Out2.os() << "#!/bin/sh\n";
  // Allow user to setenv LLVMINTERP if lli is not in their PATH.
  Out2.os() << "lli=${LLVMINTERP-lli}\n";
  Out2.os() << "exec $lli \\\n";
  // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib.
  LibPaths.push_back("/lib");
  LibPaths.push_back("/usr/lib");
  LibPaths.push_back("/usr/X11R6/lib");
  // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a
  // shared object at all! See RH 8: plain text.
  std::vector<std::string>::iterator libc =
    std::find(Libraries.begin(), Libraries.end(), "c");
  if (libc != Libraries.end()) Libraries.erase(libc);
  // List all the shared object (native) libraries this executable will need
  // on the command line, so that we don't have to do this manually!
  for (std::vector<std::string>::iterator i = Libraries.begin(),
         e = Libraries.end(); i != e; ++i) {
    // try explicit -L arguments first:
    sys::Path FullLibraryPath;
    for (cl::list<std::string>::const_iterator P = LibPaths.begin(),
           E = LibPaths.end(); P != E; ++P) {
      FullLibraryPath = *P;
      FullLibraryPath.appendComponent("lib" + *i);
      FullLibraryPath.appendSuffix(sys::Path::GetDLLSuffix());
      if (!FullLibraryPath.isEmpty()) {
        if (!FullLibraryPath.isDynamicLibrary()) {
          // Not a native shared library; mark as invalid
          FullLibraryPath = sys::Path();
        } else break;
      }
    }
    if (FullLibraryPath.isEmpty())
      FullLibraryPath = sys::Path::FindLibrary(*i);
    if (!FullLibraryPath.isEmpty())
      Out2.os() << "    -load=" << FullLibraryPath.str() << " \\\n";
  }
  Out2.os() << "    "  << BitcodeOutputFilename << " ${1+\"$@\"}\n";
  Out2.keep();
}