[flang-commits] [clang] [flang] [llvm] [Offload] Rename and move 'clang-offload-packager' -> 'llvm-offload-binary' (PR #161438)

Joseph Huber via flang-commits flang-commits at lists.llvm.org
Fri Oct 3 06:52:32 PDT 2025


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/161438

>From c5d7a781a0dc03d10e1d5f0e5692c2b00a416e2c Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Tue, 30 Sep 2025 15:32:19 -0500
Subject: [PATCH] [Offload] Rename and move 'clang-offload-packager' ->
 'llvm-offload-binary'

Summary:
This tool is pretty much a generic interface into creating and managing
the offloading binary format. The binary format itself is just a fat
binary block used to create heterogeneous objects. This should be made
more general than just `clang` since it's likely going to be used for
larger offloading projects and is the expected way to extract
heterogeneous objects from offloading code.

Relatively straightforward rename, a few tweaks and documentation
changes. Kept in `clang-offload-packager` for legacy compatibility as we
looked this tool up by name in places, will probably delete it next
release.
---
 clang/docs/ClangOffloadPackager.rst           | 193 ------------------
 clang/lib/Driver/Action.cpp                   |   2 +-
 clang/lib/Driver/ToolChains/Clang.h           |   2 +-
 clang/test/CMakeLists.txt                     |   2 +-
 .../Driver/amdgpu-openmp-sanitize-options.c   |   2 +-
 clang/test/Driver/amdgpu-openmp-toolchain.c   |   4 +-
 clang/test/Driver/cuda-phases.cu              |   4 +-
 clang/test/Driver/hip-phases.hip              |   4 +-
 clang/test/Driver/hip-toolchain-no-rdc.hip    |   4 +-
 clang/test/Driver/linker-wrapper-image.c      |   8 +-
 clang/test/Driver/linker-wrapper.c            |  48 ++---
 clang/test/Driver/offload-packager.c          |  20 +-
 clang/test/Driver/openmp-offload-gpu.c        |   6 +-
 clang/test/Driver/openmp-offload-jit.c        |   2 +-
 clang/test/Driver/openmp-offload.c            |   6 +-
 clang/test/Driver/spirv-openmp-toolchain.c    |   2 +-
 clang/test/Driver/sycl-offload-jit.cpp        |   6 +-
 .../clang-linker-wrapper-spirv-elf.cpp        |   2 +-
 clang/test/lit.cfg.py                         |   2 +-
 clang/tools/CMakeLists.txt                    |   1 -
 .../clang-offload-packager/CMakeLists.txt     |  17 --
 flang/test/Driver/omp-driver-offload.f90      |   2 +-
 llvm/docs/CommandGuide/index.rst              |   1 +
 .../docs/CommandGuide/llvm-offload-binary.rst | 185 +++++++++++++++++
 llvm/runtimes/CMakeLists.txt                  |   8 +-
 llvm/test/CMakeLists.txt                      |   1 +
 .../llvm-offload-binary.ll                    |  10 +
 llvm/tools/llvm-offload-binary/CMakeLists.txt |  13 ++
 .../llvm-offload-binary.cpp                   |  40 ++--
 .../tools/clang-offload-packager/BUILD.gn     |  10 -
 .../gn/secondary/clang/tools/driver/BUILD.gn  |   1 -
 31 files changed, 298 insertions(+), 310 deletions(-)
 delete mode 100644 clang/docs/ClangOffloadPackager.rst
 delete mode 100644 clang/tools/clang-offload-packager/CMakeLists.txt
 create mode 100644 llvm/docs/CommandGuide/llvm-offload-binary.rst
 create mode 100644 llvm/test/tools/llvm-offload-binary/llvm-offload-binary.ll
 create mode 100644 llvm/tools/llvm-offload-binary/CMakeLists.txt
 rename clang/tools/clang-offload-packager/ClangOffloadPackager.cpp => llvm/tools/llvm-offload-binary/llvm-offload-binary.cpp (90%)
 delete mode 100644 llvm/utils/gn/secondary/clang/tools/clang-offload-packager/BUILD.gn

diff --git a/clang/docs/ClangOffloadPackager.rst b/clang/docs/ClangOffloadPackager.rst
deleted file mode 100644
index 481069b5e4235..0000000000000
--- a/clang/docs/ClangOffloadPackager.rst
+++ /dev/null
@@ -1,193 +0,0 @@
-======================
-Clang Offload Packager
-======================
-
-.. contents::
-   :local:
-
-.. _clang-offload-packager:
-
-Introduction
-============
-
-This tool bundles device files into a single image containing necessary
-metadata. We use a custom binary format for bundling all the device images
-together. The image format is a small header wrapping around a string map. This
-tool creates bundled binaries so that they can be embedded into the host to
-create a fat-binary.
-
-Binary Format
-=============
-
-The binary format is marked by the ``0x10FF10AD`` magic bytes, followed by a
-version. Each created binary contains its own magic bytes. This allows us to
-locate all the embedded offloading sections even after they may have been merged
-by the linker, such as when using relocatable linking. Conceptually, this binary
-format is a serialization of a string map and an image buffer. The binary header
-is described in the following :ref:`table<table-binary_header>`.
-
-.. table:: Offloading Binary Header
-    :name: table-binary_header
-
-    +----------+--------------+----------------------------------------------------+
-    |   Type   |  Identifier  | Description                                        |
-    +==========+==============+====================================================+
-    | uint8_t  |    magic     | The magic bytes for the binary format (0x10FF10AD) |
-    +----------+--------------+----------------------------------------------------+
-    | uint32_t |   version    | Version of this format (currently version 1)       |
-    +----------+--------------+----------------------------------------------------+
-    | uint64_t |    size      | Size of this binary in bytes                       |
-    +----------+--------------+----------------------------------------------------+
-    | uint64_t | entry offset | Absolute offset of the offload entries in bytes    |
-    +----------+--------------+----------------------------------------------------+
-    | uint64_t |  entry size  | Size of the offload entries in bytes               |
-    +----------+--------------+----------------------------------------------------+
-
-Once identified through the magic bytes, we use the size field to take a slice
-of the binary blob containing the information for a single offloading image. We
-can then use the offset field to find the actual offloading entries containing
-the image and metadata. The offload entry contains information about the device
-image. It contains the fields shown in the following
-:ref:`table<table-binary_entry>`.
-
-.. table:: Offloading Entry Table
-    :name: table-binary_entry
-
-    +----------+---------------+----------------------------------------------------+
-    |   Type   |   Identifier  | Description                                        |
-    +==========+===============+====================================================+
-    | uint16_t |  image kind   | The kind of the device image (e.g. bc, cubin)      |
-    +----------+---------------+----------------------------------------------------+
-    | uint16_t | offload kind  | The producer of the image (e.g. openmp, cuda)      |
-    +----------+---------------+----------------------------------------------------+
-    | uint32_t |     flags     | Generic flags for the image                        |
-    +----------+---------------+----------------------------------------------------+
-    | uint64_t | string offset | Absolute offset of the string metadata table       |
-    +----------+---------------+----------------------------------------------------+
-    | uint64_t |  num strings  | Number of string entries in the table              |
-    +----------+---------------+----------------------------------------------------+
-    | uint64_t |  image offset | Absolute offset of the device image in bytes       |
-    +----------+---------------+----------------------------------------------------+
-    | uint64_t |   image size  | Size of the device image in bytes                  |
-    +----------+---------------+----------------------------------------------------+
-
-This table contains the offsets of the string table and the device image itself
-along with some other integer information. The image kind lets us easily
-identify the type of image stored here without needing to inspect the binary.
-The offloading kind is used to determine which registration code or linking
-semantics are necessary for this image. These are stored as enumerations with
-the following values for the :ref:`offload kind<table-offload_kind>` and the
-:ref:`image kind<table-image_kind>`.
-
-.. table:: Image Kind
-    :name: table-image_kind
-
-    +---------------+-------+---------------------------------------+
-    |      Name     | Value | Description                           |
-    +===============+=======+=======================================+
-    | IMG_None      | 0x00  | No image information provided         |
-    +---------------+-------+---------------------------------------+
-    | IMG_Object    | 0x01  | The image is a generic object file    |
-    +---------------+-------+---------------------------------------+
-    | IMG_Bitcode   | 0x02  | The image is an LLVM-IR bitcode file  |
-    +---------------+-------+---------------------------------------+
-    | IMG_Cubin     | 0x03  | The image is a CUDA object file       |
-    +---------------+-------+---------------------------------------+
-    | IMG_Fatbinary | 0x04  | The image is a CUDA fatbinary file    |
-    +---------------+-------+---------------------------------------+
-    | IMG_PTX       | 0x05  | The image is a CUDA PTX file          |
-    +---------------+-------+---------------------------------------+
-
-.. table:: Offload Kind
-    :name: table-offload_kind
-
-    +------------+-------+---------------------------------------+
-    |      Name  | Value | Description                           |
-    +============+=======+=======================================+
-    | OFK_None   | 0x00  | No offloading information provided    |
-    +------------+-------+---------------------------------------+
-    | OFK_OpenMP | 0x01  | The producer was OpenMP offloading    |
-    +------------+-------+---------------------------------------+
-    | OFK_CUDA   | 0x02  | The producer was CUDA                 |
-    +------------+-------+---------------------------------------+
-    | OFK_HIP    | 0x03  | The producer was HIP                  |
-    +------------+-------+---------------------------------------+
-    | OFK_SYCL   | 0x04  | The producer was SYCL                 |
-    +------------+-------+---------------------------------------+
-
-The flags are used to signify certain conditions, such as the presence of
-debugging information or whether or not LTO was used. The string entry table is
-used to generically contain any arbitrary key-value pair. This is stored as an
-array of the :ref:`string entry<table-binary_string>` format.
-
-.. table:: Offloading String Entry
-    :name: table-binary_string
-
-    +----------+--------------+-------------------------------------------------------+
-    |   Type   |   Identifier | Description                                           |
-    +==========+==============+=======================================================+
-    | uint64_t |  key offset  | Absolute byte offset of the key in the string table   |
-    +----------+--------------+-------------------------------------------------------+
-    | uint64_t | value offset | Absolute byte offset of the value in the string table |
-    +----------+--------------+-------------------------------------------------------+
-
-The string entries simply provide offsets to a key and value pair in the
-binary images string table. The string table is simply a collection of null
-terminated strings with defined offsets in the image. The string entry allows us
-to create a key-value pair from this string table. This is used for passing
-arbitrary arguments to the image, such as the triple and architecture.
-
-All of these structures are combined to form a single binary blob, the order
-does not matter because of the use of absolute offsets. This makes it easier to
-extend in the future. As mentioned previously, multiple offloading images are
-bundled together by simply concatenating them in this format. Because we have
-the magic bytes and size of each image, we can extract them as-needed.
-
-Usage
-=====
-
-This tool can be used with the following arguments. Generally information is
-passed as a key-value pair to the ``image=`` argument. The ``file`` and
-``triple``, arguments are considered mandatory to make a valid image.
-The ``arch`` argument is suggested.
-
-.. code-block:: console
-
-  OVERVIEW: A utility for bundling several object files into a single binary.
-  The output binary can then be embedded into the host section table
-  to create a fatbinary containing offloading code.
-
-  USAGE: clang-offload-packager [options]
-
-  OPTIONS:
-
-  Generic Options:
-
-    --help                      - Display available options (--help-hidden for more)
-    --help-list                 - Display list of available options (--help-list-hidden for more)
-    --version                   - Display the version of this program
-
-  clang-offload-packager options:
-
-    --image=<<key>=<value>,...> - List of key and value arguments. Required
-                                  keywords are 'file' and 'triple'.
-    -o <file>                   - Write output to <file>.
-
-Example
-=======
-
-This tool simply takes many input files from the ``image`` option and creates a
-single output file with all the images combined.
-
-.. code-block:: console
-
-  clang-offload-packager -o out.bin --image=file=input.o,triple=nvptx64,arch=sm_70
-
-The inverse operation can be performed instead by passing the packaged binary as
-input. In this mode the matching images will either be placed in the output
-specified by the ``file`` option. If no ``file`` argument is provided a name
-will be generated for each matching image.
-
-.. code-block:: console
-
-  clang-offload-packager in.bin --image=file=output.o,triple=nvptx64,arch=sm_70
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp
index e19daa9cb7abf..72a42a6f957ee 100644
--- a/clang/lib/Driver/Action.cpp
+++ b/clang/lib/Driver/Action.cpp
@@ -43,7 +43,7 @@ const char *Action::getClassName(ActionClass AC) {
   case OffloadUnbundlingJobClass:
     return "clang-offload-unbundler";
   case OffloadPackagerJobClass:
-    return "clang-offload-packager";
+    return "llvm-offload-binary";
   case LinkerWrapperJobClass:
     return "clang-linker-wrapper";
   case StaticLibJobClass:
diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h
index c22789591e00a..9adad5c5430f2 100644
--- a/clang/lib/Driver/ToolChains/Clang.h
+++ b/clang/lib/Driver/ToolChains/Clang.h
@@ -163,7 +163,7 @@ class LLVM_LIBRARY_VISIBILITY OffloadBundler final : public Tool {
 class LLVM_LIBRARY_VISIBILITY OffloadPackager final : public Tool {
 public:
   OffloadPackager(const ToolChain &TC)
-      : Tool("Offload::Packager", "clang-offload-packager", TC) {}
+      : Tool("Offload::Packager", "llvm-offload-binary", TC) {}
 
   bool hasIntegratedCPP() const override { return false; }
   void ConstructJob(Compilation &C, const JobAction &JA,
diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt
index e9f4f83f98923..bcb6bd68fafc2 100644
--- a/clang/test/CMakeLists.txt
+++ b/clang/test/CMakeLists.txt
@@ -103,7 +103,6 @@ list(APPEND CLANG_TEST_DEPS
   clang-linker-wrapper
   clang-nvlink-wrapper
   clang-offload-bundler
-  clang-offload-packager
   clang-sycl-linker
   diagtool
   hmaptool
@@ -173,6 +172,7 @@ if( NOT CLANG_BUILT_STANDALONE )
     llvm-strip
     llvm-symbolizer
     llvm-windres
+    llvm-offload-binary
     obj2yaml
     opt
     split-file
diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
index 985eca1692802..914e01873089c 100644
--- a/clang/test/Driver/amdgpu-openmp-sanitize-options.c
+++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
@@ -59,6 +59,6 @@
 // GPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-mlink-bitcode-file" "[^"]*asanrtl.bc".* "-mlink-bitcode-file" "[^"]*ockl.bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-fsanitize=address".* "-x" "c".*}}
 // NOGPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-x" "c".*}}
 
-// SAN: {{"[^"]*clang-offload-packager[^"]*" "-o".* "--image=file=.*.bc,triple=amdgcn-amd-amdhsa,arch=gfx908(:xnack\-|:xnack\+)?,kind=openmp(,feature=(\-xnack|\+xnack))?"}}
+// SAN: {{"[^"]*llvm-offload-binary[^"]*" "-o".* "--image=file=.*.bc,triple=amdgcn-amd-amdhsa,arch=gfx908(:xnack\-|:xnack\+)?,kind=openmp(,feature=(\-xnack|\+xnack))?"}}
 // SAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "--offload-targets=amdgcn-amd-amdhsa".* "-x" "ir".*}}
 // SAN: {{"[^"]*clang-linker-wrapper[^"]*".* "--host-triple=x86_64-unknown-linux-gnu".* "--linker-path=[^"]*".* "--whole-archive" "[^"]*(libclang_rt.asan_static.a|libclang_rt.asan_static-x86_64.a)".* "--whole-archive" "[^"]*(libclang_rt.asan.a|libclang_rt.asan-x86_64.a)".*}}
diff --git a/clang/test/Driver/amdgpu-openmp-toolchain.c b/clang/test/Driver/amdgpu-openmp-toolchain.c
index 1091e6e372ac0..5e73e2d6833fe 100644
--- a/clang/test/Driver/amdgpu-openmp-toolchain.c
+++ b/clang/test/Driver/amdgpu-openmp-toolchain.c
@@ -22,7 +22,7 @@
 // CHECK-PHASES: 6: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (amdgcn-amd-amdhsa:gfx906)" {5}, ir
 // CHECK-PHASES: 7: backend, {6}, ir, (device-openmp, gfx906)
 // CHECK-PHASES: 8: offload, "device-openmp (amdgcn-amd-amdhsa:gfx906)" {7}, ir
-// CHECK-PHASES: 9: clang-offload-packager, {8}, image, (device-openmp)
+// CHECK-PHASES: 9: llvm-offload-binary, {8}, image, (device-openmp)
 // CHECK-PHASES: 10: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (x86_64-unknown-linux-gnu)" {9}, ir
 // CHECK-PHASES: 11: backend, {10}, assembler, (host-openmp)
 // CHECK-PHASES: 12: assembler, {11}, object, (host-openmp)
@@ -64,7 +64,7 @@
 // RUN: %clang -### -target x86_64-pc-linux-gnu -fopenmp --offload-arch=gfx90a:sramecc-:xnack+ \
 // RUN:   -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-TARGET-ID
 // CHECK-TARGET-ID: "-cc1" "-triple" "amdgcn-amd-amdhsa" {{.*}} "-target-cpu" "gfx90a" "-target-feature" "-sramecc" "-target-feature" "+xnack"
-// CHECK-TARGET-ID: clang-offload-packager{{.*}}arch=gfx90a:sramecc-:xnack+,kind=openmp
+// CHECK-TARGET-ID: llvm-offload-binary{{.*}}arch=gfx90a:sramecc-:xnack+,kind=openmp
 
 // RUN: not %clang -### -target x86_64-pc-linux-gnu -fopenmp --offload-arch=gfx90a,gfx90a:xnack+ \
 // RUN:   -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-TARGET-ID-ERROR
diff --git a/clang/test/Driver/cuda-phases.cu b/clang/test/Driver/cuda-phases.cu
index 220a320e32705..db7d29e0c78c3 100644
--- a/clang/test/Driver/cuda-phases.cu
+++ b/clang/test/Driver/cuda-phases.cu
@@ -235,7 +235,7 @@
 // NEW-DRIVER-RDC-NEXT: 12: backend, {11}, assembler, (device-cuda, sm_70)
 // NEW-DRIVER-RDC-NEXT: 13: assembler, {12}, object, (device-cuda, sm_70)
 // NEW-DRIVER-RDC-NEXT: 14: offload, "device-cuda (nvptx64-nvidia-cuda:sm_70)" {13}, object
-// NEW-DRIVER-RDC-NEXT: 15: clang-offload-packager, {8, 14}, image, (device-cuda)
+// NEW-DRIVER-RDC-NEXT: 15: llvm-offload-binary, {8, 14}, image, (device-cuda)
 // NEW-DRIVER-RDC-NEXT: 16: offload, "host-cuda (powerpc64le-ibm-linux-gnu)" {2}, "device-cuda (powerpc64le-ibm-linux-gnu)" {15}, ir
 // NEW-DRIVER-RDC-NEXT: 17: backend, {16}, assembler, (host-cuda)
 // NEW-DRIVER-RDC-NEXT: 18: assembler, {17}, object, (host-cuda)
@@ -312,7 +312,7 @@
 // LTO-NEXT: 10: compiler, {9}, ir, (device-cuda, sm_70)
 // LTO-NEXT: 11: backend, {10}, lto-bc, (device-cuda, sm_70)
 // LTO-NEXT: 12: offload, "device-cuda (nvptx64-nvidia-cuda:sm_70)" {11}, lto-bc
-// LTO-NEXT: 13: clang-offload-packager, {7, 12}, image, (device-cuda)
+// LTO-NEXT: 13: llvm-offload-binary, {7, 12}, image, (device-cuda)
 // LTO-NEXT: 14: offload, "host-cuda (powerpc64le-ibm-linux-gnu)" {2}, "device-cuda (powerpc64le-ibm-linux-gnu)" {13}, ir
 // LTO-NEXT: 15: backend, {14}, assembler, (host-cuda)
 // LTO-NEXT: 16: assembler, {15}, object, (host-cuda)
diff --git a/clang/test/Driver/hip-phases.hip b/clang/test/Driver/hip-phases.hip
index 6bac97ab8064b..13f682f18a3ab 100644
--- a/clang/test/Driver/hip-phases.hip
+++ b/clang/test/Driver/hip-phases.hip
@@ -40,7 +40,7 @@
 // OLD-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH]])" {[[P8]]}, image
 // NEW-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH]])" {[[P6]]}, ir
 // OLDN-DAG: [[P10:[0-9]+]]: linker, {[[P9]]}, hip-fatbin, (device-[[T]])
-// NEW-DAG: [[P10:[0-9]+]]: clang-offload-packager, {[[P9]]}, image, (device-[[T]])
+// NEW-DAG: [[P10:[0-9]+]]: llvm-offload-binary, {[[P9]]}, image, (device-[[T]])
 // OLDR-DAG: [[P10:[0-9]+]]: linker, {[[P9]]}, object, (device-[[T]])
 
 // OLDN-DAG: [[P11:[0-9]+]]: offload, "host-[[T]] (x86_64-unknown-linux-gnu)" {[[P2]]}, "device-[[T]] (amdgcn-amd-amdhsa)" {[[P10]]}, ir
@@ -665,7 +665,7 @@
 // LTO-NEXT: 10: compiler, {9}, ir, (device-hip, gfx90a)
 // LTO-NEXT: 11: backend, {10}, lto-bc, (device-hip, gfx90a)
 // LTO-NEXT: 12: offload, "device-hip (amdgcn-amd-amdhsa:gfx90a)" {11}, lto-bc
-// LTO-NEXT: 13: clang-offload-packager, {7, 12}, image, (device-hip)
+// LTO-NEXT: 13: llvm-offload-binary, {7, 12}, image, (device-hip)
 // LTO-NEXT: 14: offload, "host-hip (x86_64-unknown-linux-gnu)" {2}, "device-hip (x86_64-unknown-linux-gnu)" {13}, ir
 // LTO-NEXT: 15: backend, {14}, assembler, (host-hip)
 // LTO-NEXT: 16: assembler, {15}, object, (host-hip)
diff --git a/clang/test/Driver/hip-toolchain-no-rdc.hip b/clang/test/Driver/hip-toolchain-no-rdc.hip
index dc8f0a97ad371..a94299eb2d4db 100644
--- a/clang/test/Driver/hip-toolchain-no-rdc.hip
+++ b/clang/test/Driver/hip-toolchain-no-rdc.hip
@@ -97,7 +97,7 @@
 // OLD-SAME: "-targets={{.*}},hipv4-amdgcn-amd-amdhsa--gfx803,hipv4-amdgcn-amd-amdhsa--gfx900"
 // OLD-SAME: "-input={{.*}}" "-input=[[IMG_DEV_A_803]]" "-input=[[IMG_DEV_A_900]]" "-output=[[BUNDLE_A:.*hipfb]]"
 
-// NEW: [[PACKAGER:".*clang-offload-packager"]] "-o" "[[PACKAGE_A:.*.out]]"
+// NEW: [[PACKAGER:".*llvm-offload-binary"]] "-o" "[[PACKAGE_A:.*.out]]"
 // NEW-SAME: "--image=file=[[OBJ_DEV_A_803]],triple=amdgcn-amd-amdhsa,arch=gfx803,kind=hip"
 // NEW-SAME: "--image=file=[[OBJ_DEV_A_900]],triple=amdgcn-amd-amdhsa,arch=gfx900,kind=hip"
 
@@ -169,7 +169,7 @@
 // OLD-SAME: "-targets={{.*}},hipv4-amdgcn-amd-amdhsa--gfx803,hipv4-amdgcn-amd-amdhsa--gfx900"
 // OLD-SAME: "-input={{.*}}" "-input=[[IMG_DEV_B_803]]" "-input=[[IMG_DEV_B_900]]" "-output=[[BUNDLE_B:.*hipfb]]"
 
-// NEW: [[PACKAGER:".*clang-offload-packager"]] "-o" "[[PACKAGE_B:.*.out]]"
+// NEW: [[PACKAGER:".*llvm-offload-binary"]] "-o" "[[PACKAGE_B:.*.out]]"
 // NEW-SAME: "--image=file=[[OBJ_DEV_B_803]],triple=amdgcn-amd-amdhsa,arch=gfx803,kind=hip"
 // NEW-SAME: "--image=file=[[OBJ_DEV_B_900]],triple=amdgcn-amd-amdhsa,arch=gfx900,kind=hip"
 
diff --git a/clang/test/Driver/linker-wrapper-image.c b/clang/test/Driver/linker-wrapper-image.c
index 31476173cd370..b9327121edcf9 100644
--- a/clang/test/Driver/linker-wrapper-image.c
+++ b/clang/test/Driver/linker-wrapper-image.c
@@ -5,7 +5,7 @@
 
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.elf.o
 
-// RUN: clang-offload-packager -o %t.out --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
+// RUN: llvm-offload-binary -o %t.out --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
 // RUN:   -fembed-offload-object=%t.out
 // RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu \
@@ -42,7 +42,7 @@
 // OPENMP-NEXT:   ret void
 // OPENMP-NEXT: }
 
-// RUN: clang-offload-packager -o %t.out --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_70
+// RUN: llvm-offload-binary -o %t.out --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
 // RUN:   -fembed-offload-object=%t.out
 // RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu \
@@ -153,7 +153,7 @@
 // CUDA-NEXT:   ret void
 // CUDA-NEXT: }
 
-// RUN: clang-offload-packager -o %t.out --image=file=%t.elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx908
+// RUN: llvm-offload-binary -o %t.out --image=file=%t.elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
 // RUN:   -fembed-offload-object=%t.out
 // RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu \
@@ -265,7 +265,7 @@
 // HIP-NEXT:   ret void
 // HIP-NEXT: }
 
-// RUN: clang-offload-packager -o %t.out --image=file=%t.elf.o,kind=sycl,triple=spirv64-unknown-unknown,arch=generic
+// RUN: llvm-offload-binary -o %t.out --image=file=%t.elf.o,kind=sycl,triple=spirv64-unknown-unknown,arch=generic
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
 // RUN:   -fembed-offload-object=%t.out
 // RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu \
diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c
index c060dae7bb154..ced553a8497ee 100644
--- a/clang/test/Driver/linker-wrapper.c
+++ b/clang/test/Driver/linker-wrapper.c
@@ -12,7 +12,7 @@ __attribute__((visibility("protected"), used)) int x;
 // RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -o %t.amdgpu.bc
 // RUN: %clang -cc1 %s -triple spirv64-unknown-unknown -emit-llvm-bc -o %t.spirv.bc
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -24,7 +24,7 @@ __attribute__((visibility("protected"), used)) int x;
 
 // NVPTX-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.nvptx64.sm_70.img. --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -33,7 +33,7 @@ __attribute__((visibility("protected"), used)) int x;
 
 // NVPTX-LINK-DEBUG: clang{{.*}} --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}-g
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -42,7 +42,7 @@ __attribute__((visibility("protected"), used)) int x;
 
 // AMDGPU-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx908.img. --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx1030 \
 // RUN:   --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx1030
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -51,7 +51,7 @@ __attribute__((visibility("protected"), used)) int x;
 
 // AMDGPU-LTO-TEMPS: clang{{.*}} --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -flto {{.*}}-save-temps
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.spirv.bc,kind=sycl,triple=spirv64-unknown-unknown,arch=generic
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
 // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
@@ -59,7 +59,7 @@ __attribute__((visibility("protected"), used)) int x;
 
 // SPIRV-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.spirv64..img. --target=spirv64-unknown-unknown {{.*}}.o --sycl-link -Xlinker -triple=spirv64-unknown-unknown -Xlinker -arch=
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -77,12 +77,12 @@ __attribute__((visibility("protected"), used)) int x;
 // HOST-LINK: ld.lld{{.*}}-a -b -c {{.*}}.o -o a.out
 // HOST-LINK-NOT: ld.lld{{.*}}-abc
 
-// RUN: clang-offload-packager -o %t-lib.out \
+// RUN: llvm-offload-binary -o %t-lib.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_52
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t-lib.out
 // RUN: llvm-ar rcs %t.a %t.o
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t-obj.o -fembed-offload-object=%t.out
 // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
@@ -91,7 +91,7 @@ __attribute__((visibility("protected"), used)) int x;
 // STATIC-LIBRARY: clang{{.*}} -march=sm_70
 // STATIC-LIBRARY-NOT: clang{{.*}} -march=sm_50
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_52
@@ -105,7 +105,7 @@ __attribute__((visibility("protected"), used)) int x;
 // CUDA: fatbinary{{.*}}-64 --create {{.*}}.fatbin --image=profile=sm_70,file=[[IMG_SM70]] --image=profile=sm_52,file=[[IMG_SM52]]
 // CUDA: usr/bin/ld{{.*}} {{.*}}.openmp.image.{{.*}}.o {{.*}}.cuda.image.{{.*}}.o
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_80 \
 // RUN:   --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_75 \
 // RUN:   --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_70 \
@@ -117,7 +117,7 @@ __attribute__((visibility("protected"), used)) int x;
 
 // CUDA-PAR: fatbinary{{.*}}-64 --create {{.*}}.fatbin
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx90a \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a \
 // RUN:   --image=file=%t.elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx908
@@ -131,7 +131,7 @@ __attribute__((visibility("protected"), used)) int x;
 // HIP: clang{{.*}} -o [[IMG_GFX908:.+]] -dumpdir a.out.amdgcn.gfx908.img. --target=amdgcn-amd-amdhsa -mcpu=gfx908
 // HIP: clang-offload-bundler{{.*}}-type=o -bundle-align=4096 -compress -compression-level=6 -targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa--gfx90a,hip-amdgcn-amd-amdhsa--gfx908 -input={{/dev/null|NUL}} -input=[[IMG_GFX90A]] -input=[[IMG_GFX908]] -output={{.*}}.hipfb
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
@@ -150,7 +150,7 @@ __attribute__((visibility("protected"), used)) int x;
 
 // MISSING-LIBRARY: error: unable to find library -ldummy
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -159,7 +159,7 @@ __attribute__((visibility("protected"), used)) int x;
 
 // CLANG-BACKEND: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx908.img. --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-windows-msvc -emit-obj -o %t.o -fembed-offload-object=%t.out
 // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-windows-msvc --dry-run \
@@ -167,14 +167,14 @@ __attribute__((visibility("protected"), used)) int x;
 
 // COFF: "/usr/bin/lld-link" {{.*}}.o -libpath:./ -out:a.exe {{.*}}openmp.image.wrapper{{.*}}
 
-// RUN: clang-offload-packager -o %t-lib.out \
+// RUN: llvm-offload-binary -o %t-lib.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t-lib.out
 // RUN: llvm-ar rcs %t.a %t.o
-// RUN: clang-offload-packager -o %t-on.out \
+// RUN: llvm-offload-binary -o %t-on.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a:xnack+
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t-on.o -fembed-offload-object=%t-on.out
-// RUN: clang-offload-packager -o %t-off.out \
+// RUN: llvm-offload-binary -o %t-off.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a:xnack-
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t-off.o -fembed-offload-object=%t-off.out
 // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
@@ -183,14 +183,14 @@ __attribute__((visibility("protected"), used)) int x;
 // AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a:xnack+.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+ -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o
 // AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a:xnack-.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack- -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o
 
-// RUN: clang-offload-packager -o %t-lib.out \
+// RUN: llvm-offload-binary -o %t-lib.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=generic
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t-lib.out
 // RUN: llvm-ar rcs %t.a %t.o
-// RUN: clang-offload-packager -o %t1.out \
+// RUN: llvm-offload-binary -o %t1.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t1.o -fembed-offload-object=%t1.out
-// RUN: clang-offload-packager -o %t2.out \
+// RUN: llvm-offload-binary -o %t2.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t2.o -fembed-offload-object=%t2.out
 // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
@@ -199,7 +199,7 @@ __attribute__((visibility("protected"), used)) int x;
 // ARCH-ALL: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o
 // ARCH-ALL: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx908.img. --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -211,7 +211,7 @@ __attribute__((visibility("protected"), used)) int x;
 // RELOCATABLE-LINK: /usr/bin/ld.lld{{.*}}-r
 // RELOCATABLE-LINK: llvm-objcopy{{.*}}a.out --remove-section .llvm.offloading
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx90a \
 // RUN:   --image=file=%t.elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx90a
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -225,7 +225,7 @@ __attribute__((visibility("protected"), used)) int x;
 // RELOCATABLE-LINK-HIP: llvm-objcopy{{.*}}a.out --remove-section .llvm.offloading
 // RELOCATABLE-LINK-HIP: --rename-section llvm_offload_entries
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_89 \
 // RUN:   --image=file=%t.elf.o,kind=cuda,triple=nvptx64-nvidia-cuda,arch=sm_89
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
@@ -245,7 +245,7 @@ __attribute__((visibility("protected"), used)) int x;
 // OVERRIDE-NOT: clang
 // OVERRIDE: /usr/bin/ld
 
-// RUN: clang-offload-packager -o %t.out \
+// RUN: llvm-offload-binary -o %t.out \
 // RUN:   --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
 // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
diff --git a/clang/test/Driver/offload-packager.c b/clang/test/Driver/offload-packager.c
index fb5f1006cf9e2..adf25656e7f96 100644
--- a/clang/test/Driver/offload-packager.c
+++ b/clang/test/Driver/offload-packager.c
@@ -7,26 +7,26 @@
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t/elf.o
 
 // Check that we can extract files from the packaged binary.
-// RUN: clang-offload-packager -o %t/package.out \
+// RUN: llvm-offload-binary -o %t/package.out \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_80 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90c 
-// RUN: clang-offload-packager %t/package.out \
+// RUN: llvm-offload-binary %t/package.out \
 // RUN:   --image=file=%t/sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t/gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: diff %t/sm_70.o %t/elf.o
 // RUN: diff %t/gfx908.o %t/elf.o
 
 // Check that we generate a new name if one is not given
-// RUN: clang-offload-packager -o %t/package \
+// RUN: llvm-offload-binary -o %t/package \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_80 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a \
 // RUN:   --image=file=%t/elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx90c 
-// RUN: clang-offload-packager %t/package --image=kind=openmp
+// RUN: llvm-offload-binary %t/package --image=kind=openmp
 // RUN: diff *-nvptx64-nvidia-cuda-sm_70.0.o %t/elf.o; rm *-nvptx64-nvidia-cuda-sm_70.0.o
 // RUN: diff *-nvptx64-nvidia-cuda-sm_80.1.o %t/elf.o; rm *-nvptx64-nvidia-cuda-sm_80.1.o
 // RUN: diff *-amdgcn-amd-amdhsa-gfx908.2.o %t/elf.o; rm *-amdgcn-amd-amdhsa-gfx908.2.o
@@ -34,33 +34,33 @@
 // RUN: not diff *-amdgcn-amd-amdhsa-gfx90c.4.o %t/elf.o
 
 // Check that we can extract from an ELF object file
-// RUN: clang-offload-packager -o %t/package.out \
+// RUN: llvm-offload-binary -o %t/package.out \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t/package.o -fembed-offload-object=%t/package.out
-// RUN: clang-offload-packager %t/package.out \
+// RUN: llvm-offload-binary %t/package.out \
 // RUN:   --image=file=%t/sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t/gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: diff %t/sm_70.o %t/elf.o
 // RUN: diff %t/gfx908.o %t/elf.o
 
 // Check that we can extract from a bitcode file
-// RUN: clang-offload-packager -o %t/package.out \
+// RUN: llvm-offload-binary -o %t/package.out \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -o %t/package.bc -fembed-offload-object=%t/package.out
-// RUN: clang-offload-packager %t/package.out \
+// RUN: llvm-offload-binary %t/package.out \
 // RUN:   --image=file=%t/sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
 // RUN:   --image=file=%t/gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
 // RUN: diff %t/sm_70.o %t/elf.o
 // RUN: diff %t/gfx908.o %t/elf.o
 
 // Check that we can extract from an archive file to an archive file.
-// RUN: clang-offload-packager -o %t/package.out \
+// RUN: llvm-offload-binary -o %t/package.out \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t/package.o -fembed-offload-object=%t/package.out
 // RUN: llvm-ar rcs %t/package.a %t/package.o
-// RUN: clang-offload-packager %t/package.a --archive --image=file=%t/gfx908.a,arch=gfx908
+// RUN: llvm-offload-binary %t/package.a --archive --image=file=%t/gfx908.a,arch=gfx908
 // RUN: llvm-ar t %t/gfx908.a 2>&1 | FileCheck %s
 // CHECK: {{.*}}.o
diff --git a/clang/test/Driver/openmp-offload-gpu.c b/clang/test/Driver/openmp-offload-gpu.c
index 77f4cfb5f3a43..edce14e94c8a2 100644
--- a/clang/test/Driver/openmp-offload-gpu.c
+++ b/clang/test/Driver/openmp-offload-gpu.c
@@ -242,7 +242,7 @@
 // CHECK-PHASES: 7: backend, {6}, assembler, (device-openmp, sm_52)
 // CHECK-PHASES: 8: assembler, {7}, object, (device-openmp, sm_52)
 // CHECK-PHASES: 9: offload, "device-openmp (nvptx64-nvidia-cuda:sm_52)" {8}, object
-// CHECK-PHASES: 10: clang-offload-packager, {9}, image
+// CHECK-PHASES: 10: llvm-offload-binary, {9}, image
 // CHECK-PHASES: 11: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (x86_64-unknown-linux-gnu)" {10}, ir
 // CHECK-PHASES: 12: backend, {11}, assembler, (host-openmp)
 // CHECK-PHASES: 13: assembler, {12}, object, (host-openmp)
@@ -346,13 +346,13 @@
 // RUN:   %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=sm_52 -nogpulib \
 // RUN:     -foffload-lto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-FEATURES %s
 
-// CHECK-LTO-FEATURES: clang-offload-packager{{.*}}--image={{.*}}feature=+ptx{{[0-9]+}}
+// CHECK-LTO-FEATURES: llvm-offload-binary{{.*}}--image={{.*}}feature=+ptx{{[0-9]+}}
 
 // RUN:   %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=sm_52 -nogpulib \
 // RUN:     -Xopenmp-target=nvptx64-nvidia-cuda --cuda-feature=+ptx64 -foffload-lto %s 2>&1 \
 // RUN:    | FileCheck --check-prefix=CHECK-SET-FEATURES %s
 
-// CHECK-SET-FEATURES: clang-offload-packager{{.*}}--image={{.*}}feature=+ptx64
+// CHECK-SET-FEATURES: llvm-offload-binary{{.*}}--image={{.*}}feature=+ptx64
 
 //
 // Check that `-Xarch_host` works for OpenMP offloading.
diff --git a/clang/test/Driver/openmp-offload-jit.c b/clang/test/Driver/openmp-offload-jit.c
index b3566f06bbee1..6ced5c1094bf4 100644
--- a/clang/test/Driver/openmp-offload-jit.c
+++ b/clang/test/Driver/openmp-offload-jit.c
@@ -25,7 +25,7 @@
 // PHASES-JIT-NEXT: 6: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp ([[TARGET:.+]])" {5}, ir
 // PHASES-JIT-NEXT: 7: backend, {6}, lto-bc, (device-openmp, {{.*}})
 // PHASES-JIT-NEXT: 8: offload, "device-openmp ([[TARGET]])" {7}, lto-bc
-// PHASES-JIT-NEXT: 9: clang-offload-packager, {8}, image, (device-openmp)
+// PHASES-JIT-NEXT: 9: llvm-offload-binary, {8}, image, (device-openmp)
 // PHASES-JIT-NEXT: 10: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (x86_64-unknown-linux-gnu)" {9}, ir
 // PHASES-JIT-NEXT: 11: backend, {10}, assembler, (host-openmp)
 // PHASES-JIT-NEXT: 12: assembler, {11}, object, (host-openmp)
diff --git a/clang/test/Driver/openmp-offload.c b/clang/test/Driver/openmp-offload.c
index 64d45f9479fb6..fce1b88d2dc8f 100644
--- a/clang/test/Driver/openmp-offload.c
+++ b/clang/test/Driver/openmp-offload.c
@@ -103,7 +103,7 @@
 // CHK-PHASES-NEXT: 7: backend, {6}, assembler, (device-openmp)
 // CHK-PHASES-NEXT: 8: assembler, {7}, object, (device-openmp)
 // CHK-PHASES-NEXT: 9: offload, "device-openmp (powerpc64-ibm-linux-gnu)" {8}, object
-// CHK-PHASES-NEXT: 10: clang-offload-packager, {9}, image, (device-openmp)
+// CHK-PHASES-NEXT: 10: llvm-offload-binary, {9}, image, (device-openmp)
 // CHK-PHASES-NEXT: 11: offload, "host-openmp (powerpc64-ibm-linux-gnu)" {2}, "device-openmp (powerpc64-ibm-linux-gnu)" {10}, ir
 // CHK-PHASES-NEXT: 12: backend, {11}, assembler, (host-openmp)
 // CHK-PHASES-NEXT: 13: assembler, {12}, object, (host-openmp)
@@ -132,7 +132,7 @@
 // CHK-PHASES-FILES-NEXT: 15: backend, {14}, assembler, (device-openmp)
 // CHK-PHASES-FILES-NEXT: 16: assembler, {15}, object, (device-openmp)
 // CHK-PHASES-FILES-NEXT: 17: offload, "device-openmp (x86_64-pc-linux-gnu)" {16}, object
-// CHK-PHASES-FILES-NEXT: 18: clang-offload-packager, {10, 17}, image, (device-openmp)
+// CHK-PHASES-FILES-NEXT: 18: llvm-offload-binary, {10, 17}, image, (device-openmp)
 // CHK-PHASES-FILES-NEXT: 19: offload, "host-openmp (powerpc64-ibm-linux-gnu)" {3}, "device-openmp (powerpc64-ibm-linux-gnu)" {18}, ir
 // CHK-PHASES-FILES-NEXT: 20: backend, {19}, assembler, (host-openmp)
 // CHK-PHASES-FILES-NEXT: 21: assembler, {20}, object, (host-openmp)
@@ -153,7 +153,7 @@
 // CHK-PHASES-FILES-NEXT: 36: backend, {35}, assembler, (device-openmp)
 // CHK-PHASES-FILES-NEXT: 37: assembler, {36}, object, (device-openmp)
 // CHK-PHASES-FILES-NEXT: 38: offload, "device-openmp (x86_64-pc-linux-gnu)" {37}, object
-// CHK-PHASES-FILES-NEXT: 39: clang-offload-packager, {31, 38}, image, (device-openmp)
+// CHK-PHASES-FILES-NEXT: 39: llvm-offload-binary, {31, 38}, image, (device-openmp)
 // CHK-PHASES-FILES-NEXT: 40: offload, "host-openmp (powerpc64-ibm-linux-gnu)" {24}, "device-openmp (powerpc64-ibm-linux-gnu)" {39}, ir
 // CHK-PHASES-FILES-NEXT: 41: backend, {40}, assembler, (host-openmp)
 // CHK-PHASES-FILES-NEXT: 42: assembler, {41}, object, (host-openmp)
diff --git a/clang/test/Driver/spirv-openmp-toolchain.c b/clang/test/Driver/spirv-openmp-toolchain.c
index 1542f500971fa..6bf8984a9b779 100644
--- a/clang/test/Driver/spirv-openmp-toolchain.c
+++ b/clang/test/Driver/spirv-openmp-toolchain.c
@@ -21,7 +21,7 @@
 // CHECK-PHASES: 7: backend, {6}, assembler, (device-openmp)
 // CHECK-PHASES: 8: assembler, {7}, object, (device-openmp)
 // CHECK-PHASES: 9: offload, "device-openmp (spirv64-intel)" {8}, object
-// CHECK-PHASES: 10: clang-offload-packager, {9}, image, (device-openmp)
+// CHECK-PHASES: 10: llvm-offload-binary, {9}, image, (device-openmp)
 // CHECK-PHASES: 11: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (x86_64-unknown-linux-gnu)" {10}, ir
 // CHECK-PHASES: 12: backend, {11}, assembler, (host-openmp)
 // CHECK-PHASES: 13: assembler, {12}, object, (host-openmp)
diff --git a/clang/test/Driver/sycl-offload-jit.cpp b/clang/test/Driver/sycl-offload-jit.cpp
index e040f4ded18e9..72c2390a3fe4b 100644
--- a/clang/test/Driver/sycl-offload-jit.cpp
+++ b/clang/test/Driver/sycl-offload-jit.cpp
@@ -13,21 +13,21 @@
 // CHK-PHASES-NEXT: 5: compiler, {4}, ir, (device-sycl)
 // CHK-PHASES-NEXT: 6: backend, {5}, ir, (device-sycl)
 // CHK-PHASES-NEXT: 7: offload, "device-sycl (spirv64-unknown-unknown)" {6}, ir
-// CHK-PHASES-NEXT: 8: clang-offload-packager, {7}, image, (device-sycl)
+// CHK-PHASES-NEXT: 8: llvm-offload-binary, {7}, image, (device-sycl)
 // CHK-PHASES-NEXT: 9: offload, "host-sycl (x86_64{{.*}})" {2}, "device-sycl (x86_64{{.*}})" {8}, ir
 // CHK-PHASES-NEXT: 10: backend, {9}, assembler, (host-sycl)
 // CHK-PHASES-NEXT: 11: assembler, {10}, object, (host-sycl)
 // CHK-PHASES-NEXT: 12: clang-linker-wrapper, {11}, image, (host-sycl)
 
 /// Check expected default values for device compilation when using -fsycl as
-/// well as clang-offload-packager inputs.
+/// well as llvm-offload-binary inputs.
 // RUN: %clang -### -fsycl -c --target=x86_64-unknown-linux-gnu %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHK-DEVICE-TRIPLE %s
 // CHK-DEVICE-TRIPLE: "-cc1"{{.*}} "-triple" "spirv64-unknown-unknown"
 // CHK-DEVICE-TRIPLE-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
 // CHK-DEVICE-TRIPLE-SAME: "-fsycl-is-device"
 // CHK-DEVICE-TRIPLE-SAME: "-O2"
-// CHK-DEVICE-TRIPLE: clang-offload-packager{{.*}} "--image=file={{.*}}.bc,triple=spirv64-unknown-unknown,arch=generic,kind=sycl"
+// CHK-DEVICE-TRIPLE: llvm-offload-binary{{.*}} "--image=file={{.*}}.bc,triple=spirv64-unknown-unknown,arch=generic,kind=sycl"
 
 /// Check -fsycl-is-device is passed when compiling for the device.
 /// Check -fsycl-is-host is passed when compiling for host.
diff --git a/clang/test/Tooling/clang-linker-wrapper-spirv-elf.cpp b/clang/test/Tooling/clang-linker-wrapper-spirv-elf.cpp
index 85208fc8e925c..8a7d36d36b025 100644
--- a/clang/test/Tooling/clang-linker-wrapper-spirv-elf.cpp
+++ b/clang/test/Tooling/clang-linker-wrapper-spirv-elf.cpp
@@ -6,7 +6,7 @@
 // RUN: cd %t_tmp
 // RUN: %clangxx -fopenmp -fopenmp-targets=spirv64-intel -nogpulib -c -o %t_clang-linker-wrapper-spirv-elf.o %s
 // RUN: not clang-linker-wrapper -o a.out %t_clang-linker-wrapper-spirv-elf.o --save-temps --linker-path=ld
-// RUN: clang-offload-packager --image=triple=spirv64-intel,kind=openmp,file=%t.elf  %t_tmp/a.out.openmp.image.wrapper.o
+// RUN: llvm-offload-binary --image=triple=spirv64-intel,kind=openmp,file=%t.elf  %t_tmp/a.out.openmp.image.wrapper.o
 // RUN: llvm-readelf -h %t.elf | FileCheck -check-prefix=CHECK-MACHINE %s
 // RUN: llvm-readelf -t %t.elf | FileCheck -check-prefix=CHECK-SECTION %s
 // RUN: llvm-readelf -n %t.elf | FileCheck -check-prefix=CHECK-NOTES %s
diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index e6c79d7a71b51..29088ef367e7c 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -92,7 +92,7 @@
     "clang-diff",
     "clang-format",
     "clang-repl",
-    "clang-offload-packager",
+    "llvm-offload-binary",
     "clang-tblgen",
     "clang-scan-deps",
     "clang-installapi",
diff --git a/clang/tools/CMakeLists.txt b/clang/tools/CMakeLists.txt
index 50e3d694236ac..7a7c56ae217b0 100644
--- a/clang/tools/CMakeLists.txt
+++ b/clang/tools/CMakeLists.txt
@@ -14,7 +14,6 @@ add_clang_subdirectory(clang-fuzzer)
 add_clang_subdirectory(clang-import-test)
 add_clang_subdirectory(clang-linker-wrapper)
 add_clang_subdirectory(clang-nvlink-wrapper)
-add_clang_subdirectory(clang-offload-packager)
 add_clang_subdirectory(clang-offload-bundler)
 add_clang_subdirectory(clang-scan-deps)
 add_clang_subdirectory(clang-sycl-linker)
diff --git a/clang/tools/clang-offload-packager/CMakeLists.txt b/clang/tools/clang-offload-packager/CMakeLists.txt
deleted file mode 100644
index 1c29e376452c1..0000000000000
--- a/clang/tools/clang-offload-packager/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-set(LLVM_LINK_COMPONENTS 
-  ${LLVM_TARGETS_TO_BUILD}
-  BinaryFormat
-  Object
-  Support)
-
-add_clang_tool(clang-offload-packager
-  ClangOffloadPackager.cpp
-
-  DEPENDS
-  ${tablegen_deps}
-  )
-
-clang_target_link_libraries(clang-offload-packager
-  PRIVATE
-  clangBasic
-  )
diff --git a/flang/test/Driver/omp-driver-offload.f90 b/flang/test/Driver/omp-driver-offload.f90
index f4f0c21dc1f5e..09248572b9ff5 100644
--- a/flang/test/Driver/omp-driver-offload.f90
+++ b/flang/test/Driver/omp-driver-offload.f90
@@ -61,7 +61,7 @@
 ! OPENMP-OFFLOAD-ARGS-SAME:  "-fopenmp"
 ! OPENMP-OFFLOAD-ARGS-SAME:  "-fopenmp-host-ir-file-path" "{{.*}}.bc" "-fopenmp-is-target-device"
 ! OPENMP-OFFLOAD-ARGS-SAME:  {{.*}}.f90"
-! OPENMP-OFFLOAD-ARGS: "{{[^"]*}}clang-offload-packager{{.*}}" {{.*}} "--image=file={{.*}}.bc,triple=amdgcn-amd-amdhsa,arch=gfx90a,kind=openmp"
+! OPENMP-OFFLOAD-ARGS: "{{[^"]*}}llvm-offload-binary{{.*}}" {{.*}} "--image=file={{.*}}.bc,triple=amdgcn-amd-amdhsa,arch=gfx90a,kind=openmp"
 ! OPENMP-OFFLOAD-ARGS-NEXT: "{{[^"]*}}flang" "-fc1" "-triple" "aarch64-unknown-linux-gnu"
 ! OPENMP-OFFLOAD-ARGS-SAME:  "-fopenmp"
 ! OPENMP-OFFLOAD-ARGS-SAME:  "-fembed-offload-object={{.*}}.out" {{.*}}.bc"
diff --git a/llvm/docs/CommandGuide/index.rst b/llvm/docs/CommandGuide/index.rst
index f85f32a1fdd51..8f080ded81c69 100644
--- a/llvm/docs/CommandGuide/index.rst
+++ b/llvm/docs/CommandGuide/index.rst
@@ -92,6 +92,7 @@ Developer Tools
    llvm-pdbutil
    llvm-profgen
    llvm-tli-checker
+   llvm-offload-binary
 
 Remarks Tools
 ~~~~~~~~~~~~~~
diff --git a/llvm/docs/CommandGuide/llvm-offload-binary.rst b/llvm/docs/CommandGuide/llvm-offload-binary.rst
new file mode 100644
index 0000000000000..960b12d8af286
--- /dev/null
+++ b/llvm/docs/CommandGuide/llvm-offload-binary.rst
@@ -0,0 +1,185 @@
+llvm-offload-binary - LLVM Offload Binary Packager
+==================================================
+
+.. program:: llvm-offload-binary
+
+SYNOPSIS
+--------
+
+:program:`llvm-offload-binary` [*options*] [*input files...*]
+
+DESCRIPTION
+-----------
+
+:program:`llvm-offload-binary` is a utility for bundling multiple device object
+files into a single binary container. The resulting binary can then be embedded
+into the host section table to form a fat binary containing offloading code for
+different targets. Conversely, it can also extract previously bundled device
+images.
+
+The binary format begins with the magic bytes ``0x10FF10AD``, followed by a
+version and size. Each binary contains its own header, allowing tools to locate
+offloading sections even when merged by a linker. Each offload entry includes
+metadata such as the device image kind, producer kind, and key-value string
+metadata. Multiple offloading images are concatenated to form a fat binary.
+
+EXAMPLE
+-------
+
+.. code-block:: console
+
+  # Package multiple device images into a fat binary:
+  $ llvm-offload-binary -o out.bin \
+        --image=file=input.o,triple=nvptx64,arch=sm_70
+
+  # Extract a matching image from a fat binary:
+  $ llvm-offload-binary in.bin \
+        --image=file=output.o,triple=nvptx64,arch=sm_70
+
+  # Extract and archive images into a static library:
+  $ llvm-offload-binary in.bin --archive -o libdevice.a
+
+OPTIONS
+-------
+
+.. option:: --archive
+
+  When extracting from an input binary, write all extracted images into a static
+  archive instead of separate files.
+
+.. option:: --image=<<key>=<value>,...>
+
+  Specify a set of arbitrary key-value arguments describing an image.
+  Commonly used optional keys include ``arch`` (e.g. ``sm_70`` for CUDA) and
+  ``triple`` (e.g. nvptx64-nvidia-cuda).
+
+.. option:: -o <file>
+
+  Write output to <file>. When bundling, this specifies the fat binary filename.
+  When extracting, this specifies the archive or output file destination.
+
+.. option:: --help, -h
+
+  Display available options. Use ``--help-hidden`` to show hidden options.
+
+.. option:: --help-list
+
+  Display a list of all options. Use ``--help-list-hidden`` to show hidden ones.
+
+.. option:: --version
+
+  Display the version of the :program:`llvm-offload-binary` executable.
+
+.. option:: @<FILE>
+
+  Read command-line options from response file `<FILE>`.
+
+BINARY FORMAT
+-------------
+
+The binary format is marked by the magic bytes ``0x10FF10AD``, followed by a
+version number. Each created binary contains its own header. This allows tools
+to locate offloading sections even after linker operations such as relocatable
+linking. Conceptually, this binary format is a serialization of a string map and
+an image buffer.
+
+.. table:: Offloading Binary Header
+   :name: table-binary_header
+
+   +----------+--------------+----------------------------------------------------+
+   |   Type   |  Identifier  | Description                                        |
+   +==========+==============+====================================================+
+   | uint8_t  |    magic     | The magic bytes for the binary format (0x10FF10AD) |
+   +----------+--------------+----------------------------------------------------+
+   | uint32_t |   version    | Version of this format (currently version 1)       |
+   +----------+--------------+----------------------------------------------------+
+   | uint64_t |    size      | Size of this binary in bytes                       |
+   +----------+--------------+----------------------------------------------------+
+   | uint64_t | entry offset | Absolute offset of the offload entries in bytes    |
+   +----------+--------------+----------------------------------------------------+
+   | uint64_t |  entry size  | Size of the offload entries in bytes               |
+   +----------+--------------+----------------------------------------------------+
+
+Each offload entry describes a bundled image along with its associated metadata.
+
+.. table:: Offloading Entry Table
+   :name: table-binary_entry
+
+   +----------+---------------+----------------------------------------------------+
+   |   Type   |   Identifier  | Description                                        |
+   +==========+===============+====================================================+
+   | uint16_t |  image kind   | The kind of the device image (e.g. bc, cubin)      |
+   +----------+---------------+----------------------------------------------------+
+   | uint16_t | offload kind  | The producer of the image (e.g. openmp, cuda)      |
+   +----------+---------------+----------------------------------------------------+
+   | uint32_t |     flags     | Generic flags for the image                        |
+   +----------+---------------+----------------------------------------------------+
+   | uint64_t | string offset | Absolute offset of the string metadata table       |
+   +----------+---------------+----------------------------------------------------+
+   | uint64_t |  num strings  | Number of string entries in the table              |
+   +----------+---------------+----------------------------------------------------+
+   | uint64_t |  image offset | Absolute offset of the device image in bytes       |
+   +----------+---------------+----------------------------------------------------+
+   | uint64_t |   image size  | Size of the device image in bytes                  |
+   +----------+---------------+----------------------------------------------------+
+
+The entry table refers to both a string table and the raw device image itself.
+The string table provides arbitrary key-value metadata.
+
+.. table:: Offloading String Entry
+   :name: table-binary_string
+
+   +----------+--------------+-------------------------------------------------------+
+   |   Type   |   Identifier | Description                                           |
+   +==========+==============+=======================================================+
+   | uint64_t |  key offset  | Absolute byte offset of the key in the string table   |
+   +----------+--------------+-------------------------------------------------------+
+   | uint64_t | value offset | Absolute byte offset of the value in the string table |
+   +----------+--------------+-------------------------------------------------------+
+
+The string table is a collection of null-terminated strings stored in the image.
+Offsets allow string entries to be interpreted as key-value pairs, enabling
+flexible metadata such as architecture or target triple.
+
+The enumerated values for ``image kind`` and ``offload kind`` are:
+
+.. table:: Image Kind
+   :name: table-image_kind
+
+   +---------------+-------+---------------------------------------+
+   |      Name     | Value | Description                           |
+   +===============+=======+=======================================+
+   | IMG_None      | 0x00  | No image information provided         |
+   +---------------+-------+---------------------------------------+
+   | IMG_Object    | 0x01  | The image is a generic object file    |
+   +---------------+-------+---------------------------------------+
+   | IMG_Bitcode   | 0x02  | The image is an LLVM-IR bitcode file  |
+   +---------------+-------+---------------------------------------+
+   | IMG_Cubin     | 0x03  | The image is a CUDA object file       |
+   +---------------+-------+---------------------------------------+
+   | IMG_Fatbinary | 0x04  | The image is a CUDA fatbinary file    |
+   +---------------+-------+---------------------------------------+
+   | IMG_PTX       | 0x05  | The image is a CUDA PTX file          |
+   +---------------+-------+---------------------------------------+
+
+.. table:: Offload Kind
+   :name: table-offload_kind
+
+   +------------+-------+---------------------------------------+
+   |      Name  | Value | Description                           |
+   +============+=======+=======================================+
+   | OFK_None   | 0x00  | No offloading information provided    |
+   +------------+-------+---------------------------------------+
+   | OFK_OpenMP | 0x01  | The producer was OpenMP offloading    |
+   +------------+-------+---------------------------------------+
+   | OFK_CUDA   | 0x02  | The producer was CUDA                 |
+   +------------+-------+---------------------------------------+
+   | OFK_HIP    | 0x03  | The producer was HIP                  |
+   +------------+-------+---------------------------------------+
+   | OFK_SYCL   | 0x04  | The producer was SYCL                 |
+   +------------+-------+---------------------------------------+
+
+SEE ALSO
+--------
+
+:manpage:`clang(1)`, :manpage:`llvm-objdump(1)`
diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt
index 6f98eaee241bc..d0bd42e26e261 100644
--- a/llvm/runtimes/CMakeLists.txt
+++ b/llvm/runtimes/CMakeLists.txt
@@ -473,7 +473,6 @@ if(build_runtimes)
   if(LLVM_INCLUDE_TESTS)
     foreach(dep FileCheck
                 clang
-                clang-offload-packager
                 flang
                 count
                 lld
@@ -489,6 +488,7 @@ if(build_runtimes)
                 llvm-size
                 llvm-symbolizer
                 llvm-xray
+                llvm-offload-binary
                 not
                 obj2yaml
                 opt
@@ -552,7 +552,7 @@ if(build_runtimes)
       # that all .mod files are also properly build.
       list(APPEND extra_deps "flang" "module_files")
     endif()
-    foreach(dep opt llvm-link llvm-extract clang clang-offload-packager clang-nvlink-wrapper)
+    foreach(dep opt llvm-link llvm-extract clang llvm-offload-binary clang-nvlink-wrapper)
       if(TARGET ${dep})
         list(APPEND extra_deps ${dep})
       endif()
@@ -560,8 +560,8 @@ if(build_runtimes)
   endif()
   if(LLVM_LIBC_GPU_BUILD)
     list(APPEND extra_cmake_args "-DLLVM_LIBC_GPU_BUILD=ON")
-    if(TARGET clang-offload-packager)
-      list(APPEND extra_deps clang-offload-packager)
+    if(TARGET llvm-offload-binary)
+      list(APPEND extra_deps llvm-offload-binary)
     endif()
     if(TARGET clang-nvlink-wrapper)
       list(APPEND extra_deps clang-nvlink-wrapper)
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index e810fcb608a20..f01422e3b0990 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -123,6 +123,7 @@ set(LLVM_TEST_DEPENDS
   llvm-objdump
   llvm-opt-fuzzer
   llvm-opt-report
+  llvm-offload-binary
   llvm-offload-wrapper
   llvm-otool
   llvm-pdbutil
diff --git a/llvm/test/tools/llvm-offload-binary/llvm-offload-binary.ll b/llvm/test/tools/llvm-offload-binary/llvm-offload-binary.ll
new file mode 100644
index 0000000000000..b196c24b0f6f1
--- /dev/null
+++ b/llvm/test/tools/llvm-offload-binary/llvm-offload-binary.ll
@@ -0,0 +1,10 @@
+; RUN: llvm-offload-binary -o %t --image=file=%s,arch=abc,triple=x-y-z
+; RUN: llvm-objdump --offloading %t | FileCheck %s
+; RUN: llvm-offload-binary %t --image=file=%t2,arch=abc,triple=x-y-z
+; RUN: diff %s %t2
+
+;      CHECK: OFFLOADING IMAGE [0]:
+; CHECK-NEXT: kind            <none>
+; CHECK-NEXT: arch            abc
+; CHECK-NEXT: triple          x-y-z
+; CHECK-NEXT: producer        none
diff --git a/llvm/tools/llvm-offload-binary/CMakeLists.txt b/llvm/tools/llvm-offload-binary/CMakeLists.txt
new file mode 100644
index 0000000000000..6f46f1b5c570f
--- /dev/null
+++ b/llvm/tools/llvm-offload-binary/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(LLVM_LINK_COMPONENTS
+  BinaryFormat
+  Object
+  Support)
+
+add_llvm_tool(llvm-offload-binary
+  llvm-offload-binary.cpp
+
+  DEPENDS
+  intrinsics_gen
+  )
+# Legacy binary name to be removed at a later release.
+add_llvm_tool_symlink(clang-offload-packager llvm-offload-binary)
diff --git a/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp b/llvm/tools/llvm-offload-binary/llvm-offload-binary.cpp
similarity index 90%
rename from clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
rename to llvm/tools/llvm-offload-binary/llvm-offload-binary.cpp
index 64b058ec7bdba..b1bc335fe5b9e 100644
--- a/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
+++ b/llvm/tools/llvm-offload-binary/llvm-offload-binary.cpp
@@ -1,18 +1,17 @@
-//===-- clang-offload-packager/ClangOffloadPackager.cpp - file bundler ---===//
+//===-- llvm-offload-binary.cpp - offload binary management utility -------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 //
 // This tool takes several device object files and bundles them into a single
 // binary image using a custom binary format. This is intended to be used to
-// embed many device files into an application to create a fat binary.
+// embed many device files into an application to create a fat binary. It also
+// supports extracting these files from a known location.
 //
-//===---------------------------------------------------------------------===//
-
-#include "clang/Basic/Version.h"
+//===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/BinaryFormat/Magic.h"
@@ -32,37 +31,32 @@ using namespace llvm::object;
 
 static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
 
-static cl::OptionCategory
-    ClangOffloadPackagerCategory("clang-offload-packager options");
+static cl::OptionCategory OffloadBinaryCategory("llvm-offload-binary options");
 
 static cl::opt<std::string> OutputFile("o", cl::desc("Write output to <file>."),
                                        cl::value_desc("file"),
-                                       cl::cat(ClangOffloadPackagerCategory));
+                                       cl::cat(OffloadBinaryCategory));
 
 static cl::opt<std::string> InputFile(cl::Positional,
                                       cl::desc("Extract from <file>."),
                                       cl::value_desc("file"),
-                                      cl::cat(ClangOffloadPackagerCategory));
+                                      cl::cat(OffloadBinaryCategory));
 
 static cl::list<std::string>
     DeviceImages("image",
                  cl::desc("List of key and value arguments. Required keywords "
                           "are 'file' and 'triple'."),
                  cl::value_desc("<key>=<value>,..."),
-                 cl::cat(ClangOffloadPackagerCategory));
+                 cl::cat(OffloadBinaryCategory));
 
 static cl::opt<bool>
     CreateArchive("archive",
                   cl::desc("Write extracted files to a static archive"),
-                  cl::cat(ClangOffloadPackagerCategory));
+                  cl::cat(OffloadBinaryCategory));
 
 /// Path of the current binary.
 static const char *PackagerExecutable;
 
-static void PrintVersion(raw_ostream &OS) {
-  OS << clang::getClangToolFullVersion("clang-offload-packager") << '\n';
-}
-
 // Get a map containing all the arguments for the image. Repeated arguments will
 // be placed in a comma separated list.
 static DenseMap<StringRef, StringRef> getImageArguments(StringRef Image,
@@ -115,9 +109,11 @@ static Error bundleImages() {
       // Clang uses the '.o' suffix for LTO bitcode.
       if (identify_magic((*ObjectOrErr)->getBuffer()) == file_magic::bitcode)
         ImageBinary.TheImageKind = object::IMG_Bitcode;
-      else
+      else if (sys::path::has_extension(File))
         ImageBinary.TheImageKind =
             getImageKind(sys::path::extension(File).drop_front());
+      else
+        ImageBinary.TheImageKind = IMG_None;
       ImageBinary.Image = std::move(*ObjectOrErr);
       for (const auto &[Key, Value] : Args) {
         if (Key == "kind") {
@@ -222,15 +218,19 @@ static Error unbundleImages() {
 
 int main(int argc, const char **argv) {
   sys::PrintStackTraceOnErrorSignal(argv[0]);
-  cl::HideUnrelatedOptions(ClangOffloadPackagerCategory);
-  cl::SetVersionPrinter(PrintVersion);
+  cl::HideUnrelatedOptions(OffloadBinaryCategory);
   cl::ParseCommandLineOptions(
       argc, argv,
       "A utility for bundling several object files into a single binary.\n"
       "The output binary can then be embedded into the host section table\n"
       "to create a fatbinary containing offloading code.\n");
 
-  if (Help) {
+  if (sys::path::stem(argv[0]).ends_with("clang-offload-packager"))
+    WithColor::warning(errs(), PackagerExecutable)
+        << "'clang-offload-packager' is deprecated. Use 'llvm-offload-binary' "
+           "instead.\n";
+
+  if (Help || (OutputFile.empty() && InputFile.empty())) {
     cl::PrintHelpMessage();
     return EXIT_SUCCESS;
   }
diff --git a/llvm/utils/gn/secondary/clang/tools/clang-offload-packager/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/clang-offload-packager/BUILD.gn
deleted file mode 100644
index b33b534fde46b..0000000000000
--- a/llvm/utils/gn/secondary/clang/tools/clang-offload-packager/BUILD.gn
+++ /dev/null
@@ -1,10 +0,0 @@
-executable("clang-offload-packager") {
-  configs += [ "//llvm/utils/gn/build:clang_code" ]
-  deps = [
-    "//clang/lib/Basic",
-    "//llvm/lib/Object",
-    "//llvm/lib/Support",
-    "//llvm/lib/Target:TargetsToBuild",
-  ]
-  sources = [ "ClangOffloadPackager.cpp" ]
-}
diff --git a/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn
index 6f00fcac4cd54..54fca3bf1f50b 100644
--- a/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn
+++ b/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn
@@ -60,7 +60,6 @@ driver_executable("clang") {
     "//clang/tools/clang-linker-wrapper",
     "//clang/tools/clang-nvlink-wrapper",
     "//clang/tools/clang-offload-bundler",
-    "//clang/tools/clang-offload-packager",
     "//llvm/include/llvm/Config:llvm-config",
     "//llvm/lib/Analysis",
     "//llvm/lib/CodeGen",



More information about the flang-commits mailing list