summaryrefslogtreecommitdiff
path: root/bolt/lib/Rewrite/RewriteInstance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'bolt/lib/Rewrite/RewriteInstance.cpp')
-rw-r--r--bolt/lib/Rewrite/RewriteInstance.cpp571
1 files changed, 319 insertions, 252 deletions
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 9a242d94dd77..db093bfc2d8b 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -309,9 +309,11 @@ bool refersToReorderedSection(ErrorOr<BinarySection &> Section) {
Expected<std::unique_ptr<RewriteInstance>>
RewriteInstance::create(ELFObjectFileBase *File, const int Argc,
- const char *const *Argv, StringRef ToolPath) {
+ const char *const *Argv, StringRef ToolPath,
+ raw_ostream &Stdout, raw_ostream &Stderr) {
Error Err = Error::success();
- auto RI = std::make_unique<RewriteInstance>(File, Argc, Argv, ToolPath, Err);
+ auto RI = std::make_unique<RewriteInstance>(File, Argc, Argv, ToolPath,
+ Stdout, Stderr, Err);
if (Err)
return std::move(Err);
return std::move(RI);
@@ -319,6 +321,7 @@ RewriteInstance::create(ELFObjectFileBase *File, const int Argc,
RewriteInstance::RewriteInstance(ELFObjectFileBase *File, const int Argc,
const char *const *Argv, StringRef ToolPath,
+ raw_ostream &Stdout, raw_ostream &Stderr,
Error &Err)
: InputFile(File), Argc(Argc), Argv(Argv), ToolPath(ToolPath),
SHStrTab(StringTableBuilder::ELF) {
@@ -333,17 +336,23 @@ RewriteInstance::RewriteInstance(ELFObjectFileBase *File, const int Argc,
bool IsPIC = false;
const ELFFile<ELF64LE> &Obj = ELF64LEFile->getELFFile();
if (Obj.getHeader().e_type != ELF::ET_EXEC) {
- outs() << "BOLT-INFO: shared object or position-independent executable "
+ Stdout << "BOLT-INFO: shared object or position-independent executable "
"detected\n";
IsPIC = true;
}
+ // Make sure we don't miss any output on core dumps.
+ Stdout.SetUnbuffered();
+ Stderr.SetUnbuffered();
+ LLVM_DEBUG(dbgs().SetUnbuffered());
+
auto BCOrErr = BinaryContext::createBinaryContext(
File, IsPIC,
DWARFContext::create(*File, DWARFContext::ProcessDebugRelocations::Ignore,
nullptr, opts::DWPPathName,
WithColor::defaultErrorHandler,
- WithColor::defaultWarningHandler));
+ WithColor::defaultWarningHandler),
+ JournalingStreams{Stdout, Stderr});
if (Error E = BCOrErr.takeError()) {
Err = std::move(E);
return;
@@ -457,22 +466,23 @@ void RewriteInstance::markGnuRelroSections() {
bool VMAContains = checkVMA<ELFT>(Phdr, *Sec, VMAOverlap);
if (ImageOverlap) {
if (opts::Verbosity >= 1)
- errs() << "BOLT-WARNING: GNU_RELRO segment has partial file offset "
- << "overlap with section " << BinarySection->getName() << '\n';
+ BC->errs() << "BOLT-WARNING: GNU_RELRO segment has partial file offset "
+ << "overlap with section " << BinarySection->getName()
+ << '\n';
return;
}
if (VMAOverlap) {
if (opts::Verbosity >= 1)
- errs() << "BOLT-WARNING: GNU_RELRO segment has partial VMA overlap "
- << "with section " << BinarySection->getName() << '\n';
+ BC->errs() << "BOLT-WARNING: GNU_RELRO segment has partial VMA overlap "
+ << "with section " << BinarySection->getName() << '\n';
return;
}
if (!ImageContains || !VMAContains)
return;
BinarySection->setRelro();
if (opts::Verbosity >= 1)
- outs() << "BOLT-INFO: marking " << BinarySection->getName()
- << " as GNU_RELRO\n";
+ BC->outs() << "BOLT-INFO: marking " << BinarySection->getName()
+ << " as GNU_RELRO\n";
};
for (const ELFT::Phdr &Phdr : cantFail(Obj.program_headers()))
@@ -523,7 +533,7 @@ Error RewriteInstance::discoverStorage() {
}
if (BC->IsLinuxKernel)
- outs() << "BOLT-INFO: Linux kernel binary detected\n";
+ BC->outs() << "BOLT-INFO: Linux kernel binary detected\n";
for (const SectionRef &Section : InputFile->sections()) {
Expected<StringRef> SectionNameOrErr = Section.getName();
@@ -555,8 +565,8 @@ Error RewriteInstance::discoverStorage() {
return createStringError(errc::executable_format_error,
"no PT_LOAD pheader seen");
- outs() << "BOLT-INFO: first alloc address is 0x"
- << Twine::utohexstr(BC->FirstAllocAddress) << '\n';
+ BC->outs() << "BOLT-INFO: first alloc address is 0x"
+ << Twine::utohexstr(BC->FirstAllocAddress) << '\n';
FirstNonAllocatableOffset = NextAvailableOffset;
@@ -588,9 +598,9 @@ Error RewriteInstance::discoverStorage() {
NextAvailableAddress - BC->FirstAllocAddress &&
"PHDR table address calculation error");
- outs() << "BOLT-INFO: creating new program header table at address 0x"
- << Twine::utohexstr(NextAvailableAddress) << ", offset 0x"
- << Twine::utohexstr(NextAvailableOffset) << '\n';
+ BC->outs() << "BOLT-INFO: creating new program header table at address 0x"
+ << Twine::utohexstr(NextAvailableAddress) << ", offset 0x"
+ << Twine::utohexstr(NextAvailableOffset) << '\n';
PHDRTableAddress = NextAvailableAddress;
PHDRTableOffset = NextAvailableOffset;
@@ -685,7 +695,8 @@ void RewriteInstance::patchBuildID() {
uint64_t FileOffset = getFileOffsetForAddress(BuildIDSection->getAddress());
if (!FileOffset) {
- errs() << "BOLT-WARNING: Non-allocatable build-id will not be updated.\n";
+ BC->errs()
+ << "BOLT-WARNING: Non-allocatable build-id will not be updated.\n";
return;
}
@@ -693,17 +704,17 @@ void RewriteInstance::patchBuildID() {
LastIDByte ^= 1;
OS.pwrite(&LastIDByte, 1, FileOffset + IDOffset + BuildID.size() - 1);
- outs() << "BOLT-INFO: patched build-id (flipped last bit)\n";
+ BC->outs() << "BOLT-INFO: patched build-id (flipped last bit)\n";
}
Error RewriteInstance::run() {
assert(BC && "failed to create a binary context");
- outs() << "BOLT-INFO: Target architecture: "
- << Triple::getArchTypeName(
- (llvm::Triple::ArchType)InputFile->getArch())
- << "\n";
- outs() << "BOLT-INFO: BOLT version: " << BoltRevision << "\n";
+ BC->outs() << "BOLT-INFO: Target architecture: "
+ << Triple::getArchTypeName(
+ (llvm::Triple::ArchType)InputFile->getArch())
+ << "\n";
+ BC->outs() << "BOLT-INFO: BOLT version: " << BoltRevision << "\n";
if (Error E = discoverStorage())
return E;
@@ -758,10 +769,10 @@ Error RewriteInstance::run() {
updateRtFiniReloc();
if (opts::OutputFilename == "/dev/null") {
- outs() << "BOLT-INFO: skipping writing final binary to disk\n";
+ BC->outs() << "BOLT-INFO: skipping writing final binary to disk\n";
return Error::success();
} else if (BC->IsLinuxKernel) {
- errs() << "BOLT-WARNING: Linux kernel support is experimental\n";
+ BC->errs() << "BOLT-WARNING: Linux kernel support is experimental\n";
}
// Rewrite allocatable contents and copy non-allocatable parts with mods.
@@ -786,13 +797,15 @@ void RewriteInstance::discoverFileObjects() {
for (const ELFSymbolRef &Symbol : InputFile->symbols()) {
Expected<StringRef> NameOrError = Symbol.getName();
if (NameOrError && NameOrError->starts_with("__asan_init")) {
- errs() << "BOLT-ERROR: input file was compiled or linked with sanitizer "
- "support. Cannot optimize.\n";
+ BC->errs()
+ << "BOLT-ERROR: input file was compiled or linked with sanitizer "
+ "support. Cannot optimize.\n";
exit(1);
}
if (NameOrError && NameOrError->starts_with("__llvm_coverage_mapping")) {
- errs() << "BOLT-ERROR: input file was compiled or linked with coverage "
- "support. Cannot optimize.\n";
+ BC->errs()
+ << "BOLT-ERROR: input file was compiled or linked with coverage "
+ "support. Cannot optimize.\n";
exit(1);
}
@@ -924,7 +937,7 @@ void RewriteInstance::discoverFileObjects() {
StringRef SymName = cantFail(Symbol.getName(), "cannot get symbol name");
if (SymbolAddress == 0) {
if (opts::Verbosity >= 1 && SymbolType == SymbolRef::ST_Function)
- errs() << "BOLT-WARNING: function with 0 address seen\n";
+ BC->errs() << "BOLT-WARNING: function with 0 address seen\n";
continue;
}
@@ -965,13 +978,13 @@ void RewriteInstance::discoverFileObjects() {
if (BD->getSize() == ELFSymbolRef(Symbol).getSize() &&
BD->getAddress() == SymbolAddress) {
if (opts::Verbosity > 1)
- errs() << "BOLT-WARNING: ignoring duplicate global symbol " << Name
- << "\n";
+ BC->errs() << "BOLT-WARNING: ignoring duplicate global symbol "
+ << Name << "\n";
// Ignore duplicate entry - possibly a bug in the linker
continue;
}
- errs() << "BOLT-ERROR: bad input binary, global symbol \"" << Name
- << "\" is not unique\n";
+ BC->errs() << "BOLT-ERROR: bad input binary, global symbol \"" << Name
+ << "\" is not unique\n";
exit(1);
}
UniqueName = Name;
@@ -1059,9 +1072,9 @@ void RewriteInstance::discoverFileObjects() {
!SymbolSize) {
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: ignoring symbol as a marker\n");
} else if (opts::Verbosity > 1) {
- errs() << "BOLT-WARNING: symbol " << UniqueName
- << " seen in the middle of function " << *PreviousFunction
- << ". Could be a new entry.\n";
+ BC->errs() << "BOLT-WARNING: symbol " << UniqueName
+ << " seen in the middle of function " << *PreviousFunction
+ << ". Could be a new entry.\n";
}
registerName(SymbolSize);
continue;
@@ -1077,12 +1090,14 @@ void RewriteInstance::discoverFileObjects() {
PreviousFunction->getAddress() != SymbolAddress) {
if (PreviousFunction->isSymbolValidInScope(Symbol, SymbolSize)) {
if (opts::Verbosity >= 1)
- outs() << "BOLT-INFO: skipping possibly another entry for function "
- << *PreviousFunction << " : " << UniqueName << '\n';
+ BC->outs()
+ << "BOLT-INFO: skipping possibly another entry for function "
+ << *PreviousFunction << " : " << UniqueName << '\n';
registerName(SymbolSize);
} else {
- outs() << "BOLT-INFO: using " << UniqueName << " as another entry to "
- << "function " << *PreviousFunction << '\n';
+ BC->outs() << "BOLT-INFO: using " << UniqueName
+ << " as another entry to "
+ << "function " << *PreviousFunction << '\n';
registerName(0);
@@ -1114,20 +1129,21 @@ void RewriteInstance::discoverFileObjects() {
uint64_t PrevLength = PrevFDE.getAddressRange();
if (SymbolAddress > PrevStart &&
SymbolAddress < PrevStart + PrevLength) {
- errs() << "BOLT-ERROR: function " << UniqueName
- << " is in conflict with FDE ["
- << Twine::utohexstr(PrevStart) << ", "
- << Twine::utohexstr(PrevStart + PrevLength)
- << "). Skipping.\n";
+ BC->errs() << "BOLT-ERROR: function " << UniqueName
+ << " is in conflict with FDE ["
+ << Twine::utohexstr(PrevStart) << ", "
+ << Twine::utohexstr(PrevStart + PrevLength)
+ << "). Skipping.\n";
IsSimple = false;
}
}
} else if (FDE.getAddressRange() != SymbolSize) {
if (SymbolSize) {
// Function addresses match but sizes differ.
- errs() << "BOLT-WARNING: sizes differ for function " << UniqueName
- << ". FDE : " << FDE.getAddressRange()
- << "; symbol table : " << SymbolSize << ". Using max size.\n";
+ BC->errs() << "BOLT-WARNING: sizes differ for function " << UniqueName
+ << ". FDE : " << FDE.getAddressRange()
+ << "; symbol table : " << SymbolSize
+ << ". Using max size.\n";
}
SymbolSize = std::max(SymbolSize, FDE.getAddressRange());
if (BC->getBinaryDataAtAddress(SymbolAddress)) {
@@ -1151,10 +1167,11 @@ void RewriteInstance::discoverFileObjects() {
if (SymbolSize != BF->getSize()) {
if (opts::Verbosity >= 1) {
if (SymbolSize && BF->getSize())
- errs() << "BOLT-WARNING: size mismatch for duplicate entries "
- << *BF << " and " << UniqueName << '\n';
- outs() << "BOLT-INFO: adjusting size of function " << *BF << " old "
- << BF->getSize() << " new " << SymbolSize << "\n";
+ BC->errs() << "BOLT-WARNING: size mismatch for duplicate entries "
+ << *BF << " and " << UniqueName << '\n';
+ BC->outs() << "BOLT-INFO: adjusting size of function " << *BF
+ << " old " << BF->getSize() << " new " << SymbolSize
+ << "\n";
}
BF->setSize(std::max(SymbolSize, BF->getSize()));
BC->setBinaryDataSize(SymbolAddress, BF->getSize());
@@ -1165,9 +1182,9 @@ void RewriteInstance::discoverFileObjects() {
BC->getSectionForAddress(SymbolAddress);
// Skip symbols from invalid sections
if (!Section) {
- errs() << "BOLT-WARNING: " << UniqueName << " (0x"
- << Twine::utohexstr(SymbolAddress)
- << ") does not have any section\n";
+ BC->errs() << "BOLT-WARNING: " << UniqueName << " (0x"
+ << Twine::utohexstr(SymbolAddress)
+ << ") does not have any section\n";
continue;
}
@@ -1186,12 +1203,12 @@ void RewriteInstance::discoverFileObjects() {
static bool PrintedWarning = false;
if (!PrintedWarning) {
PrintedWarning = true;
- errs() << "BOLT-WARNING: split function detected on input : "
- << SymName;
+ BC->errs() << "BOLT-WARNING: split function detected on input : "
+ << SymName;
if (BC->HasRelocations)
- errs() << ". The support is limited in relocation mode\n";
+ BC->errs() << ". The support is limited in relocation mode\n";
else
- errs() << '\n';
+ BC->errs() << '\n';
}
BC->HasSplitFunctions = true;
BF->IsFragment = true;
@@ -1222,16 +1239,16 @@ void RewriteInstance::discoverFileObjects() {
BF = BC->getBinaryFunctionContainingAddress(Address);
if (BF) {
- errs() << "BOLT-WARNING: FDE [0x" << Twine::utohexstr(Address) << ", 0x"
- << Twine::utohexstr(Address + FDE->getAddressRange())
- << ") conflicts with function " << *BF << '\n';
+ BC->errs() << "BOLT-WARNING: FDE [0x" << Twine::utohexstr(Address)
+ << ", 0x" << Twine::utohexstr(Address + FDE->getAddressRange())
+ << ") conflicts with function " << *BF << '\n';
continue;
}
if (opts::Verbosity >= 1)
- errs() << "BOLT-WARNING: FDE [0x" << Twine::utohexstr(Address) << ", 0x"
- << Twine::utohexstr(Address + FDE->getAddressRange())
- << ") has no corresponding symbol table entry\n";
+ BC->errs() << "BOLT-WARNING: FDE [0x" << Twine::utohexstr(Address)
+ << ", 0x" << Twine::utohexstr(Address + FDE->getAddressRange())
+ << ") has no corresponding symbol table entry\n";
ErrorOr<BinarySection &> Section = BC->getSectionForAddress(Address);
assert(Section && "cannot get section for address from FDE");
@@ -1283,7 +1300,8 @@ void RewriteInstance::discoverFileObjects() {
/*UseMaxSize*/ true);
if (BF) {
assert(Rel.isRelative() && "Expected relative relocation for island");
- BF->markIslandDynamicRelocationAtAddress(RelAddress);
+ BC->logBOLTErrorsAndQuitOnFatal(
+ BF->markIslandDynamicRelocationAtAddress(RelAddress));
}
}
}
@@ -1395,23 +1413,24 @@ void RewriteInstance::registerFragments() {
}
if (!BD) {
if (opts::Verbosity >= 1)
- outs() << "BOLT-INFO: parent function not found for " << Name << "\n";
+ BC->outs() << "BOLT-INFO: parent function not found for " << Name
+ << "\n";
continue;
}
const uint64_t Address = BD->getAddress();
BinaryFunction *BF = BC->getBinaryFunctionAtAddress(Address);
if (!BF) {
if (opts::Verbosity >= 1)
- outs() << formatv("BOLT-INFO: parent function not found at {0:x}\n",
- Address);
+ BC->outs() << formatv(
+ "BOLT-INFO: parent function not found at {0:x}\n", Address);
continue;
}
BC->registerFragment(Function, *BF);
++ParentsFound;
}
if (!ParentsFound) {
- errs() << "BOLT-ERROR: parent function not found for " << Function
- << '\n';
+ BC->errs() << "BOLT-ERROR: parent function not found for " << Function
+ << '\n';
exit(1);
}
}
@@ -1449,7 +1468,7 @@ void RewriteInstance::createPLTBinaryFunction(uint64_t TargetAddress,
// IFUNC trampoline without symbol
BinaryFunction *TargetBF = BC->getBinaryFunctionAtAddress(Rel->Addend);
if (!TargetBF) {
- errs()
+ BC->errs()
<< "BOLT-WARNING: Expected BF to be presented as IFUNC resolver at "
<< Twine::utohexstr(Rel->Addend) << ", skipping\n";
return;
@@ -1483,8 +1502,9 @@ void RewriteInstance::disassemblePLTInstruction(const BinarySection &Section,
if (!BC->DisAsm->getInstruction(Instruction, InstrSize,
PLTData.slice(InstrOffset), InstrAddr,
nulls())) {
- errs() << "BOLT-ERROR: unable to disassemble instruction in PLT section "
- << Section.getName() << formatv(" at offset {0:x}\n", InstrOffset);
+ BC->errs()
+ << "BOLT-ERROR: unable to disassemble instruction in PLT section "
+ << Section.getName() << formatv(" at offset {0:x}\n", InstrOffset);
exit(1);
}
}
@@ -1546,9 +1566,10 @@ void RewriteInstance::disassemblePLTSectionRISCV(BinarySection &Section) {
if (!BC->DisAsm->getInstruction(Instruction, InstrSize,
PLTData.slice(InstrOffset), InstrAddr,
nulls())) {
- errs() << "BOLT-ERROR: unable to disassemble instruction in PLT section "
- << Section.getName() << " at offset 0x"
- << Twine::utohexstr(InstrOffset) << '\n';
+ BC->errs()
+ << "BOLT-ERROR: unable to disassemble instruction in PLT section "
+ << Section.getName() << " at offset 0x"
+ << Twine::utohexstr(InstrOffset) << '\n';
exit(1);
}
};
@@ -1606,8 +1627,8 @@ void RewriteInstance::disassemblePLTSectionX86(BinarySection &Section,
if (!BC->MIB->evaluateMemOperandTarget(Instruction, TargetAddress,
SectionAddress + InstrOffset,
InstrSize)) {
- errs() << "BOLT-ERROR: error evaluating PLT instruction at offset 0x"
- << Twine::utohexstr(SectionAddress + InstrOffset) << '\n';
+ BC->errs() << "BOLT-ERROR: error evaluating PLT instruction at offset 0x"
+ << Twine::utohexstr(SectionAddress + InstrOffset) << '\n';
exit(1);
}
@@ -1714,8 +1735,8 @@ void RewriteInstance::adjustFunctionBoundaries() {
const uint64_t MaxSize = NextObjectAddress - Function.getAddress();
if (MaxSize < Function.getSize()) {
- errs() << "BOLT-ERROR: symbol seen in the middle of the function "
- << Function << ". Skipping.\n";
+ BC->errs() << "BOLT-ERROR: symbol seen in the middle of the function "
+ << Function << ". Skipping.\n";
Function.setSimple(false);
Function.setMaxSize(Function.getSize());
continue;
@@ -1725,8 +1746,8 @@ void RewriteInstance::adjustFunctionBoundaries() {
// Some assembly functions have their size set to 0, use the max
// size as their real size.
if (opts::Verbosity >= 1)
- outs() << "BOLT-INFO: setting size of function " << Function << " to "
- << Function.getMaxSize() << " (was 0)\n";
+ BC->outs() << "BOLT-INFO: setting size of function " << Function
+ << " to " << Function.getMaxSize() << " (was 0)\n";
Function.setSize(Function.getMaxSize());
}
}
@@ -1812,8 +1833,8 @@ Error RewriteInstance::readSpecialSections() {
markGnuRelroSections();
if (HasDebugInfo && !opts::UpdateDebugSections && !opts::AggregateOnly) {
- errs() << "BOLT-WARNING: debug info will be stripped from the binary. "
- "Use -update-debug-sections to keep it.\n";
+ BC->errs() << "BOLT-WARNING: debug info will be stripped from the binary. "
+ "Use -update-debug-sections to keep it.\n";
}
HasTextRelocations = (bool)BC->getUniqueSectionByName(".rela.text");
@@ -1825,22 +1846,23 @@ Error RewriteInstance::readSpecialSections() {
BC->getUniqueSectionByName(BoltAddressTranslation::SECTION_NAME)) {
// Do not read BAT when plotting a heatmap
if (!opts::HeatmapMode) {
- if (std::error_code EC = BAT->parse(BATSec->getContents())) {
- errs() << "BOLT-ERROR: failed to parse BOLT address translation "
- "table.\n";
+ if (std::error_code EC = BAT->parse(BC->outs(), BATSec->getContents())) {
+ BC->errs() << "BOLT-ERROR: failed to parse BOLT address translation "
+ "table.\n";
exit(1);
}
}
}
if (opts::PrintSections) {
- outs() << "BOLT-INFO: Sections from original binary:\n";
- BC->printSections(outs());
+ BC->outs() << "BOLT-INFO: Sections from original binary:\n";
+ BC->printSections(BC->outs());
}
if (opts::RelocationMode == cl::BOU_TRUE && !HasTextRelocations) {
- errs() << "BOLT-ERROR: relocations against code are missing from the input "
- "file. Cannot proceed in relocations mode (-relocs).\n";
+ BC->errs()
+ << "BOLT-ERROR: relocations against code are missing from the input "
+ "file. Cannot proceed in relocations mode (-relocs).\n";
exit(1);
}
@@ -1848,15 +1870,16 @@ Error RewriteInstance::readSpecialSections() {
HasTextRelocations && (opts::RelocationMode != cl::BOU_FALSE);
if (BC->IsLinuxKernel && BC->HasRelocations) {
- outs() << "BOLT-INFO: disabling relocation mode for Linux kernel\n";
+ BC->outs() << "BOLT-INFO: disabling relocation mode for Linux kernel\n";
BC->HasRelocations = false;
}
BC->IsStripped = !HasSymbolTable;
if (BC->IsStripped && !opts::AllowStripped) {
- errs() << "BOLT-ERROR: stripped binaries are not supported. If you know "
- "what you're doing, use --allow-stripped to proceed";
+ BC->errs()
+ << "BOLT-ERROR: stripped binaries are not supported. If you know "
+ "what you're doing, use --allow-stripped to proceed";
exit(1);
}
@@ -1865,14 +1888,14 @@ Error RewriteInstance::readSpecialSections() {
BC->HasRelocations = false;
if (BC->HasRelocations)
- outs() << "BOLT-INFO: enabling " << (opts::StrictMode ? "strict " : "")
- << "relocation mode\n";
+ BC->outs() << "BOLT-INFO: enabling " << (opts::StrictMode ? "strict " : "")
+ << "relocation mode\n";
// Read EH frame for function boundaries info.
Expected<const DWARFDebugFrame *> EHFrameOrError = BC->DwCtx->getEHFrame();
if (!EHFrameOrError)
report_error("expected valid eh_frame section", EHFrameOrError.takeError());
- CFIRdWrt.reset(new CFIReaderWriter(*EHFrameOrError.get()));
+ CFIRdWrt.reset(new CFIReaderWriter(*BC, *EHFrameOrError.get()));
// Parse build-id
parseBuildID();
@@ -1885,63 +1908,68 @@ Error RewriteInstance::readSpecialSections() {
void RewriteInstance::adjustCommandLineOptions() {
if (BC->isAArch64() && !BC->HasRelocations)
- errs() << "BOLT-WARNING: non-relocation mode for AArch64 is not fully "
- "supported\n";
+ BC->errs() << "BOLT-WARNING: non-relocation mode for AArch64 is not fully "
+ "supported\n";
if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary())
RtLibrary->adjustCommandLineOptions(*BC);
if (opts::AlignMacroOpFusion != MFT_NONE && !BC->isX86()) {
- outs() << "BOLT-INFO: disabling -align-macro-fusion on non-x86 platform\n";
+ BC->outs()
+ << "BOLT-INFO: disabling -align-macro-fusion on non-x86 platform\n";
opts::AlignMacroOpFusion = MFT_NONE;
}
if (BC->isX86() && BC->MAB->allowAutoPadding()) {
if (!BC->HasRelocations) {
- errs() << "BOLT-ERROR: cannot apply mitigations for Intel JCC erratum in "
- "non-relocation mode\n";
+ BC->errs()
+ << "BOLT-ERROR: cannot apply mitigations for Intel JCC erratum in "
+ "non-relocation mode\n";
exit(1);
}
- outs() << "BOLT-WARNING: using mitigation for Intel JCC erratum, layout "
- "may take several minutes\n";
+ BC->outs()
+ << "BOLT-WARNING: using mitigation for Intel JCC erratum, layout "
+ "may take several minutes\n";
opts::AlignMacroOpFusion = MFT_NONE;
}
if (opts::AlignMacroOpFusion != MFT_NONE && !BC->HasRelocations) {
- outs() << "BOLT-INFO: disabling -align-macro-fusion in non-relocation "
- "mode\n";
+ BC->outs() << "BOLT-INFO: disabling -align-macro-fusion in non-relocation "
+ "mode\n";
opts::AlignMacroOpFusion = MFT_NONE;
}
if (opts::SplitEH && !BC->HasRelocations) {
- errs() << "BOLT-WARNING: disabling -split-eh in non-relocation mode\n";
+ BC->errs() << "BOLT-WARNING: disabling -split-eh in non-relocation mode\n";
opts::SplitEH = false;
}
if (opts::StrictMode && !BC->HasRelocations) {
- errs() << "BOLT-WARNING: disabling strict mode (-strict) in non-relocation "
- "mode\n";
+ BC->errs()
+ << "BOLT-WARNING: disabling strict mode (-strict) in non-relocation "
+ "mode\n";
opts::StrictMode = false;
}
if (BC->HasRelocations && opts::AggregateOnly &&
!opts::StrictMode.getNumOccurrences()) {
- outs() << "BOLT-INFO: enabling strict relocation mode for aggregation "
- "purposes\n";
+ BC->outs() << "BOLT-INFO: enabling strict relocation mode for aggregation "
+ "purposes\n";
opts::StrictMode = true;
}
if (BC->isX86() && BC->HasRelocations &&
opts::AlignMacroOpFusion == MFT_HOT && !ProfileReader) {
- outs() << "BOLT-INFO: enabling -align-macro-fusion=all since no profile "
- "was specified\n";
+ BC->outs()
+ << "BOLT-INFO: enabling -align-macro-fusion=all since no profile "
+ "was specified\n";
opts::AlignMacroOpFusion = MFT_ALL;
}
if (!BC->HasRelocations &&
opts::ReorderFunctions != ReorderFunctions::RT_NONE) {
- errs() << "BOLT-ERROR: function reordering only works when "
- << "relocations are enabled\n";
+ BC->errs() << "BOLT-ERROR: function reordering only works when "
+ << "relocations are enabled\n";
exit(1);
}
@@ -1950,7 +1978,7 @@ void RewriteInstance::adjustCommandLineOptions() {
!opts::HotText.getNumOccurrences())) {
opts::HotText = true;
} else if (opts::HotText && !BC->HasRelocations) {
- errs() << "BOLT-WARNING: hot text is disabled in non-relocation mode\n";
+ BC->errs() << "BOLT-WARNING: hot text is disabled in non-relocation mode\n";
opts::HotText = false;
}
@@ -1961,12 +1989,13 @@ void RewriteInstance::adjustCommandLineOptions() {
}
if (opts::UseOldText && !BC->OldTextSectionAddress) {
- errs() << "BOLT-WARNING: cannot use old .text as the section was not found"
- "\n";
+ BC->errs()
+ << "BOLT-WARNING: cannot use old .text as the section was not found"
+ "\n";
opts::UseOldText = false;
}
if (opts::UseOldText && !BC->HasRelocations) {
- errs() << "BOLT-WARNING: cannot use old .text in non-relocation mode\n";
+ BC->errs() << "BOLT-WARNING: cannot use old .text in non-relocation mode\n";
opts::UseOldText = false;
}
@@ -1981,23 +2010,25 @@ void RewriteInstance::adjustCommandLineOptions() {
opts::Lite = true;
if (opts::Lite && opts::UseOldText) {
- errs() << "BOLT-WARNING: cannot combine -lite with -use-old-text. "
- "Disabling -use-old-text.\n";
+ BC->errs() << "BOLT-WARNING: cannot combine -lite with -use-old-text. "
+ "Disabling -use-old-text.\n";
opts::UseOldText = false;
}
if (opts::Lite && opts::StrictMode) {
- errs() << "BOLT-ERROR: -strict and -lite cannot be used at the same time\n";
+ BC->errs()
+ << "BOLT-ERROR: -strict and -lite cannot be used at the same time\n";
exit(1);
}
if (opts::Lite)
- outs() << "BOLT-INFO: enabling lite mode\n";
+ BC->outs() << "BOLT-INFO: enabling lite mode\n";
if (!opts::SaveProfile.empty() && BAT->enabledFor(InputFile)) {
- errs() << "BOLT-ERROR: unable to save profile in YAML format for input "
- "file processed by BOLT. Please remove -w option and use branch "
- "profile.\n";
+ BC->errs()
+ << "BOLT-ERROR: unable to save profile in YAML format for input "
+ "file processed by BOLT. Please remove -w option and use branch "
+ "profile.\n";
exit(1);
}
}
@@ -2252,8 +2283,8 @@ void RewriteInstance::processRelocations() {
}
if (NumFailedRelocations)
- errs() << "BOLT-WARNING: Failed to analyze " << NumFailedRelocations
- << " relocations\n";
+ BC->errs() << "BOLT-WARNING: Failed to analyze " << NumFailedRelocations
+ << " relocations\n";
}
void RewriteInstance::readDynamicRelocations(const SectionRef &Section,
@@ -2497,8 +2528,8 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
assert(ContainingBF && "cannot find function for address in code");
if (!IsAArch64 && !ContainingBF->containsAddress(Rel.getOffset())) {
if (opts::Verbosity >= 1)
- outs() << formatv("BOLT-INFO: {0} has relocations in padding area\n",
- *ContainingBF);
+ BC->outs() << formatv(
+ "BOLT-INFO: {0} has relocations in padding area\n", *ContainingBF);
ContainingBF->setSize(ContainingBF->getMaxSize());
ContainingBF->setSimple(false);
return;
@@ -2593,12 +2624,13 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
if (BF != ReferencedBF) {
// It's possible we are referencing a function without referencing any
// code, e.g. when taking a bitmask action on a function address.
- errs() << "BOLT-WARNING: non-standard function reference (e.g. bitmask)"
- << formatv(" detected against function {0} from ", *BF);
+ BC->errs()
+ << "BOLT-WARNING: non-standard function reference (e.g. bitmask)"
+ << formatv(" detected against function {0} from ", *BF);
if (IsFromCode)
- errs() << formatv("function {0}\n", *ContainingBF);
+ BC->errs() << formatv("function {0}\n", *ContainingBF);
else
- errs() << formatv("data section at {0:x}\n", Rel.getOffset());
+ BC->errs() << formatv("data section at {0:x}\n", Rel.getOffset());
LLVM_DEBUG(printRelocationInfo(Rel, SymbolName, SymbolAddress, Addend,
ExtractedValue));
ReferencedBF = BF;
@@ -2628,10 +2660,11 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
llvm::make_second_range(ContainingBF->Relocations), CheckReloc);
if (Found) {
- errs() << "BOLT-WARNING: detected possible compiler de-virtualization "
- "bug: -1 addend used with non-pc-relative relocation against "
- << formatv("function {0} in function {1}\n", *RogueBF,
- *ContainingBF);
+ BC->errs()
+ << "BOLT-WARNING: detected possible compiler de-virtualization "
+ "bug: -1 addend used with non-pc-relative relocation against "
+ << formatv("function {0} in function {1}\n", *RogueBF,
+ *ContainingBF);
return;
}
}
@@ -2681,9 +2714,10 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
}
if (opts::Verbosity > 1 &&
BinarySection(*BC, RelocatedSection).isWritable())
- errs() << "BOLT-WARNING: writable reference into the middle of the "
- << formatv("function {0} detected at address {1:x}\n",
- *ReferencedBF, Rel.getOffset());
+ BC->errs()
+ << "BOLT-WARNING: writable reference into the middle of the "
+ << formatv("function {0} detected at address {1:x}\n",
+ *ReferencedBF, Rel.getOffset());
}
SymbolAddress = Address;
Addend = 0;
@@ -2825,8 +2859,9 @@ void RewriteInstance::selectFunctionsToProcess() {
if ((!opts::ForceFunctionNames.empty() ||
!opts::ForceFunctionNamesNR.empty()) &&
!opts::SkipFunctionNames.empty()) {
- errs() << "BOLT-ERROR: cannot select functions to process and skip at the "
- "same time. Please use only one type of selection.\n";
+ BC->errs()
+ << "BOLT-ERROR: cannot select functions to process and skip at the "
+ "same time. Please use only one type of selection.\n";
exit(1);
}
@@ -2850,8 +2885,8 @@ void RewriteInstance::selectFunctionsToProcess() {
if (Index)
--Index;
LiteThresholdExecCount = TopFunctions[Index]->getKnownExecutionCount();
- outs() << "BOLT-INFO: limiting processing to functions with at least "
- << LiteThresholdExecCount << " invocations\n";
+ BC->outs() << "BOLT-INFO: limiting processing to functions with at least "
+ << LiteThresholdExecCount << " invocations\n";
}
LiteThresholdExecCount = std::max(
LiteThresholdExecCount, static_cast<uint64_t>(opts::LiteThresholdCount));
@@ -2859,8 +2894,10 @@ void RewriteInstance::selectFunctionsToProcess() {
StringSet<> ReorderFunctionsUserSet;
StringSet<> ReorderFunctionsLTOCommonSet;
if (opts::ReorderFunctions == ReorderFunctions::RT_USER) {
- for (const std::string &Function :
- ReorderFunctions::readFunctionOrderFile()) {
+ std::vector<std::string> FunctionNames;
+ BC->logBOLTErrorsAndQuitOnFatal(
+ ReorderFunctions::readFunctionOrderFile(FunctionNames));
+ for (const std::string &Function : FunctionNames) {
ReorderFunctionsUserSet.insert(Function);
if (std::optional<StringRef> LTOCommonName = getLTOCommonName(Function))
ReorderFunctionsLTOCommonSet.insert(*LTOCommonName);
@@ -2936,15 +2973,15 @@ void RewriteInstance::selectFunctionsToProcess() {
if (!shouldProcess(Function)) {
if (opts::Verbosity >= 1) {
- outs() << "BOLT-INFO: skipping processing " << Function
- << " per user request\n";
+ BC->outs() << "BOLT-INFO: skipping processing " << Function
+ << " per user request\n";
}
Function.setIgnored();
} else {
++NumFunctionsToProcess;
if (opts::MaxFunctions.getNumOccurrences() &&
NumFunctionsToProcess == opts::MaxFunctions)
- outs() << "BOLT-INFO: processing ending on " << Function << '\n';
+ BC->outs() << "BOLT-INFO: processing ending on " << Function << '\n';
}
}
@@ -2963,8 +3000,8 @@ void RewriteInstance::selectFunctionsToProcess() {
if (mustSkip(Function)) {
for (BinaryFunction *Parent : Function.ParentFragments) {
if (opts::Verbosity >= 1) {
- outs() << "BOLT-INFO: skipping processing " << *Parent
- << " together with fragment function\n";
+ BC->outs() << "BOLT-INFO: skipping processing " << *Parent
+ << " together with fragment function\n";
}
Parent->setIgnored();
--NumFunctionsToProcess;
@@ -2979,18 +3016,18 @@ void RewriteInstance::selectFunctionsToProcess() {
});
if (IgnoredParent) {
if (opts::Verbosity >= 1) {
- outs() << "BOLT-INFO: skipping processing " << Function
- << " together with parent function\n";
+ BC->outs() << "BOLT-INFO: skipping processing " << Function
+ << " together with parent function\n";
}
Function.setIgnored();
} else {
++NumFunctionsToProcess;
if (opts::Verbosity >= 1) {
- outs() << "BOLT-INFO: processing " << Function
- << " as a sibling of non-ignored function\n";
+ BC->outs() << "BOLT-INFO: processing " << Function
+ << " as a sibling of non-ignored function\n";
}
if (opts::MaxFunctions && NumFunctionsToProcess == opts::MaxFunctions)
- outs() << "BOLT-INFO: processing ending on " << Function << '\n';
+ BC->outs() << "BOLT-INFO: processing ending on " << Function << '\n';
}
}
}
@@ -3011,12 +3048,12 @@ void RewriteInstance::preprocessProfileData() {
NamedRegionTimer T("preprocessprofile", "pre-process profile data",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
- outs() << "BOLT-INFO: pre-processing profile using "
- << ProfileReader->getReaderName() << '\n';
+ BC->outs() << "BOLT-INFO: pre-processing profile using "
+ << ProfileReader->getReaderName() << '\n';
if (BAT->enabledFor(InputFile)) {
- outs() << "BOLT-INFO: profile collection done on a binary already "
- "processed by BOLT\n";
+ BC->outs() << "BOLT-INFO: profile collection done on a binary already "
+ "processed by BOLT\n";
ProfileReader->setBAT(&*BAT);
}
@@ -3024,10 +3061,11 @@ void RewriteInstance::preprocessProfileData() {
report_error("cannot pre-process profile", std::move(E));
if (!BC->hasSymbolsWithFileName() && ProfileReader->hasLocalsWithFileName()) {
- errs() << "BOLT-ERROR: input binary does not have local file symbols "
- "but profile data includes function names with embedded file "
- "names. It appears that the input binary was stripped while a "
- "profiled binary was not\n";
+ BC->errs()
+ << "BOLT-ERROR: input binary does not have local file symbols "
+ "but profile data includes function names with embedded file "
+ "names. It appears that the input binary was stripped while a "
+ "profiled binary was not\n";
exit(1);
}
}
@@ -3080,7 +3118,7 @@ void RewriteInstance::processProfileData() {
if (Function.empty())
continue;
- Function.print(outs(), "after attaching profile");
+ Function.print(BC->outs(), "after attaching profile");
}
}
@@ -3109,8 +3147,8 @@ void RewriteInstance::disassembleFunctions() {
ErrorOr<ArrayRef<uint8_t>> FunctionData = Function.getData();
if (!FunctionData) {
- errs() << "BOLT-ERROR: corresponding section is non-executable or "
- << "empty for function " << Function << '\n';
+ BC->errs() << "BOLT-ERROR: corresponding section is non-executable or "
+ << "empty for function " << Function << '\n';
exit(1);
}
@@ -3133,21 +3171,32 @@ void RewriteInstance::disassembleFunctions() {
continue;
}
- if (!Function.disassemble()) {
- if (opts::processAllFunctions())
- BC->exitWithBugReport("function cannot be properly disassembled. "
- "Unable to continue in relocation mode.",
- Function);
+ bool DisasmFailed{false};
+ handleAllErrors(Function.disassemble(), [&](const BOLTError &E) {
+ DisasmFailed = true;
+ if (E.isFatal()) {
+ E.log(BC->errs());
+ exit(1);
+ }
+ if (opts::processAllFunctions()) {
+ BC->errs() << BC->generateBugReportMessage(
+ "function cannot be properly disassembled. "
+ "Unable to continue in relocation mode.",
+ Function);
+ exit(1);
+ }
if (opts::Verbosity >= 1)
- outs() << "BOLT-INFO: could not disassemble function " << Function
- << ". Will ignore.\n";
+ BC->outs() << "BOLT-INFO: could not disassemble function " << Function
+ << ". Will ignore.\n";
// Forcefully ignore the function.
Function.setIgnored();
+ });
+
+ if (DisasmFailed)
continue;
- }
if (opts::PrintAll || opts::PrintDisasm)
- Function.print(outs(), "after disassembly");
+ Function.print(BC->outs(), "after disassembly");
}
BC->processInterproceduralReferences();
@@ -3182,10 +3231,12 @@ void RewriteInstance::disassembleFunctions() {
// Fill in CFI information for this function
if (!Function.trapsOnEntry() && !CFIRdWrt->fillCFIInfoFor(Function)) {
if (BC->HasRelocations) {
- BC->exitWithBugReport("unable to fill CFI.", Function);
+ BC->errs() << BC->generateBugReportMessage("unable to fill CFI.",
+ Function);
+ exit(1);
} else {
- errs() << "BOLT-WARNING: unable to fill CFI for function " << Function
- << ". Skipping.\n";
+ BC->errs() << "BOLT-WARNING: unable to fill CFI for function "
+ << Function << ". Skipping.\n";
Function.setSimple(false);
continue;
}
@@ -3199,7 +3250,8 @@ void RewriteInstance::disassembleFunctions() {
check_error(LSDASection.getError(), "failed to get LSDA section");
ArrayRef<uint8_t> LSDAData = ArrayRef<uint8_t>(
LSDASection->getData(), LSDASection->getContents().size());
- Function.parseLSDA(LSDAData, LSDASection->getAddress());
+ BC->logBOLTErrorsAndQuitOnFatal(
+ Function.parseLSDA(LSDAData, LSDASection->getAddress()));
}
}
}
@@ -3214,12 +3266,21 @@ void RewriteInstance::buildFunctionsCFG() {
ParallelUtilities::WorkFuncWithAllocTy WorkFun =
[&](BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId) {
- if (!BF.buildCFG(AllocId))
+ bool HadErrors{false};
+ handleAllErrors(BF.buildCFG(AllocId), [&](const BOLTError &E) {
+ if (!E.getMessage().empty())
+ E.log(BC->errs());
+ if (E.isFatal())
+ exit(1);
+ HadErrors = true;
+ });
+
+ if (HadErrors)
return;
if (opts::PrintAll) {
auto L = BC->scopeLock();
- BF.print(outs(), "while building cfg");
+ BF.print(BC->outs(), "while building cfg");
}
};
@@ -3258,14 +3319,14 @@ void RewriteInstance::postProcessFunctions() {
Function.postProcessCFG();
if (opts::PrintAll || opts::PrintCFG)
- Function.print(outs(), "after building cfg");
+ Function.print(BC->outs(), "after building cfg");
if (opts::DumpDotAll)
Function.dumpGraphForPass("00_build-cfg");
if (opts::PrintLoopInfo) {
Function.calculateLoopInfo();
- Function.printLoopInfo(outs());
+ Function.printLoopInfo(BC->outs());
}
BC->TotalScore += Function.getFunctionScore();
@@ -3273,15 +3334,15 @@ void RewriteInstance::postProcessFunctions() {
}
if (opts::PrintGlobals) {
- outs() << "BOLT-INFO: Global symbols:\n";
- BC->printGlobalSymbols(outs());
+ BC->outs() << "BOLT-INFO: Global symbols:\n";
+ BC->printGlobalSymbols(BC->outs());
}
}
void RewriteInstance::runOptimizationPasses() {
NamedRegionTimer T("runOptimizationPasses", "run optimization passes",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
- BinaryFunctionPassManager::runAllPasses(*BC);
+ BC->logBOLTErrorsAndQuitOnFatal(BinaryFunctionPassManager::runAllPasses(*BC));
}
void RewriteInstance::preregisterSections() {
@@ -3331,7 +3392,7 @@ void RewriteInstance::emitAndLink() {
Streamer->finish();
if (Streamer->getContext().hadError()) {
- errs() << "BOLT-ERROR: Emission failed.\n";
+ BC->errs() << "BOLT-ERROR: Emission failed.\n";
exit(1);
}
@@ -3342,9 +3403,10 @@ void RewriteInstance::emitAndLink() {
raw_fd_ostream FOS(OutObjectPath, EC);
check_error(EC, "cannot create output object file");
FOS << ObjectBuffer;
- outs() << "BOLT-INFO: intermediary output object file saved for debugging "
- "purposes: "
- << OutObjectPath << "\n";
+ BC->outs()
+ << "BOLT-INFO: intermediary output object file saved for debugging "
+ "purposes: "
+ << OutObjectPath << "\n";
}
ErrorOr<BinarySection &> TextSection =
@@ -3409,8 +3471,8 @@ void RewriteInstance::emitAndLink() {
}
if (opts::PrintCacheMetrics) {
- outs() << "BOLT-INFO: cache metrics after emitting functions:\n";
- CacheMetrics::printAll(BC->getSortedFunctions());
+ BC->outs() << "BOLT-INFO: cache metrics after emitting functions:\n";
+ CacheMetrics::printAll(BC->outs(), BC->getSortedFunctions());
}
}
@@ -3576,14 +3638,15 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) {
allocateAt(BC->OldTextSectionAddress) - BC->OldTextSectionAddress;
if (CodeSize <= BC->OldTextSectionSize) {
- outs() << "BOLT-INFO: using original .text for new code with 0x"
- << Twine::utohexstr(opts::AlignText) << " alignment\n";
+ BC->outs() << "BOLT-INFO: using original .text for new code with 0x"
+ << Twine::utohexstr(opts::AlignText) << " alignment\n";
AllocationDone = true;
} else {
- errs() << "BOLT-WARNING: original .text too small to fit the new code"
- << " using 0x" << Twine::utohexstr(opts::AlignText)
- << " alignment. " << CodeSize << " bytes needed, have "
- << BC->OldTextSectionSize << " bytes available.\n";
+ BC->errs()
+ << "BOLT-WARNING: original .text too small to fit the new code"
+ << " using 0x" << Twine::utohexstr(opts::AlignText)
+ << " alignment. " << CodeSize << " bytes needed, have "
+ << BC->OldTextSectionSize << " bytes available.\n";
opts::UseOldText = false;
}
}
@@ -3604,9 +3667,9 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) {
// Check if we need to insert a padding section for hot text.
if (PaddingSize && !opts::UseOldText)
- outs() << "BOLT-INFO: padding code to 0x"
- << Twine::utohexstr(NextAvailableAddress)
- << " to accommodate hot text\n";
+ BC->outs() << "BOLT-INFO: padding code to 0x"
+ << Twine::utohexstr(NextAvailableAddress)
+ << " to accommodate hot text\n";
return;
}
@@ -3814,7 +3877,7 @@ void RewriteInstance::patchELFPHDRTable() {
assert(!PHDRTableAddress && "unexpected address for program header table");
PHDRTableOffset = Obj.getHeader().e_phoff;
if (NewWritableSegmentSize) {
- errs() << "Unable to add writable segment with UseGnuStack option\n";
+ BC->errs() << "Unable to add writable segment with UseGnuStack option\n";
exit(1);
}
}
@@ -4114,7 +4177,8 @@ void RewriteInstance::encodeBATSection() {
copyByteArray(BoltInfo), BoltInfo.size(),
/*Alignment=*/1,
/*IsReadOnly=*/true, ELF::SHT_NOTE);
- outs() << "BOLT-INFO: BAT section size (bytes): " << BoltInfo.size() << '\n';
+ BC->outs() << "BOLT-INFO: BAT section size (bytes): " << BoltInfo.size()
+ << '\n';
}
template <typename ELFShdrTy>
@@ -4175,14 +4239,14 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
if (Section.hasSectionRef() || Section.isAnonymous()) {
if (opts::Verbosity)
- outs() << "BOLT-INFO: not writing section header for section "
- << Section.getOutputName() << '\n';
+ BC->outs() << "BOLT-INFO: not writing section header for section "
+ << Section.getOutputName() << '\n';
continue;
}
if (opts::Verbosity >= 1)
- outs() << "BOLT-INFO: writing section header for "
- << Section.getOutputName() << '\n';
+ BC->outs() << "BOLT-INFO: writing section header for "
+ << Section.getOutputName() << '\n';
ELFShdrTy NewSection;
NewSection.sh_type = ELF::SHT_PROGBITS;
NewSection.sh_addr = Section.getOutputAddress();
@@ -4216,8 +4280,8 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
if (PrevSection &&
PrevSection->sh_offset + PrevSection->sh_size > Section.sh_offset) {
if (opts::Verbosity > 1) {
- outs() << "BOLT-INFO: adjusting size for section "
- << PrevBinSec->getOutputName() << '\n';
+ BC->outs() << "BOLT-INFO: adjusting size for section "
+ << PrevBinSec->getOutputName() << '\n';
}
PrevSection->sh_size = Section.sh_offset - PrevSection->sh_offset;
}
@@ -4264,8 +4328,8 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
continue;
if (opts::Verbosity >= 1)
- outs() << "BOLT-INFO: writing section header for "
- << Section.getOutputName() << '\n';
+ BC->outs() << "BOLT-INFO: writing section header for "
+ << Section.getOutputName() << '\n';
ELFShdrTy NewSection;
NewSection.sh_type = Section.getELFType();
@@ -4663,8 +4727,8 @@ void RewriteInstance::updateELFSymbolTable(
std::optional<uint64_t> Value = std::nullopt) {
NewSymbol.st_value = Value ? *Value : getNewValueForSymbol(Name);
NewSymbol.st_shndx = ELF::SHN_ABS;
- outs() << "BOLT-INFO: setting " << Name << " to 0x"
- << Twine::utohexstr(NewSymbol.st_value) << '\n';
+ BC->outs() << "BOLT-INFO: setting " << Name << " to 0x"
+ << Twine::utohexstr(NewSymbol.st_value) << '\n';
};
if (opts::HotText &&
@@ -4739,8 +4803,8 @@ void RewriteInstance::updateELFSymbolTable(
Symbol.st_other = 0;
Symbol.setBindingAndType(ELF::STB_WEAK, ELF::STT_NOTYPE);
- outs() << "BOLT-INFO: setting " << Name << " to 0x"
- << Twine::utohexstr(Symbol.st_value) << '\n';
+ BC->outs() << "BOLT-INFO: setting " << Name << " to 0x"
+ << Twine::utohexstr(Symbol.st_value) << '\n';
Symbols.emplace_back(Symbol);
};
@@ -4836,7 +4900,7 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
}
}
if (!SymTabSection) {
- errs() << "BOLT-WARNING: no symbol table found\n";
+ BC->errs() << "BOLT-WARNING: no symbol table found\n";
return;
}
@@ -4939,7 +5003,7 @@ void RewriteInstance::patchELFAllocatableRelrSection(
auto WriteRelr = [&](uint64_t Value) {
if (RelrDynOffset + DynamicRelrEntrySize > RelrDynEndOffset) {
- errs() << "BOLT-ERROR: Offset overflow for relr.dyn section\n";
+ BC->errs() << "BOLT-ERROR: Offset overflow for relr.dyn section\n";
exit(1);
}
@@ -5051,12 +5115,12 @@ RewriteInstance::patchELFAllocatableRelaSections(ELFObjectFile<ELFT> *File) {
const uint64_t &EndOffset =
IsJmpRel ? RelPltEndOffset : RelDynEndOffset;
if (!Offset || !EndOffset) {
- errs() << "BOLT-ERROR: Invalid offsets for dynamic relocation\n";
+ BC->errs() << "BOLT-ERROR: Invalid offsets for dynamic relocation\n";
exit(1);
}
if (Offset + sizeof(NewRelA) > EndOffset) {
- errs() << "BOLT-ERROR: Offset overflow for dynamic relocation\n";
+ BC->errs() << "BOLT-ERROR: Offset overflow for dynamic relocation\n";
exit(1);
}
@@ -5105,7 +5169,7 @@ void RewriteInstance::patchELFGOT(ELFObjectFile<ELFT> *File) {
}
if (!GOTSection.getObject()) {
if (!BC->IsStaticExecutable)
- errs() << "BOLT-INFO: no .got section found\n";
+ BC->errs() << "BOLT-INFO: no .got section found\n";
return;
}
@@ -5209,9 +5273,10 @@ void RewriteInstance::patchELFDynamic(ELFObjectFile<ELFT> *File) {
}
if (BC->RequiresZNow && !ZNowSet) {
- errs() << "BOLT-ERROR: output binary requires immediate relocation "
- "processing which depends on DT_FLAGS or DT_FLAGS_1 presence in "
- ".dynamic. Please re-link the binary with -znow.\n";
+ BC->errs()
+ << "BOLT-ERROR: output binary requires immediate relocation "
+ "processing which depends on DT_FLAGS or DT_FLAGS_1 presence in "
+ ".dynamic. Please re-link the binary with -znow.\n";
exit(1);
}
}
@@ -5233,7 +5298,7 @@ Error RewriteInstance::readELFDynamic(ELFObjectFile<ELFT> *File) {
}
if (!DynamicPhdr) {
- outs() << "BOLT-INFO: static input executable detected\n";
+ BC->outs() << "BOLT-INFO: static input executable detected\n";
// TODO: static PIE executable might have dynamic header
BC->IsStaticExecutable = true;
return Error::success();
@@ -5307,12 +5372,12 @@ Error RewriteInstance::readELFDynamic(ELFObjectFile<ELFT> *File) {
DynamicRelrAddress.reset();
DynamicRelrSize = 0;
} else if (!DynamicRelrEntrySize) {
- errs() << "BOLT-ERROR: expected DT_RELRENT to be presented "
- << "in DYNAMIC section\n";
+ BC->errs() << "BOLT-ERROR: expected DT_RELRENT to be presented "
+ << "in DYNAMIC section\n";
exit(1);
} else if (DynamicRelrSize % DynamicRelrEntrySize) {
- errs() << "BOLT-ERROR: expected RELR table size to be divisible "
- << "by RELR entry size\n";
+ BC->errs() << "BOLT-ERROR: expected RELR table size to be divisible "
+ << "by RELR entry size\n";
exit(1);
}
@@ -5368,11 +5433,11 @@ void RewriteInstance::rewriteFile() {
if (Function->getImageSize() > Function->getMaxSize()) {
if (opts::Verbosity >= 1)
- errs() << "BOLT-WARNING: new function size (0x"
- << Twine::utohexstr(Function->getImageSize())
- << ") is larger than maximum allowed size (0x"
- << Twine::utohexstr(Function->getMaxSize()) << ") for function "
- << *Function << '\n';
+ BC->errs() << "BOLT-WARNING: new function size (0x"
+ << Twine::utohexstr(Function->getImageSize())
+ << ") is larger than maximum allowed size (0x"
+ << Twine::utohexstr(Function->getMaxSize())
+ << ") for function " << *Function << '\n';
// Remove jump table sections that this function owns in non-reloc mode
// because we don't want to write them anymore.
@@ -5408,7 +5473,7 @@ void RewriteInstance::rewriteFile() {
// Overwrite function in the output file.
if (opts::Verbosity >= 2)
- outs() << "BOLT: rewriting function \"" << *Function << "\"\n";
+ BC->outs() << "BOLT: rewriting function \"" << *Function << "\"\n";
OS.pwrite(reinterpret_cast<char *>(Function->getImageAddress()),
Function->getImageSize(), Function->getFileOffset());
@@ -5428,8 +5493,8 @@ void RewriteInstance::rewriteFile() {
// Write cold part
if (opts::Verbosity >= 2) {
- outs() << formatv("BOLT: rewriting function \"{0}\" (split parts)\n",
- *Function);
+ BC->outs() << formatv("BOLT: rewriting function \"{0}\" (split parts)\n",
+ *Function);
}
for (const FunctionFragment &FF :
@@ -5441,14 +5506,15 @@ void RewriteInstance::rewriteFile() {
// Print function statistics for non-relocation mode.
if (!BC->HasRelocations) {
- outs() << "BOLT: " << CountOverwrittenFunctions << " out of "
- << BC->getBinaryFunctions().size()
- << " functions were overwritten.\n";
+ BC->outs() << "BOLT: " << CountOverwrittenFunctions << " out of "
+ << BC->getBinaryFunctions().size()
+ << " functions were overwritten.\n";
if (BC->TotalScore != 0) {
double Coverage = OverwrittenScore / (double)BC->TotalScore * 100.0;
- outs() << format("BOLT-INFO: rewritten functions cover %.2lf", Coverage)
- << "% of the execution count of simple functions of "
- "this binary\n";
+ BC->outs() << format("BOLT-INFO: rewritten functions cover %.2lf",
+ Coverage)
+ << "% of the execution count of simple functions of "
+ "this binary\n";
}
}
@@ -5476,10 +5542,11 @@ void RewriteInstance::rewriteFile() {
continue;
if (opts::Verbosity >= 1)
- outs() << "BOLT: writing new section " << Section.getName()
- << "\n data at 0x" << Twine::utohexstr(Section.getAllocAddress())
- << "\n of size " << Section.getOutputSize() << "\n at offset "
- << Section.getOutputFileOffset() << '\n';
+ BC->outs() << "BOLT: writing new section " << Section.getName()
+ << "\n data at 0x"
+ << Twine::utohexstr(Section.getAllocAddress()) << "\n of size "
+ << Section.getOutputSize() << "\n at offset "
+ << Section.getOutputFileOffset() << '\n';
OS.pwrite(reinterpret_cast<const char *>(Section.getOutputData()),
Section.getOutputSize(), Section.getOutputFileOffset());
}
@@ -5529,8 +5596,8 @@ void RewriteInstance::rewriteFile() {
patchELFSectionHeaderTable();
if (opts::PrintSections) {
- outs() << "BOLT-INFO: Sections after processing:\n";
- BC->printSections(outs());
+ BC->outs() << "BOLT-INFO: Sections after processing:\n";
+ BC->printSections(BC->outs());
}
Out->keep();