mirror of
https://github.com/vivier/EMILE.git
synced 2024-11-15 13:04:40 +00:00
88 lines
2.2 KiB
C
88 lines
2.2 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include <elf.h>
|
||
|
|
||
|
#include "zlib.h"
|
||
|
|
||
|
#define PAGE_SHIFT 12
|
||
|
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
||
|
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
gzFile in;
|
||
|
Elf32_Ehdr elf_header;
|
||
|
Elf32_Phdr *program_header;
|
||
|
int ret;
|
||
|
unsigned long min_addr, max_addr, kernel_size;
|
||
|
int i;
|
||
|
char * base;
|
||
|
|
||
|
in = gzopen("vmlinux.gz", "rb");
|
||
|
ret = gzread(in, &elf_header, sizeof(Elf32_Ehdr));
|
||
|
|
||
|
if (elf_header.e_machine != EM_68K)
|
||
|
{
|
||
|
fprintf(stderr, "Not MC680x0 architecture\n");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (elf_header.e_type != ET_EXEC)
|
||
|
{
|
||
|
fprintf(stderr, "Not an executable file\n");
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
program_header = (Elf32_Phdr *)malloc(elf_header.e_phnum *
|
||
|
sizeof (Elf32_Phdr));
|
||
|
if (program_header == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "Cannot allocate memory\n");
|
||
|
return 3;
|
||
|
}
|
||
|
|
||
|
ret = gzseek(in, elf_header.e_phoff, SEEK_SET);
|
||
|
|
||
|
ret = gzread(in, program_header, elf_header.e_phnum * sizeof(Elf32_Phdr));
|
||
|
min_addr = 0xffffffff;
|
||
|
max_addr = 0;
|
||
|
for (i = 0; i < elf_header.e_phnum; i++)
|
||
|
{
|
||
|
min_addr = (min_addr > program_header[i].p_vaddr) ?
|
||
|
program_header[i].p_vaddr : min_addr;
|
||
|
max_addr = (max_addr < program_header[i].p_vaddr + program_header[i].p_memsz) ?
|
||
|
program_header[i].p_vaddr + program_header[i].p_memsz: max_addr;
|
||
|
}
|
||
|
if (min_addr == 0)
|
||
|
{
|
||
|
min_addr = PAGE_SIZE;
|
||
|
program_header[0].p_vaddr += PAGE_SIZE;
|
||
|
program_header[0].p_offset += PAGE_SIZE;
|
||
|
program_header[0].p_filesz -= PAGE_SIZE;
|
||
|
program_header[0].p_memsz -= PAGE_SIZE;
|
||
|
}
|
||
|
kernel_size = max_addr - min_addr;
|
||
|
fprintf(stderr, "Kernel memory footprint: %d\n", kernel_size);
|
||
|
fprintf(stderr, "Base address: 0x%lx\n", min_addr);
|
||
|
fprintf(stderr, "Entry point: 0x%lx\n", elf_header.e_entry);
|
||
|
|
||
|
base = (char*)malloc(kernel_size);
|
||
|
memset(base, 0, kernel_size);
|
||
|
for (i = 0; i < elf_header.e_phnum; i++)
|
||
|
{
|
||
|
fprintf(stderr, "Reading Program Section #%d, "
|
||
|
"offset 0x%lx, (0x%lx,%lx)\n",
|
||
|
i, (long)program_header[i].p_offset,
|
||
|
program_header[i].p_vaddr - PAGE_SIZE,
|
||
|
(long)program_header[i].p_filesz);
|
||
|
ret = gzseek(in, program_header[i].p_offset, SEEK_SET);
|
||
|
ret = gzread(in, base + program_header[i].p_vaddr - PAGE_SIZE, program_header[i].p_filesz);
|
||
|
}
|
||
|
write(STDOUT_FILENO, base, kernel_size);
|
||
|
|
||
|
ret = gzclose(in);
|
||
|
|
||
|
return 0;
|
||
|
}
|