AmigaDOS Hunk Binary Format

AmigaDOS executables, linkable object files, and link libraries all use the Hunk format — a stream of big-endian 32-bit (long-word) identifiers followed by typed data, interpreted by the loader (LoadSeg()). This article documents the format from the 2024 ROM Kernel Reference Manual (Ch. 11), which is the only complete public specification.

Top-level structure

Every executable is a sequence of long-word hunk identifiers. The first 2 bits of each identifier are ignored (masked out). An executable must begin with HUNK_HEADER, and loading terminates on end-of-file, HUNK_BREAK, HUNK_OVERLAY, or an error. The loader dispatches on the hunk type:

if (af) { /* bit 29 (HUNKB_ADVISORY) set: skip this hunk */ }
else if (h == HUNK_END)        i++;                 /* advance to next segment */
else if (h == HUNK_BREAK)      break;               /* terminate an overlay */
else if (h == HUNK_NAME)       parse_NAME;
else if (h == HUNK_CODE)       parse_CODE;
else if (h == HUNK_DATA)       parse_DATA;
else if (h == HUNK_BSS)        parse_BSS;
else if (h == HUNK_RELOC32)    parse_RELOC32;
else if (h == HUNK_SYMBOL)     parse_SYMBOL;
else if (h == HUNK_DEBUG)      parse_DEBUG;
else if (h == HUNK_OVERLAY)    { parse_OVERLAY; break; }
else if (h == HUNK_RELRELOC32) parse_RELRELOC32;
else                           ERROR_BAD_HUNK;

Hunk type constants

All are defined in dos/doshunks.h. Values are big-endian long-words:

Constant Value Purpose
HUNK_UNIT 0x3e7 Unit (object-file grouping)
HUNK_NAME 0x3e8 Named hunk
HUNK_CODE 0x3e9 Executable code + constant data (text segment)
HUNK_DATA 0x3ea Initialized non-constant data
HUNK_BSS 0x3eb Zero-initialized data (no payload)
HUNK_RELOC32 0x3ec 32-bit absolute relocation
HUNK_RELOC16 0x3ed 16-bit relocation (object files)
HUNK_RELOC8 0x3ee 8-bit relocation (object files)
HUNK_EXT 0x3ef External symbol references (object files)
HUNK_SYMBOL 0x3f0 Symbol table (debugging)
HUNK_DEBUG 0x3f1 Hunk-format debug info
HUNK_END 0x3f2 Terminate a segment
HUNK_HEADER 0x3f3 File/segment header (first hunk)
HUNK_OVERLAY 0x3f5 Overlay data
HUNK_BREAK 0x3f6 Terminate an overlay
HUNK_DRELOC32 0x3f7 32-bit "compatibility" relocation (preferred over the short variant)
HUNK_DRELOC16 0x3f8 16-bit deprecated relocation
HUNK_DRELOC8 0x3f9 8-bit deprecated relocation
HUNK_LIB 0x3fa Link-library data
HUNK_INDEX 0x3fb Link-library index
HUNK_RELOC32SHORT 0x3fc 16-bit-offset relocation (efficient; broken id until V39)
HUNK_RELRELOC32 0x3fd 32-bit relative relocation (V39, defective — avoid)

HUNK_HEADER (0x3f3)

The first hunk of every executable. It declares the segment count and per-segment memory requirements:

Size (bits) Field Meaning
32 0 Reserved; legacy run-time library binding (removed in Kickstart v36)
32 tsize Number of segments ([1, 2³¹−1])
32 tnum First segment index to load
32 tmax Last segment index to load (inclusive)
per seg mt[j] Memory type (2 bits)
per seg ms[j] Segment size in long-words

For a regular (non-overlaid) file there is a single HUNK_HEADER, tnum is 0, and tmax is tsize − 1.

Memory type bits map directly to exec flags: 00MEMF_ANY, 01MEMF_CHIP, 10MEMF_FAST. If both bits are 1, an additional long word provides the memory type explicitly (introduced in V36).

Code, Data, and BSS hunks

  • HUNK_CODE (0x3e9) — compiled code and constant data. The first segment of an executable should be a HUNK_CODE starting with a valid opcode, since execution begins at offset 0 of the first segment.
  • HUNK_DATA (0x3ea) — initialized non-constant data.
  • HUNK_BSS (0x3eb) — zero-initialized data; carries no payload, only a size.

HUNK_CODE/HUNK_DATA each carry a size l (in long-words) followed by l long-words of payload. The payload size may be less than the segment size reserved by HUNK_HEADER; excess bytes are zero-initialized (V36+). Due to a loader bug, that zero-initialization is skipped when l is 0.

Relocations

  • HUNK_RELOC32 (0x3ec) — 32-bit absolute relocations (the common case in executables).
  • HUNK_RELOC32SHORT (0x3fc) — 16-bit offsets, more compact. It was given the wrong hunk identifier until V39 fixed it.
  • HUNK_RELRELOC32 (0x3fd) — 32-bit relative relocation (V39), but its implementation is defective and limited to 16-bit offsets; avoid it.
  • HUNK_DRELOC32 (0x3f7) — the recommended compatibility choice: such binaries also load under V36 (including the fixed V39).

The segment list

LoadSeg() returns a BPTR to a singly-linked segment list. The first four bytes of every segment are a BPTR to the next segment; the last segment's link is ZERO. C and assembler entry points begin at offset 0 of the first segment. Release the list with UnLoadSeg().

BPTR LoadSeg(STRPTR name);              /* returns BPTR to first segment, ZERO on failure */
BPTR NewLoadSeg(STRPTR file, struct TagItem *tags);   /* V36+, currently no defined tags */
BPTR InternalLoadSeg(BPTR fh, BPTR table, struct LoadSegFuncs *funcs); /* callback-based */
void UnLoadSeg(BPTR seglist);

Loader defects to code around

The LoadSeg()/NewLoadSeg() implementation has a documented history of bugs:

  1. V34 and below zero-initialized only the first 256K of BSS segments, and failed to zero the region beyond payload data in code/data segments.
  2. V36+ fixed initialization, but BSS space trailing code/data hunks is zeroed only if they contain payload. Clear such regions manually or avoid them.
  3. V36+ supports at most 2¹⁶ relocation entries in one array; linker authors should split longer lists into multiple arrays targeting the same hunk.
  4. Do not use HUNK_RELOC32SHORT for binaries that must run under V34 and below; prefer HUNK_DRELOC32 for broad compatibility.

Object files (compiler/assembler output) and link libraries add their own hunks: HUNK_UNIT groups a translation unit; HUNK_EXT holds external symbol references and definitions; HUNK_LIB and HUNK_INDEX structure link libraries. Overlays use HUNK_OVERLAY (injects file info into the first loaded hunk) and HUNK_BREAK (terminates an overlay branch, leaving the file open).

Advisory hunks

Bit 29 (HUNKB_ADVISORY), if set, marks a hunk whose contents are ignored — the following long word gives the size, and that many long-words are skipped. No publicly known tool currently writes them, and V34 and below do not support advisory hunks.

See Also


Sources: Thomas Richter, "ROM Kernel Reference Manual: AmigaDOS" (First Edition, 2024), Chapter 11 — Binary File Structure; Ralph Babel, "The Amiga Guru Book" (1993), Chapter 22 — The Format of Load and Object Modules. Raw: raw/rkm/rkm-dos-book.md; raw/rkm/guru-book.md Updated: 2026-08-08