Added a fully working x86_64 port

This commit is contained in:
Morten Delenk 2016-08-04 18:46:15 +02:00
parent ca34003648
commit dbf445de9b
No known key found for this signature in database
GPG key ID: 3F818D0F65DCB490
4 changed files with 17 additions and 8 deletions

View file

@ -2,6 +2,13 @@
#include <moduleinterface.h>
#include <elf.h>
#include <base/output.hpp>
#ifdef __LP64__
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Phdr Elf64_Phdr
#else
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Phdr Elf32_Phdr
#endif
/** \brief beginning of constructor table */
extern "C" void(*start_ctors)();
/** \brief end of constructor table */
@ -14,17 +21,17 @@ extern "C" void(*end_dtors)();
* \function load(Elf32_Ehdr)
* \brief returns program entry point
*/
auto load(Elf32_Ehdr* file) -> void(**(*)(void*))() {
auto load(Elf_Ehdr* file) -> void(**(*)(void*))() {
if((file->e_ident[0]!=ELFMAG0)||
(file->e_ident[1]!=ELFMAG1)||
(file->e_ident[2]!=ELFMAG2)||
(file->e_ident[3]!=ELFMAG3) ) {
return nullptr;
}
Elf32_Phdr *phdr = (Elf32_Phdr*)((uintptr_t)(file->e_phoff)+(uintptr_t)file);
Elf_Phdr *phdr = (Elf_Phdr*)((uintptr_t)(file->e_phoff)+(uintptr_t)file);
for(int i=0;i<file->e_phnum;i++) {
uint32_t start=phdr[i].p_vaddr;
uint32_t end=start+phdr[i].p_memsz;
uintptr_t start=phdr[i].p_vaddr;
uintptr_t end=start+phdr[i].p_memsz;
if((start <= file->e_entry) && (file->e_entry < end)) {
return (void (** (*)(void*))()) (file->e_entry-start+phdr[i].p_offset+(uintptr_t)file); //Calculate _start address
}
@ -42,7 +49,7 @@ extern "C" void _start(void ** modtable) {
for(int i=0;i<1024;i++) {
if(!modtable[i])
break;
void(**(*fptr)(void*))() = load((Elf32_Ehdr*) modtable[i]);
void(**(*fptr)(void*))() = load((Elf_Ehdr*) modtable[i]);
if(!fptr)
continue;
void(**table)()=fptr(modtable[i]);

View file

@ -22,6 +22,7 @@ SECTIONS
}
.bss : {
*(.bss)
*(COMMON)
}
kernel_end = .;
}

View file

@ -53,7 +53,7 @@ private:
void(*tbl[3])()={(void(*)())&getType,(void(*)())&size_of,(void(*)())&spawnAt};
table_type getTable() {
doCtors();
return (void(**)())&tbl;
return (table_type)&tbl;
}
auto getType() -> ModType {
return ModType::output_text;

View file

@ -1,9 +1,9 @@
ENTRY(getTable)
OUTPUT_FORMAT(elf32-little)
OUTPUT_FORMAT(elf64-x86-64)
OUTPUT_ARCH(i386:x86-64)
SECTIONS
{
. = 0x108000;
. = 0x109000;
module_start = .;
.text : {
*(.text)
@ -20,6 +20,7 @@ SECTIONS
*(.data.*)
*(.rodata)
*(.bss)
*(COMMON)
}
module_end = .;
}