@@ -5791,42 +5791,64 @@ void RewriteInstance::writeEHFrameHeader() {
5791
5791
LLVM_DEBUG (dbgs () << " BOLT: writing a new " << getEHFrameHdrSectionName ()
5792
5792
<< ' \n ' );
5793
5793
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
+ }
5796
5813
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);
5800
5818
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
+ }
5803
5844
5804
5845
Out->os ().seek (EHFrameHdrFileOffset);
5805
5846
Out->os ().write (NewEHFrameHdr.data (), NewEHFrameHdr.size ());
5806
5847
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.
5811
5849
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 ());
5830
5852
5831
5853
// Merge new .eh_frame with the relocated original so that gdb can locate all
5832
5854
// FDEs.
0 commit comments