#include #include "ext2.h" #include "lib/logger/log.h" #define FOOLOS_MODULE_NAME "elf" #define EI_NIDENT 16 typedef uint32_t Elf32_Addr; typedef uint32_t Elf32_Off; typedef uint16_t Elf32_Section; typedef uint16_t Elf32_Versym; typedef unsigned char Elf_Byte; typedef uint16_t Elf32_Half; typedef int32_t Elf32_Sword; typedef uint32_t Elf32_Word; typedef int64_t Elf32_Sxword; typedef uint64_t Elf32_Xword; typedef struct { unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; typedef struct { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr; typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; // returns elf entry point uint32_t load_elf(char *name, uint32_t *alloc) { uint32_t ext2_ramimage= fs_get_root_ext2_ramimage(); int inode_nr=ext2_filename_to_inode(ext2_ramimage,name); if(inode_nr<1)return 0; //TODO: load ELF binary and move this to own compilation unit //load binary // uint32_t vaddr=0x08048000; uint32_t vaddr=0x08000000; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"loading %s",name); ext2_check(ext2_ramimage); ext2_inode_content(ext2_ramimage,inode_nr,vaddr,0x100000); // load 1mb; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"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;phidxe_phnum;phidx++) { Elf32_Phdr *phdr=vaddr+elf->e_phoff+phidx*elf->e_phentsize; if(phidx==0) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"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_DEBUG,"data: 0x%08X-0x%08X",phdr->p_vaddr,phdr->p_vaddr+phdr->p_filesz); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"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; }