This is part 6 of SoftGPU. HIP applications ship device binaries, not source. SoftGPU cannot “run a kernel” until it can safely identify which ELF notes and metadata describe that kernel — without inventing fields or decoding ISA prematurely.

Fat binary versus code object

HIP fat binary / bundle
    └── one or more device images
            └── AMDGPU code object (ELF)
                    ├── machine-code sections (ISA — SoftGPU does not execute yet)
                    └── notes: AMDGPU / NT_AMDGPU_METADATA (MessagePack)

A code object is the ELF image the HSA loader registers. SoftGPU reads the metadata note, not the ISA bytes. Finding a kernel name is not proof SoftGPU can execute it. The inspect tool prints JSON labeled metadata_only_no_isa_execution.

The notes that matter

For code-object V3+ (LLVM AMDGPUUsage):

OwnerTypePayload
AMDGPUNT_AMDGPU_METADATA (32)MessagePack map

Important keys:

  • amdhsa.version — SoftGPU accepts [1,0]…[1,2]
  • amdhsa.target — SoftGPU requires a gfx1201 substring
  • amdhsa.kernels[] — name, symbol, kernarg/group/private sizes, .args

amdhsa.target strings look like amdgcn-amd-amdhsa--gfx1201. The gate is intentionally narrow: gfx1201 only. Other targets are rejected with UnsupportedTarget, not silently coerced.

Why bounds matter

Code objects are untrusted input. SoftGPU uses a bounded ELF walker and MessagePack decoder: file size, section count, note count, string/map/array limits, recursion depth. Oversized or exotic encodings fail closed. A parser that panics on junk is a vulnerability, not a GPU.

Details live in code-object.md. Fixtures sit under fixtures/amd-code-object/.

What this enables next

Inspection is the prerequisite for two different later paths. One is a disclosed functional IR that is not “run the code object.” The other is architectural ISA for a named subset, with goldens from llvm-mc. Neither path is implied by successfully printing a kernel name.

Next: emulation versus simulation.

Canonical: thanos.github.io.