Skip to content

Commit

Permalink
[BOLT] Do not emit old .eh_frame in relocation mode
Browse files Browse the repository at this point in the history
Summary:
In relocation mode, there is no use for old .eh_frame section. Moreover,
it can interfere with new EH frames via .eh_frame_hdr when the original
.text is reused.

(cherry picked from FBD21120070)
  • Loading branch information
maksfb committed Apr 19, 2020
1 parent 23edb3e commit 33e0b2a
Showing 1 changed file with 29 additions and 18 deletions.
47 changes: 29 additions & 18 deletions bolt/src/RewriteInstance.cpp
Expand Up @@ -2569,9 +2569,15 @@ void RewriteInstance::emitAndLink() {
/* IncrementalLinkerCompatible */ false,
/* DWARFMustBeAtTheEnd */ false));

// Make .eh_frame relocatable.
if (EHFrameSection) {
relocateEHFrameSection();
if (BC->HasRelocations) {
// The section is going to be regenerated from scratch.
// Empty the contents, but keep the section reference.
EHFrameSection->getContents().take_front(0);
} else {
// Make .eh_frame relocatable.
relocateEHFrameSection();
}
}

// Emit contents outside of BinaryContext.
Expand Down Expand Up @@ -4499,11 +4505,16 @@ void RewriteInstance::writeEHFrameHeader() {
BC->AsmInfo->isLittleEndian(),
BC->AsmInfo->getCodePointerSize()));

uint64_t OldEHFrameAddress{0};
StringRef OldEHFrameContents;
auto OldEHFrameSection =
BC->getUniqueSectionByName(Twine(getOrgSecPrefix(), ".eh_frame").str());
assert(OldEHFrameSection && "expected original .eh_frame to be present");
DWARFDebugFrame OldEHFrame(true, OldEHFrameSection->getOutputAddress());
OldEHFrame.parse(DWARFDataExtractor(OldEHFrameSection->getOutputContents(),
if (OldEHFrameSection) {
OldEHFrameAddress = OldEHFrameSection->getOutputAddress();
OldEHFrameContents = OldEHFrameSection->getOutputContents();
}
DWARFDebugFrame OldEHFrame(true, OldEHFrameAddress);
OldEHFrame.parse(DWARFDataExtractor(OldEHFrameContents,
BC->AsmInfo->isLittleEndian(),
BC->AsmInfo->getCodePointerSize()));

Expand Down Expand Up @@ -4540,19 +4551,19 @@ void RewriteInstance::writeEHFrameHeader() {
NextAvailableAddress += EHFrameHdrSec.getOutputSize();

// Merge new .eh_frame with original so that gdb can locate all FDEs.
const auto EHFrameSectionSize = (OldEHFrameSection->getOutputAddress() +
OldEHFrameSection->getOutputSize() -
EHFrameSection->getOutputAddress());

EHFrameSection =
BC->registerOrUpdateSection(".eh_frame",
EHFrameSection->getELFType(),
EHFrameSection->getELFFlags(),
EHFrameSection->getOutputData(),
EHFrameSectionSize,
EHFrameSection->getAlignment());

BC->deregisterSection(*OldEHFrameSection);
if (OldEHFrameSection) {
const auto EHFrameSectionSize = (OldEHFrameSection->getOutputAddress() +
OldEHFrameSection->getOutputSize() -
EHFrameSection->getOutputAddress());
EHFrameSection =
BC->registerOrUpdateSection(".eh_frame",
EHFrameSection->getELFType(),
EHFrameSection->getELFFlags(),
EHFrameSection->getOutputData(),
EHFrameSectionSize,
EHFrameSection->getAlignment());
BC->deregisterSection(*OldEHFrameSection);
}

DEBUG(dbgs() << "BOLT-DEBUG: size of .eh_frame after merge is "
<< EHFrameSection->getOutputSize() << '\n');
Expand Down

0 comments on commit 33e0b2a

Please sign in to comment.