Introduction
The loader puts each hunk wherever memory is free, so a program cannot know the address of its own data. Code that refers to another place with an absolute address (lea table,a0,
jsr helper, a table of pointers) has the offset inside the target hunk in a long in the file, and the hunk’s relocation block lists where those longs
are. The loader adds the target hunk’s address to each. Branches and (pc) references are relative and need nothing.
HUNK_RELOC32
Groups, then a zero. Each group is three parts, all longs:
| Part | Meaning |
|---|---|
| Count N | How many offsets follow; 0 ends the block. |
| Target hunk | The number of the hunk whose address is added (hunk numbers as in the header). |
| N offsets | Byte offsets inside the hunk the block belongs to; the long at each offset gets the target’s address added. |
The block belongs to the code or data hunk before it. A BSS hunk has none. The vasm assembler writes this block in this form (its reloc_hunk routine).
The short forms
HUNK_RELOC32SHORT ($3FC) has the same groups with words instead of longs: a word count, a word target, and word offsets; a word 0 ends it. If the block
then ends in the middle of a long, one padding word of zero follows, so the next block starts on a long boundary. The amiga-dev wiki says HUNK_DREL32 ($3F7) is handled like the short form
in a load file, and vasm’s source writes its short relocations under that id, with a comment that it is the short relocation block for OS 2.0. The viewer therefore reads $3F7 in an executable as the
short absolute relocation, and in an object file as the long data-relative form. The short form can only hold offsets below 64 KiB and fewer than 65,536 offsets per target hunk; vasm writes the long form for a hunk that does not fit.
The amitools reader also reads HUNK_RELRELOC32 ($3FD) in the short layout. For HUNK_ABSRELOC16 ($3FE) the two sources that describe it disagree
(the amiga-dev wiki: the short layout; amitools: the long layout); the viewer reads it as the short layout and no real file here uses it.
The other relocation blocks
| Id | Name | Layout | Used in |
|---|---|---|---|
$3EC | HUNK_RELOC32 | long groups | executables and object files |
$3ED | HUNK_RELOC16 | long groups | object files; a load file with it is refused (amiga-dev wiki) |
$3EE | HUNK_RELOC8 | long groups | object files; refused in a load file |
$3F7 | HUNK_DREL32 | short in an executable, long in an object file | data-relative 32-bit, or the short absolute form |
$3F8 | HUNK_DREL16 | long groups | object files (not used in load files) |
$3F9 | HUNK_DREL8 | long groups | object files (not used in load files) |
$3FC | HUNK_RELOC32SHORT | short groups, padded to a long | executables |
$3FD | HUNK_RELRELOC32 | short groups | PC-relative 32-bit |
$3FE | HUNK_ABSRELOC16 | short groups (sources disagree) | 16-bit absolute |
$4EC | HUNK_RELRELOC26 | long groups | PowerPC branches (extended hunk format) |
In the viewer
The relocations table lists every group: the hunk it is in, the block, the target hunk, the count and the first offsets. In the disassembly, an instruction that holds a relocated long carries the note
reloc -> hunk N + $value, and the name of a symbol of the target hunk at that value when there is one. With the option “hunk-relative” (the default) the value printed in the instruction
is what the file holds, an offset into hunk N, and the viewer does not give it the name of a symbol in the code’s own hunk. With “hunks one after another from the base” the viewer adds each target hunk’s
address to the relocated longs, as the loader would if the hunks were consecutive from the base address, so the addresses and symbol names are those of that layout.
A relocated value is expected to lie in the target hunk. The viewer reports an offset in the list that runs past its hunk, a target hunk the file does not have, and a value more than 32 KiB outside
the target. In the real files it was tested on (2,547 files, 354,881 relocated longs), no relocation offset ran past its hunk and no target was missing, but values beyond the target occurred:
46 values are small negative numbers (a pointer to “table minus 8”, added modulo 232) and 51 are up to $7FFE past the end of the target (a base register set to the middle of the data so that
16-bit displacements reach all of it), which is why the tolerance is 32 KiB.
Not described
Known, not yet covered
- Reference: what the loader does with each non-32-bit relocation kind in object files (that is the linker’s part), and the layout of
HUNK_ABSRELOC16, on which the sources disagree. - Viewer: only the absolute 32-bit blocks (
$3EC,$3FC, and$3F7in an executable) change the addresses in the “one after another” layout; the other kinds are listed and noted, not applied.
Links
Reference
- Hunk file format – amiga-dev wiki: RELOC32, RELOC32SHORT, DREL32 and what the loader accepts
- amitools hunk reader – the long and short group layouts
- vasm – the assembler whose
output_hunk.cwrites both forms