added elf loader
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user