Hunk Version and Stack Cookies¶
Two magic ASCII strings embedded inside any Hunk segment provide metadata that AmigaDOS components parse at run time, even though the loader itself ignores them. Both are scanned by string-search, so they can live anywhere in a segment.
The version cookie: $VER:¶
Scanned by the Version command (and by any tool that needs the version of a ROM module, executable, or library). Format:
$VER: <name> <version>.<revision>[(<day>.<month>.<year>)[ <comment>]]
Each field is a decimal ASCII token. Whitespace (one or more spaces or tabs) separates fields. The string is terminated by \0, \n, or \r. Everything after $VER: is technically optional, but the cookie is not useful without the version number.
| Field | Constraint |
|---|---|
name |
Terminated by \0, \n, \r, or the first digit (0–9). |
version |
Major version as decimal ASCII. |
revision |
Minor revision as decimal ASCII. |
day |
1–31. |
month |
1–12. |
year |
Two or four digits; Version treats values below 1900 as 2-digit and adds 2000 if < 78, else 1900. |
Example:
const char version[] = "$VER: MyProgram 45.3 (12.9.2023) (c) THOR";
The string after the date is a comment, not printed by Version unless invoked with the FULL argument.
The cookie is scanned by string-search, so the compiler/linker places it in the read-only data segment of the program and the linker resolves it via HUNK_EXT + EXT_ABS (or, less commonly, HUNK_SYMBOL for debuggers). The $VER: magic itself is just a byte sequence — there is no hunk type for it.
Don't make
$VER:aconst char *pointing at stack or heap —Versionwalks the segment list and reads whatever is at the segment addresses. Use a globalconst char[]or__attribute__((section))placement to keep it in the binary.
The stack cookie: $STACK:¶
Scanned by the Workbench, the Shell, and GetDeviceProc() (when loading handlers). Format:
$STACK: <stack_size_bytes>
| Field | Constraint |
|---|---|
stack_size_bytes |
Required minimum stack size, ASCII decimal. |
If found, the program is started with at least this many bytes of stack. The cookie never decreases the stack — it can only raise the lower bound. Other sources of stack size (Workbench icon Stack, Shell Stack, mountlist STACKSIZE) are honoured and can override upward.
Example:
const char stack[] = "$STACK: 8192"; /* ensure ≥ 8 KB stack */
ScanStackToken — programmatic scanning¶
LONG ScanStackToken(BPTR segment, LONG defaultstack); /* V47 */
Walks the singly-linked segment list starting at segment (typically the result of LoadSeg()) for a $STACK: cookie. Returns the maximum of defaultstack and any stack value found in a cookie. If no cookie is present, returns defaultstack unchanged.
Use this when launching a child binary to compute its stack size before CreateNewProc().
BCPL runtime binding (legacy)¶
Older BCPL handlers and the (now-deprecated) CLI resident segment are launched through AmigaDOS' BCPL runtime binder, which scans the first segment for an "initialization data" trailer. The binder:
- Reads the first long-word of the first segment as a byte offset to the start of the initializer list (the offset is reused as the first 68K opcode — small offsets encode harmless
ORIopcodes, which is why the mechanism works even though the offset is technically not a valid 68K instruction). - Reads the initializer list backwards from that offset. The list is a series of
(offset, gv_index)pairs;offset == 0terminates the list. The first long-word before the list is the GV size to validate against. - Populates the BCPL Global Vector with the listed function addresses.
Modern C/assembler handlers must not rely on this. They are started from the first byte of the first segment, with the startup DosPacket available in their process's pr_MsgPort. The mountlist keyword GLOBVEC controls which path is taken:
GLOBVEC |
Startup mechanism |
|---|---|
-1 or -2 |
C/assembler — process started at offset 0, packet in pr_MsgPort |
0 or -3 |
BCPL — process started through GV entry #1, packet in register d1 |
A dual-mode handler (used by the FFS to support both OFS-floppy BCPL and partition-based C startups) places a stub at offset 0 that branches around the BCPL initializer trailer, with the trailer present later in the segment for the BCPL startup path.
See Also¶
- AmigaDOS Hunk Binary Format
- Hunk Object and Link-Library Format
- AmigaOS Hunk Overlays
- BPTR, BSTR, and BCPL Legacy
- SAS/C Compiler Reference
Sources: Thomas Richter, "ROM Kernel Reference Manual: AmigaDOS" (First Edition, 2024), Chapter 11.5 — Structures within Hunks.
Raw: raw/rkm/rkm-dos-book.md
Updated: 2026-10-02