[llvm] [BOLT] Flip the first and last bits of build ID (PR #214784)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 7 09:52:29 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-bolt

Author: YongKang Zhu (yozhu)

<details>
<summary>Changes</summary>

With only the last bit in a build ID flipped, some crash analysis or symbolication tools that derive module ID from the first 16 bytes are not able to differentiate pre- and post-BOLT libraries if both are archived. So besides the last bit, we now also flip the high bit of the first byte in a build ID.

---
Full diff: https://github.com/llvm/llvm-project/pull/214784.diff


2 Files Affected:

- (modified) bolt/lib/Rewrite/BuildIDRewriter.cpp (+5-4) 
- (added) bolt/test/build-id-patch.c (+17) 


``````````diff
diff --git a/bolt/lib/Rewrite/BuildIDRewriter.cpp b/bolt/lib/Rewrite/BuildIDRewriter.cpp
index 86524746c490f..2e6a679118aa0 100644
--- a/bolt/lib/Rewrite/BuildIDRewriter.cpp
+++ b/bolt/lib/Rewrite/BuildIDRewriter.cpp
@@ -96,10 +96,11 @@ Error BuildIDRewriter::postEmitFinalizer() {
   if (!BuildIDSection || !BuildIDOffset)
     return Error::success();
 
-  const uint8_t LastByte = BuildID[BuildID.size() - 1];
-  SmallVector<char, 1> Patch = {static_cast<char>(LastByte ^ 1)};
-  BuildIDSection->addPatch(*BuildIDOffset + BuildID.size() - 1, Patch);
-  BC.outs() << "BOLT-INFO: patched build-id (flipped last bit)\n";
+  SmallVector<char, 20> Patch(BuildID.begin(), BuildID.end());
+  Patch.front() ^= 0x80;
+  Patch.back() ^= 0x01;
+  BuildIDSection->addPatch(*BuildIDOffset, Patch);
+  BC.outs() << "BOLT-INFO: patched build-id (flipped first and last bits)\n";
 
   return Error::success();
 }
diff --git a/bolt/test/build-id-patch.c b/bolt/test/build-id-patch.c
new file mode 100644
index 0000000000000..f78a8a3ca75f6
--- /dev/null
+++ b/bolt/test/build-id-patch.c
@@ -0,0 +1,17 @@
+// Check that BOLT patches the build ID of the output binary so that it cannot
+// be mistaken for the input. The high bit of the first byte and the low bit of
+// the last byte are flipped.
+//
+// REQUIRES: system-linux
+
+// RUN: %clang %cflags -Wl,-q %s -o %t.exe \
+// RUN:   -Wl,--build-id=0x0123456789abcdef0123456789abcdef01234567
+// RUN: llvm-readelf -n %t.exe | FileCheck %s --check-prefix=CHECK-INPUT
+// RUN: llvm-bolt %t.exe -o %t.bolt | FileCheck %s --check-prefix=CHECK-BOLT
+// RUN: llvm-readelf -n %t.bolt | FileCheck %s --check-prefix=CHECK-OUTPUT
+
+// CHECK-INPUT: Build ID: 0123456789abcdef0123456789abcdef01234567
+// CHECK-BOLT: BOLT-INFO: patched build-id
+// CHECK-OUTPUT: Build ID: 8123456789abcdef0123456789abcdef01234566
+
+int main() { return 0; }

``````````

</details>


https://github.com/llvm/llvm-project/pull/214784


More information about the llvm-commits mailing list