summaryrefslogtreecommitdiff
path: root/fs/elf.c
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-12-01 23:33:31 +0100
committerMichal Idziorek <m.i@gmx.at>2014-12-01 23:33:31 +0100
commitf20db37ca17245d5d20302a1ac1da347de5c3607 (patch)
treece0712176387f4555cf290615b71cdd1c935557d /fs/elf.c
parentd8331335ff1720ce28eba45afe1a02814b38b033 (diff)
very buggy fork, execve and exit
Diffstat (limited to 'fs/elf.c')
-rw-r--r--fs/elf.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/fs/elf.c b/fs/elf.c
index 3b2f2b3..57c9009 100644
--- a/fs/elf.c
+++ b/fs/elf.c
@@ -1,5 +1,8 @@
#include <stdint.h>
+#include "ext2.h"
+#include "lib/logger/log.h"
+#define FOOLOS_MODULE_NAME "elf"
#define EI_NIDENT 16
@@ -62,3 +65,102 @@ typedef struct {
Elf32_Word p_align;
}
Elf32_Phdr;
+
+// returns elf entry point
+uint32_t load_elf(char *name, uint32_t *alloc)
+{
+
+ int inode_nr=ext2_filename_to_inode(EXT2_RAM_ADDRESS,name);
+ if(inode_nr<1)return 0;
+
+ //TODO: load ELF binary and move this to own compilation unit
+
+ //load binary
+ uint32_t vaddr=0x08048000;
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"loading");
+ ext2_check(EXT2_RAM_ADDRESS);
+ ext2_inode_content(EXT2_RAM_ADDRESS,inode_nr,vaddr,0x100000); // load 1mb;
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"ELF File loaded to final destination.");
+
+ Elf32_Ehdr *elf;
+ elf=vaddr;
+
+ if(elf->e_ident[0]!=0x7f||elf->e_ident[1]!='E'||elf->e_ident[2]!='L'||elf->e_ident[3]!='F')
+ panic(FOOLOS_MODULE_NAME,"ELF mismatch!?");
+
+
+ /*
+ log(FOOLOS_MODULE_NAME, FOOLOS_LOG_INFO,
+ "elf id: class=%d, data=%d, version=%d osabi=%d abiv=%d ",
+ elf->e_ident[4],elf->e_ident[5],elf->e_ident[6],
+ elf->e_ident[7],elf->e_ident[8]);
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf type: 0x%04x",elf->e_type);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf machine: 0x%04x",elf->e_machine);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf version: %d",elf->e_version);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf entry: 0x%08X",elf->e_entry);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf ph-offset: 0x%08X",elf->e_phoff);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf sh-offset: 0x%08X",elf->e_shoff);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf flags: 0x%08X",elf->e_flags);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf eh-size (bytes): %d",elf->e_ehsize);
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf ph-ent-size(bytes): %d",elf->e_phentsize);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf ph-num: %d",elf->e_phnum);
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf sh-ent-size(byte): %d",elf->e_shentsize);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf sh-num: %d",elf->e_shnum);
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf sh-strndx: %d",elf->e_shstrndx);
+ */
+
+ // iterate over section headers
+ for(int phidx=0;phidx<elf->e_phnum;phidx++)
+ {
+ Elf32_Phdr *phdr=vaddr+elf->e_phoff+phidx*elf->e_phentsize;
+
+ if(phidx==0)
+ {
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"text: 0x%08X-0x%08X",phdr->p_vaddr,phdr->p_vaddr+phdr->p_filesz);
+ }
+
+ if(phidx==1)
+ {
+
+
+ /*
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"-- PROGRAMM HEADER %d --",phidx+1);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-type: %d",phdr->p_type);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-offset: 0x%08X",phdr->p_offset);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-vaddr: 0x%08X",phdr->p_vaddr);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-filesz: 0x%08X",phdr->p_filesz);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-memsz: 0x%08X",phdr->p_memsz);
+ */
+
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"data: 0x%08X-0x%08X",phdr->p_vaddr,phdr->p_vaddr+phdr->p_filesz);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"bss: 0x%08X-0x%08X",phdr->p_vaddr+phdr->p_filesz,phdr->p_vaddr+phdr->p_memsz);
+
+ // let's copy the rw- data block
+ uint32_t *data=vaddr+phdr->p_offset;
+ for(uint32_t *addr=phdr->p_vaddr; addr<=phdr->p_vaddr+phdr->p_filesz; addr++)
+ {
+ *addr=*data;
+ data++;
+ }
+
+ // let's zero init bss and set alloc (heap) just right after it!
+ for(uint32_t *addr=phdr->p_vaddr+phdr->p_filesz; addr<=phdr->p_vaddr+phdr->p_memsz; addr++)
+ {
+ *addr=0;
+ }
+
+ *alloc=phdr->p_vaddr+phdr->p_memsz;
+ }
+
+
+ }
+
+ return elf->e_entry;
+
+}