[BOLT] Detect incorrect update of dynamic relocations (#89681)

When we rewrite dynamic relocations, there could be cases where they
reference code locations inside functions that were rewritten. When this
happens, we need to precisely map old address to a new one. Until we can
reliably perform the mapping, detect such condition and issue an error
refusing to write a broken binary.
This commit is contained in:
Maksim Panchenko
2024-04-24 14:03:33 -07:00
committed by GitHub
parent ea3eeb483f
commit 418e4b0c4f
5 changed files with 28 additions and 29 deletions

View File

@@ -5432,6 +5432,17 @@ uint64_t RewriteInstance::getNewFunctionOrDataAddress(uint64_t OldAddress) {
if (BD && BD->isMoved())
return BD->getOutputAddress();
if (const BinaryFunction *BF =
BC->getBinaryFunctionContainingAddress(OldAddress)) {
if (BF->isEmitted()) {
BC->errs() << "BOLT-ERROR: unable to get new address corresponding to "
"input address 0x"
<< Twine::utohexstr(OldAddress) << " in function " << *BF
<< ". Consider adding this function to --skip-funcs=...\n";
exit(1);
}
}
return 0;
}

View File

@@ -0,0 +1,16 @@
# Check that llvm-bolt fails to process PIC binaries with computed goto, as the
# support is not there yet for correctly updating dynamic relocations
# referencing code inside functions.
REQUIRES: x86_64-linux
RUN: %clang %S/Inputs/indirect_goto.c -o %t -fpic -pie -Wl,-q
RUN: not llvm-bolt %t -o %t.bolt --relocs=1 --print-cfg --print-only=main \
RUN: |& FileCheck %s
# Check that processing works if main() is skipped.
RUN: llvm-bolt %t -o %t.bolt --relocs=1 --skip-funcs=main
CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW
CHECK: BOLT-ERROR: unable to get new address

View File

@@ -53,6 +53,6 @@ end_if_1:
.size _start, .-_start
.data
rel: .quad end_if_1
rel: .quad _start
# CHECK: BOLT-INFO: Shrink wrapping moved 0 spills inserting load/stores and 0 spills inserting push/pops

View File

@@ -1,18 +0,0 @@
int main(int argc, char *argv[]) {
static const void *T1[] = { &&L1, &&L2 };
static const void *T2[] = { &&L2, &&L3 };
const void **T = (argc > 1) ? T1 : T2;
int i = 0;
L0:
goto *T[argc];
L1:
++i;
L2:
i++;
L3:
i++;
return i;
}

View File

@@ -1,10 +0,0 @@
# Check llvm-bolt processes binaries compiled from sources that use indirect goto.
REQUIRES: x86_64-linux
RUN: %clang %S/Inputs/indirect_goto.c -o %t -fpic -pie -Wl,-q
RUN: llvm-bolt %t -o %t.bolt --relocs=1 --print-cfg --print-only=main \
RUN: |& FileCheck %s
# The test fails as we don't update corresponding dynamic relocations.
RUN: not %t.bolt
CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW