]>
git.dujemihanovic.xyz Git - nameless-os.git/blob - boot/x86/stage3/elf.c
d3d215ffa71fbcfca830e64c75c5ed15383cc597
1 /* Code for parsing ELF binaries (the kernel) */
7 int check_elf_header(struct elf_header
*header
)
9 if (header
->magic
!= ELF_MAGIC
)
10 return ELF_HEADER_INVALID
;
11 if (header
->bits
!= ELF_32BIT
)
12 return MISMATCHED_SYSTEM
;
13 if (header
->endianness
!= ELF_LITTLE_ENDIAN
)
14 return MISMATCHED_SYSTEM
;
15 if (header
->header_ver
!= 1)
16 return ELF_HEADER_INVALID
;
17 if (header
->os_abi
!= ELF_SYSV_ABI
)
18 return MISMATCHED_SYSTEM
;
19 if (header
->type
!= ELF_TYPE_EXECUTABLE
)
20 return NOT_EXECUTABLE
;
21 if (header
->machine
!= ELF_X86_ISA
)
22 return MISMATCHED_SYSTEM
;
23 if (header
->elf_ver
!= 1)
24 return ELF_HEADER_INVALID
;
29 int setup_elf_executable(struct elf_header
*header
)
31 /* Check the header. */
32 int header_valid
= check_elf_header(header
);
36 /* Get the program header. The casting is necessary because without it
37 * the code will add some multiple of the program header offset rather
38 * than the actual offset. */
39 struct program_header
*prog_hdr
= (struct program_header
*) ((uint32_t) header
+header
->program_hdr
);
40 for (int i
=0; i
<header
->ph_entry_count
; i
++) {
41 /* We're only interested in loadable segments. */
42 if (prog_hdr
[i
].seg_type
!= ELF_PT_LOAD
)
45 /* Calculate the memory range. */
46 void *phys_start
, *phys_end
, *virt_end
;
48 phys_start
= (void *) header
+ prog_hdr
[i
].file_offset
;
49 if (prog_hdr
[i
].memsz
& 0xfff) { /* Align if needed. */
50 phys_end
= phys_start
+((prog_hdr
[i
].memsz
+0x1000) & ~0xfff);
51 virt_end
= prog_hdr
[i
].vaddr
+((prog_hdr
[i
].memsz
+0x1000) & ~0xfff);
54 phys_end
= phys_start
+prog_hdr
[i
].memsz
;
55 virt_end
= prog_hdr
[i
].vaddr
+prog_hdr
[i
].memsz
;
58 flags
= prog_hdr
[i
].flags
& ELF_FLAG_WRITABLE
;
61 int ret
= map_range(phys_start
, phys_end
, prog_hdr
[i
].vaddr
, virt_end
, flags
);
69 int execute_elf(struct elf_header
*header
, void *arg1
, int arg2
)
71 /* Check the header and map all needed memory ranges. */
72 int ret
= setup_elf_executable(header
);
76 /* Execute the kernel. */
77 header
->entry(arg1
, arg2
);