@@ -5791,42 +5791,64 @@ void RewriteInstance::writeEHFrameHeader() {
57915791 LLVM_DEBUG (dbgs () << " BOLT: writing a new " << getEHFrameHdrSectionName ()
57925792 << ' \n ' );
57935793
5794- NextAvailableAddress =
5795- appendPadding (Out->os (), NextAvailableAddress, EHFrameHdrAlign);
5794+ // Try to overwrite the original .eh_frame_hdr if the size permits.
5795+ uint64_t EHFrameHdrOutputAddress = 0 ;
5796+ uint64_t EHFrameHdrFileOffset = 0 ;
5797+ std::vector<char > NewEHFrameHdr;
5798+ BinarySection *OldEHFrameHdrSection = getSection (getEHFrameHdrSectionName ());
5799+ if (OldEHFrameHdrSection) {
5800+ NewEHFrameHdr = CFIRdWrt->generateEHFrameHeader (
5801+ RelocatedEHFrame, NewEHFrame, OldEHFrameHdrSection->getAddress ());
5802+ if (NewEHFrameHdr.size () <= OldEHFrameHdrSection->getSize ()) {
5803+ BC->outs () << " BOLT-INFO: rewriting " << getEHFrameHdrSectionName ()
5804+ << " in-place\n " ;
5805+ EHFrameHdrOutputAddress = OldEHFrameHdrSection->getAddress ();
5806+ EHFrameHdrFileOffset = OldEHFrameHdrSection->getInputFileOffset ();
5807+ } else {
5808+ OldEHFrameHdrSection->setOutputName (getOrgSecPrefix () +
5809+ getEHFrameHdrSectionName ());
5810+ OldEHFrameHdrSection = nullptr ;
5811+ }
5812+ }
57965813
5797- const uint64_t EHFrameHdrOutputAddress = NextAvailableAddress;
5798- const uint64_t EHFrameHdrFileOffset =
5799- getFileOffsetForAddress (NextAvailableAddress);
5814+ // If there was not enough space, allocate more memory for .eh_frame_hdr.
5815+ if (!OldEHFrameHdrSection) {
5816+ NextAvailableAddress =
5817+ appendPadding (Out->os (), NextAvailableAddress, EHFrameHdrAlign);
58005818
5801- std::vector<char > NewEHFrameHdr = CFIRdWrt->generateEHFrameHeader (
5802- RelocatedEHFrame, NewEHFrame, EHFrameHdrOutputAddress);
5819+ EHFrameHdrOutputAddress = NextAvailableAddress;
5820+ EHFrameHdrFileOffset = getFileOffsetForAddress (NextAvailableAddress);
5821+
5822+ NewEHFrameHdr = CFIRdWrt->generateEHFrameHeader (
5823+ RelocatedEHFrame, NewEHFrame, EHFrameHdrOutputAddress);
5824+
5825+ NextAvailableAddress += NewEHFrameHdr.size ();
5826+ if (!BC->BOLTReserved .empty () &&
5827+ (NextAvailableAddress > BC->BOLTReserved .end ())) {
5828+ BC->errs () << " BOLT-ERROR: unable to fit " << getEHFrameHdrSectionName ()
5829+ << " into reserved space\n " ;
5830+ exit (1 );
5831+ }
5832+
5833+ // Create a new entry in the section header table.
5834+ const unsigned Flags = BinarySection::getFlags (/* IsReadOnly=*/ true ,
5835+ /* IsText=*/ false ,
5836+ /* IsAllocatable=*/ true );
5837+ BinarySection &EHFrameHdrSec = BC->registerOrUpdateSection (
5838+ getNewSecPrefix () + getEHFrameHdrSectionName (), ELF::SHT_PROGBITS,
5839+ Flags, nullptr , NewEHFrameHdr.size (), /* Alignment=*/ 1 );
5840+ EHFrameHdrSec.setOutputFileOffset (EHFrameHdrFileOffset);
5841+ EHFrameHdrSec.setOutputAddress (EHFrameHdrOutputAddress);
5842+ EHFrameHdrSec.setOutputName (getEHFrameHdrSectionName ());
5843+ }
58035844
58045845 Out->os ().seek (EHFrameHdrFileOffset);
58055846 Out->os ().write (NewEHFrameHdr.data (), NewEHFrameHdr.size ());
58065847
5807- const unsigned Flags = BinarySection::getFlags (/* IsReadOnly=*/ true ,
5808- /* IsText=*/ false ,
5809- /* IsAllocatable=*/ true );
5810- BinarySection *OldEHFrameHdrSection = getSection (getEHFrameHdrSectionName ());
5848+ // Pad the contents if overwriting in-place.
58115849 if (OldEHFrameHdrSection)
5812- OldEHFrameHdrSection->setOutputName (getOrgSecPrefix () +
5813- getEHFrameHdrSectionName ());
5814-
5815- BinarySection &EHFrameHdrSec = BC->registerOrUpdateSection (
5816- getNewSecPrefix () + getEHFrameHdrSectionName (), ELF::SHT_PROGBITS, Flags,
5817- nullptr , NewEHFrameHdr.size (), /* Alignment=*/ 1 );
5818- EHFrameHdrSec.setOutputFileOffset (EHFrameHdrFileOffset);
5819- EHFrameHdrSec.setOutputAddress (EHFrameHdrOutputAddress);
5820- EHFrameHdrSec.setOutputName (getEHFrameHdrSectionName ());
5821-
5822- NextAvailableAddress += EHFrameHdrSec.getOutputSize ();
5823-
5824- if (!BC->BOLTReserved .empty () &&
5825- (NextAvailableAddress > BC->BOLTReserved .end ())) {
5826- BC->errs () << " BOLT-ERROR: unable to fit " << getEHFrameHdrSectionName ()
5827- << " into reserved space\n " ;
5828- exit (1 );
5829- }
5850+ Out->os ().write_zeros (OldEHFrameHdrSection->getSize () -
5851+ NewEHFrameHdr.size ());
58305852
58315853 // Merge new .eh_frame with the relocated original so that gdb can locate all
58325854 // FDEs.
0 commit comments