add the support of ELF64
This commit is contained in:
parent
8b91ff3fff
commit
7f7dd4585f
2 changed files with 147 additions and 46 deletions
|
@ -40,6 +40,23 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* 32-bit ELF base types. */
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint16_t Elf32_Half;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Word;
|
||||
|
||||
/* 64-bit ELF base types. */
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef int16_t Elf64_SHalf;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
|
||||
#define ELF_MAGIC 0x464C457F
|
||||
|
||||
#define ELF_ET_NONE 0x0000 // no type
|
||||
|
@ -58,6 +75,8 @@ extern "C" {
|
|||
#define ELF_EM_88K 0x0005 // Motorola 88000
|
||||
#define ELF_EM_860 0x0007 // Intel 80860
|
||||
#define ELF_EM_MIPS 0x0008 // MIPS RS3000
|
||||
#define ELF_EM_ARM 0x0032 // ARM
|
||||
#define ELF_EM_X86_64 0x003E // AMD/Intel x86_64
|
||||
|
||||
#define ELF_CLASS_NONE 0x0000
|
||||
#define ELF_CLASS_32 0x0001 // 32bit file
|
||||
|
@ -111,60 +130,135 @@ typedef struct {
|
|||
|
||||
/** @brief Information about the executable
|
||||
*
|
||||
* ELF header\n
|
||||
* ELF32 header\n
|
||||
* This structure keeps information about the format of the executable itself.
|
||||
*/
|
||||
typedef struct {
|
||||
elf_ident_t ident;
|
||||
uint16_t type;
|
||||
uint16_t machine;
|
||||
uint32_t version;
|
||||
uint32_t entry;
|
||||
uint32_t ph_offset;
|
||||
uint32_t sh_offset;
|
||||
uint32_t flags;
|
||||
uint16_t header_size;
|
||||
uint16_t ph_entry_size;
|
||||
uint16_t ph_entry_count;
|
||||
uint16_t sh_entry_size;
|
||||
uint16_t sh_entry_count;
|
||||
uint16_t sh_str_table_index;
|
||||
} __attribute__ ((packed)) elf_header_t;
|
||||
Elf32_Half type;
|
||||
Elf32_Half machine;
|
||||
Elf32_Word version;
|
||||
Elf32_Addr entry;
|
||||
Elf32_Off ph_offset;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word flags;
|
||||
Elf32_Half header_size;
|
||||
Elf32_Half ph_entry_size;
|
||||
Elf32_Half ph_entry_count;
|
||||
Elf32_Half sh_entry_size;
|
||||
Elf32_Half sh_entry_count;
|
||||
Elf32_Half sh_str_table_index;
|
||||
} __attribute__ ((packed)) elf32_header_t;
|
||||
|
||||
/** @brief program header information
|
||||
/** @brief Information about the executable
|
||||
*
|
||||
* program header table\n
|
||||
* ELF64 header\n
|
||||
* This structure keeps information about the format of the executable itself.
|
||||
*/
|
||||
typedef struct {
|
||||
elf_ident_t ident;
|
||||
Elf64_Half type;
|
||||
Elf64_Half machine;
|
||||
Elf64_Word version;
|
||||
Elf64_Addr entry;
|
||||
Elf64_Off ph_offset;
|
||||
Elf64_Off sh_offset;
|
||||
Elf64_Word flags;
|
||||
Elf64_Half header_size;
|
||||
Elf64_Half ph_entry_size;
|
||||
Elf64_Half ph_entry_count;
|
||||
Elf64_Half sh_entry_size;
|
||||
Elf64_Half sh_entry_count;
|
||||
Elf64_Half sh_str_table_index;
|
||||
} __attribute__ ((packed)) elf64_header_t;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
typedef elf32_header_t elf_header_t;
|
||||
#else
|
||||
typedef elf64_header_t elf_header_t;
|
||||
#endif
|
||||
|
||||
/** @brief ELF32 program header information
|
||||
*
|
||||
* ELF32 program header table\n
|
||||
* This structure keeps information about the program header.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
uint32_t offset;
|
||||
uint32_t virt_addr;
|
||||
uint32_t phys_addr;
|
||||
uint32_t file_size;
|
||||
uint32_t mem_size;
|
||||
uint32_t flags;
|
||||
uint32_t alignment;
|
||||
} __attribute__ ((packed)) elf_program_header_t;
|
||||
Elf32_Word type;
|
||||
Elf32_Off offset;
|
||||
Elf32_Addr virt_addr;
|
||||
Elf32_Addr phys_addr;
|
||||
Elf32_Word file_size;
|
||||
Elf32_Word mem_size;
|
||||
Elf32_Word flags;
|
||||
Elf32_Word alignment;
|
||||
} __attribute__ ((packed)) elf32_program_header_t;
|
||||
|
||||
/** @brief Information about ELF section
|
||||
/** @brief ELF64 program header information
|
||||
*
|
||||
* ELF section\n
|
||||
* ELF64 program header table\n
|
||||
* This structure keeps information about the program header.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word type;
|
||||
Elf64_Word flags;
|
||||
Elf64_Off offset;
|
||||
Elf64_Addr virt_addr;
|
||||
Elf64_Addr phys_addr;
|
||||
Elf64_Xword file_size;
|
||||
Elf64_Xword mem_size;
|
||||
Elf64_Xword alignment;
|
||||
} __attribute__ ((packed)) elf64_program_header_t;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
typedef elf32_program_header_t elf_program_header_t;
|
||||
#else
|
||||
typedef elf64_program_header_t elf_program_header_t;
|
||||
#endif
|
||||
|
||||
/** @brief Information about ELF32 section
|
||||
*
|
||||
* ELF32 section\n
|
||||
* This structure keeps information about a specific ELF section
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t name;
|
||||
uint32_t type;
|
||||
uint32_t flags;
|
||||
uint32_t addr;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
uint32_t link;
|
||||
uint32_t info;
|
||||
uint32_t align;
|
||||
uint32_t enttry_size;
|
||||
} __attribute__ ((packed)) elf_section_header_t;
|
||||
Elf32_Word name;
|
||||
Elf32_Word type;
|
||||
Elf32_Word flags;
|
||||
Elf32_Addr addr;
|
||||
Elf32_Off offset;
|
||||
Elf32_Word size;
|
||||
Elf32_Word link;
|
||||
Elf32_Word info;
|
||||
Elf32_Word align;
|
||||
Elf32_Word enttry_size;
|
||||
} __attribute__ ((packed)) elf32_section_header_t;
|
||||
|
||||
/** @brief Information about ELF64 section
|
||||
*
|
||||
* ELF32 section\n
|
||||
* This structure keeps information about a specific ELF section
|
||||
*/
|
||||
typedef struct {
|
||||
Elf64_Word name;
|
||||
Elf64_Word type;
|
||||
Elf64_Xword flags;
|
||||
Elf64_Addr addr;
|
||||
Elf64_Off offset;
|
||||
Elf64_Xword size;
|
||||
Elf64_Word link;
|
||||
Elf64_Word info;
|
||||
Elf64_Xword align;
|
||||
Elf64_Xword enttry_size;
|
||||
} __attribute__ ((packed)) elf64_section_header_t;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
typedef elf32_section_header_t elf_section_header_t;
|
||||
#else
|
||||
typedef elf64_section_header_t elf_section_header_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -537,9 +537,9 @@ typedef struct {
|
|||
*/
|
||||
static int load_task(load_args_t* largs)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
uint32_t i, offset, idx, fd_i;
|
||||
uint32_t addr, npages, flags, stack = 0;
|
||||
uint32_t addr, npages, flags;
|
||||
size_t stack = 0;
|
||||
elf_header_t header;
|
||||
elf_program_header_t prog_header;
|
||||
//elf_section_header_t sec_header;
|
||||
|
@ -589,11 +589,19 @@ static int load_task(load_args_t* largs)
|
|||
if (BUILTIN_EXPECT(header.type != ELF_ET_EXEC, 0))
|
||||
goto invalid;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
if (BUILTIN_EXPECT(header.machine != ELF_EM_386, 0))
|
||||
goto invalid;
|
||||
|
||||
if (BUILTIN_EXPECT(header.ident._class != ELF_CLASS_32, 0))
|
||||
goto invalid;
|
||||
#else
|
||||
if (BUILTIN_EXPECT(header.machine != ELF_EM_X86_64, 0))
|
||||
goto invalid;
|
||||
|
||||
if (BUILTIN_EXPECT(header.ident._class != ELF_CLASS_64, 0))
|
||||
goto invalid;
|
||||
#endif
|
||||
|
||||
if (BUILTIN_EXPECT(header.ident.data != ELF_DATA_2LSB, 0))
|
||||
goto invalid;
|
||||
|
@ -626,8 +634,10 @@ static int load_task(load_args_t* largs)
|
|||
flags |= MAP_CODE;
|
||||
|
||||
// map page frames in the address space of the current task
|
||||
if (!map_region(prog_header.virt_addr, addr, npages, flags))
|
||||
kprintf("Could not map 0x%x at 0x%x\n", addr, prog_header.virt_addr);
|
||||
if (!map_region(prog_header.virt_addr, addr, npages, flags)) {
|
||||
kprintf("Could not map 0x%x at 0x%x (%u pages)\n", addr, prog_header.virt_addr, npages);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
// clear pages
|
||||
memset((void*) prog_header.virt_addr, 0x00, npages*PAGE_SIZE);
|
||||
|
@ -761,9 +771,6 @@ invalid:
|
|||
kprintf("program entry point 0x%x\n", (size_t) header.entry);
|
||||
|
||||
return -EINVAL;
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief This call is used to adapt create_task calls
|
||||
|
|
Loading…
Add table
Reference in a new issue