int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); CommonOptionsParser OptionsParser(argc, argv, ClangQueryCategory); if (!Commands.empty() && !CommandFiles.empty()) { llvm::errs() << argv[0] << ": cannot specify both -c and -f\n"; return 1; } ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); std::vector<std::unique_ptr<ASTUnit>> ASTs; if (Tool.buildASTs(ASTs) != 0) return 1; QuerySession QS(ASTs); if (!Commands.empty()) { for (cl::list<std::string>::iterator I = Commands.begin(), E = Commands.end(); I != E; ++I) { QueryRef Q = QueryParser::parse(*I, QS); if (!Q->run(llvm::outs(), QS)) return 1; } } else if (!CommandFiles.empty()) { for (cl::list<std::string>::iterator I = CommandFiles.begin(), E = CommandFiles.end(); I != E; ++I) { std::ifstream Input(I->c_str()); if (!Input.is_open()) { llvm::errs() << argv[0] << ": cannot open " << *I << "\n"; return 1; } while (Input.good()) { std::string Line; std::getline(Input, Line); QueryRef Q = QueryParser::parse(Line, QS); if (!Q->run(llvm::outs(), QS)) return 1; } } } else { LineEditor LE("clang-query"); LE.setListCompleter([&QS](StringRef Line, size_t Pos) { return QueryParser::complete(Line, Pos, QS); }); while (llvm::Optional<std::string> Line = LE.readLine()) { QueryRef Q = QueryParser::parse(*Line, QS); Q->run(llvm::outs(), QS); llvm::outs().flush(); if (QS.Terminate) break; } } return 0; }
int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); cl::ParseCommandLineOptions( argc, argv, "A tool to format C/C++/Obj-C code.\n\n" "If no arguments are specified, it formats the code from standard input\n" "and writes the result to the standard output.\n" "If <file>s are given, it reformats the files. If -i is specified \n" "together with <file>s, the files are edited in-place. Otherwise, the \n" "result is written to the standard output.\n"); if (Help) cl::PrintHelpMessage(); bool Error = false; switch (FileNames.size()) { case 0: Error = clang::format::format("-"); break; case 1: Error = clang::format::format(FileNames[0]); break; default: if (!Offsets.empty() || !Lengths.empty()) { llvm::errs() << "error: \"-offset\" and \"-length\" can only be used for " "single file.\n"; return 1; } for (unsigned i = 0; i < FileNames.size(); ++i) Error |= clang::format::format(FileNames[i]); break; } return Error ? 1 : 0; }
virtual bool runOnModule(Module& M) { AliasAnalysis& aa = this->getAnalysis<AliasAnalysis>(); bool checked = false; errs() << "GatherInterfacePass::runOnModule: " << M.getModuleIdentifier() << "\n"; if (!GatherInterfaceMain.empty()) { checked = true; for (cl::list<std::string>::const_iterator i = GatherInterfaceMain.begin(), e = GatherInterfaceMain.end(); i != e; ++i) { Function* f = M.getFunction(*i); if (f == NULL) { errs() << "Function '" << *i << "' not found, skipping\n"; continue; } if (f->isDeclaration()) { errs() << "Function '" << *i << "' is declaration, skipping\n"; continue; } errs() << "Gathering from: " << *f << "\n"; GatherInterface(*f, this->interface, &aa); } } if (!GatherInterfaceEntry.empty()) { checked = true; ComponentInterface ci; for (cl::list<std::string>::const_iterator i = GatherInterfaceEntry.begin(), e = GatherInterfaceEntry.end(); i != e; ++i) { errs() << "Reading interface from '" << *i << "'..."; if (ci.readFromFile(*i)) { errs() << "success\n"; } else { errs() << "failed\n"; continue; } } for (ComponentInterface::FunctionIterator i = ci.begin(), e = ci.end(); i != e; ++i) { Function* f = M.getFunction(i->first()); if (f == NULL) continue; if (!GatherInterface(*f, this->interface, &aa)) break; } } if (!checked) { GatherInterface(M, this->interface, &aa); } if (GatherInterfaceOutput != "") { proto::ComponentInterface ci; codeInto<ComponentInterface, proto::ComponentInterface> ( this->interface, ci); std::ofstream output(GatherInterfaceOutput.c_str(), std::ios::binary); assert(ci.SerializeToOstream(&output)); output.close(); } return false; }
int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); // Hide unrelated options. StringMap<cl::Option*> Options; cl::getRegisteredOptions(Options); for (StringMap<cl::Option *>::iterator I = Options.begin(), E = Options.end(); I != E; ++I) { if (I->second->Category != &ClangFormatCategory && I->first() != "help" && I->first() != "version") I->second->setHiddenFlag(cl::ReallyHidden); } cl::SetVersionPrinter(PrintVersion); cl::ParseCommandLineOptions( argc, argv, "A tool to format C/C++/Obj-C code.\n\n" "If no arguments are specified, it formats the code from standard input\n" "and writes the result to the standard output.\n" "If <file>s are given, it reformats the files. If -i is specified\n" "together with <file>s, the files are edited in-place. Otherwise, the\n" "result is written to the standard output.\n"); if (Help) cl::PrintHelpMessage(); if (DumpConfig) { std::string Config = clang::format::configurationAsText(clang::format::getStyle( Style, FileNames.empty() ? AssumeFilename : FileNames[0], FallbackStyle)); llvm::outs() << Config << "\n"; return 0; } bool Error = false; switch (FileNames.size()) { case 0: Error = clang::format::format("-"); break; case 1: Error = clang::format::format(FileNames[0]); break; default: if (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty()) { llvm::errs() << "error: -offset, -length and -lines can only be used for " "single file.\n"; return 1; } for (unsigned i = 0; i < FileNames.size(); ++i) Error |= clang::format::format(FileNames[i]); break; } return Error ? 1 : 0; }
int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); cl::HideUnrelatedOptions(ClangFormatCategory); cl::SetVersionPrinter(PrintVersion); cl::ParseCommandLineOptions( argc, argv, "A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf code.\n\n" "If no arguments are specified, it formats the code from standard input\n" "and writes the result to the standard output.\n" "If <file>s are given, it reformats the files. If -i is specified\n" "together with <file>s, the files are edited in-place. Otherwise, the\n" "result is written to the standard output.\n"); if (Help) cl::PrintHelpMessage(); if (DumpConfig) { llvm::Expected<clang::format::FormatStyle> FormatStyle = clang::format::getStyle( Style, FileNames.empty() ? AssumeFileName : FileNames[0], FallbackStyle); if (!FormatStyle) { llvm::errs() << llvm::toString(FormatStyle.takeError()) << "\n"; return 1; } std::string Config = clang::format::configurationAsText(*FormatStyle); outs() << Config << "\n"; return 0; } bool Error = false; switch (FileNames.size()) { case 0: Error = clang::format::format("-"); break; case 1: Error = clang::format::format(FileNames[0]); break; default: if (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty()) { errs() << "error: -offset, -length and -lines can only be used for " "single file.\n"; return 1; } for (unsigned i = 0; i < FileNames.size(); ++i) Error |= clang::format::format(FileNames[i]); break; } return Error ? 1 : 0; }
//Check options of the decoder engine void setOptions(){ //Verify if directory is well formed OptionMng::setDirectory(&VTLDir); OptionMng::setDirectory(&OutputDir); OptionMng::setDirectory(&InputDir); //Set an optimization level if (OptLevelO1){ optLevel = 1; }else if (OptLevelO2){ optLevel = 2; }else if (OptLevelO3){ optLevel = 3; }else{ optLevel = 0; } //Set native variables string writer_file = OutputDir + "writer.txt"; if (YuvFile != ""){ yuv_file = (char*)YuvFile.c_str(); } write_file = (char*)writer_file.c_str(); if (nodisplay){ display_flags = DISPLAY_DISABLE; } else { display_flags = DISPLAY_ENABLE; } if (!debexec.empty()){ enableTrace = true; } }
int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv); LLVMContext Context; // Load both modules. Die if that fails. Module *LModule = ReadModule(Context, LeftFilename); Module *RModule = ReadModule(Context, RightFilename); if (!LModule || !RModule) return 1; DiffConsumer Consumer(LModule, RModule); DifferenceEngine Engine(Context, Consumer); // If any global names were given, just diff those. if (!GlobalsToCompare.empty()) { for (unsigned I = 0, E = GlobalsToCompare.size(); I != E; ++I) diffGlobal(Engine, LModule, RModule, GlobalsToCompare[I]); // Otherwise, diff everything in the module. } else { Engine.diff(LModule, RModule); } delete LModule; delete RModule; return Consumer.hadDifferences(); }
int main(int argc, char **argv) { InitLLVM X(argc, argv); llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded); cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n"); LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable, ClDemangle, ClUseRelativeAddress, ClDefaultArch); for (const auto &hint : ClDsymHint) { if (sys::path::extension(hint) == ".dSYM") { Opts.DsymHints.push_back(hint); } else { errs() << "Warning: invalid dSYM hint: \"" << hint << "\" (must have the '.dSYM' extension).\n"; } } LLVMSymbolizer Symbolizer(Opts); DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None, ClPrettyPrint, ClPrintSourceContextLines, ClVerbose); if (ClInputAddresses.empty()) { const int kMaxInputStringLength = 1024; char InputString[kMaxInputStringLength]; while (fgets(InputString, sizeof(InputString), stdin)) symbolizeInput(InputString, Symbolizer, Printer); } else { for (StringRef Address : ClInputAddresses) symbolizeInput(Address, Symbolizer, Printer); } return 0; }
InternalizePass::InternalizePass(bool AllButMain) : ModulePass(ID), AllButMain(AllButMain){ initializeInternalizePassPass(*PassRegistry::getPassRegistry()); if (!APIFile.empty()) // If a filename is specified, use it. LoadFile(APIFile.c_str()); if (!APIList.empty()) // If a list is specified, use it as well. ExternalNames.insert(APIList.begin(), APIList.end()); }
int main(int argc, char **argv) { InitLLVM X(argc, argv); cl::ParseCommandLineOptions(argc, argv, "llvm-undname\n"); if (Symbols.empty()) { while (true) { std::string LineStr; std::getline(std::cin, LineStr); if (std::cin.eof()) break; StringRef Line(LineStr); Line = Line.trim(); if (Line.empty() || Line.startswith("#") || Line.startswith(";")) continue; // If the user is manually typing in these decorated names, don't echo // them to the terminal a second time. If they're coming from redirected // input, however, then we should display the input line so that the // mangled and demangled name can be easily correlated in the output. if (!sys::Process::StandardInIsUserInput()) { outs() << Line << "\n"; outs().flush(); } demangle(Line); outs() << "\n"; } } else { for (StringRef S : Symbols) { outs() << S << "\n"; outs().flush(); demangle(S); outs() << "\n"; } } return 0; }
bool optimize() { return optimizeLevel || doInline() || !passList.empty(); }
// I don't think there's a way to specify an initial value for cl::list, // so if nothing was specified, add the default static void AddCheckPrefixIfNeeded() { if (CheckPrefixes.empty()) CheckPrefixes.push_back("CHECK"); }
//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeDebugIRPass(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); // For codegen passes, only passes that do IR to IR transformation are // supported. initializeCodeGenPreparePass(Registry); initializeAtomicExpandLoadLinkedPass(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); #endif cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); if (AnalyzeOnly && NoOutput) { errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n"; return 1; } SMDiagnostic Err; // Load the input module... std::unique_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (!M.get()) { Err.print(argv[0], errs()); return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); // Figure out what stream we are supposed to write to... std::unique_ptr<tool_output_file> Out; if (NoOutput) { if (!OutputFilename.empty()) errs() << "WARNING: The -o (output filename) option is ignored when\n" "the --disable-output option is used.\n"; } else { // Default to standard output. if (OutputFilename.empty()) OutputFilename = "-"; std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, sys::fs::F_None)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } } // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) NoOutput = true; if (PassPipeline.getNumOccurrences() > 0) { OutputKind OK = OK_NoOutput; if (!NoOutput) OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode; VerifierKind VK = VK_VerifyInAndOut; if (NoVerify) VK = VK_NoVerifier; else if (VerifyEach) VK = VK_VerifyEachPass; // The user has asked to use the new pass manager and provided a pipeline // string. Hand off the rest of the functionality to the new code for that // layer. return runPassPipeline(argv[0], Context, *M.get(), Out.get(), PassPipeline, OK, VK) ? 0 : 1; } // Create a PassManager to hold and optimize the collection of passes we are // about to build. // PassManager Passes; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple())); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLI->disableAllFunctions(); Passes.add(TLI); // Add an appropriate DataLayout instance for this module. const DataLayout *DL = M.get()->getDataLayout(); if (!DL && !DefaultDataLayout.empty()) { M->setDataLayout(DefaultDataLayout); DL = M.get()->getDataLayout(); } if (DL) Passes.add(new DataLayoutPass(M.get())); // pass tcl files to LegupConfig if (!ConfigFile.empty()) { for (unsigned i = 0; i < ConfigFile.size();++i) { if (!legup::parseTclFile(ConfigFile[i], legup::LEGUP_CONFIG)) { return 1; } } } // run LegUp tcl commands if (!LegUpTclCommands.empty()) { if (!legup::parseTclString(LegUpTclCommands, legup::LEGUP_CONFIG)) { return 1; } return 0; } Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = nullptr; if (ModuleTriple.getArch()) Machine = GetTargetMachine(Triple(ModuleTriple)); std::unique_ptr<TargetMachine> TM(Machine); // Add internal analysis passes from the target machine. if (TM.get()) TM->addAnalysisPasses(Passes); std::unique_ptr<FunctionPassManager> FPasses; if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new FunctionPassManager(M.get())); if (DL) FPasses->add(new DataLayoutPass(M.get())); if (TM.get()) TM->addAnalysisPasses(*FPasses); } if (PrintBreakpoints) { // Default to standard output. if (!Out) { if (OutputFilename.empty()) OutputFilename = "-"; std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, sys::fs::F_None)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } } Passes.add(createBreakpointPrinter(Out->os())); NoOutput = true; } // If the -strip-debug command line option was specified, add it. If // -std-compile-opts was also specified, it will handle StripDebug. if (StripDebug && !StandardCompileOpts) addPass(Passes, createStripSymbolsPass(true)); // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { // Check to see if -std-compile-opts was specified before this option. If // so, handle it. if (StandardCompileOpts && StandardCompileOpts.getPosition() < PassList.getPosition(i)) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts && StandardLinkOpts.getPosition() < PassList.getPosition(i)) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 1, 0); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 0); OptLevelO2 = false; } if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 1); OptLevelOs = false; } if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 2); OptLevelOz = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 3, 0); OptLevelO3 = false; } const PassInfo *PassInf = PassList[i]; Pass *P = nullptr; if (PassInf->getTargetMachineCtor()) P = PassInf->getTargetMachineCtor()(TM.get()); else if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: "******"\n"; if (P) { PassKind Kind = P->getPassKind(); addPass(Passes, P); if (AnalyzeOnly) { switch (Kind) { case PT_BasicBlock: Passes.add(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Region: Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Loop: Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Function: Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_CallGraphSCC: Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet)); break; default: Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet)); break; } } } if (PrintEachXForm) Passes.add(createPrintModulePass(errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. if (StandardCompileOpts) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1) AddOptimizationPasses(Passes, *FPasses, 1, 0); if (OptLevelO2) AddOptimizationPasses(Passes, *FPasses, 2, 0); if (OptLevelOs) AddOptimizationPasses(Passes, *FPasses, 2, 1); if (OptLevelOz) AddOptimizationPasses(Passes, *FPasses, 2, 2); if (OptLevelO3) AddOptimizationPasses(Passes, *FPasses, 3, 0); if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses->doInitialization(); for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F) FPasses->run(*F); FPasses->doFinalization(); } // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) { Passes.add(createVerifierPass()); Passes.add(createDebugInfoVerifierPass()); } // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) Passes.add(createPrintModulePass(Out->os())); else Passes.add(createBitcodeWriterPass(Out->os())); } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Declare success. if (!NoOutput || PrintBreakpoints) Out->keep(); return 0; }
int main(int argc, char **argv) { InitLLVM X(argc, argv); LLVMContext Context; cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n"); // Use lazy loading, since we only care about selected global values. SMDiagnostic Err; std::unique_ptr<Module> M = getLazyIRFileModule(InputFilename, Err, Context); if (!M.get()) { Err.print(argv[0], errs()); return 1; } // Use SetVector to avoid duplicates. SetVector<GlobalValue *> GVs; // Figure out which aliases we should extract. for (size_t i = 0, e = ExtractAliases.size(); i != e; ++i) { GlobalAlias *GA = M->getNamedAlias(ExtractAliases[i]); if (!GA) { errs() << argv[0] << ": program doesn't contain alias named '" << ExtractAliases[i] << "'!\n"; return 1; } GVs.insert(GA); } // Extract aliases via regular expression matching. for (size_t i = 0, e = ExtractRegExpAliases.size(); i != e; ++i) { std::string Error; Regex RegEx(ExtractRegExpAliases[i]); if (!RegEx.isValid(Error)) { errs() << argv[0] << ": '" << ExtractRegExpAliases[i] << "' " "invalid regex: " << Error; } bool match = false; for (Module::alias_iterator GA = M->alias_begin(), E = M->alias_end(); GA != E; GA++) { if (RegEx.match(GA->getName())) { GVs.insert(&*GA); match = true; } } if (!match) { errs() << argv[0] << ": program doesn't contain global named '" << ExtractRegExpAliases[i] << "'!\n"; return 1; } } // Figure out which globals we should extract. for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) { GlobalValue *GV = M->getNamedGlobal(ExtractGlobals[i]); if (!GV) { errs() << argv[0] << ": program doesn't contain global named '" << ExtractGlobals[i] << "'!\n"; return 1; } GVs.insert(GV); } // Extract globals via regular expression matching. for (size_t i = 0, e = ExtractRegExpGlobals.size(); i != e; ++i) { std::string Error; Regex RegEx(ExtractRegExpGlobals[i]); if (!RegEx.isValid(Error)) { errs() << argv[0] << ": '" << ExtractRegExpGlobals[i] << "' " "invalid regex: " << Error; } bool match = false; for (auto &GV : M->globals()) { if (RegEx.match(GV.getName())) { GVs.insert(&GV); match = true; } } if (!match) { errs() << argv[0] << ": program doesn't contain global named '" << ExtractRegExpGlobals[i] << "'!\n"; return 1; } } // Figure out which functions we should extract. for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) { GlobalValue *GV = M->getFunction(ExtractFuncs[i]); if (!GV) { errs() << argv[0] << ": program doesn't contain function named '" << ExtractFuncs[i] << "'!\n"; return 1; } GVs.insert(GV); } // Extract functions via regular expression matching. for (size_t i = 0, e = ExtractRegExpFuncs.size(); i != e; ++i) { std::string Error; StringRef RegExStr = ExtractRegExpFuncs[i]; Regex RegEx(RegExStr); if (!RegEx.isValid(Error)) { errs() << argv[0] << ": '" << ExtractRegExpFuncs[i] << "' " "invalid regex: " << Error; } bool match = false; for (Module::iterator F = M->begin(), E = M->end(); F != E; F++) { if (RegEx.match(F->getName())) { GVs.insert(&*F); match = true; } } if (!match) { errs() << argv[0] << ": program doesn't contain global named '" << ExtractRegExpFuncs[i] << "'!\n"; return 1; } } // Figure out which BasicBlocks we should extract. SmallVector<BasicBlock *, 4> BBs; for (StringRef StrPair : ExtractBlocks) { auto BBInfo = StrPair.split(':'); // Get the function. Function *F = M->getFunction(BBInfo.first); if (!F) { errs() << argv[0] << ": program doesn't contain a function named '" << BBInfo.first << "'!\n"; return 1; } // Do not materialize this function. GVs.insert(F); // Get the basic block. auto Res = llvm::find_if(*F, [&](const BasicBlock &BB) { return BB.getName().equals(BBInfo.second); }); if (Res == F->end()) { errs() << argv[0] << ": function " << F->getName() << " doesn't contain a basic block named '" << BBInfo.second << "'!\n"; return 1; } BBs.push_back(&*Res); } // Use *argv instead of argv[0] to work around a wrong GCC warning. ExitOnError ExitOnErr(std::string(*argv) + ": error reading input: "); if (Recursive) { std::vector<llvm::Function *> Workqueue; for (GlobalValue *GV : GVs) { if (auto *F = dyn_cast<Function>(GV)) { Workqueue.push_back(F); } } while (!Workqueue.empty()) { Function *F = &*Workqueue.back(); Workqueue.pop_back(); ExitOnErr(F->materialize()); for (auto &BB : *F) { for (auto &I : BB) { auto *CI = dyn_cast<CallInst>(&I); if (!CI) continue; Function *CF = CI->getCalledFunction(); if (!CF) continue; if (CF->isDeclaration() || GVs.count(CF)) continue; GVs.insert(CF); Workqueue.push_back(CF); } } } } auto Materialize = [&](GlobalValue &GV) { ExitOnErr(GV.materialize()); }; // Materialize requisite global values. if (!DeleteFn) { for (size_t i = 0, e = GVs.size(); i != e; ++i) Materialize(*GVs[i]); } else { // Deleting. Materialize every GV that's *not* in GVs. SmallPtrSet<GlobalValue *, 8> GVSet(GVs.begin(), GVs.end()); for (auto &F : *M) { if (!GVSet.count(&F)) Materialize(F); } } { std::vector<GlobalValue *> Gvs(GVs.begin(), GVs.end()); legacy::PassManager Extract; Extract.add(createGVExtractionPass(Gvs, DeleteFn)); Extract.run(*M); // Now that we have all the GVs we want, mark the module as fully // materialized. // FIXME: should the GVExtractionPass handle this? ExitOnErr(M->materializeAll()); } // Extract the specified basic blocks from the module and erase the existing // functions. if (!ExtractBlocks.empty()) { legacy::PassManager PM; PM.add(createBlockExtractorPass(BBs, true)); PM.run(*M); } // In addition to deleting all other functions, we also want to spiff it // up a little bit. Do this now. legacy::PassManager Passes; if (!DeleteFn) Passes.add(createGlobalDCEPass()); // Delete unreachable globals Passes.add(createStripDeadDebugInfoPass()); // Remove dead debug info Passes.add(createStripDeadPrototypesPass()); // Remove dead func decls std::error_code EC; ToolOutputFile Out(OutputFilename, EC, sys::fs::F_None); if (EC) { errs() << EC.message() << '\n'; return 1; } if (OutputAssembly) Passes.add( createPrintModulePass(Out.os(), "", PreserveAssemblyUseListOrder)); else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true)) Passes.add(createBitcodeWriterPass(Out.os(), PreserveBitcodeUseListOrder)); Passes.run(*M.get()); // Declare success. Out.keep(); return 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; }
// main - Entry point for the llc compiler. // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets first, so that --version shows registered targets. InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); // Initialize codegen and IR passes used by llc so that the -print-after, // -print-before, and -stop-after options work. PassRegistry *Registry = PassRegistry::getPassRegistry(); initializeCore(*Registry); initializeCodeGen(*Registry); initializeLoopStrengthReducePass(*Registry); initializeLowerIntrinsicsPass(*Registry); initializeUnreachableBlockElimPass(*Registry); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); // Load the module to be compiled... SMDiagnostic Err; std::auto_ptr<Module> M; Module *mod = 0; Triple TheTriple; bool SkipModule = MCPU == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); // If user just wants to list available options, skip module loading if (!SkipModule) { M.reset(ParseIRFile(InputFilename, Err, Context)); mod = M.get(); if (mod == 0) { Err.print(argv[0], errs()); return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod->setTargetTriple(Triple::normalize(TargetTriple)); TheTriple = Triple(mod->getTargetTriple()); } else { TheTriple = Triple(Triple::normalize(TargetTriple)); } if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << argv[0] << ": " << Error; return 1; } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options; Options.LessPreciseFPMADOption = EnableFPMAD; Options.NoFramePointerElim = DisableFPElim; Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf; Options.AllowFPOpFusion = FuseFPOps; Options.UnsafeFPMath = EnableUnsafeFPMath; Options.NoInfsFPMath = EnableNoInfsFPMath; Options.NoNaNsFPMath = EnableNoNaNsFPMath; Options.HonorSignDependentRoundingFPMathOption = EnableHonorSignDependentRoundingFPMath; Options.UseSoftFloat = GenerateSoftFloatCalls; if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; Options.NoZerosInBSS = DontPlaceZerosInBSS; Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; Options.DisableTailCalls = DisableTailCalls; Options.StackAlignmentOverride = OverrideStackAlignment; Options.RealignStack = EnableRealignStack; Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; Options.EnableSegmentedStacks = SegmentedStacks; Options.UseInitArray = UseInitArray; std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(target.get() && "Could not allocate target machine!"); assert(mod && "Should have exited after outputting help!"); TargetMachine &Target = *target.get(); if (DisableDotLoc) Target.setMCUseLoc(false); if (DisableCFI) Target.setMCUseCFI(false); if (EnableDwarfDirectory) Target.setMCUseDwarfDirectory(true); if (GenerateSoftFloatCalls) FloatABIForCalls = FloatABI::Soft; // Disable .loc support for older OS X versions. if (TheTriple.isMacOSX() && TheTriple.isMacOSXVersionLT(10, 6)) Target.setMCUseLoc(false); // Figure out where we are going to send the output. OwningPtr<tool_output_file> Out (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); if (!Out) return 1; // Build up all of the passes that we want to do to the module. PassManager PM; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple); if (DisableSimplifyLibCalls) TLI->disableAllFunctions(); PM.add(TLI); // Add the target data from the target machine, if it exists, or the module. if (const TargetData *TD = Target.getTargetData()) PM.add(new TargetData(*TD)); else PM.add(new TargetData(mod)); // Override default to generate verbose assembly. Target.setAsmVerbosityDefault(true); if (RelaxAll) { if (FileType != TargetMachine::CGFT_ObjectFile) errs() << argv[0] << ": warning: ignoring -mc-relax-all because filetype != obj"; else Target.setMCRelaxAll(true); } { formatted_raw_ostream FOS(Out->os()); AnalysisID StartAfterID = 0; AnalysisID StopAfterID = 0; const PassRegistry *PR = PassRegistry::getPassRegistry(); if (!StartAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StartAfter); if (!PI) { errs() << argv[0] << ": start-after pass is not registered.\n"; return 1; } StartAfterID = PI->getTypeInfo(); } if (!StopAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StopAfter); if (!PI) { errs() << argv[0] << ": stop-after pass is not registered.\n"; return 1; } StopAfterID = PI->getTypeInfo(); } // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify, StartAfterID, StopAfterID)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); PM.run(*mod); } // Declare success. Out->keep(); return 0; }
// Returns true on error. static bool format(StringRef FileName) { ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr = MemoryBuffer::getFileOrSTDIN(FileName); if (std::error_code EC = CodeOrErr.getError()) { llvm::errs() << EC.message() << "\n"; return true; } std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get()); if (Code->getBufferSize() == 0) return false; // Empty files are formatted correctly. FormatterDocument Doc(std::move(Code)); if (!Offsets.empty() || !Lengths.empty()) { if (Offsets.size() != Lengths.size()) { llvm::errs() << "error: number of offsets not equal to number of lengths.\n"; return true; } for ( unsigned i=0 ; i < Offsets.size() ; i++ ) { unsigned FromLine = Doc.getLineAndColumn(Offsets[i]).first; unsigned ToLine = Doc.getLineAndColumn(Offsets[i] + Lengths[i]).first; if (ToLine == 0) { llvm::errs() << "error: offset + length after end of file\n"; return true; } std::ostringstream s; s << FromLine << ":" << ToLine; LineRanges.push_back(s.str()); } } if (LineRanges.empty()) LineRanges.push_back("1:999999"); std::string Output = Doc.memBuffer().getBuffer(); Replacements Replaces; for ( unsigned Range = 0 ; Range < LineRanges.size() ; Range++ ) { unsigned FromLine, ToLine; if (parseLineRange(LineRanges[Range], FromLine, ToLine)) { llvm::errs() << "error: invalid <start line>:<end line> pair\n"; return true; } if (FromLine > ToLine) { llvm::errs() << "error: start line should be less than end line\n"; return true; } for ( unsigned Line = FromLine ; Line<=ToLine ; Line++ ) { size_t Offset = getOffsetOfLine(Line,Output); ssize_t Length = getOffsetOfLine(Line+1,Output)-1-Offset; if (Length < 0) break; std::string Formatted = Doc.reformat(LineRange(Line,1), FormatOptions).second; if (Formatted.find_first_not_of(" \t\v\f", 0) == StringRef::npos) Formatted = ""; if (Formatted == Output.substr(Offset, Length)) continue; Output.replace(Offset, Length, Formatted); Doc.updateCode(std::move(MemoryBuffer::getMemBuffer(Output))); Replaces.insert(clang::tooling::Replacement(FileName, Offset, Length, Formatted)); } } if (OutputXML) { llvm::outs() << "<?xml version='1.0'?>\n<replacements>\n"; outputReplacementsXML(Replaces); llvm::outs() << "</replacements>\n"; } else { if (Inplace) { if (FileName == "-") { llvm::errs() << "error: cannot use -i when reading from stdin.\n"; return true; } else { std::error_code EC; raw_fd_ostream writer(FileName, EC, llvm::sys::fs::F_None); if (EC) { llvm::errs() << "error: writing " << FileName << ": " << EC.message() << "\n"; return true; } writer << Output; } } else { llvm::outs() << Output; } } return false; }
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; }
// Parse the command line options as presented and return the operation // specified. Process all modifiers and check to make sure that constraints on // modifier/operation pairs have not been violated. static ArchiveOperation parseCommandLine() { if (MRI) { if (!RestOfArgs.empty()) fail("Cannot mix -M and other options"); runMRIScript(); } getOptions(); // Keep track of number of operations. We can only specify one // per execution. unsigned NumOperations = 0; // Keep track of the number of positional modifiers (a,b,i). Only // one can be specified. unsigned NumPositional = 0; // Keep track of which operation was requested ArchiveOperation Operation; bool MaybeJustCreateSymTab = false; for(unsigned i=0; i<Options.size(); ++i) { switch(Options[i]) { case 'd': ++NumOperations; Operation = Delete; break; case 'm': ++NumOperations; Operation = Move ; break; case 'p': ++NumOperations; Operation = Print; break; case 'q': ++NumOperations; Operation = QuickAppend; break; case 'r': ++NumOperations; Operation = ReplaceOrInsert; break; case 't': ++NumOperations; Operation = DisplayTable; break; case 'x': ++NumOperations; Operation = Extract; break; case 'c': Create = true; break; case 'l': /* accepted but unused */ break; case 'o': OriginalDates = true; break; case 's': Symtab = true; MaybeJustCreateSymTab = true; break; case 'S': Symtab = false; break; case 'u': OnlyUpdate = true; break; case 'v': Verbose = true; break; case 'a': getRelPos(); AddAfter = true; NumPositional++; break; case 'b': getRelPos(); AddBefore = true; NumPositional++; break; case 'i': getRelPos(); AddBefore = true; NumPositional++; break; default: cl::PrintHelpMessage(); } } // At this point, the next thing on the command line must be // the archive name. getArchive(); // Everything on the command line at this point is a member. getMembers(); if (NumOperations == 0 && MaybeJustCreateSymTab) { NumOperations = 1; Operation = CreateSymTab; if (!Members.empty()) show_help("The s operation takes only an archive as argument"); } // Perform various checks on the operation/modifier specification // to make sure we are dealing with a legal request. if (NumOperations == 0) show_help("You must specify at least one of the operations"); if (NumOperations > 1) show_help("Only one operation may be specified"); if (NumPositional > 1) show_help("You may only specify one of a, b, and i modifiers"); if (AddAfter || AddBefore) { if (Operation != Move && Operation != ReplaceOrInsert) show_help("The 'a', 'b' and 'i' modifiers can only be specified with " "the 'm' or 'r' operations"); } if (OriginalDates && Operation != Extract) show_help("The 'o' modifier is only applicable to the 'x' operation"); if (OnlyUpdate && Operation != ReplaceOrInsert) show_help("The 'u' modifier is only applicable to the 'r' operation"); // Return the parsed operation to the caller return Operation; }
// This function handles the high level operations of GNU objcopy including // handling command line options. It's important to outline certain properties // we expect to hold of the command line operations. Any operation that "keeps" // should keep regardless of a remove. Additionally any removal should respect // any previous removals. Lastly whether or not something is removed shouldn't // depend a) on the order the options occur in or b) on some opaque priority // system. The only priority is that keeps/copies overrule removes. void HandleArgs(Object &Obj, const Reader &Reader) { if (!SplitDWO.empty()) { SplitDWOToFile(Reader, SplitDWO); } // Localize: if (LocalizeHidden) { Obj.SymbolTable->localize([](const Symbol &Sym) { return Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL; }); } SectionPred RemovePred = [](const SectionBase &) { return false; }; // Removes: if (!ToRemove.empty()) { RemovePred = [&](const SectionBase &Sec) { return std::find(std::begin(ToRemove), std::end(ToRemove), Sec.Name) != std::end(ToRemove); }; } if (StripDWO || !SplitDWO.empty()) RemovePred = [RemovePred](const SectionBase &Sec) { return IsDWOSection(Sec) || RemovePred(Sec); }; if (ExtractDWO) RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { return OnlyKeepDWOPred(Obj, Sec) || RemovePred(Sec); }; if (StripAllGNU) RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { if (RemovePred(Sec)) return true; if ((Sec.Flags & SHF_ALLOC) != 0) return false; if (&Sec == Obj.SectionNames) return false; switch (Sec.Type) { case SHT_SYMTAB: case SHT_REL: case SHT_RELA: case SHT_STRTAB: return true; } return Sec.Name.startswith(".debug"); }; if (StripSections) { RemovePred = [RemovePred](const SectionBase &Sec) { return RemovePred(Sec) || (Sec.Flags & SHF_ALLOC) == 0; }; } if (StripDebug) { RemovePred = [RemovePred](const SectionBase &Sec) { return RemovePred(Sec) || Sec.Name.startswith(".debug"); }; } if (StripNonAlloc) RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { if (RemovePred(Sec)) return true; if (&Sec == Obj.SectionNames) return false; return (Sec.Flags & SHF_ALLOC) == 0; }; if (StripAll) RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { if (RemovePred(Sec)) return true; if (&Sec == Obj.SectionNames) return false; if (Sec.Name.startswith(".gnu.warning")) return false; return (Sec.Flags & SHF_ALLOC) == 0; }; // Explicit copies: if (!OnlyKeep.empty()) { RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { // Explicitly keep these sections regardless of previous removes. if (std::find(std::begin(OnlyKeep), std::end(OnlyKeep), Sec.Name) != std::end(OnlyKeep)) return false; // Allow all implicit removes. if (RemovePred(Sec)) return true; // Keep special sections. if (Obj.SectionNames == &Sec) return false; if (Obj.SymbolTable == &Sec || Obj.SymbolTable->getStrTab() == &Sec) return false; // Remove everything else. return true; }; } if (!Keep.empty()) { RemovePred = [RemovePred](const SectionBase &Sec) { // Explicitly keep these sections regardless of previous removes. if (std::find(std::begin(Keep), std::end(Keep), Sec.Name) != std::end(Keep)) return false; // Otherwise defer to RemovePred. return RemovePred(Sec); }; } Obj.removeSections(RemovePred); if (!AddSection.empty()) { for (const auto &Flag : AddSection) { auto SecPair = StringRef(Flag).split("="); auto SecName = SecPair.first; auto File = SecPair.second; auto BufOrErr = MemoryBuffer::getFile(File); if (!BufOrErr) reportError(File, BufOrErr.getError()); auto Buf = std::move(*BufOrErr); auto BufPtr = reinterpret_cast<const uint8_t *>(Buf->getBufferStart()); auto BufSize = Buf->getBufferSize(); Obj.addSection<OwnedDataSection>(SecName, ArrayRef<uint8_t>(BufPtr, BufSize)); } } if (!AddGnuDebugLink.empty()) { Obj.addSection<GnuDebugLinkSection>(StringRef(AddGnuDebugLink)); } }
bool PatmosSinglePathInfo::isEnabled() { return !SPRootList.empty(); }