ELF specification
ELF specification for MOS-compatible processors[edit | edit source]
This is version 0.3.1 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:
- Key words for use in RFCs to Indicate Requirement Levels
- Tool Interface Standard (TIS), Executable and Linking Format (ELF) Specification, Version 1.2
- Semantic Versioning 2.0.0
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 shall have a constant name of EM_MOS. The constant of EM_MOS shall be set to 6502 (decimal; equivalent to 0x1966 in hexadecimal).
The e_flags field bits shall have the following meanings. These values may be logically OR'ed to indicate that multiple features are present.
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 and EM_MOS_65C02 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 EM_MOS_6502, EM_MOS_65C02, and EM_MOS_W65C02 bits are set to one. |
EM_MOS_65EL02 | 0x00000200 | 65EL02 only instructions and addressing modes, as defined in the RedPower CPU Instruction Table This bit may be set to one only if the EM_MOS_6502 and EM_MOS_65C02 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. |
EM_MOS_HUC6280 | 0x00000800 | HuC6280 only instructions, as defined in Chris Covell's opcode matrix reference. 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_65DTV02 | 0x00001000 | Instructions specific to the C64DTV implementation of the 6502, as defined in 64tass reference manual . This bit may be set to one only if the EM_MOS_6502 bit is set to one. |
EM_MOS_4510 | 0x00002000 | CSG 4510 only instructions, as defined in 64tass reference manual. This bit may be set to one only if the EM_MOS_6502, EM_MOS_65C02, EM_MOS_R65C02 and EM_MOS_65CE02 bits are set to one. |
EM_MOS_45GS02 | 0x00004000 | 45GS02 only instructions, as defined in the MEGA65 User Guide. This bit may be set to one only if the EM_MOS_6502, EM_MOS_65C02, EM_MOS_R65C02, EM_MOS_65CE02 and EM_MOS_4510 bits are set to one. |
EM_MOS_SPC700 | 0x00020000 | Instructions used on the Sony SPC700 architecture. As the architecture is similar to, but not binary-compatible with, the 6502, this bit may be set to one only if no other 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.
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_PCREL_16 | 12 | A 16-bit PC-relative jump value, calculated from the end of the instruction. From the beginning of the instruction, the jump range is [-32765, +32770], however, this jump range is wrapped at bank boundaries. Used for the BRL instruction on the 65C816. |
R_MOS_FK_DATA_4 | 13 | 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 | 14 | 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. |
R_MOS_ADDR_ASCIZ | 15 | A null-terminated, decimal ASCII string of the value. Generated by .mos_addr_asciz assember directive. See Assembler for details. |
R_MOS_IMM16 | 16 | A 16-bit immediate value. |
R_MOS_ADDR13 | 17 | A 13-bit address, stored in the low 13 bits of a 16-bit value. Used only on the SPC700. |
Mapping symbols[edit | edit source]
Mapping symbols are regular ELF symbols whose names are prefixed with a string of characters that begins with the symbol $
. They mark the start of a sequence of instructions which are to be interpreted under the assumption of a particular processor mode or function, as denoted by the mapping symbol itself. This functionality is intended to allow utilities working with ELF files to appropriately decode and interpret sequences of instructions whose format or function is affected by CPU state. While various utilities may use mapping symbols in this way, they do not affect runtime behavior and serve only as hints.
The complete list of mapping symbols defined by the specification is listed below:
Name prefix | Type | Description |
---|---|---|
$ml | STT_NOTYPE | 65C816, 65EL02: Indicates the start of a sequence of instructions for which it should be assumed that the M processor flag is set to 0. |
$mh | STT_NOTYPE | 65C816, 65EL02: Indicates the start of a sequence of instructions for which it should be assumed that the M processor flag is set to 1. |
$xl | STT_NOTYPE | 65C816, 65EL02: Indicates the start of a sequence of instructions for which it should be assumed that the X processor flag is set to 0. |
$xh | STT_NOTYPE | 65C816, 65EL02: Indicates the start of a sequence of instructions for which it should be assumed that the X processor flag is set to 1. |
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
65EL02 Instruction Set Extension Reference