[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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
16
bolt/test/X86/indirect-goto-pie.test
Normal file
16
bolt/test/X86/indirect-goto-pie.test
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user