[BOLT][NFC] Refactor data section emission code

Summary: RewriteInstance::emitDataSection() -> BinarySection::emitAsData()

(cherry picked from FBD18623050)
This commit is contained in:
Maksim Panchenko 2019-11-19 14:47:49 -08:00
parent 95a1c7f553
commit 3b1b9916dd
4 changed files with 56 additions and 59 deletions

View File

@ -14,13 +14,14 @@
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#undef DEBUG_TYPE #undef DEBUG_TYPE
#define DEBUG_TYPE "binary-section" #define DEBUG_TYPE "bolt"
using namespace llvm; using namespace llvm;
using namespace bolt; using namespace bolt;
namespace opts { namespace opts {
extern cl::opt<bool> PrintRelocations; extern cl::opt<bool> PrintRelocations;
extern cl::opt<bool> HotData;
} }
uint64_t uint64_t
@ -61,6 +62,53 @@ BinarySection::hash(const BinaryData &BD,
return Hash; return Hash;
} }
void BinarySection::emitAsData(MCStreamer &Streamer, StringRef NewName) const {
StringRef SectionName = !NewName.empty() ? NewName : getName();
StringRef SectionContents = getContents();
auto *ELFSection = BC.Ctx->getELFSection(SectionName,
getELFType(),
getELFFlags());
Streamer.SwitchSection(ELFSection);
Streamer.EmitValueToAlignment(getAlignment());
if (BC.HasRelocations && opts::HotData && isReordered())
Streamer.EmitLabel(BC.Ctx->getOrCreateSymbol("__hot_data_start"));
DEBUG(dbgs() << "BOLT-DEBUG: emitting "
<< (isAllocatable() ? "" : "non-")
<< "allocatable data section " << SectionName << '\n');
if (!hasRelocations()) {
Streamer.EmitBytes(SectionContents);
} else {
uint64_t SectionOffset = 0;
for (auto &Relocation : relocations()) {
assert(Relocation.Offset < SectionContents.size() && "overflow detected");
if (SectionOffset < Relocation.Offset) {
Streamer.EmitBytes(
SectionContents.substr(SectionOffset,
Relocation.Offset - SectionOffset));
SectionOffset = Relocation.Offset;
}
DEBUG(dbgs() << "BOLT-DEBUG: emitting relocation for symbol "
<< Relocation.Symbol->getName() << " at offset 0x"
<< Twine::utohexstr(Relocation.Offset)
<< " with size "
<< Relocation::getSizeForType(Relocation.Type) << '\n');
auto RelocationSize = Relocation.emit(&Streamer);
SectionOffset += RelocationSize;
}
assert(SectionOffset <= SectionContents.size() && "overflow error");
if (SectionOffset < SectionContents.size()) {
Streamer.EmitBytes(SectionContents.substr(SectionOffset));
}
}
if (BC.HasRelocations && opts::HotData && isReordered())
Streamer.EmitLabel(BC.Ctx->getOrCreateSymbol("__hot_data_end"));
}
BinarySection::~BinarySection() { BinarySection::~BinarySection() {
if (isReordered()) { if (isReordered()) {
delete[] getData(); delete[] getData();

View File

@ -410,6 +410,10 @@ public:
IsAnonymous = Flag; IsAnonymous = Flag;
} }
/// Emit the section as data, possibly with relocations. Use name \p NewName
// for the section during emission if non-empty.
void emitAsData(MCStreamer &Streamer, StringRef NewName = StringRef()) const;
/// Reorder the contents of this section according to /p Order. If /// Reorder the contents of this section according to /p Order. If
/// /p Inplace is true, the entire contents of the section is reordered, /// /p Inplace is true, the entire contents of the section is reordered,
/// otherwise the new contents contain only the reordered data. /// otherwise the new contents contain only the reordered data.

View File

@ -220,7 +220,7 @@ HotTextMoveSections("hot-text-move-sections",
cl::ZeroOrMore, cl::ZeroOrMore,
cl::cat(BoltCategory)); cl::cat(BoltCategory));
static cl::opt<bool> cl::opt<bool>
HotData("hot-data", HotData("hot-data",
cl::desc("hot data symbols support (relocation mode)"), cl::desc("hot data symbols support (relocation mode)"),
cl::ZeroOrMore, cl::ZeroOrMore,
@ -2985,7 +2985,7 @@ void RewriteInstance::emitAndLink() {
// Relocate .eh_frame to .eh_frame_old. // Relocate .eh_frame to .eh_frame_old.
if (EHFrameSection) { if (EHFrameSection) {
relocateEHFrameSection(); relocateEHFrameSection();
emitDataSection(Streamer.get(), *EHFrameSection, ".eh_frame_old"); EHFrameSection->emitAsData(*Streamer, ".eh_frame_old");
} }
// Update _end if needed. // Update _end if needed.
@ -3560,55 +3560,6 @@ void RewriteInstance::updateOutputValues(const MCAsmLayout &Layout) {
} }
} }
void RewriteInstance::emitDataSection(MCStreamer *Streamer,
const BinarySection &Section,
StringRef NewName) {
StringRef SectionName = !NewName.empty() ? NewName : Section.getName();
StringRef SectionContents = Section.getContents();
auto *ELFSection = BC->Ctx->getELFSection(SectionName,
Section.getELFType(),
Section.getELFFlags());
Streamer->SwitchSection(ELFSection);
Streamer->EmitValueToAlignment(Section.getAlignment());
if (BC->HasRelocations && opts::HotData && Section.isReordered())
Streamer->EmitLabel(BC->Ctx->getOrCreateSymbol("__hot_data_start"));
DEBUG(dbgs() << "BOLT-DEBUG: emitting "
<< (Section.isAllocatable() ? "" : "non-")
<< "allocatable data section " << SectionName << '\n');
if (!Section.hasRelocations()) {
Streamer->EmitBytes(SectionContents);
} else {
uint64_t SectionOffset = 0;
for (auto &Relocation : Section.relocations()) {
assert(Relocation.Offset < SectionContents.size() && "overflow detected");
if (SectionOffset < Relocation.Offset) {
Streamer->EmitBytes(
SectionContents.substr(SectionOffset,
Relocation.Offset - SectionOffset));
SectionOffset = Relocation.Offset;
}
DEBUG(dbgs() << "BOLT-DEBUG: emitting relocation for symbol "
<< Relocation.Symbol->getName() << " at offset 0x"
<< Twine::utohexstr(Relocation.Offset)
<< " with size "
<< Relocation::getSizeForType(Relocation.Type) << '\n');
auto RelocationSize = Relocation.emit(Streamer);
SectionOffset += RelocationSize;
}
assert(SectionOffset <= SectionContents.size() && "overflow error");
if (SectionOffset < SectionContents.size()) {
Streamer->EmitBytes(SectionContents.substr(SectionOffset));
}
}
if (BC->HasRelocations && opts::HotData && Section.isReordered())
Streamer->EmitLabel(BC->Ctx->getOrCreateSymbol("__hot_data_end"));
}
void RewriteInstance::emitDataSections(MCStreamer *Streamer) { void RewriteInstance::emitDataSections(MCStreamer *Streamer) {
for (const auto &Section : BC->sections()) { for (const auto &Section : BC->sections()) {
if (!Section.hasRelocations() || !Section.hasSectionRef()) if (!Section.hasRelocations() || !Section.hasSectionRef())
@ -3619,7 +3570,7 @@ void RewriteInstance::emitDataSections(MCStreamer *Streamer) {
std::string EmitName = Section.isReordered() std::string EmitName = Section.isReordered()
? std::string(Section.getOutputName()) ? std::string(Section.getOutputName())
: OrgSecPrefix + std::string(SectionName); : OrgSecPrefix + std::string(SectionName);
emitDataSection(Streamer, Section, EmitName); Section.emitAsData(*Streamer, EmitName);
} }
} }

View File

@ -117,12 +117,6 @@ public:
/// Emit function code. /// Emit function code.
void emitFunctions(MCStreamer *Streamer); void emitFunctions(MCStreamer *Streamer);
/// Emit data \p Section, possibly with relocations. Use name \p Name if
/// non-empty.
void emitDataSection(MCStreamer *Streamer,
const BinarySection &Section,
StringRef Name = StringRef());
/// Emit data sections that have code references in them. /// Emit data sections that have code references in them.
void emitDataSections(MCStreamer *Streamer); void emitDataSections(MCStreamer *Streamer);