[BOLT] Emit .eh_frame_hdr before .eh_frame to prevent table scans from libdw (#201917)
resolves https://github.com/llvm/llvm-project/issues/201701 by moving
the `.eh_frame_hdr` section-header entry before `.eh_frame` before
assigning final section indices.
This lets BOLT binaries work with existing [libdw library logic
expecting the index before the
table](67199e1c97/libdw/dwarf_getcfi_elf.c (L301)),
preventing linear `.eh_frame` scanning.
This commit is contained in:
parent
33e8502336
commit
ef752a0780
2 changed files with 26 additions and 1 deletions
|
|
@ -5104,6 +5104,22 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
|
|||
addSection(NewSection, Section);
|
||||
}
|
||||
|
||||
// Some consumers, including elfutils/libdw, stop scanning section headers
|
||||
// once they find .eh_frame and only use .eh_frame_hdr if it appeared first.
|
||||
// Keep layout-driven ordering for size calculations above, but preserve the
|
||||
// conventional section-header order before assigning final indices.
|
||||
auto HasOutputName = [](StringRef Name) {
|
||||
return [Name](const auto &SectionKV) {
|
||||
return SectionKV.first && SectionKV.first->getOutputName() == Name;
|
||||
};
|
||||
};
|
||||
auto EHFrameHdrIt =
|
||||
llvm::find_if(OutputSections, HasOutputName(getEHFrameHdrSectionName()));
|
||||
auto EHFrameIt = llvm::find_if(OutputSections, HasOutputName(".eh_frame"));
|
||||
if (EHFrameHdrIt != OutputSections.end() &&
|
||||
EHFrameIt != OutputSections.end() && EHFrameIt < EHFrameHdrIt)
|
||||
std::rotate(EHFrameIt, EHFrameHdrIt, std::next(EHFrameHdrIt));
|
||||
|
||||
// Assign indices to sections.
|
||||
for (uint32_t Index = 1; Index < OutputSections.size(); ++Index)
|
||||
OutputSections[Index].first->setIndex(Index);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
# Check that llvm-bolt overwrites .eh_frame_hdr in-place.
|
||||
# Check that llvm-bolt overwrites .eh_frame_hdr in-place and keeps the
|
||||
# .eh_frame_hdr section header before .eh_frame when it has to create a new
|
||||
# header.
|
||||
|
||||
REQUIRES: system-linux
|
||||
|
||||
|
|
@ -6,7 +8,14 @@ RUN: %clang %cflags %p/Inputs/hello.c -o %t -Wl,-q
|
|||
RUN: llvm-bolt %t -o %t.bolt --use-old-text \
|
||||
RUN: | FileCheck %s --check-prefix=CHECK-BOLT
|
||||
RUN: llvm-readelf -WS %t.bolt | FileCheck %s
|
||||
RUN: touch %t.empty
|
||||
RUN: llvm-objcopy --update-section .eh_frame_hdr=%t.empty %t %t.small-hdr
|
||||
RUN: llvm-bolt %t.small-hdr -o %t.small-hdr.bolt
|
||||
RUN: llvm-readelf -WS %t.small-hdr.bolt | FileCheck %s --check-prefix=ORDER
|
||||
|
||||
CHECK-BOLT: rewriting .eh_frame_hdr in-place
|
||||
|
||||
CHECK-NOT: .bolt.org.eh_frame_hdr
|
||||
|
||||
ORDER: ] .eh_frame_hdr
|
||||
ORDER-NEXT: ] .eh_frame
|
||||
|
|
|
|||
Loading…
Reference in a new issue