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: 00 → MEMF_ANY, 01 → MEMF_CHIP, 10 → MEMF_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 aHUNK_CODEstarting 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:
- 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.
- V36+ fixed initialization, but BSS space trailing code/data hunks is zeroed only if they contain payload. Clear such regions manually or avoid them.
- V36+ supports at most 2¹⁶ relocation entries in one array; linker authors should split longer lists into multiple arrays targeting the same hunk.
- Do not use
HUNK_RELOC32SHORTfor binaries that must run under V34 and below; preferHUNK_DRELOC32for broad compatibility.
Object files and link libraries¶
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