add the support of ELF64

This commit is contained in:
Stefan Lankes 2012-07-22 20:12:24 +02:00
parent 8b91ff3fff
commit 7f7dd4585f
2 changed files with 147 additions and 46 deletions

View file

@ -40,6 +40,23 @@
extern "C" { extern "C" {
#endif #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_MAGIC 0x464C457F
#define ELF_ET_NONE 0x0000 // no type #define ELF_ET_NONE 0x0000 // no type
@ -58,6 +75,8 @@ extern "C" {
#define ELF_EM_88K 0x0005 // Motorola 88000 #define ELF_EM_88K 0x0005 // Motorola 88000
#define ELF_EM_860 0x0007 // Intel 80860 #define ELF_EM_860 0x0007 // Intel 80860
#define ELF_EM_MIPS 0x0008 // MIPS RS3000 #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_NONE 0x0000
#define ELF_CLASS_32 0x0001 // 32bit file #define ELF_CLASS_32 0x0001 // 32bit file
@ -111,60 +130,135 @@ typedef struct {
/** @brief Information about the executable /** @brief Information about the executable
* *
* ELF header\n * ELF32 header\n
* This structure keeps information about the format of the executable itself. * This structure keeps information about the format of the executable itself.
*/ */
typedef struct { typedef struct {
elf_ident_t ident; elf_ident_t ident;
uint16_t type; Elf32_Half type;
uint16_t machine; Elf32_Half machine;
uint32_t version; Elf32_Word version;
uint32_t entry; Elf32_Addr entry;
uint32_t ph_offset; Elf32_Off ph_offset;
uint32_t sh_offset; Elf32_Off sh_offset;
uint32_t flags; Elf32_Word flags;
uint16_t header_size; Elf32_Half header_size;
uint16_t ph_entry_size; Elf32_Half ph_entry_size;
uint16_t ph_entry_count; Elf32_Half ph_entry_count;
uint16_t sh_entry_size; Elf32_Half sh_entry_size;
uint16_t sh_entry_count; Elf32_Half sh_entry_count;
uint16_t sh_str_table_index; Elf32_Half sh_str_table_index;
} __attribute__ ((packed)) elf_header_t; } __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. * This structure keeps information about the program header.
*/ */
typedef struct { typedef struct {
uint32_t type; Elf32_Word type;
uint32_t offset; Elf32_Off offset;
uint32_t virt_addr; Elf32_Addr virt_addr;
uint32_t phys_addr; Elf32_Addr phys_addr;
uint32_t file_size; Elf32_Word file_size;
uint32_t mem_size; Elf32_Word mem_size;
uint32_t flags; Elf32_Word flags;
uint32_t alignment; Elf32_Word alignment;
} __attribute__ ((packed)) elf_program_header_t; } __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 * This structure keeps information about a specific ELF section
*/ */
typedef struct { typedef struct {
uint32_t name; Elf32_Word name;
uint32_t type; Elf32_Word type;
uint32_t flags; Elf32_Word flags;
uint32_t addr; Elf32_Addr addr;
uint32_t offset; Elf32_Off offset;
uint32_t size; Elf32_Word size;
uint32_t link; Elf32_Word link;
uint32_t info; Elf32_Word info;
uint32_t align; Elf32_Word align;
uint32_t enttry_size; Elf32_Word enttry_size;
} __attribute__ ((packed)) elf_section_header_t; } __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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -537,9 +537,9 @@ typedef struct {
*/ */
static int load_task(load_args_t* largs) static int load_task(load_args_t* largs)
{ {
#ifdef CONFIG_X86_32
uint32_t i, offset, idx, fd_i; 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_header_t header;
elf_program_header_t prog_header; elf_program_header_t prog_header;
//elf_section_header_t sec_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)) if (BUILTIN_EXPECT(header.type != ELF_ET_EXEC, 0))
goto invalid; goto invalid;
#ifdef CONFIG_X86_32
if (BUILTIN_EXPECT(header.machine != ELF_EM_386, 0)) if (BUILTIN_EXPECT(header.machine != ELF_EM_386, 0))
goto invalid; goto invalid;
if (BUILTIN_EXPECT(header.ident._class != ELF_CLASS_32, 0)) if (BUILTIN_EXPECT(header.ident._class != ELF_CLASS_32, 0))
goto invalid; 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)) if (BUILTIN_EXPECT(header.ident.data != ELF_DATA_2LSB, 0))
goto invalid; goto invalid;
@ -626,8 +634,10 @@ static int load_task(load_args_t* largs)
flags |= MAP_CODE; flags |= MAP_CODE;
// map page frames in the address space of the current task // map page frames in the address space of the current task
if (!map_region(prog_header.virt_addr, addr, npages, flags)) 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); kprintf("Could not map 0x%x at 0x%x (%u pages)\n", addr, prog_header.virt_addr, npages);
return -ENOMEM;
}
// clear pages // clear pages
memset((void*) prog_header.virt_addr, 0x00, npages*PAGE_SIZE); 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); kprintf("program entry point 0x%x\n", (size_t) header.entry);
return -EINVAL; return -EINVAL;
#else
return -EINVAL;
#endif
} }
/** @brief This call is used to adapt create_task calls /** @brief This call is used to adapt create_task calls