From b07e870d785fcebc2e6cc00f46fb4765abd8fa7d Mon Sep 17 00:00:00 2001 From: Maksim Panchenko <maks@fb.com> Date: Wed, 20 Nov 2019 00:16:19 -0800 Subject: [PATCH] [BOLT] Add BinarySection::flushPendingRelocations() (cherry picked from FBD18623527) --- bolt/src/BinarySection.cpp | 20 ++++++++++++++++++++ bolt/src/BinarySection.h | 3 +++ bolt/src/RewriteInstance.cpp | 19 ++----------------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/bolt/src/BinarySection.cpp b/bolt/src/BinarySection.cpp index ed110a73be29..4be31f093b79 100644 --- a/bolt/src/BinarySection.cpp +++ b/bolt/src/BinarySection.cpp @@ -109,6 +109,26 @@ void BinarySection::emitAsData(MCStreamer &Streamer, StringRef NewName) const { Streamer.EmitLabel(BC.Ctx->getOrCreateSymbol("__hot_data_end")); } +void BinarySection::flushPendingRelocations(raw_pwrite_stream &OS) { + DEBUG(dbgs() << "BOLT-DEBUG: flushing pending relocs for section " + << getName() << '\n'); + for (auto &Reloc : PendingRelocations) { + DEBUG(dbgs() << "BOLT-DEBUG: writing value 0x" + << Twine::utohexstr(Reloc.Addend) + << " of size " << Relocation::getSizeForType(Reloc.Type) + << " at offset 0x" + << Twine::utohexstr(Reloc.Offset) << '\n'); + assert(Reloc.Type == ELF::R_X86_64_32 && + "only R_X86_64_32 relocations are supported at the moment"); + const uint32_t Value = Reloc.Addend; + OS.pwrite(reinterpret_cast<const char*>(&Value), + Relocation::getSizeForType(Reloc.Type), + FileOffset + Reloc.Offset); + } + + clearList(PendingRelocations); +} + BinarySection::~BinarySection() { if (isReordered()) { delete[] getData(); diff --git a/bolt/src/BinarySection.h b/bolt/src/BinarySection.h index 401b391ecfb0..d212f1e829a4 100644 --- a/bolt/src/BinarySection.h +++ b/bolt/src/BinarySection.h @@ -414,6 +414,9 @@ public: // for the section during emission if non-empty. void emitAsData(MCStreamer &Streamer, StringRef NewName = StringRef()) const; + /// Flush all pending relocations to the emitted section. + void flushPendingRelocations(raw_pwrite_stream &OS); + /// Reorder the contents of this section according to /p Order. If /// /p Inplace is true, the entire contents of the section is reordered, /// otherwise the new contents contain only the reordered data. diff --git a/bolt/src/RewriteInstance.cpp b/bolt/src/RewriteInstance.cpp index 838560cafb8d..bd55ed23e888 100644 --- a/bolt/src/RewriteInstance.cpp +++ b/bolt/src/RewriteInstance.cpp @@ -3748,23 +3748,8 @@ void RewriteInstance::rewriteNoteSections() { Size += BSec->getOutputSize(); } - if (BSec->hasPendingRelocations()) { - DEBUG(dbgs() << "BOLT-DEBUG: processing relocs for section " - << SectionName << '\n'); - for (auto &Reloc : BSec->pendingRelocations()) { - DEBUG(dbgs() << "BOLT-DEBUG: writing value 0x" - << Twine::utohexstr(Reloc.Addend) - << " of size " << Relocation::getSizeForType(Reloc.Type) - << " at offset 0x" - << Twine::utohexstr(Reloc.Offset) << '\n'); - assert(Reloc.Type == ELF::R_X86_64_32 && - "only R_X86_64_32 relocations are supported at the moment"); - uint32_t Value = Reloc.Addend; - OS.pwrite(reinterpret_cast<const char*>(&Value), - Relocation::getSizeForType(Reloc.Type), - NextAvailableOffset + Reloc.Offset); - } - } + BSec->setFileOffset(NextAvailableOffset); + BSec->flushPendingRelocations(OS); } // Set/modify section info.