Skip to content

Conversation

@david-salinas
Copy link
Contributor

This commit creates llvm-extract-bundle-entry as a wrapper to llvm-objcopy,
to allow extracting HIP offload fatbin bundles given a URI argument.

@llvmbot
Copy link
Member

llvmbot commented Nov 24, 2025

@llvm/pr-subscribers-llvm-binary-utilities

Author: David Salinas (david-salinas)

Changes

This commit creates llvm-extract-bundle-entry as a wrapper to llvm-objcopy,
to allow extracting HIP offload fatbin bundles given a URI argument.


Patch is 32.21 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/169386.diff

8 Files Affected:

  • (modified) llvm/include/llvm/Object/OffloadBundle.h (+2-2)
  • (modified) llvm/lib/Object/OffloadBundle.cpp (+21-7)
  • (added) llvm/test/tools/llvm-objcopy/extract-bundle-entry.test (+74)
  • (modified) llvm/tools/llvm-objcopy/CMakeLists.txt (+6)
  • (added) llvm/tools/llvm-objcopy/ExtractBundleEntryOpts.td (+31)
  • (modified) llvm/tools/llvm-objcopy/ObjcopyOptions.cpp (+88-1)
  • (modified) llvm/tools/llvm-objcopy/ObjcopyOptions.h (+10)
  • (modified) llvm/tools/llvm-objcopy/llvm-objcopy.cpp (+2)
diff --git a/llvm/include/llvm/Object/OffloadBundle.h b/llvm/include/llvm/Object/OffloadBundle.h
index bbb313c06c441..24be9397f8d84 100644
--- a/llvm/include/llvm/Object/OffloadBundle.h
+++ b/llvm/include/llvm/Object/OffloadBundle.h
@@ -210,8 +210,8 @@ LLVM_ABI Error extractOffloadBundleFatBinary(
 
 /// Extract code object memory from the given \p Source object file at \p Offset
 /// and of \p Size, and copy into \p OutputFileName.
-LLVM_ABI Error extractCodeObject(const ObjectFile &Source, int64_t Offset,
-                                 int64_t Size, StringRef OutputFileName);
+LLVM_ABI Error extractCodeObject(const ObjectFile &Source, size_t Offset,
+                                 size_t Size, StringRef OutputFileName);
 
 /// Extract code object memory from the given \p Source object file at \p Offset
 /// and of \p Size, and copy into \p OutputFileName.
diff --git a/llvm/lib/Object/OffloadBundle.cpp b/llvm/lib/Object/OffloadBundle.cpp
index 046cde8640b49..9988e70858ef9 100644
--- a/llvm/lib/Object/OffloadBundle.cpp
+++ b/llvm/lib/Object/OffloadBundle.cpp
@@ -217,24 +217,37 @@ Error object::extractOffloadBundleFatBinary(
   return Error::success();
 }
 
-Error object::extractCodeObject(const ObjectFile &Source, int64_t Offset,
-                                int64_t Size, StringRef OutputFileName) {
+Error object::extractCodeObject(const ObjectFile &Source, size_t Offset,
+                                size_t Size, StringRef OutputFileName) {
   Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
       FileOutputBuffer::create(OutputFileName, Size);
 
-  if (!BufferOrErr)
-    return BufferOrErr.takeError();
+  if (auto EC = BufferOrErr.takeError())
+    return std::move(EC);
 
   Expected<MemoryBufferRef> InputBuffOrErr = Source.getMemoryBufferRef();
   if (Error Err = InputBuffOrErr.takeError())
-    return Err;
+    return createFileError(OutputFileName, std::move(Err));
+  ;
+
+  if (Size > InputBuffOrErr->getBufferSize())
+    return createStringError("size in URI is larger than source");
+
+  if (Offset > InputBuffOrErr->getBufferSize())
+    return createStringError(inconvertibleErrorCode(),
+                             "offset in URI is beyond the size of the source");
+
+  if (Offset + Size > InputBuffOrErr->getBufferSize())
+    return createStringError(
+        inconvertibleErrorCode(),
+        "offset + size in URI is beyond the size of the source");
 
   std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
   std::copy(InputBuffOrErr->getBufferStart() + Offset,
             InputBuffOrErr->getBufferStart() + Offset + Size,
             Buf->getBufferStart());
   if (Error E = Buf->commit())
-    return E;
+    return createFileError(OutputFileName, std::move(E));
 
   return Error::success();
 }
@@ -259,6 +272,7 @@ Error object::extractOffloadBundleByURI(StringRef URIstr) {
   // create a URI object
   Expected<std::unique_ptr<OffloadBundleURI>> UriOrErr(
       OffloadBundleURI::createOffloadBundleURI(URIstr, FILE_URI));
+
   if (!UriOrErr)
     return UriOrErr.takeError();
 
@@ -275,7 +289,7 @@ Error object::extractOffloadBundleByURI(StringRef URIstr) {
   auto Obj = ObjOrErr->getBinary();
   if (Error Err =
           object::extractCodeObject(*Obj, Uri.Offset, Uri.Size, OutputFile))
-    return Err;
+    return createFileError(Uri.FileName, std::move(Err));
 
   return Error::success();
 }
diff --git a/llvm/test/tools/llvm-objcopy/extract-bundle-entry.test b/llvm/test/tools/llvm-objcopy/extract-bundle-entry.test
new file mode 100644
index 0000000000000..25aa6f1e9271b
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/extract-bundle-entry.test
@@ -0,0 +1,74 @@
+## Test llvm-extract-bundle-entry
+# REQUIRES: target={{x86_64-.*-linux.*}}
+# REQUIRES: amdgpu-registered-target
+
+# RUN: yaml2obj %s -o %t.elf
+# RUN: llvm-extract-bundle-entry file://%t.elf#offset=8192\&size=4048
+# RUN: llvm-objdump -d %t.elf-offset8192-size4048.co  | FileCheck %s
+
+# RUN: not llvm-extract-bundle-entry file://%t.elf#offset=8192\&size=4048000 2>&1 | \
+# RUN:  FileCheck %s --check-prefix=ERR1
+
+# RUN: not llvm-extract-bundle-entry file://%t.elf#offset=819200000\&size=4048 2>&1 | \
+# RUN:  FileCheck %s --check-prefix=ERR2
+
+# RUN: not llvm-extract-bundle-entry file://%t.elf#offset=8192\&size=8048 2>&1 | \
+# RUN:  FileCheck %s --check-prefix=ERR3
+
+# CHECK:        s_load_dword s7, s[4:5], 0x24                              // 000000001900: C00201C2 00000024
+# CHECK-NEXT:        s_load_dwordx4 s[0:3], s[4:5], 0x0                         // 000000001908: C00A0002 00000000
+# CHECK-NEXT:        v_mov_b32_e32 v1, 0                                        // 000000001910: 7E020280
+# CHECK-NEXT:        s_waitcnt lgkmcnt(0)                                       // 000000001914: BF8CC07F
+# CHECK-NEXT:        s_and_b32 s4, s7, 0xffff                                   // 000000001918: 8604FF07 0000FFFF
+# CHECK-NEXT:        s_mul_i32 s6, s6, s4                                       // 000000001920: 92060406
+# CHECK-NEXT:        v_add_u32_e32 v0, s6, v0                                   // 000000001924: 68000006
+# CHECK-NEXT:        v_lshlrev_b64 v[0:1], 2, v[0:1]                            // 000000001928: D28F0000 00020082
+# CHECK-NEXT:        v_mov_b32_e32 v3, s3                                       // 000000001930: 7E060203
+# CHECK-NEXT:        v_add_co_u32_e32 v2, vcc, s2, v0                           // 000000001934: 32040002
+# CHECK-NEXT:        v_addc_co_u32_e32 v3, vcc, v3, v1, vcc                     // 000000001938: 38060303
+# CHECK-NEXT:        global_load_dword v2, v[2:3], off                          // 00000000193C: DC508000 027F0002
+# CHECK-NEXT:        v_mov_b32_e32 v3, s1                                       // 000000001944: 7E060201
+# CHECK-NEXT:        v_add_co_u32_e32 v0, vcc, s0, v0                           // 000000001948: 32000000
+# CHECK-NEXT:        v_addc_co_u32_e32 v1, vcc, v3, v1, vcc                     // 00000000194C: 38020303
+# CHECK-NEXT:        global_load_dword v3, v[0:1], off                          // 000000001950: DC508000 037F0000
+# CHECK-NEXT:        s_waitcnt vmcnt(0)                                         // 000000001958: BF8C0F70
+# CHECK-NEXT:        v_add_u32_e32 v2, v3, v2                                   // 00000000195C: 68040503
+# CHECK-NEXT:        global_store_dword v[0:1], v2, off                         // 000000001960: DC708000 007F0200
+# CHECK-NEXT:        s_endpgm                                                   // 000000001968: BF810000
+
+# ERR1: size in URI is larger than source
+# ERR2: offset in URI is beyond the size of the source
+# ERR3: offset + size in URI is beyond the size of the source
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x2041B0
+ProgramHeaders:
+  - Type:            PT_PHDR
+    Flags:           [ PF_R ]
+    VAddr:           0x200040
+    Align:           0x8
+    Offset:          0x40
+  - Type:            PT_GNU_STACK
+    Flags:           [ PF_W, PF_R ]
+    Align:           0x0
+    Offset:          0x0
+Sections:
+  - Name:            .hip_fatbin
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x201000
+    AddressAlign:    0x1000
+    Content:         5F5F434C414E475F4F46464C4F41445F42554E444C455F5F0200000000000000001000000000000000000000000000001B00000000000000686F73742D7838365F36342D756E6B6E6F776E2D6C696E75782D2D0010000000000000D00F0000000000001F0000000000000068697076342D616D6467636E2D616D642D616D646873612D2D676678393038000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007F454C460201014003000000000000000300E0000100000000000000000000004000000000000000100C0000000000003005000040003800090040000F000D000600000004000000400000000000000040000000000000004000000000000000F801000000000000F80100000000000008000000000000000100000004000000000000000000000000000000000000000000000000000000C008000000000000C008000000000000001000000000000001000000050000000009000000000000001900000000000000190000000000006C000000000000006C00000000000000001000000000000001000000060000007009000000000000702900000000000070290000000000007000000000000000900600000000000000100000000000000100000006000000E009000000000000E039000000000000E039000000000000000000000000000001000000000000000010000000000000020000000600000070090000000000007029000000000000702900000000000070000000000000007000000000000000080000000000000052E574640400000070090000000000007029000000000000702900000000000070000000000000009006000000000000010000000000000051E57464060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000004000000380200000000000038020000000000003802000000000000340500000000000034050000000000000400000000000000070000001D05000020000000414D44475055000083AE616D646873612E6B65726E656C7391DE0012AB2E616770725F636F756E7400A52E61726773DC001085AE2E616464726573735F7370616365A6676C6F62616CA52E6E616D65AA415F642E636F65726365A72E6F666673657400A52E73697A6508AB2E76616C75655F6B696E64AD676C6F62616C5F62756666657285AE2E616464726573735F7370616365A6676C6F62616CA52E6E616D65AA425F642E636F65726365A72E6F666673657408A52E73697A6508AB2E76616C75655F6B696E64AD676C6F62616C5F62756666657284A52E6E616D65A14EA72E6F666673657410A52E73697A6508AB2E76616C75655F6B696E64A862795F76616C756583A72E6F666673657418A52E73697A6504AB2E76616C75655F6B696E64B468696464656E5F626C6F636B5F636F756E745F7883A72E6F66667365741CA52E73697A6504AB2E76616C75655F6B696E64B468696464656E5F626C6F636B5F636F756E745F7983A72E6F666673657420A52E73697A6504AB2E76616C75655F6B696E64B468696464656E5F626C6F636B5F636F756E745F7A83A72E6F666673657424A52E73697A6502AB2E76616C75655F6B696E64B368696464656E5F67726F75705F73697A655F7883A72E6F666673657426A52E73697A6502AB2E76616C75655F6B696E64B368696464656E5F67726F75705F73697A655F7983A72E6F666673657428A52E73697A6502AB2E76616C75655F6B696E64B368696464656E5F67726F75705F73697A655F7A83A72E6F66667365742AA52E73697A6502AB2E76616C75655F6B696E64B268696464656E5F72656D61696E6465725F7883A72E6F66667365742CA52E73697A6502AB2E76616C75655F6B696E64B268696464656E5F72656D61696E6465725F7983A72E6F66667365742EA52E73697A6502AB2E76616C75655F6B696E64B268696464656E5F72656D61696E6465725F7A83A72E6F666673657440A52E73697A6508AB2E76616C75655F6B696E64B668696464656E5F676C6F62616C5F6F66667365745F7883A72E6F666673657448A52E73697A6508AB2E76616C75655F6B696E64B668696464656E5F676C6F62616C5F6F66667365745F7983A72E6F666673657450A52E73697A6508AB2E76616C75655F6B696E64B668696464656E5F676C6F62616C5F6F66667365745F7A83A72E6F666673657458A52E73697A6502AB2E76616C75655F6B696E64B068696464656E5F677269645F64696D73B92E67726F75705F7365676D656E745F66697865645F73697A6500B62E6B65726E6172675F7365676D656E745F616C69676E08B52E6B65726E6172675F7365676D656E745F73697A65CD0118A92E6C616E6775616765A84F70656E434C2043B12E6C616E67756167655F76657273696F6E920200B82E6D61785F666C61745F776F726B67726F75705F73697A65CD0400A52E6E616D65B25F5A3973696D706C65416464506A504B6A6DBB2E707269766174655F7365676D656E745F66697865645F73697A6500AB2E736770725F636F756E740CB12E736770725F7370696C6C5F636F756E7400A72E73796D626F6CB55F5A3973696D706C65416464506A504B6A6D2E6B64B82E756E69666F726D5F776F726B5F67726F75705F73697A6501B32E757365735F64796E616D69635F737461636BC2AB2E766770725F636F756E7404B12E766770725F7370696C6C5F636F756E7400AF2E7761766566726F6E745F73697A6540AD616D646873612E746172676574B9616D6467636E2D616D642D616D646873612D2D676678393038AE616D646873612E76657273696F6E92010200000000000000000000000000000000000000000000000000000000000000010000001203070000190000000000006C000000000000001400000011030600800800000000000040000000000000002A00000011000A00E03900000000000001000000000000000100000001000000010000001A000000000008400000D20001000000360A4A7A5238A4D3F113F4DD04000000040000000200000001000000000000000300000000000000000000000000000000000000005F5A3973696D706C65416464506A504B6A6D005F5A3973696D706C65416464506A504B6A6D2E6B64005F5F6869705F637569645F623730363264386333326134613933330000000000000000000000000000000000000000000000000000000000000000000000180100000000000080100000000000000000000000000000000000000000000000000000000000004000AF008C000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C20102C02400000002000AC0000000008002027E7FC08CBF07FF0486FFFF0000060406920600006800008FD2820002000302067E0200043203030638008050DC02007F020102067E0000003203030238008050DC00007F03700F8CBF03050468008070DC00027F00000081BF00000000060000000000000070070000000000000B000000000000001800000000000000050000000000000...
[truncated]

@github-actions
Copy link

github-actions bot commented Nov 24, 2025

🐧 Linux x64 Test Results

  • 186571 tests passed
  • 4886 tests skipped

@david-salinas david-salinas force-pushed the llvm-extract-bundle-entry branch 2 times, most recently from 4491674 to ed63bd5 Compare November 24, 2025 20:43
@david-salinas david-salinas requested a review from lamb-j November 25, 2025 16:26
  This commit creates llvm-extract-bundle-entry as a wrapper to llvm-objcopy,
  to allow extracting HIP offload fatbin bundles given a URI argument.
@lamb-j
Copy link
Contributor

lamb-j commented Nov 25, 2025

Re-work of #143347

Copy link
Contributor

@lamb-j lamb-j left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but we should wait for others to review as well

This allows us to get the behavior we want without modifying the expected behavior of stand-alone llvm-objdump. And it more closely mimics the behavior of the tools it's intending to replace (roc-obj-ls, roc-obj-extract)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants