-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[BOLT] Overwrite .eh_frame and .gcc_except_table #116755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3887,6 +3887,43 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) { | |
|
||
void RewriteInstance::mapAllocatableSections( | ||
BOLTLinker::SectionMapper MapSection) { | ||
|
||
if (opts::UseOldText || opts::StrictMode) { | ||
auto tryRewriteSection = [&](BinarySection &OldSection, | ||
BinarySection &NewSection) { | ||
if (OldSection.getSize() < NewSection.getOutputSize()) | ||
return; | ||
|
||
BC->outs() << "BOLT-INFO: rewriting " << OldSection.getName() | ||
<< " in-place\n"; | ||
|
||
NewSection.setOutputAddress(OldSection.getAddress()); | ||
NewSection.setOutputFileOffset(OldSection.getInputFileOffset()); | ||
MapSection(NewSection, OldSection.getAddress()); | ||
|
||
// Pad contents with zeros. | ||
NewSection.addPadding(OldSection.getSize() - NewSection.getOutputSize()); | ||
|
||
// Prevent the original section name from appearing in the section header | ||
// table. | ||
OldSection.setAnonymous(true); | ||
}; | ||
|
||
if (EHFrameSection) { | ||
BinarySection *NewEHFrameSection = | ||
getSection(getNewSecPrefix() + getEHFrameSectionName()); | ||
assert(NewEHFrameSection && "New contents expected for .eh_frame"); | ||
tryRewriteSection(*EHFrameSection, *NewEHFrameSection); | ||
} | ||
BinarySection *EHSection = getSection(".gcc_except_table"); | ||
BinarySection *NewEHSection = | ||
getSection(getNewSecPrefix() + ".gcc_except_table"); | ||
if (EHSection) { | ||
assert(NewEHSection && "New contents expected for .gcc_except_table"); | ||
tryRewriteSection(*EHSection, *NewEHSection); | ||
} | ||
} | ||
|
||
// Allocate read-only sections first, then writable sections. | ||
enum : uint8_t { ST_READONLY, ST_READWRITE }; | ||
for (uint8_t SType = ST_READONLY; SType <= ST_READWRITE; ++SType) { | ||
|
@@ -4164,7 +4201,6 @@ void RewriteInstance::rewriteNoteSections() { | |
// New section size. | ||
uint64_t Size = 0; | ||
bool DataWritten = false; | ||
uint8_t *SectionData = nullptr; | ||
// Copy over section contents unless it's one of the sections we overwrite. | ||
if (!willOverwriteSection(SectionName)) { | ||
Size = Section.sh_size; | ||
|
@@ -4196,12 +4232,7 @@ void RewriteInstance::rewriteNoteSections() { | |
if (BSec->getAllocAddress()) { | ||
assert(!DataWritten && "Writing section twice."); | ||
(void)DataWritten; | ||
SectionData = BSec->getOutputData(); | ||
|
||
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: " << (Size ? "appending" : "writing") | ||
<< " contents to section " << SectionName << '\n'); | ||
OS.write(reinterpret_cast<char *>(SectionData), BSec->getOutputSize()); | ||
Size += BSec->getOutputSize(); | ||
Size += BSec->write(OS); | ||
} | ||
|
||
BSec->setOutputFileOffset(NextAvailableOffset); | ||
|
@@ -4232,8 +4263,7 @@ void RewriteInstance::rewriteNoteSections() { | |
<< " of size " << Section.getOutputSize() << " at offset 0x" | ||
<< Twine::utohexstr(Section.getOutputFileOffset()) << '\n'); | ||
|
||
OS.write(Section.getOutputContents().data(), Section.getOutputSize()); | ||
NextAvailableOffset += Section.getOutputSize(); | ||
NextAvailableOffset += Section.write(OS); | ||
} | ||
} | ||
|
||
|
@@ -4347,6 +4377,10 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File, | |
BinarySection *BinSec = BC->getSectionForSectionRef(SecRef); | ||
assert(BinSec && "Matching BinarySection should exist."); | ||
|
||
// Exclude anonymous sections. | ||
if (BinSec->isAnonymous()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume this is the matching bit of
in the rewriter. Can you add a comment? Do we have other anonymous sections outside of this one in the patch? Looks like this is a larger functional change (OK to have it here, but I want to understand) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We currently use anonymous sections to emit jump tables. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LG |
||
continue; | ||
|
||
addSection(Section, *BinSec); | ||
} | ||
|
||
|
@@ -5699,8 +5733,8 @@ void RewriteInstance::rewriteFile() { | |
<< Twine::utohexstr(Section.getAllocAddress()) << "\n of size " | ||
<< Section.getOutputSize() << "\n at offset " | ||
<< Section.getOutputFileOffset() << '\n'; | ||
OS.pwrite(reinterpret_cast<const char *>(Section.getOutputData()), | ||
Section.getOutputSize(), Section.getOutputFileOffset()); | ||
OS.seek(Section.getOutputFileOffset()); | ||
Section.write(OS); | ||
} | ||
|
||
for (BinarySection &Section : BC->allocatableSections()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Check that llvm-bolt can overwrite .eh_frame section in-place. | ||
|
||
REQUIRES: system-linux | ||
|
||
RUN: %clang %cflags %p/Inputs/hello.c -o %t -Wl,-q | ||
RUN: llvm-bolt %t -o %t.bolt --strict | FileCheck %s | ||
|
||
CHECK: rewriting .eh_frame in-place |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the padding is required to make sure the size match? We can add that in a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we overwrite the original contents, if the new section is smaller, there will be leftovers from the original section left in the tail. Hence, we write zeros to remove "junk" bytes.