return !BF.isIgnored();
}
-void RewriteInstance::discoverStorage() {
+Error RewriteInstance::discoverStorage() {
NamedRegionTimer T("discoverStorage", "discover storage", TimerGroupName,
TimerGroupDesc, opts::TimeRewrite);
NextAvailableAddress = 0;
uint64_t NextAvailableOffset = 0;
- ELF64LE::PhdrRange PHs =
- cantFail(Obj.program_headers(), "program_headers() failed");
+ Expected<ELF64LE::PhdrRange> PHsOrErr = Obj.program_headers();
+ if (Error E = PHsOrErr.takeError())
+ return E;
+
+ ELF64LE::PhdrRange PHs = PHsOrErr.get();
for (const ELF64LE::Phdr &Phdr : PHs) {
switch (Phdr.p_type) {
case ELF::PT_LOAD:
}
for (const SectionRef &Section : InputFile->sections()) {
- StringRef SectionName = cantFail(Section.getName());
+ Expected<StringRef> SectionNameOrErr = Section.getName();
+ if (Error E = SectionNameOrErr.takeError())
+ return E;
+ StringRef SectionName = SectionNameOrErr.get();
if (SectionName == ".text") {
BC->OldTextSectionAddress = Section.getAddress();
BC->OldTextSectionSize = Section.getSize();
- StringRef SectionContents = cantFail(Section.getContents());
+ Expected<StringRef> SectionContentsOrErr = Section.getContents();
+ if (Error E = SectionContentsOrErr.takeError())
+ return E;
+ StringRef SectionContents = SectionContentsOrErr.get();
BC->OldTextSectionOffset =
SectionContents.data() - InputFile->getData().data();
}
if (!opts::HeatmapMode &&
!(opts::AggregateOnly && BAT->enabledFor(InputFile)) &&
(SectionName.startswith(getOrgSecPrefix()) ||
- SectionName == getBOLTTextSectionName())) {
- errs() << "BOLT-ERROR: input file was processed by BOLT. "
- "Cannot re-optimize.\n";
- exit(1);
- }
+ SectionName == getBOLTTextSectionName()))
+ return createStringError(
+ errc::function_not_supported,
+ "BOLT-ERROR: input file was processed by BOLT. Cannot re-optimize");
}
- assert(NextAvailableAddress && NextAvailableOffset &&
- "no PT_LOAD pheader seen");
+ if (!NextAvailableAddress || !NextAvailableOffset)
+ return createStringError(errc::executable_format_error,
+ "no PT_LOAD pheader seen");
outs() << "BOLT-INFO: first alloc address is 0x"
<< Twine::utohexstr(BC->FirstAllocAddress) << '\n';
// Tools such as objcopy can strip section contents but leave header
// entries. Check that at least .text is mapped in the file.
- if (!getFileOffsetForAddress(BC->OldTextSectionAddress)) {
- errs() << "BOLT-ERROR: input binary is not a valid ELF executable as its "
- "text section is not mapped to a valid segment\n";
- exit(1);
- }
+ if (!getFileOffsetForAddress(BC->OldTextSectionAddress))
+ return createStringError(errc::executable_format_error,
+ "BOLT-ERROR: input binary is not a valid ELF "
+ "executable as its text section is not "
+ "mapped to a valid segment");
+ return Error::success();
}
void RewriteInstance::parseSDTNotes() {
outs() << "BOLT-INFO: patched build-id (flipped last bit)\n";
}
-void RewriteInstance::run() {
- if (!BC) {
- errs() << "BOLT-ERROR: failed to create a binary context\n";
- return;
- }
+Error RewriteInstance::run() {
+ assert(BC && "failed to create a binary context");
outs() << "BOLT-INFO: Target architecture: "
<< Triple::getArchTypeName(
<< "\n";
outs() << "BOLT-INFO: BOLT version: " << BoltRevision << "\n";
- discoverStorage();
+ if (Error E = discoverStorage())
+ return E;
readSpecialSections();
adjustCommandLineOptions();
discoverFileObjects();
// aggregation job.
if (opts::AggregateOnly && BAT->enabledFor(InputFile)) {
processProfileData();
- return;
+ return Error::success();
}
selectFunctionsToProcess();
postProcessFunctions();
if (opts::DiffOnly)
- return;
+ return Error::success();
runOptimizationPasses();
if (opts::LinuxKernelMode) {
errs() << "BOLT-WARNING: not writing the output file for Linux Kernel\n";
- return;
+ return Error::success();
} else if (opts::OutputFilename == "/dev/null") {
outs() << "BOLT-INFO: skipping writing final binary to disk\n";
- return;
+ return Error::success();
}
// Rewrite allocatable contents and copy non-allocatable parts with mods.
rewriteFile();
+ return Error::success();
}
void RewriteInstance::discoverFileObjects() {