Skip to content

Commit

Permalink
[BOLT] Fix writing out unmarked .eh_frame section
Browse files Browse the repository at this point in the history
When BOLT updates .eh_frame section, it concatenates newly-generated
contents (from CFI directives) with the original .eh_frame that has
relocations applied to it. However, if no new content is generated,
the original .eh_frame has to be left intact. In that case, BOLT was
still writing out the relocatable copy of the original .eh_frame section
to the new segment, even though this copy was never used and was not
even marked in the section header table.

Detect the scenario above and skip allocating extra space for .eh_frame.

Reviewed By: rafauler

Differential Revision: https://reviews.llvm.org/D135223
  • Loading branch information
maksfb committed Oct 7, 2022
1 parent c683e28 commit 0b213c9
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
10 changes: 10 additions & 0 deletions bolt/lib/Rewrite/RewriteInstance.cpp
Expand Up @@ -3798,6 +3798,16 @@ void RewriteInstance::mapDataSections(RuntimeDyld &RTDyld) {
if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary())
RtLibrary->addRuntimeLibSections(Sections);

if (!EHFrameSection || !EHFrameSection->isFinalized()) {
ErrorOr<BinarySection &> OldEHFrameSection =
BC->getUniqueSectionByName(Twine(getOrgSecPrefix(), ".eh_frame").str());
if (OldEHFrameSection) {
RTDyld.reassignSectionAddress(OldEHFrameSection->getSectionID(),
NextAvailableAddress);
BC->deregisterSection(*OldEHFrameSection);
}
}

for (std::string &SectionName : Sections) {
ErrorOr<BinarySection &> Section = BC->getUniqueSectionByName(SectionName);
if (!Section || !Section->isAllocatable() || !Section->isFinalized())
Expand Down
27 changes: 27 additions & 0 deletions bolt/test/X86/dummy-eh-frame-bug.s
@@ -0,0 +1,27 @@
# REQUIRES: system-linux

# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o
# RUN: ld.lld %t.o -o %t.exe -q
# RUN: llvm-bolt %t.exe -o %t.bolt.exe --funcs=nocfi_function
# RUN: llvm-readelf --section-headers %t.bolt.exe | FileCheck %s

## Check that llvm-bolt does not allocate unmarked space for original .eh_frame
## after .text when no update is needed to .eh_frame.

# CHECK: {{ .text}} PROGBITS [[#%x,ADDR:]] [[#%x,OFFSET:]] [[#%x,SIZE:]]
# CHECK-NEXT: 0000000000000000 [[#%x, OFFSET + SIZE]]

.text
.globl nocfi_function
.type nocfi_function,@function
nocfi_function:
ret
.size nocfi_function, .-nocfi_function

.globl _start
.type _start,@function
_start:
.cfi_startproc
call nocfi_function
.size _start, .-_start
.cfi_endproc

0 comments on commit 0b213c9

Please sign in to comment.