hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit a20e952715d8ce171aea568d63cd3909fbb00c3b
parent f081dc1a05477851b699c1c2c287f894a6fd1ad5
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 16 Feb 2021 17:29:26 -0500

format::elf: initial riggings for new module

Diffstat:
Aformat/elf/types.ha | 446+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 446 insertions(+), 0 deletions(-)

diff --git a/format/elf/types.ha b/format/elf/types.ha @@ -0,0 +1,446 @@ +// An implementation of the ELF64 file format. Best accompanied with a reading +// of the ELF-64 Object Format (Version 1.5). +// +// TODO: +// - Flesh out ELF32 structures +export def MAGIC: str = "\x7FELF"; +export def EI_MAG0: uint = 0; +export def EI_MAG1: uint = 1; +export def EI_MAG2: uint = 2; +export def EI_MAG3: uint = 3; +export def EI_CLASS: uint = 4; +export def EI_DATA: uint = 5; +export def EI_VERSION: uint = 6; +export def EI_OSABI: uint = 7; +export def EI_ABIVERSION: uint = 8; +export def EI_PAD: uint = 9; +export def EI_NIDENT: uint = 16; +export def EV_CURRENT: u32 = 1; + +// ELF header for ELF64 +export type header64 = struct { + // ELF identification + e_ident: [EI_NIDENT]u8, + // Object file type + e_type: elf_type, + // Machine type + e_machine: u16, + // Object file version ([EV_CURRENT]) + e_version: u32, + // Entry point address + e_entry: u64, + // Program header offset + e_phoff: u64, + // Section header offset + e_shoff: u64, + // Processor-specific flags + e_flags: u32, + // ELF header size + e_ehsize: u16, + // Size of program header entry + e_phentsize: u16, + // Number of program header entries + e_phnum: u16, + // Size of section header entry + e_shentsize: u16, + // Number of section header entries + e_shnum: u16, + // Section name string table index, or [shn::UNDEF] + e_shstrndx: u16, +}; + +// Section header for ELF64 +export type section64 = struct { + // Section name + sh_name: u32, + // Section type + sh_type: u32, + // Section attributes + sh_flags: u64, + // Virtual address in memory + sh_addr: u64, + // Offset in file + sh_offset: u64, + // Size of section + sh_size: u64, + // Link to other section + sh_link: u32, + // Miscellaenous information + sh_info: u32, + // Address alignment boundary + sh_addralign: u64, + // Size of entries, if section has table + sh_entsize: u64, +}; + +// ELF file class +export type ident_class = enum u8 { + // 32-bit objects + ELF32 = 1, + // 64-bit objects + ELF64 = 2, +}; + +// Byte ordering +export type ident_data = enum u8 { + // Object file data structures are little-endian + LSB = 1, + // Object file data structures are big-endian + MSB = 2, +}; + +// Application binary interface +export type ident_abi = enum u8 { + // System-V ABI + SYSV = 0, + // HP-UX operating system + HPUX = 1, + // Standalone (embedded) application + STANDALONE = 255, +}; + +// ELF file type +export type elf_type = enum u16 { + // No file type + NONE = 0, + // Relocatable object file + REL = 1, + // Executable file + EXEC = 2, + // Shared object file + DYN = 3, + // Core file + CORE = 4, + // Environment-specific use + LOOS = 0xFE00, + // Environment-specific use + HIOS = 0xFEFF, + // Processor-specific use + LOPROC = 0xFF00, + // Processor-specific use + HIPROC = 0xFFFF, +}; + +// Special section indicies +export type shn = enum u16 { + // Used to mark an undefined or meaningless section reference + UNDEF = 0, + // Processor-specific use + LOPROC = 0xFF00, + // Processor-specific use + HIPROC = 0xFF1F, + // Environment-specific-use + LOOS = 0xFF20, + // Environment-specific-use + HIOS = 0xFF3F, + // Indicates that the corresponding reference is an absolute value + ABS = 0xFFF1, + // Indicates a symbol that has been declared as a common block + COMMON = 0xFFF2, +}; + +// Section type +export type sht = enum u32 { + // Marks an unused section header + NULL = 0, + // Contains information defined by the program + PROGBITS = 1, + // Contains a linker symbol table + SYMTAB = 2, + // Contains a string table + STRTAB = 3, + // Contains "Rela" type relocation entries + RELA = 4, + // Contains a symbol hash table + HASH = 5, + // Contains dynamic linking tables + DYNAMIC = 6, + // Contains note information + NOTE = 7, + // Contains uninitialized space; does not occupy any space in the file + NOBITS = 8, + // Contains "Rel" type relocation entries + REL = 9, + // Reserved + SHLIB = 10, + // Contains a dynamic loader symbol table + DYNSYM = 11, + // Environment-specific use + LOOS = 0x60000000, + // Environment-specific use + HIOS = 0x6FFFFFFF, + // Processor-specific use + LOPROC = 0x7000000, + // Processor-specific use + HIPROC = 0x7FFFFFF, +}; + +// Section flags +export type shf = enum u32 { + // Section contains writable data + WRITE = 0x1, + // Section is allocated in memory image of program + ALLOC = 0x2, + // Section contains executable instructions + EXECINSTR = 0x4, + // Environment-specific use + MASKOS = 0x0F000000, + // Processor-specific use + MASKPROC = 0xF0000000, +}; + +// Symbol table entry +export type sym64 = struct { + // Symbol name offset + st_name: u32, + // Type and binding attributes + st_info: u8, + // Reserved + st_other: u8, + // Section table index + st_shndx: u16, + // Symbol value + st_value: u64, + // Size of object + st_size: u64, +}; + +// Symbol bindings +export type stb = enum u8 { + // Not visible outside the object file + LOCAL = 0, + // Global symbol, visible to all object files + GLOBAL = 1, + // Global scope, but with lower precedence than global symbols + WEAK = 2, + // Environment-specific use + LOOS = 10, + // Environment-specific use + HIOS = 12, + // Processor-specific use + LOPROC = 13, + // Processor-specific use + HIPROC = 15, +}; + +// Obtains the binding part of [sym64.st_info]. +// +// Equivalent to the ELF64_ST_BIND macro. +export fn st_bind(i: u8) stb = (i >> 4): stb; + +// Symbol types +export type stt = enum u8 { + // No type specified (e.g. an absolute symbol) + NOTYPE = 0, + // Data object + OBJECT = 1, + // Function entry point + FUNC = 2, + // Symbol is associated with a section + SECTION = 3, + // Source file associated with the object + FILE = 4, + // Environment-specific use + LOOS = 10, + // Environment-specific use + HIOS = 12, + // Processor-specific use + LOPROC = 13, + // Processor-specific use + HIPROC = 15, +}; + +// Obtains the type part of [sym64.st_info]. +// +// Equivalent to the ELF64_ST_TYPE macro. +export fn st_type(i: u8) stt = (i & 0xF): stt; + +// Converts symbol bindings and type into [sym64.st_info]. +// +// Equivalent to the ELF64_ST_INFO macro. +export fn st_info(b: stb, t: stt) u8 = b: u8 << 4 + t: u8 & 0xF; + +// Relocation entry +export type rel64 = struct { + // Address of reference + r_offset: u64, + // Symbol table index and type of relocation + r_info: u64, +}; + +// Relocation entry with explicit addend +export type rela64 = struct { + // Address of reference + r_offset: u64, + // Symbol table index and type of relocation + r_info: u64, + // Constant part of expression + r_addend: i64, +}; + +// Obtains the symbol table index part of [rel64.r_info]. +// +// Equivalent to the ELF64_R_SYM macro. +export fn r64_sym(info: u64) u64 = info >> 32; + +// Obtains the relocation type part of [rel64.r_info]. +// +// Equivalent to the ELF64_R_TYPE macro. +export fn r64_type(info: u64) u64 = info & 0xFFFFFFFF; + +// Converts symbol table index and a relocation type into [rel64.r_info]. +// +// Equivalent to the ELF64_R_INFO macro. +export fn r64_info(sym: u64, stype: u64) u64 = sym << 32 | stype & 0xFFFFFFFF; + +// Program header table entry (segment) +export type phdr64 = struct { + // Type of segment + p_type: pt, + // Segment attributes + p_flags: u32, + // Offset in file + p_offset: u64, + // Virtual address in memory + p_vaddr: u64, + // Reserved + p_paddr: u64, + // Size of segment in file + p_filesz: u64, + // Size of segment in memory + p_memsz: u64, + // Alignment of segment + p_align: u64, +}; + +// Segment types +export type pt = enum u32 { + // Unused entry + NULL = 0, + // Loadable segment + LOAD = 1, + // Dynamic linking tables + DYNAMIC = 2, + // Program interpreter path name + INTERP = 3, + // Note sections + NOTE = 4, + // Reserved + SHLIB = 5, + // Program header table + PHDR = 6, + // Environment-specific use + LOOS = 0x60000000, + // Environment-specific use + HIOS = 0x6FFFFFFF, + // Processor-specific use + LOPROC = 0x70000000, + // Processor-specific use + HIPROC = 0x7FFFFFFF, +}; + +// Segment attributes +export type pf = enum u32 { + // Execute permission + X = 0x1, + // Write permission + W = 0x2, + // Read permission + R = 0x4, + // Reserved for environment-specific use + MASKOS = 0x00FF0000, + // Reserved for processor-specific use + MASKPROC = 0xFF000000, +}; + +// Dynamic table entry +export type dyn64 = struct { + // The type of this entry + d_tag: dt, + // Additional data associated with this entry. The value which is valid + // is selected based on the entry type. + union { + d_val: u64, + d_ptr: u64, + }, +}; + +// Dynamic table entry type +export type dt = enum i64 { + // Marks the end of the dynamic array. + NULL = 0, + // The string table offset of the name of a needed library. + NEEDED = 1, + // Total size, in bytes, of the relocation entries associated with the + // procedure linkage table. + PLTRELSZ = 2, + // Contains an address associated with the linkage table. The specific + // meaning of this field is processor-dependent. + PLTGOT = 3, + // Address of the symbol hash table. + HASH = 4, + // Address of the dynamic string table. + STRTAB = 5, + // Address of the dynamic symbol table. + SYMTAB = 6, + // Address of a relocation table with rela64 entries. + RELA = 7, + // Total size, in bytes, of the RELA relocation table. + RELASZ = 8, + // Size, in bytes, of each RELA relocation entry. + REALENT = 9, + // Total size, in bytes, of the string table. + STRSZ = 10, + // Size, in bytes, of each symbol table entry. + SYMENT = 11, + // Address of the initialization function. + INIT = 12, + // Address of the termination function. + FINI = 13, + // The string table offset of the name of this shared object. + SONAME = 14, + // The string table offset of a shared library search path string. + RPATH = 15, + // The presence of this dynamic table entry modifies the symbol + // resolution algorithm for references within the library. Symbols + // defined within the library are used to resolve references before the + // dynamic linker searches the usual search path. + SYMBOLIC = 16, + // Address of a relocation table with rel64 entries. + REL = 17, + // Total size, in bytes, of the REL relocation table. + RELSZ = 18, + // Size, in bytes, of each REL relocation entry. + RELENT = 19, + // Type of relocation entry used for the procedure linkage table. The + // d_val member contains either [dt::REL] or [dt::RELA]. + PLTREL = 20, + // Reserved for debugger use. + DEBUG = 21, + // The presence of this dynamic table entry signals that the relocation + // table contains relocations for a non-writable segment. + TEXTREL = 22, + // Address of the relocations associated with the procedure linkage + // table. + JMPREL = 23, + // The presence of this dynamic table entry signals that the dynamic + // loader should process all relocations for this object before + // transferring control to the program. + BIND_NOW = 24, + // Pointer to an array of initialiation functions. + INIT_ARRAY = 25, + // Pointer to an array of termination functions. + FINI_ARRAY = 26, + // Size, in bytes, of the array of initialization functions. + INIT_ARRAYSZ = 27, + // Size, in bytes, of the array of termination functions. + FINI_ARRAYSZ = 28, + // Reserved for environment-specific use. + LOOS = 0x60000000, + // Reserved for environment-specific use. + HIOS = 0x6FFFFFFF, + // Reserved for processor-specific use. + LOPROC = 0x70000000, + // Reserved for processor-specific use. + HIPROC = 0x7FFFFFFF, +};