[llvm] [llvm][llvm-objdump] Fix fatbin handling on 32-bit systems (PR #141620)

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Tue May 27 08:25:09 PDT 2025


https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/141620

Which fixes a test failure seen on the bots, introduced by https://github.com/llvm/llvm-project/pull/140286.
```
[ RUN      ] OffloadingBundleTest.checkExtractOffloadBundleFatBinary
ObjectTests: ../llvm/llvm/include/llvm/ADT/StringRef.h:618: StringRef llvm::StringRef::drop_front(size_t) const: Assertion `size() >= N && "Dropping more elements than exist"' failed.
0 0x0a24a990 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/tcwg-buildbot/worker/clang-armv8-quick/stage1/unittests/Object/./ObjectTests+0x31a990)
1 0x0a248364 llvm::sys::RunSignalHandlers() (/home/tcwg-buildbot/worker/clang-armv8-quick/stage1/unittests/Object/./ObjectTests+0x318364)
2 0x0a24b410 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
3 0xf46ed6f0 __default_rt_sa_restorer ./signal/../sysdeps/unix/sysv/linux/arm/sigrestorer.S:80:0
4 0xf46ddb06 ./csu/../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:47:0
5 0xf471d292 __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
6 0xf46ec840 gsignal ./signal/../sysdeps/posix/raise.c:27:6
```
Also reported on 32-bit x86.

I think the cause is the code was casting the result of StringRef.find into an int64_t. The failure value of find is StringRef::npos, which is defined as:
static constexpr size_t npos = ~size_t(0);

I think what happens is size_t(0) is 32 bits of 0s, inverted to 32 bits of 1s. This is then cast to int64_t, which you might think would sign extend from the most significant bit, but if it did not and just added 0s, then the result would always be > 0. So I could be wrong about the exact cause here, but switching to size_t throughout fixes the issue.

Also I don't see a reason it needs to be a signed number, given that it always searches forward from the current offset.

>From 9d8824ec4c80b6210771bb3f22d771cff04cd22b Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 27 May 2025 15:08:58 +0000
Subject: [PATCH] [llvm][llvm-objdump] Fix fatbin handling on 32-bit systems

Which fixes a test failure seen on the bots, introduced by
https://github.com/llvm/llvm-project/pull/140286.

[ RUN      ] OffloadingBundleTest.checkExtractOffloadBundleFatBinary
ObjectTests: ../llvm/llvm/include/llvm/ADT/StringRef.h:618: StringRef llvm::StringRef::drop_front(size_t) const: Assertion `size() >= N && "Dropping more elements than exist"' failed.
0 0x0a24a990 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/tcwg-buildbot/worker/clang-armv8-quick/stage1/unittests/Object/./ObjectTests+0x31a990)
1 0x0a248364 llvm::sys::RunSignalHandlers() (/home/tcwg-buildbot/worker/clang-armv8-quick/stage1/unittests/Object/./ObjectTests+0x318364)
2 0x0a24b410 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
3 0xf46ed6f0 __default_rt_sa_restorer ./signal/../sysdeps/unix/sysv/linux/arm/sigrestorer.S:80:0
4 0xf46ddb06 ./csu/../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:47:0
5 0xf471d292 __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
6 0xf46ec840 gsignal ./signal/../sysdeps/posix/raise.c:27:6

Also reported on 32-bit x86.

The cause is that the code was casting the result of StringRef.find
into an int64_t. The failure value of find is StringRef::npos, which
is defined as:
static constexpr size_t npos = ~size_t(0);

So making that into an int64_t means it is > 0 and the code continued
to search for bundles that didn't exist, at an offset beyond the largest
file we could handle.

I have changed the code to use size_t throughout, as this matches the
APIs used, and it does not search backwards in the file so the offset
does not need to be signed.
---
 llvm/lib/Object/OffloadBundle.cpp | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Object/OffloadBundle.cpp b/llvm/lib/Object/OffloadBundle.cpp
index 5f087a5c84e8d..239a3e2616ba5 100644
--- a/llvm/lib/Object/OffloadBundle.cpp
+++ b/llvm/lib/Object/OffloadBundle.cpp
@@ -38,12 +38,11 @@ Error extractOffloadBundle(MemoryBufferRef Contents, uint64_t SectionOffset,
                            StringRef FileName,
                            SmallVectorImpl<OffloadBundleFatBin> &Bundles) {
 
-  uint64_t Offset = 0;
-  int64_t NextbundleStart = 0;
+  size_t Offset = 0;
+  size_t NextbundleStart = 0;
 
   // There could be multiple offloading bundles stored at this section.
-  while (NextbundleStart >= 0) {
-
+  while (NextbundleStart != StringRef::npos) {
     std::unique_ptr<MemoryBuffer> Buffer =
         MemoryBuffer::getMemBuffer(Contents.getBuffer().drop_front(Offset), "",
                                    /*RequiresNullTerminator=*/false);
@@ -60,10 +59,9 @@ Error extractOffloadBundle(MemoryBufferRef Contents, uint64_t SectionOffset,
 
     // Find the next bundle by searching for the magic string
     StringRef Str = Buffer->getBuffer();
-    NextbundleStart =
-        (int64_t)Str.find(StringRef("__CLANG_OFFLOAD_BUNDLE__"), 24);
+    NextbundleStart = Str.find(StringRef("__CLANG_OFFLOAD_BUNDLE__"), 24);
 
-    if (NextbundleStart >= 0)
+    if (NextbundleStart != StringRef::npos)
       Offset += NextbundleStart;
   }
 



More information about the llvm-commits mailing list