Skip to content

Commit fe4d176

Browse files
[WORKAROUND][BOLT][AArch64] Static binary patching for ELF.
When patching statically linked binaries, avoid patching GOT entries that did not belong to the original text section and had an alias. One such special case is the '_init' function that belongs to the '.init' section. It has '.init' as an alias, which points to the same address of '_init' in the original binary. This was observed with GNU linker. BOLT normally rejects these cases. See issue: #100096
1 parent a9962ed commit fe4d176

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5265,6 +5265,34 @@ void RewriteInstance::patchELFGOT(ELFObjectFile<ELFT> *File) {
52655265
GOTContents.size());
52665266
++GOTEntry) {
52675267
if (uint64_t NewAddress = getNewFunctionAddress(*GOTEntry)) {
5268+
auto *Function = BC->getBinaryFunctionAtAddress(*GOTEntry);
5269+
5270+
// WORKAROUND:
5271+
// Background:
5272+
// Static binaries generated with GNU linker have GOT entries, which is
5273+
// wrong. LLD does not suffer from this. See related discussion:
5274+
// https://github.com/llvm/llvm-project/issues/100096
5275+
//
5276+
// The current approach is for BOLT to abort when a static binary contains
5277+
// such entries. However, this patch may serve as a 'Workaround' in case
5278+
// someone has encountered such a binary. ATTOW it is unclear if/when GNU
5279+
// linker will have this fixed.
5280+
//
5281+
// The workaround:
5282+
// On static binaries, avoid patching the "_init" got entry. It also
5283+
// checks that it does not belong to the original text section and that it
5284+
// an alias. This function actually aliases '.init', belongs to the
5285+
// '.init' section, and points to the same address of '_init' in the
5286+
// original binary.
5287+
if (BC->IsStaticExecutable && !Function->Aliases.empty() &&
5288+
Function->getOriginSectionName() != ".bolt.org.text" &&
5289+
(Function->getOneName() == "_init")) {
5290+
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: ignoring GOT entry 0x"
5291+
<< Twine::utohexstr(*GOTEntry) << " for '"
5292+
<< Function->getOneName() << "'" << '\n');
5293+
continue;
5294+
}
5295+
52685296
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: patching GOT entry 0x"
52695297
<< Twine::utohexstr(*GOTEntry) << " with 0x"
52705298
<< Twine::utohexstr(NewAddress) << '\n');

bolt/test/AArch64/patch-elfstatic-libc.test

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ REQUIRES: system-linux
1111

1212
RUN: %clang %p/../Inputs/main.c -o %t -Wl,-q -static
1313
RUN: llvm-bolt %t -o %t.bolt > /dev/null 2>&1
14-
RUN: not --crash %t.bolt 2>&1 | FileCheck %s
15-
CHECK: Unexpected reloc type in static binary.
14+
RUN: not %t.bolt 2>&1 | FileCheck %s --allow-empty
15+
16+
CHECK-NOT: Unexpected reloc type in static binary.

0 commit comments

Comments
 (0)