196 lines
5.6 KiB
C
196 lines
5.6 KiB
C
|
/*#include <stdlib.h>
|
||
|
|
||
|
#include <drivers/elf_load.h>*/
|
||
|
|
||
|
|
||
|
/*
|
||
|
ELF Header
|
||
|
|
||
|
The ELF header is always found at the start of the file.
|
||
|
Position (32 bit) Position (64 bit) Value
|
||
|
0-3 0-3 Magic number - 0x7F, then 'ELF' in ASCII
|
||
|
4 4 1 = 32 bit, 2 = 64 bit
|
||
|
5 5 1 = little endian, 2 = big endian
|
||
|
6 6 ELF header version
|
||
|
7 7 OS ABI - usually 0 for System V
|
||
|
8-15 8-15 Unused/padding
|
||
|
16-17 16-17 Type (1 = relocatable, 2 = executable, 3 = shared, 4 = core)
|
||
|
18-19 18-19 Instruction set - see table below
|
||
|
20-23 20-23 ELF Version (currently 1)
|
||
|
24-27 24-31 Program entry offset
|
||
|
28-31 32-39 Program header table offset
|
||
|
32-35 40-47 Section header table offset
|
||
|
36-39 48-51 Flags - architecture dependent; see note below
|
||
|
40-41 52-53 ELF Header size
|
||
|
42-43 54-55 Size of an entry in the program header table
|
||
|
44-45 56-57 Number of entries in the program header table
|
||
|
46-47 58-59 Size of an entry in the section header table
|
||
|
48-49 60-61 Number of entries in the section header table
|
||
|
50-51 62-63 Section index to the section header string table
|
||
|
|
||
|
The flags entry can probably be ignored for x86 ELFs, as no flags are actually defined.
|
||
|
|
||
|
Instruction Set Architectures:
|
||
|
Architecture Value
|
||
|
No Specific 0x00
|
||
|
Sparc 0x02
|
||
|
x86 0x03
|
||
|
MIPS 0x08
|
||
|
PowerPC 0x14
|
||
|
ARM 0x28
|
||
|
SuperH 0x2A
|
||
|
IA-64 0x32
|
||
|
x86-64 0x3E
|
||
|
AArch64 0xB7
|
||
|
RISC-V 0xF3
|
||
|
|
||
|
Program header
|
||
|
|
||
|
This is an array of N (given in the main header) entries in the following format. Make sure to use the correct version depending on whether the file is 32 bit or 64 bit as the tables are quite different.
|
||
|
|
||
|
32 bit version:
|
||
|
Position Value
|
||
|
0-3 Type of segment (see below)
|
||
|
4-7 The offset in the file that the data for this segment can be found (p_offset)
|
||
|
8-11 Where you should start to put this segment in virtual memory (p_vaddr)
|
||
|
12-15 Reserved for segment's physical address (p_paddr)
|
||
|
16-19 Size of the segment in the file (p_filesz)
|
||
|
20-23 Size of the segment in memory (p_memsz, at least as big as p_filesz)
|
||
|
24-27 Flags (see below)
|
||
|
28-31 The required alignment for this section (usually a power of 2)
|
||
|
|
||
|
64 bit version:
|
||
|
Position Value
|
||
|
0-3 Type of segment (see below)
|
||
|
4-7 Flags (see below)
|
||
|
8-15 The offset in the file that the data for this segment can be found (p_offset)
|
||
|
16-23 Where you should start to put this segment in virtual memory (p_vaddr)
|
||
|
24-31 Reserved for segment's physical address (p_paddr)
|
||
|
32-39 Size of the segment in the file (p_filesz)
|
||
|
40-47 Size of the segment in memory (p_memsz, at least as big as p_filesz)
|
||
|
48-55 The required alignment for this section (usually a power of 2)
|
||
|
|
||
|
Segment types: 0 = null - ignore the entry; 1 = load - clear p_memsz bytes at p_vaddr to 0, then copy p_filesz bytes from p_offset to p_vaddr; 2 = dynamic - requires dynamic linking; 3 = interp - contains a file path to an executable to use as an interpreter for the following segment; 4 = note section. There are more values, but mostly contain architecture/environment specific information, which is probably not required for the majority of ELF files.
|
||
|
|
||
|
Flags: 1 = executable, 2 = writable, 4 = readable.
|
||
|
*/
|
||
|
|
||
|
/*typedef struct elf_header {
|
||
|
uint32_t elf_magic;
|
||
|
|
||
|
uint8_t bitness;*/ /* 1 = 32 bit, 2 = 64 bit */
|
||
|
/*uint8_t endianess;*/ /* 1 = little endian, 2 = big endian */
|
||
|
|
||
|
/*uint8_t elf_header_version;
|
||
|
|
||
|
uint8_t os_abi;*/ /* usually 0 for System V */
|
||
|
|
||
|
/*uint8_t unused_padding[8];
|
||
|
|
||
|
uint16_t type;
|
||
|
|
||
|
uint16_t isa;
|
||
|
|
||
|
uint32_t elf_version;
|
||
|
|
||
|
uint32_t program_entry_offset;
|
||
|
uint32_t program_header_offset;
|
||
|
uint32_t section_header_offset;
|
||
|
|
||
|
uint32_t flags;
|
||
|
|
||
|
uint16_t elf_header_size;
|
||
|
|
||
|
uint16_t program_header_entry_size;
|
||
|
uint16_t program_header_num_entries;
|
||
|
uint16_t section_header_entry_size;
|
||
|
uint16_t section_header_num_entries;
|
||
|
|
||
|
uint16_t section_header_string_table_index;
|
||
|
} elf_header_t;
|
||
|
|
||
|
typedef struct program_header_entry {
|
||
|
uint32_t type;
|
||
|
|
||
|
uint32_t p_offset;
|
||
|
uint32_t p_vaddr;
|
||
|
uint32_t p_paddr;
|
||
|
uint32_t p_filesz;
|
||
|
uint32_t p_memsz;
|
||
|
|
||
|
uint32_t flags;
|
||
|
|
||
|
uint32_t alignment_required;
|
||
|
} program_header_entry_t;*/
|
||
|
|
||
|
|
||
|
|
||
|
/*int32_t elf_check(void* executable)
|
||
|
{
|
||
|
elf_header_t* e_header = (elf_header_t*)executable;
|
||
|
|
||
|
char* elf_magic = (char*)e_header->elf_magic;
|
||
|
if (elf_magic[0] != 0x7F || elf_magic[1] != 'E' || elf_magic[2] != 'L' || elf_magic[3] != 'F')
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (e_header->bitness != 1 || e_header->endianess != 1)
|
||
|
{
|
||
|
return -2;
|
||
|
}
|
||
|
|
||
|
uint32_t* cph_addr = (uint32_t*)e_header + e_header->program_header_offset
|
||
|
program_header_entry_t* p_header = (program_header_entry_t*)cph_addr;
|
||
|
uint8_t load = 0;
|
||
|
uin16_t num_phs = 1;
|
||
|
|
||
|
while (p_header)
|
||
|
{
|
||
|
if (num_phs == program_header_num_entries)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (p_header->type == 1)
|
||
|
{
|
||
|
load = 1;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
cph_addr += e_header->program_header_entry_size;
|
||
|
p_header = (program_header_entry_t*)cph_addr;
|
||
|
num_phs++;
|
||
|
}
|
||
|
|
||
|
uint32_t memsz = p_header->p_vaddr + p_header->p_memsz;
|
||
|
|
||
|
void* new_mem = malloc(memsz);
|
||
|
|
||
|
void* memloc = memclr(new_mem, (size_t)memsz);
|
||
|
|
||
|
void *memcpy(void *dst, const void *src, uint32_t n);
|
||
|
|
||
|
void* program_header_table_end = (e_header->program_header_entry_size + e_header->program_header_num_entries);
|
||
|
|
||
|
void* data_begin = (p_header->p_offset + p_header->p_filesz);
|
||
|
|
||
|
memcpy(memloc, p_header->p_offset*/
|
||
|
|
||
|
/*
|
||
|
typedef struct program_header_entry {
|
||
|
uint32_t type;
|
||
|
|
||
|
uint32_t p_offset;
|
||
|
uint32_t p_vaddr;
|
||
|
uint32_t p_paddr;
|
||
|
uint32_t p_filesz;
|
||
|
uint32_t p_memsz;
|
||
|
|
||
|
uint32_t flags;
|
||
|
|
||
|
uint32_t alignment_required;
|
||
|
} program_header_entry_t;
|
||
|
*/
|
||
|
/*}*/
|