Comprehensive technical documentation covering: - Hardware: OCS/ECS/AGA custom chip registers, Copper & Blitter deep dives - Boot sequence: cold boot through startup-sequence - Binary format: HUNK executable spec, relocation, debug info - Linking & ABI: .fd files, LVO tables, register calling conventions - Exec kernel: tasks, interrupts, memory, signals, semaphores - AmigaDOS: file I/O, FFS/OFS layout, CLI/Shell scripting - Graphics: planar bitmaps, Copper programming, HAM/EHB modes - Intuition: screens, windows, IDCMP, BOOPSI - Devices: trackdisk, SCSI, serial, timer, audio, keyboard - Libraries: utility, expansion, IFFParse, locale, ARexx - Networking: bsdsocket API, SANA-II, TCP/IP stack comparison - Toolchain: GCC, vasm/vlink, SAS/C, NDK, debugging - Reverse engineering: IDA/Ghidra setup, compiler fingerprints, case studies - CPU & MMU: 68040/060 emulation libs, PMMU, cache management - Driver development: SANA-II, Picasso96/RTG, AHI audio All files include breadcrumb navigation. No local paths or proprietary content.
3.7 KiB
Reconstructing Library JMP Tables
Overview
Every AmigaOS library has a JMP table at negative offsets from its base pointer. Reconstructing this table maps LVOs to function names and is essential for identifying all OS calls made by a binary under analysis.
JMP Table Layout
lib_base - N*6: JFF xxxx xxxx ; JMP to function N (6 bytes)
...
lib_base - 24: JMP Reserved()
lib_base - 18: JMP Expunge()
lib_base - 12: JMP Close()
lib_base - 6: JMP Open()
lib_base + 0: struct Library ; lib_Node, lib_Version, ...
Each entry is a 68k JMP (abs.l) — opcode 4EF9 followed by a 4-byte absolute address, totalling 6 bytes. Hence LVO = −6 × slot_index.
Finding the Library Base
From SysBase LibList
The exec.library maintains a doubly-linked list at SysBase→LibList:
struct ExecBase {
...
struct List LibList; /* offset +378 — list of open libraries */
...
};
/* Walk the list: */
struct Node *n = SysBase->LibList.lh_Head;
while (n->ln_Succ) {
struct Library *lib = (struct Library *)n;
printf("%s v%d\n", lib->lib_Node.ln_Name, lib->lib_Version);
n = n->ln_Succ;
}
In IDA Pro
After loading, SysBase is at $4. Use Edit → Segments → Create Segment pointed at $4 with type WORD to follow the pointer to ExecBase. Then navigate to LibList at offset +0x17A and walk the linked list.
Reading the JMP Table in IDA
- Know the library base address (e.g.,
DOSBasefrom theOpenLibraryresult) - Navigate to
lib_base - 6— first user function slot - IDA shows
JMP sub_XXXXXX— the target is the actual function implementation - Rename each
sub_with the function name from the LVO table
Automated Script: apply_lvo_names.py
import idaapi, idc
LVO_DOS = {
-30: "Open", # LVO -30 = Open(name, mode) d1/d2
-36: "Close",
-42: "Read",
-48: "Write",
-54: "Input",
-60: "Output",
-126: "WaitForChar",
-138: "Delay",
# ... extend from dos_lib.fd
}
DOS_BASE = idc.get_name_ea_simple("_DOSBase")
dos_ptr = idc.get_wide_dword(DOS_BASE)
for lvo, name in LVO_DOS.items():
jmp_entry = dos_ptr + lvo
# read the JMP target: opcode at jmp_entry is 4EF9, target at +2
target = idc.get_wide_dword(jmp_entry + 2)
idc.set_name(target, f"dos_{name}", idaapi.SN_NOWARN)
print(f"LVO {lvo:+d}: {name} → {target:#010x}")
Mapping LVO → Function via .fd Files
NDK39 .fd files define the exact register assignments and bias (LVO offset):
## NDK39/fd/dos_lib.fd (excerpt)
##base _DOSBase
##bias 30
##public
Open(name,accessMode)(d1,d2)
##bias 36
Close(file)(d1)
##bias 42
Read(file,buffer,length)(d1,d2,d3)
##bias 48
Write(file,buffer,length)(d1,d2,d3)
The ##bias value is the positive LVO — the actual call offset is −bias.
JSR −LVO(A6) Pattern in Disassembly
; Typical OS call site in disassembly:
MOVEA.L (_DOSBase).L, A6
JSR (-30,A6) ; Open(d1=name, d2=mode)
; D0 = file handle (BPTR) or 0 on error
In IDA, this appears as jsr ($fffffffe2,a6) with displacement -30 ($FFFFFFE2 in two's complement 16-bit). Applying LVO names makes this jsr (Open,a6).
Common Library Bases and LVO Tables
See ../../../04_linking_and_libraries/lvo_table.md for complete LVO offset tables for:
exec.librarydos.librarygraphics.libraryintuition.library
References
- NDK39:
fd/directory — all library.fdfiles 04_linking_and_libraries/lvo_table.md- ADCD 2.1:
Libraries_Manual_guide/ - IDA Pro scripting:
idc.pyreference