added elf loader

This commit is contained in:
Luxferre
2026-06-19 07:45:35 +03:00
parent ce40bb9a28
commit bd27989a03
3 changed files with 78 additions and 7 deletions
+51 -1
View File
@@ -723,7 +723,7 @@ BEGIN {
LVA = int(LVA)
pc = LVA
NEXT_FD = 3
LAST_SEC = -1
LAST_SEC = -1
VIRT_NSEC = 0
srand()
}
@@ -733,6 +733,56 @@ BEGIN {
# Execution section
END {
# ELF detection and parsing
# The file has been loaded into MEM starting from original LVA
orig_LVA = LVA
elf_size = pc - orig_LVA
# Verify if it starts with ELF magic (0x7F, 'E', 'L', 'F') and is large enough to contain a header
if(elf_size >= 52 && MEM[LVA] == 127 && MEM[LVA+1] == 69 && MEM[LVA+2] == 76 && MEM[LVA+3] == 70) {
# Verify class is ELF32, data is LSB (little endian), and machine is RISC-V (243 / 0xf3)
if(MEM[LVA+4] != 1 || MEM[LVA+5] != 1 || (MEM[LVA+18] + MEM[LVA+19] * 256) != 243)
trapout("Incompatible ELF file (must be RV32 little-endian)")
# Read entry point (4 bytes at offset 24)
e_entry = MEM[LVA+24] + MEM[LVA+25] * 256 + MEM[LVA+26] * 65536 + MEM[LVA+27] * 16777216
# Read program header table offset (4 bytes at offset 28)
e_phoff = MEM[LVA+28] + MEM[LVA+29] * 256 + MEM[LVA+30] * 65536 + MEM[LVA+31] * 16777216
# Read number of program headers (2 bytes at offset 44)
e_phnum = MEM[LVA+44] + MEM[LVA+45] * 256
# Read size of program header entry (2 bytes at offset 42)
e_phentsize = MEM[LVA+42] + MEM[LVA+43] * 256
# Back up the entire ELF image to ELF_DATA array and clear MEM in the loaded range
for(i = 0; i < elf_size; i++) {
ELF_DATA[i] = MEM[orig_LVA + i]
delete MEM[orig_LVA + i]
}
# Load segment data into memory
for(p = 0; p < e_phnum; p++) {
ph_addr = e_phoff + p * e_phentsize
p_type = ELF_DATA[ph_addr] + ELF_DATA[ph_addr+1] * 256 + ELF_DATA[ph_addr+2] * 65536 + ELF_DATA[ph_addr+3] * 16777216
# We only load PT_LOAD (p_type == 1)
if(p_type == 1) {
p_offset = ELF_DATA[ph_addr+4] + ELF_DATA[ph_addr+5] * 256 + ELF_DATA[ph_addr+6] * 65536 + ELF_DATA[ph_addr+7] * 16777216
p_vaddr = ELF_DATA[ph_addr+8] + ELF_DATA[ph_addr+9] * 256 + ELF_DATA[ph_addr+10] * 65536 + ELF_DATA[ph_addr+11] * 16777216
p_filesz = ELF_DATA[ph_addr+16] + ELF_DATA[ph_addr+17] * 256 + ELF_DATA[ph_addr+18] * 65536 + ELF_DATA[ph_addr+19] * 16777216
p_memsz = ELF_DATA[ph_addr+20] + ELF_DATA[ph_addr+21] * 256 + ELF_DATA[ph_addr+22] * 65536 + ELF_DATA[ph_addr+23] * 16777216
# Copy p_filesz bytes from ELF_DATA to MEM
for(i = 0; i < p_filesz; i++)
MEM[p_vaddr + i] = ELF_DATA[p_offset + i]
# Zero-initialize the remaining p_memsz - p_filesz bytes
for(i = p_filesz; i < p_memsz; i++)
MEM[p_vaddr + i] = 0
}
}
# Override LVA to the entry point (actual memory start value inside the ELF file)
LVA = e_entry
}
memsize = pc - LVA
pc = LVA
while(pc > -1) {