User Tools

Site Tools


wswan:guide:elf_quirks

wswan toolchain ELF quirks

The ELF format created by Wonderful has some quirks, owing both to the non-upstream binutils fork used and to the specifics of the ROM format itself.

In general, gcc-ia16 ELF files follow the 32-bit x86 ELF format.

Segment relocations

binutils-ia16 introduces a custom set of relocations to support segmentation - the segelf specification as proposed by H. Peter Anvin. In particular, ELFs emitted by Wonderful currently use the following relocations:

  • R_386_32 (in DWARF debug sections; uses 32-bit ELF addresses above)
  • R_386_16
  • R_386_PC16
  • R_386_SEG16 (segelf)
  • R_386_SUB16 (segelf)

In addition, R_386_SUB32 relocations are improperly emitted in DWARF debug sections by some versions of the toolchain; these should be ignored.

More extensive documentation for these relocations is available here.

Address space (wswan)

ELF addresses 0x80000000 - 0xFFFFFFFF correspond to addresses in ROM.

31                 bit                 0
 ---- ---- ---- ---- ---- ---- ---- ----
 1bbb bbbb bbbb cccc cccc cccc cccc cccc
  ||| |||| |||| |||| |||| |||| |||| ||||
  ||| |||| |||| ++++-++++-++++-++++-++++- CPU address (bits 0-19)
  +++-++++-++++-------------------------- 64KB ROM bank (bits 30-20)
                                          Corresponds to banks 000 - 7FF (128 MB maximum)
                                          The last ROM bank uses addresses FFFxxxxx

To turn this into a physical address in the cartridge ROM's space, you should use the following equation: ((addr & 0xFFFF) | ((addr & 0x7FF00000) >> 4)) & rom_mask.

The high four bits of the CPU address are ignored for physical ROM address transformations. This is because their purpose is to tell the compiler/linker at what address the CPU accesses the 64KB bank, not where it is physically stored on the cartridge. For example:

  • The ELF address FFFF0000 means ROM bank 7FF, offset 0000, accessed at F0000 by the CPU,
  • The ELF address FFF30000 means ROM bank 7FF, offset 0000, accessed at 30000 by the CPU.

ELF addresses 0x00000000 - 0x0000FFFF correspond to IRAM addresses.

31                 bit                 0
 ---- ---- ---- ---- ---- ---- ---- ----
 0000 0000 0000 0000 cccc cccc cccc cccc
                     |||| |||| |||| ||||
                     ++++-++++-++++-++++- IRAM address (bits 0-15)

ELF addresses 0x00n10000 - 0x00n1FFFF currently correspond to SRAM addresses (where n is the SRAM bank), but this may be changed in a future version, so please don't rely on it.

Address space (wwitch)

All of this may be changed in a future version, so please don't rely on it.

ELF VMA addresses 0x00000000 - 0x0000FFFF correspond to the 64K of code placed in NOR flash.

ELF VMA addresses 0x00010000 - 0x0001FFFF correspond to the 64K of data placed in SRAM.

wswan/guide/elf_quirks.txt · Last modified: 2024/09/22 11:58 by asie