forked from OSchip/llvm-project
[BOLT][NFC] Refactor data section emission code
Summary: RewriteInstance::emitDataSection() -> BinarySection::emitAsData() (cherry picked from FBD18623050)
This commit is contained in:
parent
95a1c7f553
commit
3b1b9916dd
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue