ELF specification

From llvm-mos
Jump to navigation Jump to search

ELF specification for MOS-compatible processors[edit | edit source]

This is version 0.1.4 of this specification.

Comments and improvements are solicited at johnwbyrd at gmail dot com.

Overview[edit | edit source]

This is a specification to extend the Executable and Linking Format (ELF) to encompass the MOS family of processors and their relatives. These include, but are not limited to, the MOS 6502, the MOS 65816, and comparable processors.

This specification considers the following documents to be normative, and incorporates them by reference:

ELF header[edit | edit source]

The EI_CLASS field of the e_ident[] identification index, as defined in the ELF header, should be set to ELFCLASS32, which has a value of 1. This identifies ELF files as having (at most) 32 bits of address space.

Although the ELF format encompasses 32-bit address types, it does not require them. MOS processors can access 16 bits by default and 24 bits at most. When an 8-bit, 16-bit, or 24-bit address is stored in a 32-bit ELF address type, the unused high bits should be zeroed.

Unused bits in any 32-bit ELF address field should be set to zero. If these unused bits are set in any ELF file, then tool behavior is undefined. However, if a tool detects that these unused bits are set, then this condition may be flagged as a warning or as an error by the tool.

Machine type field[edit | edit source]

The e_machine field should have a constant name of EM_MOS. The constant of EM_MOS shall be set to 6502 (hexadecimal, 0x1966).

The e_flags field bits should have the following meanings. These values may be logically OR'ed to indicate that multiple features are present.

e_flags bit fields
Name Value Description
EM_MOS_6502 0x00000001 MOS 6502 "generic" instructions, also known as NMOS 6502, as defined in the MCS6500 Microcomputer Family Programming Manual, Second Edition. This bit should be set, unless the target architecture is incapable of running 6502 family instructions, such as would be the case in a virtual machine such as SWEET16 or bbcvm.
EM_MOS_6502_BCD 0x00000002 MOS 6502 compatible BCD (binary coded decimal) instruction handling, including CLD and SED instructions for the 6502 series. For most 6502 compatible cores, this bit should be set to one, to indicate that BCD mode support is present on the target processor. However, some 6502 near-compatible cores, such as the Ricoh 2A0x, have their BCD mode disabled; this bit should be set to zero if the target core is not expected to support BCD. This bit may be set to one only if the EM_MOS_6502 bit is set to one.
EM_MOS_6502X 0x00000004 NMOS 6502 "illegal" opcodes including ALR, ANC, ARR, AXS, DCP, ISC, LAS, LAX, RLA, RRA, SAX, SLO, and SRE, as defined in the Illegal Opcodes section of the 6502/6510/8500/8502 Opcode matrix. This bit may be set to one only if the EM_MOS_6502 bit is set to one.
EM_MOS_65C02 0x00000008 MOS 65C02 generic additional instructions and addressing modes, including BRA, PHX, PHY, PLX, PLY, STZ, TRB, TSB, as defined in Programming the 65816, Including the 6502, 65C02 and 65802 and 65C02 Opcodes. This bit may be set to one only if the EM_MOS_6502 bit is set to one.
EM_MOS_R65C02 0x00000010 MOS 65C02 Rockwell/WDC additional instructions, including BBR, BBS, RMB, and SMB, as defined in 65C02 Opcodes. This bit may be set to one only if the EM_MOS_6502 and EM_MOS_65C02 bits are set to one.
EM_MOS_W65C02 0x00000020 MOS 65C02 WDC only instructions, including STP and WAI, as defined in 65C02 Opcodes. This bit may be set to one only if the EM_MOS_6502, EM_MOS_65C02, and EM_MOS_R65C02 bits are set to one.
EM_MOS_W65816 0x00000100 MOS 65C816 native mode instructions and addressing modes, as defined in Programming the 65816, Including the 6502, 65C02 and 65802 and 65C816 Opcodes. This bit may be set to one only if the following bits are set to one: EM_MOS_6502, EM_MOS_65C02, EM_MOS_R65C02, EM_MOS_W65C02.
EM_MOS_65EL02 0x00000200 65EL02 only instructions and addressing modes, including ASW, DEW, DEZ, INW, INZ, as defined in 64tass reference manual. This bit may be set to one only if the EM_MOS_6502, EM_MOS_65C02, and EM_MOS_R65C02 bits are set to one.
EM_MOS_65CE02 0x00000400 65CE02 only instructions, as defined in 64tass reference manual. This bit may be set to one only if the EM_MOS_6502, EM_MOS_65C02, and EM_MOS_R65C02 bits are set to one.

Behavior of a binary resulting from linking incompatible combinations of e_flags values, is undefined. Linkers are suggested, but not required, to emit warnings when a flag mismatch exists between ELF objects, libraries, and/or executables.

Section flags[edit | edit source]

Each ELF section header contains a 32-bit word named sh_flags. For MOS-format ELF files, these flags have special meanings.

e_flags bit fields
Name Value Description
SHF_MOS_ZEROPAGE 0x10000000 This bit should be set to one if this ELF section is to be placed in zero page or direct page. An assembler or linker may use this information to determine whether addresses in this section will be 8 bits long.

Relocation types[edit | edit source]

Relocations should behave as specified in the Relocations section of the ELF specification as described earlier. Each relocation entry in a MOS ELF file describes a particular MOS relocation. The lowest byte in the r_info field in an Elf32_Rel or Elf32_Rela relocation entry, is treated as a MOS-specific relocation type. (The ELF specification refers to this as the ELF32_R_TYPE macro.)

The exact types of MOS-specific relocations for ELF can be viewed in MOS.def as part of the llvm-mos distribution.

Name Value Description
R_MOS_NONE 0 No relocation type. Should not be emitted by the writer. Readers should recognize this as an error in the ELF file.
R_MOS_IMM8 1 An 8-bit immediate value.
R_MOS_ADDR8 2 An 8-bit (e.g. zero page or direct page) address.
R_MOS_ADDR16 3 A 16-bit address. Standard for most MOS processors.
R_MOS_ADDR16_LO 4 The least significant byte of a 16-bit address. All MOS processors are little endian, so this would also be the leftmost byte in a 16-bit address.
R_MOS_ADDR16_HI 5 The most significant byte of a 16-bit address.
R_MOS_PCREL_8 6 An 8-bit PC-relative jump value, calculated from the end of the instruction. From the beginning of the instruction, the jump range is [-126, +129]. Used for the B?? series of MOS instructions.
R_MOS_ADDR24 7 A 24-bit address, used in the 65816 series.
R_MOS_ADDR24_BANK 8 The 8-bit bank value from a 24-bit address. The most significant byte.
R_MOS_ADDR24_SEGMENT 9 The 16-bit segment value from a 24-bit address.
R_MOS_ADDR24_SEGMENT_LO 10 The low byte from the segment value in a 24-bit address.
R_MOS_ADDR24_SEGMENT_HI 11 The high byte from the segment value in a 24-bit address.
R_MOS_FK_DATA_4 12 A generic four-byte, 32-bit value. Although MOS does not use native 32-bit relocations, DWARF may use this relocation type when describing debug information.
R_MOS_FK_DATA_8 13 A generic eight-byte, 64-bit value. Although MOS does not use native 64-bit relocations, DWARF may use this relocation type when describing debug information.

References[edit | edit source]

Commodore Semiconductor Group CSG65CE02 Technical Reference

MCS6500 Family Microcomputer Programming Manual, January 1976

Tool Interface Standard (TIS), Executable and Linking Format (ELF) Specification, Version 1.2