Add elf parser
This commit is contained in:
parent
5c36fac374
commit
1a48bec601
3
Makefile
3
Makefile
|
@ -8,6 +8,7 @@ clean:
|
|||
|
||||
test:
|
||||
$(MAKE) -C test
|
||||
rm -f test.img
|
||||
dd if=/dev/zero bs=1M count=0 seek=64 of=test.img
|
||||
parted -s test.img mklabel msdos
|
||||
parted -s test.img mkpart primary 1 100%
|
||||
|
@ -15,4 +16,4 @@ test:
|
|||
echfs-utils -m -p0 test.img import test/test.elf test.elf
|
||||
echfs-utils -m -p0 test.img import test/qloader2.cfg qloader2.cfg
|
||||
./qloader2-install test.img
|
||||
qemu-system-x86_64 -hda test.img
|
||||
qemu-system-x86_64 -hda test.img -monitor stdio
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/elf.h>
|
||||
|
||||
#define PT_LOAD 0x00000001
|
||||
#define PT_INTERP 0x00000003
|
||||
#define PT_PHDR 0x00000006
|
||||
|
||||
#define ABI_SYSV 0x00
|
||||
#define ARCH_X86_64 0x3e
|
||||
#define BITS_LE 0x01
|
||||
|
||||
/* Indices into identification array */
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
#define EI_OSABI 7
|
||||
|
||||
struct elf_hdr {
|
||||
uint8_t ident[16];
|
||||
uint16_t type;
|
||||
uint16_t machine;
|
||||
uint32_t version;
|
||||
uint32_t entry;
|
||||
uint32_t phoff;
|
||||
uint32_t shoff;
|
||||
uint32_t flags;
|
||||
uint16_t hdr_size;
|
||||
uint16_t phdr_size;
|
||||
uint16_t ph_num;
|
||||
uint16_t shdr_size;
|
||||
uint16_t sh_num;
|
||||
uint16_t shstrndx;
|
||||
};
|
||||
|
||||
struct elf_phdr {
|
||||
uint32_t p_type;
|
||||
uint32_t p_offset;
|
||||
uint32_t p_vaddr;
|
||||
uint32_t p_paddr;
|
||||
uint32_t p_filesz;
|
||||
uint32_t p_memsz;
|
||||
uint32_t p_flags;
|
||||
};
|
||||
|
||||
int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count);
|
||||
|
||||
int elf_load(struct echfs_file_handle *fd) {
|
||||
struct elf_hdr hdr;
|
||||
echfs_read(fd, &hdr, 0, sizeof(struct elf_hdr));
|
||||
|
||||
if (strncmp((char *)hdr.ident, "\177ELF", 4)) {
|
||||
print("Not a valid ELF file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (hdr.ident[EI_DATA] != BITS_LE) {
|
||||
print("Not a Little-endian ELF file.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < hdr.ph_num; i++) {
|
||||
struct elf_phdr phdr;
|
||||
echfs_read(fd, &phdr, hdr.phoff + i * sizeof(struct elf_phdr),
|
||||
sizeof(struct elf_phdr));
|
||||
|
||||
if (phdr.p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
|
||||
echfs_read(fd, (void *)phdr.p_vaddr, phdr.p_offset, phdr.p_filesz);
|
||||
|
||||
size_t to_zero = (size_t)(phdr.p_memsz - phdr.p_filesz);
|
||||
|
||||
if (to_zero) {
|
||||
void *ptr = (void *)(phdr.p_vaddr + phdr.p_filesz);
|
||||
memset(ptr, 0, to_zero);
|
||||
}
|
||||
}
|
||||
|
||||
asm volatile (
|
||||
"jmp %0\n\t"
|
||||
:
|
||||
: "r" (hdr.entry)
|
||||
: "memory"
|
||||
);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef __LIB__ELF_H__
|
||||
#define __LIB__ELF_H__
|
||||
|
||||
#include <fs/echfs.h>
|
||||
|
||||
int elf_load(struct echfs_file_handle *fd);
|
||||
|
||||
#endif
|
|
@ -12,6 +12,7 @@ asm (
|
|||
#include <lib/config.h>
|
||||
#include <fs/echfs.h>
|
||||
#include <sys/interrupt.h>
|
||||
#include <lib/elf.h>
|
||||
|
||||
#define CONFIG_NAME "qloader2.cfg"
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
test.elf:
|
||||
test.elf: test.asm linker.ld
|
||||
nasm test.asm -felf32 -o test.o
|
||||
../toolchain/bin/i386-elf-ld test.o -nostdlib -T ./linker.ld -o test.elf
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
section .text
|
||||
|
||||
; Entry point
|
||||
global _start
|
||||
_start:
|
||||
|
||||
mov eax, 0xdeadbeef
|
||||
jmp $
|
||||
|
|
Loading…
Reference in New Issue