1 #include "bolt/Profile/DataAggregator.h" 2 #include "bolt/Rewrite/RewriteInstance.h" 3 #include "bolt/Utils/CommandLineOpts.h" 4 #include "llvm/MC/TargetRegistry.h" 5 #include "llvm/Object/Binary.h" 6 #include "llvm/Support/CommandLine.h" 7 #include "llvm/Support/Errc.h" 8 #include "llvm/Support/Error.h" 9 #include "llvm/Support/Path.h" 10 #include "llvm/Support/TargetSelect.h" 11 12 using namespace llvm; 13 using namespace bolt; 14 15 namespace opts { 16 17 static cl::OptionCategory *HeatmapCategories[] = {&HeatmapCategory, 18 &BoltOutputCategory}; 19 20 static cl::opt<std::string> InputFilename(cl::Positional, 21 cl::desc("<executable>"), 22 cl::Required, 23 cl::cat(HeatmapCategory)); 24 25 } // namespace opts 26 27 static StringRef ToolName; 28 29 static void report_error(StringRef Message, std::error_code EC) { 30 assert(EC); 31 errs() << ToolName << ": '" << Message << "': " << EC.message() << ".\n"; 32 exit(1); 33 } 34 35 static void report_error(StringRef Message, Error E) { 36 assert(E); 37 errs() << ToolName << ": '" << Message << "': " << toString(std::move(E)) 38 << ".\n"; 39 exit(1); 40 } 41 42 static std::string GetExecutablePath(const char *Argv0) { 43 SmallString<256> ExecutablePath(Argv0); 44 // Do a PATH lookup if Argv0 isn't a valid path. 45 if (!llvm::sys::fs::exists(ExecutablePath)) 46 if (llvm::ErrorOr<std::string> P = 47 llvm::sys::findProgramByName(ExecutablePath)) 48 ExecutablePath = *P; 49 return std::string(ExecutablePath.str()); 50 } 51 52 int main(int argc, char **argv) { 53 cl::HideUnrelatedOptions(makeArrayRef(opts::HeatmapCategories)); 54 cl::ParseCommandLineOptions(argc, argv, ""); 55 56 if (opts::PerfData.empty()) { 57 errs() << ToolName << ": expected -perfdata=<filename> option.\n"; 58 exit(1); 59 } 60 61 opts::HeatmapMode = true; 62 opts::AggregateOnly = true; 63 if (!sys::fs::exists(opts::InputFilename)) 64 report_error(opts::InputFilename, errc::no_such_file_or_directory); 65 66 // Output to stdout by default 67 if (opts::OutputFilename.empty()) 68 opts::OutputFilename = "-"; 69 70 // Initialize targets and assembly printers/parsers. 71 llvm::InitializeAllTargetInfos(); 72 llvm::InitializeAllTargetMCs(); 73 llvm::InitializeAllAsmParsers(); 74 llvm::InitializeAllDisassemblers(); 75 76 llvm::InitializeAllTargets(); 77 llvm::InitializeAllAsmPrinters(); 78 79 ToolName = argv[0]; 80 std::string ToolPath = GetExecutablePath(argv[0]); 81 Expected<OwningBinary<Binary>> BinaryOrErr = 82 createBinary(opts::InputFilename); 83 if (Error E = BinaryOrErr.takeError()) 84 report_error(opts::InputFilename, std::move(E)); 85 Binary &Binary = *BinaryOrErr.get().getBinary(); 86 87 if (auto *e = dyn_cast<ELFObjectFileBase>(&Binary)) { 88 auto RIOrErr = 89 RewriteInstance::createRewriteInstance(e, argc, argv, ToolPath); 90 if (Error E = RIOrErr.takeError()) 91 report_error("RewriteInstance", std::move(E)); 92 93 RewriteInstance &RI = *RIOrErr.get(); 94 if (Error E = RI.setProfile(opts::PerfData)) 95 report_error(opts::PerfData, std::move(E)); 96 97 if (Error E = RI.run()) 98 report_error(opts::InputFilename, std::move(E)); 99 } else { 100 report_error(opts::InputFilename, object_error::invalid_file_type); 101 } 102 103 return EXIT_SUCCESS; 104 } 105