====== 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 [[https://codeberg.org/tkchia/build-ia16/src/branch/master/elf16-writeup.md|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.