[llvm] [BOLT] Do not fail in case of instrumentation binary without fini & fini_array & instrumentation-sleep-time>0 (PR #170086)
Vasily Leonenko via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 1 00:38:13 PST 2025
https://github.com/vleonen created https://github.com/llvm/llvm-project/pull/170086
This PR allows instrument binaries without the .fini and .fini_array entries if the user passes the `instrumentation-sleep-time` option.
The `.fini` or `.fini_array` entries are used to hook into the process finalization process and write a profile during finalization. However, with the `instrumentation-sleep-time` option, the profile should be written periodically, without the need for it to be written at finalization.
>From 14ae27780a4b7e6428746b1d75ca76992a6b08df Mon Sep 17 00:00:00 2001
From: Vasily Leonenko <vasiliy.leonenko at gmail.com>
Date: Sat, 29 Nov 2025 21:15:48 +0300
Subject: [PATCH] [BOLT] Do not fail in case of instrumentation binary without
fini & fini_array & instrumentation-sleep-time>0
---
bolt/lib/Rewrite/RewriteInstance.cpp | 12 ++++++++-
bolt/test/AArch64/instrument-no-fini.s | 34 ++++++++++++++++++++++++++
bolt/test/X86/instrument-no-fini.s | 34 ++++++++++++++++++++++++++
3 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 bolt/test/AArch64/instrument-no-fini.s
create mode 100644 bolt/test/X86/instrument-no-fini.s
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 1c6244b2d2bf8..b1314a48a4c22 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -80,6 +80,7 @@ namespace opts {
extern cl::list<std::string> HotTextMoveSections;
extern cl::opt<bool> Hugify;
extern cl::opt<bool> Instrument;
+extern cl::opt<uint32_t> InstrumentationSleepTime;
extern cl::opt<bool> KeepNops;
extern cl::opt<bool> Lite;
extern cl::list<std::string> PrintOnly;
@@ -1507,6 +1508,10 @@ Error RewriteInstance::discoverRtFiniAddress() {
}
if (!BC->FiniArrayAddress || !BC->FiniArraySize) {
+ // it is not mandatory to have finalization hooks if we have
+ // InstrumentationSleepTime>0
+ if (opts::InstrumentationSleepTime > 0)
+ return Error::success();
return createStringError(
std::errc::not_supported,
"Instrumentation needs either DT_FINI or DT_FINI_ARRAY");
@@ -1616,9 +1621,14 @@ Error RewriteInstance::updateRtFiniReloc() {
if (!RT || !RT->getRuntimeFiniAddress())
return Error::success();
- if (!BC->FiniArrayAddress || !BC->FiniArraySize)
+ if (!BC->FiniArrayAddress || !BC->FiniArraySize) {
+ // it is not mandatory to have finalization hooks if we have
+ // InstrumentationSleepTime>0
+ if (opts::InstrumentationSleepTime > 0)
+ return Error::success();
return createStringError(std::errc::not_supported,
"inconsistent .fini_array state");
+ }
ErrorOr<BinarySection &> FiniArraySection =
BC->getSectionForAddress(*BC->FiniArrayAddress);
diff --git a/bolt/test/AArch64/instrument-no-fini.s b/bolt/test/AArch64/instrument-no-fini.s
new file mode 100644
index 0000000000000..526ce11080f4f
--- /dev/null
+++ b/bolt/test/AArch64/instrument-no-fini.s
@@ -0,0 +1,34 @@
+# Test that BOLT will produce error by default and pass with instrumentation-sleep-time option
+
+# REQUIRES: system-linux,bolt-runtime,target=aarch64{{.*}}
+
+# RUN: llvm-mc -triple aarch64 -filetype=obj %s -o %t.o
+# RUN: ld.lld -q -pie -o %t.exe %t.o
+# RUN: llvm-readelf -d %t.exe | FileCheck --check-prefix=CHECK-NO-FINI %s
+# RUN: not llvm-bolt --instrument -o %t.out %t.exe 2>&1 | FileCheck %s --check-prefix=CHECK-BOLT-FAIL
+# RUN: llvm-bolt --instrument --instrumentation-sleep-time=1 -o %t.out %t.exe 2>&1 | FileCheck %s --check-prefix=CHECK-BOLT-PASS
+
+# CHECK-NO-FINI: INIT
+# CHECK-NO-FINI-NOT: FINI
+# CHECK-NO-FINI-NOT: FINI_ARRAY
+
+# CHECK-BOLT-FAIL: Instrumentation needs either DT_FINI or DT_FINI_ARRAY
+
+# CHECK-BOLT-PASS-NOT: Instrumentation needs either DT_FINI or DT_FINI_ARRAY
+# CHECK-BOLT-PASS: runtime library initialization was hooked via DT_INIT
+
+ .text
+ .globl _start
+ .type _start, %function
+_start:
+ # BOLT errs when instrumenting without relocations; create a dummy one.
+ .reloc 0, R_AARCH64_NONE
+ ret
+ .size _start, .-_start
+
+ .globl _init
+ .type _init, %function
+ # Force DT_INIT to be created (needed for instrumentation).
+_init:
+ ret
+ .size _init, .-_init
diff --git a/bolt/test/X86/instrument-no-fini.s b/bolt/test/X86/instrument-no-fini.s
new file mode 100644
index 0000000000000..fff23761d1499
--- /dev/null
+++ b/bolt/test/X86/instrument-no-fini.s
@@ -0,0 +1,34 @@
+# Test that BOLT will produce error by default and pass with instrumentation-sleep-time option
+
+# REQUIRES: system-linux,bolt-runtime,target=x86_64-{{.*}}
+
+# RUN: llvm-mc -triple x86_64 -filetype=obj %s -o %t.o
+# RUN: ld.lld -q -pie -o %t.exe %t.o
+# RUN: llvm-readelf -d %t.exe | FileCheck --check-prefix=CHECK-NO-FINI %s
+# RUN: not llvm-bolt --instrument -o %t.out %t.exe 2>&1 | FileCheck %s --check-prefix=CHECK-BOLT-FAIL
+# RUN: llvm-bolt --instrument --instrumentation-sleep-time=1 -o %t.out %t.exe 2>&1 | FileCheck %s --check-prefix=CHECK-BOLT-PASS
+
+# CHECK-NO-FINI: INIT
+# CHECK-NO-FINI-NOT: FINI
+# CHECK-NO-FINI-NOT: FINI_ARRAY
+
+# CHECK-BOLT-FAIL: Instrumentation needs either DT_FINI or DT_FINI_ARRAY
+
+# CHECK-BOLT-PASS-NOT: Instrumentation needs either DT_FINI or DT_FINI_ARRAY
+# CHECK-BOLT-PASS: runtime library initialization was hooked via DT_INIT
+
+ .text
+ .globl _start
+ .type _start, %function
+_start:
+ # BOLT errs when instrumenting without relocations; create a dummy one.
+ .reloc 0, R_X86_64_NONE
+ retq
+ .size _start, .-_start
+
+ .globl _init
+ .type _init, %function
+ # Force DT_INIT to be created (needed for instrumentation).
+_init:
+ retq
+ .size _init, .-_init
More information about the llvm-commits
mailing list